<commit_before>var mamidApp = angular.module('mamidApp', ['ngRoute', 'ngResource']);

// http://www.codelord.net/2014/06/25/generic-error-handling-in-angularjs/
var specificallyHandleInProgress = false;
var HEADER_NAME = 'MyApp-Handle-Errors-Generically';
mamidApp.factory('RequestsErrorHandler', ['$q', function ($q) {
    return {
        // --- The user's API for claiming responsiblity for requests ---
        specificallyHandled: function (specificallyHandledBlock) {
            specificallyHandleInProgress = true;
            try {
                return specificallyHandledBlock();
            } finally {
                specificallyHandleInProgress = false;
            }
        },

        // --- Response interceptor for handling errors generically ---
        responseError: function (rejection) {
            var shouldHandle = (rejection && rejection.config && rejection.config.headers
            && rejection.config.headers[HEADER_NAME]);
            if (shouldHandle) {
                window.console.error(rejection);
                window.alert(rejection.data);
            }

            return $q.reject(rejection);
        }
    };
}]);
mamidApp.config(['$provide', '$httpProvider', function ($provide, $httpProvider) {
    $httpProvider.interceptors.push('RequestsErrorHandler');

    // --- Decorate $http to add a special header by default ---

    function addHeaderToConfig(config) {
        config = config || {};
        config.headers = config.headers || {};

        // Add the header unless user asked to handle errors himself
        if (!specificallyHandleInProgress) {
            config.headers[HEADER_NAME] = true;
        }

        return config;
    }

    // The rest here is mostly boilerplate needed to decorate $http safely
    $provide.decorator('$http', ['$delegate', function ($delegate) {
        function decorateRegularCall(method) {
            return function (url, config) {
                return $delegate[method](url, addHeaderToConfig(config));
            };
        }

        function decorateDataCall(method) {
            return function (url, data, config) {
                return $delegate[method](url, data, addHeaderToConfig(config));
            };
        }

        function copyNotOverriddenAttributes(newHttp) {
            for (var attr in $delegate) {
                if (!newHttp.hasOwnProperty(attr)) {
                    if (typeof($delegate[attr]) === 'function') {
                        newHttp[attr] = function () {
                            return $delegate[attr].apply($delegate, arguments);
                        };
                    } else {
                        newHttp[attr] = $delegate[attr];
                    }
                }
            }
        }

        var newHttp = function (config) {
            return $delegate(addHeaderToConfig(config));
        };

        newHttp.get = decorateRegularCall('get');
        newHttp.delete = decorateRegularCall('delete');
        newHttp.head = decorateRegularCall('head');
        newHttp.jsonp = decorateRegularCall('jsonp');
        newHttp.post = decorateDataCall('post');
        newHttp.put = decorateDataCall('put');

        copyNotOverriddenAttributes(newHttp);

        return newHttp;
    }]);
}]);

mamidApp.config(function ($routeProvider) {
    $routeProvider
        .when('/', {
            templateUrl: 'pages/home.html',
            controller: 'mainController'
        })
        .when('/slaves', {
            templateUrl: 'pages/slaves.html',
            controller: 'slaveIndexController'
        })
        .when('/slaves/:slaveId', {
            templateUrl: 'pages/slave.html',
            controller: 'slaveByIdController'
        })
        .when('/replicasets', {
            templateUrl: 'pages/replicasets.html',
            controller: 'replicasetIndexController'
        })
        .when('/replicasets/:replicasetId', {
            templateUrl: 'pages/replicaset.html',
            controller: 'replicasetByIdController'
        })
        .when('/problems', {
            templateUrl: 'pages/problems.html',
            controller: 'problemIndexController'
        })
        .when('/riskgroups', {
            templateUrl: 'pages/riskgroups.html',
            controller: 'riskGroupIndexController'
        })
});

mamidApp.factory('SlaveService', function ($resource) {
    return $resource('/api/slaves/:slave', {slave: "@id"}, {
        create: {method: 'put'},
        queryByReplicaSet: {method: 'get', url: '/api/replicasets/:replicaset/slaves/'}
    });
});

mamidApp.factory('ProblemService', function ($resource) {
    return $resource('/api/problems/:problem', {problem: "@id"}, {});
});

mamidApp.factory('ReplicaSetService', function ($resource) {
    return $resource('/api/replicasets/:replicaset', {replicaset: "@id"}, {
        create: {method: 'put'}
    });
});

mamidApp.factory('RiskGroupService', function ($resource) {
    return $resource('/api/riskgroups/:riskgroup', {riskgroup: "@id"}, {
        create: {method: 'put'},
        getUnassignedSlaves: {method: 'get', url: '/api/riskgroups/0/slaves/', isArray: true},
        assignToRiskGroup: {
            method: 'put',
            url: '/api/riskgroups/:riskgroup/slaves/:slave',
            params: {riskgroup: "@riskgroup", slave: "@slave"}
        },
        removeFromRiskGroup: {
            method: 'delete',
            url: '/api/riskgroups/:riskgroup/slaves/:slave',
            params: {riskgroup: "@riskgroup", slave: "@slave"}
        },
        getSlaves: {method: 'get', url: '/api/riskgroups/:riskgroup/slaves', isArray: true},
        remove: {method: 'delete'}
    });
});

mamidApp.controller('mainController', function ($scope) {
    $scope.message = 'Greetings from the controller';
});

mamidApp.controller('slaveIndexController', function ($scope, $http, SlaveService) {
    $scope.slaves = SlaveService.query()
});

mamidApp.controller('problemIndexController', function ($scope, $http, $timeout, ProblemService) {
    (function tick() {
        ProblemService.query(function (problems) {
            $scope.problems = problems;
            $timeout(tick, 1000 * 5);
        });
    })();
});

mamidApp.controller('riskGroupIndexController', function ($scope, $http, RiskGroupService) {
    $scope.riskgroups = RiskGroupService.query();
    $scope.unassigned_slaves = RiskGroupService.getUnassignedSlaves();
    $scope.new_riskgroup = new RiskGroupService();
    $scope.createRiskGroup = function () {
        $scope.new_riskgroup.$create();
        $scope.new_riskgroup = null;
        $scope.riskgroups = RiskGroupService.query();
    };
    $scope.assignToRiskGroup = function (slave, oldriskgroup) {
        if (slave.riskgroup == 0) {
            RiskGroupService.removeFromRiskGroup({slave: slave.id, riskgroup: oldriskgroup.id});
            $scope.riskgroups = RiskGroupService.query();
            $scope.unassigned_slaves = RiskGroupService.getUnassignedSlaves();
            return;
        }
        RiskGroupService.assignToRiskGroup({slave: slave.id, riskgroup: slave.riskgroup});
        $scope.riskgroups = RiskGroupService.query();
        $scope.unassigned_slaves = RiskGroupService.getUnassignedSlaves();
    };
    $scope.getSlaves = function (riskgroup) {
        riskgroup.slaves = RiskGroupService.getSlaves({riskgroup: riskgroup.id});
    }
    $scope.removeRiskGroup = function (riskgroup) {
        riskgroup.slaves = RiskGroupService.remove({riskgroup: riskgroup.id});
        $scope.riskgroups = RiskGroupService.query();
        $('#confirm_remove' + riskgroup.id).modal('hide');
    }
    $scope.isDeletable = function (riskgroup) {
        if (riskgroup.slaves === undefined) {
            $scope.getSlaves(riskgroup);
        }
        return riskgroup.slaves.length == 0;
    }
    $(function () {
        $('[data-toggle="tooltip"]').tooltip();
    })
});

mamidApp.controller('slaveByIdController', function ($scope, $http, $routeParams, $location, SlaveService) {
    var slaveId = $routeParams['slaveId'];
    $scope.is_create_view = slaveId === "new";
    if ($scope.is_create_view) {
        $scope.slave = new SlaveService();

        $scope.slave.configured_state = "disabled";

        //Copy slave for edit form so that changes are only applied to model when apply is clicked
        $scope.edit_slave = angular.copy($scope.slave);
    } else {
        $scope.slave = SlaveService.get({slave: slaveId});

        //Copy slave for edit form so that changes are only applied to model when apply is clicked
        $scope.slave.$promise.then(function () {
            $scope.edit_slave = angular.copy($scope.slave);
        });
    }

    $scope.updateSlave = function () {
        angular.copy($scope.edit_slave, $scope.slave);
        if ($scope.is_create_view) {
            $scope.slave.$create();
        } else {
            $scope.slave.$save();
        }
        $location.path("/slaves");
    };

    $scope.deleteSlave = function () {
        $scope.slave.$delete();
        $('#confirm_remove').modal('hide');
        $location.path("/slaves");
    };

    $scope.setSlaveState = function (state) {
        $scope.slave.configured_state = state;
        $scope.slave.$save();
    }
});

mamidApp.controller('replicasetIndexController', function ($scope, $http, ReplicaSetService) {
    $scope.replicasets = ReplicaSetService.query()
});

mamidApp.controller('replicasetByIdController',
    function ($scope, $http, $routeParams, $location, SlaveService, ReplicaSetService) {
        var replicasetId = $routeParams['replicasetId'];
        $scope.is_create_view = replicasetId === "new";
        if ($scope.is_create_view) {
            $scope.replicaset = new ReplicaSetService();

            //Copy replicaset for edit form so that changes are only applied to model when apply is clicked
            $scope.edit_replicaset = angular.copy($scope.replicaset);
        } else {
            $scope.replicaset = ReplicaSetService.get({replicaset: replicasetId});
            $scope.replicaset_slaves = SlaveService.queryByReplicaSet({replicaset: replicasetId});

            //Copy replicaset for edit form so that changes are only applied to model when apply is clicked
            $scope.replicaset.$promise.then(function () {
                $scope.edit_replicaset = angular.copy($scope.replicaset);
            });
        }

        $scope.updateReplicaSet = function () {
            angular.copy($scope.edit_replicaset, $scope.replicaset);
            if ($scope.is_create_view) {
                $scope.replicaset.$create();
            } else {
                $scope.replicaset.$save();
            }
            $location.path("/replicasets");
        };

        $scope.deleteReplicaSet = function () {
            $scope.replicaset.$delete();
            $('#confirm_remove').modal('hide');
            $location.path("/replicasets");
        };
    });<commit_msg>UPD: GUI: fancy error messages<commit_after>var mamidApp = angular.module('mamidApp', ['ngRoute', 'ngResource']);

