function NoHostAvailableError(innerErrors, message) {
  DriverError.call(this, message);
  this.innerErrors = innerErrors;
  this.info = 'Represents an error when a query cannot be performed because no host is available or could be reached by the driver.';
  if (!message) {
    this.message = 'All host(s) tried for query failed.';
    if (innerErrors) {
      const hostList = Object.keys(innerErrors);
      if (hostList.length > 0) {
        const host = hostList[0];
        this.message += util.format(' First host tried, %s: %s. See innerErrors.', host, innerErrors[host]);
      }
    }
  }
}

Represents an error when a query cannot be performed because no host is available or could be reached by the driver.
@param {Object} innerErrors An object map containing the error per host tried
@param {String} [message]
@constructor

Represents an error when a query cannot be performed because no host is available or could be reached by the driver .


function BusyConnectionError(address, maxRequestsPerConnection, connectionLength) {
  const message = util.format('All connections to host %s are busy, %d requests are in-flight on %s',
    address, maxRequestsPerConnection, connectionLength === 1 ? 'a single connection': 'each connection');
  DriverError.call(this, message, this.constructor);
  this.info = 'Represents a client-side error indicating that all connections to a certain host have reached ' +
    'the maximum amount of in-flight requests supported (pooling.maxRequestsPerConnection)';
}

Represents a client-side error indicating that all connections to a certain host have reached
the maximum amount of in-flight requests supported.
@param {String} address
@param {Number} maxRequestsPerConnection
@param {Number} connectionLength
@constructor

Represents a client - side error indicating that all connections to a certain host have reached the maximum amount of in - flight requests supported .


function extend(baseOptions, userOptions) {
  if (arguments.length === 1) {
    userOptions = arguments[0];
    baseOptions = {};
  }
  const options = utils.deepExtend(baseOptions, defaultOptions(), userOptions);
  if (!util.isArray(options.contactPoints) || options.contactPoints.length === 0) {
    throw new TypeError('Contacts points are not defined.');
  }
  for (let i = 0; i < options.contactPoints.length; i++) {
    const hostName = options.contactPoints[i];
    if (!hostName) {
      throw new TypeError(util.format('Contact point %s (%s) is not a valid host name, ' +
        'the following values are valid contact points: ipAddress, hostName or ipAddress:port', i, hostName));
    }
  }
  if (!options.logEmitter) {
    options.logEmitter = function () {};
  }
  if (!options.queryOptions) {
    throw new TypeError('queryOptions not defined in options');
  }

  if (options.requestTracker !== null && !(options.requestTracker instanceof tracker.RequestTracker)) {
    throw new TypeError('requestTracker must be an instance of RequestTracker');
  }

  if (!(options.metrics instanceof metrics.ClientMetrics)) {
    throw new TypeError('metrics must be an instance of ClientMetrics');
  }

  validatePoliciesOptions(options.policies);
  validateProtocolOptions(options.protocolOptions);
  validateSocketOptions(options.socketOptions);
  options.encoding = options.encoding || {};
  validateEncodingOptions(options.encoding);
  if (options.profiles && !util.isArray(options.profiles)) {
    throw new TypeError('profiles must be an Array of ExecutionProfile instances');
  }
  return options;
}

Extends and validates the user options
@param {Object} [baseOptions] The source object instance that will be overridden
@param {Object} userOptions
@returns {Object}


function validatePoliciesOptions(policiesOptions) {
  if (!policiesOptions) {
    throw new TypeError('policies not defined in options');
  }
  if (!(policiesOptions.loadBalancing instanceof policies.loadBalancing.LoadBalancingPolicy)) {
    throw new TypeError('Load balancing policy must be an instance of LoadBalancingPolicy');
  }
  if (!(policiesOptions.reconnection instanceof policies.reconnection.ReconnectionPolicy)) {
    throw new TypeError('Reconnection policy must be an instance of ReconnectionPolicy');
  }
  if (!(policiesOptions.retry instanceof policies.retry.RetryPolicy)) {
    throw new TypeError('Retry policy must be an instance of RetryPolicy');
  }
  if (!(policiesOptions.addressResolution instanceof policies.addressResolution.AddressTranslator)) {
    throw new TypeError('Address resolution policy must be an instance of AddressTranslator');
  }
  if (policiesOptions.timestampGeneration !== null &&
    !(policiesOptions.timestampGeneration instanceof policies.timestampGeneration.TimestampGenerator)) {
    throw new TypeError('Timestamp generation policy must be an instance of TimestampGenerator');
  }
}

Validates the policies from the client options.
@param {ClientOptions.policies} policiesOptions
@private

Validates the policies from the client options .


function validateProtocolOptions(protocolOptions) {
  if (!protocolOptions) {
    throw new TypeError('protocolOptions not defined in options');
  }
  const version = protocolOptions.maxVersion;
  if (version && (typeof version !== 'number' || !types.protocolVersion.isSupported(version))) {
    throw new TypeError(util.format('protocolOptions.maxVersion provided (%s) is invalid', version));
  }
}

Validates the protocol options.
@param {ClientOptions.protocolOptions} protocolOptions
@private


function validateSocketOptions(socketOptions) {
  if (!socketOptions) {
    throw new TypeError('socketOptions not defined in options');
  }
  if (typeof socketOptions.readTimeout !== 'number') {
    throw new TypeError('socketOptions.readTimeout must be a Number');
  }
  if (typeof socketOptions.coalescingThreshold !== 'number' || socketOptions.coalescingThreshold <= 0) {
    throw new TypeError('socketOptions.coalescingThreshold must be a positive Number');
  }
}

Validates the socket options.
@param {ClientOptions.socketOptions} socketOptions
@private


function validateEncodingOptions(encodingOptions) {
  if (encodingOptions.map) {
    const mapConstructor = encodingOptions.map;
    if (typeof mapConstructor !== 'function' ||
      typeof mapConstructor.prototype.forEach !== 'function' ||
      typeof mapConstructor.prototype.set !== 'function') {
      throw new TypeError('Map constructor not valid');
    }
  }

  if (encodingOptions.set) {
    const setConstructor = encodingOptions.set;
    if (typeof setConstructor !== 'function' ||
      typeof setConstructor.prototype.forEach !== 'function' ||
      typeof setConstructor.prototype.add !== 'function') {
      throw new TypeError('Set constructor not valid');
    }
  }

  if ((encodingOptions.useBigIntAsLong || encodingOptions.useBigIntAsVarint) && typeof BigInt === 'undefined') {
    throw new TypeError('BigInt is not supported by the JavaScript engine');
  }
}

Validates the encoding options.
@param {ClientOptions.encoding} encodingOptions
@private


function setProtocolDependentDefaults(options, version) {
  let coreConnectionsPerHost = coreConnectionsPerHostV3;
  let maxRequestsPerConnection = maxRequestsPerConnectionV3;
  if (!types.protocolVersion.uses2BytesStreamIds(version)) {
    coreConnectionsPerHost = coreConnectionsPerHostV2;
    maxRequestsPerConnection = maxRequestsPerConnectionV2;
  }
  options.pooling = utils.deepExtend({}, { coreConnectionsPerHost, maxRequestsPerConnection }, options.pooling);
}

function setProtocolDependentDefaults ( options , version ) { let coreConnectionsPerHost = coreConnectionsPerHostV3 ; let maxRequestsPerConnection = maxRequestsPerConnectionV3 ; if ( ! types . protocolVersion . uses2BytesStreamIds ( version ) ) { coreConnectionsPerHost = coreConnectionsPerHostV2 ; maxRequestsPerConnection = maxRequestsPerConnectionV2 ; } options . pooling = utils . deepExtend ( { } , { coreConnectionsPerHost , maxRequestsPerConnection } , options . pooling ) ; }

Sets the default options that depend on the protocol version.
@param {ClientOptions} options
@param {Number} version

Sets the default options that depend on the protocol version .


function(name) {
    name = name.toLowerCase();
    if (name.indexOf('<') > 0) {
      const listMatches = /^(list|set)<(.+)>$/.exec(name);
      if (listMatches) {
        return { code: this[listMatches[1]], info: this.getByName(listMatches[2])};
      }
      const mapMatches = /^(map)< *(.+) *, *(.+)>$/.exec(name);
      if (mapMatches) {
        return { code: this[mapMatches[1]], info: [this.getByName(mapMatches[2]), this.getByName(mapMatches[3])]};
      }
      const udtMatches = /^(udt)<(.+)>$/.exec(name);
      if (udtMatches) {
        //udt name as raw string
        return { code: this[udtMatches[1]], info: udtMatches[2]};
      }
      const tupleMatches = /^(tuple)<(.+)>$/.exec(name);
      if (tupleMatches) {
        //tuple info as an array of types
        return { code: this[tupleMatches[1]], info: tupleMatches[2].split(',').map(function (x) {
          return this.getByName(x.trim());
        }, this)};
      }
    }
    const typeInfo = { code: this[name], info: null};
    if (typeof typeInfo.code !== 'number') {
      throw new TypeError('Data type with name ' + name + ' not valid');
    }
    return typeInfo;
  }

function
(
name
)
{
name
=
name
.
toLowerCase
(
)
;
if
(
name
.
indexOf
(
'<'
)
>
0
)
{
const
listMatches
=
/
^(list|set)<(.+)>$
/
.
exec
(
name
)
;
if
(
listMatches
)
{
return
{
code
:
this
[
listMatches
[
1
]
]
,
info
:
this
.
getByName
(
listMatches
[
2
]
)
}
;
}
const
mapMatches
=
/
^(map)< *(.+) *, *(.+)>$
/
.
exec
(
name
)
;
if
(
mapMatches
)
{
return
{
code
:
this
[
mapMatches
[
1
]
]
,
info
:
[
this
.
getByName
(
mapMatches
[
2
]
)
,
this
.
getByName
(
mapMatches
[
3
]
)
]
}
;
}
const
udtMatches
=
/
^(udt)<(.+)>$
/
.
exec
(
name
)
;
if
(
udtMatches
)
{
//udt name as raw string
return
{
code
:
this
[
udtMatches
[
1
]
]
,
info
:
udtMatches
[
2
]
}
;
}
const
tupleMatches
=
/
^(tuple)<(.+)>$
/
.
exec
(
name
)
;
if
(
tupleMatches
)
{
//tuple info as an array of types
return
{
code
:
this
[
tupleMatches
[
1
]
]
,
info
:
tupleMatches
[
2
]
.
split
(
','
)
.
map
(
function
(
x
)
{
return
this
.
getByName
(
x
.
trim
(
)
)
;
}
,
this
)
}
;
}
}
const
typeInfo
=
{
code
:
this
[
name
]
,
info
:
}
;
if
(
typeof
typeInfo
.
code
!==
'number'
)
{
throw
new
TypeError
(
'Data type with name '
+
name
+
' not valid'
)
;
}
return
typeInfo
;
}

Returns the typeInfo of a given type name
@param name
@returns {{code: number, info: *|Object}}


function getDataTypeNameByCode(item) {
  if (!item || typeof item.code !== 'number') {
    throw new errors.ArgumentError('Invalid signature type definition');
  }
  const typeName = _dataTypesByCode[item.code];
  if (!typeName) {
    throw new errors.ArgumentError(util.format('Type with code %d not found', item.code));
  }
  if (!item.info) {
    return typeName;
  }
  if (util.isArray(item.info)) {
    return (typeName +
      '<' +
      item.info.map(function (t) {
        return getDataTypeNameByCode(t);
      }).join(', ') +
      '>');
  }
  if (typeof item.info.code === 'number') {
    return typeName + '<' + getDataTypeNameByCode(item.info) + '>';
  }
  return typeName;
}

function
getDataTypeNameByCode
(
item
)
{
if
(
!
item
||
typeof
item
.
code
!==
'number'
)
{
throw
new
errors
.
ArgumentError
(
'Invalid signature type definition'
)
;
}
const
typeName
=
_dataTypesByCode
[
item
.
code
]
;
if
(
!
typeName
)
{
throw
new
errors
.
ArgumentError
(
util
.
format
(
'Type with code %d not found'
,
item
.
code
)
)
;
}
if
(
!
item
.
info
)
{
return
typeName
;
}
if
(
util
.
isArray
(
item
.
info
)
)
{
return
(
typeName
+
'<'
+
item
.
info
.
map
(
function
(
t
)
{
return
getDataTypeNameByCode
(
t
)
;
}
)
.
join
(
', '
)
+
'>'
)
;
}
if
(
typeof
item
.
info
.
code
===
'number'
)
{
return
typeName
+
'<'
+
getDataTypeNameByCode
(
item
.
info
)
+
'>'
;
}
return
typeName
;
}

