<commit_before>'use strict';

describe('unit tests for module ng.django.forms', function() {
	function compileForm($compile, scope, replace_value) {
		var template =
			'<form name="valid_form" action=".">' +
			'<input name="email_field" ng-model="model.email" type="text" {value} />' +
			'</form>';
		var form = angular.element(template.replace('{value}', replace_value));
		$compile(form)(scope);
		scope.$digest();
	}

	describe('test default form behavior', function() {
		var scope;

		beforeEach(inject(function($rootScope) {
			scope = $rootScope.$new();
		}));

		describe('on unbound forms', function() {
			it('the view value of empty input fields should remain undefined', inject(function($compile) {
				compileForm($compile, scope, '');
				expect(scope.valid_form.email_field.$viewValue).toBe(undefined);
			}));
		});

		describe('on bound forms', function() {
			it('the view value of filled input fields should remain undefined', inject(function($compile) {
				compileForm($compile, scope, 'value="john@example.net"');
				expect(scope.valid_form.email_field.$viewValue).toBe(undefined);
			}));
		});
	});

	describe('test overridden form behavior', function() {
		var scope;

		beforeEach(function() {
			// djangular's 'form' directive, overrides the behavior of the view value.
			module('ng.django.forms');
		});

		beforeEach(inject(function($rootScope) {
			scope = $rootScope.$new();
		}));

		describe('on unbound forms', function() {
			it('the view value of empty input fields should be empty', inject(function($compile) {
				compileForm($compile, scope, '');
				expect(scope.valid_form.email_field.$viewValue).toBe('');
			}));
		});

		describe('on bound forms', function() {
			it('the view value of filled input fields should remain as is', inject(function($compile) {
				compileForm($compile, scope, 'value="john@example.net"');
				expect(scope.valid_form.email_field.$viewValue).toBe('john@example.net');
			}));
		});

	});

	describe('test directive validateDate', function() {
		var scope, form;

		beforeEach(function() {
			// djangular's 'form' directive, overrides the behavior of the view value.
			module('ng.django.forms');
		});

		beforeEach(inject(function($rootScope) {
			scope = $rootScope.$new();
		}));

		beforeEach(inject(function($compile) {
			var doc =
				'<form name="form">' +
				'<input name="date_field" ng-model="model.date" type="text" validate-date="^(\\d{4})-(\\d{1,2})-(\\d{1,2})$" />' +
				'</form>';
			var element = angular.element(doc);
			scope.model = { date: null };
			$compile(element)(scope);
			form = scope.form;
		}));

		it('to reject 2014/04/01', function() {
			form.date_field.$setViewValue('2014/04/01');
			scope.$digest();
			expect(form.date_field.$valid).toBe(false);
		});

		it('to accept 2014-04-01', function() {
			form.date_field.$setViewValue('2014-03-01');
			scope.$digest();
			expect(form.date_field.$valid).toBe(true);
		});

		it('to reject 2014-04-31', function() {
			form.date_field.$setViewValue('2014-02-29');
			scope.$digest();
			expect(form.date_field.$valid).toBe(false);
		});
	});

	describe('test provider djangoForm', function() {
		var scope, djangoForm;

		beforeEach(function() {
			module('ng.django.forms');
		});

		describe('using manual instantiation', function() {
			beforeEach(function() {
				angular.module('testApp', function() {}).config(function(djangoFormProvider) {
					djangoForm = djangoFormProvider.$get();
				});
				module('ng.django.forms', 'testApp');
			});

			beforeEach(inject(function($rootScope) {
				scope = $rootScope.$new();
			}));

			beforeEach(inject(function($compile) {
				var form = angular.element(
					'<form name="form" action=".">' +
					'<input name="email_field" ng-model="model.email" type="text" />' +
					'</form>'
				);
				$compile(form)(scope);
				scope.$digest();
			}));

			it('should give a valid form', function() {
				expect(djangoForm.setErrors(scope.form, {})).toBe(false);
				expect(scope.form.email_field.$valid).toBe(true);
			});

			it('should give an invalid form', function() {
				var errors = { email_field: ['A server side error occurred'] };
				expect(djangoForm.setErrors(scope.form, errors)).toBe(true);
				expect(scope.form.email_field.$valid).toBe(false);
			});

		});
	});

	describe('test provider djangoRMI', function() {
		var $httpBackend, djangoRMI;

		beforeEach(function() {
			module('ng.django.forms');
		});

		describe('emulating get_current_remote_methods', function() {
			beforeEach(function() {
				angular.module('testApp', function() {}).config(function(djangoRMIProvider) {
					djangoRMIProvider.configure({"foo": {"url": "/straight_methods/", "headers": {"DjNg-Remote-Method": "foo"}, "method": "auto"}, "bar": {"url": "/straight_methods/", "headers": {"DjNg-Remote-Method": "bar"}, "method": "auto"}});
				});
				module('ng.django.forms', 'testApp');
			});

			beforeEach(inject(function($injector) {
				$httpBackend = $injector.get('$httpBackend');
			}));

			it('should call View method foo using GET', inject(function(djangoRMI) {
				$httpBackend.when('GET', '/straight_methods/').respond(200, {success: true});
				djangoRMI.foo().success(function(data) {
					expect(data.success).toBe(true);
				});
				$httpBackend.flush();
			}));

			it('should call View method foo using POST', inject(function(djangoRMI) {
				$httpBackend.when('POST', '/straight_methods/').respond(200, {yeah: 'success'});
				djangoRMI.foo({some: 'data'}).success(function(data) {
					expect(data.yeah).toBe('success');
				});
				$httpBackend.flush();
			}));
		});

		describe('emulating get_all_remote_methods', function() {
			beforeEach(function() {
				angular.module('testApp', function() {}).config(function(djangoRMIProvider) {
					djangoRMIProvider.configure({"submethods": {"sub": {"app": {"foo": {"url": "/sub_methods/sub/app/", "headers": {"DjNg-Remote-Method": "foo"}, "method": "auto"}, "bar": {"url": "/sub_methods/sub/app/", "headers": {"DjNg-Remote-Method": "bar"}, "method": "auto"}}}}, "straightmethods": {"foo": {"url": "/straight_methods/", "headers": {"DjNg-Remote-Method": "foo"}, "method": "auto"}, "bar": {"url": "/straight_methods/", "headers": {"DjNg-Remote-Method": "bar"}, "method": "auto"}}});
				});
				module('ng.django.forms', 'testApp');
			});

			beforeEach(inject(function($injector) {
				$httpBackend = $injector.get('$httpBackend');
			}));

			it('should call View method foo using GET', inject(function(djangoRMI) {
				$httpBackend.when('GET', '/sub_methods/sub/app/').respond(200, {foo: null});
				djangoRMI.submethods.sub.app.foo().success(function(data) {
					expect(data.foo).toBe(null);
				});
				$httpBackend.flush();
			}));

			it('should call View method bar using GET', inject(function(djangoRMI) {
				$httpBackend.when('GET', '/sub_methods/sub/app/').respond(200, {bar: 'nothing'});
				djangoRMI.submethods.sub.app.bar().success(function(data) {
					expect(data.bar).toBe('nothing');
				});
				$httpBackend.flush();
			}));

			it('should call View method foo using POST', inject(function(djangoRMI) {
				$httpBackend.when('POST', '/sub_methods/sub/app/').respond(200, {foo: 'some data'});
				djangoRMI.submethods.sub.app.foo({some: 'data'}).success(function(data) {
					expect(data.foo).toBe('some data');
				});
				$httpBackend.flush();
			}));

			it('should call View method bar using POST', inject(function(djangoRMI) {
				$httpBackend.when('POST', '/sub_methods/sub/app/').respond(200, {bar: 'other data'});
				djangoRMI.submethods.sub.app.bar({other: 'data'}).success(function(data) {
					expect(data.bar).toBe('other data');
				});
				$httpBackend.flush();
			}));
		});
	});
});
<commit_msg><input> fields with no value have undefined values<commit_after>'use strict';

