<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: CacheConfiguration.js</title>

    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">

    <h1 class="page-title">Source: CacheConfiguration.js</h1>

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const ComplexObjectType = require('./ObjectType').ComplexObjectType;
const ObjectArrayType = require('./ObjectType').ObjectArrayType;
const BinaryUtils = require('./internal/BinaryUtils');
const BinaryReader = require('./internal/BinaryReader');
const BinaryWriter = require('./internal/BinaryWriter');
const ArgumentChecker = require('./internal/ArgumentChecker');
const Errors = require('./Errors');

/**
 * Class representing Cache Key part of Ignite {@link CacheConfiguration}.
 *
 * All configuration settings are optional and have defaults which are defined on a server side.
 *
 * See Apache Ignite documentation for details of every configuration setting. 
 */
class CacheKeyConfiguration {

    /**
     * Public constructor.
     *
     * @param {string} [typeName=null]
     * @param {string} [affinityKeyFieldName=null]
     *
     * @return {CacheKeyConfiguration} - new CacheKeyConfiguration instance.
     */
    constructor(typeName = null, affinityKeyFieldName = null) {
        this._typeName = typeName;
        this._affinityKeyFieldName = affinityKeyFieldName;
    }

    /**
     *
     *
     * @param {string} typeName
     *
     * @return {CacheKeyConfiguration} - the same instance of the CacheKeyConfiguration.
     */
    setTypeName(typeName) {
        this._typeName = typeName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getTypeName() {
        return this._typeName;
    }

    /**
     *
     *
     * @param {string} affinityKeyFieldName
     *
     * @return {CacheKeyConfiguration} - the same instance of the CacheKeyConfiguration.
     */
    setAffinityKeyFieldName(affinityKeyFieldName) {
        this._affinityKeyFieldName = affinityKeyFieldName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getAffinityKeyFieldName() {
        return this._affinityKeyFieldName;
    }

    /** Private methods */

    /**
     * @ignore
     */
    async _write(buffer) {
        await BinaryWriter.writeString(buffer, this._typeName);
        await BinaryWriter.writeString(buffer, this._affinityKeyFieldName);
    }

    /**
     * @ignore
     */
    async _read(buffer) {
        this._typeName = await BinaryReader.readObject(buffer);
        this._affinityKeyFieldName = await BinaryReader.readObject(buffer);
    }
}

/**
 * Class representing one Query Entity element of Ignite {@link CacheConfiguration}.
 *
 * All configuration settings are optional and have defaults which are defined on a server side.
 *
 * See Apache Ignite documentation for details of every configuration setting. 
 */
class QueryEntity {

    /**
     * Public constructor.
     *
     * @return {QueryEntity} - new QueryEntity instance.
     */
    constructor() {
        this._keyTypeName = null;
        this._valueTypeName = null;
        this._tableName = null;
        this._keyFieldName = null;
        this._valueFieldName = null;
        this._fields = null;
        this._aliases = null;
        this._indexes = null;
    }

    /**
     *
     *
     * @param {string} keyTypeName
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setKeyTypeName(keyTypeName) {
        this._keyTypeName = keyTypeName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getKeyTypeName() {
        return this._keyTypeName;
    }

    /**
     *
     *
     * @param {string} valueTypeName
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setValueTypeName(valueTypeName) {
        this._valueTypeName = valueTypeName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getValueTypeName() {
        return this._valueTypeName;
    }

    /**
     *
     *
     * @param {string} tableName
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setTableName(tableName) {
        this._tableName = tableName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getTableName() {
        return this._tableName;
    }

    /**
     *
     *
     * @param {string} keyFieldName
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setKeyFieldName(keyFieldName) {
        this._keyFieldName = keyFieldName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getKeyFieldName() {
        return this._keyFieldName;
    }

    /**
     *
     *
     * @param {string} valueFieldName
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setValueFieldName(valueFieldName) {
        this._valueFieldName = valueFieldName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getValueFieldName() {
        return this._valueFieldName;
    }

    /**
     * 
     *
     * @param {Array&lt;QueryField>} fields
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setFields(fields) {
        this._fields = fields;
        return this;
    }

    /**
     * 
     *
     * @return {Array&lt;QueryField>}
     */
    getFields() {
        return this._fields;
    }

    /**
     * 
     *
     * @param {Map&lt;string, string>} aliases
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setAliases(aliases) {
        this._aliases = aliases;
        return this;
    }

    /**
     * 
     *
     * @return {Map&lt;string, string>}
     */
    getAliases() {
        return this._aliases;
    }

    /**
     * 
     *
     * @param {Array&lt;QueryIndex>} indexes
     *
     * @return {QueryEntity} - the same instance of the QueryEntity.
     */
    setIndexes(indexes) {
        this._indexes = indexes;
        return this;
    }

    /**
     * 
     *
     * @return {Array&lt;QueryIndex>}
     */
    getIndexes() {
        return this._indexes;
    }

    /** Private methods */

    /**
     * @ignore
     */
    async _write(buffer) {
        await BinaryWriter.writeString(buffer, this._keyTypeName);
        await BinaryWriter.writeString(buffer, this._valueTypeName);
        await BinaryWriter.writeString(buffer, this._tableName);
        await BinaryWriter.writeString(buffer, this._keyFieldName);
        await BinaryWriter.writeString(buffer, this._valueFieldName);
        await this._writeSubEntities(buffer, this._fields);
        await this._writeAliases(buffer);
        await this._writeSubEntities(buffer, this._indexes);
    }

    /**
     * @ignore
     */
    async _writeAliases(buffer) {
        const length = this._aliases ? this._aliases.size : 0;
        buffer.writeInteger(length);
        if (length > 0) {
            for (let [key, value] of this._aliases.entries()) {
                await BinaryWriter.writeString(buffer, key);
                await BinaryWriter.writeString(buffer, value);
            }
        }
    }

    /**
     * @ignore
     */
    async _writeSubEntities(buffer, entities) {
        const length = entities ? entities.length : 0;
        buffer.writeInteger(length);
        if (length > 0) {
            for (let entity of entities) {
                await entity._write(buffer);
            }
        }
    }

    /**
     * @ignore
     */
    async _read(buffer) {
        this._keyTypeName = await BinaryReader.readObject(buffer);
        this._valueTypeName = await BinaryReader.readObject(buffer);
        this._tableName = await BinaryReader.readObject(buffer);
        this._keyFieldName = await BinaryReader.readObject(buffer);
        this._valueFieldName = await BinaryReader.readObject(buffer);
        this._fields = await this._readSubEntities(buffer, QueryField);
        await this._readAliases(buffer);
        this._indexes = await this._readSubEntities(buffer, QueryIndex);
    }

    /**
     * @ignore
     */
    async _readSubEntities(buffer, objectConstructor) {
        const length = buffer.readInteger(buffer);
        const result = new Array(length);
        if (length > 0) {
            let res;
            for (let i = 0; i &lt; length; i++) {
                res = new objectConstructor();
                await res._read(buffer);
                result[i] = res;
            }
        }
        return result;
    }

    /**
     * @ignore
     */
    async _readAliases(buffer) {
        const length = buffer.readInteger(buffer);
        this._aliases = new Map();
        if (length > 0) {
            let res;
            for (let i = 0; i &lt; length; i++) {
                this._aliases.set(await BinaryReader.readObject(buffer), await BinaryReader.readObject(buffer));
            }
        }
    }
}

/**
 * Class representing one Query Field element of {@link QueryEntity} of Ignite {@link CacheConfiguration}.
 *
 * All configuration settings are optional and have defaults which are defined on a server side.
 *
 * See Apache Ignite documentation for details of every configuration setting. 
 */
class QueryField {

    /**
     * Public constructor.
     *
     * @param {string} [name=null]
     * @param {string} [typeName=null]
     *
     * @return {QueryField} - new QueryField instance.
     */
    constructor(name = null, typeName = null) {
        this._name = name;
        this._typeName = typeName;
        this._isKeyField = false;
        this._isNotNull = false;
        this._defaultValue = undefined;
        this._precision = -1;
        this._scale = -1;
        this._valueType = null;
        this._buffer = null;
        this._index = null;
    }

    /**
     *
     *
     * @param {string} name
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setName(name) {
        this._name = name;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getName() {
        return this._name;
    }

    /**
     *
     *
     * @param {string} typeName
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setTypeName(typeName) {
        this._typeName = typeName;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getTypeName() {
        return this._typeName;
    }

    /**
     *
     *
     * @param {boolean} isKeyField
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setIsKeyField(isKeyField) {
        this._isKeyField = isKeyField;
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getIsKeyField() {
        return this._isKeyField;
    }

    /**
     *
     *
     * @param {boolean} isNotNull
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setIsNotNull(isNotNull) {
        this._isNotNull = isNotNull;
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getIsNotNull() {
        return this._isNotNull;
    }

    /**
     *
     *
     * @param {*} defaultValue
     * @param {ObjectType.PRIMITIVE_TYPE | CompositeType} [valueType=null] - type of the default value:
     *   - either a type code of primitive (simple) type
     *   - or an instance of class representing non-primitive (composite) type
     *   - or null (or not specified) that means the type is not specified
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setDefaultValue(defaultValue, valueType = null) {
        this._defaultValue = defaultValue;
        this._valueType = valueType;
        return this;
    }

    /**
     *
     *
     * @param {ObjectType.PRIMITIVE_TYPE | CompositeType} [valueType=null] - type of the default value:
     *   - either a type code of primitive (simple) type
     *   - or an instance of class representing non-primitive (composite) type
     *   - or null (or not specified) that means the type is not specified
     *
     * @async
     *
     * @return {*}
     */
    async getDefaultValue(valueType = null) {
        if (this._defaultValue === undefined) {
            if (this._buffer) {
                const position = this._buffer.position;
                this._buffer.position = this._index;
                const result = await BinaryReader.readObject(this._buffer, valueType);
                this._buffer.position = position;
                return result;
            }
            else {
                return null;
            }
        }
        else {
            return this._defaultValue;
        }
    }

    /**
     *
     *
     * @param {number} precision
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setPrecision(precision) {
        ArgumentChecker.isInteger(precision, 'precision');
        this._precision = precision;
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getPrecision() {
        return this._precision;
    }

    /**
     *
     *
     * @param {number} scale
     *
     * @return {QueryField} - the same instance of the QueryField.
     */
    setScale(scale) {
        ArgumentChecker.isInteger(scale, 'scale');
        this._scale = scale;
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getScale() {
        return this._scale;
    }

    /** Private methods */

    /**
     * @ignore
     */
    async _write(buffer) {
        await BinaryWriter.writeString(buffer, this._name);
        await BinaryWriter.writeString(buffer, this._typeName);
        buffer.writeBoolean(this._isKeyField);
        buffer.writeBoolean(this._isNotNull);
        await BinaryWriter.writeObject(buffer, this._defaultValue ? this._defaultValue : null, this._valueType);
        buffer.writeInteger(this._precision);
        buffer.writeInteger(this._scale);
    }

    /**
     * @ignore
     */
    async _read(buffer) {
        this._name = await BinaryReader.readObject(buffer);
        this._typeName = await BinaryReader.readObject(buffer);
        this._isKeyField = buffer.readBoolean();
        this._isNotNull = buffer.readBoolean();
        this._defaultValue = undefined;
        this._buffer = buffer;
        this._index = buffer.position;
        await BinaryReader.readObject(buffer);
        this._precision = buffer.readInteger();
        this._scale = buffer.readInteger();
    }
}

/**
 * 
 * @typedef QueryIndex.INDEX_TYPE
 * @enum
 * @readonly
 * @property SORTED 0
 * @property FULLTEXT 1
 * @property GEOSPATIAL 2
 */
 const INDEX_TYPE = Object.freeze({
    SORTED : 0,
    FULLTEXT : 1,
    GEOSPATIAL : 2
});

/**
 * Class representing one Query Index element of {@link QueryEntity} of Ignite {@link CacheConfiguration}.
 *
 * All configuration settings are optional and have defaults which are defined on a server side.
 *
 * See Apache Ignite documentation for details of every configuration setting. 
 */
class QueryIndex {
    
    /**
     * Public constructor.
     *
     * @param {string} [name=null]
     * @param {string} [typeName=QueryIndex.INDEX_TYPE.SORTED]
     *
     * @return {QueryIndex} - new QueryIndex instance.
     */
    constructor(name = null, type = QueryIndex.INDEX_TYPE.SORTED) {
        this._name = name;
        this.setType(type);
        this._inlineSize = -1;
        this._fields = null;
    }

    static get INDEX_TYPE() {
        return INDEX_TYPE;
    }

    /**
     *
     *
     * @param {string} name
     *
     * @return {QueryIndex} - the same instance of the QueryIndex.
     */
    setName(name) {
        this._name = name;
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getName() {
        return this._name;
    }

    /**
     *
     *
     * @param {QueryIndex.INDEX_TYPE} type
     *
     * @return {QueryIndex} - the same instance of the QueryIndex.
     *
     * @throws {IgniteClientError} if error.
     */
    setType(type) {
        ArgumentChecker.hasValueFrom(type, 'type', false, QueryIndex.INDEX_TYPE);
        this._type = type;
        return this;
    }

    /**
     *
     *
     * @return {QueryIndex.INDEX_TYPE}
     */
    getType() {
        return this._type;
    }

    /**
     *
     *
     * @param {number} inlineSize
     *
     * @return {QueryIndex} - the same instance of the QueryIndex.
     */
    setInlineSize(inlineSize) {
        this._inlineSize = inlineSize;
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
     getInlineSize() {
        return this._inlineSize;
    }

    /**
     * 
     *
     * @param {Map&lt;string, boolean>} fields
     *
     * @return {QueryIndex} - the same instance of the QueryIndex.
     */
    setFields(fields) {
        this._fields = fields;
        return this;
    }

    /**
     * 
     *
     * @return {Map&lt;string, boolean>}
     */
    getFields() {
        return this._fields;
    }

    /** Private methods */

    /**
     * @ignore
     */
    async _write(buffer) {
        await BinaryWriter.writeString(buffer, this._name);
        buffer.writeByte(this._type);
        buffer.writeInteger(this._inlineSize);
        // write fields
        const length = this._fields ? this._fields.size : 0;
        buffer.writeInteger(length);
        if (length > 0) {
            for (let [key, value] of this._fields.entries()) {
                await BinaryWriter.writeString(buffer, key);
                buffer.writeBoolean(value);
            }
        }
    }

    /**
     * @ignore
     */
    async _read(buffer) {
        this._name = await BinaryReader.readObject(buffer);
        this._type = buffer.readByte();
        this._inlineSize = buffer.readInteger();
        // read fields
        const length = buffer.readInteger(buffer);
        this._fields = new Map();
        if (length > 0) {
            let res;
            for (let i = 0; i &lt; length; i++) {
                this._fields.set(await BinaryReader.readObject(buffer), buffer.readBoolean());
            }
        }
    }
}

const PROP_NAME = 0;
const PROP_CACHE_MODE = 1;
const PROP_ATOMICITY_MODE = 2;
const PROP_BACKUPS = 3;
const PROP_WRITE_SYNCHRONIZATION_MODE = 4;
const PROP_COPY_ON_READ = 5;
const PROP_READ_FROM_BACKUP = 6;
const PROP_DATA_REGION_NAME = 100;
const PROP_IS_ONHEAP_CACHE_ENABLED = 101;
const PROP_QUERY_ENTITY = 200;
const PROP_QUERY_PARALLELISM = 201;
const PROP_QUERY_DETAIL_METRICS_SIZE = 202;
const PROP_SQL_SCHEMA = 203;
const PROP_SQL_INDEX_INLINE_MAX_SIZE = 204;
const PROP_SQL_ESCAPE_ALL = 205;
const PROP_MAX_QUERY_ITERATORS = 206;
const PROP_REBALANCE_MODE = 300;
const PROP_REBALANCE_DELAY = 301;
const PROP_REBALANCE_TIMEOUT = 302;
const PROP_REBALANCE_BATCH_SIZE = 303;
const PROP_REBALANCE_BATCHES_PREFETCH_COUNT = 304;
const PROP_REBALANCE_ORDER = 305;
const PROP_REBALANCE_THROTTLE = 306;
const PROP_GROUP_NAME = 400;
const PROP_CACHE_KEY_CONFIGURATION = 401;
const PROP_DEFAULT_LOCK_TIMEOUT = 402;
const PROP_MAX_CONCURRENT_ASYNC_OPS = 403;
const PROP_PARTITION_LOSS_POLICY = 404;
const PROP_EAGER_TTL = 405;
const PROP_STATISTICS_ENABLED = 406;

const PROP_TYPES = Object.freeze({
    [PROP_NAME] : BinaryUtils.TYPE_CODE.STRING,
    [PROP_CACHE_MODE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_ATOMICITY_MODE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_BACKUPS] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_WRITE_SYNCHRONIZATION_MODE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_COPY_ON_READ] : BinaryUtils.TYPE_CODE.BOOLEAN,
    [PROP_READ_FROM_BACKUP] : BinaryUtils.TYPE_CODE.BOOLEAN,
    [PROP_DATA_REGION_NAME] : BinaryUtils.TYPE_CODE.STRING,
    [PROP_IS_ONHEAP_CACHE_ENABLED] : BinaryUtils.TYPE_CODE.BOOLEAN,
    [PROP_QUERY_ENTITY] : new ObjectArrayType(new ComplexObjectType(new QueryEntity())),
    [PROP_QUERY_PARALLELISM] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_QUERY_DETAIL_METRICS_SIZE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_SQL_SCHEMA] : BinaryUtils.TYPE_CODE.STRING,
    [PROP_SQL_INDEX_INLINE_MAX_SIZE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_SQL_ESCAPE_ALL] : BinaryUtils.TYPE_CODE.BOOLEAN,
    [PROP_MAX_QUERY_ITERATORS] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_REBALANCE_MODE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_REBALANCE_DELAY] : BinaryUtils.TYPE_CODE.LONG,
    [PROP_REBALANCE_TIMEOUT] : BinaryUtils.TYPE_CODE.LONG,
    [PROP_REBALANCE_BATCH_SIZE] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_REBALANCE_BATCHES_PREFETCH_COUNT] : BinaryUtils.TYPE_CODE.LONG,
    [PROP_REBALANCE_ORDER] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_REBALANCE_THROTTLE] : BinaryUtils.TYPE_CODE.LONG,
    [PROP_GROUP_NAME] : BinaryUtils.TYPE_CODE.STRING,
    [PROP_CACHE_KEY_CONFIGURATION] : new ObjectArrayType(new ComplexObjectType(new CacheKeyConfiguration())),
    [PROP_DEFAULT_LOCK_TIMEOUT] : BinaryUtils.TYPE_CODE.LONG,
    [PROP_MAX_CONCURRENT_ASYNC_OPS] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_PARTITION_LOSS_POLICY] : BinaryUtils.TYPE_CODE.INTEGER,
    [PROP_EAGER_TTL] : BinaryUtils.TYPE_CODE.BOOLEAN,
    [PROP_STATISTICS_ENABLED] : BinaryUtils.TYPE_CODE.BOOLEAN
});