Gets the data type name for a given type definition
@internal
@ignore
@throws {ArgumentError}


function FrameHeader(version, flags, streamId, opcode, bodyLength) {
  this.version = version;
  this.flags = flags;
  this.streamId = streamId;
  this.opcode = opcode;
  this.bodyLength = bodyLength;
}

function FrameHeader ( version , flags , streamId , opcode , bodyLength ) { this . version = version ; this . flags = flags ; this . streamId = streamId ; this . opcode = opcode ; this . bodyLength = bodyLength ; }

classes
Represents a frame header that could be used to read from a Buffer or to write to a Buffer
@ignore
@param {Number} version Protocol version
@param {Number} flags
@param {Number} streamId
@param {Number} opcode
@param {Number} bodyLength
@constructor


function generateTimestamp(date, microseconds) {
  if (!date) {
    date = new Date();
  }
  let longMicro = Long.ZERO;
  if (typeof microseconds === 'number' && microseconds >= 0 && microseconds < 1000) {
    longMicro = Long.fromInt(microseconds);
  }
  else {
    if (_timestampTicks > 999) {
      _timestampTicks = 0;
    }
    longMicro = Long.fromInt(_timestampTicks);
    _timestampTicks++;
  }
  return Long
    .fromNumber(date.getTime())
    .multiply(_longOneThousand)
    .add(longMicro);
}

function generateTimestamp ( date , microseconds ) { if ( ! date ) { date = new Date ( ) ; } let longMicro = Long . ZERO ; if ( typeof microseconds === 'number' && microseconds >= 0 && microseconds < 1000 ) { longMicro = Long . fromInt ( microseconds ) ; } else { if ( _timestampTicks > 999 ) { _timestampTicks = 0 ; } longMicro = Long . fromInt ( _timestampTicks ) ; _timestampTicks ++ ; } return Long . fromNumber ( date . getTime ( ) ) . multiply ( _longOneThousand ) . add ( longMicro ) ; }

Generates a value representing the timestamp for the query in microseconds based on the date and the microseconds provided
@param {Date} [date] The date to generate the value, if not provided it will use the current date.
@param {Number} [microseconds] A number from 0 to 999 used to build the microseconds part of the date.
@returns {Long}


function MutableLong(b00, b16, b32, b48) {
  // Use an array of uint16
  this._arr = [ b00 & 0xffff, b16 & 0xffff, b32 & 0xffff, b48 & 0xffff ];
}

Constructs a signed int64 representation.
@constructor
@ignore

Constructs a signed int64 representation .


function Aggregate() {
  /**
   * Name of the aggregate.
   * @type {String}
   */
  this.name = null;
  /**
   * Name of the keyspace where the aggregate is declared.
   */
  this.keyspaceName = null;
  /**
   * Signature of the aggregate.
   * @type {Array.<String>}
   */
  this.signature = null;
  /**
   * List of the CQL aggregate argument types.
   * @type {Array.<{code, info}>}
   */
  this.argumentTypes = null;
  /**
   * State Function.
   * @type {String}
   */
  this.stateFunction = null;
  /**
   * State Type.
   * @type {{code, info}}
   */
  this.stateType = null;
  /**
   * Final Function.
   * @type {String}
   */
  this.finalFunction = null;
  this.initConditionRaw = null;
  /**
   * Initial state value of this aggregate.
   * @type {String}
   */
  this.initCondition = null;
  /**
   * Type of the return value.
   * @type {{code: number, info: (Object|Array|null)}}
   */
  this.returnType = null;
}

Creates a new Aggregate.
@classdesc Describes a CQL aggregate.
@alias module:metadata~Aggregate
@constructor


function Host(address, protocolVersion, options, metadata) {
  events.EventEmitter.call(this);
  /**
   * Gets ip address and port number of the node separated by `:`.
   * @type {String}
   */
  this.address = address;
  this.setDownAt = 0;

  /**
   * Gets the timestamp of the moment when the Host was marked as UP.
   * @type {Number|null}
   * @ignore
   * @internal
   */
  this.isUpSince = null;

  Object.defineProperty(this, 'options', { value: options, enumerable: false, writable: false});

  /**
   * The host pool.
   * @internal
   * @ignore
   * @type {HostConnectionPool}
   */
  Object.defineProperty(this, 'pool', { value: new HostConnectionPool(this, protocolVersion), enumerable: false});

  const self = this;
  this.pool.on('open', this._onNewConnectionOpen.bind(this));
  this.pool.on('remove', function onConnectionRemovedFromPool() {
    self._checkPoolState();
  });
  /**
   * Gets string containing the Cassandra version.
   * @type {String}
   */
  this.cassandraVersion = null;
  /**
   * Gets data center name of the node.
   * @type {String}
   */
  this.datacenter = null;
  /**
   * Gets rack name of the node.
   * @type {String}
   */
  this.rack = null;
  /**
   * Gets the tokens assigned to the node.
   * @type {Array}
   */
  this.tokens = null;

  /**
   * Gets the id of the host.
   *
This identifier is used by the server for internal communication / gossip.

   * @type {Uuid}
   */
  this.hostId = null;

  // the distance as last set using the load balancing policy
  this._distance = types.distance.ignored;
  this._healthResponseCounter = 0;

  // Make some of the private instance variables not enumerable to prevent from showing when inspecting
  Object.defineProperty(this, '_metadata', { value: metadata, enumerable: false });
  Object.defineProperty(this, '_healthResponseCountTimer', { value: null, enumerable: false, writable: true });

  this.reconnectionSchedule = this.options.policies.reconnection.newSchedule();
  this.reconnectionDelay = 0;
}

Creates a new Host instance.
@classdesc
Represents a Cassandra node.
@extends EventEmitter
@constructor


function ConstantSpeculativeExecutionPolicy(delay, maxSpeculativeExecutions) {
  if (!(delay >= 0)) {
    throw new errors.ArgumentError('delay must be a positive number or zero');
  }
  if (!(maxSpeculativeExecutions > 0)) {
    throw new errors.ArgumentError('maxSpeculativeExecutions must be a positive number');
  }
  this._delay = delay;
  this._maxSpeculativeExecutions = maxSpeculativeExecutions;
}

Creates a new instance of ConstantSpeculativeExecutionPolicy.
@classdesc
A {@link SpeculativeExecutionPolicy} that schedules a given number of speculative executions,
separated by a fixed delay.
@constructor
@param {Number} delay The delay between each speculative execution.
@param {Number} maxSpeculativeExecutions The amount of speculative executions that should be scheduled after the
initial execution. Must be strictly positive.
@extends {SpeculativeExecutionPolicy}

Creates a new instance of ConstantSpeculativeExecutionPolicy .


function MaterializedView(name) {
  DataCollection.call(this, name);
  /**
   * Name of the table.
   * @type {String}
   */
  this.tableName = null;
  /**
   * View where clause.
   * @type {String}
   */
  this.whereClause = null;
  /**
   * Determines if all the table columns where are included in the view.
   * @type {boolean}
   */
  this.includeAllColumns = false;
}

Creates a new MaterializedView.
@param {String} name Name of the View.
@classdesc Describes a CQL materialized view.
@alias module:metadata~MaterializedView
@augments {module:metadata~DataCollection}
@constructor


function DataCollection(name) {
  events.EventEmitter.call(this);
  this.setMaxListeners(0);
  //private
  Object.defineProperty(this, 'loading', { value: false, enumerable: false, writable: true });
  Object.defineProperty(this, 'loaded', { value: false, enumerable: false, writable: true });
  /**
   * Name of the object
   * @type {String}
   */
  this.name = name;
  /**
   * False-positive probability for SSTable Bloom filters.
   * @type {number}
   */
  this.bloomFilterFalsePositiveChance = 0;
  /**
   * Level of caching: all, keys_only, rows_only, none
   * @type {String}
   */
  this.caching = null;
  /**
   * A human readable comment describing the table.
   * @type {String}
   */
  this.comment = null;
  /**
   * Specifies the time to wait before garbage collecting tombstones (deletion markers)
   * @type {number}
   */
  this.gcGraceSeconds = 0;
  /**
   * Compaction strategy class used for the table.
   * @type {String}
   */
  this.compactionClass = null;
  /**
   * Associative-array containing the compaction options keys and values.
   * @type {Object}
   */
  this.compactionOptions = null;
  /**
   * Associative-array containing the compression options.
   * @type {Object}
   */
  this.compression = null;
  /**
   * Specifies the probability of read repairs being invoked over all replicas in the current data center.
   * @type {number}
   */
  this.localReadRepairChance = 0;
  /**
   * Specifies the probability with which read repairs should be invoked on non-quorum reads. The value must be
   * between 0 and 1.
   * @type {number}
   */
  this.readRepairChance = 0;
  /**
   * An associative Array containing extra metadata for the table.
   *

   * For Apache Cassandra versions prior to 3.0.0, this method always returns null.
   *

   * @type {Object}
   */
  this.extensions = null;
  /**
   * When compression is enabled, this option defines the probability
   * with which checksums for compressed blocks are checked during reads.
   * The default value for this options is 1.0 (always check).
   *

   *   For Apache Cassandra versions prior to 3.0.0, this method always returns null.
   *

   * @type {Number|null}
   */
  this.crcCheckChance = null;
  /**
   * Whether the populate I/O cache on flush is set on this table.
   * @type {Boolean}
   */
  this.populateCacheOnFlush = false;
  /**
   * Returns the default TTL for this table.
   * @type {Number}
   */
  this.defaultTtl = 0;
  /**
   * * Returns the speculative retry option for this table.
   * @type {String}
   */
  this.speculativeRetry = 'NONE';
  /**
   * Returns the minimum index interval option for this table.
   *

   *   Note: this option is available in Apache Cassandra 2.1 and above, and will return null for
   *   earlier versions.
   *

   * @type {Number|null}
   */
  this.minIndexInterval = 128;
  /**
   * Returns the maximum index interval option for this table.
   *

   * Note: this option is available in Apache Cassandra 2.1 and above, and will return null for
   * earlier versions.
   *

   * @type {Number|null}
   */
  this.maxIndexInterval = 2048;
  /**
   * Array describing the table columns.
   * @type {Array}
   */
  this.columns = null;
  /**
   * An associative Array of columns by name.
   * @type {Object}
   */
  this.columnsByName = null;
  /**
   * Array describing the columns that are part of the partition key.
   * @type {Array}
   */
  this.partitionKeys = [];
  /**
   * Array describing the columns that form the clustering key.
   * @type {Array}
   */
  this.clusteringKeys = [];
  /**
   * Array describing the clustering order of the columns in the same order as the clusteringKeys.
   * @type {Array}
   */
  this.clusteringOrder = [];
}

Creates a new instance of DataCollection
@param {String} name Name of the data object.
@classdesc Describes a table or a view
@alias module:metadata~DataCollection
@constructor
@abstract


async function example() {
  await client.connect();
  await client.execute(`CREATE KEYSPACE IF NOT EXISTS examples
                        WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1' }`);
  await client.execute(`USE examples`);
  await client.execute(`CREATE TABLE IF NOT EXISTS tbl_sample_kv (id uuid, value text, PRIMARY KEY (id))`);

  // The maximum amount of async executions that are going to be launched in parallel
  // at any given time
  const concurrencyLevel = 32;
  const promises = new Array(concurrencyLevel);

  const info = {
    totalLength: 10000,
    counter: 0
  };

  // Launch in parallel n async operations (n being the concurrency level)
  for (let i = 0; i < concurrencyLevel; i++) {
    promises[i] = executeOneAtATime(info);
  }

  try {
    // The n promises are going to be resolved when all the executions are completed.
    await Promise.all(promises);

    console.log(`Finished executing ${info.totalLength} queries with a concurrency level of ${concurrencyLevel}.`);

  } finally {
    client.shutdown();
  }
}

Inserts multiple rows in a table limiting the amount of parallel requests.

Note that here is a built-in method in the driver executeConcurrent() that allows you to execute
multiple simultaneous requests using an Array or a Stream. Check out execute-concurrent-array.js for more
information.