describe('unit tests for module ng.django.forms', function() {
	function compileForm($compile, scope, replace_value) {
		var template =
			'<form name="valid_form" action=".">' +
			'<input name="email_field" ng-model="model.email" type="text" {value} />' +
			'</form>';
		var form = angular.element(template.replace('{value}', replace_value));
		$compile(form)(scope);
		scope.$digest();
	}

	describe('test default form behavior', function() {
		var scope;

		beforeEach(inject(function($rootScope) {
			scope = $rootScope.$new();
		}));

		describe('on unbound forms', function() {
			it('the view value of empty input fields should remain undefined', inject(function($compile) {
				compileForm($compile, scope, '');
				expect(scope.valid_form.email_field.$viewValue).toBe(undefined);
			}));
		});

		describe('on bound forms', function() {
			it('the view value of filled input fields should remain undefined', inject(function($compile) {
				compileForm($compile, scope, 'value="john@example.net"');
				expect(scope.valid_form.email_field.$viewValue).toBe(undefined);
			}));
		});
	});

	describe('test overridden form behavior', function() {
		var scope;

		beforeEach(function() {
			// djangular's 'form' directive, overrides the behavior of the view value.
			module('ng.django.forms');
		});

		beforeEach(inject(function($rootScope) {
			scope = $rootScope.$new();
		}));

		describe('on unbound forms', function() {
			it('the view value of empty input fields should be empty', inject(function($compile) {
				compileForm($compile, scope, '');
				expect(scope.valid_form.email_field.$viewValue).toBe(undefined);
			}));
		});

		describe('on bound forms', function() {
			it('the view value of filled input fields should remain as is', inject(function($compile) {
				compileForm($compile, scope, 'value="john@example.net"');
				expect(scope.valid_form.email_field.$viewValue).toBe('john@example.net');
			}));
		});

	});

	describe('test directive validateDate', function() {
		var scope, form;

		beforeEach(function() {
			// djangular's 'form' directive, overrides the behavior of the view value.
			module('ng.django.forms');
		});

		beforeEach(inject(function($rootScope) {
			scope = $rootScope.$new();
		}));

		beforeEach(inject(function($compile) {
			var doc =
				'<form name="form">' +
				'<input name="date_field" ng-model="model.date" type="text" validate-date="^(\\d{4})-(\\d{1,2})-(\\d{1,2})$" />' +
				'</form>';
			var element = angular.element(doc);
			scope.model = { date: null };
			$compile(element)(scope);
			form = scope.form;
		}));

		it('to reject 2014/04/01', function() {
			form.date_field.$setViewValue('2014/04/01');
			scope.$digest();
			expect(form.date_field.$valid).toBe(false);
		});

		it('to accept 2014-04-01', function() {
			form.date_field.$setViewValue('2014-03-01');
			scope.$digest();
			expect(form.date_field.$valid).toBe(true);
		});

		it('to reject 2014-04-31', function() {
			form.date_field.$setViewValue('2014-02-29');
			scope.$digest();
			expect(form.date_field.$valid).toBe(false);
		});
	});

	describe('test provider djangoForm', function() {
		var scope, djangoForm;

		beforeEach(function() {
			module('ng.django.forms');
		});

		describe('using manual instantiation', function() {
			beforeEach(function() {
				angular.module('testApp', function() {}).config(function(djangoFormProvider) {
					djangoForm = djangoFormProvider.$get();
				});
				module('ng.django.forms', 'testApp');
			});

			beforeEach(inject(function($rootScope) {
				scope = $rootScope.$new();
			}));

			beforeEach(inject(function($compile) {
				var form = angular.element(
					'<form name="form" action=".">' +
					'<input name="email_field" ng-model="model.email" type="text" />' +
					'</form>'
				);
				$compile(form)(scope);
				scope.$digest();
			}));

			it('should give a valid form', function() {
				expect(djangoForm.setErrors(scope.form, {})).toBe(false);
				expect(scope.form.email_field.$valid).toBe(true);
			});

			it('should give an invalid form', function() {
				var errors = { email_field: ['A server side error occurred'] };
				expect(djangoForm.setErrors(scope.form, errors)).toBe(true);
				expect(scope.form.email_field.$valid).toBe(false);
			});

		});
	});

	describe('test provider djangoRMI', function() {
		var $httpBackend, djangoRMI;

		beforeEach(function() {
			module('ng.django.forms');
		});

		describe('emulating get_current_remote_methods', function() {
			beforeEach(function() {
				angular.module('testApp', function() {}).config(function(djangoRMIProvider) {
					djangoRMIProvider.configure({"foo": {"url": "/straight_methods/", "headers": {"DjNg-Remote-Method": "foo"}, "method": "auto"}, "bar": {"url": "/straight_methods/", "headers": {"DjNg-Remote-Method": "bar"}, "method": "auto"}});
				});
				module('ng.django.forms', 'testApp');
			});

			beforeEach(inject(function($injector) {
				$httpBackend = $injector.get('$httpBackend');
			}));

			it('should call View method foo using GET', inject(function(djangoRMI) {
				$httpBackend.when('GET', '/straight_methods/').respond(200, {success: true});
				djangoRMI.foo().success(function(data) {
					expect(data.success).toBe(true);
				});
				$httpBackend.flush();
			}));

			it('should call View method foo using POST', inject(function(djangoRMI) {
				$httpBackend.when('POST', '/straight_methods/').respond(200, {yeah: 'success'});
				djangoRMI.foo({some: 'data'}).success(function(data) {
					expect(data.yeah).toBe('success');
				});
				$httpBackend.flush();
			}));
		});

		describe('emulating get_all_remote_methods', function() {
			beforeEach(function() {
				angular.module('testApp', function() {}).config(function(djangoRMIProvider) {
					djangoRMIProvider.configure({"submethods": {"sub": {"app": {"foo": {"url": "/sub_methods/sub/app/", "headers": {"DjNg-Remote-Method": "foo"}, "method": "auto"}, "bar": {"url": "/sub_methods/sub/app/", "headers": {"DjNg-Remote-Method": "bar"}, "method": "auto"}}}}, "straightmethods": {"foo": {"url": "/straight_methods/", "headers": {"DjNg-Remote-Method": "foo"}, "method": "auto"}, "bar": {"url": "/straight_methods/", "headers": {"DjNg-Remote-Method": "bar"}, "method": "auto"}}});
				});
				module('ng.django.forms', 'testApp');
			});

			beforeEach(inject(function($injector) {
				$httpBackend = $injector.get('$httpBackend');
			}));

			it('should call View method foo using GET', inject(function(djangoRMI) {
				$httpBackend.when('GET', '/sub_methods/sub/app/').respond(200, {foo: null});
				djangoRMI.submethods.sub.app.foo().success(function(data) {
					expect(data.foo).toBe(null);
				});
				$httpBackend.flush();
			}));

			it('should call View method bar using GET', inject(function(djangoRMI) {
				$httpBackend.when('GET', '/sub_methods/sub/app/').respond(200, {bar: 'nothing'});
				djangoRMI.submethods.sub.app.bar().success(function(data) {
					expect(data.bar).toBe('nothing');
				});
				$httpBackend.flush();
			}));

			it('should call View method foo using POST', inject(function(djangoRMI) {
				$httpBackend.when('POST', '/sub_methods/sub/app/').respond(200, {foo: 'some data'});
				djangoRMI.submethods.sub.app.foo({some: 'data'}).success(function(data) {
					expect(data.foo).toBe('some data');
				});
				$httpBackend.flush();
			}));

			it('should call View method bar using POST', inject(function(djangoRMI) {
				$httpBackend.when('POST', '/sub_methods/sub/app/').respond(200, {bar: 'other data'});
				djangoRMI.submethods.sub.app.bar({other: 'data'}).success(function(data) {
					expect(data.bar).toBe('other data');
				});
				$httpBackend.flush();
			}));
		});
	});
});
<|endoftext|>


<commit_before>require('babel-core/polyfill');
var fs = require('fs');
var path = require('path');
var webpack = require('webpack');
var WebpackIsomorphicTools = require('webpack-isomorphic-tools');
var assetsPath = path.resolve(__dirname, '../static/dist');
var host = 'localhost';
var port = parseInt(process.env.PORT) + 1 || 3001;

// https://github.com/halt-hammerzeit/webpack-isomorphic-tools
var WebpackIsomorphicToolsPlugin = require('webpack-isomorphic-tools/plugin');
var webpackIsomorphicToolsPlugin = new WebpackIsomorphicToolsPlugin(require('./webpack-isomorphic-tools'));

var babelrc = fs.readFileSync('./.babelrc');
var babelrcObject = {};

try {
  babelrcObject = JSON.parse(babelrc);
} catch (err) {
  console.error('==>     ERROR: Error parsing your .babelrc.');
  console.error(err);
}

var babelrcObjectDevelopment = babelrcObject.env && babelrcObject.env.development || {};
var babelLoaderQuery = Object.assign({}, babelrcObject, babelrcObjectDevelopment);
delete babelLoaderQuery.env;

babelLoaderQuery.plugins = babelLoaderQuery.plugins || [];
if (babelLoaderQuery.plugins.indexOf('react-transform') < 0) {
  babelLoaderQuery.plugins.push('react-transform');
}

babelLoaderQuery.extra = babelLoaderQuery.extra || {};
if (!babelLoaderQuery.extra['react-transform']) {
  babelLoaderQuery.extra['react-transform'] = {};
}
if (!babelLoaderQuery.extra['react-transform'].transforms) {
  babelLoaderQuery.extra['react-transform'].transforms = [];
}
babelLoaderQuery.extra['react-transform'].transforms.push({
  transform: 'react-transform-hmr',
  imports: ['react'],
  locals: ['module']
});