// http://www.codelord.net/2014/06/25/generic-error-handling-in-angularjs/
var specificallyHandleInProgress = false;
var HEADER_NAME = 'MyApp-Handle-Errors-Generically';
mamidApp.factory('RequestsErrorHandler', ['$q', function ($q) {
    return {
        // --- The user's API for claiming responsiblity for requests ---
        specificallyHandled: function (specificallyHandledBlock) {
            specificallyHandleInProgress = true;
            try {
                return specificallyHandledBlock();
            } finally {
                specificallyHandleInProgress = false;
            }
        },

        // --- Response interceptor for handling errors generically ---
        responseError: function (rejection) {
            var shouldHandle = (rejection && rejection.config && rejection.config.headers
            && rejection.config.headers[HEADER_NAME]);
            if (shouldHandle) {
                var root = $('#content')[0];
                var ediv = document.createElement('div');
                ediv.setAttribute('class', 'alert alert-danger alert-dismissible fade in');
                ediv.setAttribute('role', 'alert');
                var button = document.createElement('button');
                button.setAttribute('class', 'close');
                button.setAttribute('data-dismiss', 'alert');
                button.setAttribute('type', 'button');
                button.innerHTML = '×';
                ediv.appendChild(button);
                var h4 = document.createElement('h4');
                h4.innerHTML = 'Houps! An error occurred.';
                ediv.appendChild(h4);
                var p = document.createElement('p');
                p.innerHTML = rejection.data;
                ediv.appendChild(p);
                root.insertBefore(ediv, root.firstChild);
                window.console.error(rejection);
            }

            return $q.reject(rejection);
        }
    };
}]);
mamidApp.config(['$provide', '$httpProvider', function ($provide, $httpProvider) {
    $httpProvider.interceptors.push('RequestsErrorHandler');

    // --- Decorate $http to add a special header by default ---

    function addHeaderToConfig(config) {
        config = config || {};
        config.headers = config.headers || {};

        // Add the header unless user asked to handle errors himself
        if (!specificallyHandleInProgress) {
            config.headers[HEADER_NAME] = true;
        }

        return config;
    }

    // The rest here is mostly boilerplate needed to decorate $http safely
    $provide.decorator('$http', ['$delegate', function ($delegate) {
        function decorateRegularCall(method) {
            return function (url, config) {
                return $delegate[method](url, addHeaderToConfig(config));
            };
        }

        function decorateDataCall(method) {
            return function (url, data, config) {
                return $delegate[method](url, data, addHeaderToConfig(config));
            };
        }

        function copyNotOverriddenAttributes(newHttp) {
            for (var attr in $delegate) {
                if (!newHttp.hasOwnProperty(attr)) {
                    if (typeof($delegate[attr]) === 'function') {
                        newHttp[attr] = function () {
                            return $delegate[attr].apply($delegate, arguments);
                        };
                    } else {
                        newHttp[attr] = $delegate[attr];
                    }
                }
            }
        }

        var newHttp = function (config) {
            return $delegate(addHeaderToConfig(config));
        };

        newHttp.get = decorateRegularCall('get');
        newHttp.delete = decorateRegularCall('delete');
        newHttp.head = decorateRegularCall('head');
        newHttp.jsonp = decorateRegularCall('jsonp');
        newHttp.post = decorateDataCall('post');
        newHttp.put = decorateDataCall('put');

        copyNotOverriddenAttributes(newHttp);

        return newHttp;
    }]);
}]);

mamidApp.config(function ($routeProvider) {
    $routeProvider
        .when('/', {
            templateUrl: 'pages/home.html',
            controller: 'mainController'
        })
        .when('/slaves', {
            templateUrl: 'pages/slaves.html',
            controller: 'slaveIndexController'
        })
        .when('/slaves/:slaveId', {
            templateUrl: 'pages/slave.html',
            controller: 'slaveByIdController'
        })
        .when('/replicasets', {
            templateUrl: 'pages/replicasets.html',
            controller: 'replicasetIndexController'
        })
        .when('/replicasets/:replicasetId', {
            templateUrl: 'pages/replicaset.html',
            controller: 'replicasetByIdController'
        })
        .when('/problems', {
            templateUrl: 'pages/problems.html',
            controller: 'problemIndexController'
        })
        .when('/riskgroups', {
            templateUrl: 'pages/riskgroups.html',
            controller: 'riskGroupIndexController'
        })
});

mamidApp.factory('SlaveService', function ($resource) {
    return $resource('/api/slaves/:slave', {slave: "@id"}, {
        create: {method: 'put'},
        queryByReplicaSet: {method: 'get', url: '/api/replicasets/:replicaset/slaves/'}
    });
});

mamidApp.factory('ProblemService', function ($resource) {
    return $resource('/api/problems/:problem', {problem: "@id"}, {});
});

mamidApp.factory('ReplicaSetService', function ($resource) {
    return $resource('/api/replicasets/:replicaset', {replicaset: "@id"}, {
        create: {method: 'put'}
    });
});

mamidApp.factory('RiskGroupService', function ($resource) {
    return $resource('/api/riskgroups/:riskgroup', {riskgroup: "@id"}, {
        create: {method: 'put'},
        getUnassignedSlaves: {method: 'get', url: '/api/riskgroups/0/slaves/', isArray: true},
        assignToRiskGroup: {
            method: 'put',
            url: '/api/riskgroups/:riskgroup/slaves/:slave',
            params: {riskgroup: "@riskgroup", slave: "@slave"}
        },
        removeFromRiskGroup: {
            method: 'delete',
            url: '/api/riskgroups/:riskgroup/slaves/:slave',
            params: {riskgroup: "@riskgroup", slave: "@slave"}
        },
        getSlaves: {method: 'get', url: '/api/riskgroups/:riskgroup/slaves', isArray: true},
        remove: {method: 'delete'}
    });
});

mamidApp.controller('mainController', function ($scope) {
    $scope.message = 'Greetings from the controller';
});

mamidApp.controller('slaveIndexController', function ($scope, $http, SlaveService) {
    $scope.slaves = SlaveService.query()
});

mamidApp.controller('problemIndexController', function ($scope, $http, $timeout, ProblemService) {
    (function tick() {
        ProblemService.query(function (problems) {
            $scope.problems = problems;
            $timeout(tick, 1000 * 5);
        });
    })();
});

mamidApp.controller('riskGroupIndexController', function ($scope, $http, RiskGroupService) {
    $scope.riskgroups = RiskGroupService.query();
    $scope.unassigned_slaves = RiskGroupService.getUnassignedSlaves();
    $scope.new_riskgroup = new RiskGroupService();
    $scope.createRiskGroup = function () {
        $scope.new_riskgroup.$create();
        $scope.new_riskgroup = null;
        $scope.riskgroups = RiskGroupService.query();
    };
    $scope.assignToRiskGroup = function (slave, oldriskgroup) {
        if (slave.riskgroup == 0) {
            RiskGroupService.removeFromRiskGroup({slave: slave.id, riskgroup: oldriskgroup.id});
            $scope.riskgroups = RiskGroupService.query();
            $scope.unassigned_slaves = RiskGroupService.getUnassignedSlaves();
            return;
        }
        RiskGroupService.assignToRiskGroup({slave: slave.id, riskgroup: slave.riskgroup});
        $scope.riskgroups = RiskGroupService.query();
        $scope.unassigned_slaves = RiskGroupService.getUnassignedSlaves();
    };
    $scope.getSlaves = function (riskgroup) {
        riskgroup.slaves = RiskGroupService.getSlaves({riskgroup: riskgroup.id});
    }
    $scope.removeRiskGroup = function (riskgroup) {
        riskgroup.slaves = RiskGroupService.remove({riskgroup: riskgroup.id});
        $scope.riskgroups = RiskGroupService.query();
        $('#confirm_remove' + riskgroup.id).modal('hide');
    }
    $scope.isDeletable = function (riskgroup) {
        if (riskgroup.slaves === undefined) {
            $scope.getSlaves(riskgroup);
        }
        return riskgroup.slaves.length == 0;
    }
    $(function () {
        $('[data-toggle="tooltip"]').tooltip();
    })
});

mamidApp.controller('slaveByIdController', function ($scope, $http, $routeParams, $location, SlaveService) {
    var slaveId = $routeParams['slaveId'];
    $scope.is_create_view = slaveId === "new";
    if ($scope.is_create_view) {
        $scope.slave = new SlaveService();

        $scope.slave.configured_state = "disabled";

        //Copy slave for edit form so that changes are only applied to model when apply is clicked
        $scope.edit_slave = angular.copy($scope.slave);
    } else {
        $scope.slave = SlaveService.get({slave: slaveId});

        //Copy slave for edit form so that changes are only applied to model when apply is clicked
        $scope.slave.$promise.then(function () {
            $scope.edit_slave = angular.copy($scope.slave);
        });
    }

    $scope.updateSlave = function () {
        angular.copy($scope.edit_slave, $scope.slave);
        if ($scope.is_create_view) {
            $scope.slave.$create();
        } else {
            $scope.slave.$save();
        }
        $location.path("/slaves");
    };

    $scope.deleteSlave = function () {
        $scope.slave.$delete();
        $('#confirm_remove').modal('hide');
        $location.path("/slaves");
    };

    $scope.setSlaveState = function (state) {
        $scope.slave.configured_state = state;
        $scope.slave.$save();
    }
});

mamidApp.controller('replicasetIndexController', function ($scope, $http, ReplicaSetService) {
    $scope.replicasets = ReplicaSetService.query()
});

mamidApp.controller('replicasetByIdController',
    function ($scope, $http, $routeParams, $location, SlaveService, ReplicaSetService) {
        var replicasetId = $routeParams['replicasetId'];
        $scope.is_create_view = replicasetId === "new";
        if ($scope.is_create_view) {
            $scope.replicaset = new ReplicaSetService();

            //Copy replicaset for edit form so that changes are only applied to model when apply is clicked
            $scope.edit_replicaset = angular.copy($scope.replicaset);
        } else {
            $scope.replicaset = ReplicaSetService.get({replicaset: replicasetId});
            $scope.replicaset_slaves = SlaveService.queryByReplicaSet({replicaset: replicasetId});

            //Copy replicaset for edit form so that changes are only applied to model when apply is clicked
            $scope.replicaset.$promise.then(function () {
                $scope.edit_replicaset = angular.copy($scope.replicaset);
            });
        }

        $scope.updateReplicaSet = function () {
            angular.copy($scope.edit_replicaset, $scope.replicaset);
            if ($scope.is_create_view) {
                $scope.replicaset.$create();
            } else {
                $scope.replicaset.$save();
            }
            $location.path("/replicasets");
        };

        $scope.deleteReplicaSet = function () {
            $scope.replicaset.$delete();
            $('#confirm_remove').modal('hide');
            $location.path("/replicasets");
        };
    });<|endoftext|>


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