You can also use existing libraries to limit concurrency in a loop, for example:
- https://caolan.github.io/async/docs.html#eachLimit
- http://bluebirdjs.com/docs/api/promise.map.html

Inserts multiple rows in a table limiting the amount of parallel requests .


function TableMetadata(name) {
  DataCollection.call(this, name);
  /**
   * Applies only to counter tables.
   * When set to true, replicates writes to all affected replicas regardless of the consistency level specified by
   * the client for a write request. For counter tables, this should always be set to true.
   * @type {Boolean}
   */
  this.replicateOnWrite = true;
  /**
   * Returns the memtable flush period (in milliseconds) option for this table.
   * @type {Number}
   */
  this.memtableFlushPeriod = 0;
  /**
   * Returns the index interval option for this table.
   *

   * Note: this option is only available in Apache Cassandra 2.0. It is deprecated in Apache Cassandra 2.1 and
   * above, and will therefore return null for 2.1 nodes.
   *

   * @type {Number|null}
   */
  this.indexInterval = null;
  /**
   * Determines  whether the table uses the COMPACT STORAGE option.
   * @type {Boolean}
   */
  this.isCompact = false;
  /**
   *
   * @type {Array.<Index>}
   */
  this.indexes = null;

  /**
   * Determines whether the Change Data Capture (CDC) flag is set for the table.
   * @type {Boolean|null}
   */
  this.cdc = null;

  /**
   * Determines whether the table is a virtual table or not.
   * @type {Boolean}
   */
  this.virtual = false;
}

/**
   *
   * @type {Array.<Index>}
   */

Creates a new instance of TableMetadata
@classdesc Describes a table
@param {String} name Name of the Table
@augments {module:metadata~DataCollection}
@alias module:metadata~TableMetadata
@constructor


function SchemaParserV1(options, cc) {
  SchemaParser.call(this, options, cc);
  this.selectTable = _selectTableV1;
  this.selectColumns = _selectColumnsV1;
  this.selectUdt = _selectUdtV1;
  this.selectAggregates = _selectAggregatesV1;
  this.selectFunctions = _selectFunctionsV1;
}

function SchemaParserV1 ( options , cc ) { SchemaParser . call ( this , options , cc ) ; this . selectTable = _selectTableV1 ; this . selectColumns = _selectColumnsV1 ; this . selectUdt = _selectUdtV1 ; this . selectAggregates = _selectAggregatesV1 ; this . selectFunctions = _selectFunctionsV1 ; }

Used to parse schema information for Cassandra versions 1.2.x, and 2.x
@param {ClientOptions} options The client options
@param {ControlConnection} cc
@constructor
@ignore

Used to parse schema information for Cassandra versions 1 . 2 . x and 2 . x


function SchemaParserV2(options, cc, udtResolver) {
  SchemaParser.call(this, options, cc);
  this.udtResolver = udtResolver;
  this.selectTable = _selectTableV2;
  this.selectColumns = _selectColumnsV2;
  this.selectUdt = _selectUdtV2;
  this.selectAggregates = _selectAggregatesV2;
  this.selectFunctions = _selectFunctionsV2;
  this.selectIndexes = _selectIndexesV2;
}

function SchemaParserV2 ( options , cc , udtResolver ) { SchemaParser . call ( this , options , cc ) ; this . udtResolver = udtResolver ; this . selectTable = _selectTableV2 ; this . selectColumns = _selectColumnsV2 ; this . selectUdt = _selectUdtV2 ; this . selectAggregates = _selectAggregatesV2 ; this . selectFunctions = _selectFunctionsV2 ; this . selectIndexes = _selectIndexesV2 ; }

Used to parse schema information for Cassandra versions 3.x and above
@param {ClientOptions} options The client options
@param {ControlConnection} cc The control connection to be used
@param {Function} udtResolver The function to be used to retrieve the udts.
@constructor
@ignore

Used to parse schema information for Cassandra versions 3 . x and above


function SchemaParserV3(options, cc, udtResolver) {
  SchemaParserV2.call(this, options, cc, udtResolver);
  this.supportsVirtual = true;
}

function SchemaParserV3 ( options , cc , udtResolver ) { SchemaParserV2 . call ( this , options , cc , udtResolver ) ; this . supportsVirtual = true ; }

Used to parse schema information for Cassandra versions 4.x and above.

This parser similar to [SchemaParserV2] expect it also parses virtual
keyspaces.

@param {ClientOptions} options The client options
@param {ControlConnection} cc The control connection to be used
@param {Function} udtResolver The function to be used to retrieve the udts.
@constructor
@ignore

Used to parse schema information for Cassandra versions 4 . x and above .


function getByVersion(options, cc, udtResolver, version, currentInstance) {
  let parserConstructor = SchemaParserV1;
  if (version && version[0] === 3) {
    parserConstructor = SchemaParserV2;
  } else if (version && version[0] >= 4) {
    parserConstructor = SchemaParserV3;
  }
  if (!currentInstance || !(currentInstance instanceof parserConstructor)){
    return new parserConstructor(options, cc, udtResolver);
  }
  return currentInstance;
}

function getByVersion ( options , cc , udtResolver , version , currentInstance ) { let parserConstructor = SchemaParserV1 ; if ( version && version [ 0 ] === 3 ) { parserConstructor = SchemaParserV2 ; } else if ( version && version [ 0 ] >= 4 ) { parserConstructor = SchemaParserV3 ; } if ( ! currentInstance || ! ( currentInstance instanceof parserConstructor ) ) { return new parserConstructor ( options , cc , udtResolver ) ; } return currentInstance ; }

Creates a new instance if the currentInstance is not valid for the
provided Cassandra version
@param {ClientOptions} options The client options
@param {ControlConnection} cc The control connection to be used
@param {Function} udtResolver The function to be used to retrieve the udts.
@param {Array.<Number>} [version] The cassandra version
@param {SchemaParser} [currentInstance] The current instance
@returns {SchemaParser}


function encodeRoutingKey(fromUser) {
    const encoder = self._getEncoder();
    try {
      if (fromUser) {
        encoder.setRoutingKeyFromUser(params, execOptions);
      } else {
        encoder.setRoutingKeyFromMeta(meta, params, execOptions);
      }
    }
    catch (err) {
      return callback(err);
    }
    callback();
  }

function encodeRoutingKey ( fromUser ) { const encoder = self . _getEncoder ( ) ; try { if ( fromUser ) { encoder . setRoutingKeyFromUser ( params , execOptions ) ; } else { encoder . setRoutingKeyFromMeta ( meta , params , execOptions ) ; } } catch ( err ) { return callback ( err ) ; } callback ( ) ; }

Wrapper function as encoding a routing key could throw a TypeError


function getJsFiles(dir, fileArray) {
  const files = fs.readdirSync(dir);
  fileArray = fileArray || [];
  files.forEach(function(file) {
    if (file === 'node_modules') {
      return;
    }
    if (fs.statSync(dir + file).isDirectory()) {
      getJsFiles(dir + file + '/', fileArray);
      return;
    }
    if (file.substring(file.length-3, file.length) !== '.js') {
      return;
    }
    fileArray.push(dir+file);
  });
  return fileArray;
}

function getJsFiles ( dir , fileArray ) { const files = fs . readdirSync ( dir ) ; fileArray = fileArray || [ ] ; files . forEach ( function ( file ) { if ( file === 'node_modules' ) { return ; } if ( fs . statSync ( dir + file ) . isDirectory ( ) ) { getJsFiles ( dir + file + '/' , fileArray ) ; return ; } if ( file . substring ( file . length - 3 , file . length ) !== '.js' ) { return ; } fileArray . push ( dir + file ) ; } ) ; return fileArray ; }

This script is used to check that the samples run correctly.
It is not a valid example, see README.md and subdirectories for more information.
 List all js files in the directory

This script is used to check that the samples run correctly . It is not a valid example see README . md and subdirectories for more information . List all js files in the directory


function SchemaFunction() {
  /**
   * Name of the cql function.
   * @type {String}
   */
  this.name = null;
  /**
   * Name of the keyspace where the cql function is declared.
   */
  this.keyspaceName = null;
  /**
   * Signature of the function.
   * @type {Array.<String>}
   */
  this.signature = null;
  /**
   * List of the function argument names.
   * @type {Array.<String>}
   */
  this.argumentNames = null;
  /**
   * List of the function argument types.
   * @type {Array.<{code, info}>}
   */
  this.argumentTypes = null;
  /**
   * Body of the function.
   * @type {String}
   */
  this.body = null;
  /**
   * Determines if the function is called when the input is null.
   * @type {Boolean}
   */
  this.calledOnNullInput = null;
  /**
   * Name of the programming language, for example: java, javascript, ...
   * @type {String}
   */
  this.language = null;
  /**
   * Type of the return value.
   * @type {{code: number, info: (Object|Array|null)}}
   */
  this.returnType = null;
}

Creates a new SchemaFunction.
@classdesc Describes a CQL function.
@alias module:metadata~SchemaFunction
@constructor


function copyBuffer(buf) {
  const targetBuffer = allocBufferUnsafe(buf.length);
  buf.copy(targetBuffer);
  return targetBuffer;
}

function copyBuffer ( buf ) { const targetBuffer = allocBufferUnsafe ( buf . length ) ; buf . copy ( targetBuffer ) ; return targetBuffer ; }


function fixStack(stackTrace, error) {
  if (stackTrace) {
    error.stack += '\n  (event loop)\n' + stackTrace.substr(stackTrace.indexOf("\n") + 1);
  }
  return error;
}

function
fixStack
(
stackTrace
,
error
)
{
if
(
stackTrace
)
{
error
.
stack
+=
'\n  (event loop)\n'
+
stackTrace
.
substr
(
stackTrace
.
indexOf
(
"\n"
)
+
1
)
;
}
return
error
;
}

Appends the original stack trace to the error after a tick of the event loop


function log(type, info, furtherInfo) {
  if (!this.logEmitter) {
    if (!this.options || !this.options.logEmitter) {
      throw new Error('Log emitter not defined');
    }
    this.logEmitter = this.options.logEmitter;
  }
  this.logEmitter('log', type, this.constructor.name, info, furtherInfo || '');
}

function
log
(
type
,
info
,
furtherInfo
)
{
if
(
!
this
.
logEmitter
)
{
if
(
!
this
.
options
||
!
this
.
options
.
logEmitter
)
{
throw
new
Error
(
'Log emitter not defined'
)
;
}
this
.
logEmitter
=
this
.
options
.
logEmitter
;
}
this
.
logEmitter
(
'log'
,
type
,
this
.
constructor
.
name
,
info
,
furtherInfo
||
''
)
;
}

Uses the logEmitter to emit log events
@param {String} type
@param {String} info
@param [furtherInfo]


function toLowerCaseProperties(obj) {
  const keys = Object.keys(obj);
  const result = {};
  for (let i = 0; i < keys.length; i++) {
    const k = keys[i];
    result[k.toLowerCase()] = obj[k];
  }
  return result;
}

function toLowerCaseProperties ( obj ) { const keys = Object . keys ( obj ) ; const result = { } ; for ( let i = 0 ; i < keys . length ; i ++ ) { const k = keys [ i ] ; result [ k . toLowerCase ( ) ] = obj [ k ] ; } return result ; }

Returns a new object with the property names set to lowercase.

Returns a new object with the property names set to lowercase .


function deepExtend(target) {
  const sources = Array.prototype.slice.call(arguments, 1);
  sources.forEach(function (source) {
    for (const prop in source) {
      if (!source.hasOwnProperty(prop)) {
        continue;
      }
      const targetProp = target[prop];
      const targetType = (typeof targetProp);
      //target prop is
      // a native single type
      // or not existent
      // or is not an anonymous object (not class instance)
      if (!targetProp ||
        targetType === 'number' ||
        targetType === 'string' ||
        util.isArray(targetProp) ||
        util.isDate(targetProp) ||
        targetProp.constructor.name !== 'Object') {
        target[prop] = source[prop];
      }
      else {
        //inner extend
        target[prop] = deepExtend({}, targetProp, source[prop]);
      }
    }
  });
  return target;
}

Extends the target by the most inner props of sources
@param {Object} target
@returns {Object}


function arrayIterator (arr) {
  let index = 0;
  return { next : function () {
    if (index >= arr.length) {
      return {done: true};
    }
    return {value: arr[index++], done: false };
  }};
}

function arrayIterator ( arr ) { let index = 0 ; return { next : function ( ) { if ( index >= arr . length ) { return { done : true } ; } return { value : arr [ index ++ ] , done : false } ; } } ; }