/**
 * 
 * @typedef CacheConfiguration.CACHE_ATOMICITY_MODE
 * @enum
 * @readonly
 * @property TRANSACTIONAL 0
 * @property ATOMIC 1
 */
const CACHE_ATOMICITY_MODE = Object.freeze({
    TRANSACTIONAL : 0,
    ATOMIC : 1
});

/**
 * 
 * @typedef CacheConfiguration.CACHE_MODE
 * @enum
 * @readonly
 * @property LOCAL 0
 * @property REPLICATED 1
 * @property PARTITIONED 2
 */
const CACHE_MODE = Object.freeze({
    LOCAL : 0,
    REPLICATED : 1,
    PARTITIONED : 2
});

/**
 * 
 * @typedef CacheConfiguration.PARTITION_LOSS_POLICY
 * @enum
 * @readonly
 * @property READ_ONLY_SAFE 0
 * @property READ_ONLY_ALL 1
 * @property READ_WRITE_SAFE 2
 * @property READ_WRITE_ALL 3
 * @property IGNORE 4
 */
const PARTITION_LOSS_POLICY = Object.freeze({
    READ_ONLY_SAFE : 0,
    READ_ONLY_ALL : 1,
    READ_WRITE_SAFE : 2,
    READ_WRITE_ALL : 3,
    IGNORE : 4
});

