<commit_before>/*
 *  Manifest - organize a program of songs for an ensemble
 */

function Manifest(manifest) {

	var __Manifest = function(that, manifest) {
		that.manifest = manifest ;
		console.log('Creating manifest ', that.manifest) ;
	}(this, manifest) ;

	this.getBaseUrl = function(song) {

		if ( song.hasOwnProperty('baseUrl') && song.baseUrl !== '' ) {
			return song.baseUrl ;
		}
		if ( this.manifest.hasOwnProperty('baseUrl') && this.manifest.baseUrl !== '' ) {
			return this.manifest.baseUrl ;
		}
		return '' ;
	} ;

    this.displaySong = function(song) {

		var html = '' ;

		if ( song.hasOwnProperty('metadata') ) {
			html += this.displaySongMetadata(song) ;
		}

		if ( song.hasOwnProperty('scores') ) {
			html += this.displaySongScores(song) ;
		}

		if ( song.hasOwnProperty('parts') ) {
			html += this.displaySongParts(song) ;
		}

		if ( song.hasOwnProperty('recordings') ) {
			html += this.displaySongRecordings(song) ;
		}

		return html ;
	} ;

	this.displaySongMetadata = function(song) {

		var html = '\n' +
			"
\n
" + song.metadata.title + "
\n" +
			"
Composed by " + song.metadata.composer ;

		if ( song.metadata.hasOwnProperty('arranger') &&
			 song.metadata.arranger !== '' &&
			 song.metadata.composer !== song.metadata.arranger ) {
			html += ', Arranged by ' + song.metadata.arranger ;
		}

		html += "
\n
\n" ;

		return html ;
	} ;

	this.displaySongRecordings = function(song) {

		var name,
			recording,
			href,
			html = "
\n
Recordings
\n
\n",
			howManyRecordings ;

		for ( name in song.recordings ) {
	 		recording = song.recordings[name] ;
			href = song.recordings[name] ;
			if ( href !== '' ) {
				html += '
' + name + "
\n" ;
				howManyRecordings += 1 ;
			}
		};

		if ( howManyRecordings == 0 ) {
			html = '' ;
		} else {
			html += "
\n
\n" ;
		}

		return html ;
	} ;

	this.displaySongScores = function(song) {

		var name,
			score,
			href,
			html = "
\n
Scores
\n
\n" ;

		for ( name in song.scores ) {
	 		score = song.scores[name] ;
			href = this.getBaseUrl(song) +
				song.fileLocation + '/pdf/' +
				song.filePrefix + score.fileSuffix + '.pdf' ;
			html += '
' + name + "
\n" ;
		}

		html += "
\n
\n" ;

		return html ;
	} ;

	this.displaySongParts = function(song) {

		var name,
			href,
			html = "
\n
Parts
\n
\n" ;

		for ( name in song.parts ) {
			part = song.parts[name] ;
			href = this.getBaseUrl(song) +
				song.fileLocation + '/pdf/' +
				song.filePrefix + part.fileSuffix + '.pdf' ;
			html += '
' + name + "
\n" ;
		};
		html += "
\n
\n" ;

		return html ;
	} ;

	this.displayProgramSummary = function() {

		var programIndex, number, songIndex, song, baseUrl,
			html = "
\n
Program
\n
\n",
			songHtml = ''  ;

		console.log
		for ( programIndex = 0 ; programIndex < this.manifest.programOrder.length ; programIndex++ ) {

			number = this.manifest.programOrder[programIndex] ;
			songIndex = this.manifest.program[number] ;
			song = this.manifest.songs[songIndex] ;
			html += '
' + song.metadata.title + "
\n";
		}
		html += "
\n
\n" ;

		return html ;
	} ;

	this.displayProgram = function() {

		var programIndex, number, songIndex, song, baseUrl,
			html = "
\n",
			songHtml = ''  ;

		for ( programIndex = 0 ; programIndex < this.manifest.programOrder.length ; programIndex++ ) {

			number = this.manifest.programOrder[programIndex] ;
			songIndex = this.manifest.program[number] ;
			song = this.manifest.songs[songIndex] ;
			html += this.displaySong(song) ;
		}
		html += "
\n" ;

		return html ;
	} ;

	this.displayPartsInBook = function(manifest, chair, partsLists) {

		var songId,
			song,
			partsList,
			partIndex,
			part,
			href,
			html = "
\n
" + chair + "
\n\n
\n" ;

		Object.keys(partsLists).forEach(function(songId) {

	    	song = this.manifest.manifest.songs[songId] ;
			partsList = partsLists[songId] ;
			html += '
' + song.metadata.title ;
			for ( partIndex = 0 ; partIndex < partsList.length ; partIndex++ ) {
				part = partsList[partIndex] ;
				href = manifest.getBaseUrl(song) + song.filePrefix + song.parts[part].fileSuffix + '.pdf' ;
				html += ' ' + part + '' ;
				if ( partIndex+1 < partsList.length ) {
					html += ',' ;
				}
			}
			html += "
\n" ;
		});

		html += "
\n
\n" ;

		return html ;
	} ;

	this.displayBookSummary= function() {

		var key, name
			books = this.manifest.partsInBooks,
			html = "
\n
\n" ;

		for ( key in books ) {

			if ( books.hasOwnProperty(key) ) {
				name = books[key] ;
				html += '
' + name + "
\n";
			}
		}
		html += "
\n
\n" ;

		return html ;
	} ;

	this.displayPartsInBooks = function() {

		var html, key,
			books = this.manifest.partsInBooks ;

		for ( key in books ) {

			if ( books.hasOwnProperty(key) ) {

				html += this.displayPartsInBook( this, key, books[key] ) ;

			}
		}

		return html ;
	} ;

	this.displayManifest = function() {

		var html = '' ;
		html += this.displayProgramSummary() ;
		html += this.displayBookSummary() ;
		html += this.displayProgram() ;
		html += this.displayPartsInBooks() ;

		return html ;
	}

	this.placeManifestOnReady = function(content) {

		var manifest = this ;

		document.addEventListener(

			'DOMContentLoaded',

				function(){
					var container = document.getElementById(manifest.selector) ;
					if ( container !== undefined  &&  typeof container === 'object' ) {
						container.innerHTML = content ;
						return ;
					}
					console.log('Could not find elmement with id ' + manifest.selector + 'so addding child.') ;
					document.getElementsByTagName('BODY')[0].innerHTML = content ;
				},

			false
		);
	}

} ;

<commit_msg>last version of example with inline data<commit_after>/*
 *  Manifest - organize a program of songs for an ensemble
 */

function Manifest(manifest) {

	var __Manifest = function(that, manifest) {
		that.manifest = manifest ;
		console.log('Creating manifest ', that.manifest) ;
	}(this, manifest) ;

	this.getBaseUrl = function(song) {

		if ( song.hasOwnProperty('baseUrl') && song.baseUrl !== '' ) {
			return song.baseUrl ;
		}
		if ( this.manifest.hasOwnProperty('baseUrl') && this.manifest.baseUrl !== '' ) {
			return this.manifest.baseUrl ;
		}
		return '' ;
	} ;

    this.displaySong = function(song) {

		var html = '' ;

		if ( song.hasOwnProperty('metadata') ) {
			html += this.displaySongMetadata(song) ;
		}

		if ( song.hasOwnProperty('scores') ) {
			html += this.displaySongScores(song) ;
		}

		if ( song.hasOwnProperty('parts') ) {
			html += this.displaySongParts(song) ;
		}

		if ( song.hasOwnProperty('recordings') ) {
			html += this.displaySongRecordings(song) ;
		}

		return html ;
	} ;

	this.displaySongMetadata = function(song) {

		var html = '\n' +
			"
\n
" + song.metadata.title + "
\n" +
			"
Composed by " + song.metadata.composer ;

		if ( song.metadata.hasOwnProperty('arranger') &&
			 song.metadata.arranger !== '' &&
			 song.metadata.composer !== song.metadata.arranger ) {
			html += ', Arranged by ' + song.metadata.arranger ;
		}

		html += "
\n
\n" ;

		return html ;
	} ;

	this.displaySongRecordings = function(song) {

		var name,
			recording,
			href,
			html = "
\n
Recordings
\n
\n",
			howManyRecordings ;

		for ( name in song.recordings ) {
	 		recording = song.recordings[name] ;
			href = song.recordings[name] ;
			if ( href !== '' ) {
				html += '
' + name + "
\n" ;
				howManyRecordings += 1 ;
			}
		};

		if ( howManyRecordings == 0 ) {
			html = '' ;
		} else {
			html += "
\n
\n" ;
		}

		return html ;
	} ;

	this.displaySongScores = function(song) {

		var name,
			score,
			href,
			html = "
\n
Scores
\n
\n" ;

		for ( name in song.scores ) {
	 		score = song.scores[name] ;
			href = this.getBaseUrl(song) +
				song.fileLocation + '/pdf/' +
				song.filePrefix + score.fileSuffix + '.pdf' ;
			html += '
' + name + "
\n" ;
		}

		html += "
\n
\n" ;

		return html ;
	} ;

	this.displaySongParts = function(song) {

		var name,
			href,
			html = "
\n
Parts
\n
\n" ;

		for ( name in song.parts ) {
			part = song.parts[name] ;
			href = this.getBaseUrl(song) +
				song.fileLocation + '/pdf/' +
				song.filePrefix + part.fileSuffix + '.pdf' ;
			html += '
' + name + "
\n" ;
		}
		html += "
\n
\n" ;

		return html ;
	} ;

	this.displayProgramSummary = function() {

		var programIndex, number, songIndex, song, baseUrl,
			html = "
\n
Program
\n
\n",
			songHtml = ''  ;

		console.log
		for ( programIndex = 0 ; programIndex < this.manifest.programOrder.length ; programIndex++ ) {

			number = this.manifest.programOrder[programIndex] ;
			songIndex = this.manifest.program[number] ;
			song = this.manifest.songs[songIndex] ;
			html += '
' + song.metadata.title + "
\n";
		}
		html += "
\n
\n" ;

		return html ;
	} ;

	this.displayProgram = function() {

		var programIndex, number, songIndex, song, baseUrl,
			html = "
\n",
			songHtml = ''  ;

		for ( programIndex = 0 ; programIndex < this.manifest.programOrder.length ; programIndex++ ) {

			number = this.manifest.programOrder[programIndex] ;
			songIndex = this.manifest.program[number] ;
			song = this.manifest.songs[songIndex] ;
			html += this.displaySong(song) ;
		}
		html += "
\n" ;

		return html ;
	} ;

	this.displayPartsInBook = function(manifest, chair, partsLists) {

		var songId,
			song,
			partsList,
			partIndex,
			part,
			href,
			html = "
\n
" + chair + "
\n    " ;

		Object.keys(partsLists).forEach(function(songId) {

	    	song = this.manifest.manifest.songs[songId] ;
			partsList = partsLists[songId] ;
			html += '
' + song.metadata.title ;
			for ( partIndex = 0 ; partIndex < partsList.length ; partIndex++ ) {
				part = partsList[partIndex] ;
				href = manifest.getBaseUrl(song) + song.filePrefix + song.parts[part].fileSuffix + '.pdf' ;
				html += ' ' + part + '' ;
				if ( partIndex+1 < partsList.length ) {
					html += ',' ;
				}
			}
		});

		html += "
\n" ;

		return html ;
	} ;

	this.displayBookSummary= function() {

		var key, name
			books = this.manifest.partsInBooks,
			html = "
\n
\n" ;

		for ( key in books ) {

			if ( books.hasOwnProperty(key) ) {
				name = books[key] ;
				html += '
' + name + "
\n";
			}
		}
		html += "
\n
\n" ;

		return html ;
	} ;

	this.displayPartsInBooks = function() {

		var html, key,
			books = this.manifest.partsInBooks ;

		for ( key in books ) {

			if ( books.hasOwnProperty(key) ) {

				html += this.displayPartsInBook( this, key, books[key] ) ;

			}
		}

		return html ;
	} ;

	this.displayManifest = function() {

		var html = '' ;
		html += this.displayProgramSummary() ;
		html += this.displayBookSummary() ;
		html += this.displayProgram() ;
		html += this.displayPartsInBooks() ;

		return html ;
	}

	this.placeManifestOnReady = function(content) {

		var manifest = this ;

		document.addEventListener(

			'DOMContentLoaded',

				function(){
					var container = document.getElementById(manifest.selector) ;
					if ( container !== undefined  &&  typeof container === 'object' ) {
						container.innerHTML = content ;
						return ;
					}
					console.log('Could not find elmement with id ' + manifest.selector + 'so addding child.') ;
					document.getElementsByTagName('BODY')[0].innerHTML = content ;
				},

			false
		);
	}

} ;

