<commit_before>const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');

// We removed all our provides!  But, if we need to add more back, let's do that
//
// environment.plugins.set(
//   'Provide',
//   new webpack.ProvidePlugin({
//   }),
// )

// Explicitly include modules that use ES6 syntax
environment.loaders.get('babel').exclude = /node_modules\/(?!(memoized-class-decorator|query-string)\/).*/;

//
// environment.loaders.get('sass').use.unshift({
//   loader: 'cache-loader'
// });

environment.plugins.prepend(
  'LodashModuleReplacementPlugin',
  new LodashModuleReplacementPlugin(),
);

// don't load all of moment's locales
environment.plugins.append(
  'Ignore',
  new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
)

module.exports = environment
<commit_msg>Compile strict-uri-encode for IE11 compat<commit_after>const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');

// We removed all our provides!  But, if we need to add more back, let's do that
//
// environment.plugins.set(
//   'Provide',
//   new webpack.ProvidePlugin({
//   }),
// )

// Explicitly include modules that use ES6 syntax
environment.loaders.get('babel').exclude = /node_modules\/(?!(query-string|strict-uri-encode)\/).*/;

//
// environment.loaders.get('sass').use.unshift({
//   loader: 'cache-loader'
// });

environment.plugins.prepend(
  'LodashModuleReplacementPlugin',
  new LodashModuleReplacementPlugin(),
);

// don't load all of moment's locales
environment.plugins.append(
  'Ignore',
  new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
)

module.exports = environment
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2019 Google LLC. 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.
 * =============================================================================
 */

const karmaTypescriptConfig = {
  tsconfig: 'tsconfig.test.json',
  // Disable coverage reports and instrumentation by default for tests
  coverageOptions: {instrumentation: false},
  reports: {},
  bundlerOptions: {
    transforms: [
      require('karma-typescript-es6-transform')({
        presets: [
          // ensure we get es5 by adding IE 11 as a target
          ['@babel/env', {'targets': {'ie': '11'}, 'loose': true}]
        ]
      })
    ],
    // worker_node_test in tfjs-core contains a conditional require statement
    // that confuses the bundler of karma-typescript.
    ignore: ['./worker_node_test']
  }
};

const devConfig = {
  frameworks: ['jasmine', 'karma-typescript'],
  files: [
    {pattern: './node_modules/@babel/polyfill/dist/polyfill.js'},
    'src/setup_test.ts',
    {pattern: 'src/**/*.ts'},
  ],
  preprocessors: {'src/**/*.ts': ['karma-typescript']},
  karmaTypescriptConfig,
  reporters: ['dots', 'karma-typescript']
};

module.exports = function(config) {
  const args = [];
  if (config.grep) {
    args.push('--grep', config.grep);
  }
  if (config.flags) {
    args.push('--flags', config.flags);
  }
  let exclude = [];
  if (config.excludeTest != null) {
    exclude.push(config.excludeTest);
  }

  config.set({
    ...devConfig,
    exclude,
    port: 9876,
    colors: true,
    autoWatch: false,
    browsers: ['Chrome', 'chrome_webgpu'],
    singleRun: true,
    customLaunchers: {
      chrome_webgpu: {
        base: 'Chrome',
        flags: ['--enable-unsafe-webgpu'],
      }
    },
    client: {jasmine: {random: false}, args: args}
  })
}
<commit_msg>webgpu: Disable dawn robustness (#4238)<commit_after>/**
 * @license
 * Copyright 2019 Google LLC. 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.
 * =============================================================================
 */

const karmaTypescriptConfig = {
  tsconfig: 'tsconfig.test.json',
  // Disable coverage reports and instrumentation by default for tests
  coverageOptions: {instrumentation: false},
  reports: {},
  bundlerOptions: {
    transforms: [require('karma-typescript-es6-transform')({
      presets: [
        // ensure we get es5 by adding IE 11 as a target
        ['@babel/env', {'targets': {'ie': '11'}, 'loose': true}]
      ]
    })],
    // worker_node_test in tfjs-core contains a conditional require statement
    // that confuses the bundler of karma-typescript.
    ignore: ['./worker_node_test']
  }
};

const devConfig = {
  frameworks: ['jasmine', 'karma-typescript'],
  files: [
    {pattern: './node_modules/@babel/polyfill/dist/polyfill.js'},
    'src/setup_test.ts',
    {pattern: 'src/**/*.ts'},
  ],
  preprocessors: {'src/**/*.ts': ['karma-typescript']},
  karmaTypescriptConfig,
  reporters: ['dots', 'karma-typescript']
};

module.exports = function(config) {
  const args = [];
  if (config.grep) {
    args.push('--grep', config.grep);
  }
  if (config.flags) {
    args.push('--flags', config.flags);
  }
  let exclude = [];
  if (config.excludeTest != null) {
    exclude.push(config.excludeTest);
  }

  config.set({
    ...devConfig,
    exclude,
    port: 9876,
    colors: true,
    autoWatch: false,
    browsers: ['Chrome', 'chrome_webgpu'],
    singleRun: true,
    customLaunchers: {
      chrome_webgpu: {
        base: 'Chrome',
        flags: [
          '--enable-unsafe-webgpu', '--enable-dawn-features=disable_robustness'
        ],
      }
    },
    client: {jasmine: {random: false}, args: args}
  })
}
<|endoftext|>


<commit_before>const webpack = require('webpack');
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
  context: path.join(__dirname, '../app'),
  devtool: 'inline-source-map',
  entry: {
    app: [
      'babel-polyfill',
      'react-hot-loader/patch',
      'webpack-dev-server/client?http://localhost:8080',
      'webpack/hot/only-dev-server',
      './src/main/js/index.js',
    ],
  },
  output: {
    path: path.resolve(__dirname, './app/build'),
    filename: 'app.bundle.js',
    publicPath: 'http://localhost:8080/',
  },
  devServer: {
    hot: true,
    publicPath: 'http://localhost:8080/',
    historyApiFallback: true,
  },
  module: {
    rules: [
      {
        exclude: /node_modules/,
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['react', 'es2015', 'stage-1'],
          },
        },
      },
      {
        exclude: /node_modules/,
        test: /\.sass$/,
        use: [
          {
            loader: 'style-loader/useable',
          },
          { loader: 'css-loader' },
          { loader: 'sass-loader' },
        ],
      },
    ],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
    new CopyWebpackPlugin([
            { from: './src/main/app.js' },
            { from: './src/main/index.html' },
            { from: './src/main/res', to: 'res' },
    ]),
  ],
};
<commit_msg>Configured ExtractTextPlugin<commit_after>const webpack = require('webpack');
const path = require('path');

const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  context: path.join(__dirname, '../app'),
  devtool: 'inline-source-map',
  entry: {
    app: [
      'babel-polyfill',
      'react-hot-loader/patch',
      'webpack-dev-server/client?http://localhost:8080',
      'webpack/hot/only-dev-server',
			'./src/main/res/css/main.sass',
      './src/main/js/index.js',
    ],
  },
  output: {
    path: path.resolve(__dirname, './app/build'),
    filename: 'app.bundle.js',
    publicPath: 'http://localhost:8080/',
  },
  devServer: {
    hot: true,
    publicPath: 'http://localhost:8080/',
    historyApiFallback: true,
  },
  module: {
    rules: [
      {
        exclude: /node_modules/,
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['react', 'es2015', 'stage-1'],
          },
        },
      },
      {
        exclude: /node_modules/,
        test: /\.sass$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: ['css-loader', 'sass-loader'],
				}),
      },
			{
				exclude: /node_modules/,
				test: /\.css$/,
				use: ExtractTextPlugin.extract({
          use: 'css-loader',
        }),
			}
    ],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
		new ExtractTextPlugin({filename: 'main.css', allChunks: true}),
		new HtmlWebpackPlugin({
      title: 'devRantron',
      template: 'src/main/index.ejs',
    }),
    new CopyWebpackPlugin([
            { from: './src/main/res', to: 'res' },
    ]),
  ],
};
<|endoftext|>


<commit_before>app.controller("HubsController", [
    "$scope",
    "$location",
    "$log",
    function ($scope, $location, $log) {
        'use strict';

        $log.debug("Hubs Controller Initialized");
    }]);
<commit_msg>Update tmp/controllers/hubsController.js<commit_after><|endoftext|>


<commit_before>// Colin 'Oka' Hall-Coates
// http://oka.io
// MIT, 2015

;(function ($) {
'use strict';

var def = Object.defineProperties,
    OP = Object.prototype,
    AP = Array.prototype,
    SP = String.prototype,
    NP = Number.prototype;

function $(g, s) {return {get: g, set: s};}

def(SP, {
  capitalize: $(function () {
    return this.substring(0, 1).toUpperCase() + this.substring(1);
  }),
  chars: $(function () {
    return this.split('');
  }),
  chr: $(function () {
    return this.substring(0, 1);
  }),
  downcase: $(function () {
    return this.toLowerCase();
  }),
  empty: $(function () {
    return this.length < 1;
  }),
  reverse: $(function () {
    var r = '', i = this.length - 1, e;
    for (e = 0; i >= e; i--) r += this[i];
    return r;
  }),
  upcase: $(function () {
    return this.toUpperCase();
  })
});

def(AP, {
  clear: $(function () {
    while (this.length > 0) this.pop(); return this;
  }),
  compact: $(function () {
    return this.filter(function (e) {
      return (typeof e !== 'undefined');
    });
  }),
  uniq: $(function () {
    var c = {};
    return this.filter(function (e) {
      return (c.hasOwnProperty(e) ? false : c[e] = true);
    });
  }),
});

def(OP, {
  array: $(function () {
    return Array.isArray(this);
  }),
  bool: $(function () {
    return typeof this === 'boolean';
  }),
  func: $(function () {
    return typeof this === 'function';
  }),
  numeric: $(function () {
    return typeof this === 'number' && this === this;
  }),
  object: $(function () {
    return !Array.isArray(this) && typeof this === 'object';
  }),
  size: $(function () {
    if (Array.isArray(this) ||
      typeof this === 'string' ||
      typeof this === 'function') return this.length;
    else if (typeof this === 'object') return Object.keys(this).length;
    else if (typeof this === 'number' && this === this) return this;
  }),
  string: $(function () {
    return typeof this === 'string' || this instanceof String;
  })
});

def(NP, {
  abs: $(function () {
    return Math.abs(this);
  }),
  finite: $(function () {
    return isFinite(this);
  }),
  floor: $(function () {
    return Math.floor(this);
  }),
  integer: $(function () {
    return this.toFixed() == this;
  }),
  polar: $(function () {
    return [Math.abs(this), (this > 0 ? 0 : Math.PI)];
  })
});

var _String = {
  _p: SP,
  prepend: function (o) {
    return o + this;
  }
};

var _Array = {
  _p: AP,
  drop: AP.slice,
  fetch: function(n, d) {
    if (typeof n !== 'number' || !isFinite(n)) throw new TypeError('Expected number');
    if (Math.abs(n) > this.length - 1 && typeof d === 'undefined') throw new RangeError('Index out of bounds');
    if (n < 0) n = this.length + n;
    return (typeof this[n] !== 'undefined' ? this[n] : d);
  },
  take: function (n) {
    return this.slice().splice(0, n);
  },
  valuesAt: function () {
    var a = Array.prototype.slice.call(arguments),
        s = this,
        o = [];

    a.forEach(function (e) {
      if (typeof e !== 'number' || !isFinite(e)) throw new TypeError('Expected index');
      if (e < 0) e = s.length + e;
      o.push(s[e]);
    });

    return o;
  },
  zip: function() {
    var a = Array.prototype.slice.call(arguments),
        o = [];

    this.forEach(function(e, i) {
      var q = [e];

      a.forEach(function(e) {
        if (!Array.isArray(e)) throw new TypeError('Expected type array');
        q.push(e[i]);
      });

      o.push(q);
    });

    return o;
  }
};

var _Object = {
  _p: OP,
  eql: function (o) {
    return this === o;
  }
};

var _Number = {
  _p: NP
};

function buildPrototypes(e) {
  for (var k in e) {
    if (k === '_p') continue;
    if (e.hasOwnProperty(k)) e._p[k] = (e._p[k] || e[k]);
  }
}

[_String, _Array, _Object, _Number].forEach(buildPrototypes);

}());<commit_msg>Number.prototype.round<commit_after>// Colin 'Oka' Hall-Coates
// http://oka.io
// MIT, 2015