Uses the iterator protocol to go through the items of the Array
@param arr
@returns {{next: function}}


function iteratorToArray(iterator) {
  const values = [];
  let item = iterator.next();
  while (!item.done) {
    values.push(item.value);
    item = iterator.next();
  }
  return values;
}

function iteratorToArray ( iterator ) { const values = [ ] ; let item = iterator . next ( ) ; while ( ! item . done ) { values . push ( item . value ) ; item = iterator . next ( ) ; } return values ; }

Convert the iterator values into an array
@param iterator
@returns {Array}


function binarySearch(arr, key, compareFunc) {
  let low = 0;
  let high = arr.length-1;

  while (low <= high) {
    const mid = (low + high) >>> 1;
    const midVal = arr[mid];
    const cmp = compareFunc(midVal, key);
    if (cmp < 0) {
      low = mid + 1;
    }
    else if (cmp > 0) {
      high = mid - 1;
    }
    else
    {
      //The key was found in the Array
      return mid;
    }
  }
  // key not found
  return ~low;
}

function
binarySearch
(
arr
,
key
,
compareFunc
)
{
let
low
=
0
;
let
high
=
arr
.
length
1
;
while
(
low
<=
high
)
{
const
mid
=
(
low
+
high
)
>>>
1
;
const
midVal
=
arr
[
mid
]
;
const
cmp
=
compareFunc
(
midVal
,
key
)
;
if
(
cmp
<
0
)
{
low
=
mid
+
1
;
}
else
if
(
cmp
>
0
)
{
high
=
mid
1
;
}
else
{
//The key was found in the Array
return
mid
;
}
}
// key not found
return
~
low
;
}

Searches the specified Array for the provided key using the binary
search algorithm.  The Array must be sorted.
@param {Array} arr
@param key
@param {function} compareFunc
@returns {number} The position of the key in the Array, if it is found.
If it is not found, it returns a negative number which is the bitwise complement of the index of the first element that is larger than key.

Searches the specified Array for the provided key using the binary search algorithm . The Array must be sorted .


function insertSorted(arr, item, compareFunc) {
  if (arr.length === 0) {
    return arr.push(item);
  }
  let position = binarySearch(arr, item, compareFunc);
  if (position < 0) {
    position = ~position;
  }
  arr.splice(position, 0, item);
}

function insertSorted ( arr , item , compareFunc ) { if ( arr . length === 0 ) { return arr . push ( item ) ; } let position = binarySearch ( arr , item , compareFunc ) ; if ( position < 0 ) { position = ~ position ; } arr . splice ( position , 0 , item ) ; }

Inserts the value in the position determined by its natural order determined by the compare func
@param {Array} arr
@param item
@param {function} compareFunc


function validateFn(fn, name) {
  if (typeof fn !== 'function') {
    throw new errors.ArgumentError(util.format('%s is not a function', name || 'callback'));
  }
  return fn;
}

function
validateFn
(
fn
,
name
)
{
if
(
typeof
fn
!==
'function'
)
{
throw
new
errors
.
ArgumentError
(
util
.
format
(
'%s is not a function'
,
name
||
'callback'
)
)
;
}
return
fn
;
}

Validates the provided parameter is of type function.
@param {Function} fn The instance to validate.
@param {String} [name] Name of the function to use in the error message. Defaults to 'callback'.
@returns {Function}

Validates the provided parameter is of type function .


function stringRepeat(val, times) {
  if (!times || times < 0) {
    return null;
  }
  if (times === 1) {
    return val;
  }
  return new Array(times + 1).join(val);
}

function stringRepeat ( val , times ) { if ( ! times || times < 0 ) { return null ; } if ( times === 1 ) { return val ; } return new Array ( times + 1 ) . join ( val ) ; }

Returns a string with a value repeated n times
@param {String} val
@param {Number} times
@returns {String}


function promiseWrapper(options, originalCallback, handler) {
  if (typeof originalCallback === 'function') {
    // Callback-based invocation
    handler.call(this, originalCallback);
    return undefined;
  }
  const factory = options.promiseFactory || defaultPromiseFactory;
  const self = this;
  return factory(function handlerWrapper(callback) {
    handler.call(self, callback);
  });
}

function
promiseWrapper
(
options
,
originalCallback
,
handler
)
{
if
(
typeof
originalCallback
===
'function'
)
{
// Callback-based invocation
handler
.
call
(
this
,
originalCallback
)
;
return
undefined
;
}
const
factory
=
options
.
promiseFactory
||
defaultPromiseFactory
;
const
self
=
this
;
return
factory
(
function
handlerWrapper
(
callback
)
{
handler
.
call
(
self
,
callback
)
;
}
)
;
}

Wraps the callback-based method. When no originalCallback is not defined, it returns a Promise.
@param {ClientOptions} options
@param {Function} originalCallback
@param {Function} handler
@returns {Promise|undefined}

Wraps the callback - based method . When no originalCallback is not defined it returns a Promise .


function WhiteListPolicy (childPolicy, whiteList) {
  if (!childPolicy) {
    throw new Error("You must specify a child load balancing policy");
  }
  if (!util.isArray(whiteList)) {
    throw new Error("You must provide the white list of host addresses");
  }
  this.childPolicy = childPolicy;
  const map = {};
  whiteList.forEach(function (address) {
    map[address] = true;
  });
  this.whiteList = map;
}

Create a new policy that wraps the provided child policy but only "allow" hosts
from the provided while list.
@class
@classdesc
A load balancing policy wrapper that ensure that only hosts from a provided
white list will ever be returned.

This policy wraps another load balancing policy and will delegate the choice
of hosts to the wrapped policy with the exception that only hosts contained
in the white list provided when constructing this policy will ever be
returned. Any host not in the while list will be considered ignored
and thus will not be connected to.

This policy can be useful to ensure that the driver only connects to a
predefined set of hosts. Keep in mind however that this policy defeats
somewhat the host auto-detection of the driver. As such, this policy is only
useful in a few special cases or for testing, but is not optimal in general.
If all you want to do is limiting connections to hosts of the local
data-center then you should use DCAwareRoundRobinPolicy and *not* this policy
in particular.
@param {LoadBalancingPolicy} childPolicy the wrapped policy.
@param {Array.<string>}  whiteList the white listed hosts address in the format ipAddress:port.
Only hosts from this list may get connected
to (whether they will get connected to or not depends on the child policy).
@extends LoadBalancingPolicy
@constructor

Create a new policy that wraps the provided child policy but only allow hosts from the provided while list .


function EventDebouncer(delay, logger) {
  this._delay = delay;
  this._logger = logger;
  this._queue = null;
  this._timeout = null;
}

function EventDebouncer ( delay , logger ) { this . _delay = delay ; this . _logger = logger ; this . _queue = null ; this . _timeout = null ; }

Debounce protocol events by acting on those events with a sliding delay.
@param {Number} delay
@param {Function} logger
@ignore
@constructor

Debounce protocol events by acting on those events with a sliding delay .


function FrameReader(header, body, offset) {
  this.header = header;
  this.opcode = header.opcode;
  this.offset = offset || 0;
  this.buf = body;
}

function FrameReader ( header , body , offset ) { this . header = header ; this . opcode = header . opcode ; this . offset = offset || 0 ; this . buf = body ; }

Buffer forward reader of CQL binary frames
@param {FrameHeader} header
@param {Buffer} body
@param {Number} [offset]


function Connection(endpoint, protocolVersion, options) {
  events.EventEmitter.call(this);
  this.setMaxListeners(0);

  if (!options) {
    throw new Error('options is not defined');
  }

  /**
   * Gets the ip and port of the server endpoint.
   * @type {String}
   */
  this.endpoint = endpoint;

  /**
   * Gets the friendly name of the host, used to identify the connection in log messages.
   * With direct connect, this is the address and port.
   * @type {String}
   */
  this.endpointFriendlyName = endpoint;

  if (!this.endpoint || this.endpoint.indexOf(':') < 0) {
    throw new Error('EndPoint must contain the ip address and port separated by : symbol');
  }

  const portSeparatorIndex = this.endpoint.lastIndexOf(':');
  this.address = this.endpoint.substr(0, portSeparatorIndex);
  this.port = this.endpoint.substr(portSeparatorIndex + 1);

  Object.defineProperty(this, "options", { value: options, enumerable: false, writable: false});

  if (protocolVersion === null) {
    // Set initial protocol version
    protocolVersion = types.protocolVersion.maxSupported;
    if (options.protocolOptions.maxVersion) {
      // User provided the protocol version
      protocolVersion = options.protocolOptions.maxVersion;
    }
    // Allow to check version using this connection instance
    this._checkingVersion = true;
  }

  this.protocolVersion = protocolVersion;
  /** @type {Object.<String, OperationState>} */
  this._operations = {};
  this._pendingWrites = [];
  this._preparing = {};

  /**
   * The timeout state for the idle request (heartbeat)
   */
  this._idleTimeout = null;
  this.timedOutOperations = 0;
  this._streamIds = new StreamIdStack(this.protocolVersion);
  this._metrics = options.metrics;

  this.encoder = new Encoder(protocolVersion, options);
  this.keyspace = null;
  this.emitDrain = false;
  /**
   * Determines if the socket is open and startup succeeded, whether the connection can be used to send requests /
   * receive events
   */
  this.connected = false;
  /**
   * Determines if the socket can be considered as open
   */
  this.isSocketOpen = false;
}

Represents a connection to a Cassandra node
@param {String} endpoint An string containing ip address and port of the host
@param {Number|null} protocolVersion
@param {ClientOptions} options
@extends EventEmitter
@constructor


function getClockId(clockId) {
  let buffer = clockId;
  if (typeof clockId === 'string') {
    buffer = utils.allocBufferFromString(clockId, 'ascii');
  }
  if (!(buffer instanceof Buffer)) {
    //Generate
    buffer = getRandomBytes(2);
  }
  else if (buffer.length !== 2) {
    throw new Error('Clock identifier must have 2 bytes');
  }
  return buffer;
}

function
getClockId
(
clockId
)
{
let
buffer
=
clockId
;
if
(
typeof
clockId
===
'string'
)
{
buffer
=
utils
.
allocBufferFromString
(
clockId
,
'ascii'
)
;
}
if
(
!
(
buffer
instanceof
Buffer
)
)
{
//Generate
buffer
=
getRandomBytes
(
2
)
;
}
else
if
(
buffer
.
length
!==
2
)
{
throw
new
Error
(
'Clock identifier must have 2 bytes'
)
;
}
return
buffer
;
}

Returns a buffer of length 2 representing the clock identifier
@param {String|Buffer} clockId
@returns {Buffer}
@private


function getNodeId(nodeId) {
  let buffer = nodeId;
  if (typeof nodeId === 'string') {
    buffer = utils.allocBufferFromString(nodeId, 'ascii');
  }
  if (!(buffer instanceof Buffer)) {
    //Generate
    buffer = getRandomBytes(6);
  }
  else if (buffer.length !== 6) {
    throw new Error('Node identifier must have 6 bytes');
  }
  return buffer;
}

function
getNodeId
(
nodeId
)
{
let
buffer
=
nodeId
;
if
(
typeof
nodeId
===
'string'
)
{
buffer
=
utils
.
allocBufferFromString
(
nodeId
,
'ascii'
)
;
}
if
(
!
(
buffer
instanceof
Buffer
)
)
{
//Generate
buffer
=
getRandomBytes
(
6
)
;
}
else
if
(
buffer
.
length
!==
6
)
{
throw
new
Error
(
'Node identifier must have 6 bytes'
)
;
}
return
buffer
;
}

Returns a buffer of length 6 representing the clock identifier
@param {String|Buffer} nodeId
@returns {Buffer}
@private


function getTicks(ticks) {
  if (typeof ticks !== 'number'|| ticks >= _ticksInMs) {
    _ticks++;
    if (_ticks >= _ticksInMs) {
      _ticks = 0;
    }
    ticks = _ticks;
  }
  return ticks;
}

function getTicks ( ticks ) { if ( typeof ticks !== 'number' || ticks >= _ticksInMs ) { _ticks ++ ; if ( _ticks >= _ticksInMs ) { _ticks = 0 ; } ticks = _ticks ; } return ticks ; }

Returns the ticks portion of a timestamp.  If the ticks are not provided an internal counter is used that gets reset at 10000.
@private
@param {Number} [ticks]
@returns {Number}

