<commit_before>//
// Copyright 2014, Andreas Lundquist
//
// 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.
//
// DFRobot - Bluno - Hello World
// version: 0.1 - 2014-11-21
//

// Route all console logs to Evothings studio log
if (window.hyper && window.hyper.log) { console.log = hyper.log; };

document.addEventListener(
	'deviceready',
	function() { evothings.scriptsLoaded(app.initialize) },
	false);

var app = {};

//app.DFRBLU_SERVICE_UUID = 'dfb0';
app.DFRBLU_SERVICE_UUID = '0000dfb0-0000-1000-8000-00805f9b34fb';
app.DFRBLU_CHAR_RXTX_UUID = '0000dfb1-0000-1000-8000-00805f9b34fb';
app.DFRBLU_TX_UUID_DESCRIPTOR = '00002902-0000-1000-8000-00805f9b34fb';

app.initialize = function()
{
	app.connected = false;
};

app.startScan = function()
{
	app.disconnect();

	console.log('Scanning started...');

	app.devices = {};

	var htmlString =
		'' +
		'
   Scanning...
';

	$('#scanResultView').append($(htmlString));

	$('#scanResultView').show();

	function onScanSuccess(device)
	{
		if (device.name != null)
		{
			app.devices[device.address] = device;

			console.log(
				'Found: ' + device.name + ', ' +
				device.address + ', ' + device.rssi);

			var htmlString =
				'
' +
				'
' + device.name + '
' +
				'
' + device.address + '
' +
				'
';

			$('#scanResultView').append($(htmlString));
		}
	}

	function onScanFailure(errorCode)
	{
		// Show an error message to the user
		app.disconnect('Failed to scan for devices.');

		// Write debug information to console.
		console.log('Error ' + errorCode);
	}

	evothings.easyble.reportDeviceOnce(true);
	evothings.easyble.startScan(onScanSuccess, onScanFailure);

	$('#startView').hide();
};

app.setLoadingLabel = function(message)
{
	console.log(message);
	$('#loadingStatus').text(message);
}

app.connectTo = function(address)
{
	device = app.devices[address];

	$('#loadingView').css('display', 'table');

	app.setLoadingLabel('Trying to connect to ' + device.name);

	function onConnectSuccess(device)
	{
		function onServiceSuccess(device)
		{
			// Application is now connected
			app.connected = true;
			app.device = device;

			console.log('Connected to ' + device.name);

			$('#loadingView').hide();
			$('#scanResultView').hide();
			$('#controlView').show();

			device.enableNotification(
				app.DFRBLU_CHAR_RXTX_UUID,
				app.receivedData,
				function(errorcode) {
					console.log('BLE enableNotification error: ' + errorCode);
				});
		}

		function onServiceFailure(errorCode)
		{
			// Disconnect and show an error message to the user.
			app.disconnect('Device is not from DFRobot');

			// Write debug information to console.
			console.log('Error reading services: ' + errorCode);
		}

		app.setLoadingLabel('Identifying services...');

		// Connect to the appropriate BLE service
		device.readServices([app.DFRBLU_SERVICE_UUID], onServiceSuccess, onServiceFailure);
	}

	function onConnectFailure(errorCode)
	{
		// Disconnect and show an error message to the user.
		app.disconnect('Failed to connect to device');

		// Write debug information to console
		console.log('Error ' + errorCode);
	}

	// Stop scanning
	evothings.easyble.stopScan();

	// Connect to our device
	console.log('Identifying service for communication');
	device.connect(onConnectSuccess, onConnectFailure);
};

app.sendData = function(data)
{
	if (app.connected)
	{
		function onMessageSendSucces()
		{
			console.log('Succeded to send message.');
		}

		function onMessageSendFailure(errorCode)
		{
			console.log('Failed to send data with error: ' + errorCode);
			app.disconnect('Failed to send data');
		}

		data = new Uint8Array(data);

		app.device.writeCharacteristic(
			app.DFRBLU_CHAR_RXTX_UUID,
			data,
			onMessageSendSucces,
			onMessageSendFailure);
	}
	else
	{
		// Disconnect and show an error message to the user.
		app.disconnect('Disconnected');

		// Write debug information to console
		console.log('Error - No device connected.');
	}
};

app.receivedData = function(data)
{
	if (app.connected)
	{
		var data = new Uint8Array(data);

		if (data[0] === 0xAD)
		{
			console.log('Data received: [' +
				data[0] +', ' + data[1] +', ' + data[2] + ']');

			var value = (data[2] << 8) | data[1];

			console.log(value);

			$('#analogDigitalResult').text(value);
		}
	}
	else
	{
		// Disconnect and show an error message to the user.
		app.disconnect('Disconnected');

		// Write debug information to console
		console.log('Error - No device connected.');
	}
};

app.disconnect = function(errorMessage)
{
	if (errorMessage)
	{
		navigator.notification.alert(errorMessage, function() {});
	}

	app.connected = false;
	app.device = null;

	// Stop any ongoing scan and close devices.
	evothings.easyble.stopScan();
	evothings.easyble.closeConnectedDevices();

	console.log('Disconnected');

	$('#scanResultView').hide();
	$('#scanResultView').empty();
	$('#controlView').hide();
	$('#startView').show();
};
<commit_msg>Fixed typo reported by nogray<commit_after>//
// Copyright 2014, Andreas Lundquist
//
// 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.
//
// DFRobot - Bluno - Hello World
// version: 0.1 - 2014-11-21
//

// Route all console logs to Evothings studio log
if (window.hyper && window.hyper.log) { console.log = hyper.log; };

document.addEventListener(
	'deviceready',
	function() { evothings.scriptsLoaded(app.initialize) },
	false);

var app = {};

//app.DFRBLU_SERVICE_UUID = 'dfb0';
app.DFRBLU_SERVICE_UUID = '0000dfb0-0000-1000-8000-00805f9b34fb';
app.DFRBLU_CHAR_RXTX_UUID = '0000dfb1-0000-1000-8000-00805f9b34fb';
app.DFRBLU_TX_UUID_DESCRIPTOR = '00002902-0000-1000-8000-00805f9b34fb';

app.initialize = function()
{
	app.connected = false;
};

app.startScan = function()
{
	app.disconnect();

	console.log('Scanning started...');

	app.devices = {};

	var htmlString =
		'' +
		'
   Scanning...
';

	$('#scanResultView').append($(htmlString));

	$('#scanResultView').show();

	function onScanSuccess(device)
	{
		if (device.name != null)
		{
			app.devices[device.address] = device;

			console.log(
				'Found: ' + device.name + ', ' +
				device.address + ', ' + device.rssi);

			var htmlString =
				'
' +
				'
' + device.name + '
' +
				'
' + device.address + '
' +
				'
';

			$('#scanResultView').append($(htmlString));
		}
	}

	function onScanFailure(errorCode)
	{
		// Show an error message to the user
		app.disconnect('Failed to scan for devices.');

		// Write debug information to console.
		console.log('Error ' + errorCode);
	}

	evothings.easyble.reportDeviceOnce(true);
	evothings.easyble.startScan(onScanSuccess, onScanFailure);

	$('#startView').hide();
};

app.setLoadingLabel = function(message)
{
	console.log(message);
	$('#loadingStatus').text(message);
}

app.connectTo = function(address)
{
	device = app.devices[address];

	$('#loadingView').css('display', 'table');

	app.setLoadingLabel('Trying to connect to ' + device.name);

	function onConnectSuccess(device)
	{
		function onServiceSuccess(device)
		{
			// Application is now connected
			app.connected = true;
			app.device = device;

			console.log('Connected to ' + device.name);

			$('#loadingView').hide();
			$('#scanResultView').hide();
			$('#controlView').show();

			device.enableNotification(
				app.DFRBLU_CHAR_RXTX_UUID,
				app.receivedData,
				function(errorCode) {
					console.log('BLE enableNotification error: ' + errorCode);
				});
		}

		function onServiceFailure(errorCode)
		{
			// Disconnect and show an error message to the user.
			app.disconnect('Device is not from DFRobot');

			// Write debug information to console.
			console.log('Error reading services: ' + errorCode);
		}

		app.setLoadingLabel('Identifying services...');

		// Connect to the appropriate BLE service
		device.readServices([app.DFRBLU_SERVICE_UUID], onServiceSuccess, onServiceFailure);
	}

	function onConnectFailure(errorCode)
	{
		// Disconnect and show an error message to the user.
		app.disconnect('Failed to connect to device');

		// Write debug information to console
		console.log('Error ' + errorCode);
	}

	// Stop scanning
	evothings.easyble.stopScan();

	// Connect to our device
	console.log('Identifying service for communication');
	device.connect(onConnectSuccess, onConnectFailure);
};

app.sendData = function(data)
{
	if (app.connected)
	{
		function onMessageSendSucces()
		{
			console.log('Succeded to send message.');
		}

		function onMessageSendFailure(errorCode)
		{
			console.log('Failed to send data with error: ' + errorCode);
			app.disconnect('Failed to send data');
		}

		data = new Uint8Array(data);

		app.device.writeCharacteristic(
			app.DFRBLU_CHAR_RXTX_UUID,
			data,
			onMessageSendSucces,
			onMessageSendFailure);
	}
	else
	{
		// Disconnect and show an error message to the user.
		app.disconnect('Disconnected');

		// Write debug information to console
		console.log('Error - No device connected.');
	}
};

app.receivedData = function(data)
{
	if (app.connected)
	{
		var data = new Uint8Array(data);

		if (data[0] === 0xAD)
		{
			console.log('Data received: [' +
				data[0] +', ' + data[1] +', ' + data[2] + ']');

			var value = (data[2] << 8) | data[1];

			console.log(value);

			$('#analogDigitalResult').text(value);
		}
	}
	else
	{
		// Disconnect and show an error message to the user.
		app.disconnect('Disconnected');

		// Write debug information to console
		console.log('Error - No device connected.');
	}
};

app.disconnect = function(errorMessage)
{
	if (errorMessage)
	{
		navigator.notification.alert(errorMessage, function() {});
	}

	app.connected = false;
	app.device = null;

	// Stop any ongoing scan and close devices.
	evothings.easyble.stopScan();
	evothings.easyble.closeConnectedDevices();

	console.log('Disconnected');

	$('#scanResultView').hide();
	$('#scanResultView').empty();
	$('#controlView').hide();
	$('#startView').show();
};
<|endoftext|>


<commit_before><commit_msg>Add benchmarks<commit_after><|endoftext|>