;(function ($) {
'use strict';

var def = Object.defineProperties,
    OP = Object.prototype,
    AP = Array.prototype,
    SP = String.prototype,
    NP = Number.prototype;

function $(g, s) {return {get: g, set: s};}

def(SP, {
  capitalize: $(function () {
    return this.substring(0, 1).toUpperCase() + this.substring(1);
  }),
  chars: $(function () {
    return this.split('');
  }),
  chr: $(function () {
    return this.substring(0, 1);
  }),
  downcase: $(function () {
    return this.toLowerCase();
  }),
  empty: $(function () {
    return this.length < 1;
  }),
  reverse: $(function () {
    var r = '', i = this.length - 1, e;
    for (e = 0; i >= e; i--) r += this[i];
    return r;
  }),
  upcase: $(function () {
    return this.toUpperCase();
  })
});

def(AP, {
  clear: $(function () {
    while (this.length > 0) this.pop(); return this;
  }),
  compact: $(function () {
    return this.filter(function (e) {
      return (typeof e !== 'undefined');
    });
  }),
  uniq: $(function () {
    var c = {};
    return this.filter(function (e) {
      return (c.hasOwnProperty(e) ? false : c[e] = true);
    });
  }),
});

def(OP, {
  array: $(function () {
    return Array.isArray(this);
  }),
  bool: $(function () {
    return typeof this === 'boolean';
  }),
  func: $(function () {
    return typeof this === 'function';
  }),
  numeric: $(function () {
    return typeof this === 'number' && this === this;
  }),
  object: $(function () {
    return !Array.isArray(this) && typeof this === 'object';
  }),
  size: $(function () {
    if (Array.isArray(this) ||
      typeof this === 'string' ||
      typeof this === 'function') return this.length;
    else if (typeof this === 'object') return Object.keys(this).length;
    else if (typeof this === 'number' && this === this) return this;
  }),
  string: $(function () {
    return typeof this === 'string' || this instanceof String;
  })
});

def(NP, {
  abs: $(function () {
    return Math.abs(this);
  }),
  finite: $(function () {
    return isFinite(this);
  }),
  floor: $(function () {
    return Math.floor(this);
  }),
  integer: $(function () {
    return this.toFixed() == this;
  }),
  polar: $(function () {
    return [Math.abs(this), (this > 0 ? 0 : Math.PI)];
  }),
  round: $(function () {
    return Math.round(this);
  })
});

var _String = {
  _p: SP,
  prepend: function (o) {
    return o + this;
  }
};

var _Array = {
  _p: AP,
  drop: AP.slice,
  fetch: function(n, d) {
    if (typeof n !== 'number' || !isFinite(n)) throw new TypeError('Expected number');
    if (Math.abs(n) > this.length - 1 && typeof d === 'undefined') throw new RangeError('Index out of bounds');
    if (n < 0) n = this.length + n;
    return (typeof this[n] !== 'undefined' ? this[n] : d);
  },
  take: function (n) {
    return this.slice().splice(0, n);
  },
  valuesAt: function () {
    var a = Array.prototype.slice.call(arguments),
        s = this,
        o = [];

    a.forEach(function (e) {
      if (typeof e !== 'number' || !isFinite(e)) throw new TypeError('Expected index');
      if (e < 0) e = s.length + e;
      o.push(s[e]);
    });

    return o;
  },
  zip: function() {
    var a = Array.prototype.slice.call(arguments),
        o = [];

    this.forEach(function(e, i) {
      var q = [e];

      a.forEach(function(e) {
        if (!Array.isArray(e)) throw new TypeError('Expected type array');
        q.push(e[i]);
      });

      o.push(q);
    });

    return o;
  }
};

var _Object = {
  _p: OP,
  eql: function (o) {
    return this === o;
  }
};

var _Number = {
  _p: NP
};

function buildPrototypes(e) {
  for (var k in e) {
    if (k === '_p') continue;
    if (e.hasOwnProperty(k)) e._p[k] = (e._p[k] || e[k]);
  }
}

[_String, _Array, _Object, _Number].forEach(buildPrototypes);

}());<|endoftext|>


<commit_before>const words = require('lodash/words');
const capitalize = require('lodash/capitalize');
const { expect } = require('../setup');
const { runForAtLeast } = require('../lib/mocha-utils');
const cli = require('../lib/cli');
const {
	DEVICE_ID,
	DEVICE_PLATFORM_ID,
	DEVICE_PLATFORM_NAME
} = require('../lib/env');

describe('Serial Commands [@device]', () => {
	const help = [
		'Simple serial interface to your devices',
		'Usage: particle serial <command>',
		'Help:  particle help serial <command>',
		'',
		'Commands:',
		'  list      Show devices connected via serial to your computer',
		'  monitor   Connect and display messages from a device',
		'  identify  Ask for and display device ID via serial',
		'  wifi      Configure Wi-Fi credentials over serial',
		'  mac       Ask for and display MAC address via serial',
		'  inspect   Ask for and display device module information via serial',
		'  flash     Flash firmware over serial using YMODEM protocol',
		'  claim     Claim a device with the given claim code',
		'',
		'Global Options:',
		'  -v, --verbose  Increases how much logging to display  [count]',
		'  -q, --quiet    Decreases how much logging to display  [count]'
	];

	before(async () => {
		await cli.startListeningMode();
	});

	after(runForAtLeast(15, async () => {
		await cli.stopListeningMode();
	}));

	it('Shows `help` content', async () => {
		const { stdout, stderr, exitCode } = await cli.run(['help', 'serial']);

		expect(stdout).to.equal('');
		expect(stderr.split('\n')).to.include.members(help);
		expect(exitCode).to.equal(0);
	});

	it('Shows `help` content when run without arguments', async () => {
		const { stdout, stderr, exitCode } = await cli.run('serial');

		expect(stdout).to.equal('');
		expect(stderr.split('\n')).to.include.members(help);
		expect(exitCode).to.equal(0);
	});

	it('Shows `help` content when run with `--help` flag', async () => {
		const { stdout, stderr, exitCode } = await cli.run(['serial', '--help']);

		expect(stdout).to.equal('');
		expect(stderr.split('\n')).to.include.members(help);
		expect(exitCode).to.equal(0);
	});

	it('Lists devices', async () => {
		const platform = capitalize(DEVICE_PLATFORM_NAME);
		const { stdout, stderr, exitCode } = await cli.run(['serial', 'list']);

		expect(stdout).to.include('Found 1 device connected via serial');
		expect(stdout).to.include(platform);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Identifies device', async () => {
		const { stdout, stderr, exitCode } = await cli.run(['serial', 'identify']);

		expect(stdout).to.include(`Your device id is ${DEVICE_ID}`);
		expect(stdout).to.include('Your system firmware version is');
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Inspects device', async () => {
		const platform = capitalize(DEVICE_PLATFORM_NAME);
		const { stdout, stderr, exitCode } = await cli.run(['serial', 'inspect']);
		const pass = words(stdout).filter(w => w === 'PASS');

		expect(stdout).to.not.include('FAIL');
		expect(stdout).to.include(`Platform: ${DEVICE_PLATFORM_ID} - ${platform}`);
		expect(pass).to.have.lengthOf.at.least(16);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});
});

<commit_msg>Updating serial list test to look for Device ID in the command output.<commit_after>const words = require('lodash/words');
const capitalize = require('lodash/capitalize');
const { expect } = require('../setup');
const { runForAtLeast } = require('../lib/mocha-utils');
const cli = require('../lib/cli');
const {
	DEVICE_ID,
	DEVICE_PLATFORM_ID,
	DEVICE_PLATFORM_NAME
} = require('../lib/env');

describe('Serial Commands [@device]', () => {
	const help = [
		'Simple serial interface to your devices',
		'Usage: particle serial <command>',
		'Help:  particle help serial <command>',
		'',
		'Commands:',
		'  list      Show devices connected via serial to your computer',
		'  monitor   Connect and display messages from a device',
		'  identify  Ask for and display device ID via serial',
		'  wifi      Configure Wi-Fi credentials over serial',
		'  mac       Ask for and display MAC address via serial',
		'  inspect   Ask for and display device module information via serial',
		'  flash     Flash firmware over serial using YMODEM protocol',
		'  claim     Claim a device with the given claim code',
		'',
		'Global Options:',
		'  -v, --verbose  Increases how much logging to display  [count]',
		'  -q, --quiet    Decreases how much logging to display  [count]'
	];

	before(async () => {
		await cli.startListeningMode();
	});

	after(runForAtLeast(15, async () => {
		await cli.stopListeningMode();
	}));

	it('Shows `help` content', async () => {
		const { stdout, stderr, exitCode } = await cli.run(['help', 'serial']);

		expect(stdout).to.equal('');
		expect(stderr.split('\n')).to.include.members(help);
		expect(exitCode).to.equal(0);
	});

	it('Shows `help` content when run without arguments', async () => {
		const { stdout, stderr, exitCode } = await cli.run('serial');

		expect(stdout).to.equal('');
		expect(stderr.split('\n')).to.include.members(help);
		expect(exitCode).to.equal(0);
	});

	it('Shows `help` content when run with `--help` flag', async () => {
		const { stdout, stderr, exitCode } = await cli.run(['serial', '--help']);

		expect(stdout).to.equal('');
		expect(stderr.split('\n')).to.include.members(help);
		expect(exitCode).to.equal(0);
	});

	it('Lists devices', async () => {
		const platform = capitalize(DEVICE_PLATFORM_NAME);
		const { stdout, stderr, exitCode } = await cli.run(['serial', 'list']);

		expect(stdout).to.include('Found 1 device connected via serial');
		expect(stdout).to.include(`${platform} - ${DEVICE_ID}`);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Identifies device', async () => {
		const { stdout, stderr, exitCode } = await cli.run(['serial', 'identify']);

		expect(stdout).to.include(`Your device id is ${DEVICE_ID}`);
		expect(stdout).to.include('Your system firmware version is');
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Inspects device', async () => {
		const platform = capitalize(DEVICE_PLATFORM_NAME);
		const { stdout, stderr, exitCode } = await cli.run(['serial', 'inspect']);
		const pass = words(stdout).filter(w => w === 'PASS');

		expect(stdout).to.not.include('FAIL');
		expect(stdout).to.include(`Platform: ${DEVICE_PLATFORM_ID} - ${platform}`);
		expect(pass).to.have.lengthOf.at.least(16);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});
});

<|endoftext|>


<commit_before>/*
*     (C) Copyright 2008 Telefonica Investigacion y Desarrollo
*     S.A.Unipersonal (Telefonica I+D)
*
*     This file is part of Morfeo EzWeb Platform.
*
*     Morfeo EzWeb Platform is free software: you can redistribute it and/or modify
*     it under the terms of the GNU Affero General Public License as published by
*     the Free Software Foundation, either version 3 of the License, or
*     (at your option) any later version.
*
*     Morfeo EzWeb Platform is distributed in the hope that it will be useful,
*     but WITHOUT ANY WARRANTY; without even the implied warranty of
*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*     GNU Affero General Public License for more details.
*
*     You should have received a copy of the GNU Affero General Public License
*     along with Morfeo EzWeb Platform.  If not, see <http://www.gnu.org/licenses/>.
*
*     Info about members and contributors of the MORFEO project
*     is available at
*
*     http://morfeo-project.org
 */