/**
 * 
 * @typedef CacheConfiguration.REABALANCE_MODE
 * @enum
 * @readonly
 * @property SYNC 0
 * @property ASYNC 1
 * @property NONE 2
 */
const REABALANCE_MODE = Object.freeze({
    SYNC : 0,
    ASYNC : 1,
    NONE : 2
});

/**
 * 
 * @typedef CacheConfiguration.WRITE_SYNCHRONIZATION_MODE
 * @enum
 * @readonly
 * @property FULL_SYNC 0
 * @property FULL_ASYNC 1
 * @property PRIMARY_SYNC 2
 */
const WRITE_SYNCHRONIZATION_MODE = Object.freeze({
    FULL_SYNC : 0,
    FULL_ASYNC : 1,
    PRIMARY_SYNC : 2
});

/**
 * Class representing Ignite cache configuration on a server.
 *
 * All configuration settings are optional and have defaults which are defined on a server side.
 *
 * See Apache Ignite documentation for details of every configuration setting. 
 */
class CacheConfiguration {

    /**
     * Public constructor.
     *
     * @return {CacheConfiguration} - new CacheConfiguration instance.
     */
    constructor() {
        this._properties = new Map();
    }

    static get CACHE_ATOMICITY_MODE() {
        return CACHE_ATOMICITY_MODE;
    }