<commit_before>/*
 * Namespace: lb.base.i18n
 * Base Internationalization (i18n) Module
 *
 * This module provides the basis for the adaptation of a web application to
 * different languages in an international context.
 *
 * The issue is addressed in a generic way in this module, which relies on
 * language codes associated with a set of language properties defined by the
 * application:
 * - string properties,
 * - functions for localized behavior, formatting and sorting,
 * - object properties, to group properties within. The groups may be nested.
 *
 * A language code is a string which identifies the language, region and other
 * variations of the language as defined in RFC5646 "Tags for Identifying
 * Languages", for example:
 * - 'en' for English,
 * - 'fr' for French,
 * - 'en-GB' for English/Great Britain,
 * - 'en-US' for English/USA,
 * - 'fr-FR' for French/France,
 * - 'fr-CA' for French/Canada.
 *
 * The lookup of language properties is done from the most specific language
 * to the less specific language, with longer language codes considered more
 * specific than shorter language codes. Only language codes which are
 * substrings of the language selected for the lookup are considered.
 * For example, if the selected language is 'en-GB', 'en-GB' and 'en' are
 * considered in this order, while 'en-US', 'fr-FR', 'fr-CA' and 'fr' are left
 * out.
 *
 * The empty string '' is the least specific language code possible, which will
 * always be considered last in the lookup process. Common default properties
 * can be associated with the empty language code '', they will be shared by
 * all languages.
 *
 * Any custom property may be defined in language properties for the needs of
 * your application, and associated with a language code by calling
 * addLanguageProperties(). Calling reset() removes all language properties.
 *
 * The list of language codes associated with language properties is returned
 * by getLanguageCodes(). It is initially empty.
 * [Note: changes pending - add getLanguageCodes]
 *
 * Author:
 * Eric Bréchemier <legalbox@eric.brechemier.name>
 *
 * Copyright:
 * Legal Box SAS (c) 2010, All Rights Reserved
 *
 * License:
 * BSD License
 * http://creativecommons.org/licenses/BSD/
 *
 * Version:
 * 2010-12-17
 */
/*requires lb.base.js */
/*jslint white:false, plusplus:false */
/*global lb, goog, navigator */
// preserve the module, if already loaded
lb.base.i18n = lb.base.i18n || (function() {
  // Builder of
  // Closure for lb.base.i18n module

  // Declare aliases
  var getOption = lb.base.config.getOption,

  // private fields

      // TODO: rename to languageList or languages
      // languageVariants - array, the list of language objects,
      //                    sorted by language code, from less specific to
      //                    most specific.
      //                    Each language object is in the format:
      //                    | {
      //                    |    language: 'en-US', // string, language code
      //                    |    properties: {...}  // object, properties given
      //                    |                       // in addLanguageProperties
      //                    | }
      // Note:
      // In current implementation, the same language code may be repeated in
      // several language objects. These duplicates may be merged into a single
      // language object in a future implementation (trading less memory for
      // more computations due to added merging step).
      languageVariants = [];

  function getLanguage(){
    // For internal use - refactoring in progress
    // Return the default language configured with 'lbLanguage' property

    var defaultLanguage = navigator.language ||
                          navigator.browserLanguage ||
                          '';
    return getOption('lbLanguage',defaultLanguage).toLowerCase();
  }

  function getLanguageVariants(language){
    // Function: getLanguageVariants(language): array
    // Get the language variants for given language, sorted by language tag
    // from less specific to most specific.
    //
    // Parameter:
    //   language - string, an optional language tag, as defined in RFC5646
    //              "Tags for Identifying Languages".
    //              Omitting the language and null or undefined values
    //              (or any value without the toLowerCase() property) act as a
    //              wildcard to return all language variants.
    //
    // Returns:
    //   * array, the list of properties objects for all language variants
    //     whose tag is a subset of given language, ordered by language tag,
    //   * or if the optional language argument is omitted,
    //     array, the list of properties objects for all language variants,
    //     sorted by language tag.
    //
    // Note:
    //   In case several language variants were added for the same tag, the
    //   language variant added last is considered more specific and comes
    //   last in this list.

    var isWildcard = language===undefined ||
                     language===null ||
                     !language.toLowerCase,
        languageProperties = [],
        i,
        languageVariant;
    if (!isWildcard){
      language = language.toLowerCase();
    }
    for(i=0; i<languageVariants.length; i++){
      languageVariant = languageVariants[i];
      if ( isWildcard ||
        // selected language starts with the tag of this language variant
        language.indexOf(languageVariant.language)===0 ){
        languageProperties.push(languageVariant.properties);
      }
    }
    return languageProperties;
  }

  function addLanguageProperties(languageCode,languageProperties){
    // Function: addLanguageProperties(languageCode,languageProperties)
    // Add or replace language properties associated with given language code.
    //
    // Language properties may be specified in multiple calls with the same
    // language code. In case of duplicate properties, the ones last are
    // considered more specific and take precedence over properties defined
    // previously.
    //
    // Parameters:
    //   languageCode - string, the language code identifying the language,
    //                  as defined in RFC5646 "Tags for Identifying Languages"
    //   languageProperties - object, a set of language properties
    //
    // Note:
    //   Nothing happens in case the given language code is null, undefined,
    //   or misses the toLowerCase method.
    if ( languageCode===undefined ||
         languageCode===null ||
         !languageCode.toLowerCase ){
      return;
    }

    // Note: array.sort does not guarantee that the order of items with the
    // same value is preserved. This is the case in recent versions of Firefox,
    // Opera and Chrome, but not in IE and Safari.
    //
    // Thus I chose to insert the new item at the highest position where
    // the lexical order of previous language is lesser or equal, instead of
    // adding the item to the array and calling sort().

    var lowerCaseLanguage = languageCode.toLowerCase(),
        newLanguageVariant = {
          language: lowerCaseLanguage,
          properties: languageProperties
        },
        length = languageVariants.length,
        i = 0,
        j;

    // find the first suitable position for insertion
    for (j=length-1; j>=0; j--){
      if (lowerCaseLanguage >= languageVariants[j].language){
        i = j+1; // insert just after
        break;
      }
    }

    // insert at found location (possibly 0)
    languageVariants.splice(i,0,newLanguageVariant);
  }

  function getProperty(){
    // Function: getProperty(...,name): any
    // Lookup the property with given name, optionally nested within
    // other properties, based on language configured in 'lbLanguage' property.
    //
    // The last argument is the name of the property. Preceding arguments
    // are the names of parent properties, allowing to nest a property
    // within sections and subsections. In any case, the first property is
    // always looked for at the top of language variants.
    //
    // Parameters:
    //   ... - string, the name of parent properties, starting at the top level
    //   name - string, the name of the looked up property
    //
    // Returns:
    //   * any, the value of the property found in the most specific language
    //     variant according to the language currently selected,
    //   * or null if the property is not found in suitable languages.

    var name,
        properties = getLanguageVariants( getLanguage() ),
        property,
        i,
        j;
    // for each language variant, from most specific to less specific
    for (i=properties.length-1; i>=0; i--){
      property = properties[i]; // start at top
      for (j=0; j<arguments.length && property; j++){
        name = arguments[j];
        if (name in property && j===arguments.length-1){
          return property[name];
        }
        property = property[name];
      }
    }
    return null;
  }

  function getValueOf(){
    // Function: getValueOf(...,name,args): any
    //
    // Lookup the function with given name, optionally nested within
    // other properties, based on selected language, and return the first
    // defined result value of such a function.
    //
    // The last two arguments are the name of the function and arguments to be
    // provided in calls to the function. Preceding arguments, if any, are the
    // names of parent properties, allowing to nest the function within
    // sections and subsections. The first property, or the function name in
    // case no parent property is provided, is looked for at the top of
    // language variants for the current language.
    //
    // Parameters:
    //   ... - string, the name of parent properties, starting at the top level
    //   name - string, the name of the looked up function
    //   args - array, the list of arguments for the function
    //
    // Returns:
    //   * any, the value of the most specific function found in given position
    //     which returns a value different from null,
    //   * or null if there is no such function found in suitable languages.

    var namePosition = arguments.length-2,
        name,
        argsPosition = namePosition+1,
        args = arguments[argsPosition],
        properties = getLanguageVariants( getLanguage() ),
        property,
        i,
        j,
        func,
        value;

    // for each language variant, from most specific to less specific
    for (i=properties.length-1; i>=0; i--){
      property = properties[i]; // start at top
      for (j=0; j<=namePosition && property; j++){
        name = arguments[j];
        if (name in property && j===namePosition){
          func = property[name];
          if (typeof func === 'function'){
            value = func.apply(null,args);
            if (value!==undefined && value!==null){
              return value;
            }
          }
        }
        property = property[name];
      }
    }
    return null;
  }

  function reset(){
    // Function: reset()
    // Remove all language variants.

    languageVariants.length = 0;
  }

  return { // public API
    getLanguageVariants: getLanguageVariants,
    addLanguageProperties: addLanguageProperties,
    getProperty: getProperty,
    getValueOf: getValueOf,
    reset: reset
  };
}());
<commit_msg>Refactoring: renamed the private field languageVariants to languages<commit_after>/*
 * Namespace: lb.base.i18n
 * Base Internationalization (i18n) Module
 *
 * This module provides the basis for the adaptation of a web application to
 * different languages in an international context.
 *
 * The issue is addressed in a generic way in this module, which relies on
 * language codes associated with a set of language properties defined by the
 * application:
 * - string properties,
 * - functions for localized behavior, formatting and sorting,
 * - object properties, to group properties within. The groups may be nested.
 *
 * A language code is a string which identifies the language, region and other
 * variations of the language as defined in RFC5646 "Tags for Identifying
 * Languages", for example:
 * - 'en' for English,
 * - 'fr' for French,
 * - 'en-GB' for English/Great Britain,
 * - 'en-US' for English/USA,
 * - 'fr-FR' for French/France,
 * - 'fr-CA' for French/Canada.
 *
 * The lookup of language properties is done from the most specific language
 * to the less specific language, with longer language codes considered more
 * specific than shorter language codes. Only language codes which are
 * substrings of the language selected for the lookup are considered.
 * For example, if the selected language is 'en-GB', 'en-GB' and 'en' are
 * considered in this order, while 'en-US', 'fr-FR', 'fr-CA' and 'fr' are left
 * out.
 *
 * The empty string '' is the least specific language code possible, which will
 * always be considered last in the lookup process. Common default properties
 * can be associated with the empty language code '', they will be shared by
 * all languages.
 *
 * Any custom property may be defined in language properties for the needs of
 * your application, and associated with a language code by calling
 * addLanguageProperties(). Calling reset() removes all language properties.
 *
 * The list of language codes associated with language properties is returned
 * by getLanguageCodes(). It is initially empty.
 * [Note: changes pending - add getLanguageCodes]
 *
 * Author:
 * Eric Bréchemier <legalbox@eric.brechemier.name>
 *
 * Copyright:
 * Legal Box SAS (c) 2010, All Rights Reserved
 *
 * License:
 * BSD License
 * http://creativecommons.org/licenses/BSD/
 *
 * Version:
 * 2010-12-17
 */