module.exports = {
  devtool: 'inline-source-map',
  context: path.resolve(__dirname, '..'),
  entry: {
    'main': [
      'webpack-hot-middleware/client?path=http://' + host + ':' + port + '/__webpack_hmr',
      'bootstrap-sass!./src/theme/bootstrap.config.js',
      './src/client.js'
    ]
  },
  output: {
    path: assetsPath,
    filename: '[name]-[hash].js',
    chunkFilename: '[name]-[chunkhash].js',
    publicPath: 'http://' + host + ':' + port + '/dist/'
  },
  module: {
    loaders: [
      { test: /\.js$/, exclude: /node_modules/, loaders: ['babel?' + JSON.stringify(babelLoaderQuery), 'eslint-loader']},
      { test: /\.json$/, loader: 'json-loader' },
      { test: /\.less$/, loader: 'style!css?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]!autoprefixer?browsers=last 2 version!less?outputStyle=expanded&sourceMap' },
      { test: /\.scss$/, loader: 'style!css?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]!autoprefixer?browsers=last 2 version!sass?outputStyle=expanded&sourceMap' },
      { test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff" },
      { test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff" },
      { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/octet-stream" },
      { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file" },
      { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=image/svg+xml" },
      { test: webpackIsomorphicToolsPlugin.regular_expression('images'), loader: 'url-loader?limit=10240' }
    ]
  },
  progress: true,
  resolve: {
    modulesDirectories: [
      'src',
      'node_modules'
    ],
    extensions: ['', '.json', '.js']
  },
  plugins: [
    // hot reload
    new webpack.HotModuleReplacementPlugin(),
    new webpack.IgnorePlugin(/webpack-stats\.json$/),
    new webpack.DefinePlugin({
      __CLIENT__: true,
      __SERVER__: false,
      __DEVELOPMENT__: true,
      __DEVTOOLS__: true  // <-------- DISABLE redux-devtools HERE
    }),
    webpackIsomorphicToolsPlugin.development()
  ]
};
<commit_msg>Fixing css test 2<commit_after>require('babel-core/polyfill');
var fs = require('fs');
var path = require('path');
var webpack = require('webpack');
var WebpackIsomorphicTools = require('webpack-isomorphic-tools');
var assetsPath = path.resolve(__dirname, '../static/dist');
var host = 'localhost';
var port = parseInt(process.env.PORT) + 1 || 3001;

// https://github.com/halt-hammerzeit/webpack-isomorphic-tools
var WebpackIsomorphicToolsPlugin = require('webpack-isomorphic-tools/plugin');
var webpackIsomorphicToolsPlugin = new WebpackIsomorphicToolsPlugin(require('./webpack-isomorphic-tools'));

var babelrc = fs.readFileSync('./.babelrc');
var babelrcObject = {};

try {
  babelrcObject = JSON.parse(babelrc);
} catch (err) {
  console.error('==>     ERROR: Error parsing your .babelrc.');
  console.error(err);
}

var babelrcObjectDevelopment = babelrcObject.env && babelrcObject.env.development || {};
var babelLoaderQuery = Object.assign({}, babelrcObject, babelrcObjectDevelopment);
delete babelLoaderQuery.env;

babelLoaderQuery.plugins = babelLoaderQuery.plugins || [];
if (babelLoaderQuery.plugins.indexOf('react-transform') < 0) {
  babelLoaderQuery.plugins.push('react-transform');
}

babelLoaderQuery.extra = babelLoaderQuery.extra || {};
if (!babelLoaderQuery.extra['react-transform']) {
  babelLoaderQuery.extra['react-transform'] = {};
}
if (!babelLoaderQuery.extra['react-transform'].transforms) {
  babelLoaderQuery.extra['react-transform'].transforms = [];
}
babelLoaderQuery.extra['react-transform'].transforms.push({
  transform: 'react-transform-hmr',
  imports: ['react'],
  locals: ['module']
});

module.exports = {
  devtool: 'inline-source-map',
  context: path.resolve(__dirname, '..'),
  entry: {
    'main': [
      'webpack-hot-middleware/client?path=http://' + host + ':' + port + '/__webpack_hmr',
      'bootstrap-sass!./src/theme/bootstrap.config.js',
      './src/client.js'
    ]
  },
  output: {
    path: assetsPath,
    filename: '[name]-[hash].js',
    chunkFilename: '[name]-[chunkhash].js',
    publicPath: 'http://' + host + ':' + port + '/dist/'
  },
  module: {
    loaders: [
      { test: /\.js$/, exclude: /(node_modules|bootstrap-sass\.config)/, loaders: ['babel?' + JSON.stringify(babelLoaderQuery), 'eslint-loader']},
      { test: /\.json$/, loader: 'json-loader' },
      { test: /\.less$/, loader: 'style!css?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]!autoprefixer?browsers=last 2 version!less?outputStyle=expanded&sourceMap' },
      { test: /\.scss$/, loader: 'style!css?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]!autoprefixer?browsers=last 2 version!sass?outputStyle=expanded&sourceMap' },
      { test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff" },
      { test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff" },
      { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/octet-stream" },
      { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file" },
      { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=image/svg+xml" },
      { test: webpackIsomorphicToolsPlugin.regular_expression('images'), loader: 'url-loader?limit=10240' }
    ]
  },
  progress: true,
  resolve: {
    modulesDirectories: [
      'src',
      'node_modules'
    ],
    extensions: ['', '.json', '.js']
  },
  plugins: [
    // hot reload
    new webpack.HotModuleReplacementPlugin(),
    new webpack.IgnorePlugin(/webpack-stats\.json$/),
    new webpack.DefinePlugin({
      __CLIENT__: true,
      __SERVER__: false,
      __DEVELOPMENT__: true,
      __DEVTOOLS__: true  // <-------- DISABLE redux-devtools HERE
    }),
    webpackIsomorphicToolsPlugin.development()
  ]
};
<|endoftext|>


<commit_before>function MaterialsFilePicker() {
  this.selectedMaterials = {};
}

MaterialsFilePicker.prototype.pick = function(div) {
  var courseId = gon.course;
  var that = this;
  $.ajax({
    url: '/courses/' + courseId + '/materials.json',
    success: function(rootNode) { that.onWorkbinStructureReceived(rootNode); }
  });

  var htmlContent = '
\

Select Files
\

\

\

\

\

\
    <button id="#done-picking" data-dismiss="modal" class="btn btn-primary">\
      Done\
    </button>\
    <button data-dismiss="modal" class="btn">\
      Cancel\
    </button>\

';

  $(div).html(htmlContent);
  this.treeElement = $('#file-picker-tree', div);

  $("#done-picking").click(function() { that.onDone(); });
}

MaterialsFilePicker.prototype.onDone = function() {
  var selectedItems = [];
  for (var id in this.selectedMaterials) {
    var currentTuple = this.selectedMaterials[id];
    selectedItems.push(currentTuple);
  }

  this.onSelectionCompleted(selectedItems);
};

MaterialsFilePicker.prototype.onWorkbinStructureReceived = function(rootNode) {
  var shouldIncludeFiles = true;
  var treeData = parseFileJsonForJqTree(rootNode, shouldIncludeFiles);

  this.treeElement.tree({
    data: treeData,
    autoOpen: true,
    keyboardSupport: false
  });
};

MaterialsFilePicker.prototype.onNodeClicked = function(event) {
  // Disable single selection: click to select for everything.
  event.preventDefault();

  var selectedNode = event.node;
  var nodeId = selectedNode.id;

  var isNodeSelected = this.treeElement.tree('isNodeSelected', selectedNode);
  var isNodeAFile = nodeId.indexOf("file") !== -1;

  // We don't bother with folders - only individual files.
  if (isNodeAFile) {
    var indexAfterPrefix = nodeId.indexOf("_") + 1;
    var id = nodeId.slice(indexAfterPrefix);

    // <ID, Type, Name, URL>
    if (isNodeSelected) {
      this.treeElement.tree('removeFromSelection', selectedNode);

      var tuple = [id, "Material", selectedNode.label, selectedNode.url];
      this.selectedMaterials[id] = tuple;
    } else {
      this.treeElement.tree('addToSelection', selectedNode);
      delete this.selectedMaterials[id];
    }
  }
};<commit_msg>Fix incorrect IDs being used.<commit_after>function MaterialsFilePicker() {
  this.selectedMaterials = {};
}

MaterialsFilePicker.prototype.pick = function(div) {
  var courseId = gon.course;
  var that = this;
  $.ajax({
    url: '/courses/' + courseId + '/materials.json',
    success: function(rootNode) { that.onWorkbinStructureReceived(rootNode); }
  });

  var htmlContent = '
\

Select Files
\

\

\

\

\

\

\
      Done\

\
    <button data-dismiss="modal" class="btn">\
      Cancel\
    </button>\

';

  $(div).html(htmlContent);
  this.treeElement = $('#file-picker-tree', div);

  $("#done-picking").click(function() { that.onDone(); });
}

MaterialsFilePicker.prototype.onDone = function() {
  var selectedItems = [];
  for (var id in this.selectedMaterials) {
    var currentTuple = this.selectedMaterials[id];
    selectedItems.push(currentTuple);
  }

  this.onSelectionCompleted(selectedItems);
};

MaterialsFilePicker.prototype.onWorkbinStructureReceived = function(rootNode) {
  var shouldIncludeFiles = true;
  var treeData = parseFileJsonForJqTree(rootNode, shouldIncludeFiles);

  this.treeElement.tree({
    data: treeData,
    autoOpen: true,
    keyboardSupport: false
  });
};

MaterialsFilePicker.prototype.onNodeClicked = function(event) {
  // Disable single selection: click to select for everything.
  event.preventDefault();

  var selectedNode = event.node;
  var nodeId = selectedNode.id;

  var isNodeSelected = this.treeElement.tree('isNodeSelected', selectedNode);
  var isNodeAFile = nodeId.indexOf("file") !== -1;

  // We don't bother with folders - only individual files.
  if (isNodeAFile) {
    var indexAfterPrefix = nodeId.indexOf("_") + 1;
    var id = nodeId.slice(indexAfterPrefix);

    // <ID, Type, Name, URL>
    if (isNodeSelected) {
      this.treeElement.tree('removeFromSelection', selectedNode);

      var tuple = [id, "Material", selectedNode.label, selectedNode.url];
      this.selectedMaterials[id] = tuple;
    } else {
      this.treeElement.tree('addToSelection', selectedNode);
      delete this.selectedMaterials[id];
    }
  }
};<|endoftext|>


<commit_before>
'use strict';

/**
 * 定义首页控制器
 */
define(function(require, exports, module) {

    module.exports = function(app) {

        require('common/service/networkSvc');
        require('common/service/authenticationSvc');

        // auth为路由改变时的登陆标记
        app.register.controller('indexCtrl', function($scope, $http, $rootScope, networkSvc, $location, auth, authenticationSvc, $log, $modal) {

            // 服务端和客户端的双重校验
            // 每个页面加载前执行确认接口权限
            authenticationSvc.isLogin()
            .then(
            	// 安全路由确认客户端已经登陆，isLogin()确认服务器端登陆
            	function(){
            		// -------------混乱数据区-------------
            		$rootScope.title = "EasyGo";
            		$scope.uname = authenticationSvc.getUserInfo().uname;

                    // 顶部nav选项
                    $scope.navInitIndex = 0;
                    $scope.navs = [
                    	{'name' : $scope.uname,'index' : '0','param' : 'user'},
                        {'name' : '团队管理','index' : '1','param' : 'depart'},
                        {'name' : '申请管理','index' : '2','param' : 'apply'},
                        {'name' : '通知管理','index' : '3','param' : 'notice'},
                    ];
                    $scope.clickNavBtn = function(index){
                        $scope.navInitIndex = index;
                        console.log('nav ' + $scope.navInitIndex);
                    }

                    // 左边nav选项
                    $scope.snavInitIndex = 0;
                    $scope.snavs = [
                        {'name' : '团队管理','index' : '0','param' : 'depart'},
                        {'name' : '申请管理','index' : '1','param' : 'apply'},
                        {'name' : '通知管理','index' : '2','param' : 'notice'},
                    ];
                    $scope.clickSNavBtn = function(index){
                        $scope.snavInitIndex = index;
                        console.log('snav ' + $scope.snavInitIndex);
                    }

                    // tab切换
                    $scope.tabInitIndex = 0;
                    $scope._tabs = {
                    	'notice' : [{'name' : '未读通知','index' : '0','param' : 'unread'},
                        {'name' : '已读通知','index' : '1','param' : 'read'},
                        {'name' : '我的通知','index' : '2','param' : 'mine'}],

                    	'apply' : [{'name' : '未读申请','index' : '0','param' : 'unread'},
                        {'name' : '已读申请','index' : '1','param' : 'read'},
                        {'name' : '我的申请','index' : '2','param' : 'mine'}],

                    	'depart' : [{'name' : '未读部门','index' : '0','param' : 'unread'},
                        {'name' : '已读部门','index' : '1','param' : 'read'},
                        {'name' : '我的部门','index' : '2','param' : 'mine'}],
	                };

                    $scope.tabs = [
                        {'name' : '未读通知','index' : '0','param' : 'unread'},
                        {'name' : '已读通知','index' : '1','param' : 'read'},
                        {'name' : '我的通知','index' : '2','param' : 'mine'},
                    ];

                    $scope.userNavs = [
	                    {'name' : '1','index' : '0','param' : 'all'},
	                    {'name' : '2','index' : '1','param' : 'pending'},
	                    {'name' : '3','index' : '2','param' : 'unstart'}
                    ];
                    $scope.departNavs = [
	                    {'name' : '4','index' : '0','param' : 'all'},
	                    {'name' : '5','index' : '1','param' : 'pending'},
	                    {'name' : '6','index' : '2','param' : 'unstart'}
                    ];
                    $scope.applyNavs = [
	                    {'name' : '7','index' : '0','param' : 'all'},
	                    {'name' : '8','index' : '1','param' : 'pending'},
	                    {'name' : '9','index' : '2','param' : 'unstart'}
                    ];
                    $scope.noticeNavs = [
                    	{'name' : '未读','index' : '0','param' : 'all'},
                    	{'name' : '11','index' : '1','param' : 'pending'},
                    	{'name' : '12','index' : '2','param' : 'unstart'}
                    ];
                    $scope.clickTabBtn = function(index){
                        $scope.tabInitIndex = index;
                        console.log('tab ' + $scope.tabInitIndex);
                    }

            		// -------------混乱数据区-------------

            		// 页面加载请求数据
            		networkSvc.getList('notice')
            		.then(
            			// networkSvc.getList() resolve接口
            		    function(res){
            		        switch(res.data.code){
            		            case '-99':
            		                alert('请先登录');
            		                $location.path("/login");
            		                break;
            		            case '0':
            		                alert('失败了，程序猿在奋力为你解决');
            		                break;
            		            case '1':
                                    $scope.notice = res.data.data;
                                    $log.log($scope.notice);

                                    // http://mgcrea.github.io/angular-strap/
                                    // Show a basic modal from a controller
                                    var myModal = $modal({title: 'My Title', content: 'My Content', show: true});

            		                break;
            		            default:
            		                $scope.info = '失败了，程序猿在奋力为你解决';
            		                break;
            		        }
            		    },
            		    // networkSvc.getList() reject接口
            		    function(err){
                            alert('失败了，程序猿在奋力为你解决');
            		        $log.log(err);
            		    },
            		    // networkSvc.getList() notify接口
            		    function(proc){
            		        // loading
            		    }
            		);
            	},
            	// 客户端以及登陆而服务器端未登录
            	function(){
            		alert('请先登录');
            		$location.path("/login");
            	}
            );

			// 登出操作
			$scope.logout = function () {
			    authenticationSvc.logout()
		    	.then(
	    			// authenticationSvc.logout() resolve接口
	    		    function(res){
	    		        switch(res.data.code){
	    		            case '1':
	    		            	$location.path("/login");
	    		                break;
	    		            default:
		    		            alert('失败了，程序猿在奋力为你解决');
		    		            break;
	    		        }
	    		    },
	    		    // authenticationSvc.logout() reject接口
	    		    function(err){
                        alert('失败了，程序猿在奋力为你解决');
	    		        $log.log(err);
	    		    },
	    		    // authenticationSvc.logout() notify接口
	    		    function(proc){
	    		        // loading
	    		    }
		    	);
			}

        });
    }
});

<commit_msg>update index<commit_after>
'use strict';

/**
 * 定义首页控制器
 */
define(function(require, exports, module) {

    module.exports = function(app) {

        require('common/service/networkSvc');
        require('common/service/authenticationSvc');

        // auth为路由改变时的登陆标记
        app.register.controller('indexCtrl', function($scope, $http, $rootScope, networkSvc, $location, auth, authenticationSvc, $log, $modal) {

            // 服务端和客户端的双重校验
            // 每个页面加载前执行确认接口权限
            authenticationSvc.isLogin()
            .then(
            	// 安全路由确认客户端已经登陆，isLogin()确认服务器端登陆
            	function(){
            		// -------------混乱数据区-------------
            		$rootScope.title = "EasyGo";
            		$scope.uname = authenticationSvc.getUserInfo().uname;

                    // 顶部nav选项
                    $scope.navInitIndex = 0;
                    $scope.navs = [
                    	{'name' : $scope.uname,'index' : '0','param' : 'user'},
                        {'name' : '团队管理','index' : '1','param' : 'depart'},
                        {'name' : '申请管理','index' : '2','param' : 'apply'},
                        {'name' : '通知管理','index' : '3','param' : 'notice'},
                    ];
                    $scope.clickNavBtn = function(index){
                        $scope.navInitIndex = index;
                        console.log('nav ' + $scope.navInitIndex);
                    }

                    // 左边nav选项
                    $scope.snavInitIndex = 0;
                    $scope.snavs = [
                        {'name' : '团队管理','index' : '0','param' : 'depart'},
                        {'name' : '申请管理','index' : '1','param' : 'apply'},
                        {'name' : '通知管理','index' : '2','param' : 'notice'},
                    ];
                    $scope.clickSNavBtn = function(index){
                        $scope.snavInitIndex = index;
                        console.log('snav ' + $scope.snavInitIndex);
                    }

                    // tab切换
                    $scope.tabInitIndex = 0;
                    $scope._tabs = {
                    	'notice' : [{'name' : '未读通知','index' : '0','param' : 'unread'},
                        {'name' : '已读通知','index' : '1','param' : 'read'},
                        {'name' : '我的通知','index' : '2','param' : 'mine'}],

                    	'apply' : [{'name' : '未读申请','index' : '0','param' : 'unread'},
                        {'name' : '已读申请','index' : '1','param' : 'read'},
                        {'name' : '我的申请','index' : '2','param' : 'mine'}],

                    	'depart' : [{'name' : '未读部门','index' : '0','param' : 'unread'},
                        {'name' : '已读部门','index' : '1','param' : 'read'},
                        {'name' : '我的部门','index' : '2','param' : 'mine'}],
	                };

                    $scope.tabs = [
                        {'name' : '未读通知','index' : '0','param' : 'unread'},
                        {'name' : '已读通知','index' : '1','param' : 'read'},
                        {'name' : '我的通知','index' : '2','param' : 'mine'},
                    ];

                    $scope.userNavs = [
	                    {'name' : '1','index' : '0','param' : 'all'},
	                    {'name' : '2','index' : '1','param' : 'pending'},
	                    {'name' : '3','index' : '2','param' : 'unstart'}
                    ];
                    $scope.departNavs = [
	                    {'name' : '4','index' : '0','param' : 'all'},
	                    {'name' : '5','index' : '1','param' : 'pending'},
	                    {'name' : '6','index' : '2','param' : 'unstart'}
                    ];
                    $scope.applyNavs = [
	                    {'name' : '7','index' : '0','param' : 'all'},
	                    {'name' : '8','index' : '1','param' : 'pending'},
	                    {'name' : '9','index' : '2','param' : 'unstart'}
                    ];
                    $scope.noticeNavs = [
                    	{'name' : '未读','index' : '0','param' : 'all'},
                    	{'name' : '11','index' : '1','param' : 'pending'},
                    	{'name' : '12','index' : '2','param' : 'unstart'}
                    ];
                    $scope.clickTabBtn = function(index){
                        $scope.tabInitIndex = index;
                        console.log('tab ' + $scope.tabInitIndex);
                    }

            		// -------------混乱数据区-------------

            		// 页面加载请求数据
            		networkSvc.getList('notice')
            		.then(
            			// networkSvc.getList() resolve接口
            		    function(res){
            		        switch(res.data.code){
            		            case '-99':
            		                alert('请先登录');
            		                $location.path("/login");
            		                break;
            		            case '0':
            		                alert('失败了，程序猿在奋力为你解决');
            		                break;
            		            case '1':
                                    $scope.notice = res.data.data;
                                    $log.log($scope.notice);

                                    // http://mgcrea.github.io/angular-strap/
                                    // Show a basic modal from a controller
                                    // var myModal = $modal({title: 'My Title', content: 'My Content', show: true});

            		                break;
            		            default:
            		                $scope.info = '失败了，程序猿在奋力为你解决';
            		                break;
            		        }
            		    },
            		    // networkSvc.getList() reject接口
            		    function(err){
                            alert('失败了，程序猿在奋力为你解决');
            		        $log.log(err);
            		    },
            		    // networkSvc.getList() notify接口
            		    function(proc){
            		        // loading
            		    }
            		);
            	},
            	// 客户端以及登陆而服务器端未登录
            	function(){
            		alert('请先登录');
            		$location.path("/login");
            	}
            );

			// 登出操作
			$scope.logout = function () {
			    authenticationSvc.logout()
		    	.then(
	    			// authenticationSvc.logout() resolve接口
	    		    function(res){
	    		        switch(res.data.code){
	    		            case '1':
	    		            	$location.path("/login");
	    		                break;
	    		            default:
		    		            alert('失败了，程序猿在奋力为你解决');
		    		            break;
	    		        }
	    		    },
	    		    // authenticationSvc.logout() reject接口
	    		    function(err){
                        alert('失败了，程序猿在奋力为你解决');
	    		        $log.log(err);
	    		    },
	    		    // authenticationSvc.logout() notify接口
	    		    function(proc){
	    		        // loading
	    		    }
		    	);
			}

        });
    }
});

<|endoftext|>


<commit_before>import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import config from '../config';

const defaultState = {
  fetchedParams: false,
  fetchingParams: false,
  paramError: null,
  parameters: null,
};

export const ParameterContext = React.createContext([{}, () => {}]);

export function ParameterProvider(props) {
  const [
    { fetchedParams, fetchingParams, paramError, parameters },
    setState,
  ] = useState(defaultState);

  useEffect(() => {
    const fetchData = () => {
      setState(state => ({ ...state, fetchingParams: true, paramError: null }));

      fetch(`${config.api}/parameters`)
        .then(response => {
          if (response.status >= 400) {
            throw new paramError('Bad response');
          }
          return response.json();
        })
        .then(
          json => {
            setState(state => ({
              ...state,
              fetchedParams: true,
              fetchingParams: false,
              parameters: json.results,
            }));
          },
          e => {
            console.log('e', e);
            setState(state => ({
              ...state,
              fetchedParams: true,
              fetchingParams: false,
              paramError: e,
            }));
          }
        );
    };

    fetchData();

    return () => {
      setState(defaultState);
    };
  }, []);

  const getMaxColorValue = function (activeParameterId) {
    return parameters.find(p => p.id === activeParameterId)?.maxColorValue;
  };

  return (
    <ParameterContext.Provider
      value={{
        fetchedParams,
        fetchingParams,
        paramError,
        parameters,
        getMaxColorValue,
      }}
    >
      {props.children}
    </ParameterContext.Provider>
  );
}
ParameterProvider.propTypes = {
  children: PropTypes.node,
};
<commit_msg>Add optional chaining, parameters might not be done fetching<commit_after>import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import config from '../config';

const defaultState = {
  fetchedParams: false,
  fetchingParams: false,
  paramError: null,
  parameters: null,
};

export const ParameterContext = React.createContext([{}, () => {}]);

export function ParameterProvider(props) {
  const [
    { fetchedParams, fetchingParams, paramError, parameters },
    setState,
  ] = useState(defaultState);

  useEffect(() => {
    const fetchData = () => {
      setState(state => ({ ...state, fetchingParams: true, paramError: null }));

      fetch(`${config.api}/parameters`)
        .then(response => {
          if (response.status >= 400) {
            throw new paramError('Bad response');
          }
          return response.json();
        })
        .then(
          json => {
            setState(state => ({
              ...state,
              fetchedParams: true,
              fetchingParams: false,
              parameters: json.results,
            }));
          },
          e => {
            console.log('e', e);
            setState(state => ({
              ...state,
              fetchedParams: true,
              fetchingParams: false,
              paramError: e,
            }));
          }
        );
    };

    fetchData();

    return () => {
      setState(defaultState);
    };
  }, []);

  const getMaxColorValue = function (activeParameterId) {
    return parameters?.find(p => p.id === activeParameterId)?.maxColorValue;
  };

  return (
    <ParameterContext.Provider
      value={{
        fetchedParams,
        fetchingParams,
        paramError,
        parameters,
        getMaxColorValue,
      }}
    >
      {props.children}
    </ParameterContext.Provider>
  );
}
ParameterProvider.propTypes = {
  children: PropTypes.node,
};
<|endoftext|>


<commit_before>/* eslint unicorn/filename-case: "off", func-names: "off", camelcase: "off", no-unused-vars: "off" */

module.exports = function (iface) {
    const {mqttPub, mqttSub, mqttStatus, log, Service, Characteristic} = iface;

    /*
     // Required Characteristics
     this.addCharacteristic(Characteristic.AirQuality);

     // Optional Characteristics

      {"name": "statusAirQuality"},
      {"name": "statusLowBattery", "optional": true},
      {"name": "statusTampered", "optional": true},
      {"name": "statusActive", "optional": true},
      {"name": "statusFault", "optional": true},
      {"name": "statusOzoneDensity", "type": "Number", "optional": true},
      {"name": "statusNitrogenDioxideDensity", "type": "Number", "optional": true},
      {"name": "statusSulphurDioxideDensity", "type": "Number", "optional": true},
      {"name": "statusPM2_5Density", "type": "Number", "optional": true},
      {"name": "statusPM10Density", "type": "Number", "optional": true},
      {"name": "statusVOCDensity", "type": "Number", "optional": true},
      {"name": "statusCarbonMonoxideLevel", "type": "Number", "optional": true},
      {"name": "statusCarbonDioxideLevel", "type": "Number", "optional": true}

     Characteristic.AirQuality.UNKNOWN = 0;
     Characteristic.AirQuality.EXCELLENT = 1;
     Characteristic.AirQuality.GOOD = 2;
     Characteristic.AirQuality.FAIR = 3;
     Characteristic.AirQuality.INFERIOR = 4;
     Characteristic.AirQuality.POOR = 5;
     */

    return function createService_AirQualitySensor(acc, settings, subtype) {
        mqttSub(settings.topic.statusAirQuality, val => {
            log.debug('> hap update', settings.name, 'AirQuality', mqttStatus[settings.topic.statusAirQuality]);
            acc.getService(subtype)
                .updateCharacteristic(Characteristic.AirQuality, val);
        });

        acc.addService(Service.AirQualitySensor, settings.name, subtype)
            .getCharacteristic(Characteristic.AirQuality)
            .on('get', callback => {
                log.debug('< hap get', settings.name, 'AirQualitySensor', 'AirQuality');
                log.debug('> hap re_get', settings.name, mqttStatus[settings.topic.statusAirQuality]);
                callback(null, mqttStatus[settings.topic.statusAirQuality]);
            });

        if (settings.topic.statusOzoneDensity) {
             mqttSub(settings.topic.statusOzoneDensity, val => {
                log.debug('> hap update', settings.name, 'OzoneDensity', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.OzoneDensity, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.OzoneDensity)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'OzoneDensity');
                    log.debug('> hap re_get', settings.name, 'OzoneDensity', mqttStatus[settings.topic.statusOzoneDensity]);
                    callback(null, mqttStatus[settings.topic.statusOzoneDensity]);
                });
      	}

        if (settings.topic.statusNitrogenDioxideDensity) {
             mqttSub(settings.topic.statusNitrogenDioxideDensity, val => {
                log.debug('> hap update', settings.name, 'NitrogenDioxideDensity', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.NitrogenDioxideDensity, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.NitrogenDioxideDensity)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'NitrogenDioxideDensity');
                    log.debug('> hap re_get', settings.name, 'NitrogenDioxideDensity', mqttStatus[settings.topic.statusNitrogenDioxideDensity]);
                    callback(null, mqttStatus[settings.topic.statusNitrogenDioxideDensity]);
                });
      	}

        if (settings.topic.statusSulphurDioxideDensity) {
             mqttSub(settings.topic.statusSulphurDioxideDensity, val => {
                log.debug('> hap update', settings.name, 'SulphurDioxideDensity', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.SulphurDioxideDensity, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.SulphurDioxideDensity)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'SulphurDioxideDensity');
                    log.debug('> hap re_get', settings.name, 'SulphurDioxideDensity', mqttStatus[settings.topic.statusSulphurDioxideDensity]);
                    callback(null, mqttStatus[settings.topic.statusSulphurDioxideDensity]);
                });
      	}

        if (settings.topic.statusPM2_5Density) {
             mqttSub(settings.topic.statusPM2_5Density, val => {
                log.debug('> hap update', settings.name, 'PM2_5Density', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.PM2_5Density, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.PM2_5Density)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'PM2_5Density');
                    log.debug('> hap re_get', settings.name, 'PM2_5Density', mqttStatus[settings.topic.statusPM2_5Density]);
                    callback(null, mqttStatus[settings.topic.statusPM2_5Density]);
                });
      	}

        if (settings.topic.statusPM10Density) {
             mqttSub(settings.topic.statusPM10Density, val => {
                log.debug('> hap update', settings.name, 'PM10Density', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.PM10Density, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.PM10Density)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'PM10Density');
                    log.debug('> hap re_get', settings.name, 'PM10Density', mqttStatus[settings.topic.statusPM10Density]);
                    callback(null, mqttStatus[settings.topic.statusPM10Density]);
                });
      	}

        if (settings.topic.statusVOCDensity) {
             mqttSub(settings.topic.statusVOCDensity, val => {
                log.debug('> hap update', settings.name, 'VOCDensity', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.VOCDensity, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.VOCDensity)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'VOCDensity');
                    log.debug('> hap re_get', settings.name, 'VOCDensity', mqttStatus[settings.topic.statusVOCDensity]);
                    callback(null, mqttStatus[settings.topic.statusVOCDensity]);
                });
      	}

        if (settings.topic.statusCarbonMonoxideLevel) {
             mqttSub(settings.topic.statusCarbonMonoxideLevel, val => {
                log.debug('> hap update', settings.name, 'CarbonMonoxideLevel', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.CarbonMonoxideLevel, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.CarbonMonoxideLevel)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'CarbonMonoxideLevel');
                    log.debug('> hap re_get', settings.name, 'CarbonMonoxideLevel', mqttStatus[settings.topic.statusCarbonMonoxideLevel]);
                    callback(null, mqttStatus[settings.topic.statusCarbonMonoxideLevel]);
                });
      	}

        if (settings.topic.statusCarbonDioxideLevel) {
             mqttSub(settings.topic.statusCarbonDioxideLevel, val => {
                log.debug('> hap update', settings.name, 'CarbonDioxideLevel', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.CarbonDioxideLevel, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.CarbonDioxideLevel)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'CarbonDioxideLevel');
                    log.debug('> hap re_get', settings.name, 'CarbonDioxideLevel', mqttStatus[settings.topic.statusCarbonDioxideLevel]);
                    callback(null, mqttStatus[settings.topic.statusCarbonDioxideLevel]);
                });
      	}

    };
};
<commit_msg>fix lint issues<commit_after>/* eslint unicorn/filename-case: "off", func-names: "off", camelcase: "off", no-unused-vars: "off" */

module.exports = function (iface) {
    const {mqttPub, mqttSub, mqttStatus, log, Service, Characteristic} = iface;

    /*
     // Required Characteristics
     this.addCharacteristic(Characteristic.AirQuality);

     // Optional Characteristics

      {"name": "statusAirQuality"},
      {"name": "statusLowBattery", "optional": true},
      {"name": "statusTampered", "optional": true},
      {"name": "statusActive", "optional": true},
      {"name": "statusFault", "optional": true},
      {"name": "statusOzoneDensity", "type": "Number", "optional": true},
      {"name": "statusNitrogenDioxideDensity", "type": "Number", "optional": true},
      {"name": "statusSulphurDioxideDensity", "type": "Number", "optional": true},
      {"name": "statusPM2_5Density", "type": "Number", "optional": true},
      {"name": "statusPM10Density", "type": "Number", "optional": true},
      {"name": "statusVOCDensity", "type": "Number", "optional": true},
      {"name": "statusCarbonMonoxideLevel", "type": "Number", "optional": true},
      {"name": "statusCarbonDioxideLevel", "type": "Number", "optional": true}

     Characteristic.AirQuality.UNKNOWN = 0;
     Characteristic.AirQuality.EXCELLENT = 1;
     Characteristic.AirQuality.GOOD = 2;
     Characteristic.AirQuality.FAIR = 3;
     Characteristic.AirQuality.INFERIOR = 4;
     Characteristic.AirQuality.POOR = 5;
     */

    return function createService_AirQualitySensor(acc, settings, subtype) {
        mqttSub(settings.topic.statusAirQuality, val => {
            log.debug('> hap update', settings.name, 'AirQuality', mqttStatus[settings.topic.statusAirQuality]);
            acc.getService(subtype)
                .updateCharacteristic(Characteristic.AirQuality, val);
        });

        acc.addService(Service.AirQualitySensor, settings.name, subtype)
            .getCharacteristic(Characteristic.AirQuality)
            .on('get', callback => {
                log.debug('< hap get', settings.name, 'AirQualitySensor', 'AirQuality');
                log.debug('> hap re_get', settings.name, mqttStatus[settings.topic.statusAirQuality]);
                callback(null, mqttStatus[settings.topic.statusAirQuality]);
            });

        if (settings.topic.statusOzoneDensity) {
            mqttSub(settings.topic.statusOzoneDensity, val => {
                log.debug('> hap update', settings.name, 'OzoneDensity', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.OzoneDensity, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.OzoneDensity)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'OzoneDensity');
                    log.debug('> hap re_get', settings.name, 'OzoneDensity', mqttStatus[settings.topic.statusOzoneDensity]);
                    callback(null, mqttStatus[settings.topic.statusOzoneDensity]);
                });
        }

        if (settings.topic.statusNitrogenDioxideDensity) {
            mqttSub(settings.topic.statusNitrogenDioxideDensity, val => {
                log.debug('> hap update', settings.name, 'NitrogenDioxideDensity', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.NitrogenDioxideDensity, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.NitrogenDioxideDensity)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'NitrogenDioxideDensity');
                    log.debug('> hap re_get', settings.name, 'NitrogenDioxideDensity', mqttStatus[settings.topic.statusNitrogenDioxideDensity]);
                    callback(null, mqttStatus[settings.topic.statusNitrogenDioxideDensity]);
                });
        }

        if (settings.topic.statusSulphurDioxideDensity) {
            mqttSub(settings.topic.statusSulphurDioxideDensity, val => {
                log.debug('> hap update', settings.name, 'SulphurDioxideDensity', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.SulphurDioxideDensity, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.SulphurDioxideDensity)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'SulphurDioxideDensity');
                    log.debug('> hap re_get', settings.name, 'SulphurDioxideDensity', mqttStatus[settings.topic.statusSulphurDioxideDensity]);
                    callback(null, mqttStatus[settings.topic.statusSulphurDioxideDensity]);
                });
        }

        if (settings.topic.statusPM2_5Density) {
            mqttSub(settings.topic.statusPM2_5Density, val => {
                log.debug('> hap update', settings.name, 'PM2_5Density', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.PM2_5Density, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.PM2_5Density)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'PM2_5Density');
                    log.debug('> hap re_get', settings.name, 'PM2_5Density', mqttStatus[settings.topic.statusPM2_5Density]);
                    callback(null, mqttStatus[settings.topic.statusPM2_5Density]);
                });
        }

        if (settings.topic.statusPM10Density) {
            mqttSub(settings.topic.statusPM10Density, val => {
                log.debug('> hap update', settings.name, 'PM10Density', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.PM10Density, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.PM10Density)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'PM10Density');
                    log.debug('> hap re_get', settings.name, 'PM10Density', mqttStatus[settings.topic.statusPM10Density]);
                    callback(null, mqttStatus[settings.topic.statusPM10Density]);
                });
        }

        if (settings.topic.statusVOCDensity) {
            mqttSub(settings.topic.statusVOCDensity, val => {
                log.debug('> hap update', settings.name, 'VOCDensity', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.VOCDensity, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.VOCDensity)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'VOCDensity');
                    log.debug('> hap re_get', settings.name, 'VOCDensity', mqttStatus[settings.topic.statusVOCDensity]);
                    callback(null, mqttStatus[settings.topic.statusVOCDensity]);
                });
        }

        if (settings.topic.statusCarbonMonoxideLevel) {
            mqttSub(settings.topic.statusCarbonMonoxideLevel, val => {
                log.debug('> hap update', settings.name, 'CarbonMonoxideLevel', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.CarbonMonoxideLevel, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.CarbonMonoxideLevel)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'CarbonMonoxideLevel');
                    log.debug('> hap re_get', settings.name, 'CarbonMonoxideLevel', mqttStatus[settings.topic.statusCarbonMonoxideLevel]);
                    callback(null, mqttStatus[settings.topic.statusCarbonMonoxideLevel]);
                });
        }

        if (settings.topic.statusCarbonDioxideLevel) {
            mqttSub(settings.topic.statusCarbonDioxideLevel, val => {
                log.debug('> hap update', settings.name, 'CarbonDioxideLevel', val);
                acc.getService(subtype)
                    .updateCharacteristic(Characteristic.CarbonDioxideLevel, val);
            });
            acc.getService(subtype)
                .getCharacteristic(Characteristic.CarbonDioxideLevel)
                .on('get', callback => {
                    log.debug('< hap get', settings.name, 'CarbonDioxideLevel');
                    log.debug('> hap re_get', settings.name, 'CarbonDioxideLevel', mqttStatus[settings.topic.statusCarbonDioxideLevel]);
                    callback(null, mqttStatus[settings.topic.statusCarbonDioxideLevel]);
                });
        }
    };
};
<|endoftext|>


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