/////////////////////////////////////
// FullDragboard
/////////////////////////////////////

/**
 * @class Represents a dragboard layout to be used to place igadgets into the dragboard.
 *
 * This dragobard uses percentages for horizontal units and px for vertical units.
 *
 * @extends DragboardLayout
 */
function FullDragboardLayout(dragboard, scrollbarSpace) {
	if (arguments.length == 0)
		return; // Allow empty constructor (allowing hierarchy)

	this.initialized = false;
	DragboardLayout.call(this, dragboard, scrollbarSpace);
}

FullDragboardLayout.prototype = new DragboardLayout();

FullDragboardLayout.prototype.fromPixelsToVCells = function(pixels) {
	return 1;
}

FullDragboardLayout.prototype.fromVCellsToPixels = function(cells) {
	return this.getHeight();
}

FullDragboardLayout.prototype.getWidthInPixels = function (cells) {
	return this.getWidth();
}

FullDragboardLayout.prototype.getHeightInPixels = function (cells) {
	return this.getHeight();
}

FullDragboardLayout.prototype.fromPixelsToHCells = function(pixels) {
	return 1;
}

FullDragboardLayout.prototype.fromHCellsToPixels = function(cells) {
	return this.getWidth();
}

FullDragboardLayout.prototype.fromHCellsToPercentage = function(cells) {
	return this.getHeight();
}

FullDragboardLayout.prototype.getColumnOffset = function(column) {
	return this.dragboard.dragboardElement.getBoundingClientRect().left;
}

FullDragboardLayout.prototype.getRowOffset = function(row) {
	return this.dragboard.dragboardElement.getBoundingClientRect().top;
}

FullDragboardLayout.prototype.adaptColumnOffset = function(pixels) {
	return new MultiValuedSize(this.dragboard.dragboardElement.getBoundingClientRect().left, 0);
}

FullDragboardLayout.prototype.adaptRowOffset = function(pixels) {
	return new MultiValuedSize(this.dragboard.dragboardElement.getBoundingClientRect().top, 0);
}

FullDragboardLayout.prototype.adaptHeight = function(contentHeight, fullSize) {
	var diff = fullSize - contentHeight;
	return new MultiValuedSize(contentHeight - diff, 1);
}

FullDragboardLayout.prototype.adaptWidth = function(contentWidth, fullSize) {
	return new MultiValuedSize(this.getWidth(), 1);
}

FullDragboardLayout.prototype.initialize = function () {
	var iGadget, i, key;

	// Insert igadgets
	var igadgetKeys = this.iGadgets.keys();
	for (i = 0; i < igadgetKeys.length; i++) {
		key = igadgetKeys[i];
		iGadget = this.iGadgets[key];
		iGadget.paint(true);
	}

	this.initialized = true;
}

/**
 * Calculate what cell is at a given position in pixels
 */
FullDragboardLayout.prototype.getCellAt = function (x, y) {
	return new DragboardPosition(0, 0);
}

FullDragboardLayout.prototype.addIGadget = function(iGadget, affectsDragboard) {
	iGadget.element.addClassName('fulldragboard');

	DragboardLayout.prototype.addIGadget.call(this, iGadget, affectsDragboard);

	if (!this.initialized)
		return;

	iGadget.setPosition(new DragboardPosition(0, 0));
}

FullDragboardLayout.prototype.removeIGadget = function(iGadget, affectsDragboard) {
	iGadget.element.removeClassName('fulldragboard');

	DragboardLayout.prototype.removeIGadget.call(this, iGadget, affectsDragboard);
}

FullDragboardLayout.prototype.initializeMove = function(igadget, draggable) {
	// Check for pendings moves
	if (this.igadgetToMove != null) {
		var msg = gettext("There was a pending move that was cancelled because initializedMove function was called before it was finished.")
		LogManagerFactory.getInstance().log(msg, Constants.WARN_MSG);
		this.cancelMove();
	}

	this.igadgetToMove = igadget;
}

FullDragboardLayout.prototype.moveTemporally = function(x, y) {
	if (this.igadgetToMove == null) {
		var msg = gettext("Dragboard: You must call initializeMove function before calling to this function (moveTemporally).");
		LogManagerFactory.getInstance().log(msg, Constants.WARN_MSG);
		return;
	}
}

FullDragboardLayout.prototype.acceptMove = function() {
	if (this.igadgetToMove == null) {
		var msg = gettext("Function acceptMove called when there is not an started igadget move.");
		LogManagerFactory.getInstance().log(msg, Constants.WARN_MSG);
		return;
	}

	this.igadgetToMove = null;
}

FullDragboardLayout.prototype.cancelMove = function() {
	if (this.igadgetToMove == null) {
		var msg = gettext("Trying to cancel an inexistant temporal move.");
		LogManagerFactory.getInstance().log(msg, Constants.WARN_MSG);
		return;
	}

	this.igadgetToMove._notifyWindowResizeEvent();
	this.igadgetToMove = null;
	this.newPosition = null;
}

FullDragboardLayout.prototype._notifyDragboardVisibilityChange = function(visibility) {
	// Notify each igadget
	var iGadget;
	var igadgetKeys = this.iGadgets.keys();
	if (visibility) {
		for (var i = 0; i < igadgetKeys.length; i++) {
			iGadget = this.iGadgets[igadgetKeys[i]];
			iGadget.element.style.position = null;
		}
	} else {
		for (var i = 0; i < igadgetKeys.length; i++) {
			iGadget = this.iGadgets[igadgetKeys[i]];
			iGadget.element.style.position = 'absolute';
		}
	}
}
<commit_msg>refs #490. Workaround IE bug.<commit_after>/*
*     (C) Copyright 2008 Telefonica Investigacion y Desarrollo
*     S.A.Unipersonal (Telefonica I+D)
*
*     This file is part of Morfeo EzWeb Platform.
*
*     Morfeo EzWeb Platform is free software: you can redistribute it and/or modify
*     it under the terms of the GNU Affero General Public License as published by
*     the Free Software Foundation, either version 3 of the License, or
*     (at your option) any later version.
*
*     Morfeo EzWeb Platform is distributed in the hope that it will be useful,
*     but WITHOUT ANY WARRANTY; without even the implied warranty of
*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*     GNU Affero General Public License for more details.
*
*     You should have received a copy of the GNU Affero General Public License
*     along with Morfeo EzWeb Platform.  If not, see <http://www.gnu.org/licenses/>.
*
*     Info about members and contributors of the MORFEO project
*     is available at
*
*     http://morfeo-project.org
 */

/////////////////////////////////////
// FullDragboard
/////////////////////////////////////

/**
 * @class Represents a dragboard layout to be used to place igadgets into the dragboard.
 *
 * This dragobard uses percentages for horizontal units and px for vertical units.
 *
 * @extends DragboardLayout
 */
function FullDragboardLayout(dragboard, scrollbarSpace) {
	if (arguments.length == 0)
		return; // Allow empty constructor (allowing hierarchy)

	this.initialized = false;
	DragboardLayout.call(this, dragboard, scrollbarSpace);
}

FullDragboardLayout.prototype = new DragboardLayout();

FullDragboardLayout.prototype.fromPixelsToVCells = function(pixels) {
	return 1;
}

FullDragboardLayout.prototype.fromVCellsToPixels = function(cells) {
	return this.getHeight();
}

FullDragboardLayout.prototype.getWidthInPixels = function (cells) {
	return this.getWidth();
}

FullDragboardLayout.prototype.getHeightInPixels = function (cells) {
	return this.getHeight();
}

FullDragboardLayout.prototype.fromPixelsToHCells = function(pixels) {
	return 1;
}

FullDragboardLayout.prototype.fromHCellsToPixels = function(cells) {
	return this.getWidth();
}

FullDragboardLayout.prototype.fromHCellsToPercentage = function(cells) {
	return this.getHeight();
}

FullDragboardLayout.prototype.getColumnOffset = function(column) {
	return this.dragboard.dragboardElement.getBoundingClientRect().left;
}

FullDragboardLayout.prototype.getRowOffset = function(row) {
	return this.dragboard.dragboardElement.getBoundingClientRect().top;
}

FullDragboardLayout.prototype.adaptColumnOffset = function(pixels) {
	return new MultiValuedSize(this.dragboard.dragboardElement.getBoundingClientRect().left, 0);
}

FullDragboardLayout.prototype.adaptRowOffset = function(pixels) {
	return new MultiValuedSize(this.dragboard.dragboardElement.getBoundingClientRect().top, 0);
}

FullDragboardLayout.prototype.adaptHeight = function(contentHeight, fullSize) {
	var diff = fullSize - contentHeight;
	return new MultiValuedSize(contentHeight - diff, 1);
}

FullDragboardLayout.prototype.adaptWidth = function(contentWidth, fullSize) {
	return new MultiValuedSize(this.getWidth(), 1);
}

FullDragboardLayout.prototype.initialize = function () {
	var iGadget, i, key;

	// Insert igadgets
	var igadgetKeys = this.iGadgets.keys();
	for (i = 0; i < igadgetKeys.length; i++) {
		key = igadgetKeys[i];
		iGadget = this.iGadgets[key];
		iGadget.paint(true);
	}

	this.initialized = true;
}

/**
 * Calculate what cell is at a given position in pixels
 */
FullDragboardLayout.prototype.getCellAt = function (x, y) {
	return new DragboardPosition(0, 0);
}

FullDragboardLayout.prototype.addIGadget = function(iGadget, affectsDragboard) {
	iGadget.element.addClassName('fulldragboard');

	DragboardLayout.prototype.addIGadget.call(this, iGadget, affectsDragboard);

	if (!this.initialized)
		return;

	iGadget.setPosition(new DragboardPosition(0, 0));
}

FullDragboardLayout.prototype.removeIGadget = function(iGadget, affectsDragboard) {
	iGadget.element.removeClassName('fulldragboard');

	DragboardLayout.prototype.removeIGadget.call(this, iGadget, affectsDragboard);
}

FullDragboardLayout.prototype.initializeMove = function(igadget, draggable) {
	// Check for pendings moves
	if (this.igadgetToMove != null) {
		var msg = gettext("There was a pending move that was cancelled because initializedMove function was called before it was finished.")
		LogManagerFactory.getInstance().log(msg, Constants.WARN_MSG);
		this.cancelMove();
	}

	this.igadgetToMove = igadget;
}

FullDragboardLayout.prototype.moveTemporally = function(x, y) {
	if (this.igadgetToMove == null) {
		var msg = gettext("Dragboard: You must call initializeMove function before calling to this function (moveTemporally).");
		LogManagerFactory.getInstance().log(msg, Constants.WARN_MSG);
		return;
	}
}

FullDragboardLayout.prototype.acceptMove = function() {
	if (this.igadgetToMove == null) {
		var msg = gettext("Function acceptMove called when there is not an started igadget move.");
		LogManagerFactory.getInstance().log(msg, Constants.WARN_MSG);
		return;
	}

	this.igadgetToMove = null;
}

FullDragboardLayout.prototype.cancelMove = function() {
	if (this.igadgetToMove == null) {
		var msg = gettext("Trying to cancel an inexistant temporal move.");
		LogManagerFactory.getInstance().log(msg, Constants.WARN_MSG);
		return;
	}

	this.igadgetToMove._notifyWindowResizeEvent();
	this.igadgetToMove = null;
	this.newPosition = null;
}

FullDragboardLayout.prototype._notifyDragboardVisibilityChange = function(visibility) {
	// Notify each igadget
	var iGadget;
	var igadgetKeys = this.iGadgets.keys();
	if (visibility) {
		for (var i = 0; i < igadgetKeys.length; i++) {
			iGadget = this.iGadgets[igadgetKeys[i]];
			iGadget.element.style.position = '';
		}
	} else {
		for (var i = 0; i < igadgetKeys.length; i++) {
			iGadget = this.iGadgets[igadgetKeys[i]];
			iGadget.element.style.position = 'absolute';
		}
	}
}
<|endoftext|>