/*requires lb.base.js */
/*jslint white:false, plusplus:false */
/*global lb, goog, navigator */
// preserve the module, if already loaded
lb.base.i18n = lb.base.i18n || (function() {
  // Builder of
  // Closure for lb.base.i18n module

  // Declare aliases
  var getOption = lb.base.config.getOption,

  // private fields

      // languages - array, the list of language objects, sorted by language
      //             code, from less specific to most specific.
      //             Each language object is in the format:
      //             | {
      //             |    language: 'en-US', // string, language code
      //             |    properties: {...}  // object, properties given
      //             |                       // in addLanguageProperties
      //             | }
      // Note:
      // In current implementation, the same language code may be repeated in
      // several language objects. These duplicates may be merged into a single
      // language object in a future implementation (trading less memory for
      // more computations due to added merging step).
      languages = [];

  function getLanguage(){
    // For internal use - refactoring in progress
    // Return the default language configured with 'lbLanguage' property

    var defaultLanguage = navigator.language ||
                          navigator.browserLanguage ||
                          '';
    return getOption('lbLanguage',defaultLanguage).toLowerCase();
  }

  function getLanguageVariants(language){
    // Function: getLanguageVariants(language): array
    // Get the language variants for given language, sorted by language tag
    // from less specific to most specific.
    //
    // Parameter:
    //   language - string, an optional language tag, as defined in RFC5646
    //              "Tags for Identifying Languages".
    //              Omitting the language and null or undefined values
    //              (or any value without the toLowerCase() property) act as a
    //              wildcard to return all language variants.
    //
    // Returns:
    //   * array, the list of properties objects for all language variants
    //     whose tag is a subset of given language, ordered by language tag,
    //   * or if the optional language argument is omitted,
    //     array, the list of properties objects for all language variants,
    //     sorted by language tag.
    //
    // Note:
    //   In case several language variants were added for the same tag, the
    //   language variant added last is considered more specific and comes
    //   last in this list.

    var isWildcard = language===undefined ||
                     language===null ||
                     !language.toLowerCase,
        languageProperties = [],
        i,
        languageVariant;
    if (!isWildcard){
      language = language.toLowerCase();
    }
    for(i=0; i<languages.length; i++){
      languageVariant = languages[i];
      if ( isWildcard ||
        // selected language starts with the tag of this language variant
        language.indexOf(languageVariant.language)===0 ){
        languageProperties.push(languageVariant.properties);
      }
    }
    return languageProperties;
  }

  function addLanguageProperties(languageCode,languageProperties){
    // Function: addLanguageProperties(languageCode,languageProperties)
    // Add or replace language properties associated with given language code.
    //
    // Language properties may be specified in multiple calls with the same
    // language code. In case of duplicate properties, the ones last are
    // considered more specific and take precedence over properties defined
    // previously.
    //
    // Parameters:
    //   languageCode - string, the language code identifying the language,
    //                  as defined in RFC5646 "Tags for Identifying Languages"
    //   languageProperties - object, a set of language properties
    //
    // Note:
    //   Nothing happens in case the given language code is null, undefined,
    //   or misses the toLowerCase method.
    if ( languageCode===undefined ||
         languageCode===null ||
         !languageCode.toLowerCase ){
      return;
    }

    // Note: array.sort does not guarantee that the order of items with the
    // same value is preserved. This is the case in recent versions of Firefox,
    // Opera and Chrome, but not in IE and Safari.
    //
    // Thus I chose to insert the new item at the highest position where
    // the lexical order of previous language is lesser or equal, instead of
    // adding the item to the array and calling sort().

    var lowerCaseLanguage = languageCode.toLowerCase(),
        newLanguageVariant = {
          language: lowerCaseLanguage,
          properties: languageProperties
        },
        length = languages.length,
        i = 0,
        j;

    // find the first suitable position for insertion
    for (j=length-1; j>=0; j--){
      if (lowerCaseLanguage >= languages[j].language){
        i = j+1; // insert just after
        break;
      }
    }

    // insert at found location (possibly 0)
    languages.splice(i,0,newLanguageVariant);
  }

  function getProperty(){
    // Function: getProperty(...,name): any
    // Lookup the property with given name, optionally nested within
    // other properties, based on language configured in 'lbLanguage' property.
    //
    // The last argument is the name of the property. Preceding arguments
    // are the names of parent properties, allowing to nest a property
    // within sections and subsections. In any case, the first property is
    // always looked for at the top of language variants.
    //
    // Parameters:
    //   ... - string, the name of parent properties, starting at the top level
    //   name - string, the name of the looked up property
    //
    // Returns:
    //   * any, the value of the property found in the most specific language
    //     variant according to the language currently selected,
    //   * or null if the property is not found in suitable languages.

    var name,
        properties = getLanguageVariants( getLanguage() ),
        property,
        i,
        j;
    // for each language variant, from most specific to less specific
    for (i=properties.length-1; i>=0; i--){
      property = properties[i]; // start at top
      for (j=0; j<arguments.length && property; j++){
        name = arguments[j];
        if (name in property && j===arguments.length-1){
          return property[name];
        }
        property = property[name];
      }
    }
    return null;
  }

  function getValueOf(){
    // Function: getValueOf(...,name,args): any
    //
    // Lookup the function with given name, optionally nested within
    // other properties, based on selected language, and return the first
    // defined result value of such a function.
    //
    // The last two arguments are the name of the function and arguments to be
    // provided in calls to the function. Preceding arguments, if any, are the
    // names of parent properties, allowing to nest the function within
    // sections and subsections. The first property, or the function name in
    // case no parent property is provided, is looked for at the top of
    // language variants for the current language.
    //
    // Parameters:
    //   ... - string, the name of parent properties, starting at the top level
    //   name - string, the name of the looked up function
    //   args - array, the list of arguments for the function
    //
    // Returns:
    //   * any, the value of the most specific function found in given position
    //     which returns a value different from null,
    //   * or null if there is no such function found in suitable languages.

    var namePosition = arguments.length-2,
        name,
        argsPosition = namePosition+1,
        args = arguments[argsPosition],
        properties = getLanguageVariants( getLanguage() ),
        property,
        i,
        j,
        func,
        value;

    // for each language variant, from most specific to less specific
    for (i=properties.length-1; i>=0; i--){
      property = properties[i]; // start at top
      for (j=0; j<=namePosition && property; j++){
        name = arguments[j];
        if (name in property && j===namePosition){
          func = property[name];
          if (typeof func === 'function'){
            value = func.apply(null,args);
            if (value!==undefined && value!==null){
              return value;
            }
          }
        }
        property = property[name];
      }
    }
    return null;
  }

  function reset(){
    // Function: reset()
    // Remove all language variants.

    languages.length = 0;
  }

  return { // public API
    getLanguageVariants: getLanguageVariants,
    addLanguageProperties: addLanguageProperties,
    getProperty: getProperty,
    getValueOf: getValueOf,
    reset: reset
  };
}());
<|endoftext|>


<commit_before>var path = require("path");
var CommonsChunkPlugin = require("../../lib/optimize/CommonsChunkPlugin");
module.exports = {
	entry: {
		pageA: "./pageA",
		pageB: "./pageB",
		pageC: "./pageC",
		adminPageA: "./adminPageA",
		adminPageB: "./adminPageB",
		adminPageC: "./adminPageC",
	},
	output: {
		path: path.join(__dirname, "js"),
		filename: "[name].js"
	},
	plugins: [
		new CommonsChunkPlugin({
			name: "admin-commons",
			chunks: ["adminPageA", "adminPageB"]
		}),
		new CommonsChunkPlugin({
			name: "commons",
			chunks: ["pageA", "pageB", "admin-commons.js"],
			minChunks: 2
		}),
		new CommonsChunkPlugin({
			name: "c-commons",
			chunks: ["pageC", "adminPageC"]
		}),
	]
}
<commit_msg>fixed typo in example<commit_after>var path = require("path");
var CommonsChunkPlugin = require("../../lib/optimize/CommonsChunkPlugin");
module.exports = {
	entry: {
		pageA: "./pageA",
		pageB: "./pageB",
		pageC: "./pageC",
		adminPageA: "./adminPageA",
		adminPageB: "./adminPageB",
		adminPageC: "./adminPageC",
	},
	output: {
		path: path.join(__dirname, "js"),
		filename: "[name].js"
	},
	plugins: [
		new CommonsChunkPlugin({
			name: "admin-commons",
			chunks: ["adminPageA", "adminPageB"]
		}),
		new CommonsChunkPlugin({
			name: "commons",
			chunks: ["pageA", "pageB", "admin-commons"],
			minChunks: 2
		}),
		new CommonsChunkPlugin({
			name: "c-commons",
			chunks: ["pageC", "adminPageC"]
		}),
	]
}
<|endoftext|>