<|endoftext|>


<commit_before>// this class is not really related to a sampleToc but can be used for any TOC

import API from 'src/util/api';
import Versioning from 'src/util/versioning';

let defaultOptions = {
  group: 'all',
  varName: 'sampleToc',
  viewName: 'sample_toc',
  filter: (entry) => !entry.value.hidden,
  sort: (a, b) => {
    if (a.value.modified && a.value.modified > b.value.modified) {
      return -1;
    } else if (
      a.value.modificationDate &&
      a.value.modificationDate > b.value.modificationDate
    ) {
      return -1;
    } else if (a.value.modified && a.value.modified < b.value.modified) {
      return 1;
    } else if (
      a.value.modificationDate &&
      a.value.modificationDate < b.value.modificationDate
    ) {
      return 1;
    } else {
      return 0;
    }
  }
};

class Toc {
  /**
   * Create an object managing the Toc
   * @param {object} [options={}]
   * @param {object} [roc=undefined]
   * @param {string} [options.group='mine'] Group to retrieve products. mine, all of a specific group name
   * @param {string} [options.varName='sampleToc']
   * @param {string} [options.viewName='sample_toc']
   * @param {function} [options.sort] Callback, by default sort by reverse date
   * @param {function} [options.filter] Callback to filter the result
   */
  constructor(roc, options = {}) {
    this.roc = roc;
    this.options = Object.assign({}, defaultOptions, options);
  }

  setFilter(filter) {
    this.options.filter = filter;
    return this.refresh();
  }

  /**
   * Retrieve the toc and put the result in the specified variable
   *
   */
  refresh(options = {}) {
    let { group, sort, filter, viewName } = Object.assign(
      {},
      this.options,
      options
    );
    let mine = 0;
    let groups = '';
    group = String(group);
    if (group === 'mine') {
      mine = 1;
    } else if (group !== 'all') {
      groups = group;
    }
    console.log('refresh', { groups, mine, filter });
    return this.roc
      .query(viewName, {
        groups,
        mine,
        sort,
        filter,
        varName: this.options.varName
      })
      .then((entries) => {
        if (this.options.callback) {
          entries.forEach(this.options.callback);
        }
        return entries;
      });
  }

  /**
   * Retrieve the allowed groups for the logged in user and create 'groupForm'
   * variable and 'groupFormSchema' (for onde module). It will keep in a cookie
   * the last selected group. Calling this method should reload automatically
   * @param {object} [options={}]
   * @param {string} [varName='groupForm'] contains the name of the variable containing the form value
   * @param {string} [schemaVarName='groupFormSchema'] contains the name of the variable containing the form schema
   * @param {string} [cookieName='eln-default-sample-group''] cookie name containing the last selected group
   * @param {string} [filter] filter applied on first refresh
   * @param {string} [autoRefresh=true] refresh least after initialization
   * @param {boolean} [listAllGroups=true] select from any group, even if not the a member
   * @return {string} the form to select group}
   */
  async initializeGroupForm(options = {}) {
    const {
      schemaVarName = 'groupFormSchema',
      varName = 'groupForm',
      cookieName = 'eln-default-sample-group',
      filter,
      autoRefresh = true,
      listAllGroups = false
    } = options;

    let groups = [];
    if (listAllGroups) {
      groups = (await this.roc.getGroupsInfo()).map((g) => g.name);
    } else {
      groups = (await this.roc.getGroupsMembership()).map((g) => g.name);
    }

    var possibleGroups = ['all', 'mine'].concat(groups);
    var defaultGroup = localStorage.getItem(cookieName);
    if (possibleGroups.indexOf(defaultGroup) === -1) {
      defaultGroup = 'all';
    }
    var schema = {
      type: 'object',
      properties: {
        group: {
          type: 'string',
          enum: possibleGroups,
          default: defaultGroup,
          required: true
        }
      }
    };
    API.createData(schemaVarName, schema);

    let groupForm = await API.createData(varName, { group: defaultGroup });

    this.options.group = groupForm.group;
    if (autoRefresh) {
      await this.refresh(filter);
    }
    let mainData = Versioning.getData();
    mainData.onChange((evt) => {
      if (evt.jpath[0] === varName) {
        localStorage.setItem(cookieName, groupForm.group);
        this.options.group = String(groupForm.group);
        this.refresh();
      }
    });

    return groupForm;
  }
}

module.exports = Toc;
<commit_msg>fix typo<commit_after>// this class is not really related to a sampleToc but can be used for any TOC

import API from 'src/util/api';
import Versioning from 'src/util/versioning';

let defaultOptions = {
  group: 'all',
  varName: 'sampleToc',
  viewName: 'sample_toc',
  filter: (entry) => !entry.value.hidden,
  sort: (a, b) => {
    if (a.value.modified && a.value.modified > b.value.modified) {
      return -1;
    } else if (
      a.value.modificationDate &&
      a.value.modificationDate > b.value.modificationDate
    ) {
      return -1;
    } else if (a.value.modified && a.value.modified < b.value.modified) {
      return 1;
    } else if (
      a.value.modificationDate &&
      a.value.modificationDate < b.value.modificationDate
    ) {
      return 1;
    } else {
      return 0;
    }
  }
};

class Toc {
  /**
   * Create an object managing the Toc
   * @param {object} [options={}]
   * @param {object} [roc=undefined]
   * @param {string} [options.group='mine'] Group to retrieve products. mine, all of a specific group name
   * @param {string} [options.varName='sampleToc']
   * @param {string} [options.viewName='sample_toc']
   * @param {function} [options.sort] Callback, by default sort by reverse date
   * @param {function} [options.filter] Callback to filter the result
   */
  constructor(roc, options = {}) {
    this.roc = roc;
    this.options = Object.assign({}, defaultOptions, options);
  }

  setFilter(filter) {
    this.options.filter = filter;
    return this.refresh();
  }

  /**
   * Retrieve the toc and put the result in the specified variable
   *
   */
  refresh(options = {}) {
    let { group, sort, filter, viewName } = Object.assign(
      {},
      this.options,
      options
    );
    let mine = 0;
    let groups = '';
    group = String(group);
    if (group === 'mine') {
      mine = 1;
    } else if (group !== 'all') {
      groups = group;
    }
    console.log('refresh', { groups, mine, filter });
    return this.roc
      .query(viewName, {
        groups,
        mine,
        sort,
        filter,
        varName: this.options.varName
      })
      .then((entries) => {
        if (this.options.callback) {
          entries.forEach(this.options.callback);
        }
        return entries;
      });
  }