<commit_before>/* eslint-env mocha */
'use strict'

const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const BlockService = require('ipfs-block-service')
const dagCBOR = require('ipld-dag-cbor')

const IPLDResolver = require('../src')

module.exports = (repo) => {
  describe('IPLD format support', () => {
    let data, cid

    before((done) => {
      const bs = new BlockService(repo)
      const resolver = new IPLDResolver({ blockService: bs })

      data = { now: Date.now() }

      dagCBOR.util.cid(data, (err, c) => {
        expect(err).to.not.exist()
        cid = c
        resolver.put(data, { cid }, done)
      })
    })

    describe('Dynamic format loading', () => {
      it('should fail to dynamically load format', (done) => {
        const bs = new BlockService(repo)
        const resolver = new IPLDResolver({
          blockService: bs,
          formats: []
        })

        resolver.get(cid, '/', (err) => {
          expect(err).to.exist()
          expect(err.message).to.equal('No resolver found for codec "dag-cbor"')
          done()
        })
      })

      it('should fail to dynamically load format via loadFormat option', (done) => {
        const errMsg = 'BOOM' + Date.now()
        const bs = new BlockService(repo)
        const resolver = new IPLDResolver({
          blockService: bs,
          formats: [],
          loadFormat (codec, callback) {
            if (codec !== 'dag-cbor') return callback(new Error('unexpected codec'))
            setTimeout(() => callback(new Error(errMsg)))
          }
        })

        resolver.get(cid, '/', (err) => {
          expect(err).to.exist()
          expect(err.message).to.equal(errMsg)
          done()
        })
      })

      it('should dynamically load missing format', (done) => {
        const bs = new BlockService(repo)
        const resolver = new IPLDResolver({
          blockService: bs,
          formats: [],
          loadFormat (codec, callback) {
            if (codec !== 'dag-cbor') return callback(new Error('unexpected codec'))
            setTimeout(() => callback(null, dagCBOR))
          }
        })

        resolver.get(cid, '/', (err, result) => {
          expect(err).to.not.exist()
          expect(result.value).to.eql(data)
          done()
        })
      })
    })
  })
}
<commit_msg>test: add test for not dynbamically loading existing format<commit_after>/* eslint-env mocha */
'use strict'

const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const BlockService = require('ipfs-block-service')
const dagCBOR = require('ipld-dag-cbor')

const IPLDResolver = require('../src')

module.exports = (repo) => {
  describe('IPLD format support', () => {
    let data, cid

    before((done) => {
      const bs = new BlockService(repo)
      const resolver = new IPLDResolver({ blockService: bs })

      data = { now: Date.now() }

      dagCBOR.util.cid(data, (err, c) => {
        expect(err).to.not.exist()
        cid = c
        resolver.put(data, { cid }, done)
      })
    })

    describe('Dynamic format loading', () => {
      it('should fail to dynamically load format', (done) => {
        const bs = new BlockService(repo)
        const resolver = new IPLDResolver({
          blockService: bs,
          formats: []
        })

        resolver.get(cid, '/', (err) => {
          expect(err).to.exist()
          expect(err.message).to.equal('No resolver found for codec "dag-cbor"')
          done()
        })
      })

      it('should fail to dynamically load format via loadFormat option', (done) => {
        const errMsg = 'BOOM' + Date.now()
        const bs = new BlockService(repo)
        const resolver = new IPLDResolver({
          blockService: bs,
          formats: [],
          loadFormat (codec, callback) {
            if (codec !== 'dag-cbor') return callback(new Error('unexpected codec'))
            setTimeout(() => callback(new Error(errMsg)))
          }
        })

        resolver.get(cid, '/', (err) => {
          expect(err).to.exist()
          expect(err.message).to.equal(errMsg)
          done()
        })
      })

      it('should dynamically load missing format', (done) => {
        const bs = new BlockService(repo)
        const resolver = new IPLDResolver({
          blockService: bs,
          formats: [],
          loadFormat (codec, callback) {
            if (codec !== 'dag-cbor') return callback(new Error('unexpected codec'))
            setTimeout(() => callback(null, dagCBOR))
          }
        })

        resolver.get(cid, '/', (err, result) => {
          expect(err).to.not.exist()
          expect(result.value).to.eql(data)
          done()
        })
      })

      it('should not dynamically load format added statically', (done) => {
        const bs = new BlockService(repo)
        const resolver = new IPLDResolver({
          blockService: bs,
          formats: [dagCBOR],
          loadFormat (codec) {
            throw new Error(`unexpected load format ${codec}`)
          }
        })

        resolver.get(cid, '/', (err, result) => {
          expect(err).to.not.exist()
          expect(result.value).to.eql(data)
          done()
        })
      })
    })
  })
}
<|endoftext|>


<commit_before>/* global describe, it */
const { expect } = require('chai')
const { copyFileSync } = require('fs')
const Seven = require('../../src/main')

const list = Seven.list
const mockDir = './test/_mock'
const tmpDir = './test/_tmp'

describe('Functional: list()', function () {
  it('should emit error on 7z error', function (done) {
    const archive = '/i/hope/this/is/not/where/your/archive/is'
    const seven = list(archive)
    seven.on('error', function (err) {
      expect(err).to.be.an.instanceof(Error)
      done()
    })
  })

  it('should emit error on spawn error', function (done) {
    const bin = '/i/hope/this/is/not/where/yout/7zip/bin/is'
    const seven = list('archive', {
      $bin: bin
    })
    seven.on('error', function (err) {
      expect(err).to.be.an.instanceof(Error)
      expect(err.code).to.equal('ENOENT')
      expect(err.syscall).to.equal(`spawn ${bin}`)
      expect(err.path).to.equal(bin)
      done()
    })
  })

  it('should set headers and footers infos', function (done) {
    const archiveBase = `${mockDir}/DirNew/ExtArchive.7z`
    const archive = `${tmpDir}/list-header-footer.7z`
    copyFileSync(archiveBase, archive)
    const seven = list(archive, { recursive: true })
    seven.on('end', function () {
      expect(seven.info.get('Physical Size')).to.equal('290')
      expect(seven.info.get('Type')).to.equal('7z')
      done()
    })
  })

  it('should single accept single $cherryPick as a string', function () {
    const seven = list('archive.7z', {
      $cherryPick: 'target1',
      $defer: true
    })
    expect(seven._args).to.contain('target1')
  })

  it('should multiple accept multiple $cherryPick as an array', function () {
    const seven = list('archive.7z', {
      $cherryPick: ['target1', 'target2'],
      $defer: true
    })
    expect(seven._args).to.contain('target1')
    expect(seven._args).to.contain('target2')
  })

  it('should accept $cherryPick and give the good values', function (done) {
    const archiveBase = `${mockDir}/DirNew/ExtArchive.7z`
    const archive = `${tmpDir}/list-exist.7z`
    copyFileSync(archiveBase, archive)
    const seven = list(archive, { recursive: true, $cherryPick: '*.txt' })
    const data = []
    const expectedData = [
      { attributes: '....A', size: 9, sizeCompressed: undefined, file: 'DirExt/root.txt' },
      { attributes: '....A', size: 9, sizeCompressed: undefined, file: 'DirExt/sub1/sub1.txt' },
      { attributes: '....A', size: 9, sizeCompressed: undefined, file: 'DirExt/sub2/sub2.txt' }
    ]
    seven.on('data', d => data.push(d))
    seven.on('end', function () {
      const withoutDatetime = data
        .map(function (d) {
          const { datetime, ...rest } = d
          return rest
        })
      const dates = data.map(d => d.datetime)
      for (const d of dates) {
        expect(d).to.be.a('date')
      }
      expect(withoutDatetime).to.deep.contain(expectedData[0])
      expect(withoutDatetime).to.deep.contain(expectedData[1])
      expect(withoutDatetime).to.deep.contain(expectedData[2])
      expect(data.length).to.equal(3)
      done()
    })
  })

  it('should emit data', function (done) {
    const archiveBase = `${mockDir}/DirNew/ExtArchive.7z`
    const archive = `${tmpDir}/list-data.7z`
    copyFileSync(archiveBase, archive)
    let counter = 0
    const seven = list(archive, { recursive: true })
    seven.on('data', function (data) {
      ++counter
      expect(data.file).to.be.a('string')
    }).on('end', function () {
      expect(counter).to.be.equal(12)
      done()
    })
  })

  it('should NOT emit progress', function (done) {
    const archiveBase = `${mockDir}/DirNew/ExtArchive.7z`
    const archive = `${tmpDir}/list-progress.7z`
    copyFileSync(archiveBase, archive)
    let once = false
    const seven = list(archive, {
      recursive: true,
      $progress: true
    })
    seven.on('progress', function (progress) {
      once = true
      expect(progress.percent).to.be.an('number')
      expect(progress.fileCount).to.be.an('number')
    }).on('end', function () {
      expect(once).to.be.equal(false)
      done()
    })
  })

  it('should work with atlernate $bin', function (done) {
    const archiveBase = `${mockDir}/DirNew/ExtArchive.7z`
    const archive = `${tmpDir}/list-path.7z`
    copyFileSync(archiveBase, archive)
    let counter = 0
    const seven = list(archive, {
      recursive: true,
      $bin: `${tmpDir}/Seven Zip`
    })
    seven.on('data', function (data) {
      ++counter
      expect(data.file).to.be.a('string')
    }).on('end', function () {
      expect(counter).to.be.equal(12)
      done()
    })
  })

  it('should list technical data', function (done) {
    const archiveBase = `${mockDir}/DirNew/NewArchive.7z`
    const archive = `${tmpDir}/list-slt.7z`
    copyFileSync(archiveBase, archive)
    let technical_data = []
    let integrity_test = false
    const seven = list(archive,
      { techInfo: true }
    )
    seven.on('data', function (data) {
      technical_data.push(data)
      expect(data.file).to.be.a('string')
      if (data.file === 'DirHex/sub2/f930abffa355e') {
        expect(data.techInfo.get('Path')).to.equal('DirHex/sub2/f930abffa355e')
        expect(data.techInfo.get('Size')).to.equal('9')
        expect(data.techInfo.get('Modified')).to.equal('2018-09-29 09:06:15')
        expect(data.techInfo.get('CRC')).to.equal('FEDC304F')
        expect(data.techInfo.get('Encrypted')).to.equal('-')
        expect(data.techInfo.get('Method')).to.equal('LZMA2:12')
        expect(data.techInfo.get('Block')).to.equal('0')
        integrity_test = true
      }
    }).on('end', function () {
      expect(seven.info.get('Blocks')).to.equal('1')
      expect(technical_data.length).to.equal(30)
      expect(integrity_test).to.equal(true)
      done()
    })
  })

  it('should list technical data of zip archives', function (done) {
    const archiveBase = `${mockDir}/DirNew/NewArchive.zip`
    const archive = `${tmpDir}/list-slt.zip`
    copyFileSync(archiveBase, archive)
    let technical_data = []
    let integrity_test = false
    const seven = list(archive,
      { techInfo: true }
    )
    seven.on('data', function (data) {
      technical_data.push(data)
      expect(data.file).to.be.a('string')
      if (data.file === 'DirHex/sub2/f930abffa355e') {
        expect(data.techInfo.get('Path')).to.equal('DirHex/sub2/f930abffa355e')
        expect(data.techInfo.get('Size')).to.equal('9')
        expect(data.techInfo.get('Modified')).to.equal('2018-09-29 09:06:15')
        expect(data.techInfo.get('CRC')).to.equal('FEDC304F')
        expect(data.techInfo.get('Encrypted')).to.equal('-')
        expect(data.techInfo.get('Method')).to.equal('Store')
        expect(data.techInfo.get('Offset')).to.equal('1698')
        integrity_test = true
      }
    }).on('end', function () {
      expect(seven.info.get('Type')).to.equal('zip')
      expect(technical_data.length).to.equal(30)
      expect(integrity_test).to.equal(true)
      done()
    })
  })
})
<commit_msg>test: Don't test dates because AppVeyor changes them<commit_after>/* global describe, it */
const { expect } = require('chai')
const { copyFileSync } = require('fs')
const Seven = require('../../src/main')