    static get CACHE_MODE() {
        return CACHE_MODE;
    }

    static get PARTITION_LOSS_POLICY() {
        return PARTITION_LOSS_POLICY;
    }

    static get REABALANCE_MODE() {
        return REABALANCE_MODE;
    }

    static get WRITE_SYNCHRONIZATION_MODE() {
        return WRITE_SYNCHRONIZATION_MODE;
    }

    /**
     *
     *
     * @param {CacheConfiguration.CACHE_ATOMICITY_MODE} atomicityMode
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setAtomicityMode(atomicityMode) {
        ArgumentChecker.hasValueFrom(atomicityMode, 'atomicityMode', false, CACHE_ATOMICITY_MODE);
        this._properties.set(PROP_ATOMICITY_MODE, atomicityMode);
        return this;
    }

    /**
     *
     *
     * @return {CacheConfiguration.CACHE_ATOMICITY_MODE}
     */
    getAtomicityMode() {
        return this._properties.get(PROP_ATOMICITY_MODE);
    }

    /**
     *
     *
     * @param {number} backups
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setBackups(backups) {
        this._properties.set(PROP_BACKUPS, backups);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getBackups() {
        return this._properties.get(PROP_BACKUPS);
    }

    /**
     *
     *
     * @param {CacheConfiguration.CACHE_MODE} cacheMode
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setCacheMode(cacheMode) {
        ArgumentChecker.hasValueFrom(cacheMode, 'cacheMode', false, CACHE_MODE);
        this._properties.set(PROP_CACHE_MODE, cacheMode);
        return this;
    }

    /**
     *
     *
     * @return {CacheConfiguration.CACHE_MODE}
     */
    getCacheMode() {
        return this._properties.get(PROP_CACHE_MODE);
    }