define([
  "app",

  "modules/fauxton/base",
  "api"
],

function(app, Fauxton, FauxtonAPI) {
  var Views = {};

  Views.Item = FauxtonAPI.View.extend({
    template: "templates/databases/item",
    tagName: "tr",

    serialize: function() {
      return {
        database: this.model
      };
    }
  });

  Views.List = FauxtonAPI.View.extend({
    dbLimit: 10,
    perPage: 10,
    template: "templates/databases/list",
    events: {
      "click button.all": "selectAll",
      "submit form.database-search": "switchDatabase"
    },

    initialize: function(options) {
      var params = app.getParams();
      this.collection.on("add", this.render, this);
      this.page = params.page ? parseInt(params.page, 10) : 1;
    },

    serialize: function() {
      return {
        databases: this.collection
      };
    },

    switchDatabase: function(event) {
      event.preventDefault();
      var dbname = this.$el.find("input.search-query").val();

      if (dbname) {
        // TODO: switch to using a model, or Databases.databaseUrl()
        // Neither of which are in scope right now
        // var db = new Database.Model({id: dbname});
        var url = ["/database/", dbname, "/_all_docs?limit=10"].join('');
        FauxtonAPI.navigate(url);
      }
    },

    paginated: function() {
      var start = (this.page - 1) * this.perPage;
      var end = this.page * this.perPage - 1;
      return this.collection.slice(start, end);
    },

    beforeRender: function() {
      _.each(this.paginated(), function(database) {
        this.insertView("table.databases tbody", new Views.Item({
          model: database
        }));
      }, this);

      this.insertView("#database-pagination", new Fauxton.Pagination({
        page: this.page,
        perPage: this.perPage,
        total: this.collection.length,
        urlFun: function(page) {
          return "#/_all_dbs?page=" + page;
        }
      }));
    },

    afterRender: function() {
      var dbLimit = this.dbLimit;
      var ajaxReq;

      this.$el.find("input.search-query").typeahead({
        source: function(query, process) {
          var url = [
            app.host,
            "/_all_dbs?startkey=%22",
            query,
            "%22&endkey=%22",
            query,
            "\u9999%22&limit=",
            dbLimit
          ].join('');
          if (ajaxReq) ajaxReq.abort();
          ajaxReq = $.ajax({
            url: url,
            dataType: 'json',
            success: function(data) {
              process(data);
            }
          });
        }
      });
    },

    selectAll: function(evt){
      $("input:checkbox").attr('checked', !$(evt.target).hasClass('active'));
    }
  });

  Views.Sidebar = FauxtonAPI.View.extend({
    template: "templates/databases/sidebar",
    events: {
      "click a#new": "newDatabase",
      "click a#owned": "showMine",
      "click a#shared": "showShared"
    },

    newDatabase: function() {
      var notification;
      var db;
      // TODO: use a modal here instead of the prompt
      var name = prompt('Name of database', 'newdatabase');
      if (name === null) {
        return;
      } else if (name.length === 0) {
        notification = FauxtonAPI.addNotification({
          msg: "Please enter a valid database name",
          type: "error",
          clear: true
        });
        return;
      }
      db = new this.collection.model({
        id: encodeURIComponent(name),
        name: name
      });
      notification = FauxtonAPI.addNotification({msg: "Creating database."});
      db.save().done(function() {
        notification = FauxtonAPI.addNotification({
          msg: "Database created successfully",
          type: "success",
          clear: true
        });
        var route = "#/database/" +  name + "/_all_docs?limit=100";
        app.router.navigate(route, { trigger: true });
      }
      ).error(function(xhr) {
        var responseText = JSON.parse(xhr.responseText).reason;
        notification = FauxtonAPI.addNotification({
          msg: "Create database failed: " + responseText,
          type: "error",
          clear: true
        });
      }
      );
    },

    showMine: function(){
      $.contribute(
        'Show unshared databases',
        'app/addons/databases/views.js'
      );
    },

    showShared: function(){
      $.contribute(
        'Show shared databases (e.g. continuous replications to/from the database)',
        'app/addons/databases/views.js'
      );
    }
  });

  return Views;
});
<commit_msg>Fix extraneous database list renderings<commit_after>// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