Returns the ticks portion of a timestamp . If the ticks are not provided an internal counter is used that gets reset at 10000 .


function getTimeWithTicks(date, ticks) {
  if (!(date instanceof Date) || isNaN(date.getTime())) {
    // time with ticks for the current time
    date = new Date();
    const time = date.getTime();
    _ticksForCurrentTime++;
    if(_ticksForCurrentTime > _ticksInMs || time > _lastTimestamp) {
      _ticksForCurrentTime = 0;
      _lastTimestamp = time;
    }
    ticks = _ticksForCurrentTime;
  }
  return {
    time: date.getTime(),
    ticks: getTicks(ticks)
  };
}

function
getTimeWithTicks
(
date
,
ticks
)
{
if
(
!
(
date
instanceof
Date
)
||
isNaN
(
date
.
getTime
(
)
)
)
{
// time with ticks for the current time
date
=
new
Date
(
)
;
const
time
=
date
.
getTime
(
)
;
_ticksForCurrentTime
++
;
if
(
_ticksForCurrentTime
>
_ticksInMs
||
time
>
_lastTimestamp
)
{
_ticksForCurrentTime
=
0
;
_lastTimestamp
=
time
;
}
ticks
=
_ticksForCurrentTime
;
}
return
{
time
:
date
.
getTime
(
)
,
ticks
:
getTicks
(
ticks
)
}
;
}

Returns an object with the time representation of the date expressed in milliseconds since unix epoch
and a ticks property for the 100-nanoseconds precision.
@private
@returns {{time: Number, ticks: Number}}

Returns an object with the time representation of the date expressed in milliseconds since unix epoch and a ticks property for the 100 - nanoseconds precision .


function generateBuffer(date, ticks, nodeId, clockId) {
  const timeWithTicks = getTimeWithTicks(date, ticks);
  nodeId = getNodeId(nodeId);
  clockId = getClockId(clockId);
  const buffer = utils.allocBufferUnsafe(16);
  //Positions 0-7 Timestamp
  writeTime(buffer, timeWithTicks.time, timeWithTicks.ticks);
  //Position 8-9 Clock
  clockId.copy(buffer, 8, 0);
  //Positions 10-15 Node
  nodeId.copy(buffer, 10, 0);
  //Version Byte: Time based
  //0001xxxx
  //turn off first 4 bits
  buffer[6] = buffer[6] & 0x0f;
  //turn on fifth bit
  buffer[6] = buffer[6] | 0x10;

  //IETF Variant Byte: 1.0.x
  //10xxxxxx
  //turn off first 2 bits
  buffer[8] = buffer[8] & 0x3f;
  //turn on first bit
  buffer[8] = buffer[8] | 0x80;
  return buffer;
}

function
generateBuffer
(
date
,
ticks
,
nodeId
,
clockId
)
{
const
timeWithTicks
=
getTimeWithTicks
(
date
,
ticks
)
;
nodeId
=
getNodeId
(
nodeId
)
;
clockId
=
getClockId
(
clockId
)
;
const
buffer
=
utils
.
allocBufferUnsafe
(
16
)
;
//Positions 0-7 Timestamp
writeTime
(
buffer
,
timeWithTicks
.
time
,
timeWithTicks
.
ticks
)
;
//Position 8-9 Clock
clockId
.
copy
(
buffer
,
8
,
0
)
;
//Positions 10-15 Node
nodeId
.
copy
(
buffer
,
10
,
0
)
;
//Version Byte: Time based
//0001xxxx
//turn off first 4 bits
buffer
[
6
]
=
buffer
[
6
]
&
0x0f
;
//turn on fifth bit
buffer
[
6
]
=
buffer
[
6
]
|
0x10
;
//IETF Variant Byte: 1.0.x
//10xxxxxx
//turn off first 2 bits
buffer
[
8
]
=
buffer
[
8
]
&
0x3f
;
//turn on first bit
buffer
[
8
]
=
buffer
[
8
]
|
0x80
;
return
buffer
;
}

Generates a 16-length Buffer instance
@private
@param {Date} date
@param {Number} ticks
@param {String|Buffer} nodeId
@param {String|Buffer} clockId
@returns {Buffer}


function Encoder(protocolVersion, options) {
  this.encodingOptions = options.encoding || utils.emptyObject;
  defineInstanceMembers.call(this);
  this.setProtocolVersion(protocolVersion);
  setEncoders.call(this);
  if (this.encodingOptions.copyBuffer) {
    this.handleBuffer = handleBufferCopy;
  }
  else {
    this.handleBuffer = handleBufferRef;
  }
}

function Encoder ( protocolVersion , options ) { this . encodingOptions = options . encoding || utils . emptyObject ; defineInstanceMembers . call ( this ) ; this . setProtocolVersion ( protocolVersion ) ; setEncoders . call ( this ) ; if ( this . encodingOptions . copyBuffer ) { this . handleBuffer = handleBufferCopy ; } else { this . handleBuffer = handleBufferRef ; } }

Serializes and deserializes to and from a CQL type and a Javascript Type.
@param {Number} protocolVersion
@param {ClientOptions} options
@constructor

Serializes and deserializes to and from a CQL type and a Javascript Type .


Returns the number of zero bits preceding the highest-order one-bit in the binary representation of the value.
@param {Long} value
@returns {Number}

Returns the number of zero bits preceding the highest - order one - bit in the binary representation of the value .


function Index(name, target, kind, options) {
  /**
   * Name of the index.
   * @type {String}
   */
  this.name = name;
  /**
   * Target of the index.
   * @type {String}
   */
  this.target = target;
  /**
   * A numeric value representing index kind (0: custom, 1: keys, 2: composite);
   * @type {Number}
   */
  this.kind = typeof kind === 'string' ? getKindByName(kind) : kind;
  /**
   * An associative array containing the index options
   * @type {Object}
   */
  this.options = options;
}

Creates a new Index instance.
@classdesc Describes a CQL index.
@param {String} name
@param {String} target
@param {Number|String} kind
@param {Object} options
@alias module:metadata~Index
@constructor


function (key) {
        return _.sortBy(files, function (el) {
            return Number($(el).find('span[data-lint]').attr(key)) * -1;
        });
    }

function ( key ) { return _ . sortBy ( files , function ( el ) { return Number ( $ ( el ) . find ( 'span[data-lint]' ) . attr ( key ) ) * - 1 ; } ) ; }

work-horse @param:  key  The 'data-<key>' to sort by @return: descending sorted array of <li> elements


function loadMode(cm) {
    var doc = cm.view.doc;
    cm.view.mode = CodeMirror.getMode(cm.options, cm.options.mode);
    doc.iter(0, doc.size, function(line) { line.stateAfter = null; });
    cm.view.frontier = 0;
    startWorker(cm, 100);
  }

function loadMode ( cm ) { var doc = cm . view . doc ; cm . view . mode = CodeMirror . getMode ( cm . options , cm . options . mode ) ; doc . iter ( 0 , doc . size , function ( line ) { line . stateAfter = null ; } ) ; cm . view . frontier = 0 ; startWorker ( cm , 100 ) ; }

STATE UPDATES Used to get the editor into a consistent state again when options change.

STATE UPDATES Used to get the editor into a consistent state again when options change .


function updateScrollbars(d /* display */, docHeight) {
    var totalHeight = docHeight + 2 * paddingTop(d);
    d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px";
    var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight);
    var needsH = d.scroller.scrollWidth > d.scroller.clientWidth;
    var needsV = scrollHeight > d.scroller.clientHeight;
    if (needsV) {
      d.scrollbarV.style.display = "block";
      d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0";
      d.scrollbarV.firstChild.style.height =
        (scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px";
    } else d.scrollbarV.style.display = "";
    if (needsH) {
      d.scrollbarH.style.display = "block";
      d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0";
      d.scrollbarH.firstChild.style.width =
        (d.scroller.scrollWidth - d.scroller.clientWidth + d.scrollbarH.clientWidth) + "px";
    } else d.scrollbarH.style.display = "";
    if (needsH && needsV) {
      d.scrollbarFiller.style.display = "block";
      d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px";
    } else d.scrollbarFiller.style.display = "";

    if (mac_geLion && scrollbarWidth(d.measure) === 0)
      d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px";
  }

function
updateScrollbars
(
d
/* display */
,
docHeight
)
{
var
totalHeight
=
docHeight
+
2
*
paddingTop
(
d
)
;
d
.
sizer
.
style
.
minHeight
=
d
.
heightForcer
.
style
.
top
=
totalHeight
+
"px"
;
var
scrollHeight
=
Math
.
max
(
totalHeight
,
d
.
scroller
.
scrollHeight
)
;
var
needsH
=
d
.
scroller
.
scrollWidth
>
d
.
scroller
.
clientWidth
;
var
needsV
=
scrollHeight
>
d
.
scroller
.
clientHeight
;
if
(
needsV
)
{
d
.
scrollbarV
.
style
.
display
=
"block"
;
d
.
scrollbarV
.
style
.
bottom
=
needsH
scrollbarWidth
(
d
.
measure
)
+
"px"
:
"0"
;
d
.
scrollbarV
.
firstChild
.
style
.
height
=
(
scrollHeight
d
.
scroller
.
clientHeight
+
d
.
scrollbarV
.
clientHeight
)
+
"px"
;
}
else
d
.
scrollbarV
.
style
.
display
=
""
;
if
(
needsH
)
{
d
.
scrollbarH
.
style
.
display
=
"block"
;
d
.
scrollbarH
.
style
.
right
=
needsV
scrollbarWidth
(
d
.
measure
)
+
"px"
:
"0"
;
d
.
scrollbarH
.
firstChild
.
style
.
width
=
(
d
.
scroller
.
scrollWidth
d
.
scroller
.
clientWidth
+
d
.
scrollbarH
.
clientWidth
)
+
"px"
;
}
else
d
.
scrollbarH
.
style
.
display
=
""
;
if
(
needsH
&&
needsV
)
{
d
.
scrollbarFiller
.
style
.
display
=
"block"
;
d
.
scrollbarFiller
.
style
.
height
=
d
.
scrollbarFiller
.
style
.
width
=
scrollbarWidth
(
d
.
measure
)
+
"px"
;
}
else
d
.
scrollbarFiller
.
style
.
display
=
""
;
if
(
mac_geLion
&&
scrollbarWidth
(
d
.
measure
)
===
0
)
d
.
scrollbarV
.
style
.
minWidth
=
d
.
scrollbarH
.
style
.
minHeight
=
mac_geMountainLion
"18px"
:
"12px"
;
}

Re-synchronize the fake scrollbars with the actual size of the content. Optionally force a scrollTop.

Re - synchronize the fake scrollbars with the actual size of the content . Optionally force a scrollTop .


function restartBlink(cm) {
    var display = cm.display;
    clearInterval(display.blinker);
    var on = true;
    display.cursor.style.visibility = display.otherCursor.style.visibility = "";
    display.blinker = setInterval(function() {
      if (!display.cursor.offsetHeight) return;
      display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden";
    }, cm.options.cursorBlinkRate);
  }

function restartBlink ( cm ) { var display = cm . display ; clearInterval ( display . blinker ) ; var on = true ; display . cursor . style . visibility = display . otherCursor . style . visibility = "" ; display . blinker = setInterval ( function ( ) { if ( ! display . cursor . offsetHeight ) return ; display . cursor . style . visibility = display . otherCursor . style . visibility = ( on = ! on ) ? "" : "hidden" ; } , cm . options . cursorBlinkRate ) ; }


function coordsChar(cm, x, y) {
    var doc = cm.view.doc;
    y += cm.display.viewOffset;
    if (y < 0) return {line: 0, ch: 0, outside: true};
    var lineNo = lineAtHeight(doc, y);
    if (lineNo >= doc.size) return {line: doc.size - 1, ch: getLine(doc, doc.size - 1).text.length};
    if (x < 0) x = 0;

    for (;;) {
      var lineObj = getLine(doc, lineNo);
      var found = coordsCharInner(cm, lineObj, lineNo, x, y);
      var merged = collapsedSpanAtEnd(lineObj);
      if (merged && found.ch == lineRight(lineObj))
        lineNo = merged.find().to.line;
      else
        return found;
    }
  }