    /**
     *
     *
     * @param {boolean} copyOnRead
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setCopyOnRead(copyOnRead) {
        this._properties.set(PROP_COPY_ON_READ, copyOnRead);
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getCopyOnRead() {
        return this._properties.get(PROP_COPY_ON_READ);
    }

    /**
     *
     *
     * @param {string} dataRegionName
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setDataRegionName(dataRegionName) {
        this._properties.set(PROP_DATA_REGION_NAME, dataRegionName);
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getDataRegionName() {
        return this._properties.get(PROP_DATA_REGION_NAME);
    }

    /**
     *
     *
     * @param {boolean} eagerTtl
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setEagerTtl(eagerTtl) {
        this._properties.set(PROP_EAGER_TTL, eagerTtl);
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getEagerTtl() {
        return this._properties.get(PROP_EAGER_TTL);
    }

    /**
     *
     *
     * @param {boolean} statisticsEnabled
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setStatisticsEnabled(statisticsEnabled) {
        this._properties.set(PROP_STATISTICS_ENABLED, statisticsEnabled);
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getStatisticsEnabled() {
        return this._properties.get(PROP_STATISTICS_ENABLED);
    }

    /**
     *
     *
     * @param {string} groupName
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setGroupName(groupName) {
        this._properties.set(PROP_GROUP_NAME, groupName);
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getGroupName() {
        return this._properties.get(PROP_GROUP_NAME);
    }

    /**
     *
     *
     * @param {number} lockTimeout
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setDefaultLockTimeout(lockTimeout) {
        this._properties.set(PROP_DEFAULT_LOCK_TIMEOUT, lockTimeout);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getDefaultLockTimeout() {
        return this._properties.get(PROP_DEFAULT_LOCK_TIMEOUT);
    }

    /**
     *
     *
     * @param {number} maxConcurrentAsyncOperations
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setMaxConcurrentAsyncOperations(maxConcurrentAsyncOperations) {
        this._properties.set(PROP_MAX_CONCURRENT_ASYNC_OPS, maxConcurrentAsyncOperations);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getMaxConcurrentAsyncOperations() {
        return this._properties.get(PROP_MAX_CONCURRENT_ASYNC_OPS);
    }

    /**
     *
     *
     * @param {number} maxQueryIterators
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setMaxQueryIterators(maxQueryIterators) {
        this._properties.set(PROP_MAX_QUERY_ITERATORS, maxQueryIterators);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getMaxQueryIterators() {
        return this._properties.get(PROP_MAX_QUERY_ITERATORS);
    }

    /**
     *
     *
     * @param {boolean} isOnheapCacheEnabled
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setIsOnheapCacheEnabled(isOnheapCacheEnabled) {
        this._properties.set(PROP_IS_ONHEAP_CACHE_ENABLED, isOnheapCacheEnabled);
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getIsOnheapCacheEnabled() {
        return this._properties.get(PROP_IS_ONHEAP_CACHE_ENABLED);
    }

    /**
     *
     *
     * @param {CacheConfiguration.PARTITION_LOSS_POLICY} partitionLossPolicy
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setPartitionLossPolicy(partitionLossPolicy) {
        ArgumentChecker.hasValueFrom(partitionLossPolicy, 'partitionLossPolicy', false, PARTITION_LOSS_POLICY);
        this._properties.set(PROP_PARTITION_LOSS_POLICY, partitionLossPolicy);
        return this;
    }

    /**
     *
     *
     * @return {CacheConfiguration.PARTITION_LOSS_POLICY}
     */
    getPartitionLossPolicy() {
        return this._properties.get(PROP_PARTITION_LOSS_POLICY);
    }