var View = require('../view').extend();

_.extend(View.prototype, require('../mixins/observe'), {
	tagName: 'form',

	elements: {
		button: 'button'
	},

	events: {
		'focus input,textarea,[data-spytext]': 'onFocus',
		'blur input,textarea,[data-spytext]': 'onBlur',
		'input input,textarea,[data-spytext]': 'onChange',
		'change select,input,textarea,[data-spytext]': 'onChange',
		'click label': 'labelClick',
		'mouseover .invalid>label.icon': 'onHover',
		'mouseout .invalid>label.icon': 'onUnhover'
	},

	initialize: function(opts) {
		_.extend(this, _.pick(opts, 'onError', 'onSuccess', 'onComplete', 'submit'));

		// use properties from model validation to set up more bindings.
		// all model validation properties are assumed to be 'value' getter
		// and all selectors in form view default to [name=""] instead of [data-hook=""]
		this.bindings = _.mapObject(_.defaults(this.bindings || {}, _.mapObject(this.model.validation, function(value, key) {
			return 'value';
		})), function(value, key) {
			return _.isObject(value) ? value : {
				selector: '[name="' + key + '"],[data-name="' + key + '"]',
				type: value
			};
		});

		this.delegate('submit', this.submit.bind(this));

		this.listenTo(this.model, 'validated', this.setValid);
		this.listenTo(this.model, 'reset', this.reset);

		if(!this.model.isNew() && _.size(this.model.attributes) === 1)
			this.model.fetch();
	},

	attach: function() {
		this.$el.attr('novalidate', 'novalidate');

		var _view = this;

		this.observe({ delayInput: true, validate: true });

		// do not validate new or not fetched models
		if(!this.model.isNew() && _.size(this.model.attributes) > 1)
			this.model.validate(null, { validateAll: true });

		this.$('[data-spytext],[name]:not(:disabled)').each(function() {
			if(!/checkbox|radio/.test(this.type) && this.value) {
				delete this.delayInput;

				// TODO see how this handles defaults (meaning defaults might be
				// rendered with dust, and then this change event resets them
				if(_view.model.isNew())
					$(this).trigger('change');
			}

			// set non-empty classes
			_view.onChange({ currentTarget: this });
		});

		if($.fn.placeholder)
			this.$('input,textarea').placeholder();
	},

	labelClick: function(e) {
		$(e.currentTarget).siblings('input,textarea,[data-spytext]').focus();
	},

	reset: function() {
		this.$('.invalid,.valid').removeClass('valid invalid');
		this.$('label.error').remove();
		this.attach();
	},

	onHover: function() {
		this.$el.addClass('hide-errors');
	},

	onUnhover: function() {
		this.$el.removeClass('hide-errors');
	},

	onChange: function(e) {
		var target = e.currentTarget,
			value = target.nodeName === 'DIV' ? target.textContent.trim() : target.value;

		$(target).closest('form div.container').toggleClass('not-empty', !!value);
	},

	onFocus: function(e) {
		$(e.currentTarget).closest('form div.container').addClass('focus');
	},

	onBlur: function(e) {
		$(e.currentTarget).closest('form div.container').removeClass('focus');
	},

	onError: function(xhr, textStatus, error) {
		var _view = this;

		var message = xhr.responseJSON;

		if(_view.messageView)
			_view.messageView.remove();

		_view.messageView = new app.views.Message({
			message: message
		}).enter(_view.$el, 'before');
	},

	onSuccess: function(data, statusText, xhr) {
		this.trigger('submitted', data, statusText, xhr);
	},

	onComplete: function(xhr, textStatus) {
		this.elements.button.prop('disabled', false);
		$(document.body).removeClass('progress');
	},

	submit: function(e) {
		var _view = this;

		e.preventDefault();

		if(this.model.isValid()) {
			$(document.body).addClass('progress');

			this.elements.button.prop('disabled', true);

			return this.model.save(null, {
				success: this.onSuccess,
				error: this.onError,
				complete: this.onComplete,
				context: this,
				validate: false
			});
		}
	},

	setValid: function (model, errors, valid, options) {
		var _view = this;

		_.each(errors, function(error, property) {
			var $el = _view.$('[data-name="' + property + '"],[name="' + property + '"]');

			delete $el[0].delayInput;

			var $container = $el
				.removeClass('valid').addClass('invalid').closest('form .container'),
				$label = $container.find('label.error');

			if($label.length === 0)
				$('' + error + '').appendTo($container);
			else if($label.text() !== error)
				$label.text(error);

			$container.removeClass('valid').addClass('invalid');
		});

		if(!_.isEmpty(errors) && options && options.validateAll)
			_view.$('[name].invalid,[data-name].invalid').first().focus();

		_.each(valid, function(attr) {
			var $el = _view.$('[data-name="' + attr + '"],[name="' + attr + '"]');

			delete $el[0].delayInput;

			$el.removeClass('invalid').addClass('valid')
				.closest('form .container')
				.removeClass('invalid').addClass('valid')
				.find('label.error').remove();
		});
	},
});

module.exports = View;
<commit_msg>Listen to all events on select as well.<commit_after>var app = require('../ridge');

var View = require('../view').extend();

_.extend(View.prototype, require('../mixins/observe'), {
	tagName: 'form',

	elements: {
		button: 'button'
	},

	events: {
		'focus select,input,textarea,[data-spytext]': 'onFocus',
		'blur select,input,textarea,[data-spytext]': 'onBlur',
		'input select,input,textarea,[data-spytext]': 'onChange',
		'change select,input,textarea,[data-spytext]': 'onChange',
		'click label': 'labelClick',
		'mouseover .invalid>label.icon': 'onHover',
		'mouseout .invalid>label.icon': 'onUnhover'
	},

	initialize: function(opts) {
		_.extend(this, _.pick(opts, 'onError', 'onSuccess', 'onComplete', 'submit'));

		// use properties from model validation to set up more bindings.
		// all model validation properties are assumed to be 'value' getter
		// and all selectors in form view default to [name=""] instead of [data-hook=""]
		this.bindings = _.mapObject(_.defaults(this.bindings || {}, _.mapObject(this.model.validation, function(value, key) {
			return 'value';
		})), function(value, key) {
			return _.isObject(value) ? value : {
				selector: '[name="' + key + '"],[data-name="' + key + '"]',
				type: value
			};
		});

		this.delegate('submit', this.submit.bind(this));

		this.listenTo(this.model, 'validated', this.setValid);
		this.listenTo(this.model, 'reset', this.reset);

		if(!this.model.isNew() && _.size(this.model.attributes) === 1)
			this.model.fetch();
	},

	attach: function() {
		this.$el.attr('novalidate', 'novalidate');

		var _view = this;

		this.observe({ delayInput: true, validate: true });

		// do not validate new or not fetched models
		if(!this.model.isNew() && _.size(this.model.attributes) > 1)
			this.model.validate(null, { validateAll: true });

		this.$('[data-spytext],[name]:not(:disabled)').each(function() {
			if(!/checkbox|radio/.test(this.type) && this.value) {
				delete this.delayInput;

				// TODO see how this handles defaults (meaning defaults might be
				// rendered with dust, and then this change event resets them
				if(_view.model.isNew())
					$(this).trigger('change');
			}

			// set non-empty classes
			_view.onChange({ currentTarget: this });
		});

		if($.fn.placeholder)
			this.$('input,textarea').placeholder();
	},

	labelClick: function(e) {
		$(e.currentTarget).siblings('input,textarea,[data-spytext]').focus();
	},

	reset: function() {
		this.$('.invalid,.valid').removeClass('valid invalid');
		this.$('label.error').remove();
		this.attach();
	},

	onHover: function() {
		this.$el.addClass('hide-errors');
	},

	onUnhover: function() {
		this.$el.removeClass('hide-errors');
	},

	onChange: function(e) {
		var target = e.currentTarget,
			value = target.nodeName === 'DIV' ? target.textContent.trim() : target.value;

		$(target).closest('form div.container').toggleClass('not-empty', !!value);
	},

	onFocus: function(e) {
		$(e.currentTarget).closest('form div.container').addClass('focus');
	},

	onBlur: function(e) {
		$(e.currentTarget).closest('form div.container').removeClass('focus');
	},

	onError: function(xhr, textStatus, error) {
		var _view = this;

		var message = xhr.responseJSON;

		if(_view.messageView)
			_view.messageView.remove();

		_view.messageView = new app.views.Message({
			message: message
		}).enter(_view.$el, 'before');
	},

	onSuccess: function(data, statusText, xhr) {
		this.trigger('submitted', data, statusText, xhr);
	},

	onComplete: function(xhr, textStatus) {
		this.elements.button.prop('disabled', false);
		$(document.body).removeClass('progress');
	},

	submit: function(e) {
		var _view = this;

		e.preventDefault();

		if(this.model.isValid()) {
			$(document.body).addClass('progress');

			this.elements.button.prop('disabled', true);

			return this.model.save(null, {
				success: this.onSuccess,
				error: this.onError,
				complete: this.onComplete,
				context: this,
				validate: false
			});
		}
	},

	setValid: function (model, errors, valid, options) {
		var _view = this;

		_.each(errors, function(error, property) {
			var $el = _view.$('[data-name="' + property + '"],[name="' + property + '"]');

			delete $el[0].delayInput;

			var $container = $el
				.removeClass('valid').addClass('invalid').closest('form .container'),
				$label = $container.find('label.error');

			if($label.length === 0)
				$('' + error + '').appendTo($container);
			else if($label.text() !== error)
				$label.text(error);

			$container.removeClass('valid').addClass('invalid');
		});

		if(!_.isEmpty(errors) && options && options.validateAll)
			_view.$('[name].invalid,[data-name].invalid').first().focus();

		_.each(valid, function(attr) {
			var $el = _view.$('[data-name="' + attr + '"],[name="' + attr + '"]');

			delete $el[0].delayInput;

			$el.removeClass('invalid').addClass('valid')
				.closest('form .container')
				.removeClass('invalid').addClass('valid')
				.find('label.error').remove();
		});
	},
});

module.exports = View;
<|endoftext|>