define([
  "app",

  "modules/fauxton/base",
  "api"
],

function(app, Fauxton, FauxtonAPI) {
  var Views = {};

  Views.Item = FauxtonAPI.View.extend({
    template: "templates/databases/item",
    tagName: "tr",

    serialize: function() {
      return {
        database: this.model
      };
    }
  });

  Views.List = FauxtonAPI.View.extend({
    dbLimit: 10,
    perPage: 10,
    template: "templates/databases/list",
    events: {
      "click button.all": "selectAll",
      "submit form.database-search": "switchDatabase"
    },

    initialize: function(options) {
      var params = app.getParams();
      this.page = params.page ? parseInt(params.page, 10) : 1;
    },

    serialize: function() {
      return {
        databases: this.collection
      };
    },

    switchDatabase: function(event) {
      event.preventDefault();
      var dbname = this.$el.find("input.search-query").val();

      if (dbname) {
        // TODO: switch to using a model, or Databases.databaseUrl()
        // Neither of which are in scope right now
        // var db = new Database.Model({id: dbname});
        var url = ["/database/", dbname, "/_all_docs?limit=10"].join('');
        FauxtonAPI.navigate(url);
      }
    },

    paginated: function() {
      var start = (this.page - 1) * this.perPage;
      var end = this.page * this.perPage - 1;
      return this.collection.slice(start, end);
    },

    beforeRender: function() {
      _.each(this.paginated(), function(database) {
        this.insertView("table.databases tbody", new Views.Item({
          model: database
        }));
      }, this);

      this.insertView("#database-pagination", new Fauxton.Pagination({
        page: this.page,
        perPage: this.perPage,
        total: this.collection.length,
        urlFun: function(page) {
          return "#/_all_dbs?page=" + page;
        }
      }));
    },

    afterRender: function() {
      var dbLimit = this.dbLimit;
      var ajaxReq;

      this.$el.find("input.search-query").typeahead({
        source: function(query, process) {
          var url = [
            app.host,
            "/_all_dbs?startkey=%22",
            query,
            "%22&endkey=%22",
            query,
            "\u9999%22&limit=",
            dbLimit
          ].join('');
          if (ajaxReq) ajaxReq.abort();
          ajaxReq = $.ajax({
            url: url,
            dataType: 'json',
            success: function(data) {
              process(data);
            }
          });
        }
      });
    },

    selectAll: function(evt){
      $("input:checkbox").attr('checked', !$(evt.target).hasClass('active'));
    }
  });

  Views.Sidebar = FauxtonAPI.View.extend({
    template: "templates/databases/sidebar",
    events: {
      "click a#new": "newDatabase",
      "click a#owned": "showMine",
      "click a#shared": "showShared"
    },

    newDatabase: function() {
      var notification;
      var db;
      // TODO: use a modal here instead of the prompt
      var name = prompt('Name of database', 'newdatabase');
      if (name === null) {
        return;
      } else if (name.length === 0) {
        notification = FauxtonAPI.addNotification({
          msg: "Please enter a valid database name",
          type: "error",
          clear: true
        });
        return;
      }
      db = new this.collection.model({
        id: encodeURIComponent(name),
        name: name
      });
      notification = FauxtonAPI.addNotification({msg: "Creating database."});
      db.save().done(function() {
        notification = FauxtonAPI.addNotification({
          msg: "Database created successfully",
          type: "success",
          clear: true
        });
        var route = "#/database/" +  name + "/_all_docs?limit=100";
        app.router.navigate(route, { trigger: true });
      }
      ).error(function(xhr) {
        var responseText = JSON.parse(xhr.responseText).reason;
        notification = FauxtonAPI.addNotification({
          msg: "Create database failed: " + responseText,
          type: "error",
          clear: true
        });
      }
      );
    },

    showMine: function(){
      $.contribute(
        'Show unshared databases',
        'app/addons/databases/views.js'
      );
    },

    showShared: function(){
      $.contribute(
        'Show shared databases (e.g. continuous replications to/from the database)',
        'app/addons/databases/views.js'
      );
    }
  });

  return Views;
});
<|endoftext|>