  /**
   * Retrieve the allowed groups for the logged in user and create 'groupForm'
   * variable and 'groupFormSchema' (for onde module). It will keep in a cookie
   * the last selected group. Calling this method should reload automatically
   * @param {object} [options={}]
   * @param {string} [varName='groupForm'] contains the name of the variable containing the form value
   * @param {string} [schemaVarName='groupFormSchema'] contains the name of the variable containing the form schema
   * @param {string} [cookieName='eln-default-sample-group''] cookie name containing the last selected group
   * @param {string} [filter] filter applied on first refresh
   * @param {string} [autoRefresh=true] refresh least after initialization
   * @param {boolean} [listAllGroups=true] select from any group, even if not the a member
   * @return {string} the form to select group}
   */
  async initializeGroupForm(options = {}) {
    const {
      schemaVarName = 'groupFormSchema',
      varName = 'groupForm',
      cookieName = 'eln-default-sample-group',
      filter,
      autoRefresh = true,
      listAllGroups = false
    } = options;

    let groups = [];
    if (listAllGroups) {
      groups = (await this.roc.getGroupsInfo()).map((g) => g.name);
    } else {
      groups = (await this.roc.getGroupMembership()).map((g) => g.name);
    }

    var possibleGroups = ['all', 'mine'].concat(groups);
    var defaultGroup = localStorage.getItem(cookieName);
    if (possibleGroups.indexOf(defaultGroup) === -1) {
      defaultGroup = 'all';
    }
    var schema = {
      type: 'object',
      properties: {
        group: {
          type: 'string',
          enum: possibleGroups,
          default: defaultGroup,
          required: true
        }
      }
    };
    API.createData(schemaVarName, schema);

    let groupForm = await API.createData(varName, { group: defaultGroup });

    this.options.group = groupForm.group;
    if (autoRefresh) {
      await this.refresh(filter);
    }
    let mainData = Versioning.getData();
    mainData.onChange((evt) => {
      if (evt.jpath[0] === varName) {
        localStorage.setItem(cookieName, groupForm.group);
        this.options.group = String(groupForm.group);
        this.refresh();
      }
    });

    return groupForm;
  }
}

module.exports = Toc;
<|endoftext|>


<commit_before>import {Apis} from "bitsharesjs-ws";
/** This file centralized customization and branding efforts throughout the whole wallet and is meant to facilitate
 *  the process.
 *
 *  @author Stefan Schiessl <stefan.schiessl@blockchainprojectsbv.com>
 */

/**
 * Determine if we are running on testnet or mainnet
 * @private
 */
function _isTestnet() {
    const testnet =
        "39f5e2ede1f8bc1a3a54a7914414e3779e33193f1f5693510e73cb7a87617447"; // just for the record
    const mainnet =
        "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8";

    // treat every other chain as testnet
    return Apis.instance().chain_id !== mainnet;
}

/**
 * Wallet name that is used throughout the UI and also in translations
 * @returns {string}
 */
export function getWalletName() {
    return "BitShares";
}

/**
 * URL of this wallet
 * @returns {string}
 */
export function getWalletURL() {
    return "https://wallet.bitshares.org";
}

/**
 * Returns faucet information
 *
 * @returns {{url: string, show: boolean}}
 */
export function getFaucet() {
    return {
        url: "https://faucet.bitshares.eu/onboarding", // 2017-12-infrastructure worker proposal
        show: true,
        editable: false,
        referrer: "onboarding.bitshares.foundation"
    };
}

export function getTestFaucet() {
    // fixme should be solved by introducing _isTestnet into getFaucet and fixing the mess in the Settings when fetching faucet address
    return {
        url: "https://faucet.testnet.bitshares.eu", // operated as a contribution by BitShares EU
        show: true,
        editable: false
    };
}

/**
 * Logo that is used throughout the UI
 * @returns {*}
 */
export function getLogo() {
    return require("assets/logo-ico-blue.png");
}

/**
 * Default set theme for the UI
 * @returns {string}
 */
export function getDefaultTheme() {
    // possible ["darkTheme", "lightTheme", "midnightTheme"]
    return "darkTheme";
}

/**
 * Default login method. Either "password" (for cloud login mode) or "wallet" (for local wallet mode)
 * @returns {string}
 */
export function getDefaultLogin() {
    // possible: one of "password", "wallet"
    return "password";
}

/**
 * Default units used by the UI
 *
 * @returns {[string,string,string,string,string,string]}
 */
export function getUnits() {
    if (_isTestnet()) {
        return ["TEST"];
    }
    return ["BTS", "USD", "CNY", "BTC", "EUR", "GBP"];
}

export function getDefaultMarket() {
    if (_isTestnet()) {
        return "USD_TEST";
    }
    return "USD_BTS";
}

/**
 * These are the highlighted bases in "My Markets" of the exchange
 *
 * @returns {[string]}
 */
export function getMyMarketsBases() {
    if (_isTestnet()) {
        return ["TEST"];
    }
    return ["BTS", "BTC", "ETH", "USD", "CNY"];
}

/**
 * These are the default quotes that are shown after selecting a base
 *
 * @returns {[string]}
 */
export function getMyMarketsQuotes() {
    if (_isTestnet()) {
        return ["TEST"];
    }
    let tokens = {
        nativeTokens: [
            "BTC",
            "BTS",
            "CNY",
            "EUR",
            "GOLD",
            "KRW",
            "RUBLE",
            "SILVER",
            "USD"
        ],
        gdexTokens: [
            "GDEX.BTC",
            "GDEX.BTO",
            "GDEX.EOS",
            "GDEX.ETH",
            "GDEX.BTM",
            "GDEX.NEO",
            "GDEX.GAS",
            "GDEX.QTUM",
            "GDEX.BKBT",
            "GDEX.GXC",
            "GDEX.HPB",
            "GDEX.SEER",
            "GDEX.FOTA",
            "GDEX.JRC",
            "GDEX.EOSDAC",
            "GDEX.MTS",
            "GDEX.GUSD",
            "GDEX.IQ",
            "GDEX.NULS",
            "GDEX.USDT"
        ],
        openledgerTokens: [
            "OBITS"
        ],
        rudexTokens: [
            "PPY",
            "RUDEX.BTC",
            "RUDEX.ETH",
            "RUDEX.USDT",
            "RUDEX.EOS",
            "RUDEX.GOLOS",
            "RUDEX.GBG",
            "RUDEX.STEEM",
            "RUDEX.SBD",
            "RUDEX.KRM",
            "RUDEX.WLS",
            "RUDEX.SMOKE",
            "RUDEX.GRC"
        ],
        xbtsxTokens: [
            "XBTSX.STH",
            "XBTSX.POST",
            "XBTSX.DOGE",
            "XBTSX.BTC",
            "XBTSX.BTG",
            "XBTSX.BCH",
            "XBTSX.LTC",
            "XBTSX.DASH",
            "XBTSX.NVC",
            "XBTSX.UNI",
            "XBTSX.NMC",
            "XBTSX.WAVES",
            "XBTSX.COF",
            "XBTSX.MDL",
            "XBTSX.ETH",
            "XBTSX.EXR"
        ],
        otherTokens: [
        ]
    };

    let allTokens = [];
    for (let type in tokens) {
        allTokens = allTokens.concat(tokens[type]);
    }
    return allTokens;
}

/**
 * The featured markets displayed on the landing page of the UI
 *
 * @returns {list of string tuples}
 */
export function getFeaturedMarkets(quotes = []) {
    if (_isTestnet()) {
        return [["USD", "TEST"]];
    }
    return [
        ["USD", "BTS"],
        ["USD", "GOLD"],
        ["USD", "GDEX.BTC"],
        ["USD", "GDEX.ETH"],
        ["USD", "GDEX.EOS"],
        ["USD", "GDEX.BTO"],
        ["USD", "RUDEX.GOLOS"],
        ["USD", "RUDEX.STEEM"],
        ["USD", "RUDEX.EOS"],
        ["USD", "RUDEX.BTC"],
        ["USD", "RUDEX.ETH"],
        ["USD", "RUDEX.USDT"],
        ["USD", "RUDEX.WLS"],
        ["USD", "RUDEX.SMOKE"],
        ["CNY", "BTS"],
        ["CNY", "USD"],
        ["CNY", "GDEX.BTC"],
        ["CNY", "GDEX.ETH"],
        ["CNY", "GDEX.EOS"],
        ["CNY", "GDEX.BTO"],
        ["CNY", "GDEX.BTM"],
        ["CNY", "GDEX.SEER"],
        ["CNY", "GDEX.BKBT"],
        ["CNY", "GDEX.USDT"],
        ["CNY", "GDEX.GXC"],
        ["CNY", "RUDEX.GOLOS"],
        ["CNY", "RUDEX.STEEM"],
        ["CNY", "RUDEX.EOS"],
        ["CNY", "RUDEX.BTC"],
        ["CNY", "RUDEX.ETH"],
        ["CNY", "RUDEX.USDT"],
        ["CNY", "RUDEX.WLS"],
        ["CNY", "RUDEX.SMOKE"],
        ["BTS", "PPY"],
        ["BTS", "OBITS"],
        ["BTS", "RUBLE"],
        ["BTS", "SILVER"],
        ["BTS", "GOLD"],
        ["BTS", "GDEX.BTC"],
        ["BTS", "GDEX.ETH"],
        ["BTS", "GDEX.EOS"],
        ["BTS", "GDEX.BTO"],
        ["BTS", "GDEX.USDT"],
        ["RUDEX.USDT", "RUDEX.BTC"],
        ["RUDEX.USDT", "RUDEX.ETH"],
        ["RUDEX.USDT", "RUDEX.EOS"],
        ["RUDEX.USDT", "PPY"],
        ["RUDEX.USDT", "RUBLE"],
        ["RUDEX.BTC", "RUDEX.ETH"],
        ["RUDEX.BTC", "RUDEX.EOS"],
        ["RUDEX.BTC", "RUDEX.STEEM"],
        ["RUDEX.BTC", "RUDEX.GOLOS"],
        ["RUDEX.BTC", "RUDEX.WLS"],
        ["RUDEX.BTC", "PPY"],
        ["RUBLE", "RUDEX.BTC"],
        ["RUBLE", "RUDEX.ETH"],
        ["RUBLE", "RUDEX.USDT"],
        ["RUBLE", "RUDEX.GOLOS"],
        ["BTS", "RUDEX.GOLOS"],
        ["BTS", "RUDEX.STEEM"],
        ["BTS", "RUDEX.EOS"],
        ["BTS", "RUDEX.BTC"],
        ["BTS", "RUDEX.ETH"],
        ["BTS", "RUDEX.USDT"],
        ["BTS", "RUDEX.WLS"],
        ["BTS", "RUDEX.SMOKE"],
        ["BTS", "XBTSX.STH"],
        ["BTS", "XBTSX.WAVES"]
    ].filter(a => {
        if (!quotes.length) return true;
        return quotes.indexOf(a[0]) !== -1;
    });
}

/**
 * Recognized namespaces of assets
 *
 * @returns {[string,string,string,string,string,string,string]}
 */