const list = Seven.list
const mockDir = './test/_mock'
const tmpDir = './test/_tmp'

describe('Functional: list()', function () {
  it('should emit error on 7z error', function (done) {
    const archive = '/i/hope/this/is/not/where/your/archive/is'
    const seven = list(archive)
    seven.on('error', function (err) {
      expect(err).to.be.an.instanceof(Error)
      done()
    })
  })

  it('should emit error on spawn error', function (done) {
    const bin = '/i/hope/this/is/not/where/yout/7zip/bin/is'
    const seven = list('archive', {
      $bin: bin
    })
    seven.on('error', function (err) {
      expect(err).to.be.an.instanceof(Error)
      expect(err.code).to.equal('ENOENT')
      expect(err.syscall).to.equal(`spawn ${bin}`)
      expect(err.path).to.equal(bin)
      done()
    })
  })

  it('should set headers and footers infos', function (done) {
    const archiveBase = `${mockDir}/DirNew/ExtArchive.7z`
    const archive = `${tmpDir}/list-header-footer.7z`
    copyFileSync(archiveBase, archive)
    const seven = list(archive, { recursive: true })
    seven.on('end', function () {
      expect(seven.info.get('Physical Size')).to.equal('290')
      expect(seven.info.get('Type')).to.equal('7z')
      done()
    })
  })

  it('should single accept single $cherryPick as a string', function () {
    const seven = list('archive.7z', {
      $cherryPick: 'target1',
      $defer: true
    })
    expect(seven._args).to.contain('target1')
  })

  it('should multiple accept multiple $cherryPick as an array', function () {
    const seven = list('archive.7z', {
      $cherryPick: ['target1', 'target2'],
      $defer: true
    })
    expect(seven._args).to.contain('target1')
    expect(seven._args).to.contain('target2')
  })

  it('should accept $cherryPick and give the good values', function (done) {
    const archiveBase = `${mockDir}/DirNew/ExtArchive.7z`
    const archive = `${tmpDir}/list-exist.7z`
    copyFileSync(archiveBase, archive)
    const seven = list(archive, { recursive: true, $cherryPick: '*.txt' })
    const data = []
    const expectedData = [
      { attributes: '....A', size: 9, sizeCompressed: undefined, file: 'DirExt/root.txt' },
      { attributes: '....A', size: 9, sizeCompressed: undefined, file: 'DirExt/sub1/sub1.txt' },
      { attributes: '....A', size: 9, sizeCompressed: undefined, file: 'DirExt/sub2/sub2.txt' }
    ]
    seven.on('data', d => data.push(d))
    seven.on('end', function () {
      const withoutDatetime = data
        .map(function (d) {
          const { datetime, ...rest } = d
          return rest
        })
      const dates = data.map(d => d.datetime)
      for (const d of dates) {
        expect(d).to.be.a('date')
      }
      expect(withoutDatetime).to.deep.contain(expectedData[0])
      expect(withoutDatetime).to.deep.contain(expectedData[1])
      expect(withoutDatetime).to.deep.contain(expectedData[2])
      expect(data.length).to.equal(3)
      done()
    })
  })

  it('should emit data', function (done) {
    const archiveBase = `${mockDir}/DirNew/ExtArchive.7z`
    const archive = `${tmpDir}/list-data.7z`
    copyFileSync(archiveBase, archive)
    let counter = 0
    const seven = list(archive, { recursive: true })
    seven.on('data', function (data) {
      ++counter
      expect(data.file).to.be.a('string')
    }).on('end', function () {
      expect(counter).to.be.equal(12)
      done()
    })
  })

  it('should NOT emit progress', function (done) {
    const archiveBase = `${mockDir}/DirNew/ExtArchive.7z`
    const archive = `${tmpDir}/list-progress.7z`
    copyFileSync(archiveBase, archive)
    let once = false
    const seven = list(archive, {
      recursive: true,
      $progress: true
    })
    seven.on('progress', function (progress) {
      once = true
      expect(progress.percent).to.be.an('number')
      expect(progress.fileCount).to.be.an('number')
    }).on('end', function () {
      expect(once).to.be.equal(false)
      done()
    })
  })

  it('should work with atlernate $bin', function (done) {
    const archiveBase = `${mockDir}/DirNew/ExtArchive.7z`
    const archive = `${tmpDir}/list-path.7z`
    copyFileSync(archiveBase, archive)
    let counter = 0
    const seven = list(archive, {
      recursive: true,
      $bin: `${tmpDir}/Seven Zip`
    })
    seven.on('data', function (data) {
      ++counter
      expect(data.file).to.be.a('string')
    }).on('end', function () {
      expect(counter).to.be.equal(12)
      done()
    })
  })

  it('should list technical data', function (done) {
    const archiveBase = `${mockDir}/DirNew/NewArchive.7z`
    const archive = `${tmpDir}/list-slt.7z`
    copyFileSync(archiveBase, archive)
    let technical_data = []
    let integrity_test = false
    const seven = list(archive,
      { techInfo: true }
    )
    seven.on('data', function (data) {
      technical_data.push(data)
      expect(data.file).to.be.a('string')
      if (data.file === 'DirHex/sub2/f930abffa355e') {
        expect(data.techInfo.get('Path')).to.equal('DirHex/sub2/f930abffa355e')
        expect(data.techInfo.get('Size')).to.equal('9')
        expect(data.techInfo.get('CRC')).to.equal('FEDC304F')
        expect(data.techInfo.get('Encrypted')).to.equal('-')
        expect(data.techInfo.get('Method')).to.equal('LZMA2:12')
        expect(data.techInfo.get('Block')).to.equal('0')
        integrity_test = true
      }
    }).on('end', function () {
      expect(seven.info.get('Blocks')).to.equal('1')
      expect(technical_data.length).to.equal(30)
      expect(integrity_test).to.equal(true)
      done()
    })
  })

  it('should list technical data of zip archives', function (done) {
    const archiveBase = `${mockDir}/DirNew/NewArchive.zip`
    const archive = `${tmpDir}/list-slt.zip`
    copyFileSync(archiveBase, archive)
    let technical_data = []
    let integrity_test = false
    const seven = list(archive,
      { techInfo: true }
    )
    seven.on('data', function (data) {
      technical_data.push(data)
      expect(data.file).to.be.a('string')
      if (data.file === 'DirHex/sub2/f930abffa355e') {
        expect(data.techInfo.get('Path')).to.equal('DirHex/sub2/f930abffa355e')
        expect(data.techInfo.get('Size')).to.equal('9')
        expect(data.techInfo.get('CRC')).to.equal('FEDC304F')
        expect(data.techInfo.get('Encrypted')).to.equal('-')
        expect(data.techInfo.get('Method')).to.equal('Store')
        expect(data.techInfo.get('Offset')).to.equal('1698')
        integrity_test = true
      }
    }).on('end', function () {
      expect(seven.info.get('Type')).to.equal('zip')
      expect(technical_data.length).to.equal(30)
      expect(integrity_test).to.equal(true)
      done()
    })
  })
})
<|endoftext|>


<commit_before>/* global describe,it */
var //path = require("path"),
    url = require("url"),
    //http = require("http"),
    temp = require("temp"),
    //shell = require("shelljs"),
    log = require('npmlog'),
    nopt = require('nopt'),
    should = require("should"),
    //request = require("request"),
    rimraf = require("rimraf"),
    util = require("util"),
    async = require("async");

var knownOpts = {
	"proxy": url,
	"level": ['silly', 'verbose', 'info', 'http', 'warn', 'error']
};
var shortHands = {
	"p": "--proxy",
	"l": "--level",
	"v": "--level verbose"
};
var opt = nopt(knownOpts, shortHands, process.argv, 2 /*drop 'node' & basename*/);
log.heading = 'generator.spec';
log.level = opt.level || 'error';
log.info("opt:", opt);

var generator = require("./../ares-generator.js");

var badConfigs = [
	undefined,
	[],
	{},
	{ foo: "bar" },
	{ sources: [ {} ] },
	{ sources: [ { _id: "my-id", type: "my-type", description: "my-description", files: [] } ] },
	{ sources: [ { id: "my-id", _type: "my-type", description: "my-description", files: [] } ] },
	{ sources: [ { id: "my-id", type: "my-type", _description: "my-description", files: [] } ] },
	{ sources: [ { id: "my-id", type: "my-type", description: "my-description", _files: [] } ] },
	{ sources: [
		{ id: "id1", type: "my-type", description: "my-description", files: [] },
		{ id: "id2", type: "my-type", description: "my-description", _files: [] }
	] },
	{ eof: null }
];

var configOk = {
	"proxyUrl": opt.proxy || process.env['http_proxy'],
	"sources": [
		{
			"id": "bootplate-nightly",
			"type": "template",
			"files": [
				{
					"url": "http://nightly.enyojs.com/latest/bootplate-latest.zip",
					"prefixToRemove": "bootplate",
					"excluded": [
						"bootplate/api"
					]
				}
			],
			"description": "Enyo bootplate for webOS - Nightly"
		},
		{
			"id": "bootplate-2.2.0",
			"type": "template",
			"files": [
				{
					"url": "http://enyojs.com/archive/bootplate-2.2.0.zip",
					"prefixToRemove": "bootplate",
					"excluded": [
						"bootplate/api"
					]
				}
			],
			"description": "Enyo bootplate 2.2.0"
		},
		{
			"id": "bootplate-2.1.1",
			"type": "template",
			"files": [
				{
					"url": "http://enyojs.com/archive/bootplate-2.1.1.zip",
					"prefixToRemove": "bootplate",
					"excluded": [
						"bootplate/api"
					]
				}
			],
			"description": "Enyo bootplate 2.1.1"
		}
	]
};