    /**
     *
     *
     * @param {number} queryDetailMetricsSize
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setQueryDetailMetricsSize(queryDetailMetricsSize) {
        this._properties.set(PROP_QUERY_DETAIL_METRICS_SIZE, queryDetailMetricsSize);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getQueryDetailMetricsSize() {
        return this._properties.get(PROP_QUERY_DETAIL_METRICS_SIZE);
    }

    /**
     *
     *
     * @param {number} queryParallelism
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setQueryParallelism(queryParallelism) {
        this._properties.set(PROP_QUERY_PARALLELISM, queryParallelism);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getQueryParallelism() {
        return this._properties.get(PROP_QUERY_PARALLELISM);
    }

    /**
     *
     *
     * @param {boolean} readFromBackup
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setReadFromBackup(readFromBackup) {
        this._properties.set(PROP_READ_FROM_BACKUP, readFromBackup);
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getReadFromBackup() {
        return this._properties.get(PROP_READ_FROM_BACKUP);
    }

    /**
     *
     *
     * @param {number} rebalanceBatchSize
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setRebalanceBatchSize(rebalanceBatchSize) {
        this._properties.set(PROP_REBALANCE_BATCH_SIZE, rebalanceBatchSize);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getRebalanceBatchSize() {
        return this._properties.get(PROP_REBALANCE_BATCH_SIZE);
    }

    /**
     *
     *
     * @param {number} rebalanceBatchesPrefetchCount
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setRebalanceBatchesPrefetchCount(rebalanceBatchesPrefetchCount) {
        this._properties.set(PROP_REBALANCE_BATCHES_PREFETCH_COUNT, rebalanceBatchesPrefetchCount);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getRebalanceBatchesPrefetchCount() {
        return this._properties.get(PROP_REBALANCE_BATCHES_PREFETCH_COUNT);
    }

    /**
     *
     *
     * @param {number} rebalanceDelay
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setRebalanceDelay(rebalanceDelay) {
        this._properties.set(PROP_REBALANCE_DELAY, rebalanceDelay);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getRebalanceDelay() {
        return this._properties.get(PROP_REBALANCE_DELAY);
    }

    /**
     *
     *
     * @param {CacheConfiguration.REABALANCE_MODE} rebalanceMode
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setRebalanceMode(rebalanceMode) {
        ArgumentChecker.hasValueFrom(rebalanceMode, 'rebalanceMode', false, REABALANCE_MODE);
        this._properties.set(PROP_REBALANCE_MODE, rebalanceMode);
        return this;
    }

    /**
     *
     *
     * @return {CacheConfiguration.REABALANCE_MODE}
     */
    getRebalanceMode() {
        return this._properties.get(PROP_REBALANCE_MODE);
    }

    /**
     *
     *
     * @param {number} rebalanceOrder
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setRebalanceOrder(rebalanceOrder) {
        this._properties.set(PROP_REBALANCE_ORDER, rebalanceOrder);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getRebalanceOrder() {
        return this._properties.get(PROP_REBALANCE_ORDER);
    }

    /**
     *
     *
     * @param {number} rebalanceThrottle
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setRebalanceThrottle(rebalanceThrottle) {
        this._properties.set(PROP_REBALANCE_THROTTLE, rebalanceThrottle);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getRebalanceThrottle() {
        return this._properties.get(PROP_REBALANCE_THROTTLE);
    }

    /**
     *
     *
     * @param {number} rebalanceTimeout
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setRebalanceTimeout(rebalanceTimeout) {
        this._properties.set(PROP_REBALANCE_TIMEOUT, rebalanceTimeout);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getRebalanceTimeout() {
        return this._properties.get(PROP_REBALANCE_TIMEOUT);
    }

    /**
     *
     *
     * @param {boolean} sqlEscapeAll
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setSqlEscapeAll(sqlEscapeAll) {
        this._properties.set(PROP_SQL_ESCAPE_ALL, sqlEscapeAll);
        return this;
    }

    /**
     *
     *
     * @return {boolean}
     */
    getSqlEscapeAll() {
        return this._properties.get(PROP_SQL_ESCAPE_ALL);
    }