<commit_before>import expect               from 'expect';
import nodeRevisionsReducer from '../../src/reducers/node-revisions-reducer';
import * as types           from '../../src/constants/ActionTypes';

describe('node revisions reducer', () => {
    it('should return the initial state', () => {
        expect(nodeRevisionsReducer(undefined, {})).toEqual({});
    });

    const uuid = 'a1b2c3';

    it('should handle the REQUEST_NODE_REVISIONS action', () => {
        expect(nodeRevisionsReducer({}, {
            type: types.REQUEST_NODE_REVISIONS,
            uuid
        }))
            .toEqual({
                [uuid]: {
                    didInvalidate: false,
                    isFetching:    true,
                    items:         []
                }
            })
        ;
    });

    it('should handle the RECEIVE_NODE_REVISIONS action', () => {
        const expectedRevisions = [1, 2, 3];

        expect(nodeRevisionsReducer({}, {
            type: types.RECEIVE_NODE_REVISIONS,
            uuid,
            items: expectedRevisions
        }))
            .toEqual({
                [uuid]: {
                    didInvalidate: false,
                    isFetching:    false,
                    items:         expectedRevisions
                }
            })
        ;
    });

    it('should handle the RECEIVE_NODE_UPDATE action', () => {
        expect(nodeRevisionsReducer({}, {
            type: types.RECEIVE_NODE_UPDATE,
            uuid
        }))
            .toEqual({
                [uuid]: {
                    didInvalidate: true,
                    isFetching:    false,
                    items:         []
                }
            })
        ;
    });
});<commit_msg>feat(explorer): fix node revisions reducer test<commit_after>import expect               from 'expect';
import nodeRevisionsReducer from '../../src/reducers/node-revisions-reducer';
import {
    REQUEST_NODE_REVISIONS,
    RECEIVE_NODE_REVISIONS,
    INVALIDATE_NODE_REVISIONS
} from '../../src/constants/ActionTypes';