describe("Testing generator", function() {

	badConfigs.forEach(function(config) {
		log.info("t1", "---- ");
		it("t1. should fail to instanciate a code generator", function(done) {
			log.verbose("config:" + util.inspect(config));
			generator.create(config, function(err, gen) {
				log.verbose("t1", "err:", err);
				should.exist(err);
				should.not.exist(gen);
				done();
			});
		});
	});

	log.info("t2", "---- ");
	it("t2. should instanciate a code generator (real-world config)", function(done) {
		generator.create(configOk, function(err, gen) {
			should.not.exist(err);
			should.exist(gen);
			done();
		});
	});

	log.info("t3", "---- ");
	it("t3. should generate a config based on one file", function(done) {
		var ctx = {};
		async.waterfall([
			generator.create.bind(generator, {sources: [{
				id: "my-id",
				type: "my-type",
				description: "my-description",
				files: [{
					url: __filename,
					installAs: "foo.js"
				}]
			}]}),
			function(gen, next) {
				log.silly("t3-1", "arguments", arguments);
				ctx.gen = gen;
				ctx.tmpDir = temp.path({prefix: "generator.spec."});
				ctx.gen.generate(["my-id"], null /*subst*/, ctx.tmpDir /*dest*/, null /*options*/, next);
			},
			function(filelist, next) {
				log.silly("t3-2", "arguments", arguments);
				log.info("t3", "filelist:", filelist);
				// XXX each item in filelist should
				// XXX include only files & be
				// XXX relative to the desination dir.
				next();
			}
		], function(err) {
			should.not.exist(err);
			rimraf(ctx.tmpDir, done);
		});
	});

	log.info("t4", "---- ");
	it("t4. should generate a config based on one folder", function(done) {
		var ctx = {};
		async.waterfall([
			generator.create.bind(generator, {sources: [{
				id: "my-id",
				type: "my-type",
				description: "my-description",
				files: [{
					url: __dirname
				}]
			}]}),
			function(gen, next) {
				log.silly("t4-1", "arguments", arguments);
				ctx.gen = gen;
				ctx.tmpDir = temp.path({prefix: "generator.spec."});
				ctx.gen.generate(["my-id"], null /*subst*/, ctx.tmpDir /*dest*/, null /*options*/, next);
			},
			function(filelist, next) {
				log.silly("t4-2", "arguments", arguments);
				log.info("t4", "filelist:", filelist);
				should.exist(filelist);
				filelist.should.be.an.instanceOf(Array);
				filelist.length.should.equal(3);
				// XXX each item in filelist should
				// XXX include only files & be
				// XXX relative to the desination dir.
				next();
			}
		], function(err) {
			should.not.exist(err);
			rimraf(ctx.tmpDir, done);
		});
	});

	log.info("t5", "---- ");
	it("t5. should generate a config based on one folder (with exclusion)", function(done) {
		var ctx = {};
		async.waterfall([
			generator.create.bind(generator, {sources: [{
				id: "my-id",
				type: "my-type",
				description: "my-description",
				files: [{
					url: __dirname,
					filterOut: "\.js$"
				}]
			}]}),
			function(gen, next) {
				log.silly("t5-1", "arguments", arguments);
				ctx.gen = gen;
				ctx.tmpDir = temp.path({prefix: "generator.spec."});
				ctx.gen.generate(["my-id"], null /*subst*/, ctx.tmpDir /*dest*/, null /*options*/, next);
			},
			function(filelist, next) {
				log.silly("t5-2", "arguments", arguments);
				log.info("t5", "filelist:", filelist);
				should.exist(filelist);
				filelist.should.be.an.instanceOf(Array);
				filelist.length.should.equal(3);
				// XXX each item in filelist should
				// XXX include only files & be
				// XXX relative to the desination dir.
				next();
			}
		], function(err) {
			should.not.exist(err);
			rimraf(ctx.tmpDir, done);
		});
	});
});
<commit_msg>ENYO-2935: jshint: fix bad escaping<commit_after>/* global describe,it */
var //path = require("path"),
    url = require("url"),
    //http = require("http"),
    temp = require("temp"),
    //shell = require("shelljs"),
    log = require('npmlog'),
    nopt = require('nopt'),
    should = require("should"),
    //request = require("request"),
    rimraf = require("rimraf"),
    util = require("util"),
    async = require("async");

var knownOpts = {
	"proxy": url,
	"level": ['silly', 'verbose', 'info', 'http', 'warn', 'error']
};
var shortHands = {
	"p": "--proxy",
	"l": "--level",
	"v": "--level verbose"
};
var opt = nopt(knownOpts, shortHands, process.argv, 2 /*drop 'node' & basename*/);
log.heading = 'generator.spec';
log.level = opt.level || 'error';
log.info("opt:", opt);

var generator = require("./../ares-generator.js");

var badConfigs = [
	undefined,
	[],
	{},
	{ foo: "bar" },
	{ sources: [ {} ] },
	{ sources: [ { _id: "my-id", type: "my-type", description: "my-description", files: [] } ] },
	{ sources: [ { id: "my-id", _type: "my-type", description: "my-description", files: [] } ] },
	{ sources: [ { id: "my-id", type: "my-type", _description: "my-description", files: [] } ] },
	{ sources: [ { id: "my-id", type: "my-type", description: "my-description", _files: [] } ] },
	{ sources: [
		{ id: "id1", type: "my-type", description: "my-description", files: [] },
		{ id: "id2", type: "my-type", description: "my-description", _files: [] }
	] },
	{ eof: null }
];

var configOk = {
	"proxyUrl": opt.proxy || process.env['http_proxy'],
	"sources": [
		{
			"id": "bootplate-nightly",
			"type": "template",
			"files": [
				{
					"url": "http://nightly.enyojs.com/latest/bootplate-latest.zip",
					"prefixToRemove": "bootplate",
					"excluded": [
						"bootplate/api"
					]
				}
			],
			"description": "Enyo bootplate for webOS - Nightly"
		},
		{
			"id": "bootplate-2.2.0",
			"type": "template",
			"files": [
				{
					"url": "http://enyojs.com/archive/bootplate-2.2.0.zip",
					"prefixToRemove": "bootplate",
					"excluded": [
						"bootplate/api"
					]
				}
			],
			"description": "Enyo bootplate 2.2.0"
		},
		{
			"id": "bootplate-2.1.1",
			"type": "template",
			"files": [
				{
					"url": "http://enyojs.com/archive/bootplate-2.1.1.zip",
					"prefixToRemove": "bootplate",
					"excluded": [
						"bootplate/api"
					]
				}
			],
			"description": "Enyo bootplate 2.1.1"
		}
	]
};

describe("Testing generator", function() {

	badConfigs.forEach(function(config) {
		log.info("t1", "---- ");
		it("t1. should fail to instanciate a code generator", function(done) {
			log.verbose("config:" + util.inspect(config));
			generator.create(config, function(err, gen) {
				log.verbose("t1", "err:", err);
				should.exist(err);
				should.not.exist(gen);
				done();
			});
		});
	});

	log.info("t2", "---- ");
	it("t2. should instanciate a code generator (real-world config)", function(done) {
		generator.create(configOk, function(err, gen) {
			should.not.exist(err);
			should.exist(gen);
			done();
		});
	});

	log.info("t3", "---- ");
	it("t3. should generate a config based on one file", function(done) {
		var ctx = {};
		async.waterfall([
			generator.create.bind(generator, {sources: [{
				id: "my-id",
				type: "my-type",
				description: "my-description",
				files: [{
					url: __filename,
					installAs: "foo.js"
				}]
			}]}),
			function(gen, next) {
				log.silly("t3-1", "arguments", arguments);
				ctx.gen = gen;
				ctx.tmpDir = temp.path({prefix: "generator.spec."});
				ctx.gen.generate(["my-id"], null /*subst*/, ctx.tmpDir /*dest*/, null /*options*/, next);
			},
			function(filelist, next) {
				log.silly("t3-2", "arguments", arguments);
				log.info("t3", "filelist:", filelist);
				// XXX each item in filelist should
				// XXX include only files & be
				// XXX relative to the desination dir.
				next();
			}
		], function(err) {
			should.not.exist(err);
			rimraf(ctx.tmpDir, done);
		});
	});

	log.info("t4", "---- ");
	it("t4. should generate a config based on one folder", function(done) {
		var ctx = {};
		async.waterfall([
			generator.create.bind(generator, {sources: [{
				id: "my-id",
				type: "my-type",
				description: "my-description",
				files: [{
					url: __dirname
				}]
			}]}),
			function(gen, next) {
				log.silly("t4-1", "arguments", arguments);
				ctx.gen = gen;
				ctx.tmpDir = temp.path({prefix: "generator.spec."});
				ctx.gen.generate(["my-id"], null /*subst*/, ctx.tmpDir /*dest*/, null /*options*/, next);
			},
			function(filelist, next) {
				log.silly("t4-2", "arguments", arguments);
				log.info("t4", "filelist:", filelist);
				should.exist(filelist);
				filelist.should.be.an.instanceOf(Array);
				filelist.length.should.equal(3);
				// XXX each item in filelist should
				// XXX include only files & be
				// XXX relative to the desination dir.
				next();
			}
		], function(err) {
			should.not.exist(err);
			rimraf(ctx.tmpDir, done);
		});
	});

	log.info("t5", "---- ");
	it("t5. should generate a config based on one folder (with exclusion)", function(done) {
		var ctx = {};
		async.waterfall([
			generator.create.bind(generator, {sources: [{
				id: "my-id",
				type: "my-type",
				description: "my-description",
				files: [{
					url: __dirname,
					filterOut: "\\.js$"
				}]
			}]}),
			function(gen, next) {
				log.silly("t5-1", "arguments", arguments);
				ctx.gen = gen;
				ctx.tmpDir = temp.path({prefix: "generator.spec."});
				ctx.gen.generate(["my-id"], null /*subst*/, ctx.tmpDir /*dest*/, null /*options*/, next);
			},
			function(filelist, next) {
				log.silly("t5-2", "arguments", arguments);
				log.info("t5", "filelist:", filelist);
				should.exist(filelist);
				filelist.should.be.an.instanceOf(Array);
				filelist.length.should.equal(3);
				// XXX each item in filelist should
				// XXX include only files & be
				// XXX relative to the desination dir.
				next();
			}
		], function(err) {
			should.not.exist(err);
			rimraf(ctx.tmpDir, done);
		});
	});
});
<|endoftext|>


<commit_before>dojo.provide("dijit.form.CurrencyTextBox");

dojo.require("dojo.currency");
dojo.require("dijit.form.NumberTextBox");

/*=====
dojo.declare(
	"dijit.form.CurrencyTextBox.__Constraints",
	[dijit.form.NumberTextBox.__Constraints, dojo.currency.__FormatOptions, dojo.currency.__ParseOptions]
);
=====*/

dojo.declare(
	"dijit.form.CurrencyTextBox",
	dijit.form.NumberTextBox,
	{
		// summary:
		//		A validating currency textbox

		// currency: String
		//		the [ISO4217](http://en.wikipedia.org/wiki/ISO_4217) currency code, a three letter sequence like "USD"
		currency: "",

		/*=====
		// constraints: dijit.form.CurrencyTextBox.__Constraints
		//		Minimum/maximum amount allowed.
		constraints: {},
		======*/

		// Override regExpGen ValidationTextBox.regExpGen().... we use a reg-ex generating function rather
		// than a straight regexp to deal with locale  (plus formatting options too?)
		regExpGen: function(constraints){
			return this._focused? dojo.number.regexp(dojo.mixin({}, constraints, this.editOptions, {type: 'decimal'})) : dojo.currency.regexp(constraints);
		},

		// Override NumberTextBox._formatter to deal with currencies, ex: converts "123.45" to "$123.45"
		_formatter: dojo.currency.format,

/*=====
		parse: function(value, constraints){
			// summary:
			//		Parses string as a Currency, according to constraints
			// value: String
			//		The currency represented as a string
			// constraints: dojo.currency.__ParseOptions
			// tags:
			//		protected

			return 123.45;		// Number
		},
=====*/
		parse: dojo.currency.parse,

		postMixInProperties: function(){
			this.constraints.currency = this.currency;
			this.inherited(arguments);
		}
	}
);
<commit_msg>make api doc section contiguous.  Refs #7020<commit_after>dojo.provide("dijit.form.CurrencyTextBox");

dojo.require("dojo.currency");
dojo.require("dijit.form.NumberTextBox");

/*=====
dojo.declare(
	"dijit.form.CurrencyTextBox.__Constraints",
	[dijit.form.NumberTextBox.__Constraints, dojo.currency.__FormatOptions, dojo.currency.__ParseOptions]
);
=====*/

dojo.declare(
	"dijit.form.CurrencyTextBox",
	dijit.form.NumberTextBox,
	{
		// summary:
		//		A validating currency textbox
		//
		// currency: String
		//		the [ISO4217](http://en.wikipedia.org/wiki/ISO_4217) currency code, a three letter sequence like "USD"
		currency: "",
		//
		// constraints: dijit.form.CurrencyTextBox.__Constraints
		//		Minimum/maximum amount allowed.
		/*=====
		constraints: {},
		======*/

		// Override regExpGen ValidationTextBox.regExpGen().... we use a reg-ex generating function rather
		// than a straight regexp to deal with locale  (plus formatting options too?)
		regExpGen: function(constraints){
			return this._focused? dojo.number.regexp(dojo.mixin({}, constraints, this.editOptions, {type: 'decimal'})) : dojo.currency.regexp(constraints);
		},

		// Override NumberTextBox._formatter to deal with currencies, ex: converts "123.45" to "$123.45"
		_formatter: dojo.currency.format,

/*=====
		parse: function(value, constraints){
			// summary:
			//		Parses string as a Currency, according to constraints
			// value: String
			//		The currency represented as a string
			// constraints: dojo.currency.__ParseOptions
			// tags:
			//		protected

			return 123.45;		// Number
		},
=====*/
		parse: dojo.currency.parse,

		postMixInProperties: function(){
			this.constraints.currency = this.currency;
			this.inherited(arguments);
		}
	}
);
<|endoftext|>