<commit_before>const imageminMozjpeg = require('imagemin-mozjpeg');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const webpack = require('webpack');
const { UnusedFilesWebpackPlugin } = require('unused-files-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const UglifyJS = require('uglify-es');
const env_vars = require('./ENV_VARS');
const webpackConfig = {
  node: {
    process: true
  },
  devServer: {
    https: true,
    host: '0.0.0.0',
    hotOnly: true,
    port: 8080,
    headers: {
      'Strict-Transport-Security':
        'max-age=63072000; includeSubdomains; preload',
      'Content-Security-Policy':
        "default-src 'self'; frame-src 'self' connect.trezor.io:443; img-src 'self' data: blob:; script-src 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:; object-src 'none'; connect-src *;",
      'X-Content-Type-Options': 'nosniff',
      'X-Frame-Options': 'DENY',
      'X-XSS-Protection': '1; mode=block',
      'Referrer-Policy': 'same-origin'
    }
  },
  plugins: [
    new webpack.DefinePlugin(env_vars),
    new webpack.NormalModuleReplacementPlugin(/^any-promise$/, 'bluebird'),
    new ImageminPlugin({
      disable: process.env.NODE_ENV !== 'production',
      test: /\.(jpe?g|png|gif|svg)$/i,
      pngquant: {
        quality: '100'
      },
      plugins: [
        imageminMozjpeg({
          quality: 100,
          progressive: true
        })
      ]
    })
  ],
  optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all'
        }
      }
    }
  }
};
if (process.env.BUILD_TYPE === 'mewcx') {
  webpackConfig.plugins.push(
    new CopyWebpackPlugin([
      {
        from: 'src/builds/mewcx/files',
        transform: function(content, filePath) {
          if (filePath.split('.').pop() === ('js' || 'JS'))
            return UglifyJS.minify(content.toString()).code;
          if (filePath.replace(/^.*[\\\/]/, '') === 'manifest.json') {
            const version = require('./package.json').version;
            const json = JSON.parse(content);
            json.version = version;
            return JSON.stringify(json);
          }
          return content;
        }
      }
    ])
  );
}
if (process.env.NODE_ENV === 'production') {
  webpackConfig.plugins.push(
    new UnusedFilesWebpackPlugin({
      patterns: ['src/**/*.*'],
      failOnUnused: true,
      globOptions: {
        ignore: [
          // Are we using these
          'src/components/DropDownAddressSelector/#####DropDownAddressSelector.vue',
          'src/components/DropDownAddressSelector/DropDownAddressSelector.scss',
          'src/components/DropDownAddressSelector/index.js',
          // Unknown
          'src/contracts/contract-abi-etsc.json',
          'src/contracts/contract-abi-exp.json',
          'src/layouts/DevelopmentResources/DevelopmentResources.scss',
          'src/layouts/DevelopmentResources/DevelopmentResources.vue',
          'src/layouts/DevelopmentResources/index.js',
          'src/layouts/InterfaceLayout/containers/SendCurrencyContainer/SendCurrencyContainer-desktop.scss',
          'src/layouts/InterfaceLayout/containers/SendCurrencyContainer/SendCurrencyContainer-mobile.scss',
          'src/layouts/InterfaceLayout/containers/SendCurrencyContainer/SendCurrencyContainer-tablet.scss',
          'src/tokens/tokens-etsc.json',
          'src/tokens/tokens-exp.json',
          // Informational
          'src/translations/README.md',
          'src/App.scss',
          // Helpers page
          'src/layouts/InformationPages/PrivacyPolicyLayout/index.js',
          'src/layouts/InformationPages/PrivacyPolicyLayout/PrivacyPolicyLayout.scss',
          'src/layouts/InformationPages/PrivacyPolicyLayout/PrivacyPolicyLayout.vue',
          'src/layouts/InformationPages/TermsAndConditionsLayout/index.js',
          'src/layouts/InformationPages/TermsAndConditionsLayout/TermsAndConditionsLayout.scss',
          'src/layouts/InformationPages/TermsAndConditionsLayout/TermsAndConditionsLayout.vue',
          'src/layouts/InformationPages/AdvancedToolsLayout/AdvancedToolsLayout.scss',
          'src/layouts/InformationPages/AdvancedToolsLayout/AdvancedToolsLayout.vue',
          'src/layouts/InformationPages/AdvancedToolsLayout/index.js',
          'src/layouts/InformationPages/ExtensionsLayout/ExtensionsLayout.scss',
          'src/layouts/InformationPages/ExtensionsLayout/ExtensionsLayout.vue',
          'src/layouts/InformationPages/ExtensionsLayout/index.js',
          'src/layouts/InformationPages/MewGithubLayout/index.js',
          'src/layouts/InformationPages/MewGithubLayout/MewGithubLayout.scss',
          'src/layouts/InformationPages/MewGithubLayout/MewGithubLayout.vue',
          'src/components/DropDownBidCurrencySelector/DropDownBidCurrencySelector.scss',
          'src/components/DropDownBidCurrencySelector/DropDownBidCurrencySelector.vue',
          'src/components/DropDownBidCurrencySelector/index.js',
          'src/components/DropDownAddressSelector/DropDownAddressSelector.vue',
          'src/components/Notification/components/NotificationTypes/SwapNotification/index.js',
          'src/components/Notification/components/NotificationTypes/TransactionNotification/index.js',
          // Images
          'src/assets/images/background/bg-left.png',
          'src/assets/images/background/bg-right.png',
          'src/assets/images/currency/coins/AllImages/_icon-config.json',
          'src/assets/images/currency/coins/asFont/cryptocoins.json',
          'src/assets/images/currency/coins/asFont/cryptocoins.less',
          'src/assets/images/currency/coins/webfont/cryptocoins-colors.css',
          'src/assets/images/currency/coins/webfont/cryptocoins.css',
          'src/assets/images/flags/countries.json',
          'src/assets/images/icons/arrow-green-right.svg',
          'src/assets/images/icons/btc.png',
          'src/assets/images/icons/favicon.png',
          'src/assets/images/icons/github-black.png',
          'src/assets/images/icons/slack.png',
          'src/assets/images/mew-screen.png',
          'src/assets/images/networks/esn.svg',
          'src/assets/images/networks/etsc.svg',
          'src/assets/images/networks/exp.svg',
          'src/assets/images/icons/up.svg',
          // Chrome Extension
          'src/builds/mewcx/app.vue',
          'src/builds/mewcx/files/img/icons/icon128.png',
          'src/builds/mewcx/files/img/icons/icon16.png',
          'src/builds/mewcx/files/img/icons/icon192.png',
          'src/builds/mewcx/files/img/icons/icon32.png',
          'src/builds/mewcx/files/img/icons/icon48.png',
          'src/builds/mewcx/files/manifest.json',
          'src/builds/mewcx/index.js',
          'src/builds/web/storage/index.js'
        ]
      }
    })
  );
}
const pwa = {
  name: 'MyEtherWallet',
  workboxOptions: {
    importWorkboxFrom: 'local',
    skipWaiting: true,
    clientsClaim: true
  }
};
module.exports = {
  publicPath: process.env.ROUTER_MODE === 'history' ? '/' : './',
  configureWebpack: webpackConfig,
  pwa: pwa,
  lintOnSave: process.env.NODE_ENV === 'production' ? 'error' : true,
  integrity: process.env.WEBPACK_INTEGRITY === 'false' ? false : true,
  chainWebpack: config => {}
};
<commit_msg>Change back temp config<commit_after>const imageminMozjpeg = require('imagemin-mozjpeg');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const webpack = require('webpack');
const { UnusedFilesWebpackPlugin } = require('unused-files-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const UglifyJS = require('uglify-es');
const env_vars = require('./ENV_VARS');
const webpackConfig = {
  node: {
    process: true
  },
  devServer: {
    https: true,
    host: 'localhost',
    hotOnly: true,
    port: 8080,
    headers: {
      'Strict-Transport-Security':
        'max-age=63072000; includeSubdomains; preload',
      'Content-Security-Policy':
        "default-src 'self'; frame-src 'self' connect.trezor.io:443; img-src 'self' data: blob:; script-src 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:; object-src 'none'; connect-src *;",
      'X-Content-Type-Options': 'nosniff',
      'X-Frame-Options': 'DENY',
      'X-XSS-Protection': '1; mode=block',
      'Referrer-Policy': 'same-origin'
    }
  },
  plugins: [
    new webpack.DefinePlugin(env_vars),
    new webpack.NormalModuleReplacementPlugin(/^any-promise$/, 'bluebird'),
    new ImageminPlugin({
      disable: process.env.NODE_ENV !== 'production',
      test: /\.(jpe?g|png|gif|svg)$/i,
      pngquant: {
        quality: '100'
      },
      plugins: [
        imageminMozjpeg({
          quality: 100,
          progressive: true
        })
      ]
    })
  ],
  optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all'
        }
      }
    }
  }
};
if (process.env.BUILD_TYPE === 'mewcx') {
  webpackConfig.plugins.push(
    new CopyWebpackPlugin([
      {
        from: 'src/builds/mewcx/files',
        transform: function(content, filePath) {
          if (filePath.split('.').pop() === ('js' || 'JS'))
            return UglifyJS.minify(content.toString()).code;
          if (filePath.replace(/^.*[\\\/]/, '') === 'manifest.json') {
            const version = require('./package.json').version;
            const json = JSON.parse(content);
            json.version = version;
            return JSON.stringify(json);
          }
          return content;
        }
      }
    ])
  );
}
if (process.env.NODE_ENV === 'production') {
  webpackConfig.plugins.push(
    new UnusedFilesWebpackPlugin({
      patterns: ['src/**/*.*'],
      failOnUnused: true,
      globOptions: {
        ignore: [
          // Are we using these
          'src/components/DropDownAddressSelector/#####DropDownAddressSelector.vue',
          'src/components/DropDownAddressSelector/DropDownAddressSelector.scss',
          'src/components/DropDownAddressSelector/index.js',
          // Unknown
          'src/contracts/contract-abi-etsc.json',
          'src/contracts/contract-abi-exp.json',
          'src/layouts/DevelopmentResources/DevelopmentResources.scss',
          'src/layouts/DevelopmentResources/DevelopmentResources.vue',
          'src/layouts/DevelopmentResources/index.js',
          'src/layouts/InterfaceLayout/containers/SendCurrencyContainer/SendCurrencyContainer-desktop.scss',
          'src/layouts/InterfaceLayout/containers/SendCurrencyContainer/SendCurrencyContainer-mobile.scss',
          'src/layouts/InterfaceLayout/containers/SendCurrencyContainer/SendCurrencyContainer-tablet.scss',
          'src/tokens/tokens-etsc.json',
          'src/tokens/tokens-exp.json',
          // Informational
          'src/translations/README.md',
          'src/App.scss',
          // Helpers page
          'src/layouts/InformationPages/PrivacyPolicyLayout/index.js',
          'src/layouts/InformationPages/PrivacyPolicyLayout/PrivacyPolicyLayout.scss',
          'src/layouts/InformationPages/PrivacyPolicyLayout/PrivacyPolicyLayout.vue',
          'src/layouts/InformationPages/TermsAndConditionsLayout/index.js',
          'src/layouts/InformationPages/TermsAndConditionsLayout/TermsAndConditionsLayout.scss',
          'src/layouts/InformationPages/TermsAndConditionsLayout/TermsAndConditionsLayout.vue',
          'src/layouts/InformationPages/AdvancedToolsLayout/AdvancedToolsLayout.scss',
          'src/layouts/InformationPages/AdvancedToolsLayout/AdvancedToolsLayout.vue',
          'src/layouts/InformationPages/AdvancedToolsLayout/index.js',
          'src/layouts/InformationPages/ExtensionsLayout/ExtensionsLayout.scss',
          'src/layouts/InformationPages/ExtensionsLayout/ExtensionsLayout.vue',
          'src/layouts/InformationPages/ExtensionsLayout/index.js',
          'src/layouts/InformationPages/MewGithubLayout/index.js',
          'src/layouts/InformationPages/MewGithubLayout/MewGithubLayout.scss',
          'src/layouts/InformationPages/MewGithubLayout/MewGithubLayout.vue',
          'src/components/DropDownBidCurrencySelector/DropDownBidCurrencySelector.scss',
          'src/components/DropDownBidCurrencySelector/DropDownBidCurrencySelector.vue',
          'src/components/DropDownBidCurrencySelector/index.js',
          'src/components/DropDownAddressSelector/DropDownAddressSelector.vue',
          'src/components/Notification/components/NotificationTypes/SwapNotification/index.js',
          'src/components/Notification/components/NotificationTypes/TransactionNotification/index.js',
          // Images
          'src/assets/images/background/bg-left.png',
          'src/assets/images/background/bg-right.png',
          'src/assets/images/currency/coins/AllImages/_icon-config.json',
          'src/assets/images/currency/coins/asFont/cryptocoins.json',
          'src/assets/images/currency/coins/asFont/cryptocoins.less',
          'src/assets/images/currency/coins/webfont/cryptocoins-colors.css',
          'src/assets/images/currency/coins/webfont/cryptocoins.css',
          'src/assets/images/flags/countries.json',
          'src/assets/images/icons/arrow-green-right.svg',
          'src/assets/images/icons/btc.png',
          'src/assets/images/icons/favicon.png',
          'src/assets/images/icons/github-black.png',
          'src/assets/images/icons/slack.png',
          'src/assets/images/mew-screen.png',
          'src/assets/images/networks/esn.svg',
          'src/assets/images/networks/etsc.svg',
          'src/assets/images/networks/exp.svg',
          'src/assets/images/icons/up.svg',
          // Chrome Extension
          'src/builds/mewcx/app.vue',
          'src/builds/mewcx/files/img/icons/icon128.png',
          'src/builds/mewcx/files/img/icons/icon16.png',
          'src/builds/mewcx/files/img/icons/icon192.png',
          'src/builds/mewcx/files/img/icons/icon32.png',
          'src/builds/mewcx/files/img/icons/icon48.png',
          'src/builds/mewcx/files/manifest.json',
          'src/builds/mewcx/index.js',
          'src/builds/web/storage/index.js'
        ]
      }
    })
  );
}
const pwa = {
  name: 'MyEtherWallet',
  workboxOptions: {
    importWorkboxFrom: 'local',
    skipWaiting: true,
    clientsClaim: true
  }
};
module.exports = {
  publicPath: process.env.ROUTER_MODE === 'history' ? '/' : './',
  configureWebpack: webpackConfig,
  pwa: pwa,
  lintOnSave: process.env.NODE_ENV === 'production' ? 'error' : true,
  integrity: process.env.WEBPACK_INTEGRITY === 'false' ? false : true,
  chainWebpack: config => {}
};
<|endoftext|>