export function getAssetNamespaces() {
    if (_isTestnet()) {
        return [];
    }
    return ["OPEN.", "RUDEX.", "GDEX.", "XBTSX.", "CITADEL."];
}

/**
 * These namespaces will be hidden to the user, this may include "bit" for BitAssets
 * @returns {[string,string]}
 */
export function getAssetHideNamespaces() {
    // e..g "OPEN.", "bit"
    return [];
}

/**
 * Allowed gateways that the user will be able to choose from in Deposit Withdraw modal
 * @param gateway
 * @returns {boolean}
 */
export function allowedGateway(gateway) {
    const allowedGateways = [
        "TRADE",
        "OPEN",
        "RUDEX",
        "GDEX",
        "XBTSX",
        "CITADEL"
    ];
    if (!gateway) {
        // answers the question: are any allowed?
        return allowedGateways.length > 0;
    }
    return allowedGateways.indexOf(gateway) >= 0;
}

export function getSupportedLanguages() {
    // not yet supported
}

export function getAllowedLogins() {
    // possible: list containing any combination of ["password", "wallet"]
    return ["password", "wallet"];
}

export function getConfigurationAsset() {
    let assetSymbol = null;
    if (_isTestnet()) {
        assetSymbol = "NOTIFICATIONS";
    } else {
        assetSymbol = "TEST";
    }
    // explanation will be parsed out of the asset description (via split)
    return {
        symbol: assetSymbol,
        explanation:
            "This asset is used for decentralized configuration of the BitShares UI placed under bitshares.org."
    };
}
<commit_msg>restore some assets, remove gdex delisting<commit_after>import {Apis} from "bitsharesjs-ws";
/** This file centralized customization and branding efforts throughout the whole wallet and is meant to facilitate
 *  the process.
 *
 *  @author Stefan Schiessl <stefan.schiessl@blockchainprojectsbv.com>
 */

/**
 * Determine if we are running on testnet or mainnet
 * @private
 */
function _isTestnet() {
    const testnet =
        "39f5e2ede1f8bc1a3a54a7914414e3779e33193f1f5693510e73cb7a87617447"; // just for the record
    const mainnet =
        "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8";

    // treat every other chain as testnet
    return Apis.instance().chain_id !== mainnet;
}

/**
 * Wallet name that is used throughout the UI and also in translations
 * @returns {string}
 */
export function getWalletName() {
    return "BitShares";
}

/**
 * URL of this wallet
 * @returns {string}
 */
export function getWalletURL() {
    return "https://wallet.bitshares.org";
}

/**
 * Returns faucet information
 *
 * @returns {{url: string, show: boolean}}
 */
export function getFaucet() {
    return {
        url: "https://faucet.bitshares.eu/onboarding", // 2017-12-infrastructure worker proposal
        show: true,
        editable: false,
        referrer: "onboarding.bitshares.foundation"
    };
}

export function getTestFaucet() {
    // fixme should be solved by introducing _isTestnet into getFaucet and fixing the mess in the Settings when fetching faucet address
    return {
        url: "https://faucet.testnet.bitshares.eu", // operated as a contribution by BitShares EU
        show: true,
        editable: false
    };
}

/**
 * Logo that is used throughout the UI
 * @returns {*}
 */
export function getLogo() {
    return require("assets/logo-ico-blue.png");
}

/**
 * Default set theme for the UI
 * @returns {string}
 */
export function getDefaultTheme() {
    // possible ["darkTheme", "lightTheme", "midnightTheme"]
    return "darkTheme";
}

/**
 * Default login method. Either "password" (for cloud login mode) or "wallet" (for local wallet mode)
 * @returns {string}
 */
export function getDefaultLogin() {
    // possible: one of "password", "wallet"
    return "password";
}

/**
 * Default units used by the UI
 *
 * @returns {[string,string,string,string,string,string]}
 */
export function getUnits() {
    if (_isTestnet()) {
        return ["TEST"];
    }
    return ["BTS", "USD", "CNY", "BTC", "EUR", "GBP"];
}

export function getDefaultMarket() {
    if (_isTestnet()) {
        return "USD_TEST";
    }
    return "USD_BTS";
}

/**
 * These are the highlighted bases in "My Markets" of the exchange
 *
 * @returns {[string]}
 */
export function getMyMarketsBases() {
    if (_isTestnet()) {
        return ["TEST"];
    }
    return ["BTS", "BTC", "ETH", "USD", "CNY"];
}

/**
 * These are the default quotes that are shown after selecting a base
 *
 * @returns {[string]}
 */
export function getMyMarketsQuotes() {
    if (_isTestnet()) {
        return ["TEST"];
    }
    let tokens = {
        nativeTokens: [
            "BTC",
            "BTS",
            "CNY",
            "EUR",
            "GOLD",
            "KRW",
            "RUBLE",
            "SILVER",
            "USD"
        ],
        gdexTokens: [
            "GDEX.BTC",
            "GDEX.BTO",
            "GDEX.EOS",
            "GDEX.ETH",
            "GDEX.BKBT",
            "GDEX.GXC",
            "GDEX.SEER",
            "GDEX.FOTA",
            "GDEX.JRC",
            "GDEX.EOSDAC",
            "GDEX.MTS",
            "GDEX.GUSD",
            "GDEX.IQ",
            "GDEX.NULS",
            "GDEX.USDT"
        ],
        openledgerTokens: [
            "OBITS"
        ],
        rudexTokens: [
            "PPY",
            "RUDEX.BTC",
            "RUDEX.ETH",
            "RUDEX.USDT",
            "RUDEX.EOS",
            "RUDEX.GOLOS",
            "RUDEX.GBG",
            "RUDEX.STEEM",
            "RUDEX.SBD",
            "RUDEX.KRM",
            "RUDEX.WLS",
            "RUDEX.SMOKE",
            "RUDEX.GRC"
        ],
        xbtsxTokens: [
            "XBTSX.STH",
            "XBTSX.POST",
            "XBTSX.DOGE",
            "XBTSX.BTC",
            "XBTSX.BTG",
            "XBTSX.BCH",
            "XBTSX.LTC",
            "XBTSX.DASH",
            "XBTSX.NVC",
            "XBTSX.UNI",
            "XBTSX.NMC",
            "XBTSX.WAVES",
            "XBTSX.COF",
            "XBTSX.MDL",
            "XBTSX.ETH",
            "XBTSX.EXR"
        ],
        otherTokens: [
            "CVCOIN",
            "HERO",
            "OCT",
            "HERTZ",
            "YOYOW"
        ]
    };

    let allTokens = [];
    for (let type in tokens) {
        allTokens = allTokens.concat(tokens[type]);
    }
    return allTokens;
}

/**
 * The featured markets displayed on the landing page of the UI
 *
 * @returns {list of string tuples}
 */
export function getFeaturedMarkets(quotes = []) {
    if (_isTestnet()) {
        return [["USD", "TEST"]];
    }
    return [
        ["USD", "BTS"],
        ["USD", "GOLD"],
        ["USD", "HERO"],
        ["USD", "GDEX.BTC"],
        ["USD", "GDEX.ETH"],
        ["USD", "GDEX.EOS"],
        ["USD", "GDEX.BTO"],
        ["USD", "RUDEX.GOLOS"],
        ["USD", "RUDEX.STEEM"],
        ["USD", "RUDEX.EOS"],
        ["USD", "RUDEX.BTC"],
        ["USD", "RUDEX.ETH"],
        ["USD", "RUDEX.USDT"],
        ["USD", "RUDEX.WLS"],
        ["USD", "RUDEX.SMOKE"],
        ["CNY", "BTS"],
        ["CNY", "USD"],
        ["CNY", "YOYOW"],
        ["CNY", "OCT"],
        ["CNY", "GDEX.BTC"],
        ["CNY", "GDEX.ETH"],
        ["CNY", "GDEX.EOS"],
        ["CNY", "GDEX.BTO"],
        ["CNY", "GDEX.SEER"],
        ["CNY", "GDEX.BKBT"],
        ["CNY", "GDEX.USDT"],
        ["CNY", "GDEX.GXC"],
        ["CNY", "RUDEX.GOLOS"],
        ["CNY", "RUDEX.STEEM"],
        ["CNY", "RUDEX.EOS"],
        ["CNY", "RUDEX.BTC"],
        ["CNY", "RUDEX.ETH"],
        ["CNY", "RUDEX.USDT"],
        ["CNY", "RUDEX.WLS"],
        ["CNY", "RUDEX.SMOKE"],
        ["BTS", "PPY"],
        ["BTS", "RUBLE"],
        ["BTS", "HERO"],
        ["BTS", "OCT"],
        ["BTS", "SILVER"],
        ["BTS", "GOLD"],
        ["BTS", "GDEX.BTC"],
        ["BTS", "GDEX.ETH"],
        ["BTS", "GDEX.EOS"],
        ["BTS", "GDEX.BTO"],
        ["BTS", "GDEX.USDT"],
        ["RUDEX.USDT", "RUDEX.BTC"],
        ["RUDEX.USDT", "RUDEX.ETH"],
        ["RUDEX.USDT", "RUDEX.EOS"],
        ["RUDEX.USDT", "PPY"],
        ["RUDEX.USDT", "RUBLE"],
        ["RUDEX.BTC", "RUDEX.ETH"],
        ["RUDEX.BTC", "RUDEX.EOS"],
        ["RUDEX.BTC", "RUDEX.STEEM"],
        ["RUDEX.BTC", "RUDEX.GOLOS"],
        ["RUDEX.BTC", "RUDEX.WLS"],
        ["RUDEX.BTC", "PPY"],
        ["RUBLE", "RUDEX.BTC"],
        ["RUBLE", "RUDEX.ETH"],
        ["RUBLE", "RUDEX.USDT"],
        ["RUBLE", "RUDEX.GOLOS"],
        ["BTS", "RUDEX.GOLOS"],
        ["BTS", "RUDEX.STEEM"],
        ["BTS", "RUDEX.EOS"],
        ["BTS", "RUDEX.BTC"],
        ["BTS", "RUDEX.ETH"],
        ["BTS", "RUDEX.USDT"],
        ["BTS", "RUDEX.WLS"],
        ["BTS", "RUDEX.SMOKE"],
        ["BTS", "XBTSX.STH"],
        ["BTS", "XBTSX.WAVES"],
        ["BTS", "HERTZ"]
    ].filter(a => {
        if (!quotes.length) return true;
        return quotes.indexOf(a[0]) !== -1;
    });
}