<commit_before>import Promise from 'bluebird';
import fetch from './utils/fetch';

function urlBase64ToUint8Array(base64String) {
  const padding = '='.repeat((4 - base64String.length % 4) % 4);
  const base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/');

  const rawData = atob(base64);
  const outputArray = new Uint8Array(rawData.length);

  for (let i = 0; i < rawData.length; ++i) {
    outputArray[i] = rawData.charCodeAt(i);
  }
  return outputArray;
}

async function getSubscription(pushManager) {
  const subscription = await pushManager.getSubscription();
  if (subscription) return subscription;

  const response = await fetch('/api/push-service/public-key');
  const publicKey = await response.text();
  const applicationServerKey = urlBase64ToUint8Array(publicKey);
  return pushManager.subscribe({ userVisibleOnly: true, applicationServerKey });
}

async function persistRegistration(subscription) {
  while (true) {
    try {
      await fetch('/api/push-service/register', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(subscription),
      });
    } catch (error) {
      console.error('Error during service worker registration', error);
    }

    await Promise.delay(5 * 60 * 1000);
  }
}

export default function register() {
  if ('serviceWorker' in navigator) {
    window.addEventListener('load', async () => {
      const swUrl = `${process.env.PUBLIC_URL}/service-worker.bundle.js`;
      try {
        const registration = await navigator.serviceWorker.register(swUrl);

        Notification.requestPermission();

        const subscription = await getSubscription(registration.pushManager);
        persistRegistration(subscription);
      } catch (error) {
        console.error('Error during service worker registration:', error);
      }
    });
  }
}

export function unregister() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.ready.then((registration) => {
      registration.unregister();
    });
  }
}
<commit_msg>unregister service worker if unable to register to push notifications<commit_after>import Promise from 'bluebird';
import fetch from './utils/fetch';

function urlBase64ToUint8Array(base64String) {
  const padding = '='.repeat((4 - base64String.length % 4) % 4);
  const base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/');

  const rawData = atob(base64);
  const outputArray = new Uint8Array(rawData.length);

  for (let i = 0; i < rawData.length; ++i) {
    outputArray[i] = rawData.charCodeAt(i);
  }
  return outputArray;
}

async function getSubscription(pushManager) {
  const subscription = await pushManager.getSubscription();
  if (subscription) return subscription;

  const response = await fetch('/api/push-service/public-key');
  const publicKey = await response.text();
  const applicationServerKey = urlBase64ToUint8Array(publicKey);
  return pushManager.subscribe({ userVisibleOnly: true, applicationServerKey });
}

const maxRetryCount = 3;

async function persistRegistration(subscription) {
  let retryCount = 0;

  while (true) {
    try {
      await fetch('/api/push-service/register', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(subscription),
      });
    } catch (error) {
      console.error('Error during service worker registration', error);
      if (retryCount === maxRetryCount) throw error;
      retryCount++;

      await Promise.delay(60 * 1000);
      continue;
    }

    retryCount = 0;
    await Promise.delay(5 * 60 * 1000);
  }
}

export default function register() {
  if ('serviceWorker' in navigator) {
    window.addEventListener('load', async () => {
      const swUrl = `${process.env.PUBLIC_URL}/service-worker.bundle.js`;
      try {
        const registration = await navigator.serviceWorker.register(swUrl);

        Notification.requestPermission();

        const subscription = await getSubscription(registration.pushManager);
        persistRegistration(subscription).catch(
          error => (
            console.error('unregistering service worker', error),
            registration.unregister()
          ),
        );
      } catch (error) {
        console.error('Error during service worker registration:', error);
      }
    });
  }
}

export function unregister() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.ready.then((registration) => {
      registration.unregister();
    });
  }
}
<|endoftext|>


<commit_before>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Fixes the iOS orientation change bug using a jQM version of this technique https://github.com/scottjehl/iOS-Orientationchange-Fix
//>>label: iOS orientation change bugfix