<commit_before>$(document).ready(function () {
    $('div.tagcloud span').each(function () {
        frequency = $(this).data('frequency');
        $(this).css("fontSize", (frequency / 10 < 1) ? frequency / 10 + 1 + "em": (frequency / 10 > 2) ? "2em" : frequency / 10 + "em");
    });
});
<commit_msg>Added font-weight changes to TagCloud.<commit_after>$(document).ready(function () {
    $('div.tagcloud span').each(function () {
        frequency = $(this).data('frequency');
        rel = (frequency / 10 < 1) ? frequency / 10 + 1: (frequency / 10 > 2) ? "2" : frequency / 10;
        $(this).css("font-size", rel + 'em');
        if(rel < 1.2) {
            rel = 400;
        } else if(rel < 1.5) {
            rel = 600;
        } else if(rel < 1.7) {
            rel = 700;
        } else {
            rel = 800;
        }
        $(this).css("font-weight", rel);
    });
});
<|endoftext|>


<commit_before>var activity = (function () {
var exports = {};

/*
    Helpers for detecting user activity and managing user idle states
*/

/* Broadcast "idle" to server after 5 minutes of local inactivity */
var DEFAULT_IDLE_TIMEOUT_MS = 5 * 60 * 1000;
/* Time between keep-alive pings */
var ACTIVE_PING_INTERVAL_MS = 50 * 1000;

/* Mark users as offline after 140 seconds since their last checkin */
var OFFLINE_THRESHOLD_SECS = 140;

/* Keep in sync with views.py:json_update_active_status() */
exports.ACTIVE = "active";
exports.IDLE = "idle";

// When you start Zulip, has_focus should be true, but it might not be the
// case after a server-initiated reload.
exports.has_focus = document.hasFocus && document.hasFocus();

// We initialize this to true, to count new page loads, but set it to
// false in the onload function in reload.js if this was a
// server-initiated-reload to avoid counting a server-initiated reload
// as user activity.
exports.new_user_input = true;

$("html").on("mousemove", function () {
    exports.new_user_input = true;
});

var user_info = {};

function sort_users(users, user_info) {
    // TODO sort by unread count first, once we support that
    users.sort(function (a, b) {
        if (user_info[a] === 'active' && user_info[b] !== 'active') {
            return -1;
        } else if (user_info[b] === 'active' && user_info[a] !== 'active') {
            return 1;
        }

        if (user_info[a] === 'idle' && user_info[b] !== 'idle') {
            return -1;
        } else if (user_info[b] === 'idle' && user_info[a] !== 'idle') {
            return 1;
        }

        // Sort equivalent PM names alphabetically
        var full_name_a = a;
        var full_name_b = b;
        if (people_dict.has(a)) {
            full_name_a = people_dict.get(a).full_name;
        }
        if (people_dict.has(b)) {
            full_name_b = people_dict.get(b).full_name;
        }
        return util.strcmp(full_name_a, full_name_b);
    });

    return users;
}

// for testing:
exports._sort_users = sort_users;

function focus_lost() {
    if (!exports.has_focus) {
        return false;
    }

    exports.has_focus = false;
}

function update_users() {
    var users = sort_users(Object.keys(user_info), user_info);
    ui.set_presence_list(users, user_info);
}

function status_from_timestamp(baseline_time, presence) {
    if (presence.website === undefined) {
        return 'offline';
    }

    var age = baseline_time - presence.website.timestamp;

    var status = 'offline';
    if (age < OFFLINE_THRESHOLD_SECS) {
        status = presence.website.status;
    }
    return status;
}

function focus_ping() {
    $.post('/json/update_active_status',
           {status: (exports.has_focus) ? exports.ACTIVE : exports.IDLE,
            new_user_input: exports.new_user_input}, function (data) {
        if (data === undefined || data.presences === undefined) {
            // We sometimes receive no data even on successful
            // requests; we should figure out why but this will
            // prevent us from throwing errors until then
            return;
        }

        user_info = {};

        // Update Zephyr mirror activity warning
        if (data.zephyr_mirror_active === false) {
            $('#zephyr-mirror-error').show();
        } else {
            $('#zephyr-mirror-error').hide();
        }

        exports.new_user_input = false;

        // Ping returns the active peer list
        _.each(data.presences, function (presence, this_email) {
            if (page_params.email !== this_email) {
                user_info[this_email] = status_from_timestamp(data.server_timestamp, presence);
            }
        });
        update_users();
    });
}

function focus_gained() {
    if (!exports.has_focus) {
        exports.has_focus = true;

        focus_ping();
    }
}

exports.initialize = function () {
    $(window).focus(focus_gained);
    $(window).idle({idle: DEFAULT_IDLE_TIMEOUT_MS,
                onIdle: focus_lost,
                onActive: focus_gained,
                keepTracking: true});

    setInterval(focus_ping, ACTIVE_PING_INTERVAL_MS);

    focus_ping();
};

// Set user statuses. `users` should be an object with user emails as keys
// and presence information (see `status_from_timestamp`) as values.
//
// The object does not need to include every user, only the ones
// whose presence you wish to update.
//
// This rerenders the user sidebar at the end, which can be slow if done too
// often, so try to avoid calling this repeatedly.
exports.set_user_statuses = function (users, server_time) {
    _.each(users, function (presence, email) {
        if (email === page_params.email) {
            return;
        }
        user_info[email] = status_from_timestamp(server_time, presence);
    });

    update_users();
};

return exports;

}());
if (typeof module !== 'undefined') {
    module.exports = activity;
}
<commit_msg>Rename user_info -> presence_info inside activity.js.<commit_after>var activity = (function () {
var exports = {};

/*
    Helpers for detecting user activity and managing user idle states
*/

/* Broadcast "idle" to server after 5 minutes of local inactivity */
var DEFAULT_IDLE_TIMEOUT_MS = 5 * 60 * 1000;
/* Time between keep-alive pings */
var ACTIVE_PING_INTERVAL_MS = 50 * 1000;

/* Mark users as offline after 140 seconds since their last checkin */
var OFFLINE_THRESHOLD_SECS = 140;

/* Keep in sync with views.py:json_update_active_status() */
exports.ACTIVE = "active";
exports.IDLE = "idle";

// When you start Zulip, has_focus should be true, but it might not be the
// case after a server-initiated reload.
exports.has_focus = document.hasFocus && document.hasFocus();

// We initialize this to true, to count new page loads, but set it to
// false in the onload function in reload.js if this was a
// server-initiated-reload to avoid counting a server-initiated reload
// as user activity.
exports.new_user_input = true;

$("html").on("mousemove", function () {
    exports.new_user_input = true;
});

var presence_info = {};

function sort_users(users, presence_info) {
    // TODO sort by unread count first, once we support that
    users.sort(function (a, b) {
        if (presence_info[a] === 'active' && presence_info[b] !== 'active') {
            return -1;
        } else if (presence_info[b] === 'active' && presence_info[a] !== 'active') {
            return 1;
        }

        if (presence_info[a] === 'idle' && presence_info[b] !== 'idle') {
            return -1;
        } else if (presence_info[b] === 'idle' && presence_info[a] !== 'idle') {
            return 1;
        }

        // Sort equivalent PM names alphabetically
        var full_name_a = a;
        var full_name_b = b;
        if (people_dict.has(a)) {
            full_name_a = people_dict.get(a).full_name;
        }
        if (people_dict.has(b)) {
            full_name_b = people_dict.get(b).full_name;
        }
        return util.strcmp(full_name_a, full_name_b);
    });

    return users;
}

// for testing:
exports._sort_users = sort_users;

function focus_lost() {
    if (!exports.has_focus) {
        return false;
    }

    exports.has_focus = false;
}

function update_users() {
    var users = sort_users(Object.keys(presence_info), presence_info);
    ui.set_presence_list(users, presence_info);
}

function status_from_timestamp(baseline_time, presence) {
    if (presence.website === undefined) {
        return 'offline';
    }

    var age = baseline_time - presence.website.timestamp;

    var status = 'offline';
    if (age < OFFLINE_THRESHOLD_SECS) {
        status = presence.website.status;
    }
    return status;
}

function focus_ping() {
    $.post('/json/update_active_status',
           {status: (exports.has_focus) ? exports.ACTIVE : exports.IDLE,
            new_user_input: exports.new_user_input}, function (data) {
        if (data === undefined || data.presences === undefined) {
            // We sometimes receive no data even on successful
            // requests; we should figure out why but this will
            // prevent us from throwing errors until then
            return;
        }

        presence_info = {};

        // Update Zephyr mirror activity warning
        if (data.zephyr_mirror_active === false) {
            $('#zephyr-mirror-error').show();
        } else {
            $('#zephyr-mirror-error').hide();
        }

        exports.new_user_input = false;

        // Ping returns the active peer list
        _.each(data.presences, function (presence, this_email) {
            if (page_params.email !== this_email) {
                presence_info[this_email] = status_from_timestamp(data.server_timestamp, presence);
            }
        });
        update_users();
    });
}

function focus_gained() {
    if (!exports.has_focus) {
        exports.has_focus = true;

        focus_ping();
    }
}

exports.initialize = function () {
    $(window).focus(focus_gained);
    $(window).idle({idle: DEFAULT_IDLE_TIMEOUT_MS,
                onIdle: focus_lost,
                onActive: focus_gained,
                keepTracking: true});

    setInterval(focus_ping, ACTIVE_PING_INTERVAL_MS);

    focus_ping();
};

// Set user statuses. `users` should be an object with user emails as keys
// and presence information (see `status_from_timestamp`) as values.
//
// The object does not need to include every user, only the ones
// whose presence you wish to update.
//
// This rerenders the user sidebar at the end, which can be slow if done too
// often, so try to avoid calling this repeatedly.
exports.set_user_statuses = function (users, server_time) {
    _.each(users, function (presence, email) {
        if (email === page_params.email) {
            return;
        }
        presence_info[email] = status_from_timestamp(server_time, presence);
    });

    update_users();
};

return exports;

}());
if (typeof module !== 'undefined') {
    module.exports = activity;
}
<|endoftext|>