<commit_before>var my_accountws = (function(){

    "use strict";
    var currType, isPaymentAgent;

    var init = function(){
        $("#welcome").hide();
      $("#VRT_topup_link").hide();
      $("#authenticate_button").hide();
      $("#welcome_text").hide();
      BinarySocket.send({"balance": 1, "req_id": 1 });
    };

    var getBalance = function(response){
      var str , bal ;
      if(response.echo_req.req_id){
        if("error" in response) {
              if("message" in response.error) {
                  console.log(response.error.message);
              }
              return false;
          }
        else{
          currType = response.balance.currency;
          bal =  response.balance.balance;
          var isReal = !(/VRT/.test($.cookie('loginid')));
          if(parseInt(response.req_id,10) === 1){
            if(!isReal){
                str = "You're currently logged in to your virtual money account ";
                $("#welcome").show();
                $("#welcome").text(text.localize("Welcome!"));
                $("#welcome_text").show();
                $("#welcome_text .clientid").text("("+ $.cookie('loginid') +").");
                $("#welcome_text").html(text.localize(str)+$("#welcome_text").html());
                $("#cashier-portfolio").removeClass('invisible');
                      $("#profit-statement").removeClass('invisible');
                      if(bal<1000){
                    str = "Deposit %1 virtual money into your account ";
                    $("#VRT_topup_link").show();
                    $("#VRT_topup_link a").text(text.localize(str).replace("%1",currType + " 10000 "));
                }
                BinarySocket.send({"get_settings": 1, "req_id":3});
            }
            else{
               BinarySocket.send({"get_settings": 1, "req_id":4});
            }
            BinarySocket.send({"get_account_status": 1, "req_id":2});
          }

        }
      }

    };

    var showAuthenticate = function(response){
        var status;
        if("error" in response){
            if("message" in response.error) {
              console.log(response.error.message);
          }
            return false;
        }
        else{
            status = response.get_account_status[0];
            if(status === "unwelcome"){
                $("#authenticate_button").show();
                $("#authenticate_button").removeClass("invisible");
                $("#authenticate_button span").text(text.localize("Authenticate your account"));
            }
        }
    };

    var getLandingCompany = function(response){
        var country_code;
        if("error" in response){
            if("message" in response.error) {
              console.log(response.error.message);
          }
            return false;
        }
        else{
            country_code = response.get_settings.country_code;
            BinarySocket.send({"landing_company": country_code, "req_id":4});
        }
    };

    var showWelcomeText = function(response){
        var landing_company, str;
        if("error" in response){
            if("message" in response.error) {
              console.log(response.error.message);
          }
            return false;
        }
        else{
            if(/MLT/.test($.cookie('loginid'))){
                landing_company = response.landing_company.gaming_company.name;
            }
            else{
                landing_company = response.landing_company.financial_company.name;
            }
            str = "You're currently logged in to your real money account with %1 ";
            $("#welcome").show();
            $("#welcome").text(text.localize("Welcome!"));
            $("#welcome_text").show();
            $("#welcome_text .clientid").text(" ("+ $.cookie('loginid') +").");
            $("#welcome_text").html(text.localize(str).replace("%1", landing_company) + $("#welcome_text").html());
            $("#cashier-portfolio").removeClass('invisible');
            $("#profit-statement").removeClass('invisible');
            if(isPaymentAgent)
                $("#payment_agent").removeClass('invisible');
            showNoticeMsg();
        }
    };

    var showNoticeMsg = function(){
        var loginid_list = $.cookie('loginid_list');
        var res = loginid_list.split("+");
        if(res.length == "2" &&(/MLT/.test(res[0]) || /MLT/.test(res[1]))){
            $("#investment_message").removeClass("invisible");
        }
    };

    var addGTMDataLayer = function(response){
        if("error" in response){
            if("message" in response.error) {
              console.log(response.error.message);
          }
            return false;
        }
        else{
            if(page.url.param('login') || page.url.param('newaccounttype')){
                var oldUrl = window.location.href;
                var newUrl = oldUrl.replace(/(login=true&|newaccounttype=real&|newaccounttype=virtual&)/gi, "");
                var title = document.title;
                var age = parseInt((moment(str).unix()-response.get_settings.date_of_birth)/31557600);
                var name = TUser.get().fullname.split(' ');
                var data = {};
                var affiliateToken = $.cookie('affiliate_tracking');
                if (affiliateToken) {
                    dataLayer.push({'bom_affiliate_token': affiliateToken});
                }
                data['bom_country'] = response.get_settings.country;
                data['bom_email'] = TUser.get().email;
                data['language'] = page.url.param("l");
                data['pageTitle'] = title;
                data['url'] = oldUrl;
                data['visitorID'] = TUser.get().loginid;
                data['bom_today'] = Math.floor(Date.now() / 1000);

                if(response.req_id === 4){
                    data['bom_age'] = age;
                    data['bom_firstname'] = name[1];
                    data['bom_lastname'] = name[2];
                    data['bom_phone'] = response.get_settings.phone;
                }

                if(page.url.param('newaccounttype'))
                    data['event'] = 'new_account';
                else
                    data['event'] = 'log_in';

                dataLayer.push(data);
                window.history.replaceState("My Account", title, newUrl);
            }
        }
    };

    var checkPaymentAgent = function(response){
        if("error" in response){
            if("message" in response.error) {
              console.log(response.error.message);
          }
            return false;
        }
        else{
            isPaymentAgent = response.is_authenticated_payment_agent;
        }
    };

    var apiResponse = function(response){
      var type = response.msg_type;
      if(type === "balance" || (type === "error" && "balance" in response.echo_req))
        {
            getBalance(response);
        }
        if(type === "get_account_status" || (type === "error" && "get_account_status" in response.echo_req)){
            showAuthenticate(response);
        }
        if(type === "get_settings" && response.req_id === 3 || (type === "error" && "get_settings" in response.echo_req)){
            addGTMDataLayer(response);
        }
        if(type === "get_settings" && response.req_id === 4 || (type === "error" && "get_settings" in response.echo_req)){
            getLandingCompany(response);
            checkPaymentAgent(response);
            addGTMDataLayer(response);
        }
        if(type === "landing_company" || (type === "error" && "landing_company" in response.echo_req)){
            showWelcomeText(response);
        }
    };

    return {
      init : init,
      apiResponse : apiResponse

    };

})();