function coordsChar ( cm , x , y ) { var doc = cm . view . doc ; y += cm . display . viewOffset ; if ( y < 0 ) return { line : 0 , ch : 0 , outside : true } ; var lineNo = lineAtHeight ( doc , y ) ; if ( lineNo >= doc . size ) return { line : doc . size - 1 , ch : getLine ( doc , doc . size - 1 ) . text . length } ; if ( x < 0 ) x = 0 ; for ( ; ; ) { var lineObj = getLine ( doc , lineNo ) ; var found = coordsCharInner ( cm , lineObj , lineNo , x , y ) ; var merged = collapsedSpanAtEnd ( lineObj ) ; if ( merged && found . ch == lineRight ( lineObj ) ) lineNo = merged . find ( ) . to . line ; else return found ; } }


function updateDoc(cm, from, to, newText, selUpdate, origin) {
    // Possibly split or suppress the update based on the presence
    // of read-only spans in its range.
    var split = sawReadOnlySpans &&
      removeReadOnlyRanges(cm.view.doc, from, to);
    if (split) {
      for (var i = split.length - 1; i >= 1; --i)
        updateDocInner(cm, split[i].from, split[i].to, [""], origin);
      if (split.length)
        return updateDocInner(cm, split[0].from, split[0].to, newText, selUpdate, origin);
    } else {
      return updateDocInner(cm, from, to, newText, selUpdate, origin);
    }
  }

Replace the range from from to to by the strings in newText. Afterwards, set the selection to selFrom, selTo.

Replace the range from from to to by the strings in newText . Afterwards set the selection to selFrom selTo .


function setSelection(cm, anchor, head, bias, checkAtomic) {
    cm.view.goalColumn = null;
    var sel = cm.view.sel;
    // Skip over atomic spans.
    if (checkAtomic || !posEq(anchor, sel.anchor))
      anchor = skipAtomic(cm, anchor, bias, checkAtomic != "push");
    if (checkAtomic || !posEq(head, sel.head))
      head = skipAtomic(cm, head, bias, checkAtomic != "push");

    if (posEq(sel.anchor, anchor) && posEq(sel.head, head)) return;

    sel.anchor = anchor; sel.head = head;
    var inv = posLess(head, anchor);
    sel.from = inv ? head : anchor;
    sel.to = inv ? anchor : head;

    cm.curOp.updateInput = true;
    cm.curOp.selectionChanged = true;
  }

function
setSelection
(
cm
,
anchor
,
head
,
bias
,
checkAtomic
)
{
cm
.
view
.
goalColumn
=
;
var
sel
=
cm
.
view
.
sel
;
// Skip over atomic spans.
if
(
checkAtomic
||
!
posEq
(
anchor
,
sel
.
anchor
)
)
anchor
=
skipAtomic
(
cm
,
anchor
,
bias
,
checkAtomic
!=
"push"
)
;
if
(
checkAtomic
||
!
posEq
(
head
,
sel
.
head
)
)
head
=
skipAtomic
(
cm
,
head
,
bias
,
checkAtomic
!=
"push"
)
;
if
(
posEq
(
sel
.
anchor
,
anchor
)
&&
posEq
(
sel
.
head
,
head
)
)
return
;
sel
.
anchor
=
anchor
;
sel
.
head
=
head
;
var
inv
=
posLess
(
head
,
anchor
)
;
sel
.
from
=
inv
head
:
anchor
;
sel
.
to
=
inv
anchor
:
head
;
cm
.
curOp
.
updateInput
=
true
;
cm
.
curOp
.
selectionChanged
=
true
;
}

Update the selection. Last two args are only used by updateDoc, since they have to be expressed in the line numbers before the update.

Update the selection . Last two args are only used by updateDoc since they have to be expressed in the line numbers before the update .


function highlightLine(cm, line, state) {
    var mode = cm.view.mode, flattenSpans = cm.options.flattenSpans;
    var changed = !line.styles, pos = 0, curText = "", curStyle = null;
    var stream = new StringStream(line.text, cm.options.tabSize), st = line.styles || (line.styles = []);
    if (line.text == "" && mode.blankLine) mode.blankLine(state);
    while (!stream.eol()) {
      var style = mode.token(stream, state), substr = stream.current();
      stream.start = stream.pos;
      if (!flattenSpans || curStyle != style) {
        if (curText) {
          changed = changed || pos >= st.length || curText != st[pos] || curStyle != st[pos+1];
          st[pos++] = curText; st[pos++] = curStyle;
        }
        curText = substr; curStyle = style;
      } else curText = curText + substr;
      // Give up when line is ridiculously long
      if (stream.pos > 5000) break;
    }
    if (curText) {
      changed = changed || pos >= st.length || curText != st[pos] || curStyle != st[pos+1];
      st[pos++] = curText; st[pos++] = curStyle;
    }
    if (stream.pos > 5000) { st[pos++] = line.text.slice(stream.pos); st[pos++] = null; }
    if (pos != st.length) { st.length = pos; changed = true; }
    return changed;
  }

Run the given mode's parser over a line, update the styles array, which contains alternating fragments of text and CSS classes.

Run the given mode s parser over a line update the styles array which contains alternating fragments of text and CSS classes .


function e_prop(e, prop) {
    var overridden = e.override && e.override.hasOwnProperty(prop);
    return overridden ? e.override[prop] : e[prop];
  }

function e_prop ( e , prop ) { var overridden = e . override && e . override . hasOwnProperty ( prop ) ; return overridden ? e . override [ prop ] : e [ prop ] ; }

Allow 3rd-party code to override event properties by adding an override object to an event object.

Allow 3rd - party code to override event properties by adding an override object to an event object .


function Flow(opts) {
    /**
     * Supported by browser?
     * @type {boolean}
     */
    this.support = (
        typeof File !== 'undefined' &&
        typeof Blob !== 'undefined' &&
        typeof FileList !== 'undefined' &&
        (
          !!Blob.prototype.slice || !!Blob.prototype.webkitSlice || !!Blob.prototype.mozSlice ||
          false
        ) // slicing files support
    );

    if (!this.support) {
      return ;
    }

    /**
     * Check if directory upload is supported
     * @type {boolean}
     */
    this.supportDirectory = (
        /Chrome/.test(window.navigator.userAgent) ||
        /Firefox/.test(window.navigator.userAgent) ||
        /Edge/.test(window.navigator.userAgent)
    );

    /**
     * List of FlowFile objects
     * @type {Array.<FlowFile>}
     */
    this.files = [];

    /**
     * Default options for flow.js
     * @type {Object}
     */
    this.defaults = {
      chunkSize: 1024 * 1024,
      forceChunkSize: false,
      simultaneousUploads: 3,
      singleFile: false,
      fileParameterName: 'file',
      progressCallbacksInterval: 500,
      speedSmoothingFactor: 0.1,
      query: {},
      headers: {},
      withCredentials: false,
      preprocess: null,
      method: 'multipart',
      testMethod: 'GET',
      uploadMethod: 'POST',
      prioritizeFirstAndLastChunk: false,
      allowDuplicateUploads: false,
      target: '/',
      testChunks: true,
      generateUniqueIdentifier: null,
      maxChunkRetries: 0,
      chunkRetryInterval: null,
      permanentErrors: [404, 413, 415, 500, 501],
      successStatuses: [200, 201, 202],
      onDropStopPropagation: false,
      initFileFn: null,
      readFileFn: webAPIFileRead
    };

    /**
     * Current options
     * @type {Object}
     */
    this.opts = {};

    /**
     * List of events:
     *  key stands for event name
     *  value array list of callbacks
     * @type {}
     */
    this.events = {};

    var $ = this;

    /**
     * On drop event
     * @function
     * @param {MouseEvent} event
     */
    this.onDrop = function (event) {
      if ($.opts.onDropStopPropagation) {
        event.stopPropagation();
      }
      event.preventDefault();
      var dataTransfer = event.dataTransfer;
      if (dataTransfer.items && dataTransfer.items[0] &&
        dataTransfer.items[0].webkitGetAsEntry) {
        $.webkitReadDataTransfer(event);
      } else {
        $.addFiles(dataTransfer.files, event);
      }
    };

    /**
     * Prevent default
     * @function
     * @param {MouseEvent} event
     */
    this.preventEvent = function (event) {
      event.preventDefault();
    };

    /**
     * Current options
     * @type {Object}
     */
    this.opts = Flow.extend({}, this.defaults, opts || {});

  }

Flow.js is a library providing multiple simultaneous, stable and
resumable uploads via the HTML5 File API.
@param [opts]
@param {number} [opts.chunkSize]
@param {bool} [opts.forceChunkSize]
@param {number} [opts.simultaneousUploads]
@param {bool} [opts.singleFile]
@param {string} [opts.fileParameterName]
@param {number} [opts.progressCallbacksInterval]
@param {number} [opts.speedSmoothingFactor]
@param {Object|Function} [opts.query]
@param {Object|Function} [opts.headers]
@param {bool} [opts.withCredentials]
@param {Function} [opts.preprocess]
@param {string} [opts.method]
@param {string|Function} [opts.testMethod]
@param {string|Function} [opts.uploadMethod]
@param {bool} [opts.prioritizeFirstAndLastChunk]
@param {bool} [opts.allowDuplicateUploads]
@param {string|Function} [opts.target]
@param {number} [opts.maxChunkRetries]
@param {number} [opts.chunkRetryInterval]
@param {Array.<number>} [opts.permanentErrors]
@param {Array.<number>} [opts.successStatuses]
@param {Function} [opts.initFileFn]
@param {Function} [opts.readFileFn]
@param {Function} [opts.generateUniqueIdentifier]
@constructor

Flow . js is a library providing multiple simultaneous stable and resumable uploads via the HTML5 File API .


function (event, fn) {
      if (event !== undefined) {
        event = event.toLowerCase();
        if (fn !== undefined) {
          if (this.events.hasOwnProperty(event)) {
            arrayRemove(this.events[event], fn);
          }
        } else {
          delete this.events[event];
        }
      } else {
        this.events = {};
      }
    }

function ( event , fn ) { if ( event !== undefined ) { event = event . toLowerCase ( ) ; if ( fn !== undefined ) { if ( this . events . hasOwnProperty ( event ) ) { arrayRemove ( this . events [ event ] , fn ) ; } } else { delete this . events [ event ] ; } } else { this . events = { } ; } }

Remove event callback
@function
@param {string} [event] removes all events if not specified
@param {Function} [fn] removes all callbacks of event if not specified


function (event, args) {
      // `arguments` is an object, not array, in FF, so:
      args = Array.prototype.slice.call(arguments);
      event = event.toLowerCase();
      var preventDefault = false;
      if (this.events.hasOwnProperty(event)) {
        each(this.events[event], function (callback) {
          preventDefault = callback.apply(this, args.slice(1)) === false || preventDefault;
        }, this);
      }
      if (event != 'catchall') {
        args.unshift('catchAll');
        preventDefault = this.fire.apply(this, args) === false || preventDefault;
      }
      return !preventDefault;
    }

Fire an event
@function
@param {string} event event name
@param {...} args arguments of a callback
@return {bool} value is false if at least one of the event handlers which handled this event
returned false. Otherwise it returns true.


function (event) {
      var $ = this;
      var queue = event.dataTransfer.items.length;
      var files = [];
      each(event.dataTransfer.items, function (item) {
        var entry = item.webkitGetAsEntry();
        if (!entry) {
          decrement();
          return ;
        }
        if (entry.isFile) {
          // due to a bug in Chrome's File System API impl - #149735
          fileReadSuccess(item.getAsFile(), entry.fullPath);
        } else {
          readDirectory(entry.createReader());
        }
      });
      function readDirectory(reader) {
        reader.readEntries(function (entries) {
          if (entries.length) {
            queue += entries.length;
            each(entries, function(entry) {
              if (entry.isFile) {
                var fullPath = entry.fullPath;
                entry.file(function (file) {
                  fileReadSuccess(file, fullPath);
                }, readError);
              } else if (entry.isDirectory) {
                readDirectory(entry.createReader());
              }
            });
            readDirectory(reader);
          } else {
            decrement();
          }
        }, readError);
      }
      function fileReadSuccess(file, fullPath) {
        // relative path should not start with "/"
        file.relativePath = fullPath.substring(1);
        files.push(file);
        decrement();
      }
      function readError(fileError) {
        throw fileError;
      }
      function decrement() {
        if (--queue == 0) {
          $.addFiles(files, event);
        }
      }
    }

Read webkit dataTransfer object
@param event