define( [ "jquery", "jquery.mobile.core", "jquery.mobile.zoom" ], function( $ ) {
//>>excludeEnd("jqmBuildExclude");
( function( $, window ) {
    var orientation = window.orientation,
        rotation = 0;

    function checkTilt( e ){
		e = e.originalEvent;
        orientation = Math.abs( window.orientation );
        rotation = Math.abs( e.gamma );

        if( rotation > 8 && orientation === 0 ){
            if( $.mobile.zoom.enabled ){
                $.mobile.zoom.disable();
            }
        }
        else {
            if( !$.mobile.zoom.enabled ){
                $.mobile.zoom.enable();
            }
        }
    }

    $( window )
		.bind( "orientationchange", $.mobile.zoom.enable )
		.bind( "deviceorientation", checkTilt );

}( jQuery, this ));
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<commit_msg>This change brings the iOS orientationchange bug workaround up to the latest code from that external project, with an experimental attempt at iOS4.3 support on the 3GS using the devicemotion event, which may be a bad idea to use unthrottled - not sure yet. This code needs to be tested on a device with iOS5, and I imagine the check for deviceorientation will also need a check for the value of evt.gamma. At that point, we may decide to only support iOS5 for this workaround, and the code can bind only to deviceorientation and be more concise.<commit_after>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Fixes the iOS orientation change bug using a jQM version of this technique https://github.com/scottjehl/iOS-Orientationchange-Fix
//>>label: iOS orientation change bugfix

define( [ "jquery", "jquery.mobile.core", "jquery.mobile.zoom" ], function( $ ) {
//>>excludeEnd("jqmBuildExclude");
( function( $, window ) {
    var zoom = $.mobile.zoom,
        rotation = 0,
		x = y = z = 0,
		orientation, aig;

    function checkTilt( e ){
		evt = e.originalEvent;
        orientation = window.orientation;
		aig = evt.accelerationIncludingGravity;

		if( aig ){
        	x = Math.abs( aig.x );
			y = Math.abs( aig.y );
			z = Math.abs( aig.z );
		}

        if( orientation === 0 && ( e.type === "deviceorientation" || x > 7 || ( z > 4 && ( x > 6 || y > 6 ) ) ) ){
			if( zoom.enabled ){
				zoom.disable();
			}
        }
		else if( !zoom.enabled ){
			zoom.enable();
        }
    }

    $( window )
		.bind( "orientationchange", zoom.enable )
		.bind( "deviceorientation devicemotion", checkTilt );

}( jQuery, this ));
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<|endoftext|>


<commit_before>/* eslint-disable accessor-pairs */ // we're using the "set" keyword for method
/**
 * Element Model Module
 *
 * @module ElementModel
 * @exports Element
 */
define(function (require) {
  'use strict';

  // foreign modules

  var $ = require('jquery');
  var _ = require('underscore');
  var Backbone = require('backbone');

  // local modules

  var modelStates = require('forms/mixins/model-states-mixin');
  var modelValidation = require('forms/mixins/model-validation');

  // this module

  var Element;

  Element = Backbone.Model.extend({
    defaults: function () {
      return {
        page: 0,
        class: '',
        defaultValue: '',
        value: '',
        pattern: '',
        hidden: false,
        persist: true,
        isDirty: false,
        isPristine: true
      };
    },

    idAttribute: 'name',

    initialize: function () {
      var attrs = this.attributes;
      var form = attrs.form;
      var page = attrs.page;
      var Forms = BMP.Forms;
      var section = $.trim(attrs.section || '');
      // migrate builder rowClass to class
      attrs.class = attrs.class || attrs.rowClass || '';

      Forms.setAttributesFromClass(this);

      if (form) {
        page = attrs.page = form.getPage(attrs.page);
        if (page && section) {
          section = attrs.section = page.getSection(section);
          section.add(this);
        } else {
          page.add(this);
          delete attrs.section;
        }
      }

      this.set('value', attrs.defaultValue, {silent: true, validate: false});
      if (!attrs.label && attrs.type !== 'message') {
        if (attrs.prefix) {
          attrs.label = attrs.name + ' ' + attrs.prefix;
        } else {
          attrs.label = attrs.name;
        }
      }

      // FORMS-137 # Fields that are set to required are not marked as such in anyway (no *)
      if (attrs.required && attrs.label && attrs.type !== 'subForm') {
        attrs.label += ' *';
      }

      if (attrs.label) {
        this.set('label', attrs.label);
      }

      // backward compatability.
      this.on('invalid valid', this.updateErrors, this);

      this.on('change:value', function () {
        this.setDirty();
      }, this);
      this.on('remove', this.close, this);
    },

    isEmpty: function () {
      var value = this.attributes.value;
      if (Array.isArray(value)) {
        return !value.length;
      }
      return !value && value !== 0;
    },

    isValid: modelValidation.isValid,

    validate: function (attrs) {
      var errors = {};

      if (attrs === undefined) {
        attrs = this.attributes;
      }

      if (attrs.hidden) {
        // if the element is hidden, validation should be ignored.
        return undefined;
      }

      if (attrs.required && this.isEmpty()) {
        errors.value = errors.value || [];
        errors.value.push({code: 'REQUIRED'});
      }
      if (attrs.pattern && attrs.value &&
          !new RegExp(attrs.pattern).test(attrs.value)) {
        errors.value = errors.value || [];
        errors.value.push({code: 'PATTERN', PATTERN: attrs.pattern});
      }

      return _.isEmpty(errors) ? undefined : errors;
    },
    /* @deprecated */
    updateErrors: function () {
      this.set('errors', this.validationError, {validate: false, silent: true});
    },

    hasErrors: function () {
      return this.validationError && !_.isEmpty(this.validationError);
    },

    /**
     * sets the current model.validationError property to elementErrorList.
     * Fires an 'invalid' event with (model, serverErrors) as params.
     * Any errors set here will be at the front of the array, and take
     * precedence.
     *
     * @param {array|object} elementErrorList - An array of Error objects
     * @param {object} options - set merge:false to NOT merge errors
     *
     * @fires model.invalid
     */
    setExternalErrors: function (elementErrorList, options) {
      var errors = [];
      options = options || {merge: true};

      if (options.merge && this.validationError) {
        errors = this.validationError.value || errors;
      }

      if (!_.isArray(errors)) {
        errors = [errors];
      }

      this.setDirty();

      this.validationError = { value: _.uniq(errors.concat(elementErrorList).reverse()) };
      this.trigger('invalid', this, elementErrorList);
    },

    setDirty: modelStates.setDirty,

    setPristine: modelStates.setPristine,

    warn: function () {
      var warning = {};
      warning.value = warning.value || [];
      if (!BMP.Forms.supports.blob) {
        warning.value.push({code: 'NO_BLOB_PREVIEW'});
      }
      return _.isEmpty(warning) ? undefined : warning;
    },
    updateWarning: function () {
      this.set('warning', this.warn());
    },
    removeView: function () {
      var attrs = this.attributes;
      if (attrs._view) {
        attrs._view.remove();
        delete attrs._view;
      }
    },
    close: function () {
      var attrs = this.attributes;
      delete attrs.form;
      delete attrs.page;
      delete attrs.section;
      this.off(null, null, this);
    },
    /**
     * this will close any existing view first, then establish a new view
     */
    initializeView: function () {
      var Forms = BMP.Forms;
      var View, view;
      var attrs = this.attributes;

      this.removeView();

      switch (attrs.type) {
        case 'heading':
          View = Forms._views.HeadingElement;
          break;
        case 'message':
          View = Forms._views.MessageElement;
          break;
        case 'boolean':
          View = Forms._views.BooleanElement;
          break;
        case 'number':
          View = Forms._views.NumberElement;
          break;
        case 'telephone':
          View = Forms._views.TelephoneElement;
          break;
        case 'button':
          View = Forms._views.ButtonElement;
          break;
        default:
          View = Forms._views.Element;
      }
      view = new View({model: this});
      this.set('_view', view);
      return view;
    },

    /**
    @override
    */
    set: function (key, value, options) {
      var attrs, result;
      var self = this;

      if (!key) {
        return undefined;
      }

      if (typeof key === 'object') {
        // `#set(attributes, options)`
        attrs = key;
        options = value;
      } else {
        // `#set(key, value, options)`
        attrs = {};
        attrs[key] = value;
      }

      result = Backbone.Model.prototype.set.call(this, attrs, options);
      if ('blob' in attrs || 'value' in attrs) {
        if (!options || (!options.hasOwnProperty('value') || !options.hasOwnProperty('blob')) || options.validate) {
          self.isValid();
        }
      }

      return result;
    },

    /**
     * official Blink API
     */
    val: function (value) {
      if (value === undefined) {
        return this.get('value');
      }

      this.set('value', value);
      return value;
    }
  }, {
    // static properties
    /**
     * @param {Object} attrs attributes for this model.
     * @param {Form} form parent to associate with new Element.
     * @return {Element} new Element.
     */
    create: function (attrs, form) {
      var Forms = BMP.Forms;
      var dateTypes = ['date', 'time', 'datetime'];
      var el;
      var TypedElement;

      if (!attrs || !_.isObject(attrs)) {
        return new Element();
      }
      if (form) {
        attrs.form = form;
      }
      // TODO: determine Element type and select sub-Prototype
      switch (attrs.type) {
        case 'draw':
          TypedElement = Forms._models.DrawElement;
          break;
        case 'file':
          TypedElement = Forms._models.FileElement;
          break;
        case 'location':
          TypedElement = Forms._models.LocationElement;
          break;
        case 'subForm':
          TypedElement = Forms._models.SubFormElement;
          break;
        case 'heading':
          TypedElement = Forms._models.HeadingElement;
          break;
        case 'message':
          TypedElement = Forms._models.MessageElement;
          break;
        case 'boolean':
          TypedElement = Forms._models.BooleanElement;
          break;
        case 'select':
          TypedElement = Forms._models.SelectElement;
          break;
        case 'multi':
          TypedElement = Forms._models.MultiElement;
          break;
        case 'hidden':
          TypedElement = Forms._models.HiddenElement;
          break;
        case 'number':
          TypedElement = Forms._models.NumberElement;
          break;
        case 'telephone':
          TypedElement = Forms._models.TelephoneElement;
          break;
        case 'password':
          TypedElement = Forms._models.PasswordElement;
          break;
        case 'email':
          TypedElement = Forms._models.EmailElement;
          break;
        case 'url':
          TypedElement = Forms._models.URLElement;
          break;
        case 'text':
          TypedElement = Forms._models.TextElement;
          break;
        case 'button':
          TypedElement = Forms._models.ButtonElement;
          break;
        case 'textarea':
          TypedElement = Forms._models.TextAreaElement;
          break;
        default:
          if (_.indexOf(dateTypes, attrs.type) !== -1) {
            TypedElement = Forms._models.DateElement;
          } else {
            TypedElement = Forms._models.Element;
          }
      }
      // TODO: set View = read-only view for m.readOnly
      el = new TypedElement(attrs);
      return el;
    }
  });

  return Element;
});
<commit_msg>Forms-244 : required signature blocks validation, even when populated<commit_after>/* eslint-disable accessor-pairs */ // we're using the "set" keyword for method
/**
 * Element Model Module
 *
 * @module ElementModel
 * @exports Element
 */
define(function (require) {
  'use strict';

  // foreign modules

  var $ = require('jquery');
  var _ = require('underscore');
  var Backbone = require('backbone');

  // local modules

  var modelStates = require('forms/mixins/model-states-mixin');
  var modelValidation = require('forms/mixins/model-validation');

  // this module

  var Element;

  Element = Backbone.Model.extend({
    defaults: function () {
      return {
        page: 0,
        class: '',
        defaultValue: '',
        value: '',
        pattern: '',
        hidden: false,
        persist: true,
        isDirty: false,
        isPristine: true
      };
    },

    idAttribute: 'name',

    initialize: function () {
      var attrs = this.attributes;
      var form = attrs.form;
      var page = attrs.page;
      var Forms = BMP.Forms;
      var section = $.trim(attrs.section || '');
      // migrate builder rowClass to class
      attrs.class = attrs.class || attrs.rowClass || '';

      Forms.setAttributesFromClass(this);

      if (form) {
        page = attrs.page = form.getPage(attrs.page);
        if (page && section) {
          section = attrs.section = page.getSection(section);
          section.add(this);
        } else {
          page.add(this);
          delete attrs.section;
        }
      }

      this.set('value', attrs.defaultValue, {silent: true, validate: false});
      if (!attrs.label && attrs.type !== 'message') {
        if (attrs.prefix) {
          attrs.label = attrs.name + ' ' + attrs.prefix;
        } else {
          attrs.label = attrs.name;
        }
      }

      // FORMS-137 # Fields that are set to required are not marked as such in anyway (no *)
      if (attrs.required && attrs.label && attrs.type !== 'subForm') {
        attrs.label += ' *';
      }

      if (attrs.label) {
        this.set('label', attrs.label);
      }

      // backward compatability.
      this.on('invalid valid', this.updateErrors, this);

      this.on('change:value', function () {
        this.setDirty();
      }, this);
      this.on('remove', this.close, this);
    },

    isEmpty: function () {
      var value = this.attributes.value;
      if (Array.isArray(value)) {
        return !value.length;
      }
      return !value && value !== 0;
    },

    isValid: modelValidation.isValid,

    validate: function (attrs) {
      var errors = {};

      if (attrs === undefined) {
        attrs = this.attributes;
      }

      if (attrs.hidden) {
        // if the element is hidden, validation should be ignored.
        return undefined;
      }

      if (attrs.required && this.isEmpty()) {
        errors.value = errors.value || [];
        errors.value.push({code: 'REQUIRED'});
      }
      if (attrs.pattern && attrs.value &&
          !new RegExp(attrs.pattern).test(attrs.value)) {
        errors.value = errors.value || [];
        errors.value.push({code: 'PATTERN', PATTERN: attrs.pattern});
      }

      return _.isEmpty(errors) ? undefined : errors;
    },
    /* @deprecated */
    updateErrors: function () {
      this.set('errors', this.validationError, {validate: false, silent: true});
    },

    hasErrors: function () {
      return this.validationError && !_.isEmpty(this.validationError);
    },

    /**
     * sets the current model.validationError property to elementErrorList.
     * Fires an 'invalid' event with (model, serverErrors) as params.
     * Any errors set here will be at the front of the array, and take
     * precedence.
     *
     * @param {array|object} elementErrorList - An array of Error objects
     * @param {object} options - set merge:false to NOT merge errors
     *
     * @fires model.invalid
     */
    setExternalErrors: function (elementErrorList, options) {
      var errors = [];
      options = options || {merge: true};

      if (options.merge && this.validationError) {
        errors = this.validationError.value || errors;
      }

      if (!_.isArray(errors)) {
        errors = [errors];
      }

      this.setDirty();

      this.validationError = { value: _.uniq(errors.concat(elementErrorList).reverse()) };
      this.trigger('invalid', this, elementErrorList);
    },

    setDirty: modelStates.setDirty,

    setPristine: modelStates.setPristine,

    warn: function () {
      var warning = {};
      warning.value = warning.value || [];
      if (!BMP.Forms.supports.blob) {
        warning.value.push({code: 'NO_BLOB_PREVIEW'});
      }
      return _.isEmpty(warning) ? undefined : warning;
    },
    updateWarning: function () {
      this.set('warning', this.warn());
    },
    removeView: function () {
      var attrs = this.attributes;
      if (attrs._view) {
        attrs._view.remove();
        delete attrs._view;
      }
    },
    close: function () {
      var attrs = this.attributes;
      delete attrs.form;
      delete attrs.page;
      delete attrs.section;
      this.off(null, null, this);
    },
    /**
     * this will close any existing view first, then establish a new view
     */
    initializeView: function () {
      var Forms = BMP.Forms;
      var View, view;
      var attrs = this.attributes;

      this.removeView();

      switch (attrs.type) {
        case 'heading':
          View = Forms._views.HeadingElement;
          break;
        case 'message':
          View = Forms._views.MessageElement;
          break;
        case 'boolean':
          View = Forms._views.BooleanElement;
          break;
        case 'number':
          View = Forms._views.NumberElement;
          break;
        case 'telephone':
          View = Forms._views.TelephoneElement;
          break;
        case 'button':
          View = Forms._views.ButtonElement;
          break;
        default:
          View = Forms._views.Element;
      }
      view = new View({model: this});
      this.set('_view', view);
      return view;
    },

    /**
    @override
    */
    set: function (key, value, options) {
      var attrs, result;
      var self = this;

      if (!key) {
        return undefined;
      }

      if (typeof key === 'object') {
        // `#set(attributes, options)`
        attrs = key;
        options = value;
      } else {
        // `#set(key, value, options)`
        attrs = {};
        attrs[key] = value;
      }

      result = Backbone.Model.prototype.set.call(this, attrs, options);
      if ('blob' in attrs || 'value' in attrs) {
        if (!options || options.validate) {
          self.isValid();
        }
      }

      return result;
    },

    /**
     * official Blink API
     */
    val: function (value) {
      if (value === undefined) {
        return this.get('value');
      }

      this.set('value', value);
      return value;
    }
  }, {
    // static properties
    /**
     * @param {Object} attrs attributes for this model.
     * @param {Form} form parent to associate with new Element.
     * @return {Element} new Element.
     */
    create: function (attrs, form) {
      var Forms = BMP.Forms;
      var dateTypes = ['date', 'time', 'datetime'];
      var el;
      var TypedElement;

      if (!attrs || !_.isObject(attrs)) {
        return new Element();
      }
      if (form) {
        attrs.form = form;
      }
      // TODO: determine Element type and select sub-Prototype
      switch (attrs.type) {
        case 'draw':
          TypedElement = Forms._models.DrawElement;
          break;
        case 'file':
          TypedElement = Forms._models.FileElement;
          break;
        case 'location':
          TypedElement = Forms._models.LocationElement;
          break;
        case 'subForm':
          TypedElement = Forms._models.SubFormElement;
          break;
        case 'heading':
          TypedElement = Forms._models.HeadingElement;
          break;
        case 'message':
          TypedElement = Forms._models.MessageElement;
          break;
        case 'boolean':
          TypedElement = Forms._models.BooleanElement;
          break;
        case 'select':
          TypedElement = Forms._models.SelectElement;
          break;
        case 'multi':
          TypedElement = Forms._models.MultiElement;
          break;
        case 'hidden':
          TypedElement = Forms._models.HiddenElement;
          break;
        case 'number':
          TypedElement = Forms._models.NumberElement;
          break;
        case 'telephone':
          TypedElement = Forms._models.TelephoneElement;
          break;
        case 'password':
          TypedElement = Forms._models.PasswordElement;
          break;
        case 'email':
          TypedElement = Forms._models.EmailElement;
          break;
        case 'url':
          TypedElement = Forms._models.URLElement;
          break;
        case 'text':
          TypedElement = Forms._models.TextElement;
          break;
        case 'button':
          TypedElement = Forms._models.ButtonElement;
          break;
        case 'textarea':
          TypedElement = Forms._models.TextAreaElement;
          break;
        default:
          if (_.indexOf(dateTypes, attrs.type) !== -1) {
            TypedElement = Forms._models.DateElement;
          } else {
            TypedElement = Forms._models.Element;
          }
      }
      // TODO: set View = read-only view for m.readOnly
      el = new TypedElement(attrs);
      return el;
    }
  });

  return Element;
});
<|endoftext|>