/**
 * Recognized namespaces of assets
 *
 * @returns {[string,string,string,string,string,string,string]}
 */
export function getAssetNamespaces() {
    if (_isTestnet()) {
        return [];
    }
    return ["OPEN.", "RUDEX.", "GDEX.", "XBTSX.", "CITADEL."];
}

/**
 * These namespaces will be hidden to the user, this may include "bit" for BitAssets
 * @returns {[string,string]}
 */
export function getAssetHideNamespaces() {
    // e..g "OPEN.", "bit"
    return [];
}

/**
 * Allowed gateways that the user will be able to choose from in Deposit Withdraw modal
 * @param gateway
 * @returns {boolean}
 */
export function allowedGateway(gateway) {
    const allowedGateways = [
        "TRADE",
        "OPEN",
        "RUDEX",
        "GDEX",
        "XBTSX",
        "CITADEL"
    ];
    if (!gateway) {
        // answers the question: are any allowed?
        return allowedGateways.length > 0;
    }
    return allowedGateways.indexOf(gateway) >= 0;
}

export function getSupportedLanguages() {
    // not yet supported
}

export function getAllowedLogins() {
    // possible: list containing any combination of ["password", "wallet"]
    return ["password", "wallet"];
}

export function getConfigurationAsset() {
    let assetSymbol = null;
    if (_isTestnet()) {
        assetSymbol = "NOTIFICATIONS";
    } else {
        assetSymbol = "TEST";
    }
    // explanation will be parsed out of the asset description (via split)
    return {
        symbol: assetSymbol,
        explanation:
            "This asset is used for decentralized configuration of the BitShares UI placed under bitshares.org."
    };
}
<|endoftext|>


<commit_before>const fs = require('fs')

const Task = require('data.task')
const { List } = require('immutable-ext')

// https://github.com/futurize/futurize
const FutureTask = require('futurize').futurize(Task)

// (lazy) task to read file
// FutureTask simply applies to the callback-based function inside
const readFileTask = FutureTask(fs.readFile)

// need to wrap into List that provides 'traverse'
const files = List(['config.json', 'config1.json'])

files

  // we have list of files but want task of lists
  // 1st argument 'Task.of' lifts to Task - applicative functor
  //  (needed as type hint in case of failure or never running the function)
  // 2nd argument is traversing function a -> f b
  .traverse( Task.of, fn => readFileTask(fn, 'utf-8') )
  .fork(console.error, console.log)
<commit_msg>ex22 upd<commit_after>const fs = require('fs')

const Task = require('data.task')
const { List } = require('immutable-ext')

// https://github.com/futurize/futurize
const FutureTask = require('futurize').futurize(Task)

// (lazy) task to read file
// FutureTask simply applies to the callback-based function inside
const readFileTask = FutureTask(fs.readFile)

// need to wrap into List that provides 'traverse'
const files = List(['config.json', 'config1.json'])

console.log(
  `List(['config.json', 'config1.json']).traverse(Task.of, fn => readFileTask(fn, 'utf-8')).fork(..., ...) : `
)

files

  // we have list of files but want task of lists
  // 1st argument 'Task.of' lifts to Task - applicative functor
  //  (needed as type hint in case of failure or never running the function)
  // 2nd argument is traversing function a -> f b
  .traverse( Task.of, fn => readFileTask(fn, 'utf-8') )
  .fork(console.error, console.log)
<|endoftext|>


<commit_before>const express = require('express');
const app = express();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');

app.use(bodyParser.json());

const trailRouter = require(__dirname + '/routes/trail_routes');
const authRouter = require(__dirname + '/routes/auth_routes');
const hikeMatchRouter = require(__dirname + '/routes/hikematch_routes');

app.use('/api', trailRouter);
app.use('/api', authRouter);
app.use('/api', hikeMatchRouter);

module.exports = exports = {
  server: { close: function() {
    throw new Error('Server not started yet!');
  }
},
  listen: function(port, mongoString, cb) {
    mongoose.connect(mongoString);
    return this.server = app.listen(port, cb);
  },
  close: function(cb) {
    this.server.close();
    if (cb) cb();
  }
};
<commit_msg>remove extra space<commit_after>const express = require('express');
const app = express();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');

app.use(bodyParser.json());

const trailRouter = require(__dirname + '/routes/trail_routes');
const authRouter = require(__dirname + '/routes/auth_routes');
const hikeMatchRouter = require(__dirname + '/routes/hikematch_routes');

app.use('/api', trailRouter);
app.use('/api', authRouter);
app.use('/api', hikeMatchRouter);

module.exports = exports = {
  server: { close: function() {
    throw new Error('Server not started yet!');
  }
},
  listen: function(port, mongoString, cb) {
    mongoose.connect(mongoString);
    return this.server = app.listen(port, cb);
  },
  close: function(cb) {
    this.server.close();
    if (cb) cb();
  }
};
<|endoftext|>


<commit_before>//**************************************************
//**Work inspired by multiple jquery swipe plugins**
//**Done by Yohai Ararat ***************************
//**************************************************
(function($) {

  $.spotSwipe = {
    version: '1.0.0',
    enabled: 'ontouchstart' in document.documentElement,
    preventDefault: false,
    moveThreshold: 75,
    timeThreshold: 200
  };

  var   startPosX,
        startPosY,
        startTime,
        elapsedTime,
        isMoving = false;

  function onTouchEnd() {
    //  alert(this);
    this.removeEventListener('touchmove', onTouchMove);
    this.removeEventListener('touchend', onTouchEnd);
    isMoving = false;
  }

  function onTouchMove(e) {
    if ($.spotSwipe.preventDefault) { e.preventDefault(); }
    if(isMoving) {
      var x = e.touches[0].pageX;
      var y = e.touches[0].pageY;
      var dx = startPosX - x;
      var dy = startPosY - y;
      var dir;
      elapsedTime = new Date().getTime() - startTime;
      if(Math.abs(dx) >= $.spotSwipe.moveThreshold && elapsedTime <= $.spotSwipe.timeThreshold) {
        dir = dx > 0 ? 'left' : 'right';
      }
      // else if(Math.abs(dy) >= $.spotSwipe.moveThreshold && elapsedTime <= $.spotSwipe.timeThreshold) {
      //   dir = dy > 0 ? 'down' : 'up';
      // }
      if(dir) {
        e.preventDefault();
        onTouchEnd.call(this);
        $(this).trigger('swipe', dir).trigger(`swipe${dir}`);
      }
    }
  }

  function onTouchStart(e) {
    if (e.touches.length == 1) {
      startPosX = e.touches[0].pageX;
      startPosY = e.touches[0].pageY;
      isMoving = true;
      startTime = new Date().getTime();
      this.addEventListener('touchmove', onTouchMove, false);
      this.addEventListener('touchend', onTouchEnd, false);
    }
  }

  function init() {
    this.addEventListener && this.addEventListener('touchstart', onTouchStart, false);
  }

  function teardown() {
    this.removeEventListener('touchstart', onTouchStart);
  }

  $.event.special.swipe = { setup: init };

  $.each(['left', 'up', 'down', 'right'], function () {
    $.event.special[`swipe${this}`] = { setup: function(){
      $(this).on('swipe', $.noop);
    } };
  });
})(jQuery);
/****************************************************
 * Method for adding psuedo drag events to elements *
 ***************************************************/
!function($){
  $.fn.addTouch = function(){
    this.each(function(i,el){
      $(el).bind('touchstart touchmove touchend touchcancel',function(){
        //we pass the original event object because the jQuery event
        //object is normalized to w3c specs and does not provide the TouchList
        handleTouch(event);
      });
    });

    var handleTouch = function(event){
      var touches = event.changedTouches,
          first = touches[0],
          eventTypes = {
            touchstart: 'mousedown',
            touchmove: 'mousemove',
            touchend: 'mouseup'
          },
          type = eventTypes[event.type],
          simulatedEvent
        ;

      if('MouseEvent' in window && typeof window.MouseEvent === 'function') {
        simulatedEvent = new window.MouseEvent(type, {
          'bubbles': true,
          'cancelable': true,
          'screenX': first.screenX,
          'screenY': first.screenY,
          'clientX': first.clientX,
          'clientY': first.clientY
        });
      } else {
        simulatedEvent = document.createEvent('MouseEvent');
        simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0/*left*/, null);
      }
      first.target.dispatchEvent(simulatedEvent);
    };
  };
}(jQuery);

//**********************************
//**From the jQuery Mobile Library**
//**need to recreate functionality**
//**and try to improve if possible**
//**********************************