<commit_before>document.addEventListener("DOMContentLoaded", function(event){
	var editorDiv = document.getElementById("editor")
	var editor = new Quill(editorDiv)
	var codeEditor = ace.edit("code-editor")
	var postBodyInput = document.getElementById("post-body")
	var validityInput = document.getElementById("post-validity")
	var tagsInput = document.getElementById("tags-input")
	var placeholderTagsInput = document.getElementById("placeholder-tags-input")
	var tagsInputPlugin = insignia(tagsInput)
	var form = document.getElementById("post-form")
	var linkButton = document.getElementById("add-link")
	var imageButton = document.getElementById("add-image")
	var quoteButton = document.getElementById("add-quote")
	var codeButton = document.getElementById("add-code")
	var alignLeftButton = document.getElementById("align-left")
	var alignCenterButton = document.getElementById("align-center")
	var alignRightButton = document.getElementById("align-right")
	var alignJustifyButton = document.getElementById("align-justify")

	var linkModal = {
		element: document.getElementById("link-modal"),
		input: document.getElementById("modal-link"),
		init: function() { //We needt o access some objects within this obect upon initialization, so we use this function to do that.
			this.modal = new Modal(this.element)
			this.errorDiv = this.element.querySelector("div.modal-error")
			delete this.init
			return this
		}
	}.init()

	var imageModal = {
		element: document.getElementById("image-modal"),
		linkInput: document.getElementById("image-url"),
		fileInput: document.getElementById("image-upload"),
		uploadRequest: null, //This will be defined when an image is being uploaded. This is a global variable so it can be cancelled.
		init: function(){ //We need to access some objects within this object upon initializaton, so we use this function to do that.
			this.modal = new Modal(this.element)
			this.positiveButton = this.element.querySelector("button.positive") //We need to do some styling with this button, so it's better to find it now rather than later.
			this.errorDiv = this.element.querySelector("div.modal-error")
			delete this.init
			return this
		},
	}.init()

	var codeModal = {
		element: document.getElementById("code-modal"),
		selectLanguage: document.getElementById("select-language"),
		init: function() { //We need to access some objects within this object upon initializatoin, so we use this function to do that.
			this.modal = new Modal(this.element, {keyboard: false})
			delete this.init
			return this
		}
	}.init()

	editor.addModule("toolbar", {container: "div#toolbar"})
	editor.addFormat("quote", {"class": "quote"})
	editor.addFormat("code", {"class": "code-"})

	codeEditor.getSession().setUseWorker(false)

	editor.on("selection-change", function(range){
		if (range == null){
			editorDiv.classList.remove("focused")
			quoteButton.disabled = true
		}

		else {
			editorDiv.classList.add("focused")
			if (range.end - range.start > 0){
				quoteButton.disabled = false
			}
			else {
				quoteButton.disabled = true
			}
		}
	})

	linkButton.addEventListener("click", function(event){
		linkModal.modal.show()
		linkModal.input.focus()
	})

	imageButton.addEventListener("click", function(event){
		imageModal.modal.show()
	})

	codeButton.addEventListener("click", function(event){
		codeModal.modal.show()
	})

	alignLeftButton.addEventListener("click", function(event){
		editor.focus()
		var selection = editor.getSelection()
		if (selection != null){
			editor.formatLine(selection.start, selection.end, "align", "left")
		}
	})

	alignCenterButton.addEventListener("click", function(event){
		editor.focus()
		var selection = editor.getSelection()
		if (selection != null){
			editor.formatLine(selection.start, selection.end, "align", "center")
		}
	})

	alignRightButton.addEventListener("click", function(event){
		editor.focus()
		var selection = editor.getSelection()
		if (selection != null){
			editor.formatLine(selection.start, selection.end, "align", "right")
		}
	})

	alignJustifyButton.addEventListener("click", function(event){
		editor.focus()
		var selection = editor.getSelection()
		if (selection != null){
			editor.formatText(selection.start, selection.end+1, "align", "justify")
		}
	})

	linkModal.element.addEventListener("positive-pressed", function(event){
		if (linkModal.input.value.trim().length === 0) {
			linkModal.errorDiv.classList.add("active")
			event.preventDefault()
		}
		else {
			editor.focus()
			var selection = editor.getSelection()
			editor.setSelection(null)
			//This basically indicates that we don't actually have a selection.
			if (selection.end - selection.start === 0){
				editor.insertText(selection.start, linkModal.input.value, "link", linkModal.input.value)
			}
			else {
				editor.formatText(selection.start, selection.end, "link", linkModal.input.value)
			}
		}
	})

	linkModal.element.addEventListener("hide", function(event){
		linkModal.input.value = ""
		linkModal.errorDiv.classList.remove("active")
	})

	imageModal.linkInput.addEventListener("input", function(event){
		imageModal.fileInput.disabled = true
	})

	imageModal.fileInput.addEventListener("change", function(event){
		imageModal.linkInput.disabled = true
	})

	imageModal.element.addEventListener("positive-pressed", function(event){
		if (!imageModal.linkInput.disabled && imageModal.linkInput.value.length > 0) {
			editor.focus()
			var selection = editor.getSelection()
			editor.insertEmbed(selection.end, "image", imageModal.linkInput.value)
		}
		else if (!imageModal.fileInput.disabled && imageModal.fileInput.value.length > 0) {
			event.preventDefault() //We're gonna need to do this on our own.
			imageModal.uploadRequest = new XMLHttpRequest()
			var formData = new FormData()
			formData.append("image", imageModal.fileInput.files[0])
			imageModal.uploadRequest.open("POST", "/upload_image")

			imageModal.uploadRequest.onload = function(){
				console.log("hm")
				var data = JSON.parse(imageModal.uploadRequest.responseText)
				if (data.error == 0) {
					editor.focus()
					var selection = editor.getSelection()
					editor.insertEmbed(selection.end, "image", data.url)
					imageModal.modal.hide()
				}

				else if (data.error == 2){
					imageModal.errorDiv.textContent = "Image must be a JPG, PNG, or GIF."
					imageModal.errorDiv.classList.add("active")
					imageModal.positiveButton.classList.remove("uploading")
					imageModal.positiveButton.disabled = false
				}

				imageModal.uploadRequest = null
			}

			imageModal.uploadRequest.send(formData)
			imageModal.positiveButton.classList.add("uploading")
			imageModal.positiveButton.disabled = true
		}
	})

	imageModal.element.addEventListener("hide", function(event){
		imageModal.linkInput.disabled = false
		imageModal.linkInput.value = ""
		imageModal.fileInput.disabled = false
		imageModal.fileInput.value = null
		imageModal.positiveButton.classList.remove("uploading")
		imageModal.positiveButton.disabled = false
		imageModal.errorDiv.classList.remove("active")
		if (imageModal.uploadRequest != null) {
			imageModal.uploadRequest.abort()
		}
	})

	codeModal.selectLanguage.addEventListener("change", function(event){
		console.log("ace/mode/"+codeModal.selectLanguage.value)
		codeEditor.getSession().setMode("ace/mode/"+codeModal.selectLanguage.value)
	})

	codeModal.element.addEventListener("positive-pressed", function(event){
		editor.focus()
		var selection = editor.getSelection()
		editor.insertText(selection.end, codeEditor.getValue(), "code", codeModal.selectLanguage.value)
	})

	codeModal.element.addEventListener("hide", function(event){
		codeEditor.getSession().setMode("ace/mode/plain_text")
		codeModal.selectLanguage.selectedIndex = "0"
		codeEditor.setValue("")
	})

	tagsInput.addEventListener("focus", function(event){
		var div = document.getElementById("tag-input-div")
		div.classList.add("focused")
	})
	tagsInput.addEventListener("blur", function(event){
		var div = document.getElementById("tag-input-div")
		div.classList.remove("focused")
	})

	form.addEventListener("submit", function(event){
		if (editor.getText().trim().length == 0) {
			validityInput.setCustomValidity("Please fill out a post body.")
			event.preventDefault()
		}
		else {
			postBodyInput.value = editor.getHTML()
			placeholderTagsInput.value = tagsInputPlugin.value()
		}
	})

})