describe('node revisions reducer', () => {
    it('should return the initial state', () => {
        expect(nodeRevisionsReducer(undefined, {})).toEqual({});
    });

    const uuid = 'a1b2c3';

    it('should handle the REQUEST_NODE_REVISIONS action', () => {
        expect(nodeRevisionsReducer({}, {
            type: REQUEST_NODE_REVISIONS,
            uuid
        }))
            .toEqual({
                [uuid]: {
                    didInvalidate: false,
                    isFetching:    true,
                    items:         []
                }
            })
        ;
    });

    it('should handle the RECEIVE_NODE_REVISIONS action', () => {
        const expectedRevisions = [1, 2, 3];

        expect(nodeRevisionsReducer({}, {
            type: RECEIVE_NODE_REVISIONS,
            uuid,
            items: expectedRevisions
        }))
            .toEqual({
                [uuid]: {
                    didInvalidate: false,
                    isFetching:    false,
                    items:         expectedRevisions
                }
            })
        ;
    });

    it('should handle the INVALIDATE_NODE_REVISIONS action', () => {
        expect(nodeRevisionsReducer({}, {
            type: INVALIDATE_NODE_REVISIONS,
            uuid
        }))
            .toEqual({
                [uuid]: {
                    didInvalidate: true,
                    isFetching:    false,
                    items:         []
                }
            })
        ;
    });
});
<|endoftext|>


<commit_before>'use strict'

var BN = require('bn.js')
var num2bn = require('./lib/num-to-bn')
var shiftFloat = require('./lib/shift-float')
var rationalize = require('./lib/rationalize')

module.exports = makeRational

function makeRational(numer, denom) {
  if(Array.isArray(numer)) {
    if(Array.isArray(denom)) {
      return rationalize([numer[0].mul(denom[1]), numer[1].mul(denom[0])])
    }
    return numer
  }
  var shift = 0
  var a, b
  if(typeof numer === 'string') {
    a = new BN(numer)
  } else if(numer === 0) {
    return [new BN(0), new BN(1)]
  } else if(numer === Math.floor(numer)) {
    a = num2bn(numer)
  } else {
    a = num2bn(shiftFloat(numer, 1080))
    shift -= 1080
  }
  if(typeof denom === 'string') {
    b = new BN(denom)
  } else if(!denom) {
    b = num2bn(1)
  } else if(denom === Math.floor(denom)) {
    b = num2bn(denom)
  } else {
    b = num2bn(shiftFloat(denom, 1080))
    shift += 1080
  }
  if(shift > 0) {
    a = a.shln(shift)
  } else if(shift < 0) {
    b = b.shln(-shift)
  }
  return rationalize([a, b])
}
<commit_msg>fix bug in conversion of scalar<commit_after>'use strict'

var BN = require('bn.js')
var num2bn = require('./lib/num-to-bn')
var rationalize = require('./lib/rationalize')

module.exports = makeRational

function makeRational(numer, denom) {
  if(Array.isArray(numer)) {
    if(Array.isArray(denom)) {
      return rationalize([numer[0].mul(denom[1]), numer[1].mul(denom[0])])
    }
    return numer
  }
  var shift = 0
  var a, b
  if(typeof numer === 'string') {
    a = new BN(numer)
  } else if(numer === 0) {
    return [new BN(0), new BN(1)]
  } else if(numer === Math.floor(numer)) {
    a = num2bn(numer)
  } else {
    while(numer !== Math.floor(numer)) {
      numer = numer * Math.pow(2, 256)
      shift -= 256
    }
    a = num2bn(numer)
  }
  if(typeof denom === 'string') {
    b = new BN(denom)
  } else if(!denom) {
    b = num2bn(1)
  } else if(denom === Math.floor(denom)) {
    b = num2bn(denom)
  } else {
    while(denom !== Math.floor(denom)) {
      denom = denom * Math.pow(2, 256)
      shift -= 256
    }
    b = num2bn(denom)
  }
  if(shift > 0) {
    a = a.shln(shift)
  } else if(shift < 0) {
    b = b.shln(-shift)
  }
  return rationalize([a, b])
}
<|endoftext|>


<commit_before>// Copyright 2008 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Utilities to check the preconditions, postconditions and
 * invariants runtime.
 *
 * Methods in this package should be given special treatment by the compiler
 * for type-inference. For example, goog.asserts.assert(foo)
 * will restrict foo to a truthy value.
 *
 *
 * @author agrieve@google.com (Andrew Grieve)
 */

goog.provide('goog.asserts');
goog.provide('goog.asserts.AssertionError');

goog.require('goog.debug.Error');
goog.require('goog.string');

// TODO(nicksantos): Add return values for all these functions, so that they
// can be chained like:
// eatNumber(goog.asserts.isNumber(foo));
// for more lisp-y asserts.

/**
 * @define {boolean} Whether to strip out asserts or to leave them in.
 */
goog.asserts.ENABLE_ASSERTS = goog.DEBUG;

/**
 * Error object for failed assertions.
 * @param {string} messagePattern The pattern that was used to form message.
 * @param {!Array.<*>} messageArgs The items to substitute into the pattern.
 * @constructor
 * @extends {goog.debug.Error}
 */
goog.asserts.AssertionError = function(messagePattern, messageArgs) {
  messageArgs.unshift(messagePattern);
  goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs));
  // Remove the messagePattern afterwards to avoid permenantly modifying the
  // passed in array.
  messageArgs.shift();

  /**
   * The message pattern used to format the error message. Error handlers can
   * use this to uniquely identify the assertion.
   * @type {string}
   */
  this.messagePattern = messagePattern;
};
goog.inherits(goog.asserts.AssertionError, goog.debug.Error);

/** @inheritDoc */
goog.asserts.AssertionError.prototype.name = 'AssertionError';

/**
 * Throws an exception with the given message and "Assertion failed" prefixed
 * onto it.
 * @param {string} defaultMessage The message to use if givenMessage is empty.
 * @param {Array.<*>} defaultArgs The substitution arguments for defaultMessage.
 * @param {string|undefined} givenMessage Message supplied by the caller.
 * @param {Array.<*>} givenArgs The substitution arguments for givenMessage.
 * @throws {goog.asserts.AssertionError} When the value is not a number.
 * @private
 */
goog.asserts.doAssertFailure_ =
    function(defaultMessage, defaultArgs, givenMessage, givenArgs) {
  var message = 'Assertion failed';
  if (givenMessage) {
    message += ': ' + givenMessage;
    var args = givenArgs;
  } else if (defaultMessage) {
    message += ': ' + defaultMessage;
    args = defaultArgs;
  }
  // The '' + works around an Opera 10 bug in the unit tests. Without it,
  // a stack trace is added to var message above. With this, a stack trace is
  // not added until this line (it causes the extra garbage to be added after
  // the assertion message instead of in the middle of it).
  throw new goog.asserts.AssertionError('' + message, args || []);
};

/**
 * Checks if the condition evaluates to true if goog.asserts.ENABLE_ASSERTS is
 * true.
 * @param {*} condition The condition to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @throws {goog.asserts.AssertionError} When the condition evaluates to false.
 */
goog.asserts.assert = function(condition, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !condition) {
    goog.asserts.doAssertFailure_('', null, opt_message,
        Array.prototype.slice.call(arguments, 2));
  }
};

/**
 * Fails if goog.asserts.ENABLE_ASSERTS is true. This function is useful in case
 * when we want to add a check in the unreachable area like switch-case
 * statement:
 *
 *

 *  switch(type) {
 *    case FOO: doSomething(); break;
 *    case BAR: doSomethingElse(); break;
 *    default: goog.assert.fail('Unrecognized type: ' + type);
 *      // We have only 2 types - "default:" section is unreachable code.
 *  }
 *

 *
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @throws {goog.asserts.AssertionError} Failure.
 */
goog.asserts.fail = function(opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS) {
    throw new goog.asserts.AssertionError(
        'Failure' + (opt_message ? ': ' + opt_message : ''),
        Array.prototype.slice.call(arguments, 1));
  }
};