/* Removing the jQuery function ****
************************************

(function( $, window, undefined ) {

	var $document = $( document ),
		// supportTouch = $.mobile.support.touch,
		touchStartEvent = 'touchstart'//supportTouch ? "touchstart" : "mousedown",
		touchStopEvent = 'touchend'//supportTouch ? "touchend" : "mouseup",
		touchMoveEvent = 'touchmove'//supportTouch ? "touchmove" : "mousemove";

	// setup new event shortcuts
	$.each( ( "touchstart touchmove touchend " +
		"swipe swipeleft swiperight" ).split( " " ), function( i, name ) {

		$.fn[ name ] = function( fn ) {
			return fn ? this.bind( name, fn ) : this.trigger( name );
		};

		// jQuery < 1.8
		if ( $.attrFn ) {
			$.attrFn[ name ] = true;
		}
	});

	function triggerCustomEvent( obj, eventType, event, bubble ) {
		var originalType = event.type;
		event.type = eventType;
		if ( bubble ) {
			$.event.trigger( event, undefined, obj );
		} else {
			$.event.dispatch.call( obj, event );
		}
		event.type = originalType;
	}

	// also handles taphold

	// Also handles swipeleft, swiperight
	$.event.special.swipe = {

		// More than this horizontal displacement, and we will suppress scrolling.
		scrollSupressionThreshold: 30,

		// More time than this, and it isn't a swipe.
		durationThreshold: 1000,

		// Swipe horizontal displacement must be more than this.
		horizontalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30,

		// Swipe vertical displacement must be less than this.
		verticalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30,

		getLocation: function ( event ) {
			var winPageX = window.pageXOffset,
				winPageY = window.pageYOffset,
				x = event.clientX,
				y = event.clientY;

			if ( event.pageY === 0 && Math.floor( y ) > Math.floor( event.pageY ) ||
				event.pageX === 0 && Math.floor( x ) > Math.floor( event.pageX ) ) {

				// iOS4 clientX/clientY have the value that should have been
				// in pageX/pageY. While pageX/page/ have the value 0
				x = x - winPageX;
				y = y - winPageY;
			} else if ( y < ( event.pageY - winPageY) || x < ( event.pageX - winPageX ) ) {

				// Some Android browsers have totally bogus values for clientX/Y
				// when scrolling/zooming a page. Detectable since clientX/clientY
				// should never be smaller than pageX/pageY minus page scroll
				x = event.pageX - winPageX;
				y = event.pageY - winPageY;
			}

			return {
				x: x,
				y: y
			};
		},

		start: function( event ) {
			var data = event.originalEvent.touches ?
					event.originalEvent.touches[ 0 ] : event,
				location = $.event.special.swipe.getLocation( data );
			return {
						time: ( new Date() ).getTime(),
						coords: [ location.x, location.y ],
						origin: $( event.target )
					};
		},

		stop: function( event ) {
			var data = event.originalEvent.touches ?
					event.originalEvent.touches[ 0 ] : event,
				location = $.event.special.swipe.getLocation( data );
			return {
						time: ( new Date() ).getTime(),
						coords: [ location.x, location.y ]
					};
		},

		handleSwipe: function( start, stop, thisObject, origTarget ) {
			if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&
				Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold &&
				Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {
				var direction = start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight";

				triggerCustomEvent( thisObject, "swipe", $.Event( "swipe", { target: origTarget, swipestart: start, swipestop: stop }), true );
				triggerCustomEvent( thisObject, direction,$.Event( direction, { target: origTarget, swipestart: start, swipestop: stop } ), true );
				return true;
			}
			return false;

		},

		// This serves as a flag to ensure that at most one swipe event event is
		// in work at any given time
		eventInProgress: false,

		setup: function() {
			var events,
				thisObject = this,
				$this = $( thisObject ),
				context = {};

			// Retrieve the events data for this element and add the swipe context
			events = $.data( this, "mobile-events" );
			if ( !events ) {
				events = { length: 0 };
				$.data( this, "mobile-events", events );
			}
			events.length++;
			events.swipe = context;

			context.start = function( event ) {

				// Bail if we're already working on a swipe event
				if ( $.event.special.swipe.eventInProgress ) {
					return;
				}
				$.event.special.swipe.eventInProgress = true;

				var stop,
					start = $.event.special.swipe.start( event ),
					origTarget = event.target,
					emitted = false;

				context.move = function( event ) {
					if ( !start || event.isDefaultPrevented() ) {
						return;
					}

					stop = $.event.special.swipe.stop( event );
					if ( !emitted ) {
						emitted = $.event.special.swipe.handleSwipe( start, stop, thisObject, origTarget );
						if ( emitted ) {

							// Reset the context to make way for the next swipe event
							$.event.special.swipe.eventInProgress = false;
						}
					}
					// prevent scrolling
					if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) {
						event.preventDefault();
					}
				};

				context.stop = function() {
						emitted = true;

						// Reset the context to make way for the next swipe event
						$.event.special.swipe.eventInProgress = false;
						$document.off( touchMoveEvent, context.move );
						context.move = null;
				};

				$document.on( touchMoveEvent, context.move )
					.one( touchStopEvent, context.stop );
			};
			$this.on( touchStartEvent, context.start );
		},

		teardown: function() {
			var events, context;

			events = $.data( this, "mobile-events" );
			if ( events ) {
				context = events.swipe;
				delete events.swipe;
				events.length--;
				if ( events.length === 0 ) {
					$.removeData( this, "mobile-events" );
				}
			}

			if ( context ) {
				if ( context.start ) {
					$( this ).off( touchStartEvent, context.start );
				}
				if ( context.move ) {
					$document.off( touchMoveEvent, context.move );
				}
				if ( context.stop ) {
					$document.off( touchStopEvent, context.stop );
				}
			}
		}
	};
	$.each({
		swipeleft: "swipe.left",
		swiperight: "swipe.right"
	}, function( event, sourceEvent ) {

		$.event.special[ event ] = {
			setup: function() {
				$( this ).bind( sourceEvent, $.noop );
			},
			teardown: function() {
				$( this ).unbind( sourceEvent );
			}
		};
	});
})( jQuery, this );
*/
<commit_msg>Remove massive block of commented out code<commit_after>//**************************************************
//**Work inspired by multiple jquery swipe plugins**
//**Done by Yohai Ararat ***************************
//**************************************************
(function($) {

  $.spotSwipe = {
    version: '1.0.0',
    enabled: 'ontouchstart' in document.documentElement,
    preventDefault: false,
    moveThreshold: 75,
    timeThreshold: 200
  };

  var   startPosX,
        startPosY,
        startTime,
        elapsedTime,
        isMoving = false;

  function onTouchEnd() {
    //  alert(this);
    this.removeEventListener('touchmove', onTouchMove);
    this.removeEventListener('touchend', onTouchEnd);
    isMoving = false;
  }

  function onTouchMove(e) {
    if ($.spotSwipe.preventDefault) { e.preventDefault(); }
    if(isMoving) {
      var x = e.touches[0].pageX;
      var y = e.touches[0].pageY;
      var dx = startPosX - x;
      var dy = startPosY - y;
      var dir;
      elapsedTime = new Date().getTime() - startTime;
      if(Math.abs(dx) >= $.spotSwipe.moveThreshold && elapsedTime <= $.spotSwipe.timeThreshold) {
        dir = dx > 0 ? 'left' : 'right';
      }
      // else if(Math.abs(dy) >= $.spotSwipe.moveThreshold && elapsedTime <= $.spotSwipe.timeThreshold) {
      //   dir = dy > 0 ? 'down' : 'up';
      // }
      if(dir) {
        e.preventDefault();
        onTouchEnd.call(this);
        $(this).trigger('swipe', dir).trigger(`swipe${dir}`);
      }
    }
  }

  function onTouchStart(e) {
    if (e.touches.length == 1) {
      startPosX = e.touches[0].pageX;
      startPosY = e.touches[0].pageY;
      isMoving = true;
      startTime = new Date().getTime();
      this.addEventListener('touchmove', onTouchMove, false);
      this.addEventListener('touchend', onTouchEnd, false);
    }
  }

  function init() {
    this.addEventListener && this.addEventListener('touchstart', onTouchStart, false);
  }

  function teardown() {
    this.removeEventListener('touchstart', onTouchStart);
  }

  $.event.special.swipe = { setup: init };

  $.each(['left', 'up', 'down', 'right'], function () {
    $.event.special[`swipe${this}`] = { setup: function(){
      $(this).on('swipe', $.noop);
    } };
  });
})(jQuery);
/****************************************************
 * Method for adding psuedo drag events to elements *
 ***************************************************/
!function($){
  $.fn.addTouch = function(){
    this.each(function(i,el){
      $(el).bind('touchstart touchmove touchend touchcancel',function(){
        //we pass the original event object because the jQuery event
        //object is normalized to w3c specs and does not provide the TouchList
        handleTouch(event);
      });
    });

    var handleTouch = function(event){
      var touches = event.changedTouches,
          first = touches[0],
          eventTypes = {
            touchstart: 'mousedown',
            touchmove: 'mousemove',
            touchend: 'mouseup'
          },
          type = eventTypes[event.type],
          simulatedEvent
        ;

      if('MouseEvent' in window && typeof window.MouseEvent === 'function') {
        simulatedEvent = new window.MouseEvent(type, {
          'bubbles': true,
          'cancelable': true,
          'screenX': first.screenX,
          'screenY': first.screenY,
          'clientX': first.clientX,
          'clientY': first.clientY
        });
      } else {
        simulatedEvent = document.createEvent('MouseEvent');
        simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0/*left*/, null);
      }
      first.target.dispatchEvent(simulatedEvent);
    };
  };
}(jQuery);
<|endoftext|>


<commit_before>(function() {

  var sync = Backbone.sync;
  var ajax = Backbone.ajax;
  var emulateHTTP = Backbone.emulateHTTP;
  var emulateJSON = Backbone.emulateJSON;
  var history = window.history;
  var pushState = history.pushState;
  var replaceState = history.replaceState;

  QUnit.testStart(function() {
    var env = QUnit.config.current.testEnvironment;

    // We never want to actually call these during tests.
    history.pushState = history.replaceState = function(){};

    // Capture ajax settings for comparison.
    Backbone.ajax = function(settings) {
      env.ajaxSettings = settings;
    };

    // Capture the arguments to Backbone.sync for comparison.
    Backbone.sync = function(method, model, options) {
      env.syncArgs = {
        method: method,
        model: model,
        options: options
      };
      sync.apply(this, arguments);
    };

  });

  QUnit.testDone(function() {
    Backbone.sync = sync;
    Backbone.ajax = ajax;
    Backbone.emulateHTTP = emulateHTTP;
    Backbone.emulateJSON = emulateJSON;
    history.pushState = pushState;
    history.replaceState = replaceState;
  });

})();
<commit_msg>enable QUnit.config.noglobals in tests<commit_after>(function() {

  var sync = Backbone.sync;
  var ajax = Backbone.ajax;
  var emulateHTTP = Backbone.emulateHTTP;
  var emulateJSON = Backbone.emulateJSON;
  var history = window.history;
  var pushState = history.pushState;
  var replaceState = history.replaceState;

  QUnit.config.noglobals = true;

  QUnit.testStart(function() {
    var env = QUnit.config.current.testEnvironment;

    // We never want to actually call these during tests.
    history.pushState = history.replaceState = function(){};

    // Capture ajax settings for comparison.
    Backbone.ajax = function(settings) {
      env.ajaxSettings = settings;
    };

    // Capture the arguments to Backbone.sync for comparison.
    Backbone.sync = function(method, model, options) {
      env.syncArgs = {
        method: method,
        model: model,
        options: options
      };
      sync.apply(this, arguments);
    };

  });

  QUnit.testDone(function() {
    Backbone.sync = sync;
    Backbone.ajax = ajax;
    Backbone.emulateHTTP = emulateHTTP;
    Backbone.emulateJSON = emulateJSON;
    history.pushState = pushState;
    history.replaceState = replaceState;
  });

})();
<|endoftext|>