<commit_msg>Focus on ace on modal open<commit_after>document.addEventListener("DOMContentLoaded", function(event){
	var editorDiv = document.getElementById("editor")
	var editor = new Quill(editorDiv)
	var codeEditor = ace.edit("code-editor")
	var postBodyInput = document.getElementById("post-body")
	var validityInput = document.getElementById("post-validity")
	var tagsInput = document.getElementById("tags-input")
	var placeholderTagsInput = document.getElementById("placeholder-tags-input")
	var tagsInputPlugin = insignia(tagsInput)
	var form = document.getElementById("post-form")
	var linkButton = document.getElementById("add-link")
	var imageButton = document.getElementById("add-image")
	var quoteButton = document.getElementById("add-quote")
	var codeButton = document.getElementById("add-code")
	var alignLeftButton = document.getElementById("align-left")
	var alignCenterButton = document.getElementById("align-center")
	var alignRightButton = document.getElementById("align-right")
	var alignJustifyButton = document.getElementById("align-justify")

	var linkModal = {
		element: document.getElementById("link-modal"),
		input: document.getElementById("modal-link"),
		init: function() { //We needt o access some objects within this obect upon initialization, so we use this function to do that.
			this.modal = new Modal(this.element)
			this.errorDiv = this.element.querySelector("div.modal-error")
			delete this.init
			return this
		}
	}.init()

	var imageModal = {
		element: document.getElementById("image-modal"),
		linkInput: document.getElementById("image-url"),
		fileInput: document.getElementById("image-upload"),
		uploadRequest: null, //This will be defined when an image is being uploaded. This is a global variable so it can be cancelled.
		init: function(){ //We need to access some objects within this object upon initializaton, so we use this function to do that.
			this.modal = new Modal(this.element)
			this.positiveButton = this.element.querySelector("button.positive") //We need to do some styling with this button, so it's better to find it now rather than later.
			this.errorDiv = this.element.querySelector("div.modal-error")
			delete this.init
			return this
		},
	}.init()

	var codeModal = {
		element: document.getElementById("code-modal"),
		selectLanguage: document.getElementById("select-language"),
		init: function() { //We need to access some objects within this object upon initializatoin, so we use this function to do that.
			this.modal = new Modal(this.element, {keyboard: false})
			delete this.init
			return this
		}
	}.init()

	editor.addModule("toolbar", {container: "div#toolbar"})
	editor.addFormat("quote", {"class": "quote"})
	editor.addFormat("code", {"class": "code-"})

	codeEditor.getSession().setUseWorker(false)

	editor.on("selection-change", function(range){
		if (range == null){
			editorDiv.classList.remove("focused")
			quoteButton.disabled = true
		}

		else {
			editorDiv.classList.add("focused")
			if (range.end - range.start > 0){
				quoteButton.disabled = false
			}
			else {
				quoteButton.disabled = true
			}
		}
	})

	linkButton.addEventListener("click", function(event){
		linkModal.modal.show()
		linkModal.input.focus()
	})

	imageButton.addEventListener("click", function(event){
		imageModal.modal.show()
	})

	codeButton.addEventListener("click", function(event){
		codeModal.modal.show()
	})

	alignLeftButton.addEventListener("click", function(event){
		editor.focus()
		var selection = editor.getSelection()
		if (selection != null){
			editor.formatLine(selection.start, selection.end, "align", "left")
		}
	})

	alignCenterButton.addEventListener("click", function(event){
		editor.focus()
		var selection = editor.getSelection()
		if (selection != null){
			editor.formatLine(selection.start, selection.end, "align", "center")
		}
	})

	alignRightButton.addEventListener("click", function(event){
		editor.focus()
		var selection = editor.getSelection()
		if (selection != null){
			editor.formatLine(selection.start, selection.end, "align", "right")
		}
	})

	alignJustifyButton.addEventListener("click", function(event){
		editor.focus()
		var selection = editor.getSelection()
		if (selection != null){
			editor.formatText(selection.start, selection.end+1, "align", "justify")
		}
	})

	linkModal.element.addEventListener("positive-pressed", function(event){
		if (linkModal.input.value.trim().length === 0) {
			linkModal.errorDiv.classList.add("active")
			event.preventDefault()
		}
		else {
			editor.focus()
			var selection = editor.getSelection()
			editor.setSelection(null)
			//This basically indicates that we don't actually have a selection.
			if (selection.end - selection.start === 0){
				editor.insertText(selection.start, linkModal.input.value, "link", linkModal.input.value)
			}
			else {
				editor.formatText(selection.start, selection.end, "link", linkModal.input.value)
			}
		}
	})

	linkModal.element.addEventListener("hide", function(event){
		linkModal.input.value = ""
		linkModal.errorDiv.classList.remove("active")
	})

	imageModal.linkInput.addEventListener("input", function(event){
		imageModal.fileInput.disabled = true
	})

	imageModal.fileInput.addEventListener("change", function(event){
		imageModal.linkInput.disabled = true
	})

	imageModal.element.addEventListener("positive-pressed", function(event){
		if (!imageModal.linkInput.disabled && imageModal.linkInput.value.length > 0) {
			editor.focus()
			var selection = editor.getSelection()
			editor.insertEmbed(selection.end, "image", imageModal.linkInput.value)
		}
		else if (!imageModal.fileInput.disabled && imageModal.fileInput.value.length > 0) {
			event.preventDefault() //We're gonna need to do this on our own.
			imageModal.uploadRequest = new XMLHttpRequest()
			var formData = new FormData()
			formData.append("image", imageModal.fileInput.files[0])
			imageModal.uploadRequest.open("POST", "/upload_image")

			imageModal.uploadRequest.onload = function(){
				console.log("hm")
				var data = JSON.parse(imageModal.uploadRequest.responseText)
				if (data.error == 0) {
					editor.focus()
					var selection = editor.getSelection()
					editor.insertEmbed(selection.end, "image", data.url)
					imageModal.modal.hide()
				}

				else if (data.error == 2){
					imageModal.errorDiv.textContent = "Image must be a JPG, PNG, or GIF."
					imageModal.errorDiv.classList.add("active")
					imageModal.positiveButton.classList.remove("uploading")
					imageModal.positiveButton.disabled = false
				}

				imageModal.uploadRequest = null
			}

			imageModal.uploadRequest.send(formData)
			imageModal.positiveButton.classList.add("uploading")
			imageModal.positiveButton.disabled = true
		}
	})

	imageModal.element.addEventListener("hide", function(event){
		imageModal.linkInput.disabled = false
		imageModal.linkInput.value = ""
		imageModal.fileInput.disabled = false
		imageModal.fileInput.value = null
		imageModal.positiveButton.classList.remove("uploading")
		imageModal.positiveButton.disabled = false
		imageModal.errorDiv.classList.remove("active")
		if (imageModal.uploadRequest != null) {
			imageModal.uploadRequest.abort()
		}
	})

	codeModal.element.addEventListener("show", function(event){
		editor.setSelection(null)
		codeEditor.focus()
	})

	codeModal.selectLanguage.addEventListener("change", function(event){
		console.log("ace/mode/"+codeModal.selectLanguage.value)
		codeEditor.getSession().setMode("ace/mode/"+codeModal.selectLanguage.value)
	})

	codeModal.element.addEventListener("positive-pressed", function(event){
		editor.focus()
		var selection = editor.getSelection()
		edtor.setSelection(null)
		editor.insertText(selection.end, codeEditor.getValue(), "code", codeModal.selectLanguage.value)
	})

	codeModal.element.addEventListener("hide", function(event){
		codeEditor.getSession().setMode("ace/mode/plain_text")
		codeModal.selectLanguage.selectedIndex = "0"
		codeEditor.setValue("")
	})

	tagsInput.addEventListener("focus", function(event){
		var div = document.getElementById("tag-input-div")
		div.classList.add("focused")
	})
	tagsInput.addEventListener("blur", function(event){
		var div = document.getElementById("tag-input-div")
		div.classList.remove("focused")
	})

	form.addEventListener("submit", function(event){
		if (editor.getText().trim().length == 0) {
			validityInput.setCustomValidity("Please fill out a post body.")
			event.preventDefault()
		}
		else {
			postBodyInput.value = editor.getHTML()
			placeholderTagsInput.value = tagsInputPlugin.value()
		}
	})

})

<|endoftext|>