function (file) {
      var custom = this.opts.generateUniqueIdentifier;
      if (typeof custom === 'function') {
        return custom(file);
      }
      // Some confusion in different versions of Firefox
      var relativePath = file.relativePath || file.webkitRelativePath || file.fileName || file.name;
      return file.size + '-' + relativePath.replace(/[^0-9a-zA-Z_-]/img, '');
    }

Generate unique identifier for a file
@function
@param {FlowFile} file
@returns {string}


function (preventEvents) {
      // In some cases (such as videos) it's really handy to upload the first
      // and last chunk of a file quickly; this let's the server check the file's
      // metadata and determine if there's even a point in continuing.
      var found = false;
      if (this.opts.prioritizeFirstAndLastChunk) {
        each(this.files, function (file) {
          if (!file.paused && file.chunks.length &&
            file.chunks[0].status() === 'pending') {
            file.chunks[0].send();
            found = true;
            return false;
          }
          if (!file.paused && file.chunks.length > 1 &&
            file.chunks[file.chunks.length - 1].status() === 'pending') {
            file.chunks[file.chunks.length - 1].send();
            found = true;
            return false;
          }
        });
        if (found) {
          return found;
        }
      }

      // Now, simply look for the next, best thing to upload
      each(this.files, function (file) {
        if (!file.paused) {
          each(file.chunks, function (chunk) {
            if (chunk.status() === 'pending') {
              chunk.send();
              found = true;
              return false;
            }
          });
        }
        if (found) {
          return false;
        }
      });
      if (found) {
        return true;
      }

      // The are no more outstanding chunks to upload, check is everything is done
      var outstanding = false;
      each(this.files, function (file) {
        if (!file.isComplete()) {
          outstanding = true;
          return false;
        }
      });
      if (!outstanding && !preventEvents) {
        // All chunks have been uploaded, complete
        async(function () {
          this.fire('complete');
        }, this);
      }
      return false;
    }

Upload next chunk from the queue
@function
@returns {boolean}
@private


function (domNodes, isDirectory, singleFile, attributes) {
      if (domNodes instanceof Element) {
        domNodes = [domNodes];
      }

      each(domNodes, function (domNode) {
        var input;
        if (domNode.tagName === 'INPUT' && domNode.type === 'file') {
          input = domNode;
        } else {
          input = document.createElement('input');
          input.setAttribute('type', 'file');
          // display:none - not working in opera 12
          extend(input.style, {
            visibility: 'hidden',
            position: 'absolute',
            width: '1px',
            height: '1px'
          });
          // for opera 12 browser, input must be assigned to a document
          domNode.appendChild(input);
          // https://developer.mozilla.org/en/using_files_from_web_applications)
          // event listener is executed two times
          // first one - original mouse click event
          // second - input.click(), input is inside domNode
          domNode.addEventListener('click', function() {
            input.click();
          }, false);
        }
        if (!this.opts.singleFile && !singleFile) {
          input.setAttribute('multiple', 'multiple');
        }
        if (isDirectory) {
          input.setAttribute('webkitdirectory', 'webkitdirectory');
        }
        each(attributes, function (value, key) {
          input.setAttribute(key, value);
        });
        // When new files are added, simply append them to the overall list
        var $ = this;
        input.addEventListener('change', function (e) {
       	  if (e.target.value) {
            $.addFiles(e.target.files, e);
            e.target.value = '';
       	  }
        }, false);
      }, this);
    }

Assign a browse action to one or more DOM nodes.
@function
@param {Element|Array.<Element>} domNodes
@param {boolean} isDirectory Pass in true to allow directories to
@param {boolean} singleFile prevent multi file upload
@param {Object} attributes set custom attributes:
http://www.w3.org/TR/html-markup/input.file.html#input.file-attributes
eg: accept: 'image/*'
be selected (Chrome only).

Assign a browse action to one or more DOM nodes .


function (domNodes) {
      if (typeof domNodes.length === 'undefined') {
        domNodes = [domNodes];
      }
      each(domNodes, function (domNode) {
        domNode.addEventListener('dragover', this.preventEvent, false);
        domNode.addEventListener('dragenter', this.preventEvent, false);
        domNode.addEventListener('drop', this.onDrop, false);
      }, this);
    }

function ( domNodes ) { if ( typeof domNodes . length === 'undefined' ) { domNodes = [ domNodes ] ; } each ( domNodes , function ( domNode ) { domNode . addEventListener ( 'dragover' , this . preventEvent , false ) ; domNode . addEventListener ( 'dragenter' , this . preventEvent , false ) ; domNode . addEventListener ( 'drop' , this . onDrop , false ) ; } , this ) ; }

Assign one or more DOM nodes as a drop target.
@function
@param {Element|Array.<Element>} domNodes

Assign one or more DOM nodes as a drop target .


function (domNodes) {
      if (typeof domNodes.length === 'undefined') {
        domNodes = [domNodes];
      }
      each(domNodes, function (domNode) {
        domNode.removeEventListener('dragover', this.preventEvent);
        domNode.removeEventListener('dragenter', this.preventEvent);
        domNode.removeEventListener('drop', this.onDrop);
      }, this);
    }

function ( domNodes ) { if ( typeof domNodes . length === 'undefined' ) { domNodes = [ domNodes ] ; } each ( domNodes , function ( domNode ) { domNode . removeEventListener ( 'dragover' , this . preventEvent ) ; domNode . removeEventListener ( 'dragenter' , this . preventEvent ) ; domNode . removeEventListener ( 'drop' , this . onDrop ) ; } , this ) ; }

Un-assign drop event from DOM nodes
@function
@param domNodes


function () {
      var uploading = false;
      each(this.files, function (file) {
        if (file.isUploading()) {
          uploading = true;
          return false;
        }
      });
      return uploading;
    }

function ( ) { var uploading = false ; each ( this . files , function ( file ) { if ( file . isUploading ( ) ) { uploading = true ; return false ; } } ) ; return uploading ; }

Returns a boolean indicating whether or not the instance is currently
uploading anything.
@function
@returns {boolean}

Returns a boolean indicating whether or not the instance is currently uploading anything .


function () {
      var num = 0;
      var should = true;
      var simultaneousUploads = this.opts.simultaneousUploads;
      each(this.files, function (file) {
        each(file.chunks, function(chunk) {
          if (chunk.status() === 'uploading') {
            num++;
            if (num >= simultaneousUploads) {
              should = false;
              return false;
            }
          }
        });
      });
      // if should is true then return uploading chunks's length
      return should && num;
    }

should upload next chunk
@function
@returns {boolean|number}


function () {
      // Make sure we don't start too many uploads at once
      var ret = this._shouldUploadNext();
      if (ret === false) {
        return;
      }
      // Kick off the queue
      this.fire('uploadStart');
      var started = false;
      for (var num = 1; num <= this.opts.simultaneousUploads - ret; num++) {
        started = this.uploadNextChunk(true) || started;
      }
      if (!started) {
        async(function () {
          this.fire('complete');
        }, this);
      }
    }


function (fileList, event) {
      var files = [];
      each(fileList, function (file) {
        // https://github.com/flowjs/flow.js/issues/55
        if ((!ie10plus || ie10plus && file.size > 0) && !(file.size % 4096 === 0 && (file.name === '.' || file.fileName === '.'))) {
          var uniqueIdentifier = this.generateUniqueIdentifier(file);
          if (this.opts.allowDuplicateUploads || !this.getFromUniqueIdentifier(uniqueIdentifier)) {
            var f = new FlowFile(this, file, uniqueIdentifier);
            if (this.fire('fileAdded', f, event)) {
              files.push(f);
            }
          }
        }
      }, this);
      if (this.fire('filesAdded', files, event)) {
        each(files, function (file) {
          if (this.opts.singleFile && this.files.length > 0) {
            this.removeFile(this.files[0]);
          }
          this.files.push(file);
        }, this);
        this.fire('filesSubmitted', files, event);
      }
    }

Add a HTML5 File object to the list of files.
@function
@param {FileList|Array} fileList
@param {Event} [event] event is optional

Add a HTML5 File object to the list of files .


function (file) {
      for (var i = this.files.length - 1; i >= 0; i--) {
        if (this.files[i] === file) {
          this.files.splice(i, 1);
          file.abort();
          this.fire('fileRemoved', file);
        }
      }
    }

function ( file ) { for ( var i = this . files . length - 1 ; i >= 0 ; i -- ) { if ( this . files [ i ] === file ) { this . files . splice ( i , 1 ) ; file . abort ( ) ; this . fire ( 'fileRemoved' , file ) ; } } }

Cancel upload of a specific FlowFile object from the list.
@function
@param {FlowFile} file

Cancel upload of a specific FlowFile object from the list .


function (uniqueIdentifier) {
      var ret = false;
      each(this.files, function (file) {
        if (file.uniqueIdentifier === uniqueIdentifier) {
          ret = file;
        }
      });
      return ret;
    }

function ( uniqueIdentifier ) { var ret = false ; each ( this . files , function ( file ) { if ( file . uniqueIdentifier === uniqueIdentifier ) { ret = file ; } } ) ; return ret ; }

Look up a FlowFile object by its unique identifier.
@function
@param {string} uniqueIdentifier
@returns {boolean|FlowFile} false if file was not found

Look up a FlowFile object by its unique identifier .


function () {
      var sizeDelta = 0;
      var averageSpeed = 0;
      each(this.files, function (file) {
        if (!file.paused && !file.error) {
          sizeDelta += file.size - file.sizeUploaded();
          averageSpeed += file.averageSpeed;
        }
      });
      if (sizeDelta && !averageSpeed) {
        return Number.POSITIVE_INFINITY;
      }
      if (!sizeDelta && !averageSpeed) {
        return 0;
      }
      return Math.floor(sizeDelta / averageSpeed);
    }

function ( ) { var sizeDelta = 0 ; var averageSpeed = 0 ; each ( this . files , function ( file ) { if ( ! file . paused && ! file . error ) { sizeDelta += file . size - file . sizeUploaded ( ) ; averageSpeed += file . averageSpeed ; } } ) ; if ( sizeDelta && ! averageSpeed ) { return Number . POSITIVE_INFINITY ; } if ( ! sizeDelta && ! averageSpeed ) { return 0 ; } return Math . floor ( sizeDelta / averageSpeed ) ; }

Returns remaining time to upload all files in seconds. Accuracy is based on average speed.
If speed is zero, time remaining will be equal to positive infinity `Number.POSITIVE_INFINITY`
@function
@returns {number}

Returns remaining time to upload all files in seconds . Accuracy is based on average speed . If speed is zero time remaining will be equal to positive infinity Number . POSITIVE_INFINITY


function () {
      var timeSpan = Date.now() - this._lastProgressCallback;
      if (!timeSpan) {
        return ;
      }
      var smoothingFactor = this.flowObj.opts.speedSmoothingFactor;
      var uploaded = this.sizeUploaded();
      // Prevent negative upload speed after file upload resume
      this.currentSpeed = Math.max((uploaded - this._prevUploadedSize) / timeSpan * 1000, 0);
      this.averageSpeed = smoothingFactor * this.currentSpeed + (1 - smoothingFactor) * this.averageSpeed;
      this._prevUploadedSize = uploaded;
    }

Update speed parameters
@link http://stackoverflow.com/questions/2779600/how-to-estimate-download-time-remaining-accurately
@function


function (chunk, event, message) {
      switch (event) {
        case 'progress':
          if (Date.now() - this._lastProgressCallback <
            this.flowObj.opts.progressCallbacksInterval) {
            break;
          }
          this.measureSpeed();
          this.flowObj.fire('fileProgress', this, chunk);
          this.flowObj.fire('progress');
          this._lastProgressCallback = Date.now();
          break;
        case 'error':
          this.error = true;
          this.abort(true);
          this.flowObj.fire('fileError', this, message, chunk);
          this.flowObj.fire('error', message, this, chunk);
          break;
        case 'success':
          if (this.error) {
            return;
          }
          this.measureSpeed();
          this.flowObj.fire('fileProgress', this, chunk);
          this.flowObj.fire('progress');
          this._lastProgressCallback = Date.now();
          if (this.isComplete()) {
            this.currentSpeed = 0;
            this.averageSpeed = 0;
            this.flowObj.fire('fileSuccess', this, message, chunk);
          }
          break;
        case 'retry':
          this.flowObj.fire('fileRetry', this, chunk);
          break;
      }
    }