<commit_before>// Deps
var
  request = require("request"),
  Events  = require("events").EventEmitter,
  util    = require("util"),
  fs      = require("fs");
  mapProc = require("../mapProcessor");
var
  log     = util.log;

// Other stuff.
var MINUTE = 60000; // Milliseconds.

//  Test data.
// var
//   testData = require("../../FIDS_response_most_fields.json");

// Define a data map for flight stats FIDS data. This maps FS fields to common CTI
// field names.
var dMap = require("./fsFidsMap").map;

// Report name of data source.
exports.name = "FlightStats FIDS";

// More than one url?! No worries, use array.
// var urls = [
//   { portCode: "MEL", url: "https://api.flightstats.com/flex/fids/rest/v1/json/MEL/departures" },
//   { portCode: "MEL", url: "https://api.flightstats.com/flex/fids/rest/v1/json/MEL/arrivals" }
// ];

// Open the fids url file and parse contents to json structure. Expect
// file contents to be array of objects.
var urls = require("./fsFids.json");
// Light error checking on urls structure.
urls.forEach(function(url)
{
  if (!(url.url && url.portCode)) throw "FIDS url definition not complete.";
});

// Check length of urls array. If no elements, throw error.
if (urls.length === 0)
{
  throw "No urls defined for FIDS data source.";
}

// Obtain app id and app key from environment.
var
  appId = process.env.FS_APP_ID,
  appKey = process.env.FS_APP_KEY;
// If these are not present, throw exception.
if (!(appId && appKey))
{
  throw "Cannot use FlightStats data source without credentials.";
}

// Define fields of interest.
var fsFields = [
  "flightId",                 // Numeric flight ID. This can be used to look up more detailed flight information via the Flight Status by Flight API.  430791
  "lastUpdatedTimeUtc",          // Date that this flight information was last updated, according to the selected airport's timezone. 01/30/2013
  "lastUpdatedDateUtc",       // Date that this flight information was last updated, in UTC. 01/31/2013
  "dayOffset",                // Nonnegative integer representing the number of days forward from today (according to the selected airport's time zone). For today's flights, this will be 0.  0
  "statusCode",               // Single-character FlightStats code for the status of the flight  A
  "airlineName",              // Name of the airline. For wet leases, this will be the marketing airline rather than the operating airline.  British Airways
  "airlineCode",              // Airline code of the airline. For wet leases, this will be the code for the marketing airline rather than the operating airline. BA
  "flightNumber",             // Flight number assigned by the airline.  100
  "isCodeshare",              // Boolean value indicating whether the flight is a codeshare (flight marketed by multiple airlines).  true
  "operatedFlightNumber",     // Flight number assigned by the operating airline.  200
  "operatingAirlineName",     // Name of the operating airline.  British Airways
  "operatingAirlineCode",     // Code of the operating airline.  BA
  "destinationAirportName",   // Name of the flight's destination airport. Portland International Airport
  "destinationAirportCode",   // Code of the flight's destination airport. PDX
  "destinationCity",          // Name of the flight's destination city.  Portland
  "destinationFamiliarName",  // A name for the destination that the travelers expect, particularly used to distinguish between cities with the same name or multiple airports that serve the same city. New York JFK
  "destinationStateCode",     // State (or province, where applicable) code of the destination airport.  OR
  "destinationCountryCode",   // Country code of the flight's destination airport. us
  "flight",                   // The combination of the airline code and the flight number.  AA 100
  "delayed",                  // Boolean value indicating whether the flight is delayed. true
  "remarks",                  // A phrase with additional information about the status of the flight, including delay information (in minutes) if appropriate. Arrived 30 minutes late
  "remarksWithTime",          // A phrase with additional information about the status of the flight, including local time if appropriate. Arrived 04:27
  "remarksCode",              // One of a small fixed set of strings describing the kind of remark appearing in the remarks field. See Remarks Codes. This field can be requested even if the request does not actually include the remarks field. ARRIVED_LATE
  "airportCode",              // Code for the destination (for departing flights) or origin (for arrivals) airport.  LHR
  "airportName",              // Name of the destination (for departing flights) or origin (for arrivals) airport. London Heathrow
  "city",                     // Name of the destination (for departing flights) or origin (for arrivals) city.  London
  "gate",                     // Name of the gate where the flight will depart/arrive. C12
  "terminal",                 // Name of the terminal where the flight will depart/arrive. C
  "scheduledTime",            // The scheduled arrival or departure time, depending on whether you asked for arrivals or departures. 01:30
  "scheduledDate",            // The scheduled arrival or departure date, depending on whether you asked for arrivals or departures. If you have opted to use runway times this may be a runway time if no gate time is available.
  "estimatedTime",            // The estimated arrival or departure time, depending on whether you asked for arrivals or departures. 01:34
  "estimatedDate",            // The estimated arrival or departure date, depending on whether you asked for arrivals or departures. If you have opted to use runway times this may be a runway time if no gate time is available.
  "actualTime",               // The actual arrival or departure time, depending on whether you asked for arrivals or departures.  01:33
  "actualDate",               // The actual arrival or departure date, depending on whether you asked for arrivals or departures. If you have opted to use runway times this may be a runway time if no gate time is available.
  "currentTime",              // The most accurate arrival or departure time (priority: 1. actual 2. estimated 3 scheduled), depending on whether you asked for arrivals or departures.  01:33
  "currentDate",              // The most accurate arrival or departure date (priority: 1. actual 2. estimated 3 scheduled), depending on whether you asked for arrivals or departures. If you have opted to use runway times this may be a runway time if no gate time is available.
  "scheduledGateTime",        // The scheduled gate arrival or departure time, depending on whether you asked for arrivals or departures.  07:40
  "scheduledGateDate",        // The scheduled gate arrival or departure date, depending on whether you asked for arrivals or departures.  01/30/2013
  "estimatedGateTime",        // The estimated gate arrival or departure time, depending on whether you asked for arrivals or departures.  07:50
  "estimatedGateDate",        // The estimated gate arrival or departure date, depending on whether you asked for arrivals or departures.  01/30/2013
  "actualGateTime",           // The actual gate arrival or departure time, depending on whether you asked for arrivals or departures. 08:05
  "actualGateDate",           //  The actual gate arrival or departure date, depending on whether you asked for arrivals or departures. 01/30/2013
  "currentGateTime",          // The most accurate gate arrival or departure time, depending on whether you asked for arrivals or departures.  08:05
  "currentGateDate",          // The most accurate gate arrival or departure date, depending on whether you asked for arrivals or departures.  01/30/2013
  "codesharesAsCodes",        // If this flight is marketed by multiple carriers, this field lists those codeshare flights with the airline code and flight number.   ["UA 6416","NH 7328","AC 4030"]
  "uplineAirportCodes",       // The codes of the airports, in order, from the flight segments preceding this segment. ["DFW","ATL"]
  "downlineAirportCodes",     // The codes of the airports, in order, from the flight segments after segment.  ["SEA","YVR"]
  "weather",                  // A short description of the weather conditions at the remote airport.  Cloudy
  "temperatureC",             // Air temperature, in degrees Celsius/centigrade, at the remote airport.  0
  "temperatureF"              // Air temperature, in degrees Fahrenheit, at the remote airport.  0
];

// Define standard request parameters.
var reqOptions = {
  method: "GET",
  proxy: (process.env ? process.env.http_proxy : null),
  // url: "http://cassiopeia:3000/test",
  url: null,
  qs: {
    "appId": appId,
    "appKey": appKey,
    "requestedFields": fsFields.join(","),
    "timeFormat": "24",
    "excludeCargoOnlyFlights": true,
    "includeCodeshares": false
  },
  headers: {
    Host: "api.flightstats.com"
    // Host: "cassiopeia:3000"
  },
  json: true
};

var lastRun = null; // The last time this store collected data.
// Collect data from web service providers.
exports.collect = collect;
function collect(callback)
{
  // This data store will run every minute or right away if it hasn't run before.
  if (lastRun !== null && Date.now() - lastRun < (2 * MINUTE))
  {
    return false;
  }
  // This data source was last run at the current time.
  lastRun = Date.now();

  // If a callback wasn't supplied, use a default noop.
  if (!callback) callback = function(error, data) { log(error, data); };

  // Iterate over urls, request data from each.
  urls.forEach(function(url)
  {
    // Make a request for data.
    reqOptions.url = url.url;
    request(reqOptions, function(error, res, body)
    {
      // Check that body is not undefined. If it is, bail out immediately.
      if (body === undefined)
      {
        error = error ? error : "No content received.";
        callback(error, body);
        return;
      }

      // Flight stats do strange erroring? Ah yes, they do, but if you send a special param
      // they can do normal http errors. XXX Investigate this feature later.
      if (body.error) error = body.error;
      // Otherwise execute callback.
      log(url.url);
      log("Collected [" + body.fidsData.length + "] FIDS entries.");
      body.portCode = url.portCode;
      callback(error, body);
    });
  });

  // Return true to indicate that this data store was run.
  return true;
}

// Process FIDS data. Here we use a standard mapProcessor to extract the data we
// need from the flight stats FIDS data structure.
exports.auger = function(input)
{
  // For each record, insert a port code field.
  var recordCb = function(record)
  {
    record.portCode = input.portCode;
  };

  // Process fids data with the map processor.
  return mapProc.processData(input.fidsData, dMap, null, recordCb);
}