<commit_before>function onCalling(){

var client = '353317309491-vkamti6jshvv4l1ucp3i6jbs1rn7mthm.apps.googleusercontent.com';
gapi.load('client:auth2', initClient);
/**
 *  Initializes the API client library and sets up sign-in state
 *  listeners.
 */
function initClient() {
  gapi.client.init({
    discoveryDocs: DISCOVERY_DOCS,
    clientId: CLIENT_ID,
    scope: SCOPES
  });
}
var event = {
  'summary': 'Google I/O 2015',
  'location': '800 Howard St., San Francisco, CA 94103',
  'description': 'A chance to hear more about Google\'s developer products.',
  'start': {
    'dateTime': '2017-11-01T09:00:00-07:00',
    'timeZone': 'America/Los_Angeles'
  },
  'end': {
    'dateTime': '2017-11-01T17:00:00-07:00',
    'timeZone': 'America/Los_Angeles'
  },
  'recurrence': [
    'RRULE:FREQ=DAILY;COUNT=2'
  ],
  'attendees': [
    {'email': 'lpage@example.com'},
    {'email': 'sbrin@example.com'}
  ],
  'reminders': {
    'useDefault': false,
    'overrides': [
      {'method': 'email', 'minutes': 24 * 60},
      {'method': 'popup', 'minutes': 10}
    ]
  }
};
alert("Before the request!");
var request = gapi.client.calendar.events.insert({

  'calendarId': 'primary',
  'resource': event
});
alert("after the request is aasigned request is:"+request);
request.execute(function(event) {
  alert("we are trying to add event here");
  appendPre('Event created: ' + event.htmlLink);
});
}
<commit_msg>just for update<commit_after>function onCalling(){

var client = '353317309491-vkamti6jshvv4l1ucp3i6jbs1rn7mthm.apps.googleusercontent.com';
// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"];

// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = "https://www.googleapis.com/auth/calendar.readonly";
gapi.load('client:auth2', initClient);
/**
 *  Initializes the API client library and sets up sign-in state
 *  listeners.
 */
function initClient() {
  gapi.client.init({
    discoveryDocs: DISCOVERY_DOCS,
    clientId: CLIENT_ID,
    scope: SCOPES
  });
}
var event = {
  'summary': 'Google I/O 2015',
  'location': '800 Howard St., San Francisco, CA 94103',
  'description': 'A chance to hear more about Google\'s developer products.',
  'start': {
    'dateTime': '2017-11-01T09:00:00-07:00',
    'timeZone': 'America/Los_Angeles'
  },
  'end': {
    'dateTime': '2017-11-01T17:00:00-07:00',
    'timeZone': 'America/Los_Angeles'
  },
  'recurrence': [
    'RRULE:FREQ=DAILY;COUNT=2'
  ],
  'attendees': [
    {'email': 'lpage@example.com'},
    {'email': 'sbrin@example.com'}
  ],
  'reminders': {
    'useDefault': false,
    'overrides': [
      {'method': 'email', 'minutes': 24 * 60},
      {'method': 'popup', 'minutes': 10}
    ]
  }
};
alert("Before the request!");
var request = gapi.client.calendar.events.insert({

  'calendarId': 'primary',
  'resource': event
});
alert("after the request is aasigned request is:"+request);
request.execute(function(event) {
  alert("we are trying to add event here");
  appendPre('Event created: ' + event.htmlLink);
});
}
<|endoftext|>


<commit_before>angular.module("consolio", ['consAuth', 'consAlert']).
    filter('calDate', function() {
        return function(dstr) {
            return moment(dstr).calendar();
        };
    }).
    config(['$routeProvider', '$locationProvider',
            function($routeProvider, $locationProvider) {
                $routeProvider.
                    when('/index/', {templateUrl: '/static/partials/index.html',
                                     controller: 'ConsolioCtrl'}).
                    when('/db/:name/', {templateUrl: '/static/partials/db.html',
                                        controller: 'DBCtrl'}).
                    when('/admin/', {templateUrl: '/static/partials/admin.html',
                                     controller: 'AdminCtrl'}).
                    otherwise({redirectTo: '/index/'});
                $locationProvider.html5Mode(true);
                $locationProvider.hashPrefix('!');
            }]);

function ConsolioCtrl($scope, $http, $rootScope, consAuth, bAlert) {
    $rootScope.$watch('loggedin', function() { $scope.auth = consAuth.get(); });

    $http.get("/api/me/").success(function(me) { $scope.me = me; });

    $scope.databases = [];
    $http.get("/api/database/").success(function(databases) {
        $scope.databases = databases;
    });

    $scope.newbucket = "";

    $scope.newdb = function() {
        var dbname = $("#newbucketname").val();
        var password = $("#newbucketpass").val();
        $http.post('/api/database/',
                   'name=' + encodeURIComponent(dbname) +
                   '&password=' + encodeURIComponent(password),
                   {headers: {"Content-Type": "application/x-www-form-urlencoded"}})
            .error(function(data, code) {
                bAlert("Error " + code, "Couldn't create " + dbname +
                       ": " + data, "error");
            })
            .success(function(data) {
                $("#newbucketname").val("");
                $("#newbucketpass").val("");
                if ((!$scope.databases) || $scope.databases.length == 0) {
                    $scope.databases = [data];
                }
            });
    };
}

function DBCtrl($scope, $http, $routeParams, $rootScope, $location, consAuth, bAlert) {
    $scope.dbname = $routeParams.name;
    var dburl = "/api/database/" + $scope.dbname + "/";
    $http.get(dburl)
        .success(function(data) {
            $scope.db = data;
        })
        .error(function(data, code) {
            bAlert("Error " + code, "Couldn't get DB: " + data, "error");
        });

    $scope.delete = function() {
        $http.delete(dburl)
            .success(function(data) {
                $location.path("/index/");
            })
            .error(function(data, code) {
                bAlert("Error " + code, "Couldn't delete DB: " + data, "error");
            });
    };
}

function AdminCtrl($scope, $http, $rootScope, $location, bAlert) {
    $http.get("/api/me/")
        .success(function(data) {
            $scope.me = data;
        })
        .error(function(data, error) {
            $location.path("/index/");
        });

    $scope.webhooks = [];
    $http.get("/api/webhook/")
        .success(function(data) {
            $scope.webhooks = data;
        })
        .error(function(data, error) {
            bAlert("Error " + code, "Couldn't get webhooks: " + data, "error");
        });

    $scope.add = function() {
        var n = $("#newhookname").val();
        var u = $("#newhookurl").val();
        $http.post("/api/webhook/",
                   'name=' + encodeURIComponent(n) +
                   '&url=' + encodeURIComponent(u),
                   {headers: {"Content-Type": "application/x-www-form-urlencoded"}})
            .success(function(data) {
                $("#newhookname").val("");
                $("#newhookurl").val("");
                $scope.webhooks.push(data);
            })
            .error(function(data, code) {
                bAlert("Error " + code, "Couldn't create webhook: " + data, "error");
            });
    };

    $scope.delete = function(n) {
        $http.delete("/api/webhook/" + encodeURIComponent(n) + "/")
            .success(function(data) {
                $scope.webhooks = _.filter($scope.webhooks, function(e) {
                    return e.name !== n;
                });
            })
            .error(function(data, code) {
                bAlert("Error " + code, "Couldn't delete webhook: " + data, "error");
            });
    };
}

function LoginCtrl($scope, $http, $rootScope, consAuth) {
    $rootScope.$watch('loggedin', function() { $scope.auth = consAuth.get(); });
    $http.get("/api/me/").success(function(me) { $scope.me = me; });

    $scope.logout = consAuth.logout;
    $scope.login = consAuth.login;
}
<commit_msg>Javascript arrays + angular = weirdness.<commit_after>angular.module("consolio", ['consAuth', 'consAlert']).
    filter('calDate', function() {
        return function(dstr) {
            return moment(dstr).calendar();
        };
    }).
    config(['$routeProvider', '$locationProvider',
            function($routeProvider, $locationProvider) {
                $routeProvider.
                    when('/index/', {templateUrl: '/static/partials/index.html',
                                     controller: 'ConsolioCtrl'}).
                    when('/db/:name/', {templateUrl: '/static/partials/db.html',
                                        controller: 'DBCtrl'}).
                    when('/admin/', {templateUrl: '/static/partials/admin.html',
                                     controller: 'AdminCtrl'}).
                    otherwise({redirectTo: '/index/'});
                $locationProvider.html5Mode(true);
                $locationProvider.hashPrefix('!');
            }]);

function ConsolioCtrl($scope, $http, $rootScope, consAuth, bAlert) {
    $rootScope.$watch('loggedin', function() { $scope.auth = consAuth.get(); });

    $http.get("/api/me/").success(function(me) { $scope.me = me; });

    $scope.databases = [];
    $http.get("/api/database/").success(function(databases) {
        $scope.databases = databases;
    });

    $scope.newbucket = "";

    $scope.newdb = function() {
        var dbname = $("#newbucketname").val();
        var password = $("#newbucketpass").val();
        $http.post('/api/database/',
                   'name=' + encodeURIComponent(dbname) +
                   '&password=' + encodeURIComponent(password),
                   {headers: {"Content-Type": "application/x-www-form-urlencoded"}})
            .error(function(data, code) {
                bAlert("Error " + code, "Couldn't create " + dbname +
                       ": " + data, "error");
            })
            .success(function(data) {
                $("#newbucketname").val("");
                $("#newbucketpass").val("");
                var tmp = $scope.databases.slice(0);
                tmp.push(data);
                $scope.databases = tmp;
            });
    };
}

function DBCtrl($scope, $http, $routeParams, $rootScope, $location, consAuth, bAlert) {
    $scope.dbname = $routeParams.name;
    var dburl = "/api/database/" + $scope.dbname + "/";
    $http.get(dburl)
        .success(function(data) {
            $scope.db = data;
        })
        .error(function(data, code) {
            bAlert("Error " + code, "Couldn't get DB: " + data, "error");
        });

    $scope.delete = function() {
        $http.delete(dburl)
            .success(function(data) {
                $location.path("/index/");
            })
            .error(function(data, code) {
                bAlert("Error " + code, "Couldn't delete DB: " + data, "error");
            });
    };
}

function AdminCtrl($scope, $http, $rootScope, $location, bAlert) {
    $http.get("/api/me/")
        .success(function(data) {
            $scope.me = data;
        })
        .error(function(data, error) {
            $location.path("/index/");
        });

    $scope.webhooks = [];
    $http.get("/api/webhook/")
        .success(function(data) {
            $scope.webhooks = data;
        })
        .error(function(data, error) {
            bAlert("Error " + code, "Couldn't get webhooks: " + data, "error");
        });

    $scope.add = function() {
        var n = $("#newhookname").val();
        var u = $("#newhookurl").val();
        $http.post("/api/webhook/",
                   'name=' + encodeURIComponent(n) +
                   '&url=' + encodeURIComponent(u),
                   {headers: {"Content-Type": "application/x-www-form-urlencoded"}})
            .success(function(data) {
                $("#newhookname").val("");
                $("#newhookurl").val("");
                $scope.webhooks.push(data);
            })
            .error(function(data, code) {
                bAlert("Error " + code, "Couldn't create webhook: " + data, "error");
            });
    };

    $scope.delete = function(n) {
        $http.delete("/api/webhook/" + encodeURIComponent(n) + "/")
            .success(function(data) {
                $scope.webhooks = _.filter($scope.webhooks, function(e) {
                    return e.name !== n;
                });
            })
            .error(function(data, code) {
                bAlert("Error " + code, "Couldn't delete webhook: " + data, "error");
            });
    };
}

function LoginCtrl($scope, $http, $rootScope, consAuth) {
    $rootScope.$watch('loggedin', function() { $scope.auth = consAuth.get(); });
    $http.get("/api/me/").success(function(me) { $scope.me = me; });

    $scope.logout = consAuth.logout;
    $scope.login = consAuth.login;
}
<|endoftext|>