function ( chunk , event , message ) { switch ( event ) { case 'progress' : if ( Date . now ( ) - this . _lastProgressCallback < this . flowObj . opts . progressCallbacksInterval ) { break ; } this . measureSpeed ( ) ; this . flowObj . fire ( 'fileProgress' , this , chunk ) ; this . flowObj . fire ( 'progress' ) ; this . _lastProgressCallback = Date . now ( ) ; break ; case 'error' : this . error = true ; this . abort ( true ) ; this . flowObj . fire ( 'fileError' , this , message , chunk ) ; this . flowObj . fire ( 'error' , message , this , chunk ) ; break ; case 'success' : if ( this . error ) { return ; } this . measureSpeed ( ) ; this . flowObj . fire ( 'fileProgress' , this , chunk ) ; this . flowObj . fire ( 'progress' ) ; this . _lastProgressCallback = Date . now ( ) ; if ( this . isComplete ( ) ) { this . currentSpeed = 0 ; this . averageSpeed = 0 ; this . flowObj . fire ( 'fileSuccess' , this , message , chunk ) ; } break ; case 'retry' : this . flowObj . fire ( 'fileRetry' , this , chunk ) ; break ; } }

For internal usage only.
Callback when something happens within the chunk.
@function
@param {FlowChunk} chunk
@param {string} event can be 'progress', 'success', 'error' or 'retry'
@param {string} [message]

For internal usage only . Callback when something happens within the chunk .


function (reset) {
      this.currentSpeed = 0;
      this.averageSpeed = 0;
      var chunks = this.chunks;
      if (reset) {
        this.chunks = [];
      }
      each(chunks, function (c) {
        if (c.status() === 'uploading') {
          c.abort();
          this.flowObj.uploadNextChunk();
        }
      }, this);
    }

function ( reset ) { this . currentSpeed = 0 ; this . averageSpeed = 0 ; var chunks = this . chunks ; if ( reset ) { this . chunks = [ ] ; } each ( chunks , function ( c ) { if ( c . status ( ) === 'uploading' ) { c . abort ( ) ; this . flowObj . uploadNextChunk ( ) ; } } , this ) ; }


function () {
      if (typeof this.flowObj.opts.initFileFn === "function") {
        this.flowObj.opts.initFileFn(this);
      }

      this.abort(true);
      this.error = false;
      // Rebuild stack of chunks from file
      this._prevProgress = 0;
      var round = this.flowObj.opts.forceChunkSize ? Math.ceil : Math.floor;
      var chunks = Math.max(
        round(this.size / this.flowObj.opts.chunkSize), 1
      );
      for (var offset = 0; offset < chunks; offset++) {
        this.chunks.push(
          new FlowChunk(this.flowObj, this, offset)
        );
      }
    }

function
(
)
{
if
(
typeof
this
.
flowObj
.
opts
.
initFileFn
===
"function"
)
{
this
.
flowObj
.
opts
.
initFileFn
(
this
)
;
}
this
.
abort
(
true
)
;
this
.
error
=
false
;
// Rebuild stack of chunks from file
this
.
_prevProgress
=
0
;
var
round
=
this
.
flowObj
.
opts
.
forceChunkSize
Math
.
ceil
:
Math
.
floor
;
var
chunks
=
Math
.
max
(
round
(
this
.
size
/
this
.
flowObj
.
opts
.
chunkSize
)
,
1
)
;
for
(
var
offset
=
0
;
offset
<
chunks
;
offset
++
)
{
this
.
chunks
.
push
(
new
FlowChunk
(
this
.
flowObj
,
this
,
offset
)
)
;
}
}

Clear current chunks and slice file again
@function


function () {
      if (this.error) {
        return 1;
      }
      if (this.chunks.length === 1) {
        this._prevProgress = Math.max(this._prevProgress, this.chunks[0].progress());
        return this._prevProgress;
      }
      // Sum up progress across everything
      var bytesLoaded = 0;
      each(this.chunks, function (c) {
        // get chunk progress relative to entire file
        bytesLoaded += c.progress() * (c.endByte - c.startByte);
      });
      var percent = bytesLoaded / this.size;
      // We don't want to lose percentages when an upload is paused
      this._prevProgress = Math.max(this._prevProgress, percent > 0.9999 ? 1 : percent);
      return this._prevProgress;
    }

Get current upload progress status
@function
@returns {number} from 0 to 1


function () {
      var outstanding = false;
      each(this.chunks, function (chunk) {
        var status = chunk.status();
        if (status === 'pending' || status === 'uploading' || status === 'reading' || chunk.preprocessState === 1 || chunk.readState === 1) {
          outstanding = true;
          return false;
        }
      });
      return !outstanding;
    }

function ( ) { var outstanding = false ; each ( this . chunks , function ( chunk ) { var status = chunk . status ( ) ; if ( status === 'pending' || status === 'uploading' || status === 'reading' || chunk . preprocessState === 1 || chunk . readState === 1 ) { outstanding = true ; return false ; } } ) ; return ! outstanding ; }

Indicates if file is has finished uploading and received a response
@function
@returns {boolean}


function () {
      if (this.paused || this.error) {
        return 0;
      }
      var delta = this.size - this.sizeUploaded();
      if (delta && !this.averageSpeed) {
        return Number.POSITIVE_INFINITY;
      }
      if (!delta && !this.averageSpeed) {
        return 0;
      }
      return Math.floor(delta / this.averageSpeed);
    }

function ( ) { if ( this . paused || this . error ) { return 0 ; } var delta = this . size - this . sizeUploaded ( ) ; if ( delta && ! this . averageSpeed ) { return Number . POSITIVE_INFINITY ; } if ( ! delta && ! this . averageSpeed ) { return 0 ; } return Math . floor ( delta / this . averageSpeed ) ; }

Returns remaining time to finish upload file in seconds. Accuracy is based on average speed.
If speed is zero, time remaining will be equal to positive infinity `Number.POSITIVE_INFINITY`
@function
@returns {number}

Returns remaining time to finish upload file in seconds . Accuracy is based on average speed . If speed is zero time remaining will be equal to positive infinity Number . POSITIVE_INFINITY


function webAPIFileRead(fileObj, startByte, endByte, fileType, chunk) {
    var function_name = 'slice';

    if (fileObj.file.slice)
      function_name =  'slice';
    else if (fileObj.file.mozSlice)
      function_name = 'mozSlice';
    else if (fileObj.file.webkitSlice)
      function_name = 'webkitSlice';

    chunk.readFinished(fileObj.file[function_name](startByte, endByte, fileType));
  }

function webAPIFileRead ( fileObj , startByte , endByte , fileType , chunk ) { var function_name = 'slice' ; if ( fileObj . file . slice ) function_name = 'slice' ; else if ( fileObj . file . mozSlice ) function_name = 'mozSlice' ; else if ( fileObj . file . webkitSlice ) function_name = 'webkitSlice' ; chunk . readFinished ( fileObj . file [ function_name ] ( startByte , endByte , fileType ) ) ; }

Default read function using the webAPI

@function webAPIFileRead(fileObj, startByte, endByte, fileType, chunk)


function () {
      // Set up request and listen for event
      this.xhr = new XMLHttpRequest();
      this.xhr.addEventListener("load", this.testHandler, false);
      this.xhr.addEventListener("error", this.testHandler, false);
      var testMethod = evalOpts(this.flowObj.opts.testMethod, this.fileObj, this);
      var data = this.prepareXhrRequest(testMethod, true);
      this.xhr.send(data);
    }

function
(
)
{
// Set up request and listen for event
this
.
xhr
=
new
XMLHttpRequest
(
)
;
this
.
xhr
.
addEventListener
(
"load"
,
this
.
testHandler
,
false
)
;
this
.
xhr
.
addEventListener
(
"error"
,
this
.
testHandler
,
false
)
;
var
testMethod
=
evalOpts
(
this
.
flowObj
.
opts
.
testMethod
,
this
.
fileObj
,
this
)
;
var
data
=
this
.
prepareXhrRequest
(
testMethod
,
true
)
;
this
.
xhr
.
send
(
data
)
;
}

Makes a GET request without any data to see if the chunk has already
been uploaded in a previous session
@function


function () {
      var preprocess = this.flowObj.opts.preprocess;
      var read = this.flowObj.opts.readFileFn;
      if (typeof preprocess === 'function') {
        switch (this.preprocessState) {
          case 0:
            this.preprocessState = 1;
            preprocess(this);
            return;
          case 1:
            return;
        }
      }
      switch (this.readState) {
        case 0:
          this.readState = 1;
          read(this.fileObj, this.startByte, this.endByte, this.fileObj.file.type, this);
          return;
        case 1:
          return;
      }
      if (this.flowObj.opts.testChunks && !this.tested) {
        this.test();
        return;
      }

      this.loaded = 0;
      this.total = 0;
      this.pendingRetry = false;

      // Set up request and listen for event
      this.xhr = new XMLHttpRequest();
      this.xhr.upload.addEventListener('progress', this.progressHandler, false);
      this.xhr.addEventListener("load", this.doneHandler, false);
      this.xhr.addEventListener("error", this.doneHandler, false);

      var uploadMethod = evalOpts(this.flowObj.opts.uploadMethod, this.fileObj, this);
      var data = this.prepareXhrRequest(uploadMethod, false, this.flowObj.opts.method, this.bytes);
      this.xhr.send(data);
    }

function
(
)
{
var
preprocess
=
this
.
flowObj
.
opts
.
preprocess
;
var
read
=
this
.
flowObj
.
opts
.
readFileFn
;
if
(
typeof
preprocess
===
'function'
)
{
switch
(
this
.
preprocessState
)
{
case
0
:
this
.
preprocessState
=
1
;
preprocess
(
this
)
;
return
;
case
1
:
return
;
}
}
switch
(
this
.
readState
)
{
case
0
:
this
.
readState
=
1
;
read
(
this
.
fileObj
,
this
.
startByte
,
this
.
endByte
,
this
.
fileObj
.
file
.
type
,
this
)
;
return
;
case
1
:
return
;
}
if
(
this
.
flowObj
.
opts
.
testChunks
&&
!
this
.
tested
)
{
this
.
test
(
)
;
return
;
}
this
.
loaded
=
0
;
this
.
total
=
0
;
this
.
pendingRetry
=
false
;
// Set up request and listen for event
this
.
xhr
=
new
XMLHttpRequest
(
)
;
this
.
xhr
.
upload
.
addEventListener
(
'progress'
,
this
.
progressHandler
,
false
)
;
this
.
xhr
.
addEventListener
(
"load"
,
this
.
doneHandler
,
false
)
;
this
.
xhr
.
addEventListener
(
"error"
,
this
.
doneHandler
,
false
)
;
var
uploadMethod
=
evalOpts
(
this
.
flowObj
.
opts
.
uploadMethod
,
this
.
fileObj
,
this
)
;
var
data
=
this
.
prepareXhrRequest
(
uploadMethod
,
false
,
this
.
flowObj
.
opts
.
method
,
this
.
bytes
)
;
this
.
xhr
.
send
(
data
)
;
}

Uploads the actual data in a POST call
@function


function (isTest) {
      if (this.readState === 1) {
        return 'reading';
      } else if (this.pendingRetry || this.preprocessState === 1) {
        // if pending retry then that's effectively the same as actively uploading,
        // there might just be a slight delay before the retry starts
        return 'uploading';
      } else if (!this.xhr) {
        return 'pending';
      } else if (this.xhr.readyState < 4) {
        // Status is really 'OPENED', 'HEADERS_RECEIVED'
        // or 'LOADING' - meaning that stuff is happening
        return 'uploading';
      } else {
        if (this.flowObj.opts.successStatuses.indexOf(this.xhr.status) > -1) {
          // HTTP 200, perfect
		      // HTTP 202 Accepted - The request has been accepted for processing, but the processing has not been completed.
          return 'success';
        } else if (this.flowObj.opts.permanentErrors.indexOf(this.xhr.status) > -1 ||
            !isTest && this.retries >= this.flowObj.opts.maxChunkRetries) {
          // HTTP 413/415/500/501, permanent error
          return 'error';
        } else {
          // this should never happen, but we'll reset and queue a retry
          // a likely case for this would be 503 service unavailable
          this.abort();
          return 'pending';
        }
      }
    }

Retrieve current chunk upload status
@function
@returns {string} 'pending', 'uploading', 'success', 'error'