/**
 * Checks if the value is a number if goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @return {number} The value, guaranteed to be a number when asserts enabled.
 * @throws {goog.asserts.AssertionError} When the value is not a number.
 */
goog.asserts.assertNumber = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) {
    goog.asserts.doAssertFailure_('Expected number but got %s: %s.',
        [goog.typeOf(value), value], opt_message,
        Array.prototype.slice.call(arguments, 2));
  }
  return /** @type {number} */ (value);
};

/**
 * Checks if the value is a string if goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @return {string} The value, guaranteed to be a string when asserts enabled.
 * @throws {goog.asserts.AssertionError} When the value is not a string.
 */
goog.asserts.assertString = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) {
    goog.asserts.doAssertFailure_('Expected string but got %s: %s.',
        [goog.typeOf(value), value], opt_message,
        Array.prototype.slice.call(arguments, 2));
  }
  return /** @type {string} */ (value);
};

/**
 * Checks if the value is a function if goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @return {!Function} The value, guaranteed to be a function when asserts
 *     enabled.
 * @throws {goog.asserts.AssertionError} When the value is not a function.
 */
goog.asserts.assertFunction = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) {
    goog.asserts.doAssertFailure_('Expected function but got %s: %s.',
        [goog.typeOf(value), value], opt_message,
        Array.prototype.slice.call(arguments, 2));
  }
  return /** @type {!Function} */ (value);
};

/**
 * Checks if the value is an Object if goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @return {!Object} The value, guaranteed to be a non-null object.
 * @throws {goog.asserts.AssertionError} When the value is not an object.
 */
goog.asserts.assertObject = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) {
    goog.asserts.doAssertFailure_('Expected object but got %s: %s.',
        [goog.typeOf(value), value],
        opt_message, Array.prototype.slice.call(arguments, 2));
  }
  return /** @type {!Object} */ (value);
};

/**
 * Checks if the value is an Array if goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @return {!Array} The value, guaranteed to be a non-null array.
 * @throws {goog.asserts.AssertionError} When the value is not an array.
 */
goog.asserts.assertArray = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) {
    goog.asserts.doAssertFailure_('Expected array but got %s: %s.',
        [goog.typeOf(value), value], opt_message,
        Array.prototype.slice.call(arguments, 2));
  }
  return /** @type {!Array} */ (value);
};

/**
 * Checks if the value is a boolean if goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @return {boolean} The value, guaranteed to be a boolean when asserts are
 *     enabled.
 * @throws {goog.asserts.AssertionError} When the value is not a boolean.
 */
goog.asserts.assertBoolean = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) {
    goog.asserts.doAssertFailure_('Expected boolean but got %s: %s.',
        [goog.typeOf(value), value], opt_message,
        Array.prototype.slice.call(arguments, 2));
  }
  return /** @type {boolean} */ (value);
};

/**
 * Checks if the value is an instance of the user-defined type if
 * goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {!Function} type A user-defined constructor.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @throws {goog.asserts.AssertionError} When the value is not an instance of
 *     type.
 */
goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) {
    goog.asserts.doAssertFailure_('instanceof check failed.', null,
        opt_message, Array.prototype.slice.call(arguments, 3));
  }
};

<commit_msg><commit_after>// Copyright 2008 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Utilities to check the preconditions, postconditions and
 * invariants runtime.
 *
 * Methods in this package should be given special treatment by the compiler
 * for type-inference. For example, goog.asserts.assert(foo)
 * will restrict foo to a truthy value.
 *
 * The compiler has an option to disable asserts. So code like:
 *
 * var x = goog.asserts.assert(foo()); goog.asserts.assert(bar());
 *
 * will be transformed into:
 *
 * var x = foo();
 *
 * The compiler will leave in foo() (because its return value is used),
 * but it will remove bar() because it assumes it does not have side-effects.
 *
 *
 * @author agrieve@google.com (Andrew Grieve)
 */

goog.provide('goog.asserts');
goog.provide('goog.asserts.AssertionError');

goog.require('goog.debug.Error');
goog.require('goog.string');

/**
 * @define {boolean} Whether to strip out asserts or to leave them in.
 */
goog.asserts.ENABLE_ASSERTS = goog.DEBUG;

/**
 * Error object for failed assertions.
 * @param {string} messagePattern The pattern that was used to form message.
 * @param {!Array.<*>} messageArgs The items to substitute into the pattern.
 * @constructor
 * @extends {goog.debug.Error}
 */
goog.asserts.AssertionError = function(messagePattern, messageArgs) {
  messageArgs.unshift(messagePattern);
  goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs));
  // Remove the messagePattern afterwards to avoid permenantly modifying the
  // passed in array.
  messageArgs.shift();

  /**
   * The message pattern used to format the error message. Error handlers can
   * use this to uniquely identify the assertion.
   * @type {string}
   */
  this.messagePattern = messagePattern;
};
goog.inherits(goog.asserts.AssertionError, goog.debug.Error);

/** @inheritDoc */
goog.asserts.AssertionError.prototype.name = 'AssertionError';

/**
 * Throws an exception with the given message and "Assertion failed" prefixed
 * onto it.
 * @param {string} defaultMessage The message to use if givenMessage is empty.
 * @param {Array.<*>} defaultArgs The substitution arguments for defaultMessage.
 * @param {string|undefined} givenMessage Message supplied by the caller.
 * @param {Array.<*>} givenArgs The substitution arguments for givenMessage.
 * @throws {goog.asserts.AssertionError} When the value is not a number.
 * @private
 */
goog.asserts.doAssertFailure_ =
    function(defaultMessage, defaultArgs, givenMessage, givenArgs) {
  var message = 'Assertion failed';
  if (givenMessage) {
    message += ': ' + givenMessage;
    var args = givenArgs;
  } else if (defaultMessage) {
    message += ': ' + defaultMessage;
    args = defaultArgs;
  }
  // The '' + works around an Opera 10 bug in the unit tests. Without it,
  // a stack trace is added to var message above. With this, a stack trace is
  // not added until this line (it causes the extra garbage to be added after
  // the assertion message instead of in the middle of it).
  throw new goog.asserts.AssertionError('' + message, args || []);
};

/**
 * Checks if the condition evaluates to true if goog.asserts.ENABLE_ASSERTS is
 * true.
 * @param {*} condition The condition to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @return {*} The value of the condition.
 * @throws {goog.asserts.AssertionError} When the condition evaluates to false.
 */
goog.asserts.assert = function(condition, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !condition) {
    goog.asserts.doAssertFailure_('', null, opt_message,
        Array.prototype.slice.call(arguments, 2));
  }
  return condition;
};

/**
 * Fails if goog.asserts.ENABLE_ASSERTS is true. This function is useful in case
 * when we want to add a check in the unreachable area like switch-case
 * statement:
 *
 *

 *  switch(type) {
 *    case FOO: doSomething(); break;
 *    case BAR: doSomethingElse(); break;
 *    default: goog.assert.fail('Unrecognized type: ' + type);
 *      // We have only 2 types - "default:" section is unreachable code.
 *  }
 *

 *
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @throws {goog.asserts.AssertionError} Failure.
 */
goog.asserts.fail = function(opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS) {
    throw new goog.asserts.AssertionError(
        'Failure' + (opt_message ? ': ' + opt_message : ''),
        Array.prototype.slice.call(arguments, 1));
  }
};

/**
 * Checks if the value is a number if goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @return {number} The value, guaranteed to be a number when asserts enabled.
 * @throws {goog.asserts.AssertionError} When the value is not a number.
 */
goog.asserts.assertNumber = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) {
    goog.asserts.doAssertFailure_('Expected number but got %s: %s.',
        [goog.typeOf(value), value], opt_message,
        Array.prototype.slice.call(arguments, 2));
  }
  return /** @type {number} */ (value);
};

/**
 * Checks if the value is a string if goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @return {string} The value, guaranteed to be a string when asserts enabled.
 * @throws {goog.asserts.AssertionError} When the value is not a string.
 */
goog.asserts.assertString = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) {
    goog.asserts.doAssertFailure_('Expected string but got %s: %s.',
        [goog.typeOf(value), value], opt_message,
        Array.prototype.slice.call(arguments, 2));
  }
  return /** @type {string} */ (value);
};

/**
 * Checks if the value is a function if goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @return {!Function} The value, guaranteed to be a function when asserts
 *     enabled.
 * @throws {goog.asserts.AssertionError} When the value is not a function.
 */
goog.asserts.assertFunction = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) {
    goog.asserts.doAssertFailure_('Expected function but got %s: %s.',
        [goog.typeOf(value), value], opt_message,
        Array.prototype.slice.call(arguments, 2));
  }
  return /** @type {!Function} */ (value);
};

/**
 * Checks if the value is an Object if goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @return {!Object} The value, guaranteed to be a non-null object.
 * @throws {goog.asserts.AssertionError} When the value is not an object.
 */
goog.asserts.assertObject = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) {
    goog.asserts.doAssertFailure_('Expected object but got %s: %s.',
        [goog.typeOf(value), value],
        opt_message, Array.prototype.slice.call(arguments, 2));
  }
  return /** @type {!Object} */ (value);
};

/**
 * Checks if the value is an Array if goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @return {!Array} The value, guaranteed to be a non-null array.
 * @throws {goog.asserts.AssertionError} When the value is not an array.
 */
goog.asserts.assertArray = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) {
    goog.asserts.doAssertFailure_('Expected array but got %s: %s.',
        [goog.typeOf(value), value], opt_message,
        Array.prototype.slice.call(arguments, 2));
  }
  return /** @type {!Array} */ (value);
};

/**
 * Checks if the value is a boolean if goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @return {boolean} The value, guaranteed to be a boolean when asserts are
 *     enabled.
 * @throws {goog.asserts.AssertionError} When the value is not a boolean.
 */
goog.asserts.assertBoolean = function(value, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) {
    goog.asserts.doAssertFailure_('Expected boolean but got %s: %s.',
        [goog.typeOf(value), value], opt_message,
        Array.prototype.slice.call(arguments, 2));
  }
  return /** @type {boolean} */ (value);
};

/**
 * Checks if the value is an instance of the user-defined type if
 * goog.asserts.ENABLE_ASSERTS is true.
 * @param {*} value The value to check.
 * @param {!Function} type A user-defined constructor.
 * @param {string=} opt_message Error message in case of failure.
 * @param {...*} var_args The items to substitute into the failure message.
 * @throws {goog.asserts.AssertionError} When the value is not an instance of
 *     type.
 */
goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) {
  if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) {
    goog.asserts.doAssertFailure_('instanceof check failed.', null,
        opt_message, Array.prototype.slice.call(arguments, 3));
  }
};

<|endoftext|>