    /**
     *
     *
     * @param {number} sqlIndexInlineMaxSize
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setSqlIndexInlineMaxSize(sqlIndexInlineMaxSize) {
        this._properties.set(PROP_SQL_INDEX_INLINE_MAX_SIZE, sqlIndexInlineMaxSize);
        return this;
    }

    /**
     *
     *
     * @return {number}
     */
    getSqlIndexInlineMaxSize() {
        return this._properties.get(PROP_SQL_INDEX_INLINE_MAX_SIZE);
    }

    /**
     *
     *
     * @param {string} sqlSchema
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     */
    setSqlSchema(sqlSchema) {
        this._properties.set(PROP_SQL_SCHEMA, sqlSchema);
        return this;
    }

    /**
     *
     *
     * @return {string}
     */
    getSqlSchema() {
        return this._properties.get(PROP_SQL_SCHEMA);
    }

    /**
     *
     *
     * @param {CacheConfiguration.WRITE_SYNCHRONIZATION_MODE} writeSynchronizationMode
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setWriteSynchronizationMode(writeSynchronizationMode) {
        ArgumentChecker.hasValueFrom(writeSynchronizationMode, 'writeSynchronizationMode', false, WRITE_SYNCHRONIZATION_MODE);
        this._properties.set(PROP_WRITE_SYNCHRONIZATION_MODE, writeSynchronizationMode);
        return this;
    }

    /**
     *
     *
     * @return {CacheConfiguration.WRITE_SYNCHRONIZATION_MODE}
     */
    getWriteSynchronizationMode() {
        return this._properties.get(PROP_WRITE_SYNCHRONIZATION_MODE);
    }

    /**
     * 
     *
     * @param {...CacheKeyConfiguration} keyConfigurations
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setKeyConfigurations(...keyConfigurations) {
        ArgumentChecker.hasType(keyConfigurations, 'keyConfigurations', true, CacheKeyConfiguration);
        this._properties.set(PROP_CACHE_KEY_CONFIGURATION, keyConfigurations);
        return this;
    }

    /**
     * 
     *
     * @return {Array&lt;CacheKeyConfiguration>}
     */
    getKeyConfigurations() {
        return this._properties.get(PROP_CACHE_KEY_CONFIGURATION);
    }

    /**
     * 
     *
     * @param {...QueryEntity} queryEntities
     *
     * @return {CacheConfiguration} - the same instance of the CacheConfiguration.
     *
     * @throws {IgniteClientError} if error.
     */
    setQueryEntities(...queryEntities) {
        ArgumentChecker.hasType(queryEntities, 'queryEntities', true, QueryEntity);
        this._properties.set(PROP_QUERY_ENTITY, queryEntities);
        return this;
    }

    /**
     * 
     *
     * @return {Array&lt;QueryEntity>}
     */
    getQueryEntities() {
        return this._properties.get(PROP_QUERY_ENTITY);
    }

    /** Private methods */

    /**
     * @ignore
     */
    async _write(buffer, name) {
        this._properties.set(PROP_NAME, name);

        const startPos = buffer.position;
        buffer.position = buffer.position +
            BinaryUtils.getSize(BinaryUtils.TYPE_CODE.INTEGER) +
            BinaryUtils.getSize(BinaryUtils.TYPE_CODE.SHORT);

        for (let [propertyCode, property] of this._properties) {
            await this._writeProperty(buffer, propertyCode, property);
        }

        const length = buffer.position - startPos;
        buffer.position = startPos;

        buffer.writeInteger(length);
        buffer.writeShort(this._properties.size);
    }

    /**
     * @ignore
     */
    async _writeProperty(buffer, propertyCode, property) {
        buffer.writeShort(propertyCode);
        const propertyType = PROP_TYPES[propertyCode];
        switch (BinaryUtils.getTypeCode(propertyType)) {
            case BinaryUtils.TYPE_CODE.INTEGER:
            case BinaryUtils.TYPE_CODE.LONG:
            case BinaryUtils.TYPE_CODE.BOOLEAN:
                await BinaryWriter.writeObject(buffer, property, propertyType, false);
                return;
            case BinaryUtils.TYPE_CODE.STRING:
                await BinaryWriter.writeObject(buffer, property, propertyType);
                return;
            case BinaryUtils.TYPE_CODE.OBJECT_ARRAY:
                const length = property ? property.length : 0;
                buffer.writeInteger(length);
                for (let prop of property) {
                    await prop._write(buffer);
                }
                return;
            default:
                throw Errors.IgniteClientError.internalError();
        }
    }