pjax_config_page("user/my_accountws", function() {
    return {
        onLoad: function() {
          if (!getCookieItem('login')) {
                window.location.href = page.url.url_for('login');
                return;
            }
          BinarySocket.init({
                onmessage: function(msg){
                    var response = JSON.parse(msg.data);
                    if (response) {
                        my_accountws.apiResponse(response);

                    }
                }
            });
            Content.populate();
            my_accountws.init();
        }
    };
});
<commit_msg>my_accountws minor fix<commit_after>var my_accountws = (function(){

    "use strict";
    var currType, isPaymentAgent;

    var init = function(){
        $("#welcome").hide();
      $("#VRT_topup_link").hide();
      $("#authenticate_button").hide();
      $("#welcome_text").hide();
      BinarySocket.send({"balance": 1, "req_id": 1 });
    };

    var getBalance = function(response){
      var str , bal ;
      if(response.echo_req.req_id){
        if("error" in response) {
              if("message" in response.error) {
                  console.log(response.error.message);
              }
              return false;
          }
        else{
          currType = response.balance.currency;
          bal =  response.balance.balance;
          var isReal = !(/VRT/.test($.cookie('loginid')));
          if(parseInt(response.req_id,10) === 1){
            if(!isReal){
                str = "You're currently logged in to your virtual money account ";
                $("#welcome").show();
                $("#welcome").text(text.localize("Welcome!"));
                $("#welcome_text").show();
                $("#welcome_text .clientid").text("("+ $.cookie('loginid') +").");
                $("#welcome_text").html(text.localize(str)+$("#welcome_text").html());
                $("#cashier-portfolio").removeClass('invisible');
                      $("#profit-statement").removeClass('invisible');
                      if(bal<1000){
                    str = "Deposit %1 virtual money into your account ";
                    $("#VRT_topup_link").show();
                    $("#VRT_topup_link a").text(text.localize(str).replace("%1",currType + " 10000 "));
                }
                BinarySocket.send({"get_settings": 1, "req_id":3});
            }
            else{
               BinarySocket.send({"get_settings": 1, "req_id":4});
            }
            BinarySocket.send({"get_account_status": 1, "req_id":2});
          }

        }
      }

    };

    var showAuthenticate = function(response){
        var status;
        if("error" in response){
            if("message" in response.error) {
              console.log(response.error.message);
          }
            return false;
        }
        else{
            status = response.get_account_status[0];
            if(status === "unwelcome"){
                $("#authenticate_button").show();
                $("#authenticate_button").removeClass("invisible");
                $("#authenticate_button span").text(text.localize("Authenticate your account"));
            }
        }
    };

    var getLandingCompany = function(response){
        var country_code;
        if("error" in response){
            if("message" in response.error) {
              console.log(response.error.message);
          }
            return false;
        }
        else{
            country_code = response.get_settings.country_code;
            BinarySocket.send({"landing_company": country_code, "req_id":4});
        }
    };

    var showWelcomeText = function(response){
        var landing_company, str;
        if("error" in response){
            if("message" in response.error) {
              console.log(response.error.message);
          }
            return false;
        }
        else{
            if(/MLT/.test($.cookie('loginid'))){
                landing_company = response.landing_company.gaming_company.name;
            }
            else{
                landing_company = response.landing_company.financial_company.name;
            }
            str = "You're currently logged in to your real money account with %1 ";
            $("#welcome").show();
            $("#welcome").text(text.localize("Welcome!"));
            $("#welcome_text").show();
            $("#welcome_text .clientid").text(" ("+ $.cookie('loginid') +").");
            $("#welcome_text").html(text.localize(str).replace("%1", landing_company) + $("#welcome_text").html());
            $("#cashier-portfolio").removeClass('invisible');
            $("#profit-statement").removeClass('invisible');
            if(isPaymentAgent)
                $("#payment_agent").removeClass('invisible');
            showNoticeMsg();
        }
    };

    var showNoticeMsg = function(){
        var loginid_list = $.cookie('loginid_list');
        var res = loginid_list.split("+");
        if(res.length == "2" &&(/MLT/.test(res[0]) || /MLT/.test(res[1]))){
            $("#investment_message").removeClass("invisible");
        }
    };

    var addGTMDataLayer = function(response){
        if("error" in response){
            if("message" in response.error) {
              console.log(response.error.message);
          }
            return false;
        }
        else{
            if(page.url.param('login') || page.url.param('newaccounttype')){
                var oldUrl = window.location.href;
                var newUrl = oldUrl.replace(/(login=true&|newaccounttype=real&|newaccounttype=virtual&)/gi, "");
                var title = document.title;
                var age = parseInt((moment(str).unix()-response.get_settings.date_of_birth)/31557600);
                var name = TUser.get().fullname.split(' ');
                var data = {};
                var affiliateToken = $.cookie('affiliate_tracking');
                if (affiliateToken) {
                    dataLayer.push({'bom_affiliate_token': affiliateToken});
                }
                data['bom_country'] = response.get_settings.country;
                data['bom_email'] = TUser.get().email;
                data['language'] = page.url.param("l");
                data['pageTitle'] = title;
                data['url'] = oldUrl;
                data['visitorID'] = TUser.get().loginid;
                data['bom_today'] = Math.floor(Date.now() / 1000);

                if(response.req_id === 4){
                    data['bom_age'] = age;
                    data['bom_firstname'] = name[1];
                    data['bom_lastname'] = name[2];
                    data['bom_phone'] = response.get_settings.phone;
                }

                if(page.url.param('newaccounttype'))
                    data['event'] = 'new_account';
                else
                    data['event'] = 'log_in';

                dataLayer.push(data);
                window.history.replaceState("My Account", title, newUrl);
            }
        }
    };

    var checkPaymentAgent = function(response){
        if("error" in response){
            if("message" in response.error) {
              console.log(response.error.message);
          }
            return false;
        }
        else{
            isPaymentAgent = response.get_settings.is_authenticated_payment_agent;
        }
    };

    var apiResponse = function(response){
      var type = response.msg_type;
      if(type === "balance" || (type === "error" && "balance" in response.echo_req))
        {
            getBalance(response);
        }
        if(type === "get_account_status" || (type === "error" && "get_account_status" in response.echo_req)){
            showAuthenticate(response);
        }
        if(type === "get_settings" && response.req_id === 3 || (type === "error" && "get_settings" in response.echo_req)){
            addGTMDataLayer(response);
        }
        if(type === "get_settings" && response.req_id === 4 || (type === "error" && "get_settings" in response.echo_req)){
            getLandingCompany(response);
            checkPaymentAgent(response);
            addGTMDataLayer(response);
        }
        if(type === "landing_company" || (type === "error" && "landing_company" in response.echo_req)){
            showWelcomeText(response);
        }
    };

    var checkDisabledAccount = function(){
        var divOne = text.localize('
Your %1 account is unavailable. For any questions please contact Customer Support.
').replace('%2', page.url.url_for('contact')),
            divTwo = text.localize('
Your %1 accounts are unavailable. For any questions please contact Customer Support.
').replace('%2', page.url.url_for('contact'));
        var loginidArry = page.user.loginid_array,
            disabledAccount = [];
        for (var i = 0; i < loginidArry.length; i++) {
            if (loginidArry[i].disabled === true) {
                disabledAccount.push(loginidArry[i].id);
            }
        }
        if (disabledAccount.length === 1) {
            $(divOne.replace('%1', disabledAccount.toString())).insertAfter('.clientid');
        } else if (disabledAccount.length > 1) {
            $(divTwo.replace('%1', disabledAccount.join(', '))).insertAfter('.clientid');
        }
    };

    return {
      init : init,
      checkDisabledAccount : checkDisabledAccount,
      apiResponse : apiResponse

    };

})();

pjax_config_page("user/my_accountws", function() {
    return {
        onLoad: function() {
          if (!getCookieItem('login')) {
                window.location.href = page.url.url_for('login');
                return;
            }
          BinarySocket.init({
                onmessage: function(msg){
                    var response = JSON.parse(msg.data);
                    if (response) {
                        my_accountws.apiResponse(response);

                    }
                }
            });
            Content.populate();
            my_accountws.init();
            my_accountws.checkDisabledAccount();
        }
    };
});
<|endoftext|>


<commit_before>import {Readable} from "stream"
import {basename} from "path"

import invariant from "@octetstream/invariant"
import mimes from "mime-types"

import bind from "./util/bind"
import concat from "./util/concat"
import isBuffer from "./util/isBuffer"
import isReadable from "./util/isReadable"
import nextTick from "./util/nextTick"
import boundary from "./util/boundary"

import StreamIterator from "./util/StreamIterator"

const isString = val => typeof val === "string"

class FormData {
  constructor() {
    bind([
      Symbol.iterator, Symbol.asyncIterator, "keys", "values", "entries"
    ], this)

    this.__caret = "\r\n"
    this.__defaultContentType = "application/octet-steam"

    this.__dashes = "--"
    this.__boundary = concat("NodeJSFormDataStream", boundary())

    this.__contents = new Map()
    this.__entries = this.__contents.entries()

    this.__curr = this.__getField()

    const read = this.__read

    this.__stream = new Readable({read})

    this.headers = {
      "Content-Type": concat(
        "multipart/form-data; boundary=", this.__boundary
      )
    }
  }

  __getMime = filename => mimes.lookup(filename) || this.__defaultContentType

  __getHeader(name, filename) {
    const head = [
      this.__dashes, this.__boundary, this.__caret,
      "Content-Disposition: form-data; ", `name="${name}"`,
    ]

    if (filename) {
      head.push(`; filename="${filename}"${this.__caret}`)
      head.push(`Content-Type: "${this.__getMime(filename)}"`)
    }

    head.push(this.__caret.repeat(2))

    return Buffer.from(concat(head))
  }

  __getFooter = () => (
    Buffer.from(
      concat(
        this.__dashes, this.__boundary,
        this.__dashes, this.__caret.repeat(2)
      )
    )
  )

  /**
   * @private
   */
  async* __getField() {
    while (true) {
      await nextTick()

      const curr = this.__entries.next()

      if (curr.done === true) {
        yield this.__getFooter()

        return
      }

      const [name, {value, filename}] = curr.value

      yield this.__getHeader(name, filename)

      if (isReadable(value)) {
        const iterator = new StreamIterator(value)

        for await (const ch of iterator) {
          yield ch
        }
      } else {
        yield isBuffer(value) ? value : Buffer.from(value)
      }

      yield Buffer.from(this.__caret)
    }
  }

  /**
   * @private
   */
  __read = () => {
    const onFulfilled = curr => {
      if (curr.done) {
        return this.__stream.push(null)
      }

      const ch = curr.value

      this.__stream.push(ch)
    }

    const onRejected = err => this.__stream.emit("error", err)

    this.__curr.next().then(onFulfilled, onRejected)
  }

  __setField(name, value, filename, append = false) {
    invariant(
      !isString(name), TypeError,
      "Field name should be a string. Received %s", typeof name
    )

    invariant(
      filename && !isString(filename), TypeError,
      "Filename should be a string (if passed). Received %s", typeof filename
    )

    if (isBuffer(value) && filename) {
      filename = basename(filename)
    } else if (isReadable(value) && (value.path || filename)) {
      filename = basename(value.path || filename)
    } else {
      value = String(value)
    }

    append = Boolean(append)

    this.__contents.set(String(name), {append, value, filename})
  }

  get boundary() {
    return this.__boundary
  }

  // append = (name, value, filename) => {
  //   if (this.has(name) === false) {
  //     return this.__setField(name, value, filename, true)
  //   }

  //   const field = this.get(name)

  //   if (field.append === true) {
  //     this.__setField(name, `${field.value}${value}`, filename)
  //   }
  // }

  /**
   * Set new field on FormData
   *
   * @param {string} name – field name
   * @param {any} value – field value
   */
  set = (name, value, filename) => this.__setField(name, value, filename)

  has = name => this.__contents.has(name)

  // NOTE: This method should return only the first field value.
  // I should add this behaviour somehow
  get = name => {
    const field = this.__contents.get(name)

    return field ? field.value : void 0
  }

  // TODO: Implement this method due to spec
  // getAll = () => {}

  delete = name => void this.__contents.delete(name)

  pipe = (dest, options) => this.__stream.pipe(dest, options)

  on = (name, fn) => {
    this.__stream.on(name, fn)

    return this
  }

  [Symbol.iterator]() {
    return this.__contents[Symbol.iterator]()
  }

  [Symbol.asyncIterator]() {
    return new StreamIterator(this.__stream)
  }

  keys() {
    return this.__contents.keys()
  }

  values() {
    return this.__contents.values()
  }

  entries() {
    return this.__contents.entries()
  }

  toString() {
    return "[object FormData]"
  }

  inspect() {
    return "FormData { }"
  }
}

export default FormData
<commit_msg>Add some in-code docs.<commit_after>import {Readable} from "stream"
import {basename} from "path"

import invariant from "@octetstream/invariant"
import mimes from "mime-types"

import bind from "./util/bind"
import concat from "./util/concat"
import isBuffer from "./util/isBuffer"
import isReadable from "./util/isReadable"
import nextTick from "./util/nextTick"
import boundary from "./util/boundary"

import StreamIterator from "./util/StreamIterator"

const isString = val => typeof val === "string"

class FormData {
  constructor() {
    bind([
      Symbol.iterator, Symbol.asyncIterator, "keys", "values", "entries"
    ], this)

    this.__caret = "\r\n"
    this.__defaultContentType = "application/octet-steam"

    this.__dashes = "--"
    this.__boundary = concat("NodeJSFormDataStream", boundary())

    this.__contents = new Map()
    this.__entries = this.__contents.entries()

    this.__curr = this.__getField()

    const read = this.__read

    this.__stream = new Readable({read})

    this.headers = {
      "Content-Type": concat(
        "multipart/form-data; boundary=", this.__boundary
      )
    }
  }

  __getMime = filename => mimes.lookup(filename) || this.__defaultContentType

  __getHeader(name, filename) {
    const head = [
      this.__dashes, this.__boundary, this.__caret,
      "Content-Disposition: form-data; ", `name="${name}"`,
    ]

    if (filename) {
      head.push(`; filename="${filename}"${this.__caret}`)
      head.push(`Content-Type: "${this.__getMime(filename)}"`)
    }

    head.push(this.__caret.repeat(2))

    return Buffer.from(concat(head))
  }

  __getFooter = () => (
    Buffer.from(
      concat(
        this.__dashes, this.__boundary,
        this.__dashes, this.__caret.repeat(2)
      )
    )
  )

  /**
   * @private
   */
  async* __getField() {
    while (true) {
      await nextTick()

      const curr = this.__entries.next()

      if (curr.done === true) {
        yield this.__getFooter()

        return
      }

      const [name, {value, filename}] = curr.value

      yield this.__getHeader(name, filename)

      if (isReadable(value)) {
        const iterator = new StreamIterator(value)

        for await (const ch of iterator) {
          yield ch
        }
      } else {
        yield isBuffer(value) ? value : Buffer.from(value)
      }

      yield Buffer.from(this.__caret)
    }
  }

  /**
   * @private
   */
  __read = () => {
    const onFulfilled = curr => {
      if (curr.done) {
        return this.__stream.push(null)
      }

      const ch = curr.value

      this.__stream.push(ch)
    }

    const onRejected = err => this.__stream.emit("error", err)

    this.__curr.next().then(onFulfilled, onRejected)
  }

  /**
   * Set a new filed to internal FormData Map object
   *
   * @param {string} name
   * @param {any} value
   * @param {string} filename
   * @param {boolean} append
   *
   * @return {void}
   */
  __setField(name, value, filename, append = false) {
    invariant(
      !isString(name), TypeError,
      "Field name should be a string. Received %s", typeof name
    )

    invariant(
      filename && !isString(filename), TypeError,
      "Filename should be a string (if passed). Received %s", typeof filename
    )

    // Try to get a filename for buffer and stream values
    if (isBuffer(value) && filename) {
      filename = basename(filename)
    } else if (isReadable(value) && (value.path || filename)) {
      filename = basename(value.path || filename)
    }

    // Convers value to a string if it not stream or buffer
    if (!isBuffer(value) && !isReadable(value)) {
      value = String(value)
    }

    append = Boolean(append)

    this.__contents.set(String(name), {append, value, filename})
  }

  get boundary() {
    return this.__boundary
  }

  // append = (name, value, filename) => {
  //   if (this.has(name) === false) {
  //     return this.__setField(name, value, filename, true)
  //   }

  //   const field = this.get(name)

  //   if (field.append === true) {
  //     this.__setField(name, `${field.value}${value}`, filename)
  //   }
  // }

  /**
   * Set new field on FormData
   *
   * @param {string} name – field name
   * @param {any} value – field value
   * @param {string} filename
   *
   * @return {void}
   */
  set = (name, value, filename) => this.__setField(name, value, filename)

  /**
   * Check if the value with given key exists
   *
   * @param {string} name – name of a value you are looking for
   *
   * @return {boolean}
   */
  has = name => this.__contents.has(name)

  get = name => {
    const field = this.__contents.get(name)

    // NOTE: This method should return only the first field value.
    // I should add this behaviour somehow
    return field ? field.value : void 0
  }

  // TODO: Implement this method due to spec
  // getAll = () => {}

  delete = name => void this.__contents.delete(name)

  pipe = (dest, options) => this.__stream.pipe(dest, options)

  on = (name, fn) => {
    this.__stream.on(name, fn)

    return this
  }

  [Symbol.iterator]() {
    return this.__contents[Symbol.iterator]()
  }

  [Symbol.asyncIterator]() {
    return new StreamIterator(this.__stream)
  }

  keys() {
    return this.__contents.keys()
  }

  values() {
    return this.__contents.values()
  }

  entries() {
    return this.__contents.entries()
  }

  toString() {
    return "[object FormData]"
  }

  inspect() {
    return "FormData { }"
  }
}

export default FormData
<|endoftext|>


<commit_before>import React, { useCallback, useContext, useEffect, useState } from 'react';
import { ThemeContext } from 'styled-components';
import { defaultProps } from '../../default-props';

import { Box } from '../Box';
import { Button } from '../Button';
import { Layer } from '../Layer';
import { Paragraph } from '../Paragraph';
import { Text } from '../Text';

import { NotificationType } from './propTypes';

const Notification = ({ message, onClose, status, title, toast }) => {
  const theme = useContext(ThemeContext) || defaultProps.theme;
  const [visible, setVisible] = useState(true);

  const close = useCallback(() => {
    setVisible(false);
    if (onClose) onClose();
  }, [onClose]);

  useEffect(() => {
    const timer = setTimeout(close, theme.notification.time);

    return () => clearTimeout(timer);
  }, [close]);

  const { icon: CloseIcon } = theme.notification.close;
  const { icon: StatusIcon, color } = theme.notification[status];
  const { color: closeIconColor } = theme.notification.close;

  let content = (
    <Box
      {...theme.notification.container}
      {...(toast ? { ...theme.notification.toast.container } : {})}
      direction="row"
    >
      <Box {...theme.notification.iconContainer}>
        <StatusIcon color={color} />
      </Box>
      <Box
        {...theme.notification.textContainer}
        align="start"
        direction="row"
        justify="between"
        flex
      >
        <Box>
          <Text {...theme.notification.title}>{title}</Text>
          {message && (
            <Paragraph {...theme.notification.message}>{message}</Paragraph>
          )}
        </Box>
        {onClose && (
          <Button
            icon={<CloseIcon color={closeIconColor} />}
            onClick={close}
            plain
          />
        )}
      </Box>
    </Box>
  );

  if (toast) {
    content = visible && (
      <Layer
        {...theme.notification.toast.layer}
        role="log"
        modal={false}
        onEsc={onClose}
        responsive
        plain
      >
        {content}
      </Layer>
    );
  }

  return content;
};

Notification.defaultProps = {
  status: 'unknown',
  toast: false,
};

Object.setPrototypeOf(Notification.defaultProps, defaultProps);
Notification.displayName = 'Notification';

Notification.propTypes = NotificationType;

export { Notification };
<commit_msg>Fix missing effect dependency (#5568)<commit_after>import React, { useCallback, useContext, useEffect, useState } from 'react';
import { ThemeContext } from 'styled-components';
import { defaultProps } from '../../default-props';

import { Box } from '../Box';
import { Button } from '../Button';
import { Layer } from '../Layer';
import { Paragraph } from '../Paragraph';
import { Text } from '../Text';

import { NotificationType } from './propTypes';

const Notification = ({ message, onClose, status, title, toast }) => {
  const theme = useContext(ThemeContext) || defaultProps.theme;
  const [visible, setVisible] = useState(true);

  const close = useCallback(() => {
    setVisible(false);
    if (onClose) onClose();
  }, [onClose]);

  useEffect(() => {
    const timer = setTimeout(close, theme.notification.time);

    return () => clearTimeout(timer);
  }, [close, theme.notification.time]);

  const { icon: CloseIcon } = theme.notification.close;
  const { icon: StatusIcon, color } = theme.notification[status];
  const { color: closeIconColor } = theme.notification.close;

  let content = (
    <Box
      {...theme.notification.container}
      {...(toast ? { ...theme.notification.toast.container } : {})}
      direction="row"
    >
      <Box {...theme.notification.iconContainer}>
        <StatusIcon color={color} />
      </Box>
      <Box
        {...theme.notification.textContainer}
        align="start"
        direction="row"
        justify="between"
        flex
      >
        <Box>
          <Text {...theme.notification.title}>{title}</Text>
          {message && (
            <Paragraph {...theme.notification.message}>{message}</Paragraph>
          )}
        </Box>
        {onClose && (
          <Button
            icon={<CloseIcon color={closeIconColor} />}
            onClick={close}
            plain
          />
        )}
      </Box>
    </Box>
  );

  if (toast) {
    content = visible && (
      <Layer
        {...theme.notification.toast.layer}
        role="log"
        modal={false}
        onEsc={onClose}
        responsive
        plain
      >
        {content}
      </Layer>
    );
  }

  return content;
};

Notification.defaultProps = {
  status: 'unknown',
  toast: false,
};

Object.setPrototypeOf(Notification.defaultProps, defaultProps);
Notification.displayName = 'Notification';

Notification.propTypes = NotificationType;

export { Notification };
<|endoftext|>


<commit_before>$(function() {
	$("#menu-toggle").click(function() {
		$(".mainmenu").slideToggle();
	});
	$("#menu-clear-cache").click(function() {
		$(this).hide();
		$("#menu-clear-cache-loading").show()
		var url = $("#menu-clear-cache").data("url");
		$.get(url, function(result) {
			$("#menu-clear-cache").show();
			$("#menu-clear-cache-loading").hide();
		});
	});

		// dynamically add class form-control to all form elements
		// Todo: add class to all HTML-Tags to make this code useless
	    $('input, select, textarea')
			.not("input[type=checkbox]")
			.not("input[type=radio]")
			.not("input[type=button]")
			.not("input[type=submit]")
			.not("input[type=reset]")
			.not("input[type=image]")
			.addClass('form-control');

	// better select-boxes
    $("select").select2({width: '100%'});

});
<commit_msg>code kommentiert<commit_after>$(function() {
	// toggle hamburger menu
	$("#menu-toggle").click(function() {
		$(".mainmenu").slideToggle();
	});
	// clear-cache shortcut icon
	$("#menu-clear-cache").click(function() {
		$(this).hide();
		$("#menu-clear-cache-loading").show()
		var url = $("#menu-clear-cache").data("url");
		$.get(url, function(result) {
			$("#menu-clear-cache").show();
			$("#menu-clear-cache-loading").hide();
		});
	});

		// dynamically add class form-control to all form elements to
		// make inputs prettier
	    $('input, select, textarea')
			.not("input[type=checkbox]")
			.not("input[type=radio]")
			.not("input[type=button]")
			.not("input[type=submit]")
			.not("input[type=reset]")
			.not("input[type=image]")
			.addClass('form-control');

	// prettier select-boxes
    $("select").select2({width: '100%'});

});
<|endoftext|>


<commit_before>'use strict';

(function() {
  angular.module('ncsaas')
    .controller('ResourceListController', ['baseControllerListClass', 'resourcesService', ResourceListController]);

  function ResourceListController(baseControllerListClass, resourcesService) {
    var controllerScope = this;
    var ResourceController = baseControllerListClass.extend({
      init:function() {
        this.service = resourcesService;
        this.controllerScope = controllerScope;
        this._super();
        this.searchFieldName = 'hostname';
      },
      stopResource:function(resource) {
        var vm = this;
        resourcesService.stopResource(resource.uuid).then(
          vm.reInitResource.bind(null, resource), vm.handleActionException);
      },
      startResource:function(resource) {
        var vm = this;
        resourcesService.startResource(resource.uuid).then(
          vm.reInitResource.bind(null, resource), vm.handleActionException);
      },
      restartResource:function(resource) {
        var vm = this;
        resourcesService.restartResource(resource.uuid).then(
          vm.reInitResource.bind(null, resource), vm.handleActionException);
      },
      isOperationAvailable:function(resource, operation) {
        var availableOperations = resourcesService.getAvailableOperations(resource);
        operation = operation.toLowerCase();
        return availableOperations.indexOf(operation) !== -1;
      },
      reInitResource:function(resource) {
        var vm = this;
        resourcesService.$get(resource.uuid).then(function(response) {
          var index = vm.list.indexOf(resource);
          vm.list[index] = response;
        });
      }
    });

    controllerScope.__proto__ = new ResourceController();
  }

})();

(function() {
  angular.module('ncsaas')
    .controller('ResourceAddController',
    ['resourcesService', 'servicesService', 'projectsService', 'keysService', 'templatesService', 'baseControllerAddClass',
      ResourceAddController]);

  function ResourceAddController(
    resourcesService, servicesService, projectsService, keysService, templatesService, baseControllerAddClass) {
    var controllerScope = this;
    var ResourceController = baseControllerAddClass.extend({
      showFlavors: false,
      showTemplates: false,

      serviceList: {},
      flavorList: {},
      keyList: {},
      projectList: {},
      templateList:{},
      selectedProject: null,

      init:function() {
        this.service = resourcesService;
        this.controllerScope = controllerScope;
        this.setSignalHandler('currentCustomerUpdated', this.currentCustomerUpdatedHandler.bind(this));
        this._super();
        this.listState = 'resources.list';
        this.resource = this.instance;
      },
      activate:function() {
        var vm = this;
        // projects
        projectsService.getList().then(function(response) {
          vm.projectList = response;
        });
        // keys
        keysService.getCurrentUserKeyList().then(function(response) {
          vm.keyList = response;
        });
      },
      setService:function(service) {
        var vm = this;
        vm.flavorList = service.flavors;
        templatesService.getTemplateList(service.uuid).then(function(response) {
          vm.templateList = response;
        });
        vm.selectedService = service;
        vm.showTemplates = true;
      },
      setTemplate:function(tamplate) {
        var vm = this;
        vm.resource.template = tamplate.url;
        vm.selectedTemplate = tamplate;
        vm.showFlavors = true;
      },
      setFlavor:function(flavor) {
        var vm = this;
        vm.resource.flavor = flavor.url;
        vm.selectedFlavor = flavor;
      },
      setProject:function(project) {
        var vm = this;
        if (project) {
          vm.resource.project = project.url;
          // services
          servicesService.getList({project: project.uuid}).then(function(response) {
            vm.serviceList = response;
          });
        } else {
          vm.serviceList = {};
        }
      },
      currentCustomerUpdatedHandler: function() {
        var vm = this.controllerScope;
        vm.showFlavors = false;
        vm.showTemplates = false;
        vm.selectedProject = null;
        vm.serviceList = {};
        vm.flavorList = {};
        vm.keyList = {};
        vm.projectList = {};
        vm.templateList = {};
        vm.activate();
      }
    });

    controllerScope.__proto__ = new ResourceController();
  }
})();
<commit_msg>Fix resources add form. Addint variable showServices to controller.<commit_after>'use strict';

(function() {
  angular.module('ncsaas')
    .controller('ResourceListController', ['baseControllerListClass', 'resourcesService', ResourceListController]);

  function ResourceListController(baseControllerListClass, resourcesService) {
    var controllerScope = this;
    var ResourceController = baseControllerListClass.extend({
      init:function() {
        this.service = resourcesService;
        this.controllerScope = controllerScope;
        this._super();
        this.searchFieldName = 'hostname';
      },
      stopResource:function(resource) {
        var vm = this;
        resourcesService.stopResource(resource.uuid).then(
          vm.reInitResource.bind(null, resource), vm.handleActionException);
      },
      startResource:function(resource) {
        var vm = this;
        resourcesService.startResource(resource.uuid).then(
          vm.reInitResource.bind(null, resource), vm.handleActionException);
      },
      restartResource:function(resource) {
        var vm = this;
        resourcesService.restartResource(resource.uuid).then(
          vm.reInitResource.bind(null, resource), vm.handleActionException);
      },
      isOperationAvailable:function(resource, operation) {
        var availableOperations = resourcesService.getAvailableOperations(resource);
        operation = operation.toLowerCase();
        return availableOperations.indexOf(operation) !== -1;
      },
      reInitResource:function(resource) {
        var vm = this;
        resourcesService.$get(resource.uuid).then(function(response) {
          var index = vm.list.indexOf(resource);
          vm.list[index] = response;
        });
      }
    });

    controllerScope.__proto__ = new ResourceController();
  }

})();

(function() {
  angular.module('ncsaas')
    .controller('ResourceAddController',
    ['resourcesService', 'servicesService', 'projectsService', 'keysService', 'templatesService', 'baseControllerAddClass',
      ResourceAddController]);

  function ResourceAddController(
    resourcesService, servicesService, projectsService, keysService, templatesService, baseControllerAddClass) {
    var controllerScope = this;
    var ResourceController = baseControllerAddClass.extend({
      showServices: false,
      showFlavors: false,
      showTemplates: false,

      serviceList: {},
      flavorList: {},
      keyList: {},
      projectList: {},
      templateList:{},
      selectedProject: null,

      init:function() {
        this.service = resourcesService;
        this.controllerScope = controllerScope;
        this.setSignalHandler('currentCustomerUpdated', this.currentCustomerUpdatedHandler.bind(this));
        this._super();
        this.listState = 'resources.list';
        this.resource = this.instance;
      },
      activate:function() {
        var vm = this;
        // projects
        projectsService.getList().then(function(response) {
          vm.projectList = response;
        });
        // keys
        keysService.getCurrentUserKeyList().then(function(response) {
          vm.keyList = response;
        });
      },
      setService:function(service) {
        var vm = this;
        vm.flavorList = service.flavors;
        templatesService.getTemplateList(service.uuid).then(function(response) {
          vm.templateList = response;
        });
        vm.selectedService = service;
        vm.showTemplates = true;
      },
      setTemplate:function(tamplate) {
        var vm = this;
        vm.resource.template = tamplate.url;
        vm.selectedTemplate = tamplate;
        vm.showFlavors = true;
      },
      setFlavor:function(flavor) {
        var vm = this;
        vm.resource.flavor = flavor.url;
        vm.selectedFlavor = flavor;
      },
      setProject:function(project) {
        var vm = this;
        if (project) {
          vm.resource.project = project.url;
          vm.showServices = true;
          // services
          servicesService.getList({project: project.uuid}).then(function(response) {
            vm.serviceList = response;
          });
        } else {
          vm.serviceList = {};
        }
      },
      currentCustomerUpdatedHandler: function() {
        var vm = this.controllerScope;
        vm.showFlavors = false;
        vm.showTemplates = false;
        vm.selectedProject = null;
        vm.serviceList = {};
        vm.flavorList = {};
        vm.keyList = {};
        vm.projectList = {};
        vm.templateList = {};
        vm.activate();
      }
    });

    controllerScope.__proto__ = new ResourceController();
  }
})();
<|endoftext|>


<commit_before>var WritableStream = require('stream').Writable
                     || require('readable-stream').Writable,
    inherits = require('util').inherits;

var StreamSearch = require('streamsearch');

var PartStream = require('./PartStream'),
    HeaderParser = require('./HeaderParser');

var DASH = 45,
    B_ONEDASH = new Buffer('-'),
    B_CRLF = new Buffer('\r\n');

function Dicer(cfg) {
  if (!(this instanceof Dicer))
    return new Dicer(cfg);
  WritableStream.call(this, cfg);

  if (!cfg || (!cfg.headerFirst && typeof cfg.boundary !== 'string'))
    throw new TypeError('Boundary required');

  if (typeof cfg.boundary === 'string')
    this.setBoundary(cfg.boundary);
  else
    this._bparser = undefined;

  this._headerFirst = cfg.headerFirst;

  var self = this;

  this._dashes = 0;
  this._parts = 0;
  this._finished = false;
  this._sawFinish = false;
  this._isPreamble = true;
  this._justMatched = false;
  this._firstWrite = true;
  this._inHeader = true;
  this._part = undefined;
  this._cb = undefined;
  this._ignoreData = false;
  this._partOpts = (typeof cfg.partHwm === 'number'
                    ? { highWaterMark: cfg.partHwm }
                    : {});
  this._pause = false;

  this._hparser = new HeaderParser(cfg);
  this._hparser.on('header', function(header) {
    self._inHeader = false;
    self._part.emit('header', header);
  });

}
inherits(Dicer, WritableStream);

Dicer.prototype.emit = function(ev) {
  if (ev === 'finish' && !this._sawFinish) {
    this._sawFinish = true;
    if (!this._finished) {
      var self = this;
      process.nextTick(function() {
        self.emit('error', new Error('Unexpected end of multipart data'));
        if (self._part && !self._ignoreData) {
          var type = (self._isPreamble ? 'Preamble' : 'Part');
          self._part.emit('error', new Error(type + ' terminated early due to unexpected end of multipart data'));
          self._part.push(null);
          process.nextTick(function() {
            self.emit('finish');
            self.reset();
          });
          return;
        }
        self.emit('finish');
        self.reset();
      });
    }
  } else
    WritableStream.prototype.emit.apply(this, arguments);
};

Dicer.prototype._write = function(data, encoding, cb) {
  if (this._headerFirst && this._isPreamble) {
    if (!this._part) {
      this._part = new PartStream(this._partOpts);
      if (this._events.preamble)
        this.emit('preamble', this._part);
      else {
        this._ignoreData = true;
        // we must perform some kind of read on the stream even though we are
        // ignoring the data, otherwise node's Readable stream will not emit 'end'
        // after pushing null to the stream
        this._part.resume();
      }
    }
    var r = this._hparser.push(data);
    if (!this._inHeader && r !== undefined && r < data.length)
      data = data.slice(r);
    else
      return cb();
  }

  // allows for "easier" testing
  if (this._firstWrite) {
    this._bparser.push(B_CRLF);
    this._firstWrite = false;
  }

  this._bparser.push(data);

  if (this._pause)
    this._cb = cb;
  else
    cb();
};

Dicer.prototype.reset = function() {
  this._part = undefined;
  this._bparser = undefined;
  this._hparser = undefined;
};

Dicer.prototype.setBoundary = function(boundary) {
  var self = this;
  this._bparser = new StreamSearch('\r\n--' + boundary);
  this._bparser.on('info', function(isMatch, data, start, end) {
    self._oninfo(isMatch, data, start, end);
  });
};

Dicer.prototype._oninfo = function(isMatch, data, start, end) {
  var buf, self = this, i = 0, r, ev, shouldWriteMore = true;

  if (!this._part && this._justMatched && data) {
    while (this._dashes < 2 && (start + i) < end) {
      if (data[start + i] === DASH) {
        ++i;
        ++this._dashes;
      } else {
        if (this._dashes)
          buf = B_ONEDASH;
        this._dashes = 0;
        break;
      }
    }
    if (this._dashes === 2) {
      if ((start + i) < end && this._events.trailer)
        this.emit('trailer', data.slice(start + i, end));
      this.reset();
      this._finished = true;
    }
    if (this._dashes)
      return;
  }
  if (this._justMatched)
    this._justMatched = false;
  if (!this._part) {
    this._part = new PartStream(this._partOpts);
    this._part._read = function(n) {
      if (!self._pause)
        return;
      self._pause = false;
      if (self._cb) {
        var cb = self._cb;
        self._cb = undefined;
        cb();
      }
    };
    ev = this._isPreamble ? 'preamble' : 'part';
    if (this._events[ev])
      this.emit(ev, this._part);
    else {
      this._ignoreData = true;
      // we must perform some kind of read on the stream even though we are
      // ignoring the data, otherwise node's Readable stream will not emit 'end'
      // after pushing null to the stream
      this._part.resume();
    }
    if (!this._isPreamble)
      this._inHeader = true;
  }
  if (data && start < end && !this._ignoreData) {
    if (this._isPreamble || !this._inHeader) {
      if (buf)
        shouldWriteMore = this._part.push(buf);
      shouldWriteMore = this._part.push(data.slice(start, end));
      if (!shouldWriteMore)
        this._pause = true;
    } else if (!this._isPreamble && this._inHeader) {
      if (buf)
        this._hparser.push(buf);
      r = this._hparser.push(data.slice(start, end));
      if (!this._inHeader && r !== undefined && r < end)
        this._oninfo(false, data, start + r, end);
    }
  }
  if (isMatch) {
    this._hparser.reset();
    if (this._isPreamble)
      this._isPreamble = false;
    else {
      ++this._parts;
      this._part.on('end', function() {
        if (--self._parts === 0 && self._finished)
          self.emit('finish');
      });
    }
    this._part.push(null);
    this._part = undefined;
    this._ignoreData = false;
    this._justMatched = true;
    this._dashes = 0;
  }
};

module.exports = Dicer;
<commit_msg>Dicer: ignore errors when ignoring streams<commit_after>var WritableStream = require('stream').Writable
                     || require('readable-stream').Writable,
    inherits = require('util').inherits;

var StreamSearch = require('streamsearch');

var PartStream = require('./PartStream'),
    HeaderParser = require('./HeaderParser');

var DASH = 45,
    B_ONEDASH = new Buffer('-'),
    B_CRLF = new Buffer('\r\n'),
    EMPTY_FN = function() {};

function Dicer(cfg) {
  if (!(this instanceof Dicer))
    return new Dicer(cfg);
  WritableStream.call(this, cfg);

  if (!cfg || (!cfg.headerFirst && typeof cfg.boundary !== 'string'))
    throw new TypeError('Boundary required');

  if (typeof cfg.boundary === 'string')
    this.setBoundary(cfg.boundary);
  else
    this._bparser = undefined;

  this._headerFirst = cfg.headerFirst;

  var self = this;

  this._dashes = 0;
  this._parts = 0;
  this._finished = false;
  this._sawFinish = false;
  this._isPreamble = true;
  this._justMatched = false;
  this._firstWrite = true;
  this._inHeader = true;
  this._part = undefined;
  this._cb = undefined;
  this._ignoreData = false;
  this._partOpts = (typeof cfg.partHwm === 'number'
                    ? { highWaterMark: cfg.partHwm }
                    : {});
  this._pause = false;

  this._hparser = new HeaderParser(cfg);
  this._hparser.on('header', function(header) {
    self._inHeader = false;
    self._part.emit('header', header);
  });

}
inherits(Dicer, WritableStream);

Dicer.prototype.emit = function(ev) {
  if (ev === 'finish' && !this._sawFinish) {
    this._sawFinish = true;
    if (!this._finished) {
      var self = this;
      process.nextTick(function() {
        self.emit('error', new Error('Unexpected end of multipart data'));
        if (self._part && !self._ignoreData) {
          var type = (self._isPreamble ? 'Preamble' : 'Part');
          self._part.emit('error', new Error(type + ' terminated early due to unexpected end of multipart data'));
          self._part.push(null);
          process.nextTick(function() {
            self.emit('finish');
            self.reset();
          });
          return;
        }
        self.emit('finish');
        self.reset();
      });
    }
  } else
    WritableStream.prototype.emit.apply(this, arguments);
};

Dicer.prototype._write = function(data, encoding, cb) {
  if (this._headerFirst && this._isPreamble) {
    if (!this._part) {
      this._part = new PartStream(this._partOpts);
      if (this._events.preamble)
        this.emit('preamble', this._part);
      else {
        this._ignoreData = true;
        this._part.on('error', EMPTY_FN);
        // we must perform some kind of read on the stream even though we are
        // ignoring the data, otherwise node's Readable stream will not emit 'end'
        // after pushing null to the stream
        this._part.resume();
      }
    }
    var r = this._hparser.push(data);
    if (!this._inHeader && r !== undefined && r < data.length)
      data = data.slice(r);
    else
      return cb();
  }

  // allows for "easier" testing
  if (this._firstWrite) {
    this._bparser.push(B_CRLF);
    this._firstWrite = false;
  }

  this._bparser.push(data);

  if (this._pause)
    this._cb = cb;
  else
    cb();
};

Dicer.prototype.reset = function() {
  this._part = undefined;
  this._bparser = undefined;
  this._hparser = undefined;
};

Dicer.prototype.setBoundary = function(boundary) {
  var self = this;
  this._bparser = new StreamSearch('\r\n--' + boundary);
  this._bparser.on('info', function(isMatch, data, start, end) {
    self._oninfo(isMatch, data, start, end);
  });
};

Dicer.prototype._oninfo = function(isMatch, data, start, end) {
  var buf, self = this, i = 0, r, ev, shouldWriteMore = true;

  if (!this._part && this._justMatched && data) {
    while (this._dashes < 2 && (start + i) < end) {
      if (data[start + i] === DASH) {
        ++i;
        ++this._dashes;
      } else {
        if (this._dashes)
          buf = B_ONEDASH;
        this._dashes = 0;
        break;
      }
    }
    if (this._dashes === 2) {
      if ((start + i) < end && this._events.trailer)
        this.emit('trailer', data.slice(start + i, end));
      this.reset();
      this._finished = true;
    }
    if (this._dashes)
      return;
  }
  if (this._justMatched)
    this._justMatched = false;
  if (!this._part) {
    this._part = new PartStream(this._partOpts);
    this._part._read = function(n) {
      if (!self._pause)
        return;
      self._pause = false;
      if (self._cb) {
        var cb = self._cb;
        self._cb = undefined;
        cb();
      }
    };
    ev = this._isPreamble ? 'preamble' : 'part';
    if (this._events[ev])
      this.emit(ev, this._part);
    else {
      this._ignoreData = true;
      this._part.on('error', EMPTY_FN);
      // we must perform some kind of read on the stream even though we are
      // ignoring the data, otherwise node's Readable stream will not emit 'end'
      // after pushing null to the stream
      this._part.resume();
    }
    if (!this._isPreamble)
      this._inHeader = true;
  }
  if (data && start < end && !this._ignoreData) {
    if (this._isPreamble || !this._inHeader) {
      if (buf)
        shouldWriteMore = this._part.push(buf);
      shouldWriteMore = this._part.push(data.slice(start, end));
      if (!shouldWriteMore)
        this._pause = true;
    } else if (!this._isPreamble && this._inHeader) {
      if (buf)
        this._hparser.push(buf);
      r = this._hparser.push(data.slice(start, end));
      if (!this._inHeader && r !== undefined && r < end)
        this._oninfo(false, data, start + r, end);
    }
  }
  if (isMatch) {
    this._hparser.reset();
    if (this._isPreamble)
      this._isPreamble = false;
    else {
      ++this._parts;
      this._part.on('end', function() {
        if (--self._parts === 0 && self._finished)
          self.emit('finish');
      });
    }
    this._part.push(null);
    this._part = undefined;
    this._ignoreData = false;
    this._justMatched = true;
    this._dashes = 0;
  }
};

module.exports = Dicer;
<|endoftext|>


<commit_before>module.exports = function (config) {
	'use strict';

	config.set({
		basePath: '../../',
		frameworks: ['jasmine'],
		files: [
			'node_modules/angular/angular.js',
			'node_modules/angular-route/angular-route.js',
			'node_modules/angular-mocks/angular-mocks.js',
			'js/**/*.js',
			'test/unit/**/*.js'
		],
		autoWatch: true,
		singleRun: false,
		browsers: ['Chrome', 'Firefox'],

		reporters: ['coverage'],
		coverageReporter: {
            dir: 'test/coverage/',
            reporters: [
                {
                    type: 'lcovonly'
                },
                {
                    type: 'cobertura',subdir: '.', file: 'cobertura.xml'
                }
            ]
        },

reporters = ['dots', 'junit'];
junitReporter = {
  outputFile: 'test/coverage/test-results.xml'
},

	});
};

<commit_msg>Update karma.conf.js<commit_after>module.exports = function (config) {
	'use strict';

	config.set({
		basePath: '../../',
		frameworks: ['jasmine'],
		files: [
			'node_modules/angular/angular.js',
			'node_modules/angular-route/angular-route.js',
			'node_modules/angular-mocks/angular-mocks.js',
			'js/**/*.js',
			'test/unit/**/*.js'
		],
		autoWatch: true,
		singleRun: false,
		browsers: ['Chrome', 'Firefox'],

		reporters: ['coverage','junit'],
		coverageReporter: {
            dir: 'test/coverage/',
            reporters: [
                {
                    type: 'lcovonly'
                },
                {
                    type: 'cobertura',subdir: '.', file: 'cobertura.xml'
                }
                {
                    type: 'coveragereport', subdir'.',file: 'test-results.xml'
                }
            ]
        },

	});
};

<|endoftext|>


<commit_before>#!/usr/bin/env node
/**
 *
 *    Copyright (c) 2020 Silicon Labs
 *
 *    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 yargs = require('yargs')
const scriptUtil = require('./script-util.js')

let startTime = process.hrtime()

let arg = yargs
  .option('zcl', {
    desc: 'Specifies zcl metafile file to be used.',
    alias: 'z',
    type: 'string',
    demandOption: true,
  })
  .option('out', {
    desc: 'Output directory where the generated files will go.',
    alias: 'o',
    type: 'string',
    demandOption: true,
  })
  .option('generationTemplate', {
    desc: 'Specifies gen-template.json file to be used.',
    alias: 'g',
    type: 'string',
    demandOption: true,
  })
  .option('in', {
    desc: 'Input .zap file from which to read configuration.',
    alias: 'i',
    type: 'string',
    demandOption: false,
  })
  .option('stateDirectory', {
    desc: 'State directory',
    type: 'string',
    demandOption: false,
    default: '~/.zap',
  })
  .demandOption(
    ['zcl', 'out', 'generationTemplate'],
    'Please provide required options!'
  )
  .help()
  .wrap(null).argv

let ctx = {}

let cli = [
  'src-electron/main-process/electron-main.js',
  'generate',
  '--noUi',
  '--zcl',
  arg.zcl,
  '--generationTemplate',
  arg.generationTemplate,
  '--out',
  arg.out,
]
if (arg.in != null) {
  cli.push(arg.in)
}

scriptUtil
  .stampVersion()
  .then(() => scriptUtil.executeCmd(ctx, 'node', cli))
  .then(() => {
    let endTime = process.hrtime(startTime)
    console.log(
      `😎 All done: ${endTime[0]}s, ${Math.round(endTime[1] / 1000000)}ms.`
    )
    process.exit(0)
  })
  .catch((code) => {
    process.exit(code)
  })
<commit_msg>Reconstruct zap-generate back...<commit_after>#!/usr/bin/env node
/**
 *
 *    Copyright (c) 2020 Silicon Labs
 *
 *    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 yargs = require('yargs')
const scriptUtil = require('./script-util.js')

let startTime = process.hrtime()

let arg = yargs
  .option('zcl', {
    desc: 'Specifies zcl metafile file to be used.',
    alias: 'z',
    type: 'string',
    demandOption: true,
  })
  .option('out', {
    desc: 'Output directory where the generated files will go.',
    alias: 'o',
    type: 'string',
    demandOption: true,
  })
  .option('generationTemplate', {
    desc: 'Specifies gen-template.json file to be used.',
    alias: 'g',
    type: 'string',
    demandOption: true,
  })
  .option('in', {
    desc: 'Input .zap file from which to read configuration.',
    alias: 'i',
    type: 'string',
    demandOption: false,
  })
  .option('stateDirectory', {
    desc: 'State directory',
    type: 'string',
    demandOption: false,
    default: '~/.zap',
  })
  .demandOption(
    ['zcl', 'out', 'generationTemplate'],
    'Please provide required options!'
  )
  .help()
  .wrap(null).argv

let ctx = {}

let cli = [
  'src-electron/main-process/electron-main.js',
  'generate',
  '--noUi',
  '--noServer',
  '--stateDirectory',
  arg.stateDirectory,
  '--zcl',
  arg.zcl,
  '--generationTemplate',
  arg.generationTemplate,
  '--out',
  arg.out,
]
if (arg.in != null) {
  cli.push(arg.in)
}

scriptUtil
  .stampVersion()
  .then(() => scriptUtil.executeCmd(ctx, 'node', cli))
  .then(() => {
    let endTime = process.hrtime(startTime)
    console.log(
      `😎 All done: ${endTime[0]}s, ${Math.round(endTime[1] / 1000000)}ms.`
    )
    process.exit(0)
  })
  .catch((code) => {
    process.exit(code)
  })
<|endoftext|>