// Save the data. The intention of this function is to provide a place where flight stats
// specific, pre-save manipulation of data could be done.
exports.saveData = function (store, data, something)
{
  log("Saving data.");
  store.saveFIDS(data);
}
<commit_msg>logging no data in body instances<commit_after>// Deps
var
  request = require("request"),
  Events  = require("events").EventEmitter,
  util    = require("util"),
  fs      = require("fs");
  mapProc = require("../mapProcessor");
var
  log     = util.log;

// Other stuff.
var MINUTE = 60000; // Milliseconds.

//  Test data.
// var
//   testData = require("../../FIDS_response_most_fields.json");

// Define a data map for flight stats FIDS data. This maps FS fields to common CTI
// field names.
var dMap = require("./fsFidsMap").map;

// Report name of data source.
exports.name = "FlightStats FIDS";

// More than one url?! No worries, use array.
// var urls = [
//   { portCode: "MEL", url: "https://api.flightstats.com/flex/fids/rest/v1/json/MEL/departures" },
//   { portCode: "MEL", url: "https://api.flightstats.com/flex/fids/rest/v1/json/MEL/arrivals" }
// ];

// Open the fids url file and parse contents to json structure. Expect
// file contents to be array of objects.
var urls = require("./fsFids.json");
// Light error checking on urls structure.
urls.forEach(function(url)
{
  if (!(url.url && url.portCode)) throw "FIDS url definition not complete.";
});

// Check length of urls array. If no elements, throw error.
if (urls.length === 0)
{
  throw "No urls defined for FIDS data source.";
}

// Obtain app id and app key from environment.
var
  appId = process.env.FS_APP_ID,
  appKey = process.env.FS_APP_KEY;
// If these are not present, throw exception.
if (!(appId && appKey))
{
  throw "Cannot use FlightStats data source without credentials.";
}

// Define fields of interest.
var fsFields = [
  "flightId",                 // Numeric flight ID. This can be used to look up more detailed flight information via the Flight Status by Flight API.  430791
  "lastUpdatedTimeUtc",          // Date that this flight information was last updated, according to the selected airport's timezone. 01/30/2013
  "lastUpdatedDateUtc",       // Date that this flight information was last updated, in UTC. 01/31/2013
  "dayOffset",                // Nonnegative integer representing the number of days forward from today (according to the selected airport's time zone). For today's flights, this will be 0.  0
  "statusCode",               // Single-character FlightStats code for the status of the flight  A
  "airlineName",              // Name of the airline. For wet leases, this will be the marketing airline rather than the operating airline.  British Airways
  "airlineCode",              // Airline code of the airline. For wet leases, this will be the code for the marketing airline rather than the operating airline. BA
  "flightNumber",             // Flight number assigned by the airline.  100
  "isCodeshare",              // Boolean value indicating whether the flight is a codeshare (flight marketed by multiple airlines).  true
  "operatedFlightNumber",     // Flight number assigned by the operating airline.  200
  "operatingAirlineName",     // Name of the operating airline.  British Airways
  "operatingAirlineCode",     // Code of the operating airline.  BA
  "destinationAirportName",   // Name of the flight's destination airport. Portland International Airport
  "destinationAirportCode",   // Code of the flight's destination airport. PDX
  "destinationCity",          // Name of the flight's destination city.  Portland
  "destinationFamiliarName",  // A name for the destination that the travelers expect, particularly used to distinguish between cities with the same name or multiple airports that serve the same city. New York JFK
  "destinationStateCode",     // State (or province, where applicable) code of the destination airport.  OR
  "destinationCountryCode",   // Country code of the flight's destination airport. us
  "flight",                   // The combination of the airline code and the flight number.  AA 100
  "delayed",                  // Boolean value indicating whether the flight is delayed. true
  "remarks",                  // A phrase with additional information about the status of the flight, including delay information (in minutes) if appropriate. Arrived 30 minutes late
  "remarksWithTime",          // A phrase with additional information about the status of the flight, including local time if appropriate. Arrived 04:27
  "remarksCode",              // One of a small fixed set of strings describing the kind of remark appearing in the remarks field. See Remarks Codes. This field can be requested even if the request does not actually include the remarks field. ARRIVED_LATE
  "airportCode",              // Code for the destination (for departing flights) or origin (for arrivals) airport.  LHR
  "airportName",              // Name of the destination (for departing flights) or origin (for arrivals) airport. London Heathrow
  "city",                     // Name of the destination (for departing flights) or origin (for arrivals) city.  London
  "gate",                     // Name of the gate where the flight will depart/arrive. C12
  "terminal",                 // Name of the terminal where the flight will depart/arrive. C
  "scheduledTime",            // The scheduled arrival or departure time, depending on whether you asked for arrivals or departures. 01:30
  "scheduledDate",            // The scheduled arrival or departure date, depending on whether you asked for arrivals or departures. If you have opted to use runway times this may be a runway time if no gate time is available.
  "estimatedTime",            // The estimated arrival or departure time, depending on whether you asked for arrivals or departures. 01:34
  "estimatedDate",            // The estimated arrival or departure date, depending on whether you asked for arrivals or departures. If you have opted to use runway times this may be a runway time if no gate time is available.
  "actualTime",               // The actual arrival or departure time, depending on whether you asked for arrivals or departures.  01:33
  "actualDate",               // The actual arrival or departure date, depending on whether you asked for arrivals or departures. If you have opted to use runway times this may be a runway time if no gate time is available.
  "currentTime",              // The most accurate arrival or departure time (priority: 1. actual 2. estimated 3 scheduled), depending on whether you asked for arrivals or departures.  01:33
  "currentDate",              // The most accurate arrival or departure date (priority: 1. actual 2. estimated 3 scheduled), depending on whether you asked for arrivals or departures. If you have opted to use runway times this may be a runway time if no gate time is available.
  "scheduledGateTime",        // The scheduled gate arrival or departure time, depending on whether you asked for arrivals or departures.  07:40
  "scheduledGateDate",        // The scheduled gate arrival or departure date, depending on whether you asked for arrivals or departures.  01/30/2013
  "estimatedGateTime",        // The estimated gate arrival or departure time, depending on whether you asked for arrivals or departures.  07:50
  "estimatedGateDate",        // The estimated gate arrival or departure date, depending on whether you asked for arrivals or departures.  01/30/2013
  "actualGateTime",           // The actual gate arrival or departure time, depending on whether you asked for arrivals or departures. 08:05
  "actualGateDate",           //  The actual gate arrival or departure date, depending on whether you asked for arrivals or departures. 01/30/2013
  "currentGateTime",          // The most accurate gate arrival or departure time, depending on whether you asked for arrivals or departures.  08:05
  "currentGateDate",          // The most accurate gate arrival or departure date, depending on whether you asked for arrivals or departures.  01/30/2013
  "codesharesAsCodes",        // If this flight is marketed by multiple carriers, this field lists those codeshare flights with the airline code and flight number.   ["UA 6416","NH 7328","AC 4030"]
  "uplineAirportCodes",       // The codes of the airports, in order, from the flight segments preceding this segment. ["DFW","ATL"]
  "downlineAirportCodes",     // The codes of the airports, in order, from the flight segments after segment.  ["SEA","YVR"]
  "weather",                  // A short description of the weather conditions at the remote airport.  Cloudy
  "temperatureC",             // Air temperature, in degrees Celsius/centigrade, at the remote airport.  0
  "temperatureF"              // Air temperature, in degrees Fahrenheit, at the remote airport.  0
];

// Define standard request parameters.
var reqOptions = {
  method: "GET",
  proxy: (process.env ? process.env.http_proxy : null),
  // url: "http://cassiopeia:3000/test",
  url: null,
  qs: {
    "appId": appId,
    "appKey": appKey,
    "requestedFields": fsFields.join(","),
    "timeFormat": "24",
    "excludeCargoOnlyFlights": true,
    "includeCodeshares": false
  },
  headers: {
    Host: "api.flightstats.com"
    // Host: "cassiopeia:3000"
  },
  json: true
};

var lastRun = null; // The last time this store collected data.
// Collect data from web service providers.
exports.collect = collect;
function collect(callback)
{
  // This data store will run every minute or right away if it hasn't run before.
  if (lastRun !== null && Date.now() - lastRun < (2 * MINUTE))
  {
    return false;
  }
  // This data source was last run at the current time.
  lastRun = Date.now();

  // If a callback wasn't supplied, use a default noop.
  if (!callback) callback = function(error, data) { log(error, data); };

  // Iterate over urls, request data from each.
  urls.forEach(function(url)
  {
    // Make a request for data.
    reqOptions.url = url.url;
    request(reqOptions, function(error, res, body)
    {
      // Check that body is not undefined. If it is, bail out immediately.
      if (body === undefined)
      {
        error = error ? error : "No content received.";
        callback(error, body);
        return;
      }

      // Flight stats do strange erroring? Ah yes, they do, but if you send a special param
      // they can do normal http errors. XXX Investigate this feature later.
      if (body.error) error = body.error;
      // Otherwise execute callback.
      log(url.url);
      // Another situation in which body data might not be included?!
      if (body && body.fidsData)
      {
        log("Collected [" + body.fidsData.length + "] FIDS entries.");
        body.portCode = url.portCode;
      }
      // Log instances where above test fails.
      else
      {
        log("WARNING. Did not collect FIDS data: " + body);
      }
      callback(error, body);
    });
  });

  // Return true to indicate that this data store was run.
  return true;
}

// Process FIDS data. Here we use a standard mapProcessor to extract the data we
// need from the flight stats FIDS data structure.
exports.auger = function(input)
{
  // For each record, insert a port code field.
  var recordCb = function(record)
  {
    record.portCode = input.portCode;
  };

  // Process fids data with the map processor.
  return mapProc.processData(input.fidsData, dMap, null, recordCb);
}

// Save the data. The intention of this function is to provide a place where flight stats
// specific, pre-save manipulation of data could be done.
exports.saveData = function (store, data, something)
{
  log("Saving data.");
  store.saveFIDS(data);
}
<|endoftext|>