    /**
     * @ignore
     */
    async _read(buffer) {
        // length
        buffer.readInteger();
        await this._readProperty(buffer, PROP_ATOMICITY_MODE);
        await this._readProperty(buffer, PROP_BACKUPS);
        await this._readProperty(buffer, PROP_CACHE_MODE);
        await this._readProperty(buffer, PROP_COPY_ON_READ);
        await this._readProperty(buffer, PROP_DATA_REGION_NAME);
        await this._readProperty(buffer, PROP_EAGER_TTL);
        await this._readProperty(buffer, PROP_STATISTICS_ENABLED);
        await this._readProperty(buffer, PROP_GROUP_NAME);
        await this._readProperty(buffer, PROP_DEFAULT_LOCK_TIMEOUT);
        await this._readProperty(buffer, PROP_MAX_CONCURRENT_ASYNC_OPS);
        await this._readProperty(buffer, PROP_MAX_QUERY_ITERATORS);
        await this._readProperty(buffer, PROP_NAME);
        await this._readProperty(buffer, PROP_IS_ONHEAP_CACHE_ENABLED);
        await this._readProperty(buffer, PROP_PARTITION_LOSS_POLICY);
        await this._readProperty(buffer, PROP_QUERY_DETAIL_METRICS_SIZE);
        await this._readProperty(buffer, PROP_QUERY_PARALLELISM);
        await this._readProperty(buffer, PROP_READ_FROM_BACKUP);
        await this._readProperty(buffer, PROP_REBALANCE_BATCH_SIZE);
        await this._readProperty(buffer, PROP_REBALANCE_BATCHES_PREFETCH_COUNT);
        await this._readProperty(buffer, PROP_REBALANCE_DELAY);
        await this._readProperty(buffer, PROP_REBALANCE_MODE);
        await this._readProperty(buffer, PROP_REBALANCE_ORDER);
        await this._readProperty(buffer, PROP_REBALANCE_THROTTLE);
        await this._readProperty(buffer, PROP_REBALANCE_TIMEOUT);
        await this._readProperty(buffer, PROP_SQL_ESCAPE_ALL);
        await this._readProperty(buffer, PROP_SQL_INDEX_INLINE_MAX_SIZE);
        await this._readProperty(buffer, PROP_SQL_SCHEMA);
        await this._readProperty(buffer, PROP_WRITE_SYNCHRONIZATION_MODE);
        await this._readProperty(buffer, PROP_CACHE_KEY_CONFIGURATION);
        await this._readProperty(buffer, PROP_QUERY_ENTITY);
    }

    /**
     * @ignore
     */
    async _readProperty(buffer, propertyCode) {
        const propertyType = PROP_TYPES[propertyCode];
        switch (BinaryUtils.getTypeCode(propertyType)) {
            case BinaryUtils.TYPE_CODE.INTEGER:
            case BinaryUtils.TYPE_CODE.LONG:
            case BinaryUtils.TYPE_CODE.BOOLEAN:
                this._properties.set(propertyCode, await BinaryReader._readTypedObject(buffer, propertyType));
                return;
            case BinaryUtils.TYPE_CODE.STRING:
                this._properties.set(propertyCode, await BinaryReader.readObject(buffer, propertyType));
                return;
            case BinaryUtils.TYPE_CODE.OBJECT_ARRAY:
                const length = buffer.readInteger();
                if (length > 0) {
                    const properties = new Array(length);
                    for (let i = 0; i &lt; length; i++) {
                        const property = new propertyType._elementType._objectConstructor();
                        await property._read(buffer);
                        properties[i] = property;
                    }
                    this._properties.set(propertyCode, properties);
                }
                return;
            default:
                throw Errors.IgniteClientError.internalError();
        }
    }
}

module.exports = CacheConfiguration;
module.exports.QueryEntity = QueryEntity;
module.exports.QueryField = QueryField;
module.exports.QueryIndex = QueryIndex;
module.exports.CacheKeyConfiguration = CacheKeyConfiguration;
</code></pre>
        </article>
    </section>




</div>

<nav>
    <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="BinaryObject.html">BinaryObject</a></li><li><a href="CacheClient.html">CacheClient</a></li><li><a href="CacheConfiguration.html">CacheConfiguration</a></li><li><a href="CacheEntry.html">CacheEntry</a></li><li><a href="CacheKeyConfiguration.html">CacheKeyConfiguration</a></li><li><a href="CollectionObjectType.html">CollectionObjectType</a></li><li><a href="ComplexObjectType.html">ComplexObjectType</a></li><li><a href="CompositeType.html">CompositeType</a></li><li><a href="Cursor.html">Cursor</a></li><li><a href="EnumItem.html">EnumItem</a></li><li><a href="IgniteClient.html">IgniteClient</a></li><li><a href="IgniteClientConfiguration.html">IgniteClientConfiguration</a></li><li><a href="IgniteClientError.html">IgniteClientError</a></li><li><a href="IllegalStateError.html">IllegalStateError</a></li><li><a href="LostConnectionError.html">LostConnectionError</a></li><li><a href="MapObjectType.html">MapObjectType</a></li><li><a href="ObjectArrayType.html">ObjectArrayType</a></li><li><a href="ObjectType.html">ObjectType</a></li><li><a href="OperationError.html">OperationError</a></li><li><a href="Query.html">Query</a></li><li><a href="QueryEntity.html">QueryEntity</a></li><li><a href="QueryField.html">QueryField</a></li><li><a href="QueryIndex.html">QueryIndex</a></li><li><a href="ScanQuery.html">ScanQuery</a></li><li><a href="SqlFieldsCursor.html">SqlFieldsCursor</a></li><li><a href="SqlFieldsQuery.html">SqlFieldsQuery</a></li><li><a href="SqlQuery.html">SqlQuery</a></li><li><a href="Timestamp.html">Timestamp</a></li></ul>
</nav>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Tue May 22 2018 12:08:48 GMT+0300 (Russia TZ 2 Standard Time)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>
