From 4801a2ce250f4005f7689450fbb82f8c9b3b7649 Mon Sep 17 00:00:00 2001 From: Ranajit Banerjee Date: Mon, 24 Sep 2018 11:50:58 +0530 Subject: [PATCH 1/4] CDC-67: Propagate from group by model only if proapgateInterpolatedValues is true - Refactor code --- src/datamodel.js | 52 ++---- src/helper.js | 277 +++++++++++++++++----------- src/operator/child-iterator.js | 92 --------- src/operator/child-iterator.spec.js | 42 ----- src/operator/index.js | 1 - 5 files changed, 184 insertions(+), 280 deletions(-) delete mode 100644 src/operator/child-iterator.js delete mode 100644 src/operator/child-iterator.spec.js diff --git a/src/datamodel.js b/src/datamodel.js index be69e3a..3ca4d43 100644 --- a/src/datamodel.js +++ b/src/datamodel.js @@ -6,7 +6,8 @@ import { getRootGroupByModel, propagateToAllDataModels, getRootDataModel, - propagateImmutableActions + propagateImmutableActions, + addToPropNamespace } from './helper'; import { DM_DERIVATIVES, PROPAGATION } from './constants'; import { @@ -393,9 +394,10 @@ class DataModel extends Relation { * * @return {DataModel} DataModel instance. */ - propagate (identifiers, payload, config = {}) { + propagate (identifiers, config = {}, addToNameSpace) { const isMutableAction = config.isMutableAction; const propagationSourceId = config.sourceId; + const payload = config.payload; const rootModel = getRootDataModel(this); const propagationNameSpace = rootModel._propagationNameSpace; const rootGroupByModel = getRootGroupByModel(this); @@ -403,48 +405,20 @@ class DataModel extends Relation { groupByModel: rootGroupByModel, model: rootModel }; - - propagateToAllDataModels(identifiers, rootModels, { - propagationNameSpace, - payload, - propagationSourceId - }); - - if (isMutableAction) { - propagateImmutableActions(propagationNameSpace, rootModels, propagationSourceId); - } - return this; - } - - addToPropNamespace (sourceId, config = {}) { - let sourceNamespace; - const actionName = config.actionName; - const payload = config.payload; - const isMutableAction = config.isMutableAction; - const rootModel = getRootDataModel(this); - const propagationNameSpace = rootModel._propagationNameSpace; - const criteria = config.criteria; + addToNameSpace && addToPropNamespace(propagationNameSpace, config, this); + propagateToAllDataModels(identifiers, rootModels, { propagationNameSpace, sourceId: propagationSourceId }, + Object.assign({ + payload + }, config)); if (isMutableAction) { - !propagationNameSpace.mutableActions[sourceId] && (propagationNameSpace.mutableActions[sourceId] = {}); - sourceNamespace = propagationNameSpace.mutableActions[sourceId]; - } else { - !propagationNameSpace.immutableActions[sourceId] && (propagationNameSpace.immutableActions[sourceId] = {}); - sourceNamespace = propagationNameSpace.immutableActions[sourceId]; - } - - if (criteria === null) { - delete sourceNamespace[actionName]; - } else { - sourceNamespace[actionName] = { - criteria, - payload - }; + propagateImmutableActions(propagationNameSpace, rootModels, propagationSourceId, this); } return this; } + /** * Associates a callback with an event name. * @@ -484,9 +458,9 @@ class DataModel extends Relation { * @param {DataModel} identifiers The propagated DataModel. * @memberof DataModel */ - handlePropagation (payload) { + handlePropagation (propModel, payload) { let propListeners = this._onPropagation; - propListeners.forEach(fn => fn.call(this, payload)); + propListeners.forEach(fn => fn.call(this, propModel, payload)); } /** diff --git a/src/helper.js b/src/helper.js index 5ade5dd..b460022 100644 --- a/src/helper.js +++ b/src/helper.js @@ -3,11 +3,7 @@ import Field from './fields/field'; import fieldStore from './field-store'; import Value from './value'; import { - rowDiffsetIterator, - groupByIterator, - projectIterator, - selectIterator, - calculatedVariableIterator + rowDiffsetIterator } from './operator'; import { DM_DERIVATIVES, LOGICAL_OPERATORS } from './constants'; import createFields from './field-creator'; @@ -82,7 +78,7 @@ export const filterPropagationModel = (model, propModels, config = {}) => { const operation = config.operation || LOGICAL_OPERATORS.AND; const filterByMeasure = config.filterByMeasure || false; let fns = []; - if (propModels === null) { + if (!propModels.length) { fns = [() => false]; } else { fns = propModels.map(propModel => ((dataModel) => { @@ -209,81 +205,74 @@ export const fieldInSchema = (schema, field) => { return null; }; -export const propagateIdentifiers = (dataModel, propModel, config = {}, nonTraversingModel, grouped) => { - // function to propagate to target the DataModel instance. - const forwardPropagation = (targetDM, propagationData, hasGrouped) => { - propagateIdentifiers(targetDM, propagationData, config, nonTraversingModel, hasGrouped); + +export const getOperationArguments = (child) => { + const derivation = child._derivation; + let params = []; + let operation; + if (derivation && derivation.length === 1) { + operation = derivation[0].op; + switch (operation) { + case DM_DERIVATIVES.SELECT: + params = [derivation[0].criteria]; + break; + case DM_DERIVATIVES.PROJECT: + params = [derivation[0].meta.actualProjField]; + break; + case DM_DERIVATIVES.GROUPBY: + operation = 'groupBy'; + params = [derivation[0].meta.groupByString.split(','), derivation[0].criteria]; + break; + default: + break; + } + } + + return { + operation, + params }; +}; - if (dataModel === nonTraversingModel) { - return; +const applyExistingOperationOnModel = (propModel, dataModel) => { + const { operation, params } = getOperationArguments(dataModel); + let selectionModel = propModel[0]; + let rejectionModel = propModel[1]; + if (operation && params.length) { + selectionModel = propModel[0][operation](...params, { + saveChild: false + }); + rejectionModel = propModel[1][operation](...params, { + saveChild: false + }); } + return [selectionModel, rejectionModel]; +}; - dataModel.handlePropagation({ - payload: config.payload, - data: propModel, - sourceIdentifiers: config.sourceIdentifiers, - sourceId: config.propagationSourceId, - groupedPropModel: !!grouped - }); +const getFilteredModel = (propModel, path) => { + for (let i = 0, len = path.length; i < len; i++) { + const model = path[i]; + propModel = applyExistingOperationOnModel(propModel, model); + } + return propModel; +}; - // propagate to children created by SELECT operation - selectIterator(dataModel, (targetDM, criteria) => { - if (targetDM !== nonTraversingModel) { - const selectionModel = propModel[0].select(criteria, { - saveChild: false - }); - const rejectionModel = propModel[1].select(criteria, { - saveChild: false - }); +const propagateIdentifiers = (dataModel, propModel, config = {}, propModelInf = {}) => { + const nonTraversingModel = propModelInf.nonTraversingModel; + const excludeModels = propModelInf.excludeModels || []; - forwardPropagation(targetDM, [selectionModel, rejectionModel], grouped); - } - }); - // propagate to children created by PROJECT operation - projectIterator(dataModel, (targetDM, projField) => { - if (targetDM !== nonTraversingModel) { - const projModel = propModel[0].project(projField, { - saveChild: false - }); - const rejectionProjModel = propModel[1].project(projField, { - saveChild: false - }); + if (dataModel === nonTraversingModel) { + return; + } - forwardPropagation(targetDM, [projModel, rejectionProjModel], grouped); - } - }); + const propagate = excludeModels.length ? excludeModels.indexOf(dataModel) === -1 : true; - // propagate to children created by groupBy operation - groupByIterator(dataModel, (targetDM, conf) => { - if (targetDM !== nonTraversingModel) { - const { - reducer, - groupByString - } = conf; - // group the filtered model based on groupBy string of target - const selectionGroupedModel = propModel[0].groupBy(groupByString.split(','), reducer, { - saveChild: false - }); - const rejectionGroupedModel = propModel[1].groupBy(groupByString.split(','), reducer, { - saveChild: false - }); - forwardPropagation(targetDM, [selectionGroupedModel, rejectionGroupedModel], true); - } - }); + propagate && dataModel.handlePropagation(propModel, config); - calculatedVariableIterator(dataModel, (targetDM, ...params) => { - if (targetDM !== nonTraversingModel) { - const entryModel = propModel[0].clone(false, false).calculateVariable(...params, { - saveChild: false, - replaceVar: true - }); - const exitModel = propModel[1].clone(false, false).calculateVariable(...params, { - saveChild: false, - replaceVar: true - }); - forwardPropagation(targetDM, [entryModel, exitModel], grouped); - } + const children = dataModel._children; + children.forEach((child) => { + let [selectionModel, rejectionModel] = applyExistingOperationOnModel(propModel, child); + propagateIdentifiers(child, [selectionModel, rejectionModel], config, propModelInf); }); }; @@ -301,59 +290,135 @@ export const getRootDataModel = (model) => { return model; }; -export const propagateToAllDataModels = (identifiers, rootModels, config) => { +export const getPathToRootModel = (model, path = []) => { + if (model._parent !== null) { + path.push(model); + getPathToRootModel(model._parent, path); + } + return path; +}; + +export const propagateToAllDataModels = (identifiers, rootModels, propagationInf, config) => { let criteria; let propModel; - const propagationNameSpace = config.propagationNameSpace; - const payload = config.payload; - const propagationSourceId = config.propagationSourceId; + const { propagationNameSpace, propagateToSource } = propagationInf; + const propagationSourceId = propagationInf.sourceId; + const propagateInterpolatedValues = config.propagateInterpolatedValues; + const filterFn = (entry) => { + const filter = config.filterFn || (() => true); + return filter(entry, config); + }; - if (identifiers === null) { - criteria = null; + let criterias = []; + + if (identifiers === null && config.persistent !== true) { + criterias = [{ + criteria: [] + }]; } else { - const filteredCriteria = Object.entries(propagationNameSpace.mutableActions) - .filter(d => d[0] !== propagationSourceId) - .map(d => Object.values(d[1]).map(action => action.criteria)); - criteria = [].concat(...[...filteredCriteria, identifiers]); + let actionCriterias = Object.values(propagationNameSpace.mutableActions); + if (propagateToSource !== false) { + actionCriterias = actionCriterias.filter(d => d.config.sourceId !== propagationSourceId); + } + + const filteredCriteria = actionCriterias.filter(filterFn).map(action => action.config.criteria); + + const excludeModels = []; + + if (propagateToSource !== false) { + const sourceActionCriterias = Object.values(propagationNameSpace.mutableActions); + + sourceActionCriterias.forEach((actionInf) => { + const actionConf = actionInf.config; + if (actionConf.applyOnSource === false && actionConf.action === config.action && + actionConf.sourceId !== propagationSourceId) { + excludeModels.push(actionInf.model); + criterias.push({ + criteria: sourceActionCriterias.filter(d => d !== actionInf).map(d => d.config.criteria), + models: actionInf.model, + path: getPathToRootModel(actionInf.model) + }); + } + }); + } + + + criteria = [].concat(...[...filteredCriteria, identifiers]).filter(d => d !== null); + criterias.push({ + criteria, + excludeModels: [...excludeModels, ...config.excludeModels || []] + }); } - const rootGroupByModel = rootModels.groupByModel; const rootModel = rootModels.model; - const propConfig = { - payload, - propagationSourceId, - sourceIdentifiers: identifiers - }; - if (rootGroupByModel) { + const propConfig = Object.assign({ + sourceIdentifiers: identifiers, + propagationSourceId + }, config); + + const rootGroupByModel = rootModels.groupByModel; + if (propagateInterpolatedValues && rootGroupByModel) { propModel = filterPropagationModel(rootGroupByModel, criteria, { - filterByMeasure: true + filterByMeasure: propagateInterpolatedValues }); propagateIdentifiers(rootGroupByModel, propModel, propConfig); } - propModel = filterPropagationModel(rootModel, criteria, { - filterByMeasure: !rootGroupByModel + criterias.forEach((inf) => { + const propagationModel = filterPropagationModel(rootModel, inf.criteria); + const path = inf.path; + + if (path) { + const filteredModel = getFilteredModel(propagationModel, path.reverse()); + inf.models.handlePropagation(filteredModel, propConfig); + } else { + propagateIdentifiers(rootModel, propagationModel, propConfig, { + models: inf.models, + type: inf.type, + nonTraversingModel: propagateInterpolatedValues && rootGroupByModel + }); + } }); - propagateIdentifiers(rootModel, propModel, propConfig, rootGroupByModel); }; export const propagateImmutableActions = (propagationNameSpace, rootModels, propagationSourceId) => { - const rootGroupByModel = rootModels.groupByModel; - const rootModel = rootModels.model; const immutableActions = propagationNameSpace.immutableActions; - for (const sourceId in immutableActions) { - const actions = immutableActions[sourceId]; - for (const action in actions) { - const criteriaModel = actions[action].criteria; - propagateToAllDataModels(criteriaModel, { - groupByModel: rootGroupByModel, - model: rootModel - }, { + + for (const action in immutableActions) { + const actionInf = immutableActions[action]; + const actionConf = actionInf.config; + if (actionConf.sourceId !== propagationSourceId) { + const criteriaModel = actionConf.criteria; + propagateToAllDataModels(criteriaModel, rootModels, { propagationNameSpace, - payload: actions[action].payload, - propagationSourceId - }); + propagateToSource: false, + sourceId: propagationSourceId + }, actionConf); } } }; + +export const addToPropNamespace = (propagationNameSpace, config = {}, model) => { + let sourceNamespace; + const isMutableAction = config.isMutableAction; + const criteria = config.criteria; + const key = `${config.action}-${config.sourceId}`; + + if (isMutableAction) { + sourceNamespace = propagationNameSpace.mutableActions; + } else { + sourceNamespace = propagationNameSpace.immutableActions; + } + + if (criteria === null) { + delete sourceNamespace[key]; + } else { + sourceNamespace[key] = { + model, + config + }; + } + + return this; +}; diff --git a/src/operator/child-iterator.js b/src/operator/child-iterator.js deleted file mode 100644 index 1902fcb..0000000 --- a/src/operator/child-iterator.js +++ /dev/null @@ -1,92 +0,0 @@ -/* eslint-disable default-case */ -import { DM_DERIVATIVES } from '../constants'; - -/** - * iterate the children and call the callback for each - * - * @param {DataModel} datamodel - * @param {function} callback - * @param {DM_DERIVATIVES} operation - */ -function childIterator (datamodel, callback, operation) { - const children = datamodel._children; - children.forEach((child) => { - if (child._derivation - && child._derivation.length === 1) { - switch (operation) { - case DM_DERIVATIVES.SELECT: - if (child._derivation[0].op === DM_DERIVATIVES.SELECT) { - callback(child, child._derivation[0].criteria); - } - break; - case DM_DERIVATIVES.PROJECT: - if (child._derivation[0].op === DM_DERIVATIVES.PROJECT) { - callback(child, child._derivation[0].meta.actualProjField); - } - break; - case DM_DERIVATIVES.GROUPBY: - if (child._derivation[0].op === DM_DERIVATIVES.GROUPBY) { - callback(child, - { groupByString: child._derivation[0].meta.groupByString, - reducer: child._derivation[0].criteria }); - } - break; - case DM_DERIVATIVES.CAL_VAR: - if (child._derivation[0].op === DM_DERIVATIVES.CAL_VAR) { - let params = [child._derivation[0].meta.config, [child._derivation[0].meta.fields, - child._derivation[0].criteria]]; - callback(child, ...params); - } - break; - } - } - }); -} - -/** - * Invokes a callback for every child created by a selection operation on a DataModel. - * - * @param {DataModel} datamodel - The input DataModel instance. - * @param {Function} callback - The callback to be invoked on each child. The parameters - * provided to the callback are the child DataModel instance and the selection - * function used to create it. - */ -export function selectIterator (datamodel, callback) { - childIterator(datamodel, callback, DM_DERIVATIVES.SELECT); -} - -/** - * Invokes a callback for every measure child of a DataModel. - * - * @param {DataModel} datamodel - The input DataModel instance. - * @param {Function} callback - The callback to be invoked on each measure child. The parameters - * provided to the callback are the child DataModel instance and the child params. - */ -export function calculatedVariableIterator (datamodel, callback) { - childIterator(datamodel, callback, DM_DERIVATIVES.CAL_VAR); -} - -/** - * Invokes a callback for every projected child of a DataModel. - * - * @param {DataModel} datamodel - The input DataModel instance. - * @param {Function} callback - The callback to be invoked on each projected child. The parameters - * provided to the callback are the child DataModel instance and the - * projection string. - */ -export function projectIterator (datamodel, callback) { - childIterator(datamodel, callback, DM_DERIVATIVES.PROJECT); -} - -/** - * Invokes a callback over the children created by a groupBy - * operation on a DataModel. - * - * @param {DataModel} datamodel - The input DataModel instance. - * @param {Function} callback - The callback to be invoked. The parameters - * provided to the callback are the child DataModel instance and the groupBy string used to create it. - */ -export function groupByIterator (datamodel, callback) { - childIterator(datamodel, callback, DM_DERIVATIVES.GROUPBY); -} - diff --git a/src/operator/child-iterator.spec.js b/src/operator/child-iterator.spec.js deleted file mode 100644 index 9822ec5..0000000 --- a/src/operator/child-iterator.spec.js +++ /dev/null @@ -1,42 +0,0 @@ -/* global describe, it */ -/* eslint-disable no-unused-expressions,no-unused-vars */ - -import { expect } from 'chai'; -import { calculatedVariableIterator } from './child-iterator'; -import DataModel from '../index'; - -const data1 = [ - { profit: 10, sales: 20, city: 'a' }, - { profit: 15, sales: 25, city: 'b' }, -]; -const schema1 = [ - { name: 'profit', type: 'measure' }, - { name: 'sales', type: 'measure' }, - { name: 'city', type: 'dimension' }, -]; - -describe('Testing Child Iterator', () => { - let dm = new DataModel(data1, schema1); - let createdCallBack = (profit, sales) => profit / sales; - let hasSameChild = false; - let hasSameFunction = false; - const child = dm.calculateVariable({ - name: 'Efficiency' - }, ['profit', 'sales', createdCallBack]); - - let callback = (model, ...params) => { - if (dm._children.find(childElm => childElm === model)) { - hasSameChild = true; - } - if (params[1][1] === createdCallBack) { - hasSameFunction = true; - } - }; - describe('#calculatedVariableIterator', () => { - it('Should return expected child and its callback', () => { - calculatedVariableIterator(dm, callback); - expect(hasSameChild).to.equal(true); - expect(hasSameFunction).to.equal(true); - }); - }); -}); diff --git a/src/operator/index.js b/src/operator/index.js index d66949a..bf04b32 100644 --- a/src/operator/index.js +++ b/src/operator/index.js @@ -1,5 +1,4 @@ export { createBinnedFieldData } from './bucket-creator'; -export { selectIterator, calculatedVariableIterator, projectIterator, groupByIterator } from './child-iterator'; export { compose, bin, select, project, groupBy as groupby } from './compose'; export { calculateVariable, sort } from './pure-operators'; export { crossProduct } from './cross-product'; From 1c34eaf2c4315e54737e6ed535974d6c3ab74fd9 Mon Sep 17 00:00:00 2001 From: Ranajit Banerjee Date: Mon, 24 Sep 2018 12:40:32 +0530 Subject: [PATCH 2/4] CDC-67: Refactor code --- src/helper.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/helper.js b/src/helper.js index b460022..e9e6abc 100644 --- a/src/helper.js +++ b/src/helper.js @@ -333,8 +333,9 @@ export const propagateToAllDataModels = (identifiers, rootModels, propagationInf if (actionConf.applyOnSource === false && actionConf.action === config.action && actionConf.sourceId !== propagationSourceId) { excludeModels.push(actionInf.model); - criterias.push({ - criteria: sourceActionCriterias.filter(d => d !== actionInf).map(d => d.config.criteria), + criteria = sourceActionCriterias.filter(d => d !== actionInf).map(d => d.config.criteria); + criteria.length && criterias.push({ + criteria, models: actionInf.model, path: getPathToRootModel(actionInf.model) }); @@ -374,8 +375,7 @@ export const propagateToAllDataModels = (identifiers, rootModels, propagationInf inf.models.handlePropagation(filteredModel, propConfig); } else { propagateIdentifiers(rootModel, propagationModel, propConfig, { - models: inf.models, - type: inf.type, + excludeModels: inf.excludeModels, nonTraversingModel: propagateInterpolatedValues && rootGroupByModel }); } From bc9477907c125f0b5b375b8d7136a812e97aa0c9 Mon Sep 17 00:00:00 2001 From: Ranajit Banerjee Date: Mon, 1 Oct 2018 12:43:13 +0530 Subject: [PATCH 3/4] CDC-67: Filter immutable actions --- src/datamodel.js | 9 ++++++--- src/helper.js | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/datamodel.js b/src/datamodel.js index 3ca4d43..4aac748 100644 --- a/src/datamodel.js +++ b/src/datamodel.js @@ -394,7 +394,7 @@ class DataModel extends Relation { * * @return {DataModel} DataModel instance. */ - propagate (identifiers, config = {}, addToNameSpace) { + propagate (identifiers, config = {}, addToNameSpace, propConfig = {}) { const isMutableAction = config.isMutableAction; const propagationSourceId = config.sourceId; const payload = config.payload; @@ -405,6 +405,7 @@ class DataModel extends Relation { groupByModel: rootGroupByModel, model: rootModel }; + addToNameSpace && addToPropNamespace(propagationNameSpace, config, this); propagateToAllDataModels(identifiers, rootModels, { propagationNameSpace, sourceId: propagationSourceId }, Object.assign({ @@ -412,13 +413,15 @@ class DataModel extends Relation { }, config)); if (isMutableAction) { - propagateImmutableActions(propagationNameSpace, rootModels, propagationSourceId, this); + propagateImmutableActions(propagationNameSpace, rootModels, { + config, + propConfig + }, this); } return this; } - /** * Associates a callback with an event name. * diff --git a/src/helper.js b/src/helper.js index e9e6abc..25f18bc 100644 --- a/src/helper.js +++ b/src/helper.js @@ -382,13 +382,16 @@ export const propagateToAllDataModels = (identifiers, rootModels, propagationInf }); }; -export const propagateImmutableActions = (propagationNameSpace, rootModels, propagationSourceId) => { +export const propagateImmutableActions = (propagationNameSpace, rootModels, propagationInf) => { const immutableActions = propagationNameSpace.immutableActions; for (const action in immutableActions) { const actionInf = immutableActions[action]; const actionConf = actionInf.config; - if (actionConf.sourceId !== propagationSourceId) { + const propagationSourceId = propagationInf.config.sourceId; + const filterImmutableAction = propagationInf.propConfig.filterImmutableAction ? + propagationInf.propConfig.filterImmutableAction(actionConf, propagationInf.config) : true; + if (actionConf.sourceId !== propagationSourceId && filterImmutableAction) { const criteriaModel = actionConf.criteria; propagateToAllDataModels(criteriaModel, rootModels, { propagationNameSpace, From 76abc742a3daad0f1696c7989a077d22baf49997 Mon Sep 17 00:00:00 2001 From: Rousan Ali Date: Mon, 1 Oct 2018 16:36:31 +0530 Subject: [PATCH 4/4] Bump the version to v2.0.2 and make a build --- dist/datamodel.js | 2 +- dist/datamodel.js.map | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/datamodel.js b/dist/datamodel.js index ab032fd..d7f051f 100644 --- a/dist/datamodel.js +++ b/dist/datamodel.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("DataModel",[],t):"object"==typeof exports?exports.DataModel=t():e.DataModel=t()}(window,function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e){e.exports={name:"datamodel",description:"Relational algebra compliant in-memory tabular data store",homepage:"https://github.com/chartshq/datamodel",version:"2.0.1",license:"MIT",main:"dist/datamodel.js",author:"Charts.com ",keywords:["datamodel","data","relational","algebra","model","muze","fusioncharts","table","tabular","operation"],repository:{type:"git",url:"https://github.com/chartshq/datamodel.git"},contributors:[{name:"Akash Goswami",email:"akash@charts.com"},{name:"Subhash Haldar",email:"subhash@charts.com"},{name:"Rousan Ali",email:"rousan@charts.com",url:"https://rousan.io"},{name:"Ujjal Kumar Dutta",email:"ujjal@charts.com"}],dependencies:{"d3-dsv":"^1.0.8"},devDependencies:{"babel-cli":"6.26.0","babel-core":"^6.26.3","babel-eslint":"6.1.2","babel-loader":"^7.1.4","babel-plugin-transform-runtime":"^6.23.0","babel-preset-env":"^1.7.0","babel-preset-es2015":"^6.24.1","babel-preset-flow":"^6.23.0",chai:"3.5.0","cross-env":"^5.0.5",eslint:"3.19.0","eslint-config-airbnb":"15.1.0","eslint-plugin-import":"2.7.0","eslint-plugin-jsx-a11y":"5.1.1","eslint-plugin-react":"7.3.0","istanbul-instrumenter-loader":"^3.0.0",jsdoc:"3.5.5",json2yaml:"^1.1.0",karma:"1.7.1","karma-chai":"0.1.0","karma-chrome-launcher":"2.1.1","karma-coverage-istanbul-reporter":"^1.3.0","karma-mocha":"1.3.0","karma-spec-reporter":"0.0.31","karma-webpack":"2.0.3",marked:"^0.5.0",mocha:"3.4.2","mocha-webpack":"0.7.0","transform-runtime":"0.0.0",webpack:"^4.12.0","webpack-cli":"^3.0.7","webpack-dev-server":"^3.1.4"},scripts:{test:"npm run lint && npm run ut",ut:"karma start karma.conf.js",utd:"karma start --single-run false --browsers Chrome karma.conf.js ",build:"webpack --mode production",start:"webpack-dev-server --config webpack.config.dev.js --mode development --open",lint:"eslint ./src","lint-errors":"eslint --quiet ./src",docs:"rm -rf yaml && mkdir yaml && jsdoc -c jsdoc.conf.json"}}},function(e,t,n){var r=n(2);e.exports=r.default?r.default:r},function(e,t,n){"use strict";n.r(t);var r={};n.r(r),n.d(r,"DataFormat",function(){return o}),n.d(r,"DimensionSubtype",function(){return u}),n.d(r,"MeasureSubtype",function(){return c}),n.d(r,"FieldType",function(){return f}),n.d(r,"FilteringMode",function(){return s});var i={};n.r(i),n.d(i,"DSVArr",function(){return je}),n.d(i,"DSVStr",function(){return Ie}),n.d(i,"FlatJSON",function(){return Le}),n.d(i,"Auto",function(){return Ue});var a={};n.r(a),n.d(a,"sum",function(){return it}),n.d(a,"avg",function(){return at}),n.d(a,"min",function(){return ot}),n.d(a,"max",function(){return ut}),n.d(a,"first",function(){return ct}),n.d(a,"last",function(){return ft}),n.d(a,"count",function(){return st}),n.d(a,"sd",function(){return lt});var o={FLAT_JSON:"FlatJSON",DSV_STR:"DSVStr",DSV_ARR:"DSVArr",AUTO:"Auto"},u={CATEGORICAL:"categorical",TEMPORAL:"temporal",GEO:"geo"},c={DISCRETE:"discrete"},f={MEASURE:"measure",DIMENSION:"dimension"},s={NORMAL:"normal",INVERSE:"inverse",ALL:"all"};function l(e,t){e.length>0&&e.split(",").forEach(function(e){var n=e.split("-"),r=+n[0],i=+(n[1]||n[0]);if(i>=r)for(var a=r;a<=i;a+=1)t(a)})}var d=function(){function e(e,t){for(var n=0;n=0;)o=e[a+1],-1!==r.indexOf(o)&&i.push({index:a,token:o});return i},m.formatAs=function(e,t){var n,r=h(e),i=m.findTokens(t),a=m.getTokenDefinitions(),o=String(t),u=m.TOKEN_PREFIX,c=void 0,f=void 0,s=void 0;for(s=0,n=i.length;s=0;d--)(f=a[d].index)+1!==l.length-1?(void 0===u&&(u=l.length),s=l.substring(f+2,u),l=l.substring(0,f+2)+RegExp.escape(s)+l.substring(u,l.length),u=f):u=f;for(d=0;d1){n=Math.abs(r[1]-r[0]);for(var i=2,a=r.length;i=y&&t.data=r.stops[r.stops.length-1]}).forEach(function(e){c[e.index]=r.stops[r.stops.length-1]+"-"+h}),r.stops.unshift(r.start),b=new Set(r.stops),dr.stops[r.stops.length-1]&&b.add(h),b=[].concat(function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t3&&void 0!==arguments[3]&&arguments[3],i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:U.CROSS,a=[],o=[],u=n||Y,c=e.getFieldspace(),f=t.getFieldspace(),s=c.name,d=f.name,p=c.name+"."+f.name,h=B(c,f);if(s===d)throw new Error("DataModels must have different alias names");return c.fields.forEach(function(e){var t=w({},e.schema);-1===h.indexOf(t.name)||r||(t.name=c.name+"."+t.name),a.push(t)}),f.fields.forEach(function(e){var t=w({},e.schema);-1!==h.indexOf(t.name)?r||(t.name=f.name+"."+t.name,a.push(t)):a.push(t)}),l(e._rowDiffset,function(e){var n=!1,p=void 0;l(t._rowDiffset,function(t){var l=[],v={};v[s]={},v[d]={},c.fields.forEach(function(t){l.push(t.data[e]),v[s][t.name]=t.data[e]}),f.fields.forEach(function(e){-1!==h.indexOf(e.schema.name)&&r||l.push(e.data[t]),v[d][e.name]=e.data[t]});var m=Ye(v[s]),y=Ye(v[d]);if(u(m,y)){var g={};l.forEach(function(e,t){g[a[t].name]=e}),n&&U.CROSS!==i?o[p]=g:(o.push(g),n=!0,p=e)}else if((i===U.LEFTOUTER||i===U.RIGHTOUTER)&&!n){var b={},_=c.fields.length-1;l.forEach(function(e,t){b[a[t].name]=t<=_?e:null}),n=!0,p=e,o.push(b)}})}),new rt(o,a,{name:p})}function G(e,t){var n=""+e,r=""+t;return nr?1:0}function q(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:G;return e.length>1&&function e(t,n,r,i){if(r===n)return t;var a=n+Math.floor((r-n)/2);return e(t,n,a,i),e(t,a+1,r,i),function(e,t,n,r,i){for(var a=e,o=[],u=t;u<=r;u+=1)o[u]=a[u];for(var c=t,f=n+1,s=t;s<=r;s+=1)c>n?(a[s]=o[f],f+=1):f>r?(a[s]=o[c],c+=1):i(o[c],o[f])<=0?(a[s]=o[c],c+=1):(a[s]=o[f],f+=1)}(t,n,a,r,i),t}(e,0,e.length-1,t),e}function K(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);ta?"desc"===t?-1:1:0}}return r}function z(e,t){var n=new Map,r=[];return e.forEach(function(e){var i=e[t];n.has(i)?r[n.get(i)][1].push(e):(r.push([i,[e]]),n.set(i,r.length-1))}),r}function X(e,t,n){var r={label:e[0]};return t.reduce(function(t,r,i){return t[r]=e[1].map(function(e){return e[n[i].index]}),t},r),r}function Q(e,t,n,r,i){var a={schema:[],data:[],uids:[]},o=(i=Object.assign({},{addUid:!1,columnWise:!1},i)).addUid,u=r&&r.length>0,c=[];if(n.split(",").forEach(function(t){for(var n=0;n=0;u--)i=t[u][0],a=t[u][1],(o=ze(r,i))&&(j(a)?q(n,function(e,t){return a(e[o.index],t[o.index])}):S(a)?function(){var e=z(n,o.index),t=a[a.length-1],i=a.slice(0,a.length-1),u=i.map(function(e){return ze(r,e)});e.forEach(function(e){e.push(X(e,i,u))}),q(e,function(e,n){var r=e[2],i=n[2];return t(r,i)}),n.length=0,e.forEach(function(e){n.push.apply(n,K(e[1]))})}():(a="desc"===String(a).toLowerCase()?"desc":"asc",q(n,W(o.type,a,o.index))));e.uids=[],n.forEach(function(t){e.uids.push(t.pop())})}(a,r),i.columnWise){var f=Array.apply(void 0,K(Array(a.schema.length))).map(function(){return[]});a.data.forEach(function(e){e.forEach(function(e,t){f[t].push(e)})}),a.data=f}return a}function $(e,t){var n={},r=[],i=[],a=[],o=e.getFieldspace(),u=t.getFieldspace(),c=o.fieldsObj(),f=u.fieldsObj(),s=o.name+" union "+u.name;if(!P(e._colIdentifier.split(",").sort(),t._colIdentifier.split(",").sort()))return null;function d(e,t,r){l(e._rowDiffset,function(e){var o={},u="";i.forEach(function(n){var r=t[n].data[e];u+="-"+r,o[n]=r}),n[u]||(r&&a.push(o),n[u]=!0)})}return e._colIdentifier.split(",").forEach(function(e){var t=c[e];r.push(w({},t.schema)),i.push(t.schema.name)}),d(t,f,!1),d(e,c,!0),new rt(a,r,{name:s})}function Z(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t1&&void 0!==arguments[1]?arguments[1]:{},n={},r=t,i=e.getPartialFieldspace().getMeasure(),a=oe.defaultReducer();return"function"==typeof t&&(a=t),Object.entries(i).forEach(function(e){var o=ue(e,1)[0];"string"==typeof t[o]&&(r[o]=oe.resolve(r[o])?oe.resolve(r[o]):a),"function"!=typeof t[o]&&(r[o]=void 0),n[o]=r[o]||oe.resolve(i[o].defAggFn())||a}),n}(e,n),o=e.getPartialFieldspace(),u=o.fieldsObj(),c=o.name,f=[],s=[],d=[],p={},h=[],v=void 0;Object.entries(u).forEach(function(e){var t=ue(e,2),n=t[0],r=t[1];(-1!==i.indexOf(n)||a[n])&&(d.push(w({},r.schema)),"measure"===r.schema.type&&"discrete"!==r.schema.subtype?s.push(n):"dimension"!==r.schema.type&&"discrete"!==r.schema.subtype||f.push(n))});var m=0;return l(e._rowDiffset,function(e){var t="";f.forEach(function(n){t=t+"-"+u[n].data[e]}),void 0===p[t]?(p[t]=m,h.push({}),f.forEach(function(t){h[m][t]=u[t].data[e]}),s.forEach(function(t){h[m][t]=[u[t].data[e]]}),m+=1):s.forEach(function(n){h[p[t]][n].push(u[n].data[e])})}),h.forEach(function(e){var t=e;s.forEach(function(n){t[n]=a[n](e[n])})}),r?(r.__calculateFieldspace(),v=r):v=new pt(h,d,{name:c}),v}function fe(e,t){var n=B(e.getFieldspace(),t.getFieldspace());return function(e,t){var r=!0;return n.forEach(function(n){r=!(e[n].value!==t[n].value||!r)}),r}}function se(e,t){var n={},r=[],i=[],a=[],o=e.getFieldspace(),u=t.getFieldspace(),c=o.fieldsObj(),f=u.fieldsObj(),s=o.name+" union "+u.name;if(!P(e._colIdentifier.split(",").sort(),t._colIdentifier.split(",").sort()))return null;function d(e,t){l(e._rowDiffset,function(e){var r={},o="";i.forEach(function(n){var i=t[n].data[e];o+="-"+i,r[n]=i}),n[o]||(a.push(r),n[o]=!0)})}return e._colIdentifier.split(",").forEach(function(e){var t=c[e];r.push(w({},t.schema)),i.push(t.schema.name)}),d(e,c),d(t,f),new pt(a,r,{name:s})}function le(e,t,n){return J(e,t,n,!1,U.LEFTOUTER)}function de(e,t,n){return J(t,e,n,!1,U.RIGHTOUTER)}var pe=function(){function e(e,t){for(var n=0;nn&&(n=e)}),[t,n]}(this.data)}},{key:"parse",value:function(e){return e=parseFloat(e,10),Number.isNaN(e)?null:e}},{key:"unit",value:function(){return this.fieldUnit}},{key:"scale",value:function(){return this.fieldScale}},{key:"numberFormat",value:function(){var e=this.fieldNumberformat;return function(t){return e(t)}}},{key:"defAggFn",value:function(){return this.fieldDefAggFn}}]),t}(),ye=function(){function e(e,t){for(var n=0;n=a?c=!0:(r=e.charCodeAt(o++))===Pe?f=!0:r===Fe&&(f=!0,e.charCodeAt(o)===Pe&&++o),e.slice(i+1,t-1).replace(/""/g,'"')}for(;o2&&void 0!==arguments[2]?arguments[2]:{},i=arguments[3],a=void 0;t!==L.COMPOSE?(a={op:t,meta:r,criteria:i},e._derivation.push(a)):(a=[].concat(He(i)),e._derivation.length=0,(n=e._derivation).push.apply(n,He(a)))},Ge=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.operation||V,i=n.filterByMeasure||!1,a=[];a=null===t?[function(){return!1}]:t.map(function(e){return function(e){var t=e.getData(),n=t.schema,r=e.getFieldsConfig(),a=e.getFieldspace().fieldsObj(),o=t.data,u=Object.values(r).reduce(function(e,t){return e[t.def.name]=a[t.def.name].domain(),e},{});return function(e){return!!o.length&&o.some(function(t){return n.every(function(n){if(!(n.name in e))return!0;var a=e[n.name].valueOf();if(i&&n.type===f.MEASURE)return a>=u[n.name][0]&&a<=u[n.name][1];if(n.type!==f.DIMENSION)return!0;var o=r[n.name].index;return t[o]===e[n.name].valueOf()})})}}(e)});var o=void 0;r===V?o=e.clone(!1,!1).select(function(e){return a.every(function(t){return t(e)})},{saveChild:!1,mode:s.ALL}):o=e.clone(!1,!1).select(function(e){return a.some(function(t){return t(e)})},{mode:s.ALL,saveChild:!1});return o},qe=function(e,t,n,r){var i=e.clone(r.saveChild),a=function(e,t,n,r){var i=[],a=-1,o=void 0,u=function(e){return n(Be(t,e),e)};return r.mode===s.INVERSE&&(u=function(e){return!n(Be(t,e))}),l(e,function(e){u(e)&&(-1!==a&&e===a+1?(o=i.length-1,i[o]=i[o].split("-")[0]+"-"+e):i.push(""+e),a=e)}),i.join(",")}(i._rowDiffset,i.getPartialFieldspace().fields,t,n);return i._rowDiffset=a,i.__calculateFieldspace().calculateFieldsConfig(),r.saveChild&&Je(i,L.SELECT,{config:n},t),i},Ke=function(e,t,n,r){var i=e.clone(n.saveChild),a=t;return n.mode===s.INVERSE&&(a=r.filter(function(e){return-1===t.indexOf(e)})),i._colIdentifier=a.join(","),i.__calculateFieldspace().calculateFieldsConfig(),n.saveChild&&Je(i,L.PROJECT,{projField:t,config:n,actualProjField:a},null),i},We=function(e,t,n,r){r=Object.assign(Object.assign({},Se),r);var a=i[r.dataFormat];if(!a||"function"!=typeof a)throw new Error("No converter function found for "+r.dataFormat+" format");var o=a(t,r),u=Ve(o,2),c=u[0],f=u[1],s=ke(f,n,c),l=M.createNamespace(s,r.name);return e._partialFieldspace=l,e._rowDiffset=f.length&&f[0].length?"0-"+(f[0].length-1):"",e._colIdentifier=n.map(function(e){return e.name}).join(),e},ze=function(e,t){for(var n=0;n2&&void 0!==arguments[2]?arguments[2]:{},i=arguments[3],a=arguments[4],o=function(t,n,a){e(t,n,r,i,a)};t!==i&&(t.handlePropagation({payload:r.payload,data:n,sourceIdentifiers:r.sourceIdentifiers,sourceId:r.propagationSourceId,groupedPropModel:!!a}),function(e,t){H(e,t,L.SELECT)}(t,function(e,t){if(e!==i){var r=n[0].select(t,{saveChild:!1}),u=n[1].select(t,{saveChild:!1});o(e,[r,u],a)}}),function(e,t){H(e,t,L.PROJECT)}(t,function(e,t){if(e!==i){var r=n[0].project(t,{saveChild:!1}),u=n[1].project(t,{saveChild:!1});o(e,[r,u],a)}}),function(e,t){H(e,t,L.GROUPBY)}(t,function(e,t){if(e!==i){var r=t.reducer,a=t.groupByString,u=n[0].groupBy(a.split(","),r,{saveChild:!1}),c=n[1].groupBy(a.split(","),r,{saveChild:!1});o(e,[u,c],!0)}}),function(e,t){H(e,t,L.CAL_VAR)}(t,function(e){for(var t=arguments.length,r=Array(t>1?t-1:0),u=1;u0&&void 0!==arguments[0])||arguments[0],t=void 0;if(!1===(!(arguments.length>1&&void 0!==arguments[1])||arguments[1])){var n=this.getData({getAllFields:!0}),r=n.data,i=n.schema,a=r.map(function(e){var t={};return i.forEach(function(n,r){t[n.name]=e[r]}),t});t=new this.constructor(a,i)}else t=new this.constructor(this);return e&&this._children.push(t),t}},{key:"project",value:function(e,t){var n={mode:s.NORMAL,saveChild:!0};t=Object.assign({},n,t);var r=this.getFieldsConfig(),i=Object.keys(r),a=t.mode,o=e.reduce(function(e,t){return"RegExp"===t.constructor.name?e.push.apply(e,function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t1&&void 0!==arguments[1]?arguments[1]:[];Je(this,L.COMPOSE,null,t),this._parent=e,e._children.push(this)}}]),e}(),tt=function(){return function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,i=!1,a=void 0;try{for(var o,u=e[Symbol.iterator]();!(r=(o=u.next()).done)&&(n.push(o.value),!t||n.length!==t);r=!0);}catch(e){i=!0,a=e}finally{try{!r&&u.return&&u.return()}finally{if(i)throw a}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),nt=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{saveChild:!0},r=""+e.join(),i=[this,e,t],a=ce.apply(void 0,i);return n.saveChild&&(this._children.push(a),Je(a,L.GROUPBY,{fieldsArr:e,groupByString:r,defaultReducer:oe.defaultReducer()},t)),a._parent=this,a}},{key:"sort",value:function(e){var t=this.getData({order:"row",sort:e}),n=[t.schema.map(function(e){return e.name})].concat(t.data),r=new this.constructor(n,t.schema,{dataFormat:"DSVArr"});return r._sortingDetails=e,r}},{key:"addField",value:function(e){var t=e.fieldName();this._colIdentifier+=","+t;var n=this._partialFieldspace;if(n.fieldsObj()[e.fieldName()]){var r=n.fields.findIndex(function(e){return e.name===t});r>=0&&(n.fields[r]=e)}else n.fields.push(e);return this.__calculateFieldspace().calculateFieldsConfig(),this}},{key:"calculateVariable",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{saveChild:!0,replaceVar:!1},r=this.getFieldsConfig(),i=t.slice(0,t.length-1),a=t[t.length-1];if(r[e.name]&&!n.replaceVar)throw new Error(e.name+" field already exists in model.");var o=i.map(function(e){var t=r[e];if(!t)throw new Error(e+" is not a valid column name.");return t.index}),u=this.clone(),c=u.getFieldspace().fields,f=o.map(function(e){return c[e]}),s=[];l(u._rowDiffset,function(e){var t=f.map(function(t){return t.data[e]});s[e]=a.apply(void 0,function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t2&&void 0!==arguments[2]?arguments[2]:{},r=n.isMutableAction,i=n.sourceId,a=Qe(this),o=a._propagationNameSpace,u={groupByModel:function e(t){return t._parent&&t._derivation.find(function(e){return"group"!==e.op})?e(t._parent):t}(this),model:a};return $e(e,u,{propagationNameSpace:o,payload:t,propagationSourceId:i}),r&&function(e,t,n){var r=t.groupByModel,i=t.model,a=e.immutableActions;for(var o in a){var u=a[o];for(var c in u){var f=u[c].criteria;$e(f,{groupByModel:r,model:i},{propagationNameSpace:e,payload:u[c].payload,propagationSourceId:n})}}}(o,u,i),this}},{key:"addToPropNamespace",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=void 0,r=t.actionName,i=t.payload,a=t.isMutableAction,o=Qe(this)._propagationNameSpace,u=t.criteria;return a?(!o.mutableActions[e]&&(o.mutableActions[e]={}),n=o.mutableActions[e]):(!o.immutableActions[e]&&(o.immutableActions[e]={}),n=o.immutableActions[e]),null===u?delete n[r]:n[r]={criteria:u,payload:i},this}},{key:"on",value:function(e,t){switch(e){case"propagation":this._onPropagation.push(t)}return this}},{key:"unsubscribe",value:function(e){switch(e){case"propagation":this._onPropagation=[]}return this}},{key:"handlePropagation",value:function(e){var t=this;this._onPropagation.forEach(function(n){return n.call(t,e)})}},{key:"bin",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=this.clone(),r=t.name||e+"_binned";if(this.getFieldsConfig()[r]||!this.getFieldsConfig()[e])throw new Error("Field "+e+" already exists.");var i=I(this._partialFieldspace.fields.find(function(t){return t.name===e}),this._rowDiffset,t),a=ke([i.data],[{name:r,type:f.MEASURE,subtype:"discrete",bins:{range:i.range,mid:i.mid}}],[r])[0];return n.addField(a),Je(n,L.BIN,{measureName:e,config:t,binFieldName:r},null),n}}],[{key:"Reducers",get:function(){return oe}}]),t}(),it=ne.sum,at=ne.avg,ot=ne.min,ut=ne.max,ct=ne.first,ft=ne.last,st=ne.count,lt=ne.std,dt=n(0);rt.Operators={compose:function(){for(var e=arguments.length,t=Array(e),n=0;n1&&void 0!==arguments[1]?arguments[1]:{saveChild:!0}).saveChild;return t.forEach(function(e){n=e(n),i.push.apply(i,function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t1&&r.dispose(),n}},bin:function(){for(var e=arguments.length,t=Array(e),n=0;n",keywords:["datamodel","data","relational","algebra","model","muze","fusioncharts","table","tabular","operation"],repository:{type:"git",url:"https://github.com/chartshq/datamodel.git"},contributors:[{name:"Akash Goswami",email:"akash@charts.com"},{name:"Subhash Haldar",email:"subhash@charts.com"},{name:"Rousan Ali",email:"rousan@charts.com",url:"https://rousan.io"},{name:"Ujjal Kumar Dutta",email:"ujjal@charts.com"}],dependencies:{"d3-dsv":"^1.0.8"},devDependencies:{"babel-cli":"6.26.0","babel-core":"^6.26.3","babel-eslint":"6.1.2","babel-loader":"^7.1.4","babel-plugin-transform-runtime":"^6.23.0","babel-preset-env":"^1.7.0","babel-preset-es2015":"^6.24.1","babel-preset-flow":"^6.23.0",chai:"3.5.0","cross-env":"^5.0.5",eslint:"3.19.0","eslint-config-airbnb":"15.1.0","eslint-plugin-import":"2.7.0","eslint-plugin-jsx-a11y":"5.1.1","eslint-plugin-react":"7.3.0","istanbul-instrumenter-loader":"^3.0.0",jsdoc:"3.5.5",json2yaml:"^1.1.0",karma:"1.7.1","karma-chai":"0.1.0","karma-chrome-launcher":"2.1.1","karma-coverage-istanbul-reporter":"^1.3.0","karma-mocha":"1.3.0","karma-spec-reporter":"0.0.31","karma-webpack":"2.0.3",marked:"^0.5.0",mocha:"3.4.2","mocha-webpack":"0.7.0","transform-runtime":"0.0.0",webpack:"^4.12.0","webpack-cli":"^3.0.7","webpack-dev-server":"^3.1.4"},scripts:{test:"npm run lint && npm run ut",ut:"karma start karma.conf.js",utd:"karma start --single-run false --browsers Chrome karma.conf.js ",build:"webpack --mode production",start:"webpack-dev-server --config webpack.config.dev.js --mode development --open",lint:"eslint ./src","lint-errors":"eslint --quiet ./src",docs:"rm -rf yaml && mkdir yaml && jsdoc -c jsdoc.conf.json"}}},function(e,t,n){var r=n(2);e.exports=r.default?r.default:r},function(e,t,n){"use strict";n.r(t);var r={};n.r(r),n.d(r,"DataFormat",function(){return o}),n.d(r,"DimensionSubtype",function(){return u}),n.d(r,"MeasureSubtype",function(){return c}),n.d(r,"FieldType",function(){return f}),n.d(r,"FilteringMode",function(){return s});var i={};n.r(i),n.d(i,"DSVArr",function(){return Me}),n.d(i,"DSVStr",function(){return Ve}),n.d(i,"FlatJSON",function(){return Ye}),n.d(i,"Auto",function(){return Be});var a={};n.r(a),n.d(a,"sum",function(){return ct}),n.d(a,"avg",function(){return ft}),n.d(a,"min",function(){return st}),n.d(a,"max",function(){return lt}),n.d(a,"first",function(){return dt}),n.d(a,"last",function(){return pt}),n.d(a,"count",function(){return ht}),n.d(a,"sd",function(){return vt});var o={FLAT_JSON:"FlatJSON",DSV_STR:"DSVStr",DSV_ARR:"DSVArr",AUTO:"Auto"},u={CATEGORICAL:"categorical",TEMPORAL:"temporal",GEO:"geo"},c={DISCRETE:"discrete"},f={MEASURE:"measure",DIMENSION:"dimension"},s={NORMAL:"normal",INVERSE:"inverse",ALL:"all"};function l(e,t){e.length>0&&e.split(",").forEach(function(e){var n=e.split("-"),r=+n[0],i=+(n[1]||n[0]);if(i>=r)for(var a=r;a<=i;a+=1)t(a)})}var d=function(){function e(e,t){for(var n=0;n=0;)o=e[a+1],-1!==r.indexOf(o)&&i.push({index:a,token:o});return i},m.formatAs=function(e,t){var n,r=h(e),i=m.findTokens(t),a=m.getTokenDefinitions(),o=String(t),u=m.TOKEN_PREFIX,c=void 0,f=void 0,s=void 0;for(s=0,n=i.length;s=0;d--)(f=a[d].index)+1!==l.length-1?(void 0===u&&(u=l.length),s=l.substring(f+2,u),l=l.substring(0,f+2)+RegExp.escape(s)+l.substring(u,l.length),u=f):u=f;for(d=0;d1){n=Math.abs(r[1]-r[0]);for(var i=2,a=r.length;i=y&&t.data=r.stops[r.stops.length-1]}).forEach(function(e){c[e.index]=r.stops[r.stops.length-1]+"-"+h}),r.stops.unshift(r.start),b=new Set(r.stops),dr.stops[r.stops.length-1]&&b.add(h),b=[].concat(function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t3&&void 0!==arguments[3]&&arguments[3],i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:G.CROSS,a=[],o=[],u=n||K,c=e.getFieldspace(),f=t.getFieldspace(),s=c.name,d=f.name,p=c.name+"."+f.name,h=L(c,f);if(s===d)throw new Error("DataModels must have different alias names");return c.fields.forEach(function(e){var t=E({},e.schema);-1===h.indexOf(t.name)||r||(t.name=c.name+"."+t.name),a.push(t)}),f.fields.forEach(function(e){var t=E({},e.schema);-1!==h.indexOf(t.name)?r||(t.name=f.name+"."+t.name,a.push(t)):a.push(t)}),l(e._rowDiffset,function(e){var n=!1,p=void 0;l(t._rowDiffset,function(t){var l=[],v={};v[s]={},v[d]={},c.fields.forEach(function(t){l.push(t.data[e]),v[s][t.name]=t.data[e]}),f.fields.forEach(function(e){-1!==h.indexOf(e.schema.name)&&r||l.push(e.data[t]),v[d][e.name]=e.data[t]});var m=Ke(v[s]),y=Ke(v[d]);if(u(m,y)){var g={};l.forEach(function(e,t){g[a[t].name]=e}),n&&G.CROSS!==i?o[p]=g:(o.push(g),n=!0,p=e)}else if((i===G.LEFTOUTER||i===G.RIGHTOUTER)&&!n){var b={},_=c.fields.length-1;l.forEach(function(e,t){b[a[t].name]=t<=_?e:null}),n=!0,p=e,o.push(b)}})}),new ut(o,a,{name:p})}function z(e,t){var n=""+e,r=""+t;return nr?1:0}function X(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:z;return e.length>1&&function e(t,n,r,i){if(r===n)return t;var a=n+Math.floor((r-n)/2);return e(t,n,a,i),e(t,a+1,r,i),function(e,t,n,r,i){for(var a=e,o=[],u=t;u<=r;u+=1)o[u]=a[u];for(var c=t,f=n+1,s=t;s<=r;s+=1)c>n?(a[s]=o[f],f+=1):f>r?(a[s]=o[c],c+=1):i(o[c],o[f])<=0?(a[s]=o[c],c+=1):(a[s]=o[f],f+=1)}(t,n,a,r,i),t}(e,0,e.length-1,t),e}function Q(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);ta?"desc"===t?-1:1:0}}return r}function Z(e,t){var n=new Map,r=[];return e.forEach(function(e){var i=e[t];n.has(i)?r[n.get(i)][1].push(e):(r.push([i,[e]]),n.set(i,r.length-1))}),r}function ee(e,t,n){var r={label:e[0]};return t.reduce(function(t,r,i){return t[r]=e[1].map(function(e){return e[n[i].index]}),t},r),r}function te(e,t,n,r,i){var a={schema:[],data:[],uids:[]},o=(i=Object.assign({},{addUid:!1,columnWise:!1},i)).addUid,u=r&&r.length>0,c=[];if(n.split(",").forEach(function(t){for(var n=0;n=0;u--)i=t[u][0],a=t[u][1],(o=Ze(r,i))&&(S(a)?X(n,function(e,t){return a(e[o.index],t[o.index])}):j(a)?function(){var e=Z(n,o.index),t=a[a.length-1],i=a.slice(0,a.length-1),u=i.map(function(e){return Ze(r,e)});e.forEach(function(e){e.push(ee(e,i,u))}),X(e,function(e,n){var r=e[2],i=n[2];return t(r,i)}),n.length=0,e.forEach(function(e){n.push.apply(n,Q(e[1]))})}():(a="desc"===String(a).toLowerCase()?"desc":"asc",X(n,$(o.type,a,o.index))));e.uids=[],n.forEach(function(t){e.uids.push(t.pop())})}(a,r),i.columnWise){var f=Array.apply(void 0,Q(Array(a.schema.length))).map(function(){return[]});a.data.forEach(function(e){e.forEach(function(e,t){f[t].push(e)})}),a.data=f}return a}function ne(e,t){var n={},r=[],i=[],a=[],o=e.getFieldspace(),u=t.getFieldspace(),c=o.fieldsObj(),f=u.fieldsObj(),s=o.name+" union "+u.name;if(!M(e._colIdentifier.split(",").sort(),t._colIdentifier.split(",").sort()))return null;function d(e,t,r){l(e._rowDiffset,function(e){var o={},u="";i.forEach(function(n){var r=t[n].data[e];u+="-"+r,o[n]=r}),n[u]||(r&&a.push(o),n[u]=!0)})}return e._colIdentifier.split(",").forEach(function(e){var t=c[e];r.push(E({},t.schema)),i.push(t.schema.name)}),d(t,f,!1),d(e,c,!0),new ut(a,r,{name:s})}function re(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t1&&void 0!==arguments[1]?arguments[1]:{},n={},r=t,i=e.getPartialFieldspace().getMeasure(),a=se.defaultReducer();return"function"==typeof t&&(a=t),Object.entries(i).forEach(function(e){var o=le(e,1)[0];"string"==typeof t[o]&&(r[o]=se.resolve(r[o])?se.resolve(r[o]):a),"function"!=typeof t[o]&&(r[o]=void 0),n[o]=r[o]||se.resolve(i[o].defAggFn())||a}),n}(e,n),o=e.getPartialFieldspace(),u=o.fieldsObj(),c=o.name,f=[],s=[],d=[],p={},h=[],v=void 0;Object.entries(u).forEach(function(e){var t=le(e,2),n=t[0],r=t[1];(-1!==i.indexOf(n)||a[n])&&(d.push(E({},r.schema)),"measure"===r.schema.type&&"discrete"!==r.schema.subtype?s.push(n):"dimension"!==r.schema.type&&"discrete"!==r.schema.subtype||f.push(n))});var m=0;return l(e._rowDiffset,function(e){var t="";f.forEach(function(n){t=t+"-"+u[n].data[e]}),void 0===p[t]?(p[t]=m,h.push({}),f.forEach(function(t){h[m][t]=u[t].data[e]}),s.forEach(function(t){h[m][t]=[u[t].data[e]]}),m+=1):s.forEach(function(n){h[p[t]][n].push(u[n].data[e])})}),h.forEach(function(e){var t=e;s.forEach(function(n){t[n]=a[n](e[n])})}),r?(r.__calculateFieldspace(),v=r):v=new yt(h,d,{name:c}),v}function pe(e,t){var n=L(e.getFieldspace(),t.getFieldspace());return function(e,t){var r=!0;return n.forEach(function(n){r=!(e[n].value!==t[n].value||!r)}),r}}function he(e,t){var n={},r=[],i=[],a=[],o=e.getFieldspace(),u=t.getFieldspace(),c=o.fieldsObj(),f=u.fieldsObj(),s=o.name+" union "+u.name;if(!M(e._colIdentifier.split(",").sort(),t._colIdentifier.split(",").sort()))return null;function d(e,t){l(e._rowDiffset,function(e){var r={},o="";i.forEach(function(n){var i=t[n].data[e];o+="-"+i,r[n]=i}),n[o]||(a.push(r),n[o]=!0)})}return e._colIdentifier.split(",").forEach(function(e){var t=c[e];r.push(E({},t.schema)),i.push(t.schema.name)}),d(e,c),d(t,f),new yt(a,r,{name:s})}function ve(e,t,n){return W(e,t,n,!1,G.LEFTOUTER)}function me(e,t,n){return W(t,e,n,!1,G.RIGHTOUTER)}var ye=function(){function e(e,t){for(var n=0;nn&&(n=e)}),[t,n]}(this.data)}},{key:"parse",value:function(e){return e=parseFloat(e,10),Number.isNaN(e)?null:e}},{key:"unit",value:function(){return this.fieldUnit}},{key:"scale",value:function(){return this.fieldScale}},{key:"numberFormat",value:function(){var e=this.fieldNumberformat;return function(t){return e(t)}}},{key:"defAggFn",value:function(){return this.fieldDefAggFn}}]),t}(),Oe=function(){function e(e,t){for(var n=0;n=a?c=!0:(r=e.charCodeAt(o++))===Pe?f=!0:r===Ce&&(f=!0,e.charCodeAt(o)===Pe&&++o),e.slice(i+1,t-1).replace(/""/g,'"')}for(;o2&&void 0!==arguments[2]?arguments[2]:{},i=arguments[3],a=void 0;t!==Y?(a={op:t,meta:r,criteria:i},e._derivation.push(a)):(a=[].concat(Ge(i)),e._derivation.length=0,(n=e._derivation).push.apply(n,Ge(a)))},ze=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.operation||q,i=n.filterByMeasure||!1,a=[];a=t.length?t.map(function(e){return function(e){var t=e.getData(),n=t.schema,r=e.getFieldsConfig(),a=e.getFieldspace().fieldsObj(),o=t.data,u=Object.values(r).reduce(function(e,t){return e[t.def.name]=a[t.def.name].domain(),e},{});return function(e){return!!o.length&&o.some(function(t){return n.every(function(n){if(!(n.name in e))return!0;var a=e[n.name].valueOf();if(i&&n.type===f.MEASURE)return a>=u[n.name][0]&&a<=u[n.name][1];if(n.type!==f.DIMENSION)return!0;var o=r[n.name].index;return t[o]===e[n.name].valueOf()})})}}(e)}):[function(){return!1}];var o=void 0;r===q?o=e.clone(!1,!1).select(function(e){return a.every(function(t){return t(e)})},{saveChild:!1,mode:s.ALL}):o=e.clone(!1,!1).select(function(e){return a.some(function(t){return t(e)})},{mode:s.ALL,saveChild:!1});return o},Xe=function(e,t,n,r){var i=e.clone(r.saveChild),a=function(e,t,n,r){var i=[],a=-1,o=void 0,u=function(e){return n(qe(t,e),e)};return r.mode===s.INVERSE&&(u=function(e){return!n(qe(t,e))}),l(e,function(e){u(e)&&(-1!==a&&e===a+1?(o=i.length-1,i[o]=i[o].split("-")[0]+"-"+e):i.push(""+e),a=e)}),i.join(",")}(i._rowDiffset,i.getPartialFieldspace().fields,t,n);return i._rowDiffset=a,i.__calculateFieldspace().calculateFieldsConfig(),r.saveChild&&We(i,U,{config:n},t),i},Qe=function(e,t,n,r){var i=e.clone(n.saveChild),a=t;return n.mode===s.INVERSE&&(a=r.filter(function(e){return-1===t.indexOf(e)})),i._colIdentifier=a.join(","),i.__calculateFieldspace().calculateFieldsConfig(),n.saveChild&&We(i,H,{projField:t,config:n,actualProjField:a},null),i},$e=function(e,t,n,r){r=Object.assign(Object.assign({},xe),r);var a=i[r.dataFormat];if(!a||"function"!=typeof a)throw new Error("No converter function found for "+r.dataFormat+" format");var o=a(t,r),u=Je(o,2),c=u[0],f=u[1],s=Fe(f,n,c),l=R.createNamespace(s,r.name);return e._partialFieldspace=l,e._rowDiffset=f.length&&f[0].length?"0-"+(f[0].length-1):"",e._colIdentifier=n.map(function(e){return e.name}).join(),e},Ze=function(e,t){for(var n=0;n2&&void 0!==arguments[2]?arguments[2]:{},i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},a=i.nonTraversingModel,o=i.excludeModels||[];t!==a&&((!o.length||-1===o.indexOf(t))&&t.handlePropagation(n,r),t._children.forEach(function(t){var a=et(n,t),o=Je(a,2),u=o[0],c=o[1];e(t,[u,c],r,i)}))},nt=function(e,t,n,r){var i=void 0,a=void 0,o=n.propagationNameSpace,u=n.propagateToSource,c=n.sourceId,f=r.propagateInterpolatedValues,s=[];if(null===e&&!0!==r.persistent)s=[{criteria:[]}];else{var l,d=Object.values(o.mutableActions);!1!==u&&(d=d.filter(function(e){return e.config.sourceId!==c}));var p=d.filter(function(e){return(r.filterFn||function(){return!0})(e,r)}).map(function(e){return e.config.criteria}),h=[];if(!1!==u){var v=Object.values(o.mutableActions);v.forEach(function(e){var t=e.config;!1===t.applyOnSource&&t.action===r.action&&t.sourceId!==c&&(h.push(e.model),(i=v.filter(function(t){return t!==e}).map(function(e){return e.config.criteria})).length&&s.push({criteria:i,models:e.model,path:function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];return null!==t._parent&&(n.push(t),e(t._parent,n)),n}(e.model)}))})}i=(l=[]).concat.apply(l,[].concat(Ge(p),[e])).filter(function(e){return null!==e}),s.push({criteria:i,excludeModels:[].concat(h,Ge(r.excludeModels||[]))})}var m=t.model,y=Object.assign({sourceIdentifiers:e,propagationSourceId:c},r),g=t.groupByModel;f&&g&&(a=ze(g,i,{filterByMeasure:f}),tt(g,a,y)),s.forEach(function(e){var t=ze(m,e.criteria),n=e.path;if(n){var r=function(e,t){for(var n=0,r=t.length;n0&&void 0!==arguments[0])||arguments[0],t=void 0;if(!1===(!(arguments.length>1&&void 0!==arguments[1])||arguments[1])){var n=this.getData({getAllFields:!0}),r=n.data,i=n.schema,a=r.map(function(e){var t={};return i.forEach(function(n,r){t[n.name]=e[r]}),t});t=new this.constructor(a,i)}else t=new this.constructor(this);return e&&this._children.push(t),t}},{key:"project",value:function(e,t){var n={mode:s.NORMAL,saveChild:!0};t=Object.assign({},n,t);var r=this.getFieldsConfig(),i=Object.keys(r),a=t.mode,o=e.reduce(function(e,t){return"RegExp"===t.constructor.name?e.push.apply(e,function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t1&&void 0!==arguments[1]?arguments[1]:[];We(this,Y,null,t),this._parent=e,e._children.push(this)}}]),e}(),at=function(){return function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,i=!1,a=void 0;try{for(var o,u=e[Symbol.iterator]();!(r=(o=u.next()).done)&&(n.push(o.value),!t||n.length!==t);r=!0);}catch(e){i=!0,a=e}finally{try{!r&&u.return&&u.return()}finally{if(i)throw a}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),ot=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{saveChild:!0},r=""+e.join(),i=[this,e,t],a=de.apply(void 0,i);return n.saveChild&&(this._children.push(a),We(a,V,{fieldsArr:e,groupByString:r,defaultReducer:se.defaultReducer()},t)),a._parent=this,a}},{key:"sort",value:function(e){var t=this.getData({order:"row",sort:e}),n=[t.schema.map(function(e){return e.name})].concat(t.data),r=new this.constructor(n,t.schema,{dataFormat:"DSVArr"});return r._sortingDetails=e,r}},{key:"addField",value:function(e){var t=e.fieldName();this._colIdentifier+=","+t;var n=this._partialFieldspace;if(n.fieldsObj()[e.fieldName()]){var r=n.fields.findIndex(function(e){return e.name===t});r>=0&&(n.fields[r]=e)}else n.fields.push(e);return this.__calculateFieldspace().calculateFieldsConfig(),this}},{key:"calculateVariable",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{saveChild:!0,replaceVar:!1},r=this.getFieldsConfig(),i=t.slice(0,t.length-1),a=t[t.length-1];if(r[e.name]&&!n.replaceVar)throw new Error(e.name+" field already exists in model.");var o=i.map(function(e){var t=r[e];if(!t)throw new Error(e+" is not a valid column name.");return t.index}),u=this.clone(),c=u.getFieldspace().fields,f=o.map(function(e){return c[e]}),s=[];l(u._rowDiffset,function(e){var t=f.map(function(t){return t.data[e]});s[e]=a.apply(void 0,function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t1&&void 0!==arguments[1]?arguments[1]:{},n=arguments[2],r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},i=t.isMutableAction,a=t.sourceId,o=t.payload,u=function e(t){return t._parent?e(t._parent):t}(this),c=u._propagationNameSpace,f={groupByModel:function e(t){return t._parent&&t._derivation.find(function(e){return"group"!==e.op})?e(t._parent):t}(this),model:u};return n&&function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments[2],r=void 0,i=t.isMutableAction,a=t.criteria,o=t.action+"-"+t.sourceId;r=i?e.mutableActions:e.immutableActions,null===a?delete r[o]:r[o]={model:n,config:t}}(c,t,this),nt(e,f,{propagationNameSpace:c,sourceId:a},Object.assign({payload:o},t)),i&&function(e,t,n){var r=e.immutableActions;for(var i in r){var a=r[i].config,o=n.config.sourceId,u=!n.propConfig.filterImmutableAction||n.propConfig.filterImmutableAction(a,n.config);if(a.sourceId!==o&&u){var c=a.criteria;nt(c,t,{propagationNameSpace:e,propagateToSource:!1,sourceId:o},a)}}}(c,f,{config:t,propConfig:r}),this}},{key:"on",value:function(e,t){switch(e){case"propagation":this._onPropagation.push(t)}return this}},{key:"unsubscribe",value:function(e){switch(e){case"propagation":this._onPropagation=[]}return this}},{key:"handlePropagation",value:function(e,t){var n=this;this._onPropagation.forEach(function(r){return r.call(n,e,t)})}},{key:"bin",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=this.clone(),r=t.name||e+"_binned";if(this.getFieldsConfig()[r]||!this.getFieldsConfig()[e])throw new Error("Field "+e+" already exists.");var i=I(this._partialFieldspace.fields.find(function(t){return t.name===e}),this._rowDiffset,t),a=Fe([i.data],[{name:r,type:f.MEASURE,subtype:"discrete",bins:{range:i.range,mid:i.mid}}],[r])[0];return n.addField(a),We(n,J,{measureName:e,config:t,binFieldName:r},null),n}}],[{key:"Reducers",get:function(){return se}}]),t}(),ct=oe.sum,ft=oe.avg,st=oe.min,lt=oe.max,dt=oe.first,pt=oe.last,ht=oe.count,vt=oe.std,mt=n(0);ut.Operators={compose:function(){for(var e=arguments.length,t=Array(e),n=0;n1&&void 0!==arguments[1]?arguments[1]:{saveChild:!0}).saveChild;return t.forEach(function(e){n=e(n),i.push.apply(i,function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t1&&r.dispose(),n}},bin:function(){for(var e=arguments.length,t=Array(e),n=0;n 0) {\n const rowDiffArr = rowDiffset.split(',');\n rowDiffArr.forEach((diffStr) => {\n const diffStsArr = diffStr.split('-');\n const start = +(diffStsArr[0]);\n const end = +(diffStsArr[1] || diffStsArr[0]);\n if (end >= start) {\n for (let i = start; i <= end; i += 1) {\n callback(i);\n }\n }\n });\n }\n}\n","import { DimensionSubtype } from '../enums';\nimport { rowDiffsetIterator } from '../operator/row-diffset-iterator';\n\n/**\n * In {@link DataModel}, every tabular data consists of column, a column is stored as field.\n * Field contains all the data for a given column in an array.\n *\n * Each record consists of several fields; the fields of all records form the columns.\n * Examples of fields: name, gender, sex etc.\n *\n * In DataModel, each field can have multiple attributes which describes its data and behaviour.\n * A field can have two types of data: Measure and Dimension.\n *\n * A Dimension Field is the context on which a data is categorized and the measure is the numerical values that\n * quantify the data set.\n * In short a dimension is the lens through which you are looking at your measure data.\n *\n * Refer to {@link Schema} to get info about possible field attributes.\n *\n * @public\n * @class\n */\nexport default class Field {\n constructor(partialFeild, rowDiff) {\n this._ref = partialFeild;\n this._rowDiff = rowDiff;\n }\n\n sanitize () {\n return this._ref.sanitize();\n }\n\n parsed (val) {\n return this._ref.parsed(val);\n }\n\n domain() {\n let data = [];\n let domain = null;\n data = this.getData();\n if (this._ref.fieldType === 'dimension' && this._ref.subType() !== DimensionSubtype.TEMPORAL) {\n domain = [...new Set(data)];\n } else {\n let minD = Math.min.apply(null, data);\n let maxD = Math.max.apply(null, data);\n domain = [minD, maxD];\n }\n\n return domain;\n }\n\n parse (val) {\n return this._ref.parse(val);\n }\n\n\n clone(datas) {\n return this._ref.clone(datas);\n }\n\n fieldName() {\n return this._ref.fieldName();\n }\n\n type() {\n return this._ref.type();\n }\n\n description() {\n return this._ref.description();\n }\n\n get name() {\n return this._ref.name;\n }\n\n // set name(name) {\n // this._ref.name = name;\n // }\n\n get schema() {\n return this._ref.schema;\n }\n\n // set schema(schema) {\n // this._ref.schema = schema;\n // }\n\n get data() {\n return this._ref.data;\n }\n\n // set data(schema) {\n // throw new Error('Not yet implemented!');\n // }\n\n subType() {\n return this._ref.subType();\n }\n\n getMinDiff () {\n return this._ref.getMinDiff();\n }\n\n /**\n * Getter for unit value of the field.\n *\n * @return {string} Returns unit of the field.\n */\n unit() {\n return this._ref.unit();\n }\n\n /**\n * Getter for scale value of the field.\n *\n * @return {string} Returns scale of the field.\n */\n scale() {\n return this._ref.scale();\n }\n\n /**\n * Getter for aggregation function of the field.\n *\n * @return {Function} Returns aggregation function of the field.\n */\n defAggFn() {\n return this._ref.defAggFn();\n }\n\n getData() {\n let data = [];\n rowDiffsetIterator(this._rowDiff, (i) => {\n data.push(this._ref.data[i]);\n });\n return data;\n }\n\n bins() {\n return this._ref.bins();\n }\n}\n","/**\n * Creates a JS native date object from input\n *\n * @param {string | number | Date} date Input using which date object to be created\n * @return {Date} : JS native date object\n */\nfunction convertToNativeDate (date) {\n if (date instanceof Date) {\n return date;\n }\n\n return new Date(date);\n}\n/**\n * Apply padding before a number if its less than 1o. This is used when constant digit's number to be returned\n * between 0 - 99\n *\n * @param {number} n Input to be padded\n * @return {string} Padded number\n */\nfunction pad (n) {\n return (n < 10) ? (`0${n}`) : n;\n}\n/*\n * DateFormatter utility to convert any date format to any other date format\n * DateFormatter parse a date time stamp specified by a user abiding by rules which are defined\n * by user in terms of token. It creates JS native date object from the user specified format.\n * That native date can also be displayed\n * in any specified format.\n * This utility class only takes care of format conversion only\n */\n\n/*\n * Escapes all the special character that are used in regular expression.\n * Like\n * RegExp.escape('sgfd-$') // Output: sgfd\\-\\$\n *\n * @param text {String} : text which is to be escaped\n */\nRegExp.escape = function (text) {\n return text.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&');\n};\n\n/**\n * DateTimeFormatter class to convert any user format of date time stamp to any other format\n * of date time stamp.\n *\n * @param {string} format Format of the date given. For the above date,\n * 'year: %Y, month: %b, day: %d'.\n * @class\n */\n/* istanbul ignore next */ function DateTimeFormatter (format) {\n this.format = format;\n this.dtParams = undefined;\n this.nativeDate = undefined;\n}\n\n// The identifier of the tokens\nDateTimeFormatter.TOKEN_PREFIX = '%';\n\n// JS native Date constructor takes the date params (year, month, etc) in a certail sequence.\n// This defines the sequence of the date parameters in the constructor.\nDateTimeFormatter.DATETIME_PARAM_SEQUENCE = {\n YEAR: 0,\n MONTH: 1,\n DAY: 2,\n HOUR: 3,\n MINUTE: 4,\n SECOND: 5,\n MILLISECOND: 6\n};\n\n/*\n * This is a default number parsing utility. It tries to parse a number in integer, if parsing is unsuccessful, it\n * gives back a default value.\n *\n * @param: defVal {Number} : Default no if the parsing to integer is not successful\n * @return {Function} : An closure function which is to be called by passing an the value which needs to be parsed.\n */\nDateTimeFormatter.defaultNumberParser = function (defVal) {\n return function (val) {\n let parsedVal;\n if (isFinite(parsedVal = parseInt(val, 10))) {\n return parsedVal;\n }\n\n return defVal;\n };\n};\n\n/*\n * This is a default number range utility. It tries to find an element in the range. If not found it returns a\n * default no as an index.\n *\n * @param: range {Array} : The list which is to be serached\n * @param: defVal {Number} : Default no if the serach and find does not return anything\n * @return {Function} : An closure function which is to be called by passing an the value which needs to be found\n */\nDateTimeFormatter.defaultRangeParser = function (range, defVal) {\n return (val) => {\n let i;\n let l;\n\n if (!val) { return defVal; }\n\n const nVal = val.toLowerCase();\n\n for (i = 0, l = range.length; i < l; i++) {\n if (range[i].toLowerCase() === nVal) {\n return i;\n }\n }\n\n if (i === undefined) {\n return defVal;\n }\n return null;\n };\n};\n\n/*\n * Defines the tokens which are supporter by the dateformatter. Using this definitation a value gets extracted from\n * the user specifed date string. This also formats the value for display purpose from native JS date.\n * The definition of each token contains the following named properties\n * {\n * %token_name% : {\n * name: name of the token, this is used in reverse lookup,\n * extract: a function that returns the regular expression to extract that piece of information. All the\n * regex should be gouped by using ()\n * parser: a function which receives value extracted by the above regex and parse it to get the date params\n * formatter: a formatter function that takes milliseconds or JS Date object and format the param\n * represented by the token only.\n * }\n * }\n *\n * @return {Object} : Definition of the all the supported tokens.\n */\nDateTimeFormatter.getTokenDefinitions = function () {\n const daysDef = {\n short: [\n 'Sun',\n 'Mon',\n 'Tue',\n 'Wed',\n 'Thu',\n 'Fri',\n 'Sat'\n ],\n long: [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday'\n ]\n };\n const monthsDef = {\n short: [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec'\n ],\n long: [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December'\n ]\n };\n\n const definitions = {\n H: {\n // 24 hours format\n name: 'H',\n index: 3,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n\n return d.getHours().toString();\n }\n },\n l: {\n // 12 hours format\n name: 'l',\n index: 3,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const hours = d.getHours() % 12;\n\n return (hours === 0 ? 12 : hours).toString();\n }\n },\n p: {\n // AM or PM\n name: 'p',\n index: 3,\n extract () { return '(AM|PM)'; },\n parser: (val) => {\n if (val) {\n return val.toLowerCase();\n }\n return null;\n },\n formatter: (val) => {\n const d = convertToNativeDate(val);\n const hours = d.getHours();\n\n return (hours < 12 ? 'AM' : 'PM');\n }\n },\n P: {\n // am or pm\n name: 'P',\n index: 3,\n extract () { return '(am|pm)'; },\n parser: (val) => {\n if (val) {\n return val.toLowerCase();\n }\n return null;\n },\n formatter: (val) => {\n const d = convertToNativeDate(val);\n const hours = d.getHours();\n\n return (hours < 12 ? 'am' : 'pm');\n }\n },\n M: {\n // Two digit minutes 00 - 59\n name: 'M',\n index: 4,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const mins = d.getMinutes();\n\n return pad(mins);\n }\n },\n S: {\n // Two digit seconds 00 - 59\n name: 'S',\n index: 5,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const seconds = d.getSeconds();\n\n return pad(seconds);\n }\n },\n K: {\n // Milliseconds\n name: 'K',\n index: 6,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const ms = d.getMilliseconds();\n\n return ms.toString();\n }\n },\n a: {\n // Short name of day, like Mon\n name: 'a',\n index: 2,\n extract () { return `(${daysDef.short.join('|')})`; },\n parser: DateTimeFormatter.defaultRangeParser(daysDef.short),\n formatter (val) {\n const d = convertToNativeDate(val);\n const day = d.getDay();\n\n return (daysDef.short[day]).toString();\n }\n },\n A: {\n // Long name of day, like Monday\n name: 'A',\n index: 2,\n extract () { return `(${daysDef.long.join('|')})`; },\n parser: DateTimeFormatter.defaultRangeParser(daysDef.long),\n formatter (val) {\n const d = convertToNativeDate(val);\n const day = d.getDay();\n\n return (daysDef.long[day]).toString();\n }\n },\n e: {\n // 8 of March, 11 of November\n name: 'e',\n index: 2,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const day = d.getDate();\n\n return day.toString();\n }\n },\n d: {\n // 08 of March, 11 of November\n name: 'd',\n index: 2,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const day = d.getDate();\n\n return pad(day);\n }\n },\n b: {\n // Short month, like Jan\n name: 'b',\n index: 1,\n extract () { return `(${monthsDef.short.join('|')})`; },\n parser: DateTimeFormatter.defaultRangeParser(monthsDef.short),\n formatter (val) {\n const d = convertToNativeDate(val);\n const month = d.getMonth();\n\n return (monthsDef.short[month]).toString();\n }\n },\n B: {\n // Long month, like January\n name: 'B',\n index: 1,\n extract () { return `(${monthsDef.long.join('|')})`; },\n parser: DateTimeFormatter.defaultNumberParser(monthsDef.long),\n formatter (val) {\n const d = convertToNativeDate(val);\n const month = d.getMonth();\n\n return (monthsDef.long[month]).toString();\n }\n },\n m: {\n // Two digit month of year like 01 for January\n name: 'm',\n index: 1,\n extract () { return '(\\\\d+)'; },\n parser (val) { return DateTimeFormatter.defaultNumberParser()(val) - 1; },\n formatter (val) {\n const d = convertToNativeDate(val);\n const month = d.getMonth();\n\n return pad(month + 1);\n }\n },\n y: {\n // Short year like 90 for 1990\n name: 'y',\n index: 0,\n extract () { return '(\\\\d{4})'; },\n parser (val) {\n if (val) {\n const l = val.length;\n val = val.substring(l - 2, l);\n }\n\n return DateTimeFormatter.defaultNumberParser()(val);\n },\n formatter (val) {\n const d = convertToNativeDate(val);\n let year = d.getFullYear().toString();\n let l;\n\n if (year) {\n l = year.length;\n year = year.substring(l - 2, l);\n }\n\n return year;\n }\n },\n Y: {\n // Long year like 1990\n name: 'Y',\n index: 0,\n extract () { return '(\\\\d{4})'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const year = d.getFullYear().toString();\n\n return year;\n }\n }\n };\n\n return definitions;\n};\n\n/*\n * The tokens which works internally is not user friendly in terms of memorizing the names. This gives a formal\n * definition to the informal notations.\n *\n * @return {Object} : Formal definition of the tokens\n */\nDateTimeFormatter.getTokenFormalNames = function () {\n const definitions = DateTimeFormatter.getTokenDefinitions();\n\n return {\n HOUR: definitions.H,\n HOUR_12: definitions.l,\n AMPM_UPPERCASE: definitions.p,\n AMPM_LOWERCASE: definitions.P,\n MINUTE: definitions.M,\n SECOND: definitions.S,\n SHORT_DAY: definitions.a,\n LONG_DAY: definitions.A,\n DAY_OF_MONTH: definitions.e,\n DAY_OF_MONTH_CONSTANT_WIDTH: definitions.d,\n SHORT_MONTH: definitions.b,\n LONG_MONTH: definitions.B,\n MONTH_OF_YEAR: definitions.m,\n SHORT_YEAR: definitions.y,\n LONG_YEAR: definitions.Y\n };\n};\n\n/*\n * This defines the rules and declares dependencies that resolves a date parameter (year, month etc) from\n * the date time parameter array.\n *\n * @return {Object} : An object that contains dependencies and a resolver function. The dependencies values are fed\n * to the resolver function in that particular sequence only.\n */\nDateTimeFormatter.tokenResolver = function () {\n const definitions = DateTimeFormatter.getTokenDefinitions();\n const defaultResolver = (...args) => { // eslint-disable-line require-jsdoc\n let i = 0;\n let arg;\n let targetParam;\n const l = args.length;\n\n for (; i < l; i++) {\n arg = args[i];\n if (args[i]) {\n targetParam = arg;\n }\n }\n\n if (!targetParam) { return null; }\n\n return targetParam[0].parser(targetParam[1]);\n };\n\n return {\n YEAR: [definitions.y, definitions.Y,\n defaultResolver\n ],\n MONTH: [definitions.b, definitions.B, definitions.m,\n defaultResolver\n ],\n DAY: [definitions.a, definitions.A, definitions.e, definitions.d,\n defaultResolver\n ],\n HOUR: [definitions.H, definitions.l, definitions.p, definitions.P,\n function (hourFormat24, hourFormat12, ampmLower, ampmUpper) {\n let targetParam;\n let amOrpm;\n let isPM;\n let val;\n\n if (hourFormat12 && (amOrpm = (ampmLower || ampmUpper))) {\n if (amOrpm[0].parser(amOrpm[1]) === 'pm') {\n isPM = true;\n }\n\n targetParam = hourFormat12;\n } else if (hourFormat12) {\n targetParam = hourFormat12;\n } else {\n targetParam = hourFormat24;\n }\n\n if (!targetParam) { return null; }\n\n val = targetParam[0].parser(targetParam[1]);\n if (isPM) {\n val += 12;\n }\n return val;\n }\n ],\n MINUTE: [definitions.M,\n defaultResolver\n ],\n SECOND: [definitions.S,\n defaultResolver\n ]\n };\n};\n\n/*\n * Finds token from the format rule specified by a user.\n * @param format {String} : The format of the input date specified by the user\n * @return {Array} : An array of objects which contains the available token and their occurence index in the format\n */\nDateTimeFormatter.findTokens = function (format) {\n const tokenPrefix = DateTimeFormatter.TOKEN_PREFIX;\n const definitions = DateTimeFormatter.getTokenDefinitions();\n const tokenLiterals = Object.keys(definitions);\n const occurrence = [];\n let i;\n let forwardChar;\n\n while ((i = format.indexOf(tokenPrefix, i + 1)) >= 0) {\n forwardChar = format[i + 1];\n if (tokenLiterals.indexOf(forwardChar) === -1) { continue; }\n\n occurrence.push({\n index: i,\n token: forwardChar\n });\n }\n\n return occurrence;\n};\n\n/*\n * Format any JS date to a specified date given by user.\n *\n * @param date {Number | Date} : The date object which is to be formatted\n * @param format {String} : The format using which the date will be formatted for display\n */\nDateTimeFormatter.formatAs = function (date, format) {\n const nDate = convertToNativeDate(date);\n const occurrence = DateTimeFormatter.findTokens(format);\n const definitions = DateTimeFormatter.getTokenDefinitions();\n let formattedStr = String(format);\n const tokenPrefix = DateTimeFormatter.TOKEN_PREFIX;\n let token;\n let formattedVal;\n let i;\n let l;\n\n for (i = 0, l = occurrence.length; i < l; i++) {\n token = occurrence[i].token;\n formattedVal = definitions[token].formatter(nDate);\n formattedStr = formattedStr.replace(new RegExp(tokenPrefix + token, 'g'), formattedVal);\n }\n\n return formattedStr;\n};\n\n/*\n * Parses the user specified date string to extract the date time params.\n *\n * @return {Array} : Value of date time params in an array [year, month, day, hour, minutes, seconds, milli]\n */\nDateTimeFormatter.prototype.parse = function (dateTimeStamp, options) {\n const tokenResolver = DateTimeFormatter.tokenResolver();\n const dtParams = this.extractTokenValue(dateTimeStamp);\n const dtParamSeq = DateTimeFormatter.DATETIME_PARAM_SEQUENCE;\n const noBreak = options && options.noBreak;\n const dtParamArr = [];\n const args = [];\n let resolverKey;\n let resolverParams;\n let resolverFn;\n let val;\n let i;\n let param;\n let resolvedVal;\n let l;\n\n for (resolverKey in tokenResolver) {\n if (!{}.hasOwnProperty.call(tokenResolver, resolverKey)) { continue; }\n\n args.length = 0;\n resolverParams = tokenResolver[resolverKey];\n resolverFn = resolverParams.splice(resolverParams.length - 1, 1)[0];\n\n for (i = 0, l = resolverParams.length; i < l; i++) {\n param = resolverParams[i];\n val = dtParams[param.name];\n\n if (val === undefined) {\n args.push(null);\n } else {\n args.push([param, val]);\n }\n }\n\n resolvedVal = resolverFn.apply(this, args);\n\n if ((resolvedVal === undefined || resolvedVal === null) && !noBreak) {\n break;\n }\n\n dtParamArr[dtParamSeq[resolverKey]] = resolvedVal;\n }\n\n return dtParamArr;\n};\n\n/*\n * Extract the value of the token from user specified date time string.\n *\n * @return {Object} : An key value pair which contains the tokens as key and value as pair\n */\nDateTimeFormatter.prototype.extractTokenValue = function (dateTimeStamp) {\n const format = this.format;\n const definitions = DateTimeFormatter.getTokenDefinitions();\n const tokenPrefix = DateTimeFormatter.TOKEN_PREFIX;\n const occurrence = DateTimeFormatter.findTokens(format);\n const tokenObj = {};\n\n let lastOccurrenceIndex;\n let occObj;\n let occIndex;\n let targetText;\n let regexFormat;\n\n let l;\n let i;\n\n regexFormat = String(format);\n\n const tokenArr = occurrence.map(obj => obj.token);\n const occurrenceLength = occurrence.length;\n for (i = occurrenceLength - 1; i >= 0; i--) {\n occIndex = occurrence[i].index;\n\n if (occIndex + 1 === regexFormat.length - 1) {\n lastOccurrenceIndex = occIndex;\n continue;\n }\n\n if (lastOccurrenceIndex === undefined) {\n lastOccurrenceIndex = regexFormat.length;\n }\n\n targetText = regexFormat.substring(occIndex + 2, lastOccurrenceIndex);\n regexFormat = regexFormat.substring(0, occIndex + 2) +\n RegExp.escape(targetText) +\n regexFormat.substring(lastOccurrenceIndex, regexFormat.length);\n\n lastOccurrenceIndex = occIndex;\n }\n\n for (i = 0; i < occurrenceLength; i++) {\n occObj = occurrence[i];\n regexFormat = regexFormat.replace(tokenPrefix + occObj.token, definitions[occObj.token].extract());\n }\n\n const extractValues = dateTimeStamp.match(new RegExp(regexFormat)) || [];\n extractValues.shift();\n\n for (i = 0, l = tokenArr.length; i < l; i++) {\n tokenObj[tokenArr[i]] = extractValues[i];\n }\n return tokenObj;\n};\n\n/*\n * Give back the JS native date formed from user specified date string\n *\n * @return {Date} : Native JS Date\n */\nDateTimeFormatter.prototype.getNativeDate = function (dateTimeStamp) {\n if (dateTimeStamp instanceof Date) {\n return dateTimeStamp;\n } else if (isFinite(dateTimeStamp) && !!this.format) {\n return new Date(dateTimeStamp);\n }\n\n const dtParams = this.dtParams = this.parse(dateTimeStamp);\n\n dtParams.unshift(null);\n this.nativeDate = new (Function.prototype.bind.apply(Date, dtParams))();\n return this.nativeDate;\n};\n\n/*\n * Represents JS native date to a user specified format.\n *\n * @param format {String} : The format according to which the date is to be represented\n * @return {String} : The formatted date string\n */\nDateTimeFormatter.prototype.formatAs = function (format, dateTimeStamp) {\n let nativeDate;\n\n if (dateTimeStamp) {\n nativeDate = this.nativeDate = this.getNativeDate(dateTimeStamp);\n } else if (!(nativeDate = this.nativeDate)) {\n nativeDate = this.getNativeDate(dateTimeStamp);\n }\n\n return DateTimeFormatter.formatAs(nativeDate, format);\n};\n\nexport { DateTimeFormatter as default };\n","/**\n * The utility function to calculate major column.\n *\n * @param {Object} store - The store object.\n * @return {Function} Returns the push function.\n */\nexport default (store) => {\n let i = 0;\n return (...fields) => {\n fields.forEach((val, fieldIndex) => {\n if (!(store[fieldIndex] instanceof Array)) {\n store[fieldIndex] = Array.from({ length: i });\n }\n store[fieldIndex].push(val);\n });\n i++;\n };\n};\n","/* eslint-disable */\nconst OBJECTSTRING = 'object';\nconst objectToStrFn = Object.prototype.toString;\nconst objectToStr = '[object Object]';\nconst arrayToStr = '[object Array]';\n\nfunction checkCyclicRef(obj, parentArr) {\n let i = parentArr.length;\n let bIndex = -1;\n\n while (i) {\n if (obj === parentArr[i]) {\n bIndex = i;\n return bIndex;\n }\n i -= 1;\n }\n\n return bIndex;\n}\n\nfunction merge(obj1, obj2, skipUndef, tgtArr, srcArr) {\n var item,\n srcVal,\n tgtVal,\n str,\n cRef;\n // check whether obj2 is an array\n // if array then iterate through it's index\n // **** MOOTOOLS precution\n\n if (!srcArr) {\n tgtArr = [obj1];\n srcArr = [obj2];\n }\n else {\n tgtArr.push(obj1);\n srcArr.push(obj2);\n }\n\n if (obj2 instanceof Array) {\n for (item = 0; item < obj2.length; item += 1) {\n try {\n srcVal = obj1[item];\n tgtVal = obj2[item];\n }\n catch (e) {\n continue;\n }\n\n if (typeof tgtVal !== OBJECTSTRING) {\n if (!(skipUndef && tgtVal === undefined)) {\n obj1[item] = tgtVal;\n }\n }\n else {\n if (srcVal === null || typeof srcVal !== OBJECTSTRING) {\n srcVal = obj1[item] = tgtVal instanceof Array ? [] : {};\n }\n cRef = checkCyclicRef(tgtVal, srcArr);\n if (cRef !== -1) {\n srcVal = obj1[item] = tgtArr[cRef];\n }\n else {\n merge(srcVal, tgtVal, skipUndef, tgtArr, srcArr);\n }\n }\n }\n }\n else {\n for (item in obj2) {\n try {\n srcVal = obj1[item];\n tgtVal = obj2[item];\n }\n catch (e) {\n continue;\n }\n\n if (tgtVal !== null && typeof tgtVal === OBJECTSTRING) {\n // Fix for issue BUG: FWXT-602\n // IE < 9 Object.prototype.toString.call(null) gives\n // '[object Object]' instead of '[object Null]'\n // that's why null value becomes Object in IE < 9\n str = objectToStrFn.call(tgtVal);\n if (str === objectToStr) {\n if (srcVal === null || typeof srcVal !== OBJECTSTRING) {\n srcVal = obj1[item] = {};\n }\n cRef = checkCyclicRef(tgtVal, srcArr);\n if (cRef !== -1) {\n srcVal = obj1[item] = tgtArr[cRef];\n }\n else {\n merge(srcVal, tgtVal, skipUndef, tgtArr, srcArr);\n }\n }\n else if (str === arrayToStr) {\n if (srcVal === null || !(srcVal instanceof Array)) {\n srcVal = obj1[item] = [];\n }\n cRef = checkCyclicRef(tgtVal, srcArr);\n if (cRef !== -1) {\n srcVal = obj1[item] = tgtArr[cRef];\n }\n else {\n merge(srcVal, tgtVal, skipUndef, tgtArr, srcArr);\n }\n }\n else {\n obj1[item] = tgtVal;\n }\n }\n else {\n if (skipUndef && tgtVal === undefined) {\n continue;\n }\n obj1[item] = tgtVal;\n }\n }\n }\n return obj1;\n}\n\n\nfunction extend2 (obj1, obj2, skipUndef) {\n //if none of the arguments are object then return back\n if (typeof obj1 !== OBJECTSTRING && typeof obj2 !== OBJECTSTRING) {\n return null;\n }\n\n if (typeof obj2 !== OBJECTSTRING || obj2 === null) {\n return obj1;\n }\n\n if (typeof obj1 !== OBJECTSTRING) {\n obj1 = obj2 instanceof Array ? [] : {};\n }\n merge(obj1, obj2, skipUndef);\n return obj1;\n}\n\nexport { extend2 as default };\n","/**\n * Checks whether the value is an array.\n *\n * @param {*} val - The value to be checked.\n * @return {boolean} Returns true if the value is an array otherwise returns false.\n */\nexport function isArray (val) {\n return Array.isArray(val);\n}\n\n/**\n * Checks whether the value is an object.\n *\n * @param {*} val - The value to be checked.\n * @return {boolean} Returns true if the value is an object otherwise returns false.\n */\nexport function isObject (val) {\n return val === Object(val);\n}\n\n/**\n * Checks whether the value is a string value.\n *\n * @param {*} val - The value to be checked.\n * @return {boolean} Returns true if the value is a string value otherwise returns false.\n */\nexport function isString (val) {\n return typeof val === 'string';\n}\n\n/**\n * Checks whether the value is callable.\n *\n * @param {*} val - The value to be checked.\n * @return {boolean} Returns true if the value is callable otherwise returns false.\n */\nexport function isCallable (val) {\n return typeof val === 'function';\n}\n\n/**\n * Returns the unique values from the input array.\n *\n * @param {Array} data - The input array.\n * @return {Array} Returns a new array of unique values.\n */\nexport function uniqueValues (data) {\n return [...new Set(data)];\n}\n\nexport const getUniqueId = () => `id-${new Date().getTime()}${Math.round(Math.random() * 10000)}`;\n\nconst unique = arr => ([...new Set(arr)]);\n\n/**\n * Gets the minimum difference between two consecutive numbers in an array.\n * @param {Array} arr Array of numbers\n * @param {number} index index of the value\n * @return {number} minimum difference between values\n */\nexport const getMinDiff = (arr, index) => {\n let diff;\n let uniqueVals;\n if (index !== undefined) {\n uniqueVals = unique(arr.map(d => d[index]));\n } else {\n uniqueVals = unique(arr);\n }\n if (uniqueVals.length > 1) {\n diff = Math.abs(uniqueVals[1] - uniqueVals[0]);\n for (let i = 2, len = uniqueVals.length; i < len; i++) {\n diff = Math.min(diff, Math.abs(uniqueVals[i] - uniqueVals[i - 1]));\n }\n } else {\n diff = uniqueVals[0];\n }\n\n return diff;\n};\n\n/**\n * Checks Whether two arrays have same content.\n *\n * @param {Array} arr1 - The first array.\n * @param {Array} arr2 - The 2nd array.\n * @return {boolean} Returns whether two array have same content.\n */\nexport function isArrEqual(arr1, arr2) {\n if (!isArray(arr1) || !isArray(arr2)) {\n return arr1 === arr2;\n }\n\n if (arr1.length !== arr2.length) {\n return false;\n }\n\n for (let i = 0; i < arr1.length; i++) {\n if (arr1[i] !== arr2[i]) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Checks Whether two arrays have same content.\n *\n * @param {Array} arr1 - The first array.\n * @param {Array} arr2 - The 2nd array.\n * @return {boolean} Returns whether two array have same content.\n */\nexport function formatNumber(val) {\n return val;\n}\n","import { FieldType } from './enums';\nimport { getUniqueId } from './utils';\n\nconst fieldStore = {\n data: {},\n\n createNamespace (fieldArr, name) {\n const dataId = name || getUniqueId();\n this.data[dataId] = {\n name: dataId,\n fields: fieldArr,\n fieldsObj () {\n const retObj = {};\n this.fields.forEach((field) => {\n retObj[field.name] = field;\n });\n return retObj;\n },\n getMeasure () {\n const retObj = {};\n this.fields.forEach((field) => {\n if (field.schema.type === FieldType.MEASURE) {\n retObj[field.name] = field;\n }\n });\n return retObj;\n },\n getDimension () {\n const retObj = {};\n this.fields.forEach((field) => {\n if (field.schema.type === FieldType.DIMENSION) {\n retObj[field.name] = field;\n }\n });\n return retObj;\n },\n };\n return this.data[dataId];\n },\n};\n\nexport default fieldStore;\n","/**\n * The wrapper class on top of the primitive value of a field.\n *\n * @todo Need to have support for StringValue, NumberValue, DateTimeValue\n * and GeoValue. These types should expose predicate API mostly.\n */\nclass Value {\n\n /**\n * Creates new Value instance.\n *\n * @param {*} val - the primitive value from the field cell.\n * @param {string | Field} field - The field from which the value belongs.\n */\n constructor (val, field) {\n Object.defineProperty(this, '_value', {\n enumerable: false,\n configurable: false,\n writable: false,\n value: val\n });\n\n this.field = field;\n }\n\n /**\n * Returns the field value.\n *\n * @return {*} Returns the current value.\n */\n get value () {\n return this._value;\n }\n\n /**\n * Converts to human readable string.\n *\n * @override\n * @return {string} Returns a human readable string of the field value.\n *\n */\n toString () {\n return String(this.value);\n }\n\n /**\n * Returns the value of the field.\n *\n * @override\n * @return {*} Returns the field value.\n */\n valueOf () {\n return this.value;\n }\n}\n\nexport default Value;\n","import { rowDiffsetIterator } from './row-diffset-iterator';\n\n/**\n * Creates bin f from the data and the supplied config.\n *\n * @param {Array} data - The input data.\n * @param {Object} config - The config object.\n * @param {number} config.binSize - The size of the bin.\n * @param {number} config.numOfBins - The number of bins to be created.\n * @return {Array} Returns an array of created bins.\n */\nexport function createBinnedFieldData (field, rowDiffset, config) {\n let { buckets, binCount, binSize, start } = config;\n let dataStore = [];\n let binnedData = [];\n let [min, max] = field.domain();\n let oriMax = max;\n let stops = [];\n let binEnd;\n let prevEndpoint;\n let mid;\n let range;\n\n // create dataStore with index according to rowDiffSet\n rowDiffsetIterator(rowDiffset, (i) => {\n dataStore.push({\n data: field.data[i],\n index: i\n });\n });\n\n // create buckets if buckets not given\n if (!buckets) {\n max += 1;\n binSize = binSize || (max - min) / binCount;\n\n const extraBinELm = (max - min) % binSize;\n if (!binCount && extraBinELm !== 0) {\n max = max + binSize - extraBinELm;\n }\n binEnd = min + binSize;\n while (binEnd <= max) {\n stops.push(binEnd);\n binEnd += binSize;\n }\n start = start || min;\n buckets = { start, stops };\n }\n\n // initialize intial bucket start\n prevEndpoint = buckets.start === 0 ? 0 : buckets.start || min;\n\n // mark each data in dataStore to respective buckets\n buckets.stops.forEach((endPoint) => {\n let tempStore = dataStore.filter(datum => datum.data >= prevEndpoint && datum.data < endPoint);\n tempStore.forEach((datum) => { binnedData[datum.index] = `${prevEndpoint}-${endPoint}`; });\n prevEndpoint = endPoint;\n });\n\n // create a bin for values less than start\n dataStore.filter(datum => datum.data < buckets.start)\n .forEach((datum) => { binnedData[datum.index] = `${min}-${buckets.start}`; });\n\n // create a bin for values more than end\n dataStore.filter(datum => datum.data >= buckets.stops[buckets.stops.length - 1])\n .forEach((datum) =>\n { binnedData[datum.index] = `${buckets.stops[buckets.stops.length - 1]}-${oriMax}`; });\n\n // create range and mid\n // append start to bucket marks\n buckets.stops.unshift(buckets.start);\n range = new Set(buckets.stops);\n\n // Add endpoints to buckets marks if not added\n if (min < buckets.start) { range.add(min); }\n if (oriMax > buckets.stops[buckets.stops.length - 1]) { range.add(oriMax); }\n\n range = [...range].sort((a, b) => a - b);\n mid = [];\n\n for (let i = 1; i < range.length; i++) {\n mid.push((range[i - 1] + range[i]) / 2);\n }\n return { data: binnedData, mid, range };\n}\n","export { DataFormat, FilteringMode } from '../enums';\n/**\n * The event name for data propagation.\n */\nexport const PROPAGATION = 'propagation';\n\n/**\n * The name of the unique row id column in DataModel.\n */\nexport const ROW_ID = '__id__';\n\n/**\n * The enums for operation names performed on DataModel.\n */\nexport const DM_DERIVATIVES = {\n SELECT: 'select',\n PROJECT: 'project',\n GROUPBY: 'group',\n COMPOSE: 'compose',\n CAL_VAR: 'calculatedVariable',\n BIN: 'bin'\n};\n\nexport const JOINS = {\n CROSS: 'cross',\n LEFTOUTER: 'leftOuter',\n RIGHTOUTER: 'rightOuter',\n NATURAL: 'natural',\n FULLOUTER: 'fullOuter'\n};\n\nexport const LOGICAL_OPERATORS = {\n AND: 'and',\n OR: 'or'\n};\n","/* eslint-disable default-case */\nimport { DM_DERIVATIVES } from '../constants';\n\n/**\n * iterate the children and call the callback for each\n *\n * @param {DataModel} datamodel\n * @param {function} callback\n * @param {DM_DERIVATIVES} operation\n */\nfunction childIterator (datamodel, callback, operation) {\n const children = datamodel._children;\n children.forEach((child) => {\n if (child._derivation\n && child._derivation.length === 1) {\n switch (operation) {\n case DM_DERIVATIVES.SELECT:\n if (child._derivation[0].op === DM_DERIVATIVES.SELECT) {\n callback(child, child._derivation[0].criteria);\n }\n break;\n case DM_DERIVATIVES.PROJECT:\n if (child._derivation[0].op === DM_DERIVATIVES.PROJECT) {\n callback(child, child._derivation[0].meta.actualProjField);\n }\n break;\n case DM_DERIVATIVES.GROUPBY:\n if (child._derivation[0].op === DM_DERIVATIVES.GROUPBY) {\n callback(child,\n { groupByString: child._derivation[0].meta.groupByString,\n reducer: child._derivation[0].criteria });\n }\n break;\n case DM_DERIVATIVES.CAL_VAR:\n if (child._derivation[0].op === DM_DERIVATIVES.CAL_VAR) {\n let params = [child._derivation[0].meta.config, [child._derivation[0].meta.fields,\n child._derivation[0].criteria]];\n callback(child, ...params);\n }\n break;\n }\n }\n });\n}\n\n/**\n * Invokes a callback for every child created by a selection operation on a DataModel.\n *\n * @param {DataModel} datamodel - The input DataModel instance.\n * @param {Function} callback - The callback to be invoked on each child. The parameters\n * provided to the callback are the child DataModel instance and the selection\n * function used to create it.\n */\nexport function selectIterator (datamodel, callback) {\n childIterator(datamodel, callback, DM_DERIVATIVES.SELECT);\n}\n\n/**\n * Invokes a callback for every measure child of a DataModel.\n *\n * @param {DataModel} datamodel - The input DataModel instance.\n * @param {Function} callback - The callback to be invoked on each measure child. The parameters\n * provided to the callback are the child DataModel instance and the child params.\n */\nexport function calculatedVariableIterator (datamodel, callback) {\n childIterator(datamodel, callback, DM_DERIVATIVES.CAL_VAR);\n}\n\n/**\n * Invokes a callback for every projected child of a DataModel.\n *\n * @param {DataModel} datamodel - The input DataModel instance.\n * @param {Function} callback - The callback to be invoked on each projected child. The parameters\n * provided to the callback are the child DataModel instance and the\n * projection string.\n */\nexport function projectIterator (datamodel, callback) {\n childIterator(datamodel, callback, DM_DERIVATIVES.PROJECT);\n}\n\n/**\n * Invokes a callback over the children created by a groupBy\n * operation on a DataModel.\n *\n * @param {DataModel} datamodel - The input DataModel instance.\n * @param {Function} callback - The callback to be invoked. The parameters\n * provided to the callback are the child DataModel instance and the groupBy string used to create it.\n */\nexport function groupByIterator (datamodel, callback) {\n childIterator(datamodel, callback, DM_DERIVATIVES.GROUPBY);\n}\n\n","/**\n * The helper function that returns an array of common schema\n * from two fieldStore instances.\n *\n * @param {FieldStore} fs1 - The first FieldStore instance.\n * @param {FieldStore} fs2 - The second FieldStore instance.\n * @return {Array} An array containing the common schema.\n */\nexport function getCommonSchema (fs1, fs2) {\n const retArr = [];\n const fs1Arr = [];\n fs1.fields.forEach((field) => {\n fs1Arr.push(field.schema.name);\n });\n fs2.fields.forEach((field) => {\n if (fs1Arr.indexOf(field.schema.name) !== -1) {\n retArr.push(field.schema.name);\n }\n });\n return retArr;\n}\n","import DataModel from '../datamodel';\nimport { extend2 } from '../utils';\nimport { getCommonSchema } from './get-common-schema';\nimport { rowDiffsetIterator } from './row-diffset-iterator';\nimport { JOINS } from '../constants';\nimport { prepareJoinData } from '../helper';\n/**\n * Default filter function for crossProduct.\n *\n * @return {boolean} Always returns true.\n */\nfunction defaultFilterFn() { return true; }\n\n/**\n * Implementation of cross product operation between two DataModel instances.\n * It internally creates the data and schema for the new DataModel.\n *\n * @param {DataModel} dataModel1 - The left DataModel instance.\n * @param {DataModel} dataModel2 - The right DataModel instance.\n * @param {Function} filterFn - The filter function which is used to filter the tuples.\n * @param {boolean} [replaceCommonSchema=false] - The flag if the common name schema should be there.\n * @return {DataModel} Returns The newly created DataModel instance from the crossProduct operation.\n */\nexport function crossProduct (dm1, dm2, filterFn, replaceCommonSchema = false, jointype = JOINS.CROSS) {\n const schema = [];\n const data = [];\n const applicableFilterFn = filterFn || defaultFilterFn;\n const dm1FieldStore = dm1.getFieldspace();\n const dm2FieldStore = dm2.getFieldspace();\n const dm1FieldStoreName = dm1FieldStore.name;\n const dm2FieldStoreName = dm2FieldStore.name;\n const name = `${dm1FieldStore.name}.${dm2FieldStore.name}`;\n const commonSchemaList = getCommonSchema(dm1FieldStore, dm2FieldStore);\n\n if (dm1FieldStoreName === dm2FieldStoreName) {\n throw new Error('DataModels must have different alias names');\n }\n // Here prepare the schema\n dm1FieldStore.fields.forEach((field) => {\n const tmpSchema = extend2({}, field.schema);\n if (commonSchemaList.indexOf(tmpSchema.name) !== -1 && !replaceCommonSchema) {\n tmpSchema.name = `${dm1FieldStore.name}.${tmpSchema.name}`;\n }\n schema.push(tmpSchema);\n });\n dm2FieldStore.fields.forEach((field) => {\n const tmpSchema = extend2({}, field.schema);\n if (commonSchemaList.indexOf(tmpSchema.name) !== -1) {\n if (!replaceCommonSchema) {\n tmpSchema.name = `${dm2FieldStore.name}.${tmpSchema.name}`;\n schema.push(tmpSchema);\n }\n } else {\n schema.push(tmpSchema);\n }\n });\n\n // Here prepare Data\n rowDiffsetIterator(dm1._rowDiffset, (i) => {\n let rowAdded = false;\n let rowPosition;\n rowDiffsetIterator(dm2._rowDiffset, (ii) => {\n const tuple = [];\n const userArg = {};\n userArg[dm1FieldStoreName] = {};\n userArg[dm2FieldStoreName] = {};\n dm1FieldStore.fields.forEach((field) => {\n tuple.push(field.data[i]);\n userArg[dm1FieldStoreName][field.name] = field.data[i];\n });\n dm2FieldStore.fields.forEach((field) => {\n if (!(commonSchemaList.indexOf(field.schema.name) !== -1 && replaceCommonSchema)) {\n tuple.push(field.data[ii]);\n }\n userArg[dm2FieldStoreName][field.name] = field.data[ii];\n });\n const dm1Fields = prepareJoinData(userArg[dm1FieldStoreName]);\n const dm2Fields = prepareJoinData(userArg[dm2FieldStoreName]);\n if (applicableFilterFn(dm1Fields, dm2Fields)) {\n const tupleObj = {};\n tuple.forEach((cellVal, iii) => {\n tupleObj[schema[iii].name] = cellVal;\n });\n if (rowAdded && JOINS.CROSS !== jointype) {\n data[rowPosition] = tupleObj;\n }\n else {\n data.push(tupleObj);\n rowAdded = true;\n rowPosition = i;\n }\n }\n else if ((jointype === JOINS.LEFTOUTER || jointype === JOINS.RIGHTOUTER) && !rowAdded) {\n const tupleObj = {};\n let len = dm1FieldStore.fields.length - 1;\n tuple.forEach((cellVal, iii) => {\n if (iii <= len) {\n tupleObj[schema[iii].name] = cellVal;\n }\n else {\n tupleObj[schema[iii].name] = null;\n }\n });\n rowAdded = true;\n rowPosition = i;\n data.push(tupleObj);\n }\n });\n });\n\n return new DataModel(data, schema, { name });\n}\n","/**\n * The default sort function.\n *\n * @param {*} a - The first value.\n * @param {*} b - The second value.\n * @return {number} Returns the comparison result e.g. 1 or 0 or -1.\n */\nfunction defSortFn (a, b) {\n const a1 = `${a}`;\n const b1 = `${b}`;\n if (a1 < b1) {\n return -1;\n }\n if (a1 > b1) {\n return 1;\n }\n return 0;\n}\n\n/**\n * The helper function for merge sort which creates the sorted array\n * from the two halves of the input array.\n *\n * @param {Array} arr - The target array which needs to be merged.\n * @param {number} lo - The starting index of the first array half.\n * @param {number} mid - The ending index of the first array half.\n * @param {number} hi - The ending index of the second array half.\n * @param {Function} sortFn - The sort function.\n */\nfunction merge (arr, lo, mid, hi, sortFn) {\n const mainArr = arr;\n const auxArr = [];\n for (let i = lo; i <= hi; i += 1) {\n auxArr[i] = mainArr[i];\n }\n let a = lo;\n let b = mid + 1;\n\n for (let i = lo; i <= hi; i += 1) {\n if (a > mid) {\n mainArr[i] = auxArr[b];\n b += 1;\n } else if (b > hi) {\n mainArr[i] = auxArr[a];\n a += 1;\n } else if (sortFn(auxArr[a], auxArr[b]) <= 0) {\n mainArr[i] = auxArr[a];\n a += 1;\n } else {\n mainArr[i] = auxArr[b];\n b += 1;\n }\n }\n}\n\n/**\n * The helper function for merge sort which would be called\n * recursively for sorting the array halves.\n *\n * @param {Array} arr - The target array which needs to be sorted.\n * @param {number} lo - The starting index of the array half.\n * @param {number} hi - The ending index of the array half.\n * @param {Function} sortFn - The sort function.\n * @return {Array} Returns the target array itself.\n */\nfunction sort (arr, lo, hi, sortFn) {\n if (hi === lo) { return arr; }\n\n const mid = lo + Math.floor((hi - lo) / 2);\n sort(arr, lo, mid, sortFn);\n sort(arr, mid + 1, hi, sortFn);\n merge(arr, lo, mid, hi, sortFn);\n\n return arr;\n}\n\n/**\n * The implementation of merge sort.\n * It is used in DataModel for stable sorting as it is not sure\n * what the sorting algorithm used by browsers is stable or not.\n *\n * @param {Array} arr - The target array which needs to be sorted.\n * @param {Function} [sortFn=defSortFn] - The sort function.\n * @return {Array} Returns the input array itself in sorted order.\n */\nexport function mergeSort (arr, sortFn = defSortFn) {\n if (arr.length > 1) {\n sort(arr, 0, arr.length - 1, sortFn);\n }\n return arr;\n}\n","import { FieldType, DimensionSubtype } from '../enums';\nimport { rowDiffsetIterator } from './row-diffset-iterator';\nimport { mergeSort } from './merge-sort';\nimport { fieldInSchema } from '../helper';\nimport { isCallable, isArray, } from '../utils';\n/**\n * Generates the sorting functions to sort the data of a DataModel instance\n * according to the input data type.\n *\n * @param {string} dataType - The data type e.g. 'measure', 'datetime' etc.\n * @param {string} sortType - The sorting order i.e. 'asc' or 'desc'.\n * @param {integer} index - The index of the data which will be sorted.\n * @return {Function} Returns the the sorting function.\n */\nfunction getSortFn (dataType, sortType, index) {\n let retFunc;\n switch (dataType) {\n case FieldType.MEASURE:\n case DimensionSubtype.TEMPORAL:\n if (sortType === 'desc') {\n retFunc = (a, b) => b[index] - a[index];\n } else {\n retFunc = (a, b) => a[index] - b[index];\n }\n break;\n default:\n retFunc = (a, b) => {\n const a1 = `${a[index]}`;\n const b1 = `${b[index]}`;\n if (a1 < b1) {\n return sortType === 'desc' ? 1 : -1;\n }\n if (a1 > b1) {\n return sortType === 'desc' ? -1 : 1;\n }\n return 0;\n };\n }\n return retFunc;\n}\n\n/**\n * Groups the data according to the specified target field.\n *\n * @param {Array} data - The input data array.\n * @param {number} fieldIndex - The target field index within schema array.\n * @return {Array} Returns an array containing the grouped data.\n */\nfunction groupData(data, fieldIndex) {\n const hashMap = new Map();\n const groupedData = [];\n\n data.forEach((datum) => {\n const fieldVal = datum[fieldIndex];\n if (hashMap.has(fieldVal)) {\n groupedData[hashMap.get(fieldVal)][1].push(datum);\n } else {\n groupedData.push([fieldVal, [datum]]);\n hashMap.set(fieldVal, groupedData.length - 1);\n }\n });\n\n return groupedData;\n}\n\n/**\n * Creates the argument value used for sorting function when sort is done\n * with another fields.\n *\n * @param {Array} groupedDatum - The grouped datum for a single dimension field value.\n * @param {Array} targetFields - An array of the sorting fields.\n * @param {Array} targetFieldDetails - An array of the sorting field details in schema.\n * @return {Object} Returns an object containing the value of sorting fields and the target field name.\n */\nfunction createSortingFnArg(groupedDatum, targetFields, targetFieldDetails) {\n const arg = {\n label: groupedDatum[0]\n };\n\n targetFields.reduce((acc, next, idx) => {\n acc[next] = groupedDatum[1].map(datum => datum[targetFieldDetails[idx].index]);\n return acc;\n }, arg);\n\n return arg;\n}\n\n/**\n * Sorts the data before return in dataBuilder.\n *\n * @param {Object} dataObj - An object containing the data and schema.\n * @param {Array} sortingDetails - An array containing the sorting configs.\n */\nfunction sortData(dataObj, sortingDetails) {\n const { data, schema } = dataObj;\n let fieldName;\n let sortMeta;\n let fDetails;\n let i = sortingDetails.length - 1;\n\n for (; i >= 0; i--) {\n fieldName = sortingDetails[i][0];\n sortMeta = sortingDetails[i][1];\n fDetails = fieldInSchema(schema, fieldName);\n\n if (!fDetails) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n if (isCallable(sortMeta)) {\n // eslint-disable-next-line no-loop-func\n mergeSort(data, (a, b) => sortMeta(a[fDetails.index], b[fDetails.index]));\n } else if (isArray(sortMeta)) {\n const groupedData = groupData(data, fDetails.index);\n const sortingFn = sortMeta[sortMeta.length - 1];\n const targetFields = sortMeta.slice(0, sortMeta.length - 1);\n const targetFieldDetails = targetFields.map(f => fieldInSchema(schema, f));\n\n groupedData.forEach((groupedDatum) => {\n groupedDatum.push(createSortingFnArg(groupedDatum, targetFields, targetFieldDetails));\n });\n\n mergeSort(groupedData, (a, b) => {\n const m = a[2];\n const n = b[2];\n return sortingFn(m, n);\n });\n\n // Empty the array\n data.length = 0;\n groupedData.forEach((datum) => {\n data.push(...datum[1]);\n });\n } else {\n sortMeta = String(sortMeta).toLowerCase() === 'desc' ? 'desc' : 'asc';\n mergeSort(data, getSortFn(fDetails.type, sortMeta, fDetails.index));\n }\n }\n\n dataObj.uids = [];\n data.forEach((value) => {\n dataObj.uids.push(value.pop());\n });\n}\n\n\n/**\n * Builds the actual data array.\n *\n * @param {Array} fieldStore - An array of field.\n * @param {string} rowDiffset - A string consisting of which rows to be included eg. '0-2,4,6';\n * @param {string} colIdentifier - A string consisting of the details of which column\n * to be included eg 'date,sales,profit';\n * @param {Object} sortingDetails - An object containing the sorting details of the DataModel instance.\n * @param {Object} options - The options required to create the type of the data.\n * @return {Object} Returns an object containing the multidimensional array and the relative schema.\n */\nexport function dataBuilder (fieldStore, rowDiffset, colIdentifier, sortingDetails, options) {\n const defOptions = {\n addUid: false,\n columnWise: false\n };\n options = Object.assign({}, defOptions, options);\n\n const retObj = {\n schema: [],\n data: [],\n uids: []\n };\n const addUid = options.addUid;\n const reqSorting = sortingDetails && sortingDetails.length > 0;\n // It stores the fields according to the colIdentifier argument\n const tmpDataArr = [];\n // Stores the fields according to the colIdentifier argument\n const colIArr = colIdentifier.split(',');\n\n colIArr.forEach((colName) => {\n for (let i = 0; i < fieldStore.length; i += 1) {\n if (fieldStore[i].name === colName) {\n tmpDataArr.push(fieldStore[i]);\n break;\n }\n }\n });\n\n // Inserts the schema to the schema object\n tmpDataArr.forEach((field) => {\n /** @todo Need to use extend2 here otherwise user can overwrite the schema. */\n retObj.schema.push(field.schema);\n });\n\n if (addUid) {\n retObj.schema.push({\n name: 'uid',\n type: 'identifier'\n });\n }\n\n rowDiffsetIterator(rowDiffset, (i) => {\n retObj.data.push([]);\n const insertInd = retObj.data.length - 1;\n let start = 0;\n tmpDataArr.forEach((field, ii) => {\n retObj.data[insertInd][ii + start] = field.data[i];\n });\n if (addUid) {\n retObj.data[insertInd][tmpDataArr.length] = i;\n }\n // Creates an array of unique identifiers for each row\n retObj.uids.push(i);\n\n // If sorting needed then there is the need to expose the index\n // mapping from the old index to its new index\n if (reqSorting) { retObj.data[insertInd].push(i); }\n });\n\n // Handles the sort functionality\n if (reqSorting) {\n sortData(retObj, sortingDetails);\n }\n\n if (options.columnWise) {\n const tmpData = Array(...Array(retObj.schema.length)).map(() => []);\n retObj.data.forEach((tuple) => {\n tuple.forEach((data, i) => {\n tmpData[i].push(data);\n });\n });\n retObj.data = tmpData;\n }\n\n return retObj;\n}\n","import DataModel from '../datamodel';\nimport { extend2 } from '../utils';\nimport { rowDiffsetIterator } from './row-diffset-iterator';\nimport { isArrEqual } from '../utils/helper';\n\n/**\n * Performs the union operation between two dm instances.\n *\n * @todo Fix the conflicts between union and difference terminology here.\n *\n * @param {dm} dm1 - The first dm instance.\n * @param {dm} dm2 - The second dm instance.\n * @return {dm} Returns the newly created dm after union operation.\n */\nexport function difference (dm1, dm2) {\n const hashTable = {};\n const schema = [];\n const schemaNameArr = [];\n const data = [];\n const dm1FieldStore = dm1.getFieldspace();\n const dm2FieldStore = dm2.getFieldspace();\n const dm1FieldStoreFieldObj = dm1FieldStore.fieldsObj();\n const dm2FieldStoreFieldObj = dm2FieldStore.fieldsObj();\n const name = `${dm1FieldStore.name} union ${dm2FieldStore.name}`;\n\n // For union the columns should match otherwise return a clone of the dm1\n if (!isArrEqual(dm1._colIdentifier.split(',').sort(), dm2._colIdentifier.split(',').sort())) {\n return null;\n }\n\n // Prepare the schema\n (dm1._colIdentifier.split(',')).forEach((fieldName) => {\n const field = dm1FieldStoreFieldObj[fieldName];\n schema.push(extend2({}, field.schema));\n schemaNameArr.push(field.schema.name);\n });\n\n /**\n * The helper function to create the data.\n *\n * @param {dm} dm - The dm instance for which the data is inserted.\n * @param {Object} fieldsObj - The fieldStore object format.\n * @param {boolean} addData - If true only tuple will be added to the data.\n */\n function prepareDataHelper(dm, fieldsObj, addData) {\n rowDiffsetIterator(dm._rowDiffset, (i) => {\n const tuple = {};\n let hashData = '';\n schemaNameArr.forEach((schemaName) => {\n const value = fieldsObj[schemaName].data[i];\n hashData += `-${value}`;\n tuple[schemaName] = value;\n });\n if (!hashTable[hashData]) {\n if (addData) { data.push(tuple); }\n hashTable[hashData] = true;\n }\n });\n }\n\n // Prepare the data\n prepareDataHelper(dm2, dm2FieldStoreFieldObj, false);\n prepareDataHelper(dm1, dm1FieldStoreFieldObj, true);\n\n return new DataModel(data, schema, { name });\n}\n\n","/**\n * Reducer function that takes care about the sum aggregation\n * @param {Array} arr array of values\n * @return {number} sum of the array\n */\nfunction sum (arr) {\n let allNulls = true;\n const isNestedArray = arr[0] instanceof Array;\n const sumVal = arr.reduce((carry, a) => {\n if (isNestedArray) {\n return carry.map((x, i) => x + a[i]);\n }\n allNulls = allNulls && (a === null);\n return carry + a;\n }, isNestedArray ? Array(...Array(arr[0].length)).map(() => 0) : 0);\n return allNulls ? null : sumVal;\n}\n\n/**\n * reducer function that takes care about the mean aggregation\n * @param {Array} arr array of values\n * @return {number} mean of the array\n */\nfunction avg (arr) {\n const isNestedArray = arr[0] instanceof Array;\n const len = arr.length || 1;\n const arrSum = sum(arr);\n if (isNestedArray) {\n return arrSum.map(x => x / len);\n }\n return arrSum === null ? null : arrSum / len;\n}\n\n/**\n * reducer function that gives the min value\n * @param {Array} arr array of values\n * @return {number} min of the array\n */\nfunction min (arr) {\n const isNestedArray = arr[0] instanceof Array;\n if (isNestedArray) {\n return arr.reduce((carry, a) => carry.map((x, i) => Math.min(x, a[i])),\n Array(...Array(arr[0].length)).map(() => Infinity));\n }\n return arr.every(d => d === null) ? null : Math.min(...arr);\n}\n\n/**\n * reducer function that gives the max value\n * @param {Array} arr array of values\n * @return {number} max of the array\n */\nfunction max (arr) {\n const isNestedArray = arr[0] instanceof Array;\n if (isNestedArray) {\n return arr.reduce((carry, a) => carry.map((x, i) => Math.max(x, a[i])),\n Array(...Array(arr[0].length)).map(() => -Infinity));\n }\n return arr.every(d => d === null) ? null : Math.max(...arr);\n}\n\n/**\n * reducer function that gives the first value\n * @param {Array} arr array of values\n * @return {number} first value of the array\n */\nfunction first (arr) {\n return arr[0];\n}\n\n/**\n * reducer function that gives the last value\n * @param {Array} arr array of values\n * @return {number} last value of the array\n */\nfunction last (arr) {\n return arr[arr.length - 1];\n}\n\n/**\n * reducer function that gives the count value\n * @param {Array} arr array of values\n * @return {number} count of the array\n */\nfunction count (arr) {\n const isNestedArray = arr[0] instanceof Array;\n const len = arr.length;\n if (isNestedArray) {\n return Array(...Array(arr[0].length)).map(() => len);\n }\n return len;\n}\n\n/**\n * Calculates the variance of the input array.\n *\n * @param {Array.} arr - The input array.\n * @return {number} Returns the variance of the input array.\n */\nfunction variance (arr) {\n let mean = avg(arr);\n return avg(arr.map(num => (num - mean) ** 2));\n}\n\n/**\n * Calculates the square root of the variance of the input array.\n *\n * @param {Array.} arr - The input array.\n * @return {number} Returns the square root of the variance.\n */\nfunction std (arr) {\n return Math.sqrt(variance(arr));\n}\n\n\nconst fnList = {\n sum,\n avg,\n min,\n max,\n first,\n last,\n count,\n std\n};\n\nconst defaultReducerName = 'sum';\n\nexport {\n defaultReducerName,\n sum as defReducer,\n fnList,\n};\n","import { defReducer, fnList } from '../operator';\n\n/**\n * A page level storage which stores, registers, unregisters reducers for all the datamodel instances. There is only one\n * reducer store available in a page. All the datamodel instances receive same instance of reducer store. DataModel\n * out of the box provides handful of {@link reducer | reducers} which can be used as reducer funciton.\n *\n * @public\n * @namespace DataModel\n */\nclass ReducerStore {\n constructor () {\n this.store = new Map();\n this.store.set('defReducer', defReducer);\n\n Object.entries(fnList).forEach((key) => {\n this.store.set(key[0], key[1]);\n });\n }\n\n /**\n * Changes the `defaultReducer` globally. For all the fields which does not have `defAggFn` mentioned in schema, the\n * value of `defaultReducer` is used for aggregation.\n *\n * @public\n *\n * @param {string} [reducer='sum'] name of the default reducer. It picks up the definition from store by doing name\n * lookup. If no name is found then it takes `sum` as the default reducer.\n *\n * @return {ReducerStore} instance of the singleton store in page.\n */\n defaultReducer (...params) {\n if (params.length) {\n let reducer = params[0];\n if (typeof reducer === 'function') {\n this.store.set('defReducer', reducer);\n } else if (typeof reducer === 'string') {\n if (Object.keys(fnList).indexOf(reducer) !== -1) {\n this.store.set('defReducer', fnList[reducer]);\n }\n }\n return this;\n }\n\n return this.store.get('defReducer');\n }\n\n /**\n *\n * Registers a {@link reducer | reducer}.\n * A {@link reducer | reducer} has to be registered before it is used.\n *\n * @example\n * // find the mean squared value of a given set\n * const reducerStore = DataModel.Reducers();\n *\n * reducers.register('meanSquared', (arr) => {\n * const squaredVal = arr.map(item => item * item);\n * let sum = 0;\n * for (let i = 0, l = squaredVal.length; i < l; i++) {\n * sum += squaredVal[i++];\n * }\n *\n * return sum;\n * })\n *\n * // datamodel (dm) is already prepared with cars.json\n * const dm1 = dm.groupBy(['origin'], {\n * accleration: 'meanSquared'\n * });\n *\n * @public\n *\n * @param {string} name formal name for a reducer. If the given name already exists in store it is overridden by new\n * definition.\n * @param {Function} reducer definition of {@link reducer} function.\n *\n * @return {Function} function for unregistering the reducer.\n */\n register (name, reducer) {\n if (typeof name === 'string' && typeof reducer === 'function') {\n this.store.set(name, reducer);\n }\n\n return () => { this.__unregister(name); };\n }\n\n __unregister (name) {\n if (this.store.has(name)) {\n this.store.delete(name);\n }\n }\n\n resolve (name) {\n if (name instanceof Function) {\n return name;\n }\n return this.store.get(name);\n }\n}\n\nconst reducerStore = (function () {\n let store = null;\n\n function getStore () {\n if (store === null) {\n store = new ReducerStore();\n }\n return store;\n }\n return getStore();\n}());\n\nexport default reducerStore;\n","import { extend2 } from '../utils';\nimport { rowDiffsetIterator } from './row-diffset-iterator';\nimport DataModel from '../export';\nimport reducerStore from '../utils/reducer-store';\n\n/**\n * This function sanitize the user given field and return a common Array structure field\n * list\n * @param {DataModel} dataModel the dataModel operating on\n * @param {Array} fieldArr user input of field Array\n * @return {Array} arrays of field name\n */\nfunction getFieldArr (dataModel, fieldArr) {\n const retArr = [];\n const fieldStore = dataModel.getPartialFieldspace();\n const dimensions = fieldStore.getDimension();\n const measures = fieldStore.getMeasure();\n\n Object.entries(dimensions).forEach(([key]) => {\n if (fieldArr && fieldArr.length) {\n if (fieldArr.indexOf(key) !== -1) {\n retArr.push(key);\n }\n } else {\n retArr.push(key);\n }\n });\n\n Object.entries(measures).forEach(([key]) => {\n if (measures[key].subType() === 'discrete') {\n if (fieldArr && fieldArr.length) {\n if (fieldArr.indexOf(key) !== -1) {\n retArr.push(key);\n }\n } else {\n retArr.push(key);\n }\n }\n });\n return retArr;\n}\n\n/**\n * This sanitize the reducer provide by the user and create a common type of object.\n * user can give function Also\n * @param {DataModel} dataModel dataModel to worked on\n * @param {Object|function} [reducers={}] reducer provided by the users\n * @return {Object} object containing reducer function for every measure\n */\nfunction getReducerObj (dataModel, reducers = {}) {\n const retObj = {};\n const pReducers = reducers;\n const fieldStore = dataModel.getPartialFieldspace();\n const measures = fieldStore.getMeasure();\n let reducer = reducerStore.defaultReducer();\n if (typeof reducers === 'function') {\n reducer = reducers;\n }\n Object.entries(measures).forEach(([key]) => {\n if (typeof reducers[key] === 'string') {\n pReducers[key] = reducerStore.resolve(pReducers[key]) ? reducerStore.resolve(pReducers[key]) : reducer;\n }\n if (typeof reducers[key] !== 'function') {\n pReducers[key] = undefined;\n }\n retObj[key] = pReducers[key] || reducerStore.resolve(measures[key].defAggFn()) || reducer;\n });\n return retObj;\n}\n\n/**\n * main function which perform the group-by operations which reduce the measures value is the\n * fields are common according to the reducer function provided\n * @param {DataModel} dataModel the dataModel to worked\n * @param {Array} fieldArr fields according to which the groupby should be worked\n * @param {Object|Function} reducers reducers function\n * @param {DataModel} existingDataModel Existing datamodel instance\n * @return {DataModel} new dataModel with the group by\n */\nfunction groupBy (dataModel, fieldArr, reducers, existingDataModel) {\n const sFieldArr = getFieldArr(dataModel, fieldArr);\n const reducerObj = getReducerObj(dataModel, reducers);\n const fieldStore = dataModel.getPartialFieldspace();\n const fieldStoreObj = fieldStore.fieldsObj();\n const dbName = fieldStore.name;\n const dimensionArr = [];\n const measureArr = [];\n const schema = [];\n const hashMap = {};\n const data = [];\n let newDataModel;\n // Prepare the schema\n Object.entries(fieldStoreObj).forEach(([key, value]) => {\n if (sFieldArr.indexOf(key) !== -1 || reducerObj[key]) {\n schema.push(extend2({}, value.schema));\n if (value.schema.type === 'measure' && value.schema.subtype !== 'discrete') {\n measureArr.push(key);\n } else if (value.schema.type === 'dimension' || value.schema.subtype === 'discrete') {\n dimensionArr.push(key);\n }\n }\n });\n // Prepare the data\n let rowCount = 0;\n rowDiffsetIterator(dataModel._rowDiffset, (i) => {\n let hash = '';\n dimensionArr.forEach((_) => {\n hash = `${hash}-${fieldStoreObj[_].data[i]}`;\n });\n if (hashMap[hash] === undefined) {\n hashMap[hash] = rowCount;\n data.push({});\n dimensionArr.forEach((_) => {\n data[rowCount][_] = fieldStoreObj[_].data[i];\n });\n measureArr.forEach((_) => {\n data[rowCount][_] = [fieldStoreObj[_].data[i]];\n });\n rowCount += 1;\n } else {\n measureArr.forEach((_) => {\n data[hashMap[hash]][_].push(fieldStoreObj[_].data[i]);\n });\n }\n });\n // reduction\n data.forEach((row) => {\n const tuple = row;\n measureArr.forEach((_) => {\n tuple[_] = reducerObj[_](row[_]);\n });\n });\n if (existingDataModel) {\n existingDataModel.__calculateFieldspace();\n newDataModel = existingDataModel;\n }\n else {\n newDataModel = new DataModel(data, schema, { name: dbName });\n }\n return newDataModel;\n}\n\nexport { groupBy, getFieldArr, getReducerObj };\n","import { getCommonSchema } from './get-common-schema';\n\n/**\n * The filter function used in natural join.\n * It generates a function that will have the logic to join two\n * DataModel instances by the process of natural join.\n *\n * @param {DataModel} dm1 - The left DataModel instance.\n * @param {DataModel} dm2 - The right DataModel instance.\n * @return {Function} Returns a function that is used in cross-product operation.\n */\nexport function naturalJoinFilter (dm1, dm2) {\n const dm1FieldStore = dm1.getFieldspace();\n const dm2FieldStore = dm2.getFieldspace();\n // const dm1FieldStoreName = dm1FieldStore.name;\n // const dm2FieldStoreName = dm2FieldStore.name;\n const commonSchemaArr = getCommonSchema(dm1FieldStore, dm2FieldStore);\n\n return (dm1Fields, dm2Fields) => {\n let retainTuple = true;\n commonSchemaArr.forEach((fieldName) => {\n if (dm1Fields[fieldName].value ===\n dm2Fields[fieldName].value && retainTuple) {\n retainTuple = true;\n } else {\n retainTuple = false;\n }\n });\n return retainTuple;\n };\n}\n","import DataModel from '../export';\nimport { extend2 } from '../utils';\nimport { rowDiffsetIterator } from './row-diffset-iterator';\nimport { isArrEqual } from '../utils/helper';\n/**\n * Performs the union operation between two dm instances.\n *\n * @param {dm} dm1 - The first dm instance.\n * @param {dm} dm2 - The second dm instance.\n * @return {dm} Returns the newly created dm after union operation.\n */\nexport function union (dm1, dm2) {\n const hashTable = {};\n const schema = [];\n const schemaNameArr = [];\n const data = [];\n const dm1FieldStore = dm1.getFieldspace();\n const dm2FieldStore = dm2.getFieldspace();\n const dm1FieldStoreFieldObj = dm1FieldStore.fieldsObj();\n const dm2FieldStoreFieldObj = dm2FieldStore.fieldsObj();\n const name = `${dm1FieldStore.name} union ${dm2FieldStore.name}`;\n\n // For union the columns should match otherwise return a clone of the dm1\n if (!isArrEqual(dm1._colIdentifier.split(',').sort(), dm2._colIdentifier.split(',').sort())) {\n return null;\n }\n\n // Prepare the schema\n (dm1._colIdentifier.split(',')).forEach((fieldName) => {\n const field = dm1FieldStoreFieldObj[fieldName];\n schema.push(extend2({}, field.schema));\n schemaNameArr.push(field.schema.name);\n });\n\n /**\n * The helper function to create the data.\n *\n * @param {dm} dm - The dm instance for which the data is inserted.\n * @param {Object} fieldsObj - The fieldStore object format.\n */\n function prepareDataHelper (dm, fieldsObj) {\n rowDiffsetIterator(dm._rowDiffset, (i) => {\n const tuple = {};\n let hashData = '';\n schemaNameArr.forEach((schemaName) => {\n const value = fieldsObj[schemaName].data[i];\n hashData += `-${value}`;\n tuple[schemaName] = value;\n });\n if (!hashTable[hashData]) {\n data.push(tuple);\n hashTable[hashData] = true;\n }\n });\n }\n\n // Prepare the data\n prepareDataHelper(dm1, dm1FieldStoreFieldObj);\n prepareDataHelper(dm2, dm2FieldStoreFieldObj);\n\n return new DataModel(data, schema, { name });\n}\n","import { crossProduct } from './cross-product';\nimport { JOINS } from '../constants';\nimport { union } from './union';\n\n\nexport function leftOuterJoin (dataModel1, dataModel2, filterFn) {\n return crossProduct(dataModel1, dataModel2, filterFn, false, JOINS.LEFTOUTER);\n}\n\nexport function rightOuterJoin (dataModel1, dataModel2, filterFn) {\n return crossProduct(dataModel2, dataModel1, filterFn, false, JOINS.RIGHTOUTER);\n}\n\nexport function fullOuterJoin (dataModel1, dataModel2, filterFn) {\n return union(leftOuterJoin(dataModel1, dataModel2, filterFn), rightOuterJoin(dataModel1, dataModel2, filterFn));\n}\n","import { extend2 } from '../utils';\n\n /**\n * The base class for every field type.\n * It provides some common functionalities.\n */\nclass PartialField {\n\n /**\n * Sets basic setups to each Field instance.\n *\n * @param {string} name - The name or identifier of the field.\n * @param {Array} data - The data array.\n * @param {Object} schema - The schema of the data type.\n */\n constructor(name, data, schema) {\n this.name = name;\n this.data = data || [];\n this.schema = schema;\n this.fieldDescription = schema.description;\n this.fieldType = schema.type;\n this.sanitize();\n }\n\n /**\n * Sanitizes the field data.\n *\n * @return {PartialField} - Returns the instance of the current context for chaining.\n */\n sanitize () {\n this.data = this.data.map(d => this.parsed(this.parse(d)));\n return this;\n }\n\n /**\n * The post parsing hook for field instance.\n *\n * @param {*} val - The value to be parsed.\n * @return {*} Returns the parsed value.\n */\n parsed (val) {\n return val;\n }\n\n /**\n * Generates and returns the domain for the field.\n *\n * @abstract\n */\n domain() {\n throw new Error('Not yet implemented!');\n }\n\n subType() {\n return null;\n }\n\n\n /**\n * Parse the input value before using.\n *\n * @abstract\n */\n parse () {\n throw new Error('Not yet implemented!');\n }\n\n /**\n * Creates brand new copy of current field instance. To avoid optimization issue\n * pass the required data otherwise current data would be copied which might\n * be expensive.\n *\n * @param {Array} data - The input data, if provided current data will not be cloned.\n * @return {PartialField} Returns the cloned field instance.\n */\n clone(data) {\n data = data || extend2([], this.data);\n const schema = extend2({}, this.schema);\n // Here call the constructor to create an instance of\n // the current field class type e.g. Measure, Dimension etc.\n return new this.constructor(this.name, data, schema);\n }\n\n /**\n * @return {string} Name of the field\n */\n fieldName() {\n return this.name;\n }\n\n /**\n * @return {string} Type of the field\n */\n type() {\n return this.fieldType;\n }\n\n /**\n * @return {description} Name of the field\n */\n description() {\n return this.fieldDescription;\n }\n}\n\nexport default PartialField;\n","import PartialField from './partial-field';\nimport { generateMeasureDomain, formatNumber } from '../utils';\nimport { defaultReducerName } from '../operator/group-by-function';\n\n/**\n * Represents measure field type.\n *\n * @extends PartialField\n */\nclass Measure extends PartialField {\n\n /**\n * Creates new Measure field instance.\n *\n * @param {string} name - The name of the field.\n * @param {Array} data - An array containing the field data.\n * @param {Object} schema - The schema for the field.\n */\n constructor(name, data, schema) {\n super(name, data, schema);\n this.fieldUnit = schema.unit;\n this.fieldScale = schema.scale;\n this.fieldDefAggFn = schema.defAggFn || defaultReducerName;\n this.fieldNumberformat = schema.numberFormat instanceof Function ? schema.numberFormat : formatNumber;\n }\n\n /**\n * Returns the domain for the measure field.\n *\n * @override\n * @return {Array} Returns min and max values from measure values.\n */\n domain() {\n return generateMeasureDomain(this.data);\n }\n\n /**\n * A hook which is called for every entry(cell) of the column.\n *\n * @todo Fix the null data e.g. NaN value.\n *\n * @param {*} val - The current entry present in the column while iteration.\n * @return {number | null} Returns the parsed number value of content of cell or null.\n */\n parse (val) {\n val = parseFloat(val, 10);\n return Number.isNaN(val) ? null : val;\n }\n\n /**\n * Getter for unit value of the field.\n *\n * @return {string} Returns unit of the field.\n */\n unit() {\n return this.fieldUnit;\n }\n\n /**\n * Getter for scale value of the field.\n *\n * @return {string} Returns scale of the field.\n */\n scale() {\n return this.fieldScale;\n }\n\n /**\n * Getter for number format value of the field.\n *\n * @return {string} Returns number format of the field.\n */\n numberFormat() {\n const formatter = this.fieldNumberformat;\n return val => formatter(val);\n }\n\n /**\n * Getter for aggregation function of the field.\n *\n * @return {Function} Returns aggregation function of the field.\n */\n defAggFn() {\n return this.fieldDefAggFn;\n }\n}\n\nexport default Measure;\n","/**\n * Generates domain for measure field.\n *\n * @param {Array} data - The array of data.\n * @return {Array} Returns the measure domain.\n */\nexport default (data) => {\n let min = Number.POSITIVE_INFINITY;\n let max = Number.NEGATIVE_INFINITY;\n\n data.forEach((d) => {\n if (d < min) {\n min = d;\n }\n if (d > max) {\n max = d;\n }\n });\n\n return [min, max];\n};\n","import PartialField from './partial-field';\nimport { uniqueValues } from '../utils';\n\n/**\n * Represents dimension field type.\n *\n * @extends PartialField\n */\nclass Dimension extends PartialField {\n\n /**\n * Returns the domain for the dimension field.\n *\n * @override\n * @return {Array} Returns the unique values from dimension values.\n */\n domain() {\n return uniqueValues(this.data);\n }\n\n /**\n * A hook which is called for every entry(cell) of the column.\n *\n * @todo Fix the null data e.g. undefined or null etc.\n *\n * @param {*} val - The current entry present in the column while iteration.\n * @return {string} Returns the string representation of the value.\n */\n parse (val) {\n val = (val === undefined || val === null) ? '' : val.toString();\n return val.trim();\n }\n\n /**\n * Saves the cardinality of the dimensional values after parsing the data.\n *\n * @param {string} val - The parsed value.\n * @return {string} Returns the input val.\n */\n parsed (val) {\n this._unique = this._unique || {};\n const unique = this._unique;\n if (val in unique) {\n unique[val]++;\n } else {\n unique[val] = 1;\n }\n return val;\n }\n}\n\nexport default Dimension;\n","import { DimensionSubtype } from '../enums';\nimport Dimension from './dimension';\n\n/**\n * Represents categorical field subtype.\n *\n * @extends Dimension\n */\nclass Categorical extends Dimension {\n\n /**\n * Creates new Categorical field instance.\n *\n * @param {string} name - The name of the field.\n * @param {Array} data - An array containing the field data.\n * @param {Object} schema - The schema for the field.\n */\n constructor(name, data, schema) {\n super(name, data, schema);\n this.subtype = DimensionSubtype.CATEGORICAL;\n }\n\n /**\n * Getter for subType value of the field.\n *\n * @return {string} Returns subType of the field.\n */\n subType() {\n return this.subtype;\n }\n}\n\nexport default Categorical;\n","import { DimensionSubtype } from '../enums';\nimport Dimension from './dimension';\nimport { DateTimeFormatter, getMinDiff } from '../utils';\n\n\n/**\n * Represents datetime field subtype.\n *\n * @extends Dimension\n */\nclass DateTime extends Dimension {\n\n /**\n * Creates new DateTime field instance.\n *\n * @param {string} name - The name of the field.\n * @param {Array} data - An array containing the field data.\n * @param {Object} schema - The schema for the field.\n */\n constructor(name, data, schema) {\n super(name, data, schema);\n this.subtype = DimensionSubtype.TEMPORAL;\n this.minDiff = getMinDiff(this.data);\n }\n\n /**\n * Getter for subType value of the field.\n *\n * @return {string} Returns subType of the field.\n */\n subType() {\n return this.subtype;\n }\n\n getMinDiff () {\n return this.minDiff;\n }\n /**\n * A hook which is called for every entry(cell) of the column.\n *\n * @param {*} val - The current entry present in the column while iteration.\n * @return {number} Returns the total timestamps in millisecond.\n */\n parse(val) {\n if (this.schema.format) {\n this._dtf = this._dtf || new DateTimeFormatter(this.schema.format);\n return this._dtf.getNativeDate(val).getTime();\n }\n\n // If format is not present then it means the value is such that the it could be directly passed to date\n // constructor\n return +new Date(val);\n }\n}\n\nexport default DateTime;\n","import Measure from './measure';\n\n/**\n * Represents categorical field subtype.\n *\n * @extends Measure\n */\nclass DiscreteMeasure extends Measure {\n constructor(name, data, schema, bin) {\n super(name, data, schema);\n this.bin = bin;\n this.subtype = 'discrete';\n }\n\n /**\n * A hook which is called for every entry(cell) of the column.\n *\n * @todo Fix the null data e.g. undefined or null etc.\n *\n * @param {*} val - The current entry present in the column while iteration.\n * @return {string} Returns the string representation of the value.\n */\n parse (val) {\n val = (val === undefined || val === null) ? '' : val.toString();\n return val.trim();\n }\n\n bins() {\n return this.bin;\n }\n subType() {\n return this.subtype;\n }\n}\n\nexport default DiscreteMeasure;\n","import { FieldType, DimensionSubtype } from './enums';\nimport { Measure, Categorical, DateTime, DiscreteMeasure } from './fields';\n\n/**\n * Creates a field instance according to the provided data and schema.\n *\n * @todo Add logic for GEO dimension subtype.\n *\n * @param {Array} data - The field data array.\n * @param {Object} schema - The field schema object.\n * @return {Field} Returns the newly created field instance.\n */\nfunction createUnitField (data, schema) {\n switch (schema.type) {\n case FieldType.MEASURE:\n switch (schema.subtype) {\n case 'discrete':\n return new DiscreteMeasure(schema.name, data, schema, schema.bins);\n default:\n return new Measure(schema.name, data, schema);\n }\n case FieldType.DIMENSION:\n default:\n switch (schema.subtype) {\n case DimensionSubtype.CATEGORICAL:\n return new Categorical(schema.name, data, schema);\n case DimensionSubtype.TEMPORAL:\n return new DateTime(schema.name, data, schema);\n case DimensionSubtype.GEO:\n return new Categorical(schema.name, data, schema);\n default:\n return new Categorical(schema.name, data, schema);\n }\n }\n}\n\n/**\n * Creates the field instances with input data and schema.\n *\n * @param {Array} dataColumn - The data array for fields.\n * @param {Array} schema - The schema array for fields.\n * @param {Array} headers - The array of header names.\n * @return {Array.} Returns an array of newly created field instances.\n */\nfunction createFields (dataColumn, schema, headers) {\n const headersObj = {};\n\n if (!(headers && headers.length)) {\n headers = schema.map(item => item.name);\n }\n\n headers.forEach((header, i) => {\n headersObj[header] = i;\n });\n\n return schema.map(item => createUnitField(dataColumn[headersObj[item.name]], item));\n}\n\nexport default createFields;\n","import { DataFormat } from './enums';\n\nexport default {\n dataFormat: DataFormat.AUTO\n};\n","import { columnMajor } from '../utils';\n\n/**\n * Parses and converts data formatted in DSV array to a manageable internal format.\n *\n * @param {Array.} arr - A 2D array containing of the DSV data.\n * @param {Object} options - Option to control the behaviour of the parsing.\n * @param {boolean} [options.firstRowHeader=true] - Whether the first row of the dsv data is header or not.\n * @return {Array} Returns an array of headers and column major data.\n * @example\n *\n * // Sample input data:\n * const data = [\n * [\"a\", \"b\", \"c\"],\n * [1, 2, 3],\n * [4, 5, 6],\n * [7, 8, 9]\n * ];\n */\nfunction DSVArr (arr, options) {\n const defaultOption = {\n firstRowHeader: true,\n };\n options = Object.assign({}, defaultOption, options);\n\n let header;\n const columns = [];\n const push = columnMajor(columns);\n\n if (options.firstRowHeader) {\n // If header present then mutate the array.\n // Do in-place mutation to save space.\n header = arr.splice(0, 1)[0];\n } else {\n header = [];\n }\n\n arr.forEach(field => push(...field));\n\n return [header, columns];\n}\n\nexport default DSVArr;\n","var EOL = {},\n EOF = {},\n QUOTE = 34,\n NEWLINE = 10,\n RETURN = 13;\n\nfunction objectConverter(columns) {\n return new Function(\"d\", \"return {\" + columns.map(function(name, i) {\n return JSON.stringify(name) + \": d[\" + i + \"]\";\n }).join(\",\") + \"}\");\n}\n\nfunction customConverter(columns, f) {\n var object = objectConverter(columns);\n return function(row, i) {\n return f(object(row), i, columns);\n };\n}\n\n// Compute unique columns in order of discovery.\nfunction inferColumns(rows) {\n var columnSet = Object.create(null),\n columns = [];\n\n rows.forEach(function(row) {\n for (var column in row) {\n if (!(column in columnSet)) {\n columns.push(columnSet[column] = column);\n }\n }\n });\n\n return columns;\n}\n\nexport default function(delimiter) {\n var reFormat = new RegExp(\"[\\\"\" + delimiter + \"\\n\\r]\"),\n DELIMITER = delimiter.charCodeAt(0);\n\n function parse(text, f) {\n var convert, columns, rows = parseRows(text, function(row, i) {\n if (convert) return convert(row, i - 1);\n columns = row, convert = f ? customConverter(row, f) : objectConverter(row);\n });\n rows.columns = columns || [];\n return rows;\n }\n\n function parseRows(text, f) {\n var rows = [], // output rows\n N = text.length,\n I = 0, // current character index\n n = 0, // current line number\n t, // current token\n eof = N <= 0, // current token followed by EOF?\n eol = false; // current token followed by EOL?\n\n // Strip the trailing newline.\n if (text.charCodeAt(N - 1) === NEWLINE) --N;\n if (text.charCodeAt(N - 1) === RETURN) --N;\n\n function token() {\n if (eof) return EOF;\n if (eol) return eol = false, EOL;\n\n // Unescape quotes.\n var i, j = I, c;\n if (text.charCodeAt(j) === QUOTE) {\n while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE);\n if ((i = I) >= N) eof = true;\n else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true;\n else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }\n return text.slice(j + 1, i - 1).replace(/\"\"/g, \"\\\"\");\n }\n\n // Find next delimiter or newline.\n while (I < N) {\n if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true;\n else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }\n else if (c !== DELIMITER) continue;\n return text.slice(j, i);\n }\n\n // Return last token before EOF.\n return eof = true, text.slice(j, N);\n }\n\n while ((t = token()) !== EOF) {\n var row = [];\n while (t !== EOL && t !== EOF) row.push(t), t = token();\n if (f && (row = f(row, n++)) == null) continue;\n rows.push(row);\n }\n\n return rows;\n }\n\n function format(rows, columns) {\n if (columns == null) columns = inferColumns(rows);\n return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {\n return columns.map(function(column) {\n return formatValue(row[column]);\n }).join(delimiter);\n })).join(\"\\n\");\n }\n\n function formatRows(rows) {\n return rows.map(formatRow).join(\"\\n\");\n }\n\n function formatRow(row) {\n return row.map(formatValue).join(delimiter);\n }\n\n function formatValue(text) {\n return text == null ? \"\"\n : reFormat.test(text += \"\") ? \"\\\"\" + text.replace(/\"/g, \"\\\"\\\"\") + \"\\\"\"\n : text;\n }\n\n return {\n parse: parse,\n parseRows: parseRows,\n format: format,\n formatRows: formatRows\n };\n}\n","import dsv from \"./dsv\";\n\nvar csv = dsv(\",\");\n\nexport var csvParse = csv.parse;\nexport var csvParseRows = csv.parseRows;\nexport var csvFormat = csv.format;\nexport var csvFormatRows = csv.formatRows;\n","import dsv from \"./dsv\";\n\nvar tsv = dsv(\"\\t\");\n\nexport var tsvParse = tsv.parse;\nexport var tsvParseRows = tsv.parseRows;\nexport var tsvFormat = tsv.format;\nexport var tsvFormatRows = tsv.formatRows;\n","import { dsvFormat as d3Dsv } from 'd3-dsv';\nimport DSVArr from './dsv-arr';\n\n/**\n * Parses and converts data formatted in DSV string to a manageable internal format.\n *\n * @todo Support to be given for https://tools.ietf.org/html/rfc4180.\n * @todo Sample implementation https://github.com/knrz/CSV.js/.\n *\n * @param {string} str - The input DSV string.\n * @param {Object} options - Option to control the behaviour of the parsing.\n * @param {boolean} [options.firstRowHeader=true] - Whether the first row of the dsv string data is header or not.\n * @param {string} [options.fieldSeparator=\",\"] - The separator of two consecutive field.\n * @return {Array} Returns an array of headers and column major data.\n * @example\n *\n * // Sample input data:\n * const data = `\n * a,b,c\n * 1,2,3\n * 4,5,6\n * 7,8,9\n * `\n */\nfunction DSVStr (str, options) {\n const defaultOption = {\n firstRowHeader: true,\n fieldSeparator: ','\n };\n options = Object.assign({}, defaultOption, options);\n\n const dsv = d3Dsv(options.fieldSeparator);\n return DSVArr(dsv.parseRows(str), options);\n}\n\nexport default DSVStr;\n","import { columnMajor } from '../utils';\n\n/**\n * Parses and converts data formatted in JSON to a manageable internal format.\n *\n * @param {Array.} arr - The input data formatted in JSON.\n * @return {Array.} Returns an array of headers and column major data.\n * @example\n *\n * // Sample input data:\n * const data = [\n * {\n * \"a\": 1,\n * \"b\": 2,\n * \"c\": 3\n * },\n * {\n * \"a\": 4,\n * \"b\": 5,\n * \"c\": 6\n * },\n * {\n * \"a\": 7,\n * \"b\": 8,\n * \"c\": 9\n * }\n * ];\n */\nfunction FlatJSON (arr) {\n const header = {};\n let i = 0;\n let insertionIndex;\n const columns = [];\n const push = columnMajor(columns);\n\n arr.forEach((item) => {\n const fields = [];\n for (let key in item) {\n if (key in header) {\n insertionIndex = header[key];\n } else {\n header[key] = i++;\n insertionIndex = i - 1;\n }\n fields[insertionIndex] = item[key];\n }\n push(...fields);\n });\n\n return [Object.keys(header), columns];\n}\n\nexport default FlatJSON;\n","import FlatJSON from './flat-json';\nimport DSVArr from './dsv-arr';\nimport DSVStr from './dsv-str';\nimport { isArray, isObject, isString } from '../utils';\n\n/**\n * Parses the input data and detect the format automatically.\n *\n * @param {string|Array} data - The input data.\n * @param {Object} options - An optional config specific to data format.\n * @return {Array.} Returns an array of headers and column major data.\n */\nfunction Auto (data, options) {\n let converter;\n\n if (isString(data)) {\n converter = DSVStr;\n } else if (isArray(data) && isArray(data[0])) {\n converter = DSVArr;\n } else if (isArray(data) && (data.length === 0 || isObject(data[0]))) {\n converter = FlatJSON;\n } else {\n throw new Error('Couldn\\'t detect the data format');\n }\n\n return converter(data, options);\n}\n\nexport default Auto;\n","import { FieldType, FilteringMode } from './enums';\nimport Field from './fields/field';\nimport fieldStore from './field-store';\nimport Value from './value';\nimport {\n rowDiffsetIterator,\n groupByIterator,\n projectIterator,\n selectIterator,\n calculatedVariableIterator\n} from './operator';\nimport { DM_DERIVATIVES, LOGICAL_OPERATORS } from './constants';\nimport createFields from './field-creator';\nimport defaultConfig from './default-config';\nimport * as converter from './converter';\n\n/**\n * Prepares the selection data.\n */\nfunction prepareSelectionData (fields, i) {\n const resp = {};\n for (let field of fields) {\n resp[field.name] = new Value(field.data[i], field);\n }\n return resp;\n}\n\nexport function prepareJoinData (fields) {\n const resp = {};\n Object.keys(fields).forEach((key) => { resp[key] = new Value(fields[key], key); });\n return resp;\n}\n\nexport const updateFields = ([rowDiffset, colIdentifier], partialFieldspace, fieldStoreName) => {\n let collID = colIdentifier.length ? colIdentifier.split(',') : [];\n let partialFieldMap = partialFieldspace.fieldsObj();\n let newFields = collID.map(coll => new Field(partialFieldMap[coll], rowDiffset));\n return fieldStore.createNamespace(newFields, fieldStoreName);\n};\n\nexport const persistDerivation = (model, operation, config = {}, criteriaFn) => {\n let derivative;\n if (operation !== DM_DERIVATIVES.COMPOSE) {\n derivative = {\n op: operation,\n meta: config,\n criteria: criteriaFn\n };\n model._derivation.push(derivative);\n }\n else {\n derivative = [...criteriaFn];\n model._derivation.length = 0;\n model._derivation.push(...derivative);\n }\n};\n\nexport const selectHelper = (rowDiffset, fields, selectFn, config) => {\n const newRowDiffSet = [];\n let lastInsertedValue = -1;\n let { mode } = config;\n let li;\n let checker = index => selectFn(prepareSelectionData(fields, index), index);\n if (mode === FilteringMode.INVERSE) {\n checker = index => !selectFn(prepareSelectionData(fields, index));\n }\n rowDiffsetIterator(rowDiffset, (i) => {\n if (checker(i)) {\n if (lastInsertedValue !== -1 && i === (lastInsertedValue + 1)) {\n li = newRowDiffSet.length - 1;\n newRowDiffSet[li] = `${newRowDiffSet[li].split('-')[0]}-${i}`;\n } else {\n newRowDiffSet.push(`${i}`);\n }\n lastInsertedValue = i;\n }\n });\n return newRowDiffSet.join(',');\n};\n\nexport const filterPropagationModel = (model, propModels, config = {}) => {\n const operation = config.operation || LOGICAL_OPERATORS.AND;\n const filterByMeasure = config.filterByMeasure || false;\n let fns = [];\n if (propModels === null) {\n fns = [() => false];\n } else {\n fns = propModels.map(propModel => ((dataModel) => {\n const dataObj = dataModel.getData();\n const schema = dataObj.schema;\n const fieldsConfig = dataModel.getFieldsConfig();\n const fieldsSpace = dataModel.getFieldspace().fieldsObj();\n const data = dataObj.data;\n const domain = Object.values(fieldsConfig).reduce((acc, v) => {\n acc[v.def.name] = fieldsSpace[v.def.name].domain();\n return acc;\n }, {});\n\n return (fields) => {\n const include = !data.length ? false : data.some(row => schema.every((propField) => {\n if (!(propField.name in fields)) {\n return true;\n }\n const value = fields[propField.name].valueOf();\n if (filterByMeasure && propField.type === FieldType.MEASURE) {\n return value >= domain[propField.name][0] && value <= domain[propField.name][1];\n }\n\n if (propField.type !== FieldType.DIMENSION) {\n return true;\n }\n const idx = fieldsConfig[propField.name].index;\n return row[idx] === fields[propField.name].valueOf();\n }));\n return include;\n };\n })(propModel));\n }\n\n let filteredModel;\n if (operation === LOGICAL_OPERATORS.AND) {\n const clonedModel = model.clone(false, false);\n filteredModel = clonedModel.select(fields => fns.every(fn => fn(fields)), {\n saveChild: false,\n mode: FilteringMode.ALL\n });\n } else {\n filteredModel = model.clone(false, false).select(fields => fns.some(fn => fn(fields)), {\n mode: FilteringMode.ALL,\n saveChild: false\n });\n }\n\n return filteredModel;\n};\n\nexport const cloneWithSelect = (sourceDm, selectFn, selectConfig, cloneConfig) => {\n const cloned = sourceDm.clone(cloneConfig.saveChild);\n const rowDiffset = selectHelper(\n cloned._rowDiffset,\n cloned.getPartialFieldspace().fields,\n selectFn,\n selectConfig\n );\n cloned._rowDiffset = rowDiffset;\n cloned.__calculateFieldspace().calculateFieldsConfig();\n // Store reference to child model and selector function\n if (cloneConfig.saveChild) {\n persistDerivation(cloned, DM_DERIVATIVES.SELECT, { config: selectConfig }, selectFn);\n }\n\n return cloned;\n};\n\nexport const cloneWithProject = (sourceDm, projField, config, allFields) => {\n const cloned = sourceDm.clone(config.saveChild);\n let projectionSet = projField;\n if (config.mode === FilteringMode.INVERSE) {\n projectionSet = allFields.filter(fieldName => projField.indexOf(fieldName) === -1);\n }\n // cloned._colIdentifier = sourceDm._colIdentifier.split(',')\n // .filter(coll => projectionSet.indexOf(coll) !== -1).join();\n cloned._colIdentifier = projectionSet.join(',');\n cloned.__calculateFieldspace().calculateFieldsConfig();\n // Store reference to child model and projection fields\n if (config.saveChild) {\n persistDerivation(\n cloned,\n DM_DERIVATIVES.PROJECT,\n { projField, config, actualProjField: projectionSet },\n null\n );\n }\n\n return cloned;\n};\n\nexport const updateData = (relation, data, schema, options) => {\n options = Object.assign(Object.assign({}, defaultConfig), options);\n const converterFn = converter[options.dataFormat];\n\n if (!(converterFn && typeof converterFn === 'function')) {\n throw new Error(`No converter function found for ${options.dataFormat} format`);\n }\n\n const [header, formattedData] = converterFn(data, options);\n const fieldArr = createFields(formattedData, schema, header);\n\n // This will create a new fieldStore with the fields\n const nameSpace = fieldStore.createNamespace(fieldArr, options.name);\n relation._partialFieldspace = nameSpace;\n // If data is provided create the default colIdentifier and rowDiffset\n relation._rowDiffset = formattedData.length && formattedData[0].length ? `0-${formattedData[0].length - 1}` : '';\n relation._colIdentifier = (schema.map(_ => _.name)).join();\n return relation;\n};\n\nexport const fieldInSchema = (schema, field) => {\n let i = 0;\n\n for (; i < schema.length; ++i) {\n if (field === schema[i].name) {\n return {\n type: schema[i].subtype || schema[i].type,\n index: i\n };\n }\n }\n return null;\n};\n\nexport const propagateIdentifiers = (dataModel, propModel, config = {}, nonTraversingModel, grouped) => {\n // function to propagate to target the DataModel instance.\n const forwardPropagation = (targetDM, propagationData, hasGrouped) => {\n propagateIdentifiers(targetDM, propagationData, config, nonTraversingModel, hasGrouped);\n };\n\n if (dataModel === nonTraversingModel) {\n return;\n }\n\n dataModel.handlePropagation({\n payload: config.payload,\n data: propModel,\n sourceIdentifiers: config.sourceIdentifiers,\n sourceId: config.propagationSourceId,\n groupedPropModel: !!grouped\n });\n\n // propagate to children created by SELECT operation\n selectIterator(dataModel, (targetDM, criteria) => {\n if (targetDM !== nonTraversingModel) {\n const selectionModel = propModel[0].select(criteria, {\n saveChild: false\n });\n const rejectionModel = propModel[1].select(criteria, {\n saveChild: false\n });\n\n forwardPropagation(targetDM, [selectionModel, rejectionModel], grouped);\n }\n });\n // propagate to children created by PROJECT operation\n projectIterator(dataModel, (targetDM, projField) => {\n if (targetDM !== nonTraversingModel) {\n const projModel = propModel[0].project(projField, {\n saveChild: false\n });\n const rejectionProjModel = propModel[1].project(projField, {\n saveChild: false\n });\n\n forwardPropagation(targetDM, [projModel, rejectionProjModel], grouped);\n }\n });\n\n // propagate to children created by groupBy operation\n groupByIterator(dataModel, (targetDM, conf) => {\n if (targetDM !== nonTraversingModel) {\n const {\n reducer,\n groupByString\n } = conf;\n // group the filtered model based on groupBy string of target\n const selectionGroupedModel = propModel[0].groupBy(groupByString.split(','), reducer, {\n saveChild: false\n });\n const rejectionGroupedModel = propModel[1].groupBy(groupByString.split(','), reducer, {\n saveChild: false\n });\n forwardPropagation(targetDM, [selectionGroupedModel, rejectionGroupedModel], true);\n }\n });\n\n calculatedVariableIterator(dataModel, (targetDM, ...params) => {\n if (targetDM !== nonTraversingModel) {\n const entryModel = propModel[0].clone(false, false).calculateVariable(...params, {\n saveChild: false,\n replaceVar: true\n });\n const exitModel = propModel[1].clone(false, false).calculateVariable(...params, {\n saveChild: false,\n replaceVar: true\n });\n forwardPropagation(targetDM, [entryModel, exitModel], grouped);\n }\n });\n};\n\nexport const getRootGroupByModel = (model) => {\n if (model._parent && model._derivation.find(d => d.op !== 'group')) {\n return getRootGroupByModel(model._parent);\n }\n return model;\n};\n\nexport const getRootDataModel = (model) => {\n if (model._parent) {\n return getRootDataModel(model._parent);\n }\n return model;\n};\n\nexport const propagateToAllDataModels = (identifiers, rootModels, config) => {\n let criteria;\n let propModel;\n const propagationNameSpace = config.propagationNameSpace;\n const payload = config.payload;\n const propagationSourceId = config.propagationSourceId;\n\n if (identifiers === null) {\n criteria = null;\n } else {\n const filteredCriteria = Object.entries(propagationNameSpace.mutableActions)\n .filter(d => d[0] !== propagationSourceId)\n .map(d => Object.values(d[1]).map(action => action.criteria));\n criteria = [].concat(...[...filteredCriteria, identifiers]);\n }\n\n const rootGroupByModel = rootModels.groupByModel;\n const rootModel = rootModels.model;\n const propConfig = {\n payload,\n propagationSourceId,\n sourceIdentifiers: identifiers\n };\n\n if (rootGroupByModel) {\n propModel = filterPropagationModel(rootGroupByModel, criteria, {\n filterByMeasure: true\n });\n propagateIdentifiers(rootGroupByModel, propModel, propConfig);\n }\n\n propModel = filterPropagationModel(rootModel, criteria, {\n filterByMeasure: !rootGroupByModel\n });\n propagateIdentifiers(rootModel, propModel, propConfig, rootGroupByModel);\n};\n\nexport const propagateImmutableActions = (propagationNameSpace, rootModels, propagationSourceId) => {\n const rootGroupByModel = rootModels.groupByModel;\n const rootModel = rootModels.model;\n const immutableActions = propagationNameSpace.immutableActions;\n for (const sourceId in immutableActions) {\n const actions = immutableActions[sourceId];\n for (const action in actions) {\n const criteriaModel = actions[action].criteria;\n propagateToAllDataModels(criteriaModel, {\n groupByModel: rootGroupByModel,\n model: rootModel\n }, {\n propagationNameSpace,\n payload: actions[action].payload,\n propagationSourceId\n });\n }\n }\n};\n","import { FilteringMode } from './enums';\nimport { getUniqueId } from './utils';\nimport { persistDerivation, updateFields, cloneWithSelect, cloneWithProject, updateData } from './helper';\nimport { crossProduct, difference, naturalJoinFilter, union } from './operator';\nimport { DM_DERIVATIVES } from './constants';\n\n/**\n * Relation provides the definitions of basic operators of relational algebra like *selection*, *projection*, *union*,\n * *difference* etc.\n *\n * It is extended by {@link DataModel} to inherit the functionalities of relational algebra concept.\n *\n * @class\n * @public\n * @module Relation\n * @namespace DataModel\n */\nclass Relation {\n\n /**\n * Creates a new Relation instance by providing underlying data and schema.\n *\n * @private\n *\n * @param {Object | string | Relation} data - The input tabular data in dsv or json format or\n * an existing Relation instance object.\n * @param {Array} schema - An array of data schema.\n * @param {Object} [options] - The optional options.\n */\n constructor (...params) {\n let source;\n\n this._parent = null;\n this._derivation = [];\n this._children = [];\n\n if (params.length === 1 && ((source = params[0]) instanceof Relation)) {\n // parent datamodel was passed as part of source\n this._colIdentifier = source._colIdentifier;\n this._rowDiffset = source._rowDiffset;\n this._parent = source;\n this._partialFieldspace = this._parent._partialFieldspace;\n this._fieldStoreName = getUniqueId();\n this.__calculateFieldspace().calculateFieldsConfig();\n } else {\n updateData(this, ...params);\n this._fieldStoreName = this._partialFieldspace.name;\n this.__calculateFieldspace().calculateFieldsConfig();\n this._propagationNameSpace = {\n mutableActions: {},\n immutableActions: {}\n };\n }\n }\n\n /**\n * Retrieves the {@link Schema | schema} details for every {@link Field | field} as an array.\n *\n * @public\n *\n * @return {Array.} Array of fields schema.\n * ```\n * [\n * { name: 'Name', type: 'dimension' },\n * { name: 'Miles_per_Gallon', type: 'measure', numberFormat: (val) => `${val} miles / gallon` },\n * { name: 'Cylinder', type: 'dimension' },\n * { name: 'Displacement', type: 'measure', defAggFn: 'max' },\n * { name: 'HorsePower', type: 'measure', defAggFn: 'max' },\n * { name: 'Weight_in_lbs', type: 'measure', defAggFn: 'avg', },\n * { name: 'Acceleration', type: 'measure', defAggFn: 'avg' },\n * { name: 'Year', type: 'dimension', subtype: 'datetime', format: '%Y' },\n * { name: 'Origin' }\n * ]\n * ```\n */\n getSchema () {\n return this.getFieldspace().fields.map(d => d.schema);\n }\n\n /**\n * Returns the name of the {@link DataModel} instance. If no name was specified during {@link DataModel}\n * initialization, then it returns a auto-generated name.\n *\n * @public\n *\n * @return {string} Name of the DataModel instance.\n */\n getName() {\n return this._fieldStoreName;\n }\n\n getFieldspace () {\n return this._fieldspace;\n }\n\n __calculateFieldspace () {\n this._fieldspace = updateFields([this._rowDiffset, this._colIdentifier],\n this.getPartialFieldspace(), this._fieldStoreName);\n return this;\n }\n\n getPartialFieldspace () {\n return this._partialFieldspace;\n }\n\n /**\n * Performs {@link link_of_cross_product | cross-product} between two {@link DataModel} instances and returns a\n * new {@link DataModel} instance containing the results. This operation is also called theta join.\n *\n * Cross product takes two set and create one set where each value of one set is paired with each value of another\n * set.\n *\n * This method takes an optional predicate which filters the generated result rows. If the predicate returns true\n * the combined row is included in the resulatant table.\n *\n * @example\n * let originDM = dm.project(['Origin','Origin_Formal_Name']);\n * let carsDM = dm.project(['Name','Miles_per_Gallon','Origin'])\n *\n * console.log(carsDM.join(originDM)));\n *\n * console.log(carsDM.join(originDM,\n * obj => obj.[originDM.getName()].Origin === obj.[carsDM.getName()].Origin));\n *\n * @text\n * This is chained version of `join` operator. `join` can also be used as\n * {@link link_to_join_op | functional operator}.\n *\n * @public\n *\n * @param {DataModel} joinWith - The DataModel to be joined with the current instance DataModel.\n * @param {SelectionPredicate} filterFn - The predicate function that will filter the result of the crossProduct.\n *\n * @return {DataModel} New DataModel instance created after joining.\n */\n join (joinWith, filterFn) {\n return crossProduct(this, joinWith, filterFn);\n }\n\n /**\n * {@link natural_join | Natural join} is a special kind of cross-product join where filtering of rows are performed\n * internally by resolving common fields are from both table and the rows with common value are included.\n *\n * @example\n * let originDM = dm.project(['Origin','Origin_Formal_Name']);\n * let carsDM = dm.project(['Name','Miles_per_Gallon','Origin'])\n *\n * console.log(carsDM.naturalJoin(originDM));\n *\n * @text\n * This is chained version of `naturalJoin` operator. `naturalJoin` can also be used as\n * {@link link_to_join_op | functional operator}.\n *\n * @public\n *\n * @param {DataModel} joinWith - The DataModel with which the current instance of DataModel on which the method is\n * called will be joined.\n * @return {DataModel} New DataModel instance created after joining.\n */\n naturalJoin (joinWith) {\n return crossProduct(this, joinWith, naturalJoinFilter(this, joinWith), true);\n }\n\n /**\n * {@link link_to_union | Union} operation can be termed as vertical stacking of all rows from both the DataModel\n * instances, provided that both of the {@link DataModel} instances should have same column names.\n *\n * @example\n * console.log(EuropeanMakerDM.union(USAMakerDM));\n *\n * @text\n * This is chained version of `naturalJoin` operator. `naturalJoin` can also be used as\n * {@link link_to_join_op | functional operator}.\n *\n * @public\n *\n * @param {DataModel} unionWith - DataModel instance for which union has to be applied with the instance on which\n * the method is called\n *\n * @return {DataModel} New DataModel instance with the result of the operation\n */\n union (unionWith) {\n return union(this, unionWith);\n }\n\n /**\n * {@link link_to_difference | Difference } operation only include rows which are present in the datamodel on which\n * it was called but not on the one passed as argument.\n *\n * @example\n * console.log(highPowerDM.difference(highExpensiveDM));\n *\n * @text\n * This is chained version of `naturalJoin` operator. `naturalJoin` can also be used as\n * {@link link_to_join_op | functional operator}.\n *\n * @public\n *\n * @param {DataModel} differenceWith - DataModel instance for which difference has to be applied with the instance\n * on which the method is called\n * @return {DataModel} New DataModel instance with the result of the operation\n */\n difference (differenceWith) {\n return difference(this, differenceWith);\n }\n\n /**\n * {@link link_to_selection | Selection} is a row filtering operation. It expects an predicate and an optional mode\n * which control which all rows should be included in the resultant DataModel instance.\n *\n * {@link SelectionPredicate} is a function which returns a boolean value. For selection opearation the selection\n * function is called for each row of DataModel instance with the current row passed as argument.\n *\n * After executing {@link SelectionPredicate} the rows are labeled as either an entry of selection set or an entry\n * of rejection set.\n *\n * {@link FilteringMode} operates on the selection and rejection set to determine which one would reflect in the\n * resulatant datamodel.\n *\n * @warning\n * Selection and rejection set is only a logical idea for concept explanation purpose.\n *\n * @example\n * // with selection mode NORMAL:\n * const normDt = dt.select(fields => fields.Origin.value === \"USA\")\n * console.log(normDt));\n *\n * // with selection mode INVERSE:\n * const inverDt = dt.select(fields => fields.Origin.value === \"USA\", { mode: DataModel.FilteringMode.INVERSE })\n * console.log(inverDt);\n *\n * // with selection mode ALL:\n * const dtArr = dt.select(fields => fields.Origin.value === \"USA\", { mode: DataModel.FilteringMode.ALL })\n * // print the selected parts\n * console.log(dtArr[0]);\n * // print the inverted parts\n * console.log(dtArr[1]);\n *\n * @text\n * This is chained version of `select` operator. `select` can also be used as\n * {@link link_to_join_op | functional operator}.\n *\n * @public\n *\n * @param {SelectionPredicate} selectFn - Predicate funciton which is called for each row with the current row\n * ```\n * function (row, i) { ... }\n * ```\n * @param {Object} [config] - The configuration object to control the inclusion exclusion of a row in resultant\n * DataModel instance\n * @param {FilteringMode} [config.mode=FilteringMode.NORMAL] - The mode of the selection\n *\n * @return {DataModel} Returns the new DataModel instance(s) after operation.\n */\n select (selectFn, config) {\n const defConfig = {\n mode: FilteringMode.NORMAL,\n saveChild: true\n };\n config = Object.assign({}, defConfig, config);\n\n const cloneConfig = { saveChild: config.saveChild };\n let oDm;\n\n if (config.mode === FilteringMode.ALL) {\n const selectDm = cloneWithSelect(\n this,\n selectFn,\n { mode: FilteringMode.NORMAL },\n cloneConfig\n );\n const rejectDm = cloneWithSelect(\n this,\n selectFn,\n { mode: FilteringMode.INVERSE },\n cloneConfig\n );\n oDm = [selectDm, rejectDm];\n } else {\n oDm = cloneWithSelect(\n this,\n selectFn,\n config,\n cloneConfig\n );\n }\n\n return oDm;\n }\n\n /**\n * Retrieves a boolean value if the current {@link DataModel} instance has data.\n *\n * @example\n * const schema = [\n * { name: 'CarName', type: 'dimension' },\n * { name: 'HorsePower', type: 'measure' },\n * { name: \"Origin\", type: 'dimension' }\n * ];\n * const data = [];\n *\n * const dt = new DataModel(schema, data);\n * console.log(dt.isEmpty());\n *\n * @public\n *\n * @return {Boolean} True if the datamodel has no data, otherwise false.\n */\n isEmpty () {\n return !this._rowDiffset.length || !this._colIdentifier.length;\n }\n\n /**\n * Creates a clone from the current DataModel instance with child parent relationship.\n *\n * @private\n * @param {boolean} [saveChild=true] - Whether the cloned instance would be recorded in the parent instance.\n * @return {DataModel} - Returns the newly cloned DataModel instance.\n */\n clone (saveChild = true, linkParent = true) {\n let retDataModel;\n if (linkParent === false) {\n const dataObj = this.getData({\n getAllFields: true\n });\n const data = dataObj.data;\n const schema = dataObj.schema;\n const jsonData = data.map((row) => {\n const rowObj = {};\n schema.forEach((field, i) => {\n rowObj[field.name] = row[i];\n });\n return rowObj;\n });\n retDataModel = new this.constructor(jsonData, schema);\n }\n else {\n retDataModel = new this.constructor(this);\n }\n\n if (saveChild) {\n this._children.push(retDataModel);\n }\n return retDataModel;\n }\n\n /**\n * {@link Projection} is filter column (field) operation. It expects list of fields' name and either include those\n * or exclude those based on {@link FilteringMode} on the resultant variable.\n *\n * Projection expects array of fields name based on which it creates the selection and rejection set. All the field\n * whose name is present in array goes in selection set and rest of the fields goes in rejection set.\n *\n * {@link FilteringMode} operates on the selection and rejection set to determine which one would reflect in the\n * resulatant datamodel.\n *\n * @warning\n * Selection and rejection set is only a logical idea for concept explanation purpose.\n *\n * @example\n * const dm = new DataModel(schema, data);\n *\n * // with projection mode NORMAL:\n * const normDt = dt.project([\"Name\", \"HorsePower\"]);\n * console.log(normDt.getData());\n *\n * // with projection mode INVERSE:\n * const inverDt = dt.project([\"Name\", \"HorsePower\"], { mode: DataModel.FilteringMode.INVERSE })\n * console.log(inverDt.getData());\n *\n * // with selection mode ALL:\n * const dtArr = dt.project([\"Name\", \"HorsePower\"], { mode: DataModel.FilteringMode.ALL })\n * // print the normal parts\n * console.log(dtArr[0].getData());\n * // print the inverted parts\n * console.log(dtArr[1].getData());\n *\n * @text\n * This is chained version of `select` operator. `select` can also be used as\n * {@link link_to_join_op | functional operator}.\n *\n * @public\n *\n * @param {Array.} projField - An array of column names in string or regular expression.\n * @param {Object} [config] - An optional config to control the creation of new DataModel\n * @param {FilteringMode} [config.mode=FilteringMode.NORMAL] - Mode of the projection\n *\n * @return {DataModel} Returns the new DataModel instance after operation.\n */\n project (projField, config) {\n const defConfig = {\n mode: FilteringMode.NORMAL,\n saveChild: true\n };\n config = Object.assign({}, defConfig, config);\n const fieldConfig = this.getFieldsConfig();\n const allFields = Object.keys(fieldConfig);\n const { mode } = config;\n\n let normalizedProjField = projField.reduce((acc, field) => {\n if (field.constructor.name === 'RegExp') {\n acc.push(...allFields.filter(fieldName => fieldName.search(field) !== -1));\n } else if (field in fieldConfig) {\n acc.push(field);\n }\n return acc;\n }, []);\n\n normalizedProjField = Array.from(new Set(normalizedProjField)).map(field => field.trim());\n let dataModel;\n\n if (mode === FilteringMode.ALL) {\n let projectionClone = cloneWithProject(this, normalizedProjField, {\n mode: FilteringMode.NORMAL,\n saveChild: config.saveChild\n }, allFields);\n let rejectionClone = cloneWithProject(this, normalizedProjField, {\n mode: FilteringMode.INVERSE,\n saveChild: config.saveChild\n }, allFields);\n dataModel = [projectionClone, rejectionClone];\n } else {\n let projectionClone = cloneWithProject(this, normalizedProjField, config, allFields);\n dataModel = projectionClone;\n }\n\n return dataModel;\n }\n\n getFieldsConfig () {\n return this._fieldConfig;\n }\n\n calculateFieldsConfig () {\n this._fieldConfig = this._fieldspace.fields.reduce((acc, fieldDef, i) => {\n acc[fieldDef.name] = {\n index: i,\n def: { name: fieldDef._ref.name, type: fieldDef._ref.fieldType, subtype: fieldDef._ref.subType() }\n };\n return acc;\n }, {});\n return this;\n }\n\n\n /**\n * Frees up the resources associated with the current DataModel instance and breaks all the links instance has in\n * the DAG.\n *\n * @public\n */\n dispose () {\n this._parent.removeChild(this);\n this._parent = null;\n }\n\n /**\n * Removes the specified child {@link DataModel} from the child list of the current {@link DataModel} instance.\n *\n * @example\n * const schema = [\n * { name: 'Name', type: 'dimension' },\n * { name: 'HorsePower', type: 'measure' },\n * { name: \"Origin\", type: 'dimension' }\n * ];\n *\n * const data = [\n * { Name: \"chevrolet chevelle malibu\", Horsepower: 130, Origin: \"USA\" },\n * { Name: \"citroen ds-21 pallas\", Horsepower: 115, Origin: \"Europe\" },\n * { Name: \"datsun pl510\", Horsepower: 88, Origin: \"Japan\" },\n * { Name: \"amc rebel sst\", Horsepower: 150, Origin: \"USA\"},\n * ]\n *\n * const dt = new DataModel(schema, data);\n *\n * const dt2 = dt.select(fields => fields.Origin.value === \"USA\")\n * dt.removeChild(dt2);\n *\n * @private\n *\n * @param {DataModel} child - Delegates the parent to remove this child.\n */\n removeChild (child) {\n let idx = this._children.findIndex(sibling => sibling === child);\n idx !== -1 ? this._children.splice(idx, 1) : true;\n }\n\n /**\n * Adds the specified {@link DataModel} as a parent for the current {@link DataModel} instance.\n *\n * The optional criteriaQueue is an array containing the history of transaction performed on parent\n * {@link DataModel} to get the current one.\n *\n * @param {DataModel} parent - The datamodel instance which will act as parent.\n * @param {Array} criteriaQueue - Queue contains in-between operation meta-data.\n */\n addParent (parent, criteriaQueue = []) {\n persistDerivation(this, DM_DERIVATIVES.COMPOSE, null, criteriaQueue);\n this._parent = parent;\n parent._children.push(this);\n }\n}\n\nexport default Relation;\n","/* eslint-disable default-case */\n\nimport { FieldType } from './enums';\nimport {\n persistDerivation,\n getRootGroupByModel,\n propagateToAllDataModels,\n getRootDataModel,\n propagateImmutableActions\n} from './helper';\nimport { DM_DERIVATIVES, PROPAGATION } from './constants';\nimport {\n dataBuilder,\n rowDiffsetIterator,\n groupBy\n} from './operator';\nimport { createBinnedFieldData } from './operator/bucket-creator';\nimport Relation from './relation';\nimport reducerStore from './utils/reducer-store';\nimport createFields from './field-creator';\n\n/**\n * DataModel is an in-browser representation of tabular data. It supports\n * {@link https://en.wikipedia.org/wiki/Relational_algebra | relational algebra} operators as well as generic data\n * processing opearators.\n * DataModel extends {@link Relation} class which defines all the relational algebra opreators. DataModel gives\n * definition of generic data processing operators which are not relational algebra complient.\n *\n * @public\n * @class\n * @extends Relation\n * @memberof Datamodel\n */\nclass DataModel extends Relation {\n /**\n * Creates a new DataModel instance by providing data and schema. Data could be in the form of\n * - Flat JSON\n * - DSV String\n * - 2D Array\n *\n * By default DataModel finds suitable adapter to serialize the data. DataModel also expects a\n * {@link Schema | schema} for identifying the variables present in data.\n *\n * @constructor\n * @example\n * const data = loadData('cars.csv');\n * const schema = [\n * { name: 'Name', type: 'dimension' },\n * { name: 'Miles_per_Gallon', type: 'measure', unit : 'cm', scale: '1000', numberformat: val => `${val}G`},\n * { name: 'Cylinders', type: 'dimension' },\n * { name: 'Displacement', type: 'measure' },\n * { name: 'Horsepower', type: 'measure' },\n * { name: 'Weight_in_lbs', type: 'measure' },\n * { name: 'Acceleration', type: 'measure' },\n * { name: 'Year', type: 'dimension', subtype: 'datetime', format: '%Y' },\n * { name: 'Origin', type: 'dimension' }\n * ];\n * const dm = new DataModel(data, schema, { name: 'Cars' });\n * table(dm);\n *\n * @public\n *\n * @param {Array. | string | Array.} data Input data in any of the mentioned formats\n * @param {Array.} schema Defination of the variables. Order of the variables in data and order of the\n * variables in schema has to be same.\n * @param {object} [options] Optional arguments to specify more settings regarding the creation part\n * @param {string} [options.name] Name of the datamodel instance. If no name is given an auto generated name is\n * assigned to the instance.\n * @param {string} [options.fieldSeparator=','] specify field separator type if the data is of type dsv string.\n */\n constructor (...args) {\n super(...args);\n\n this._onPropagation = [];\n this._sortingDetails = [];\n }\n\n /**\n * Reducers are simple functions which reduces an array of numbers to a representative number of the set.\n * Like an array of numbers `[10, 20, 5, 15]` can be reduced to `12.5` if average / mean reducer function is\n * applied. All the measure fields in datamodel (variables in data) needs a reducer to handle aggregation.\n *\n * @public\n *\n * @return {ReducerStore} Singleton instance of {@link ReducerStore}.\n */\n static get Reducers () {\n return reducerStore;\n }\n\n /**\n * Retrieve the data attached to an instance in JSON format.\n *\n * @example\n * // DataModel instance is already prepared and assigned to dm variable\n * const data = dm.getData({\n * order: 'column',\n * formatter: {\n * origin: (val) => val === 'European Union' ? 'EU' : val;\n * }\n * });\n * console.log(data);\n *\n * @public\n *\n * @param {Object} [options] Options to control how the raw data is to be returned.\n * @param {string} [options.order='row'] Defines if data is retieved in row order or column order. Possible values\n * are `'rows'` and `'columns'`\n * @param {Function} [options.formatter=null] Formats the output data. This expects an object, where the keys are\n * the name of the variable needs to be formatted. The formatter function is called for each row passing the\n * value of the cell for a particular row as arguments. The formatter is a function in the form of\n * `function (value, rowId, schema) => { ... }`\n * Know more about {@link Fomatter}.\n *\n * @return {Array} Returns a multidimensional array of the data with schema. The return format looks like\n * ```\n * {\n * data,\n * schema\n * }\n * ```\n */\n getData (options) {\n const defOptions = {\n order: 'row',\n formatter: null,\n withUid: false,\n getAllFields: false,\n sort: []\n };\n options = Object.assign({}, defOptions, options);\n const fields = this.getPartialFieldspace().fields;\n\n const dataGenerated = dataBuilder.call(\n this,\n this.getPartialFieldspace().fields,\n this._rowDiffset,\n options.getAllFields ? fields.map(d => d.name).join() : this._colIdentifier,\n options.sort,\n {\n columnWise: options.order === 'column',\n addUid: !!options.withUid\n }\n );\n\n if (!options.formatter) {\n return dataGenerated;\n }\n\n const { formatter } = options;\n const { data, schema, uids } = dataGenerated;\n const fieldNames = schema.map((e => e.name));\n const fmtFieldNames = Object.keys(formatter);\n const fmtFieldIdx = fmtFieldNames.reduce((acc, next) => {\n const idx = fieldNames.indexOf(next);\n if (idx !== -1) {\n acc.push([idx, formatter[next]]);\n }\n return acc;\n }, []);\n\n if (options.order === 'column') {\n fmtFieldIdx.forEach((elem) => {\n const fIdx = elem[0];\n const fmtFn = elem[1];\n\n data[fIdx].forEach((datum, datumIdx) => {\n data[fIdx][datumIdx] = fmtFn.call(\n undefined,\n datum,\n uids[datumIdx],\n schema[fIdx]\n );\n });\n });\n } else {\n data.forEach((datum, datumIdx) => {\n fmtFieldIdx.forEach((elem) => {\n const fIdx = elem[0];\n const fmtFn = elem[1];\n\n datum[fIdx] = fmtFn.call(\n undefined,\n datum[fIdx],\n uids[datumIdx],\n schema[fIdx]\n );\n });\n });\n }\n\n return dataGenerated;\n }\n\n /**\n * Groups the data using particular dimensions and by reducing measures. It expects a list of dimensions using which\n * it projects the datamodel and perform aggregations to reduce the duplicate tuples. Refer this\n * {@link link_to_one_example_with_group_by | document} to know the intuition behind groupBy.\n *\n * DataModel by default provides definition of few {@link reducer | Reducers}.\n * {@link ReducerStore | User defined reducers} can also be registered.\n *\n * This is the chained implementation of `groupBy`.\n * `groupBy` also supports {@link link_to_compose_groupBy | composability}\n *\n * @example\n * const groupedDM = dm.groupBy(['Year'], { horsepower: 'max' } );\n * console.log(groupedDm);\n *\n * @public\n *\n * @param {Array.} fieldsArr - Array containing the name of dimensions\n * @param {Object} [reducers={}] - A map whose key is the variable name and value is the name of the reducer. If its\n * not passed, or any variable is ommitted from the object, default aggregation function is used from the\n * schema of the variable.\n *\n * @return {DataModel} Returns a new DataModel instance after performing the groupby.\n */\n groupBy (fieldsArr, reducers = {}, config = { saveChild: true }) {\n const groupByString = `${fieldsArr.join()}`;\n let params = [this, fieldsArr, reducers];\n const newDataModel = groupBy(...params);\n\n if (config.saveChild) {\n this._children.push(newDataModel);\n persistDerivation(\n newDataModel,\n DM_DERIVATIVES.GROUPBY,\n { fieldsArr, groupByString, defaultReducer: reducerStore.defaultReducer() },\n reducers\n );\n }\n\n newDataModel._parent = this;\n return newDataModel;\n }\n\n /**\n * Performs sorting operation on the current {@link DataModel} instance according to the specified sorting details.\n * Like every other operator it doesn't mutate the current DataModel instance on which it was called, instead\n * returns a new DataModel instance containing the sorted data.\n *\n * DataModel support multi level sorting by listing the variables using which sorting needs to be performed and\n * the type of sorting `ASC` or `DESC`.\n *\n * In the following example, data is sorted by `Origin` field in `DESC` order in first level followed by another\n * level of sorting by `Acceleration` in `ASC` order.\n *\n * @example\n * // here dm is the pre-declared DataModel instance containing the data of 'cars.json' file\n * let sortedDm = dm.sort([\n * [\"Origin\", \"DESC\"]\n * [\"Acceleration\"] // Default value is ASC\n * ]);\n *\n * console.log(dm.getData());\n * console.log(sortedDm.getData());\n *\n * // Sort with a custom sorting function\n * sortedDm = dm.sort([\n * [\"Origin\", \"DESC\"]\n * [\"Acceleration\", (a, b) => a - b] // Custom sorting function\n * ]);\n *\n * console.log(dm.getData());\n * console.log(sortedDm.getData());\n *\n * @text\n * DataModel also provides another sorting mechanism out of the box where sort is applied to a variable using\n * another variable which determines the order.\n * Like the above DataModel contains three fields `Origin`, `Name` and `Acceleration`. Now, the data in this\n * model can be sorted by `Origin` field according to the average value of all `Acceleration` for a\n * particular `Origin` value.\n *\n * @example\n * // here dm is the pre-declared DataModel instance containing the data of 'cars.json' file\n * const sortedDm = dm.sort([\n * ['Origin', ['Acceleration', (a, b) => avg(...a.Acceleration) - avg(...b.Acceleration)]]\n * ]);\n *\n * console.log(dm.getData());\n * console.log(sortedDm.getData());\n *\n * @public\n *\n * @param {Array.} sortingDetails - Sorting details based on which the sorting will be performed.\n * @return {DataModel} Returns a new instance of DataModel with sorted data.\n */\n sort (sortingDetails) {\n const rawData = this.getData({\n order: 'row',\n sort: sortingDetails\n });\n const header = rawData.schema.map(field => field.name);\n const dataInCSVArr = [header].concat(rawData.data);\n\n const sortedDm = new this.constructor(dataInCSVArr, rawData.schema, { dataFormat: 'DSVArr' });\n sortedDm._sortingDetails = sortingDetails;\n return sortedDm;\n }\n\n addField (field) {\n const fieldName = field.fieldName();\n this._colIdentifier += `,${fieldName}`;\n const partialFieldspace = this._partialFieldspace;\n\n if (!partialFieldspace.fieldsObj()[field.fieldName()]) {\n partialFieldspace.fields.push(field);\n } else {\n const fieldIndex = partialFieldspace.fields.findIndex(fieldinst => fieldinst.name === fieldName);\n fieldIndex >= 0 && (partialFieldspace.fields[fieldIndex] = field);\n }\n\n this.__calculateFieldspace().calculateFieldsConfig();\n return this;\n }\n\n /**\n * Creates a new variable calculated from existing variable. This method expects the defination of the newly created\n * variable and a function which resolves the value of the new variable from existing variables.\n *\n * Can create a new measure based on existing variables\n * @example\n * // DataModel already prepared and assigned to dm vairable;\n * const newDm = dataModel.calculateVariable({\n * name: 'powerToWeight',\n * type: 'measure'\n * }, ['horsepower', 'weight_in_lbs', (hp, weight) => hp / weight ]);\n *\n *\n * Can create a new dimension based on existing variables\n * @example\n * // DataModel already prepared and assigned to dm vairable;\n * const child = dataModel.calculateVariable(\n * {\n * name: 'Efficiency',\n * type: 'dimension'\n * }, ['horsepower', (hp) => {\n * if (hp < 80) { return 'low'; },\n * else if (hp < 120) { return 'moderate'; }\n * else { return 'high' }\n * }]);\n *\n * @public\n *\n * @param {Schema} schema: Schema of newly defined variable\n * @param {VariableResolver} resolver: Resolver format to resolve the current variable\n *\n * @return {DataModel} Instance of DataModel with the new field\n */\n calculateVariable (schema, dependency, config = { saveChild: true, replaceVar: false }) {\n const fieldsConfig = this.getFieldsConfig();\n const depVars = dependency.slice(0, dependency.length - 1);\n const retrieveFn = dependency[dependency.length - 1];\n\n if (fieldsConfig[schema.name] && !config.replaceVar) {\n throw new Error(`${schema.name} field already exists in model.`);\n }\n const depFieldIndices = depVars.map((field) => {\n const fieldSpec = fieldsConfig[field];\n if (!fieldSpec) {\n // @todo dont throw error here, use warning in production mode\n throw new Error(`${field} is not a valid column name.`);\n }\n return fieldSpec.index;\n });\n\n let clone = this.clone();\n\n const fs = clone.getFieldspace().fields;\n const suppliedFields = depFieldIndices.map(idx => fs[idx]);\n\n const computedValues = [];\n rowDiffsetIterator(clone._rowDiffset, (i) => {\n const fieldsData = suppliedFields.map(field => field.data[i]);\n computedValues[i] = retrieveFn(...fieldsData, i, fs);\n });\n const [field] = createFields([computedValues], [schema], [schema.name]);\n clone.addField(field);\n\n if (config.saveChild) {\n persistDerivation(clone, DM_DERIVATIVES.CAL_VAR, { config: schema, fields: depVars }, retrieveFn);\n }\n\n return clone;\n }\n\n /**\n * Propagates changes across all the connected DataModel instances.\n *\n * @param {Array} identifiers - A list of identifiers that were interacted with.\n * @param {Object} payload - The interaction specific details.\n *\n * @return {DataModel} DataModel instance.\n */\n propagate (identifiers, payload, config = {}) {\n const isMutableAction = config.isMutableAction;\n const propagationSourceId = config.sourceId;\n const rootModel = getRootDataModel(this);\n const propagationNameSpace = rootModel._propagationNameSpace;\n const rootGroupByModel = getRootGroupByModel(this);\n const rootModels = {\n groupByModel: rootGroupByModel,\n model: rootModel\n };\n\n propagateToAllDataModels(identifiers, rootModels, {\n propagationNameSpace,\n payload,\n propagationSourceId\n });\n\n if (isMutableAction) {\n propagateImmutableActions(propagationNameSpace, rootModels, propagationSourceId);\n }\n return this;\n }\n\n addToPropNamespace (sourceId, config = {}) {\n let sourceNamespace;\n const actionName = config.actionName;\n const payload = config.payload;\n const isMutableAction = config.isMutableAction;\n const rootModel = getRootDataModel(this);\n const propagationNameSpace = rootModel._propagationNameSpace;\n const criteria = config.criteria;\n\n if (isMutableAction) {\n !propagationNameSpace.mutableActions[sourceId] && (propagationNameSpace.mutableActions[sourceId] = {});\n sourceNamespace = propagationNameSpace.mutableActions[sourceId];\n } else {\n !propagationNameSpace.immutableActions[sourceId] && (propagationNameSpace.immutableActions[sourceId] = {});\n sourceNamespace = propagationNameSpace.immutableActions[sourceId];\n }\n\n if (criteria === null) {\n delete sourceNamespace[actionName];\n } else {\n sourceNamespace[actionName] = {\n criteria,\n payload\n };\n }\n\n return this;\n }\n\n /**\n * Associates a callback with an event name.\n *\n * @param {string} eventName - The name of the event.\n * @param {Function} callback - The callback to invoke.\n * @return {DataModel} Returns this current DataModel instance itself.\n */\n on (eventName, callback) {\n switch (eventName) {\n case PROPAGATION:\n this._onPropagation.push(callback);\n break;\n }\n return this;\n }\n\n /**\n * Unsubscribes the callbacks for the provided event name.\n *\n * @param {string} eventName - The name of the event to unsubscribe.\n * @return {DataModel} Returns the current DataModel instance itself.\n */\n unsubscribe (eventName) {\n switch (eventName) {\n case PROPAGATION:\n this._onPropagation = [];\n break;\n\n }\n return this;\n }\n\n /**\n * This method is used to invoke the method associated with propagation.\n *\n * @param {Object} payload The interaction payload.\n * @param {DataModel} identifiers The propagated DataModel.\n * @memberof DataModel\n */\n handlePropagation (payload) {\n let propListeners = this._onPropagation;\n propListeners.forEach(fn => fn.call(this, payload));\n }\n\n /**\n * Perfoms binning on a measure field based on a binning configuration. This method does not aggregate the number of\n * rows present in DataModel instance after binning, it just adds a new field with the binned value. Refer binning\n * {@link example_of_binning | example} to have a intuition of what binning is and the use case.\n *\n * Binning can be configured by\n * - providing custom bin configuration with non uniform buckets\n * - providing bin count\n * - providing each bin size\n *\n * When custom buckets are provided as part of binning configuration\n * @example\n * // DataModel already prepared and assigned to dm vairable\n * const buckets = {\n * start: 30\n * stops: [80, 100, 110]\n * };\n * const config = { buckets, name: 'binnedHP' }\n * const binDM = dataModel.bin('horsepower', config);\\\n *\n * @text\n * When `binCount` is defined as part of binning configuration\n * @example\n * // DataModel already prepared and assigned to dm vairable\n * const config = { binCount: 5, name: 'binnedHP' }\n * const binDM = dataModel.bin('horsepower', config);\n *\n * @text\n * When `binSize` is defined as part of binning configuration\n * @example\n * // DataModel already prepared and assigned to dm vairable\n * const config = { binSize: 200, name: 'binnedHorsepower' }\n * const binDM = dataModel.bin('horsepower', config);\n *\n * @public\n *\n * @param {String} name Name of measure which will be used to create bin\n * @param {Object} config Config required for bin creation\n * @param {Array.} config.bucketObj.stops Defination of bucket ranges. Two subsequent number from arrays\n * are picked and a range is created. The first number from range is inclusive and the second number from range\n * is exclusive.\n * @param {Number} [config.bucketObj.startAt] Force the start of the bin from a particular number.\n * If not mentioned, the start of the bin or the lower domain of the data if stops is not mentioned, else its\n * the first value of the stop.\n * @param {Number} config.binSize Bucket size for each bin\n * @param {Number} config.binCount Number of bins which will be created\n * @param {String} config.name Name of the new binned field to be created\n *\n * @returns {DataModel} Instance of new DataModel with the newly created bin.\n */\n bin (measureName, config = { }) {\n const clone = this.clone();\n const binFieldName = config.name || `${measureName}_binned`;\n if (this.getFieldsConfig()[binFieldName] || !this.getFieldsConfig()[measureName]) {\n throw new Error(`Field ${measureName} already exists.`);\n }\n const field = this._partialFieldspace.fields.find(currfield => currfield.name === measureName);\n const dataSet = createBinnedFieldData(field, this._rowDiffset, config);\n const binField = createFields([dataSet.data], [\n {\n name: binFieldName,\n type: FieldType.MEASURE,\n subtype: 'discrete', // @todo : DimensionSubtype\n bins: {\n range: dataSet.range,\n mid: dataSet.mid\n }\n }], [binFieldName])[0];\n clone.addField(binField);\n persistDerivation(clone, DM_DERIVATIVES.BIN, { measureName, config, binFieldName }, null);\n return clone;\n }\n}\n\nexport default DataModel;\n","import { fnList } from '../operator/group-by-function';\n\nexport const { sum, avg, min, max, first, last, count, std: sd } = fnList;\n","import DataModel from './datamodel';\nimport {\n compose,\n bin,\n select,\n project,\n groupby as groupBy,\n calculateVariable,\n sort,\n crossProduct,\n difference,\n naturalJoin,\n leftOuterJoin,\n rightOuterJoin,\n fullOuterJoin,\n union\n} from './operator';\nimport * as Stats from './stats';\nimport * as enums from './enums';\nimport { DateTimeFormatter } from './utils';\nimport { DataFormat, FilteringMode } from './constants';\nimport pkg from '../package.json';\n\nDataModel.Operators = {\n compose,\n bin,\n select,\n project,\n groupBy,\n calculateVariable,\n sort,\n crossProduct,\n difference,\n naturalJoin,\n leftOuterJoin,\n rightOuterJoin,\n fullOuterJoin,\n union\n};\nDataModel.Stats = Stats;\nObject.assign(DataModel, enums);\nDataModel.DateTimeFormatter = DateTimeFormatter;\nDataModel.DataFormat = DataFormat;\nDataModel.FilteringMode = FilteringMode;\nDataModel.version = pkg.version;\n\nexport default DataModel;\n","\n/**\n * DataModel's opearators are exposed as composable functional operators as well as chainable operators. Chainable\n * operators are called on the instances of {@link Datamodel} and {@link Relation} class.\n *\n * Those same operators can be used as composable operators from `DataModel.Operators` namespace.\n *\n * All these operators have similar behaviour. All these operators when called with the argument returns a function\n * which expects a DataModel instance.\n *\n * @public\n * @module Operators\n * @namespace DataModel\n */\n\n/**\n * This is functional version of selection operator. {@link link_to_selection | Selection} is a row filtering operation.\n * It takes {@link SelectionPredicate | predicate} for filtering criteria and returns a function.\n * The returned function is called with the DataModel instance on which the action needs to be performed.\n *\n * {@link SelectionPredicate} is a function which returns a boolean value. For selection opearation the selection\n * function is called for each row of DataModel instance with the current row passed as argument.\n *\n * After executing {@link SelectionPredicate} the rows are labeled as either an entry of selection set or an entry\n * of rejection set.\n *\n * {@link FilteringMode} operates on the selection and rejection set to determine which one would reflect in the\n * resulatant datamodel.\n *\n * @warning\n * [Warn] Selection and rejection set is only a logical idea for concept explanation purpose.\n *\n * @error\n * [Error] `FilteringMode.ALL` is not a valid working mode for functional version of `select`. Its only avialable on the\n * chained version.\n *\n * @example\n * const select = DataModel.Operators.select;\n * usaCarsFn = select(fields => fields.Origin.value === 'USA');\n * usaCarsDm = usaCarsFn(dm);\n * console.log(usaCarsDm);\n *\n * @public\n * @namespace DataModel\n * @module Operators\n *\n * @param {SelectionPredicate} selectFn - Predicate funciton which is called for each row with the current row\n * ```\n * function (row, i) { ... }\n * ```\n * @param {Object} [config] - The configuration object to control the inclusion exclusion of a row in resultant\n * DataModel instance\n * @param {FilteringMode} [config.mode=FilteringMode.NORMAL] - The mode of the selection\n *\n * @return {PreparatorFunction} Function which expects an instance of DataModel on which the operator needs to be\n * applied.\n */\nexport const select = (...args) => dm => dm.select(...args);\n\n/**\n * This is functional version of projection operator. {@link link_to_projection | Projection} is a column filtering\n * operation.It expects list of fields name and either include those or exclude those based on {@link FilteringMode} on\n * the resultant variable.It returns a function which is called with the DataModel instance on which the action needs\n * to be performed.\n *\n * Projection expects array of fields name based on which it creates the selection and rejection set. All the field\n * whose name is present in array goes in selection set and rest of the fields goes in rejection set.\n *\n * {@link FilteringMode} operates on the selection and rejection set to determine which one would reflect in the\n * resulatant datamodel.\n *\n * @warning\n * Selection and rejection set is only a logical idea for concept explanation purpose.\n *\n * @error\n * `FilteringMode.ALL` is not a valid working mode for functional version of `select`. Its only avialable on the\n * chained version.\n *\n * @public\n * @namespace DataModel\n * @module Operators\n *\n * @param {Array.} projField - An array of column names in string or regular expression.\n * @param {Object} [config] - An optional config to control the creation of new DataModel\n * @param {FilteringMode} [config.mode=FilteringMode.NORMAL] - Mode of the projection\n *\n * @return {PreparatorFunction} Function which expects an instance of DataModel on which the operator needs to be\n * applied.\n */\nexport const project = (...args) => dm => dm.project(...args);\n\n/**\n * This is functional version of binnig operator. Binning happens on a measure field based on a binning configuration.\n * Binning in DataModel does not aggregate the number of rows present in DataModel instance after binning, it just adds\n * a new field with the binned value. Refer binning {@link example_of_binning | example} to have a intuition of what\n * binning is and the use case.\n *\n * Binning can be configured by\n * - providing custom bin configuration with non uniform buckets\n * - providing bin count\n * - providing each bin size\n *\n * When custom buckets are provided as part of binning configuration\n * @example\n * // DataModel already prepared and assigned to dm vairable\n * const buckets = {\n * start: 30\n * stops: [80, 100, 110]\n * };\n * const config = { buckets, name: 'binnedHP' }\n * const binFn = bin('horsepower', config);\n * const binnedDm = binFn(dm);\n *\n * @text\n * When `binCount` is defined as part of binning configuration\n * @example\n * // DataModel already prepared and assigned to dm vairable\n * const config = { binCount: 5, name: 'binnedHP' }\n * const binFn = bin('horsepower', config);\n * const binnedDm = binFn(Dm);\n *\n * @text\n * When `binSize` is defined as part of binning configuration\n * @example\n * // DataModel already prepared and assigned to dm vairable\n * const config = { binSize: 200, name: 'binnedHorsepower' }\n * const binnedDm = dataModel.bin('horsepower', config);\n * const binnedDm = binFn(Dm);\n *\n * @public\n * @namespace DataModel\n * @module Operators\n *\n * @param {String} name Name of measure which will be used to create bin\n * @param {Object} config Config required for bin creation\n * @param {Array.} config.bucketObj.stops Defination of bucket ranges. Two subsequent number from arrays\n * are picked and a range is created. The first number from range is inclusive and the second number from range\n * is exclusive.\n * @param {Number} [config.bucketObj.startAt] Force the start of the bin from a particular number.\n * If not mentioned, the start of the bin or the lower domain of the data if stops is not mentioned, else its\n * the first value of the stop.\n * @param {Number} config.binSize Bucket size for each bin\n * @param {Number} config.binCount Number of bins which will be created\n * @param {String} config.name Name of the new binned field to be created\n *\n * @return {PreparatorFunction} Function which expects an instance of DataModel on which the operator needs to be\n * applied.\n */\nexport const bin = (...args) => dm => dm.bin(...args);\n\n/**\n * This is functional version of `groupBy` operator.Groups the data using particular dimensions and by reducing\n * measures. It expects a list of dimensions using which it projects the datamodel and perform aggregations to reduce\n * the duplicate tuples. Refer this {@link link_to_one_example_with_group_by | document} to know the intuition behind\n * groupBy.\n *\n * DataModel by default provides definition of few {@link reducer | Reducers}.\n * {@link ReducerStore | User defined reducers} can also be registered.\n *\n * This is the chained implementation of `groupBy`.\n * `groupBy` also supports {@link link_to_compose_groupBy | composability}\n *\n * @example\n * const groupBy = DataModel.Operators.groupBy;\n * const groupedFn = groupBy(['Year'], { horsepower: 'max' } );\n * groupedDM = groupByFn(dm);\n *\n * @public\n *\n * @param {Array.} fieldsArr - Array containing the name of dimensions\n * @param {Object} [reducers={}] - A map whose key is the variable name and value is the name of the reducer. If its\n * not passed, or any variable is ommitted from the object, default aggregation function is used from the\n * schema of the variable.\n *\n * @return {PreparatorFunction} Function which expects an instance of DataModel on which the operator needs to be\n * applied.\n */\nexport const groupBy = (...args) => dm => dm.groupBy(...args);\n\n/**\n * Enables composing operators to run multiple operations and save group of operataion as named opration on a DataModel.\n * The resulting DataModel will be the result of all the operation provided. The operations provided will be executed in\n * a serial manner ie. result of one operation will be the input for the next operations (like pipe operator in unix).\n *\n * Suported operations in compose are\n * - `select`\n * - `project`\n * - `groupBy`\n * - `bin`\n * - `compose`\n *\n * @example\n * const compose = DataModel.Operators.compose;\n * const select = DataModel.Operators.select;\n * const project = DataModel.Operators.project;\n *\n * let composedFn = compose(\n * select(fields => fields.netprofit.value <= 15),\n * project(['netprofit', 'netsales']));\n *\n * const dataModel = new DataModel(data1, schema1);\n *\n * let composedDm = composedFn(dataModel);\n *\n * @public\n * @namespace DataModel\n * @module Operators\n *\n * @param {Array.} operators: An array of operation that will be applied on the\n * datatable.\n *\n * @returns {DataModel} Instance of resultant DataModel\n */\nexport const compose = (...operations) =>\n (dm, config = { saveChild: true }) => {\n let currentDM = dm;\n let frstChild;\n const derivations = [];\n const saveChild = config.saveChild;\n\n operations.forEach((operation) => {\n currentDM = operation(currentDM);\n derivations.push(...currentDM._derivation);\n if (!frstChild) {\n frstChild = currentDM;\n }\n });\n\n saveChild && currentDM.addParent(dm, derivations);\n if (derivations.length > 1) {\n frstChild.dispose();\n }\n\n return currentDM;\n };\n","/**\n * Wrapper on calculateVariable() method of DataModel to behave\n * the pure-function functionality.\n *\n * @param {Array} args - The argument list.\n * @return {any} Returns the returned value of calling function.\n */\nexport const calculateVariable = (...args) => dm => dm.calculateVariable(...args);\n\n/**\n * Wrapper on sort() method of DataModel to behave\n * the pure-function functionality.\n *\n * @param {Array} args - The argument list.\n * @return {any} Returns the returned value of calling function.\n */\nexport const sort = (...args) => dm => dm.sort(...args);\n","import { crossProduct } from './cross-product';\nimport { naturalJoinFilter } from './natural-join-filter-function';\n\nexport function naturalJoin (dataModel1, dataModel2) {\n return crossProduct(dataModel1, dataModel2, naturalJoinFilter(dataModel1, dataModel2), true);\n}\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://DataModel/webpack/universalModuleDefinition","webpack://DataModel/webpack/bootstrap","webpack://DataModel/./src/index.js","webpack://DataModel/./src/enums/data-format.js","webpack://DataModel/./src/enums/dimension-subtype.js","webpack://DataModel/./src/enums/measure-subtype.js","webpack://DataModel/./src/enums/field-type.js","webpack://DataModel/./src/enums/filtering-mode.js","webpack://DataModel/./src/operator/row-diffset-iterator.js","webpack://DataModel/./src/fields/field.js","webpack://DataModel/./src/utils/date-time-formatter.js","webpack://DataModel/./src/utils/column-major.js","webpack://DataModel/./src/utils/extend2.js","webpack://DataModel/./src/utils/helper.js","webpack://DataModel/./src/field-store.js","webpack://DataModel/./src/value.js","webpack://DataModel/./src/operator/bucket-creator.js","webpack://DataModel/./src/operator/get-common-schema.js","webpack://DataModel/./src/constants/index.js","webpack://DataModel/./src/operator/cross-product.js","webpack://DataModel/./src/operator/merge-sort.js","webpack://DataModel/./src/operator/data-builder.js","webpack://DataModel/./src/operator/difference.js","webpack://DataModel/./src/operator/group-by-function.js","webpack://DataModel/./src/utils/reducer-store.js","webpack://DataModel/./src/operator/group-by.js","webpack://DataModel/./src/operator/natural-join-filter-function.js","webpack://DataModel/./src/operator/union.js","webpack://DataModel/./src/operator/outer-join.js","webpack://DataModel/./src/fields/partial-field.js","webpack://DataModel/./src/fields/measure.js","webpack://DataModel/./src/utils/domain-generator.js","webpack://DataModel/./src/fields/dimension.js","webpack://DataModel/./src/fields/categorical.js","webpack://DataModel/./src/fields/datetime.js","webpack://DataModel/./src/fields/discreteMeasure.js","webpack://DataModel/./src/field-creator.js","webpack://DataModel/./src/default-config.js","webpack://DataModel/./src/converter/dsv-arr.js","webpack://DataModel/./node_modules/d3-dsv/src/dsv.js","webpack://DataModel/./node_modules/d3-dsv/src/csv.js","webpack://DataModel/./node_modules/d3-dsv/src/tsv.js","webpack://DataModel/./src/converter/dsv-str.js","webpack://DataModel/./src/converter/flat-json.js","webpack://DataModel/./src/converter/auto-resolver.js","webpack://DataModel/./src/helper.js","webpack://DataModel/./src/relation.js","webpack://DataModel/./src/datamodel.js","webpack://DataModel/./src/stats/index.js","webpack://DataModel/./src/export.js","webpack://DataModel/./src/operator/compose.js","webpack://DataModel/./src/operator/pure-operators.js","webpack://DataModel/./src/operator/natural-join.js"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","DataModel","default","data_format","FLAT_JSON","DSV_STR","DSV_ARR","AUTO","dimension_subtype","CATEGORICAL","TEMPORAL","GEO","measure_subtype","DISCRETE","field_type","MEASURE","DIMENSION","filtering_mode","NORMAL","INVERSE","ALL","rowDiffsetIterator","rowDiffset","callback","length","split","forEach","diffStr","diffStsArr","start","end","fields_field","Field","partialFeild","rowDiff","_classCallCheck","this","_ref","_rowDiff","sanitize","val","parsed","data","domain","getData","fieldType","subType","Set","Math","min","apply","max","parse","datas","clone","fieldName","type","description","getMinDiff","unit","scale","defAggFn","_this","push","bins","schema","convertToNativeDate","date","Date","pad","DateTimeFormatter","format","dtParams","undefined","nativeDate","RegExp","escape","text","replace","TOKEN_PREFIX","DATETIME_PARAM_SEQUENCE","YEAR","MONTH","DAY","HOUR","MINUTE","SECOND","MILLISECOND","defaultNumberParser","defVal","parsedVal","isFinite","parseInt","defaultRangeParser","range","nVal","toLowerCase","getTokenDefinitions","daysDef","short","long","monthsDef","H","index","extract","parser","formatter","getHours","toString","hours","P","M","getMinutes","S","getSeconds","K","getMilliseconds","a","join","day","getDay","A","e","getDate","b","month","getMonth","B","y","substring","year","getFullYear","Y","getTokenFormalNames","definitions","HOUR_12","AMPM_UPPERCASE","AMPM_LOWERCASE","SHORT_DAY","LONG_DAY","DAY_OF_MONTH","DAY_OF_MONTH_CONSTANT_WIDTH","SHORT_MONTH","LONG_MONTH","MONTH_OF_YEAR","SHORT_YEAR","LONG_YEAR","tokenResolver","defaultResolver","arg","targetParam","arguments","hourFormat24","hourFormat12","ampmLower","ampmUpper","amOrpm","isPM","findTokens","tokenPrefix","tokenLiterals","keys","occurrence","forwardChar","indexOf","token","formatAs","nDate","formattedStr","String","formattedVal","dateTimeStamp","options","extractTokenValue","dtParamSeq","noBreak","dtParamArr","args","resolverKey","resolverParams","resolverFn","param","resolvedVal","splice","tokenObj","lastOccurrenceIndex","occObj","occIndex","targetText","regexFormat","tokenArr","map","obj","occurrenceLength","extractValues","match","shift","getNativeDate","unshift","Function","column_major","store","_len","fields","Array","_key","fieldIndex","from","OBJECTSTRING","objectToStrFn","objectToStr","arrayToStr","checkCyclicRef","parentArr","bIndex","extend2","obj1","obj2","skipUndef","_typeof","merge","tgtArr","srcArr","item","srcVal","tgtVal","str","cRef","isArray","isCallable","getUniqueId","getTime","round","random","unique","arr","concat","helper_toConsumableArray","diff","uniqueVals","abs","len","isArrEqual","arr1","arr2","formatNumber","field_store","createNamespace","fieldArr","dataId","fieldsObj","retObj","field","getMeasure","getDimension","src_value","Value","value_classCallCheck","configurable","writable","_value","createBinnedFieldData","config","buckets","binCount","binSize","dataStore","binnedData","_field$domain","_field$domain2","_slicedToArray","oriMax","stops","binEnd","prevEndpoint","mid","extraBinELm","endPoint","filter","datum","add","bucket_creator_toConsumableArray","sort","getCommonSchema","fs1","fs2","retArr","fs1Arr","DM_DERIVATIVES","JOINS","CROSS","LEFTOUTER","RIGHTOUTER","NATURAL","FULLOUTER","LOGICAL_OPERATORS","defaultFilterFn","crossProduct","dm1","dm2","filterFn","replaceCommonSchema","jointype","applicableFilterFn","dm1FieldStore","getFieldspace","dm2FieldStore","dm1FieldStoreName","dm2FieldStoreName","commonSchemaList","Error","tmpSchema","_rowDiffset","rowAdded","rowPosition","ii","tuple","userArg","dm1Fields","prepareJoinData","dm2Fields","tupleObj","cellVal","iii","datamodel","defSortFn","a1","b1","mergeSort","sortFn","merge_sort_sort","lo","hi","floor","mainArr","auxArr","merge_sort_merge","getSortFn","dataType","sortType","retFunc","groupData","hashMap","Map","groupedData","fieldVal","has","set","createSortingFnArg","groupedDatum","targetFields","targetFieldDetails","label","reduce","acc","next","idx","dataBuilder","fieldStore","colIdentifier","sortingDetails","uids","addUid","assign","columnWise","reqSorting","tmpDataArr","colName","insertInd","dataObj","sortMeta","fDetails","fieldInSchema","sortingFn","slice","f","data_builder_toConsumableArray","pop","sortData","tmpData","difference_difference","hashTable","schemaNameArr","dm1FieldStoreFieldObj","dm2FieldStoreFieldObj","_colIdentifier","prepareDataHelper","dm","addData","hashData","schemaName","sum","allNulls","isNestedArray","sumVal","carry","x","group_by_function_toConsumableArray","avg","arrSum","fnList","Infinity","every","first","last","count","std","sqrt","mean","num","pow","variance","defaultReducerName","reducer_store_ReducerStore","ReducerStore","reducer_store_classCallCheck","entries","reducer","_this2","__unregister","delete","reducer_store","group_by_groupBy","dataModel","reducers","existingDataModel","sFieldArr","getPartialFieldspace","dimensions","measures","group_by_slicedToArray","_ref3","getFieldArr","reducerObj","pReducers","defaultReducer","_ref5","resolve","getReducerObj","fieldStoreObj","dbName","dimensionArr","measureArr","newDataModel","_ref7","_ref8","subtype","rowCount","hash","_","row","__calculateFieldspace","src_export","naturalJoinFilter","commonSchemaArr","retainTuple","union_union","leftOuterJoin","dataModel1","dataModel2","rightOuterJoin","partial_field","PartialField","partial_field_classCallCheck","fieldDescription","constructor","measure","Measure","measure_classCallCheck","_possibleConstructorReturn","__proto__","getPrototypeOf","fieldUnit","fieldScale","fieldDefAggFn","fieldNumberformat","numberFormat","Number","POSITIVE_INFINITY","NEGATIVE_INFINITY","domain_generator","parseFloat","isNaN","dimension","uniqueValues","trim","_unique","categorical","Categorical","categorical_classCallCheck","categorical_possibleConstructorReturn","datetime","DateTime","datetime_classCallCheck","datetime_possibleConstructorReturn","minDiff","_dtf","discreteMeasure","DiscreteMeasure","bin","discreteMeasure_classCallCheck","discreteMeasure_possibleConstructorReturn","field_creator","dataColumn","headers","headersObj","header","createUnitField","default_config","dataFormat","dsv_arr","firstRowHeader","columns","dsv_arr_toConsumableArray","EOL","EOF","QUOTE","NEWLINE","RETURN","objectConverter","JSON","stringify","src_dsv","delimiter","reFormat","DELIMITER","charCodeAt","parseRows","rows","N","I","eof","eol","j","formatRow","formatValue","test","convert","customConverter","columnSet","column","inferColumns","formatRows","csv","tsv","dsv_str","fieldSeparator","dsv","flat_json","insertionIndex","auto_resolver","converter","isString","isObject","prepareSelectionData","resp","_iteratorNormalCompletion","_didIteratorError","_iteratorError","_step","_iterator","iterator","done","err","return","helper_persistDerivation","model","operation","_model$_derivation","criteriaFn","derivative","op","meta","criteria","_derivation","src_helper_toConsumableArray","helper_filterPropagationModel","propModels","filterByMeasure","fns","propModel","fieldsConfig","getFieldsConfig","fieldsSpace","values","v","def","some","propField","valueOf","filteredModel","select","fn","saveChild","helper_cloneWithSelect","sourceDm","selectFn","selectConfig","cloneConfig","cloned","newRowDiffSet","lastInsertedValue","li","checker","helper_selectHelper","calculateFieldsConfig","helper_cloneWithProject","projField","allFields","projectionSet","actualProjField","helper_updateData","relation","converterFn","converter_namespaceObject","_converterFn","_converterFn2","helper_slicedToArray","formattedData","nameSpace","_partialFieldspace","applyExistingOperationOnModel","_propModel$","_propModel$2","_getOperationArgument","child","derivation","params","groupByString","helper_getOperationArguments","selectionModel","rejectionModel","propagateIdentifiers","propModelInf","nonTraversingModel","excludeModels","handlePropagation","_children","_applyExistingOperati","_applyExistingOperati2","propagateToAllDataModels","identifiers","rootModels","propagationInf","propagationNameSpace","propagateToSource","propagationSourceId","sourceId","propagateInterpolatedValues","criterias","persistent","actionCriterias","mutableActions","filteredCriteria","entry","action","sourceActionCriterias","actionInf","actionConf","applyOnSource","models","path","getPathToRootModel","_parent","rootModel","propConfig","sourceIdentifiers","rootGroupByModel","groupByModel","inf","propagationModel","getFilteredModel","reverse","src_relation","Relation","relation_classCallCheck","source","_fieldStoreName","updateData","_propagationNameSpace","immutableActions","_fieldspace","partialFieldspace","fieldStoreName","_ref2","collID","partialFieldMap","newFields","coll","helper_updateFields","joinWith","unionWith","differenceWith","defConfig","oDm","retDataModel","getAllFields","jsonData","rowObj","fieldConfig","normalizedProjField","relation_toConsumableArray","search","_fieldConfig","fieldDef","removeChild","findIndex","sibling","parent","criteriaQueue","datamodel_classCallCheck","datamodel_possibleConstructorReturn","_onPropagation","_sortingDetails","order","withUid","dataGenerated","fieldNames","fmtFieldIdx","elem","fIdx","fmtFn","datumIdx","fieldsArr","groupBy","rawData","dataInCSVArr","sortedDm","fieldinst","dependency","replaceVar","depVars","retrieveFn","depFieldIndices","fieldSpec","fs","suppliedFields","computedValues","fieldsData","datamodel_toConsumableArray","_createFields","datamodel_slicedToArray","addField","addToNameSpace","isMutableAction","payload","getRootDataModel","getRootGroupByModel","find","sourceNamespace","addToPropNamespace","filterImmutableAction","criteriaModel","propagateImmutableActions","eventName","measureName","binFieldName","dataSet","currfield","binField","stats_sum","stats_avg","stats_min","stats_max","stats_first","stats_last","stats_count","sd","Operators","compose","_len5","operations","_key5","currentDM","frstChild","derivations","compose_toConsumableArray","addParent","dispose","_len3","_key3","project","_len2","_key2","_len4","_key4","calculateVariable","difference","naturalJoin","fullOuterJoin","union","Stats","stats_namespaceObject","enums_namespaceObject","DataFormat","FilteringMode","version","package_0","__webpack_exports__"],"mappings":"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","file":"datamodel.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"DataModel\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"DataModel\"] = factory();\n\telse\n\t\troot[\"DataModel\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 1);\n","const DataModel = require('./export');\n\nmodule.exports = DataModel.default ? DataModel.default : DataModel;\n","/**\n * DataFormat Enum defines the format of the input data.\n * Based on the format of the data the respective adapter is loaded.\n *\n * @readonly\n * @enum {string}\n */\nconst DataFormat = {\n FLAT_JSON: 'FlatJSON',\n DSV_STR: 'DSVStr',\n DSV_ARR: 'DSVArr',\n AUTO: 'Auto'\n};\n\nexport default DataFormat;\n","/**\n * DimensionSubtype enum defines the sub types of the Dimensional Field.\n *\n * @readonly\n * @enum {string}\n */\nconst DimensionSubtype = {\n CATEGORICAL: 'categorical',\n TEMPORAL: 'temporal',\n GEO: 'geo'\n};\n\nexport default DimensionSubtype;\n","/**\n * MeasureSubtype enum defines the sub types of the Dimensional Field.\n *\n * @readonly\n * @enum {string}\n */\nconst MeasureSubtype = {\n DISCRETE: 'discrete'\n};\n\nexport default MeasureSubtype;\n","/**\n * FieldType enum defines the high level field based on which visuals are controlled.\n * Measure in a high level is numeric field and Dimension in a high level is string field.\n *\n * @readonly\n * @enum {string}\n */\nconst FieldType = {\n MEASURE: 'measure',\n DIMENSION: 'dimension'\n};\n\nexport default FieldType;\n","/**\n * Filtering mode enum defines the filering modes of DataModel.\n *\n * @readonly\n * @enum {string}\n */\nconst FilteringMode = {\n NORMAL: 'normal',\n INVERSE: 'inverse',\n ALL: 'all'\n};\n\nexport default FilteringMode;\n","/**\n * Iterates through the diffSet array and call the callback with the current\n * index.\n *\n * @param {string} rowDiffset - The row diffset string e.g. '0-4,6,10-13'.\n * @param {Function} callback - The callback function to be called with every index.\n */\nexport function rowDiffsetIterator (rowDiffset, callback) {\n if (rowDiffset.length > 0) {\n const rowDiffArr = rowDiffset.split(',');\n rowDiffArr.forEach((diffStr) => {\n const diffStsArr = diffStr.split('-');\n const start = +(diffStsArr[0]);\n const end = +(diffStsArr[1] || diffStsArr[0]);\n if (end >= start) {\n for (let i = start; i <= end; i += 1) {\n callback(i);\n }\n }\n });\n }\n}\n","import { DimensionSubtype } from '../enums';\nimport { rowDiffsetIterator } from '../operator/row-diffset-iterator';\n\n/**\n * In {@link DataModel}, every tabular data consists of column, a column is stored as field.\n * Field contains all the data for a given column in an array.\n *\n * Each record consists of several fields; the fields of all records form the columns.\n * Examples of fields: name, gender, sex etc.\n *\n * In DataModel, each field can have multiple attributes which describes its data and behaviour.\n * A field can have two types of data: Measure and Dimension.\n *\n * A Dimension Field is the context on which a data is categorized and the measure is the numerical values that\n * quantify the data set.\n * In short a dimension is the lens through which you are looking at your measure data.\n *\n * Refer to {@link Schema} to get info about possible field attributes.\n *\n * @public\n * @class\n */\nexport default class Field {\n constructor(partialFeild, rowDiff) {\n this._ref = partialFeild;\n this._rowDiff = rowDiff;\n }\n\n sanitize () {\n return this._ref.sanitize();\n }\n\n parsed (val) {\n return this._ref.parsed(val);\n }\n\n domain() {\n let data = [];\n let domain = null;\n data = this.getData();\n if (this._ref.fieldType === 'dimension' && this._ref.subType() !== DimensionSubtype.TEMPORAL) {\n domain = [...new Set(data)];\n } else {\n let minD = Math.min.apply(null, data);\n let maxD = Math.max.apply(null, data);\n domain = [minD, maxD];\n }\n\n return domain;\n }\n\n parse (val) {\n return this._ref.parse(val);\n }\n\n\n clone(datas) {\n return this._ref.clone(datas);\n }\n\n fieldName() {\n return this._ref.fieldName();\n }\n\n type() {\n return this._ref.type();\n }\n\n description() {\n return this._ref.description();\n }\n\n get name() {\n return this._ref.name;\n }\n\n // set name(name) {\n // this._ref.name = name;\n // }\n\n get schema() {\n return this._ref.schema;\n }\n\n // set schema(schema) {\n // this._ref.schema = schema;\n // }\n\n get data() {\n return this._ref.data;\n }\n\n // set data(schema) {\n // throw new Error('Not yet implemented!');\n // }\n\n subType() {\n return this._ref.subType();\n }\n\n getMinDiff () {\n return this._ref.getMinDiff();\n }\n\n /**\n * Getter for unit value of the field.\n *\n * @return {string} Returns unit of the field.\n */\n unit() {\n return this._ref.unit();\n }\n\n /**\n * Getter for scale value of the field.\n *\n * @return {string} Returns scale of the field.\n */\n scale() {\n return this._ref.scale();\n }\n\n /**\n * Getter for aggregation function of the field.\n *\n * @return {Function} Returns aggregation function of the field.\n */\n defAggFn() {\n return this._ref.defAggFn();\n }\n\n getData() {\n let data = [];\n rowDiffsetIterator(this._rowDiff, (i) => {\n data.push(this._ref.data[i]);\n });\n return data;\n }\n\n bins() {\n return this._ref.bins();\n }\n}\n","/**\n * Creates a JS native date object from input\n *\n * @param {string | number | Date} date Input using which date object to be created\n * @return {Date} : JS native date object\n */\nfunction convertToNativeDate (date) {\n if (date instanceof Date) {\n return date;\n }\n\n return new Date(date);\n}\n/**\n * Apply padding before a number if its less than 1o. This is used when constant digit's number to be returned\n * between 0 - 99\n *\n * @param {number} n Input to be padded\n * @return {string} Padded number\n */\nfunction pad (n) {\n return (n < 10) ? (`0${n}`) : n;\n}\n/*\n * DateFormatter utility to convert any date format to any other date format\n * DateFormatter parse a date time stamp specified by a user abiding by rules which are defined\n * by user in terms of token. It creates JS native date object from the user specified format.\n * That native date can also be displayed\n * in any specified format.\n * This utility class only takes care of format conversion only\n */\n\n/*\n * Escapes all the special character that are used in regular expression.\n * Like\n * RegExp.escape('sgfd-$') // Output: sgfd\\-\\$\n *\n * @param text {String} : text which is to be escaped\n */\nRegExp.escape = function (text) {\n return text.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&');\n};\n\n/**\n * DateTimeFormatter class to convert any user format of date time stamp to any other format\n * of date time stamp.\n *\n * @param {string} format Format of the date given. For the above date,\n * 'year: %Y, month: %b, day: %d'.\n * @class\n */\n/* istanbul ignore next */ function DateTimeFormatter (format) {\n this.format = format;\n this.dtParams = undefined;\n this.nativeDate = undefined;\n}\n\n// The identifier of the tokens\nDateTimeFormatter.TOKEN_PREFIX = '%';\n\n// JS native Date constructor takes the date params (year, month, etc) in a certail sequence.\n// This defines the sequence of the date parameters in the constructor.\nDateTimeFormatter.DATETIME_PARAM_SEQUENCE = {\n YEAR: 0,\n MONTH: 1,\n DAY: 2,\n HOUR: 3,\n MINUTE: 4,\n SECOND: 5,\n MILLISECOND: 6\n};\n\n/*\n * This is a default number parsing utility. It tries to parse a number in integer, if parsing is unsuccessful, it\n * gives back a default value.\n *\n * @param: defVal {Number} : Default no if the parsing to integer is not successful\n * @return {Function} : An closure function which is to be called by passing an the value which needs to be parsed.\n */\nDateTimeFormatter.defaultNumberParser = function (defVal) {\n return function (val) {\n let parsedVal;\n if (isFinite(parsedVal = parseInt(val, 10))) {\n return parsedVal;\n }\n\n return defVal;\n };\n};\n\n/*\n * This is a default number range utility. It tries to find an element in the range. If not found it returns a\n * default no as an index.\n *\n * @param: range {Array} : The list which is to be serached\n * @param: defVal {Number} : Default no if the serach and find does not return anything\n * @return {Function} : An closure function which is to be called by passing an the value which needs to be found\n */\nDateTimeFormatter.defaultRangeParser = function (range, defVal) {\n return (val) => {\n let i;\n let l;\n\n if (!val) { return defVal; }\n\n const nVal = val.toLowerCase();\n\n for (i = 0, l = range.length; i < l; i++) {\n if (range[i].toLowerCase() === nVal) {\n return i;\n }\n }\n\n if (i === undefined) {\n return defVal;\n }\n return null;\n };\n};\n\n/*\n * Defines the tokens which are supporter by the dateformatter. Using this definitation a value gets extracted from\n * the user specifed date string. This also formats the value for display purpose from native JS date.\n * The definition of each token contains the following named properties\n * {\n * %token_name% : {\n * name: name of the token, this is used in reverse lookup,\n * extract: a function that returns the regular expression to extract that piece of information. All the\n * regex should be gouped by using ()\n * parser: a function which receives value extracted by the above regex and parse it to get the date params\n * formatter: a formatter function that takes milliseconds or JS Date object and format the param\n * represented by the token only.\n * }\n * }\n *\n * @return {Object} : Definition of the all the supported tokens.\n */\nDateTimeFormatter.getTokenDefinitions = function () {\n const daysDef = {\n short: [\n 'Sun',\n 'Mon',\n 'Tue',\n 'Wed',\n 'Thu',\n 'Fri',\n 'Sat'\n ],\n long: [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday'\n ]\n };\n const monthsDef = {\n short: [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec'\n ],\n long: [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December'\n ]\n };\n\n const definitions = {\n H: {\n // 24 hours format\n name: 'H',\n index: 3,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n\n return d.getHours().toString();\n }\n },\n l: {\n // 12 hours format\n name: 'l',\n index: 3,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const hours = d.getHours() % 12;\n\n return (hours === 0 ? 12 : hours).toString();\n }\n },\n p: {\n // AM or PM\n name: 'p',\n index: 3,\n extract () { return '(AM|PM)'; },\n parser: (val) => {\n if (val) {\n return val.toLowerCase();\n }\n return null;\n },\n formatter: (val) => {\n const d = convertToNativeDate(val);\n const hours = d.getHours();\n\n return (hours < 12 ? 'AM' : 'PM');\n }\n },\n P: {\n // am or pm\n name: 'P',\n index: 3,\n extract () { return '(am|pm)'; },\n parser: (val) => {\n if (val) {\n return val.toLowerCase();\n }\n return null;\n },\n formatter: (val) => {\n const d = convertToNativeDate(val);\n const hours = d.getHours();\n\n return (hours < 12 ? 'am' : 'pm');\n }\n },\n M: {\n // Two digit minutes 00 - 59\n name: 'M',\n index: 4,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const mins = d.getMinutes();\n\n return pad(mins);\n }\n },\n S: {\n // Two digit seconds 00 - 59\n name: 'S',\n index: 5,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const seconds = d.getSeconds();\n\n return pad(seconds);\n }\n },\n K: {\n // Milliseconds\n name: 'K',\n index: 6,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const ms = d.getMilliseconds();\n\n return ms.toString();\n }\n },\n a: {\n // Short name of day, like Mon\n name: 'a',\n index: 2,\n extract () { return `(${daysDef.short.join('|')})`; },\n parser: DateTimeFormatter.defaultRangeParser(daysDef.short),\n formatter (val) {\n const d = convertToNativeDate(val);\n const day = d.getDay();\n\n return (daysDef.short[day]).toString();\n }\n },\n A: {\n // Long name of day, like Monday\n name: 'A',\n index: 2,\n extract () { return `(${daysDef.long.join('|')})`; },\n parser: DateTimeFormatter.defaultRangeParser(daysDef.long),\n formatter (val) {\n const d = convertToNativeDate(val);\n const day = d.getDay();\n\n return (daysDef.long[day]).toString();\n }\n },\n e: {\n // 8 of March, 11 of November\n name: 'e',\n index: 2,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const day = d.getDate();\n\n return day.toString();\n }\n },\n d: {\n // 08 of March, 11 of November\n name: 'd',\n index: 2,\n extract () { return '(\\\\d+)'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const day = d.getDate();\n\n return pad(day);\n }\n },\n b: {\n // Short month, like Jan\n name: 'b',\n index: 1,\n extract () { return `(${monthsDef.short.join('|')})`; },\n parser: DateTimeFormatter.defaultRangeParser(monthsDef.short),\n formatter (val) {\n const d = convertToNativeDate(val);\n const month = d.getMonth();\n\n return (monthsDef.short[month]).toString();\n }\n },\n B: {\n // Long month, like January\n name: 'B',\n index: 1,\n extract () { return `(${monthsDef.long.join('|')})`; },\n parser: DateTimeFormatter.defaultNumberParser(monthsDef.long),\n formatter (val) {\n const d = convertToNativeDate(val);\n const month = d.getMonth();\n\n return (monthsDef.long[month]).toString();\n }\n },\n m: {\n // Two digit month of year like 01 for January\n name: 'm',\n index: 1,\n extract () { return '(\\\\d+)'; },\n parser (val) { return DateTimeFormatter.defaultNumberParser()(val) - 1; },\n formatter (val) {\n const d = convertToNativeDate(val);\n const month = d.getMonth();\n\n return pad(month + 1);\n }\n },\n y: {\n // Short year like 90 for 1990\n name: 'y',\n index: 0,\n extract () { return '(\\\\d{4})'; },\n parser (val) {\n if (val) {\n const l = val.length;\n val = val.substring(l - 2, l);\n }\n\n return DateTimeFormatter.defaultNumberParser()(val);\n },\n formatter (val) {\n const d = convertToNativeDate(val);\n let year = d.getFullYear().toString();\n let l;\n\n if (year) {\n l = year.length;\n year = year.substring(l - 2, l);\n }\n\n return year;\n }\n },\n Y: {\n // Long year like 1990\n name: 'Y',\n index: 0,\n extract () { return '(\\\\d{4})'; },\n parser: DateTimeFormatter.defaultNumberParser(),\n formatter (val) {\n const d = convertToNativeDate(val);\n const year = d.getFullYear().toString();\n\n return year;\n }\n }\n };\n\n return definitions;\n};\n\n/*\n * The tokens which works internally is not user friendly in terms of memorizing the names. This gives a formal\n * definition to the informal notations.\n *\n * @return {Object} : Formal definition of the tokens\n */\nDateTimeFormatter.getTokenFormalNames = function () {\n const definitions = DateTimeFormatter.getTokenDefinitions();\n\n return {\n HOUR: definitions.H,\n HOUR_12: definitions.l,\n AMPM_UPPERCASE: definitions.p,\n AMPM_LOWERCASE: definitions.P,\n MINUTE: definitions.M,\n SECOND: definitions.S,\n SHORT_DAY: definitions.a,\n LONG_DAY: definitions.A,\n DAY_OF_MONTH: definitions.e,\n DAY_OF_MONTH_CONSTANT_WIDTH: definitions.d,\n SHORT_MONTH: definitions.b,\n LONG_MONTH: definitions.B,\n MONTH_OF_YEAR: definitions.m,\n SHORT_YEAR: definitions.y,\n LONG_YEAR: definitions.Y\n };\n};\n\n/*\n * This defines the rules and declares dependencies that resolves a date parameter (year, month etc) from\n * the date time parameter array.\n *\n * @return {Object} : An object that contains dependencies and a resolver function. The dependencies values are fed\n * to the resolver function in that particular sequence only.\n */\nDateTimeFormatter.tokenResolver = function () {\n const definitions = DateTimeFormatter.getTokenDefinitions();\n const defaultResolver = (...args) => { // eslint-disable-line require-jsdoc\n let i = 0;\n let arg;\n let targetParam;\n const l = args.length;\n\n for (; i < l; i++) {\n arg = args[i];\n if (args[i]) {\n targetParam = arg;\n }\n }\n\n if (!targetParam) { return null; }\n\n return targetParam[0].parser(targetParam[1]);\n };\n\n return {\n YEAR: [definitions.y, definitions.Y,\n defaultResolver\n ],\n MONTH: [definitions.b, definitions.B, definitions.m,\n defaultResolver\n ],\n DAY: [definitions.a, definitions.A, definitions.e, definitions.d,\n defaultResolver\n ],\n HOUR: [definitions.H, definitions.l, definitions.p, definitions.P,\n function (hourFormat24, hourFormat12, ampmLower, ampmUpper) {\n let targetParam;\n let amOrpm;\n let isPM;\n let val;\n\n if (hourFormat12 && (amOrpm = (ampmLower || ampmUpper))) {\n if (amOrpm[0].parser(amOrpm[1]) === 'pm') {\n isPM = true;\n }\n\n targetParam = hourFormat12;\n } else if (hourFormat12) {\n targetParam = hourFormat12;\n } else {\n targetParam = hourFormat24;\n }\n\n if (!targetParam) { return null; }\n\n val = targetParam[0].parser(targetParam[1]);\n if (isPM) {\n val += 12;\n }\n return val;\n }\n ],\n MINUTE: [definitions.M,\n defaultResolver\n ],\n SECOND: [definitions.S,\n defaultResolver\n ]\n };\n};\n\n/*\n * Finds token from the format rule specified by a user.\n * @param format {String} : The format of the input date specified by the user\n * @return {Array} : An array of objects which contains the available token and their occurence index in the format\n */\nDateTimeFormatter.findTokens = function (format) {\n const tokenPrefix = DateTimeFormatter.TOKEN_PREFIX;\n const definitions = DateTimeFormatter.getTokenDefinitions();\n const tokenLiterals = Object.keys(definitions);\n const occurrence = [];\n let i;\n let forwardChar;\n\n while ((i = format.indexOf(tokenPrefix, i + 1)) >= 0) {\n forwardChar = format[i + 1];\n if (tokenLiterals.indexOf(forwardChar) === -1) { continue; }\n\n occurrence.push({\n index: i,\n token: forwardChar\n });\n }\n\n return occurrence;\n};\n\n/*\n * Format any JS date to a specified date given by user.\n *\n * @param date {Number | Date} : The date object which is to be formatted\n * @param format {String} : The format using which the date will be formatted for display\n */\nDateTimeFormatter.formatAs = function (date, format) {\n const nDate = convertToNativeDate(date);\n const occurrence = DateTimeFormatter.findTokens(format);\n const definitions = DateTimeFormatter.getTokenDefinitions();\n let formattedStr = String(format);\n const tokenPrefix = DateTimeFormatter.TOKEN_PREFIX;\n let token;\n let formattedVal;\n let i;\n let l;\n\n for (i = 0, l = occurrence.length; i < l; i++) {\n token = occurrence[i].token;\n formattedVal = definitions[token].formatter(nDate);\n formattedStr = formattedStr.replace(new RegExp(tokenPrefix + token, 'g'), formattedVal);\n }\n\n return formattedStr;\n};\n\n/*\n * Parses the user specified date string to extract the date time params.\n *\n * @return {Array} : Value of date time params in an array [year, month, day, hour, minutes, seconds, milli]\n */\nDateTimeFormatter.prototype.parse = function (dateTimeStamp, options) {\n const tokenResolver = DateTimeFormatter.tokenResolver();\n const dtParams = this.extractTokenValue(dateTimeStamp);\n const dtParamSeq = DateTimeFormatter.DATETIME_PARAM_SEQUENCE;\n const noBreak = options && options.noBreak;\n const dtParamArr = [];\n const args = [];\n let resolverKey;\n let resolverParams;\n let resolverFn;\n let val;\n let i;\n let param;\n let resolvedVal;\n let l;\n\n for (resolverKey in tokenResolver) {\n if (!{}.hasOwnProperty.call(tokenResolver, resolverKey)) { continue; }\n\n args.length = 0;\n resolverParams = tokenResolver[resolverKey];\n resolverFn = resolverParams.splice(resolverParams.length - 1, 1)[0];\n\n for (i = 0, l = resolverParams.length; i < l; i++) {\n param = resolverParams[i];\n val = dtParams[param.name];\n\n if (val === undefined) {\n args.push(null);\n } else {\n args.push([param, val]);\n }\n }\n\n resolvedVal = resolverFn.apply(this, args);\n\n if ((resolvedVal === undefined || resolvedVal === null) && !noBreak) {\n break;\n }\n\n dtParamArr[dtParamSeq[resolverKey]] = resolvedVal;\n }\n\n return dtParamArr;\n};\n\n/*\n * Extract the value of the token from user specified date time string.\n *\n * @return {Object} : An key value pair which contains the tokens as key and value as pair\n */\nDateTimeFormatter.prototype.extractTokenValue = function (dateTimeStamp) {\n const format = this.format;\n const definitions = DateTimeFormatter.getTokenDefinitions();\n const tokenPrefix = DateTimeFormatter.TOKEN_PREFIX;\n const occurrence = DateTimeFormatter.findTokens(format);\n const tokenObj = {};\n\n let lastOccurrenceIndex;\n let occObj;\n let occIndex;\n let targetText;\n let regexFormat;\n\n let l;\n let i;\n\n regexFormat = String(format);\n\n const tokenArr = occurrence.map(obj => obj.token);\n const occurrenceLength = occurrence.length;\n for (i = occurrenceLength - 1; i >= 0; i--) {\n occIndex = occurrence[i].index;\n\n if (occIndex + 1 === regexFormat.length - 1) {\n lastOccurrenceIndex = occIndex;\n continue;\n }\n\n if (lastOccurrenceIndex === undefined) {\n lastOccurrenceIndex = regexFormat.length;\n }\n\n targetText = regexFormat.substring(occIndex + 2, lastOccurrenceIndex);\n regexFormat = regexFormat.substring(0, occIndex + 2) +\n RegExp.escape(targetText) +\n regexFormat.substring(lastOccurrenceIndex, regexFormat.length);\n\n lastOccurrenceIndex = occIndex;\n }\n\n for (i = 0; i < occurrenceLength; i++) {\n occObj = occurrence[i];\n regexFormat = regexFormat.replace(tokenPrefix + occObj.token, definitions[occObj.token].extract());\n }\n\n const extractValues = dateTimeStamp.match(new RegExp(regexFormat)) || [];\n extractValues.shift();\n\n for (i = 0, l = tokenArr.length; i < l; i++) {\n tokenObj[tokenArr[i]] = extractValues[i];\n }\n return tokenObj;\n};\n\n/*\n * Give back the JS native date formed from user specified date string\n *\n * @return {Date} : Native JS Date\n */\nDateTimeFormatter.prototype.getNativeDate = function (dateTimeStamp) {\n if (dateTimeStamp instanceof Date) {\n return dateTimeStamp;\n } else if (isFinite(dateTimeStamp) && !!this.format) {\n return new Date(dateTimeStamp);\n }\n\n const dtParams = this.dtParams = this.parse(dateTimeStamp);\n\n dtParams.unshift(null);\n this.nativeDate = new (Function.prototype.bind.apply(Date, dtParams))();\n return this.nativeDate;\n};\n\n/*\n * Represents JS native date to a user specified format.\n *\n * @param format {String} : The format according to which the date is to be represented\n * @return {String} : The formatted date string\n */\nDateTimeFormatter.prototype.formatAs = function (format, dateTimeStamp) {\n let nativeDate;\n\n if (dateTimeStamp) {\n nativeDate = this.nativeDate = this.getNativeDate(dateTimeStamp);\n } else if (!(nativeDate = this.nativeDate)) {\n nativeDate = this.getNativeDate(dateTimeStamp);\n }\n\n return DateTimeFormatter.formatAs(nativeDate, format);\n};\n\nexport { DateTimeFormatter as default };\n","/**\n * The utility function to calculate major column.\n *\n * @param {Object} store - The store object.\n * @return {Function} Returns the push function.\n */\nexport default (store) => {\n let i = 0;\n return (...fields) => {\n fields.forEach((val, fieldIndex) => {\n if (!(store[fieldIndex] instanceof Array)) {\n store[fieldIndex] = Array.from({ length: i });\n }\n store[fieldIndex].push(val);\n });\n i++;\n };\n};\n","/* eslint-disable */\nconst OBJECTSTRING = 'object';\nconst objectToStrFn = Object.prototype.toString;\nconst objectToStr = '[object Object]';\nconst arrayToStr = '[object Array]';\n\nfunction checkCyclicRef(obj, parentArr) {\n let i = parentArr.length;\n let bIndex = -1;\n\n while (i) {\n if (obj === parentArr[i]) {\n bIndex = i;\n return bIndex;\n }\n i -= 1;\n }\n\n return bIndex;\n}\n\nfunction merge(obj1, obj2, skipUndef, tgtArr, srcArr) {\n var item,\n srcVal,\n tgtVal,\n str,\n cRef;\n // check whether obj2 is an array\n // if array then iterate through it's index\n // **** MOOTOOLS precution\n\n if (!srcArr) {\n tgtArr = [obj1];\n srcArr = [obj2];\n }\n else {\n tgtArr.push(obj1);\n srcArr.push(obj2);\n }\n\n if (obj2 instanceof Array) {\n for (item = 0; item < obj2.length; item += 1) {\n try {\n srcVal = obj1[item];\n tgtVal = obj2[item];\n }\n catch (e) {\n continue;\n }\n\n if (typeof tgtVal !== OBJECTSTRING) {\n if (!(skipUndef && tgtVal === undefined)) {\n obj1[item] = tgtVal;\n }\n }\n else {\n if (srcVal === null || typeof srcVal !== OBJECTSTRING) {\n srcVal = obj1[item] = tgtVal instanceof Array ? [] : {};\n }\n cRef = checkCyclicRef(tgtVal, srcArr);\n if (cRef !== -1) {\n srcVal = obj1[item] = tgtArr[cRef];\n }\n else {\n merge(srcVal, tgtVal, skipUndef, tgtArr, srcArr);\n }\n }\n }\n }\n else {\n for (item in obj2) {\n try {\n srcVal = obj1[item];\n tgtVal = obj2[item];\n }\n catch (e) {\n continue;\n }\n\n if (tgtVal !== null && typeof tgtVal === OBJECTSTRING) {\n // Fix for issue BUG: FWXT-602\n // IE < 9 Object.prototype.toString.call(null) gives\n // '[object Object]' instead of '[object Null]'\n // that's why null value becomes Object in IE < 9\n str = objectToStrFn.call(tgtVal);\n if (str === objectToStr) {\n if (srcVal === null || typeof srcVal !== OBJECTSTRING) {\n srcVal = obj1[item] = {};\n }\n cRef = checkCyclicRef(tgtVal, srcArr);\n if (cRef !== -1) {\n srcVal = obj1[item] = tgtArr[cRef];\n }\n else {\n merge(srcVal, tgtVal, skipUndef, tgtArr, srcArr);\n }\n }\n else if (str === arrayToStr) {\n if (srcVal === null || !(srcVal instanceof Array)) {\n srcVal = obj1[item] = [];\n }\n cRef = checkCyclicRef(tgtVal, srcArr);\n if (cRef !== -1) {\n srcVal = obj1[item] = tgtArr[cRef];\n }\n else {\n merge(srcVal, tgtVal, skipUndef, tgtArr, srcArr);\n }\n }\n else {\n obj1[item] = tgtVal;\n }\n }\n else {\n if (skipUndef && tgtVal === undefined) {\n continue;\n }\n obj1[item] = tgtVal;\n }\n }\n }\n return obj1;\n}\n\n\nfunction extend2 (obj1, obj2, skipUndef) {\n //if none of the arguments are object then return back\n if (typeof obj1 !== OBJECTSTRING && typeof obj2 !== OBJECTSTRING) {\n return null;\n }\n\n if (typeof obj2 !== OBJECTSTRING || obj2 === null) {\n return obj1;\n }\n\n if (typeof obj1 !== OBJECTSTRING) {\n obj1 = obj2 instanceof Array ? [] : {};\n }\n merge(obj1, obj2, skipUndef);\n return obj1;\n}\n\nexport { extend2 as default };\n","/**\n * Checks whether the value is an array.\n *\n * @param {*} val - The value to be checked.\n * @return {boolean} Returns true if the value is an array otherwise returns false.\n */\nexport function isArray (val) {\n return Array.isArray(val);\n}\n\n/**\n * Checks whether the value is an object.\n *\n * @param {*} val - The value to be checked.\n * @return {boolean} Returns true if the value is an object otherwise returns false.\n */\nexport function isObject (val) {\n return val === Object(val);\n}\n\n/**\n * Checks whether the value is a string value.\n *\n * @param {*} val - The value to be checked.\n * @return {boolean} Returns true if the value is a string value otherwise returns false.\n */\nexport function isString (val) {\n return typeof val === 'string';\n}\n\n/**\n * Checks whether the value is callable.\n *\n * @param {*} val - The value to be checked.\n * @return {boolean} Returns true if the value is callable otherwise returns false.\n */\nexport function isCallable (val) {\n return typeof val === 'function';\n}\n\n/**\n * Returns the unique values from the input array.\n *\n * @param {Array} data - The input array.\n * @return {Array} Returns a new array of unique values.\n */\nexport function uniqueValues (data) {\n return [...new Set(data)];\n}\n\nexport const getUniqueId = () => `id-${new Date().getTime()}${Math.round(Math.random() * 10000)}`;\n\nconst unique = arr => ([...new Set(arr)]);\n\n/**\n * Gets the minimum difference between two consecutive numbers in an array.\n * @param {Array} arr Array of numbers\n * @param {number} index index of the value\n * @return {number} minimum difference between values\n */\nexport const getMinDiff = (arr, index) => {\n let diff;\n let uniqueVals;\n if (index !== undefined) {\n uniqueVals = unique(arr.map(d => d[index]));\n } else {\n uniqueVals = unique(arr);\n }\n if (uniqueVals.length > 1) {\n diff = Math.abs(uniqueVals[1] - uniqueVals[0]);\n for (let i = 2, len = uniqueVals.length; i < len; i++) {\n diff = Math.min(diff, Math.abs(uniqueVals[i] - uniqueVals[i - 1]));\n }\n } else {\n diff = uniqueVals[0];\n }\n\n return diff;\n};\n\n/**\n * Checks Whether two arrays have same content.\n *\n * @param {Array} arr1 - The first array.\n * @param {Array} arr2 - The 2nd array.\n * @return {boolean} Returns whether two array have same content.\n */\nexport function isArrEqual(arr1, arr2) {\n if (!isArray(arr1) || !isArray(arr2)) {\n return arr1 === arr2;\n }\n\n if (arr1.length !== arr2.length) {\n return false;\n }\n\n for (let i = 0; i < arr1.length; i++) {\n if (arr1[i] !== arr2[i]) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Checks Whether two arrays have same content.\n *\n * @param {Array} arr1 - The first array.\n * @param {Array} arr2 - The 2nd array.\n * @return {boolean} Returns whether two array have same content.\n */\nexport function formatNumber(val) {\n return val;\n}\n","import { FieldType } from './enums';\nimport { getUniqueId } from './utils';\n\nconst fieldStore = {\n data: {},\n\n createNamespace (fieldArr, name) {\n const dataId = name || getUniqueId();\n this.data[dataId] = {\n name: dataId,\n fields: fieldArr,\n fieldsObj () {\n const retObj = {};\n this.fields.forEach((field) => {\n retObj[field.name] = field;\n });\n return retObj;\n },\n getMeasure () {\n const retObj = {};\n this.fields.forEach((field) => {\n if (field.schema.type === FieldType.MEASURE) {\n retObj[field.name] = field;\n }\n });\n return retObj;\n },\n getDimension () {\n const retObj = {};\n this.fields.forEach((field) => {\n if (field.schema.type === FieldType.DIMENSION) {\n retObj[field.name] = field;\n }\n });\n return retObj;\n },\n };\n return this.data[dataId];\n },\n};\n\nexport default fieldStore;\n","/**\n * The wrapper class on top of the primitive value of a field.\n *\n * @todo Need to have support for StringValue, NumberValue, DateTimeValue\n * and GeoValue. These types should expose predicate API mostly.\n */\nclass Value {\n\n /**\n * Creates new Value instance.\n *\n * @param {*} val - the primitive value from the field cell.\n * @param {string | Field} field - The field from which the value belongs.\n */\n constructor (val, field) {\n Object.defineProperty(this, '_value', {\n enumerable: false,\n configurable: false,\n writable: false,\n value: val\n });\n\n this.field = field;\n }\n\n /**\n * Returns the field value.\n *\n * @return {*} Returns the current value.\n */\n get value () {\n return this._value;\n }\n\n /**\n * Converts to human readable string.\n *\n * @override\n * @return {string} Returns a human readable string of the field value.\n *\n */\n toString () {\n return String(this.value);\n }\n\n /**\n * Returns the value of the field.\n *\n * @override\n * @return {*} Returns the field value.\n */\n valueOf () {\n return this.value;\n }\n}\n\nexport default Value;\n","import { rowDiffsetIterator } from './row-diffset-iterator';\n\n/**\n * Creates bin f from the data and the supplied config.\n *\n * @param {Array} data - The input data.\n * @param {Object} config - The config object.\n * @param {number} config.binSize - The size of the bin.\n * @param {number} config.numOfBins - The number of bins to be created.\n * @return {Array} Returns an array of created bins.\n */\nexport function createBinnedFieldData (field, rowDiffset, config) {\n let { buckets, binCount, binSize, start } = config;\n let dataStore = [];\n let binnedData = [];\n let [min, max] = field.domain();\n let oriMax = max;\n let stops = [];\n let binEnd;\n let prevEndpoint;\n let mid;\n let range;\n\n // create dataStore with index according to rowDiffSet\n rowDiffsetIterator(rowDiffset, (i) => {\n dataStore.push({\n data: field.data[i],\n index: i\n });\n });\n\n // create buckets if buckets not given\n if (!buckets) {\n max += 1;\n binSize = binSize || (max - min) / binCount;\n\n const extraBinELm = (max - min) % binSize;\n if (!binCount && extraBinELm !== 0) {\n max = max + binSize - extraBinELm;\n }\n binEnd = min + binSize;\n while (binEnd <= max) {\n stops.push(binEnd);\n binEnd += binSize;\n }\n start = start || min;\n buckets = { start, stops };\n }\n\n // initialize intial bucket start\n prevEndpoint = buckets.start === 0 ? 0 : buckets.start || min;\n\n // mark each data in dataStore to respective buckets\n buckets.stops.forEach((endPoint) => {\n let tempStore = dataStore.filter(datum => datum.data >= prevEndpoint && datum.data < endPoint);\n tempStore.forEach((datum) => { binnedData[datum.index] = `${prevEndpoint}-${endPoint}`; });\n prevEndpoint = endPoint;\n });\n\n // create a bin for values less than start\n dataStore.filter(datum => datum.data < buckets.start)\n .forEach((datum) => { binnedData[datum.index] = `${min}-${buckets.start}`; });\n\n // create a bin for values more than end\n dataStore.filter(datum => datum.data >= buckets.stops[buckets.stops.length - 1])\n .forEach((datum) =>\n { binnedData[datum.index] = `${buckets.stops[buckets.stops.length - 1]}-${oriMax}`; });\n\n // create range and mid\n // append start to bucket marks\n buckets.stops.unshift(buckets.start);\n range = new Set(buckets.stops);\n\n // Add endpoints to buckets marks if not added\n if (min < buckets.start) { range.add(min); }\n if (oriMax > buckets.stops[buckets.stops.length - 1]) { range.add(oriMax); }\n\n range = [...range].sort((a, b) => a - b);\n mid = [];\n\n for (let i = 1; i < range.length; i++) {\n mid.push((range[i - 1] + range[i]) / 2);\n }\n return { data: binnedData, mid, range };\n}\n","/**\n * The helper function that returns an array of common schema\n * from two fieldStore instances.\n *\n * @param {FieldStore} fs1 - The first FieldStore instance.\n * @param {FieldStore} fs2 - The second FieldStore instance.\n * @return {Array} An array containing the common schema.\n */\nexport function getCommonSchema (fs1, fs2) {\n const retArr = [];\n const fs1Arr = [];\n fs1.fields.forEach((field) => {\n fs1Arr.push(field.schema.name);\n });\n fs2.fields.forEach((field) => {\n if (fs1Arr.indexOf(field.schema.name) !== -1) {\n retArr.push(field.schema.name);\n }\n });\n return retArr;\n}\n","export { DataFormat, FilteringMode } from '../enums';\n/**\n * The event name for data propagation.\n */\nexport const PROPAGATION = 'propagation';\n\n/**\n * The name of the unique row id column in DataModel.\n */\nexport const ROW_ID = '__id__';\n\n/**\n * The enums for operation names performed on DataModel.\n */\nexport const DM_DERIVATIVES = {\n SELECT: 'select',\n PROJECT: 'project',\n GROUPBY: 'group',\n COMPOSE: 'compose',\n CAL_VAR: 'calculatedVariable',\n BIN: 'bin'\n};\n\nexport const JOINS = {\n CROSS: 'cross',\n LEFTOUTER: 'leftOuter',\n RIGHTOUTER: 'rightOuter',\n NATURAL: 'natural',\n FULLOUTER: 'fullOuter'\n};\n\nexport const LOGICAL_OPERATORS = {\n AND: 'and',\n OR: 'or'\n};\n","import DataModel from '../datamodel';\nimport { extend2 } from '../utils';\nimport { getCommonSchema } from './get-common-schema';\nimport { rowDiffsetIterator } from './row-diffset-iterator';\nimport { JOINS } from '../constants';\nimport { prepareJoinData } from '../helper';\n/**\n * Default filter function for crossProduct.\n *\n * @return {boolean} Always returns true.\n */\nfunction defaultFilterFn() { return true; }\n\n/**\n * Implementation of cross product operation between two DataModel instances.\n * It internally creates the data and schema for the new DataModel.\n *\n * @param {DataModel} dataModel1 - The left DataModel instance.\n * @param {DataModel} dataModel2 - The right DataModel instance.\n * @param {Function} filterFn - The filter function which is used to filter the tuples.\n * @param {boolean} [replaceCommonSchema=false] - The flag if the common name schema should be there.\n * @return {DataModel} Returns The newly created DataModel instance from the crossProduct operation.\n */\nexport function crossProduct (dm1, dm2, filterFn, replaceCommonSchema = false, jointype = JOINS.CROSS) {\n const schema = [];\n const data = [];\n const applicableFilterFn = filterFn || defaultFilterFn;\n const dm1FieldStore = dm1.getFieldspace();\n const dm2FieldStore = dm2.getFieldspace();\n const dm1FieldStoreName = dm1FieldStore.name;\n const dm2FieldStoreName = dm2FieldStore.name;\n const name = `${dm1FieldStore.name}.${dm2FieldStore.name}`;\n const commonSchemaList = getCommonSchema(dm1FieldStore, dm2FieldStore);\n\n if (dm1FieldStoreName === dm2FieldStoreName) {\n throw new Error('DataModels must have different alias names');\n }\n // Here prepare the schema\n dm1FieldStore.fields.forEach((field) => {\n const tmpSchema = extend2({}, field.schema);\n if (commonSchemaList.indexOf(tmpSchema.name) !== -1 && !replaceCommonSchema) {\n tmpSchema.name = `${dm1FieldStore.name}.${tmpSchema.name}`;\n }\n schema.push(tmpSchema);\n });\n dm2FieldStore.fields.forEach((field) => {\n const tmpSchema = extend2({}, field.schema);\n if (commonSchemaList.indexOf(tmpSchema.name) !== -1) {\n if (!replaceCommonSchema) {\n tmpSchema.name = `${dm2FieldStore.name}.${tmpSchema.name}`;\n schema.push(tmpSchema);\n }\n } else {\n schema.push(tmpSchema);\n }\n });\n\n // Here prepare Data\n rowDiffsetIterator(dm1._rowDiffset, (i) => {\n let rowAdded = false;\n let rowPosition;\n rowDiffsetIterator(dm2._rowDiffset, (ii) => {\n const tuple = [];\n const userArg = {};\n userArg[dm1FieldStoreName] = {};\n userArg[dm2FieldStoreName] = {};\n dm1FieldStore.fields.forEach((field) => {\n tuple.push(field.data[i]);\n userArg[dm1FieldStoreName][field.name] = field.data[i];\n });\n dm2FieldStore.fields.forEach((field) => {\n if (!(commonSchemaList.indexOf(field.schema.name) !== -1 && replaceCommonSchema)) {\n tuple.push(field.data[ii]);\n }\n userArg[dm2FieldStoreName][field.name] = field.data[ii];\n });\n const dm1Fields = prepareJoinData(userArg[dm1FieldStoreName]);\n const dm2Fields = prepareJoinData(userArg[dm2FieldStoreName]);\n if (applicableFilterFn(dm1Fields, dm2Fields)) {\n const tupleObj = {};\n tuple.forEach((cellVal, iii) => {\n tupleObj[schema[iii].name] = cellVal;\n });\n if (rowAdded && JOINS.CROSS !== jointype) {\n data[rowPosition] = tupleObj;\n }\n else {\n data.push(tupleObj);\n rowAdded = true;\n rowPosition = i;\n }\n }\n else if ((jointype === JOINS.LEFTOUTER || jointype === JOINS.RIGHTOUTER) && !rowAdded) {\n const tupleObj = {};\n let len = dm1FieldStore.fields.length - 1;\n tuple.forEach((cellVal, iii) => {\n if (iii <= len) {\n tupleObj[schema[iii].name] = cellVal;\n }\n else {\n tupleObj[schema[iii].name] = null;\n }\n });\n rowAdded = true;\n rowPosition = i;\n data.push(tupleObj);\n }\n });\n });\n\n return new DataModel(data, schema, { name });\n}\n","/**\n * The default sort function.\n *\n * @param {*} a - The first value.\n * @param {*} b - The second value.\n * @return {number} Returns the comparison result e.g. 1 or 0 or -1.\n */\nfunction defSortFn (a, b) {\n const a1 = `${a}`;\n const b1 = `${b}`;\n if (a1 < b1) {\n return -1;\n }\n if (a1 > b1) {\n return 1;\n }\n return 0;\n}\n\n/**\n * The helper function for merge sort which creates the sorted array\n * from the two halves of the input array.\n *\n * @param {Array} arr - The target array which needs to be merged.\n * @param {number} lo - The starting index of the first array half.\n * @param {number} mid - The ending index of the first array half.\n * @param {number} hi - The ending index of the second array half.\n * @param {Function} sortFn - The sort function.\n */\nfunction merge (arr, lo, mid, hi, sortFn) {\n const mainArr = arr;\n const auxArr = [];\n for (let i = lo; i <= hi; i += 1) {\n auxArr[i] = mainArr[i];\n }\n let a = lo;\n let b = mid + 1;\n\n for (let i = lo; i <= hi; i += 1) {\n if (a > mid) {\n mainArr[i] = auxArr[b];\n b += 1;\n } else if (b > hi) {\n mainArr[i] = auxArr[a];\n a += 1;\n } else if (sortFn(auxArr[a], auxArr[b]) <= 0) {\n mainArr[i] = auxArr[a];\n a += 1;\n } else {\n mainArr[i] = auxArr[b];\n b += 1;\n }\n }\n}\n\n/**\n * The helper function for merge sort which would be called\n * recursively for sorting the array halves.\n *\n * @param {Array} arr - The target array which needs to be sorted.\n * @param {number} lo - The starting index of the array half.\n * @param {number} hi - The ending index of the array half.\n * @param {Function} sortFn - The sort function.\n * @return {Array} Returns the target array itself.\n */\nfunction sort (arr, lo, hi, sortFn) {\n if (hi === lo) { return arr; }\n\n const mid = lo + Math.floor((hi - lo) / 2);\n sort(arr, lo, mid, sortFn);\n sort(arr, mid + 1, hi, sortFn);\n merge(arr, lo, mid, hi, sortFn);\n\n return arr;\n}\n\n/**\n * The implementation of merge sort.\n * It is used in DataModel for stable sorting as it is not sure\n * what the sorting algorithm used by browsers is stable or not.\n *\n * @param {Array} arr - The target array which needs to be sorted.\n * @param {Function} [sortFn=defSortFn] - The sort function.\n * @return {Array} Returns the input array itself in sorted order.\n */\nexport function mergeSort (arr, sortFn = defSortFn) {\n if (arr.length > 1) {\n sort(arr, 0, arr.length - 1, sortFn);\n }\n return arr;\n}\n","import { FieldType, DimensionSubtype } from '../enums';\nimport { rowDiffsetIterator } from './row-diffset-iterator';\nimport { mergeSort } from './merge-sort';\nimport { fieldInSchema } from '../helper';\nimport { isCallable, isArray, } from '../utils';\n/**\n * Generates the sorting functions to sort the data of a DataModel instance\n * according to the input data type.\n *\n * @param {string} dataType - The data type e.g. 'measure', 'datetime' etc.\n * @param {string} sortType - The sorting order i.e. 'asc' or 'desc'.\n * @param {integer} index - The index of the data which will be sorted.\n * @return {Function} Returns the the sorting function.\n */\nfunction getSortFn (dataType, sortType, index) {\n let retFunc;\n switch (dataType) {\n case FieldType.MEASURE:\n case DimensionSubtype.TEMPORAL:\n if (sortType === 'desc') {\n retFunc = (a, b) => b[index] - a[index];\n } else {\n retFunc = (a, b) => a[index] - b[index];\n }\n break;\n default:\n retFunc = (a, b) => {\n const a1 = `${a[index]}`;\n const b1 = `${b[index]}`;\n if (a1 < b1) {\n return sortType === 'desc' ? 1 : -1;\n }\n if (a1 > b1) {\n return sortType === 'desc' ? -1 : 1;\n }\n return 0;\n };\n }\n return retFunc;\n}\n\n/**\n * Groups the data according to the specified target field.\n *\n * @param {Array} data - The input data array.\n * @param {number} fieldIndex - The target field index within schema array.\n * @return {Array} Returns an array containing the grouped data.\n */\nfunction groupData(data, fieldIndex) {\n const hashMap = new Map();\n const groupedData = [];\n\n data.forEach((datum) => {\n const fieldVal = datum[fieldIndex];\n if (hashMap.has(fieldVal)) {\n groupedData[hashMap.get(fieldVal)][1].push(datum);\n } else {\n groupedData.push([fieldVal, [datum]]);\n hashMap.set(fieldVal, groupedData.length - 1);\n }\n });\n\n return groupedData;\n}\n\n/**\n * Creates the argument value used for sorting function when sort is done\n * with another fields.\n *\n * @param {Array} groupedDatum - The grouped datum for a single dimension field value.\n * @param {Array} targetFields - An array of the sorting fields.\n * @param {Array} targetFieldDetails - An array of the sorting field details in schema.\n * @return {Object} Returns an object containing the value of sorting fields and the target field name.\n */\nfunction createSortingFnArg(groupedDatum, targetFields, targetFieldDetails) {\n const arg = {\n label: groupedDatum[0]\n };\n\n targetFields.reduce((acc, next, idx) => {\n acc[next] = groupedDatum[1].map(datum => datum[targetFieldDetails[idx].index]);\n return acc;\n }, arg);\n\n return arg;\n}\n\n/**\n * Sorts the data before return in dataBuilder.\n *\n * @param {Object} dataObj - An object containing the data and schema.\n * @param {Array} sortingDetails - An array containing the sorting configs.\n */\nfunction sortData(dataObj, sortingDetails) {\n const { data, schema } = dataObj;\n let fieldName;\n let sortMeta;\n let fDetails;\n let i = sortingDetails.length - 1;\n\n for (; i >= 0; i--) {\n fieldName = sortingDetails[i][0];\n sortMeta = sortingDetails[i][1];\n fDetails = fieldInSchema(schema, fieldName);\n\n if (!fDetails) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n if (isCallable(sortMeta)) {\n // eslint-disable-next-line no-loop-func\n mergeSort(data, (a, b) => sortMeta(a[fDetails.index], b[fDetails.index]));\n } else if (isArray(sortMeta)) {\n const groupedData = groupData(data, fDetails.index);\n const sortingFn = sortMeta[sortMeta.length - 1];\n const targetFields = sortMeta.slice(0, sortMeta.length - 1);\n const targetFieldDetails = targetFields.map(f => fieldInSchema(schema, f));\n\n groupedData.forEach((groupedDatum) => {\n groupedDatum.push(createSortingFnArg(groupedDatum, targetFields, targetFieldDetails));\n });\n\n mergeSort(groupedData, (a, b) => {\n const m = a[2];\n const n = b[2];\n return sortingFn(m, n);\n });\n\n // Empty the array\n data.length = 0;\n groupedData.forEach((datum) => {\n data.push(...datum[1]);\n });\n } else {\n sortMeta = String(sortMeta).toLowerCase() === 'desc' ? 'desc' : 'asc';\n mergeSort(data, getSortFn(fDetails.type, sortMeta, fDetails.index));\n }\n }\n\n dataObj.uids = [];\n data.forEach((value) => {\n dataObj.uids.push(value.pop());\n });\n}\n\n\n/**\n * Builds the actual data array.\n *\n * @param {Array} fieldStore - An array of field.\n * @param {string} rowDiffset - A string consisting of which rows to be included eg. '0-2,4,6';\n * @param {string} colIdentifier - A string consisting of the details of which column\n * to be included eg 'date,sales,profit';\n * @param {Object} sortingDetails - An object containing the sorting details of the DataModel instance.\n * @param {Object} options - The options required to create the type of the data.\n * @return {Object} Returns an object containing the multidimensional array and the relative schema.\n */\nexport function dataBuilder (fieldStore, rowDiffset, colIdentifier, sortingDetails, options) {\n const defOptions = {\n addUid: false,\n columnWise: false\n };\n options = Object.assign({}, defOptions, options);\n\n const retObj = {\n schema: [],\n data: [],\n uids: []\n };\n const addUid = options.addUid;\n const reqSorting = sortingDetails && sortingDetails.length > 0;\n // It stores the fields according to the colIdentifier argument\n const tmpDataArr = [];\n // Stores the fields according to the colIdentifier argument\n const colIArr = colIdentifier.split(',');\n\n colIArr.forEach((colName) => {\n for (let i = 0; i < fieldStore.length; i += 1) {\n if (fieldStore[i].name === colName) {\n tmpDataArr.push(fieldStore[i]);\n break;\n }\n }\n });\n\n // Inserts the schema to the schema object\n tmpDataArr.forEach((field) => {\n /** @todo Need to use extend2 here otherwise user can overwrite the schema. */\n retObj.schema.push(field.schema);\n });\n\n if (addUid) {\n retObj.schema.push({\n name: 'uid',\n type: 'identifier'\n });\n }\n\n rowDiffsetIterator(rowDiffset, (i) => {\n retObj.data.push([]);\n const insertInd = retObj.data.length - 1;\n let start = 0;\n tmpDataArr.forEach((field, ii) => {\n retObj.data[insertInd][ii + start] = field.data[i];\n });\n if (addUid) {\n retObj.data[insertInd][tmpDataArr.length] = i;\n }\n // Creates an array of unique identifiers for each row\n retObj.uids.push(i);\n\n // If sorting needed then there is the need to expose the index\n // mapping from the old index to its new index\n if (reqSorting) { retObj.data[insertInd].push(i); }\n });\n\n // Handles the sort functionality\n if (reqSorting) {\n sortData(retObj, sortingDetails);\n }\n\n if (options.columnWise) {\n const tmpData = Array(...Array(retObj.schema.length)).map(() => []);\n retObj.data.forEach((tuple) => {\n tuple.forEach((data, i) => {\n tmpData[i].push(data);\n });\n });\n retObj.data = tmpData;\n }\n\n return retObj;\n}\n","import DataModel from '../datamodel';\nimport { extend2 } from '../utils';\nimport { rowDiffsetIterator } from './row-diffset-iterator';\nimport { isArrEqual } from '../utils/helper';\n\n/**\n * Performs the union operation between two dm instances.\n *\n * @todo Fix the conflicts between union and difference terminology here.\n *\n * @param {dm} dm1 - The first dm instance.\n * @param {dm} dm2 - The second dm instance.\n * @return {dm} Returns the newly created dm after union operation.\n */\nexport function difference (dm1, dm2) {\n const hashTable = {};\n const schema = [];\n const schemaNameArr = [];\n const data = [];\n const dm1FieldStore = dm1.getFieldspace();\n const dm2FieldStore = dm2.getFieldspace();\n const dm1FieldStoreFieldObj = dm1FieldStore.fieldsObj();\n const dm2FieldStoreFieldObj = dm2FieldStore.fieldsObj();\n const name = `${dm1FieldStore.name} union ${dm2FieldStore.name}`;\n\n // For union the columns should match otherwise return a clone of the dm1\n if (!isArrEqual(dm1._colIdentifier.split(',').sort(), dm2._colIdentifier.split(',').sort())) {\n return null;\n }\n\n // Prepare the schema\n (dm1._colIdentifier.split(',')).forEach((fieldName) => {\n const field = dm1FieldStoreFieldObj[fieldName];\n schema.push(extend2({}, field.schema));\n schemaNameArr.push(field.schema.name);\n });\n\n /**\n * The helper function to create the data.\n *\n * @param {dm} dm - The dm instance for which the data is inserted.\n * @param {Object} fieldsObj - The fieldStore object format.\n * @param {boolean} addData - If true only tuple will be added to the data.\n */\n function prepareDataHelper(dm, fieldsObj, addData) {\n rowDiffsetIterator(dm._rowDiffset, (i) => {\n const tuple = {};\n let hashData = '';\n schemaNameArr.forEach((schemaName) => {\n const value = fieldsObj[schemaName].data[i];\n hashData += `-${value}`;\n tuple[schemaName] = value;\n });\n if (!hashTable[hashData]) {\n if (addData) { data.push(tuple); }\n hashTable[hashData] = true;\n }\n });\n }\n\n // Prepare the data\n prepareDataHelper(dm2, dm2FieldStoreFieldObj, false);\n prepareDataHelper(dm1, dm1FieldStoreFieldObj, true);\n\n return new DataModel(data, schema, { name });\n}\n\n","/**\n * Reducer function that takes care about the sum aggregation\n * @param {Array} arr array of values\n * @return {number} sum of the array\n */\nfunction sum (arr) {\n let allNulls = true;\n const isNestedArray = arr[0] instanceof Array;\n const sumVal = arr.reduce((carry, a) => {\n if (isNestedArray) {\n return carry.map((x, i) => x + a[i]);\n }\n allNulls = allNulls && (a === null);\n return carry + a;\n }, isNestedArray ? Array(...Array(arr[0].length)).map(() => 0) : 0);\n return allNulls ? null : sumVal;\n}\n\n/**\n * reducer function that takes care about the mean aggregation\n * @param {Array} arr array of values\n * @return {number} mean of the array\n */\nfunction avg (arr) {\n const isNestedArray = arr[0] instanceof Array;\n const len = arr.length || 1;\n const arrSum = sum(arr);\n if (isNestedArray) {\n return arrSum.map(x => x / len);\n }\n return arrSum === null ? null : arrSum / len;\n}\n\n/**\n * reducer function that gives the min value\n * @param {Array} arr array of values\n * @return {number} min of the array\n */\nfunction min (arr) {\n const isNestedArray = arr[0] instanceof Array;\n if (isNestedArray) {\n return arr.reduce((carry, a) => carry.map((x, i) => Math.min(x, a[i])),\n Array(...Array(arr[0].length)).map(() => Infinity));\n }\n return arr.every(d => d === null) ? null : Math.min(...arr);\n}\n\n/**\n * reducer function that gives the max value\n * @param {Array} arr array of values\n * @return {number} max of the array\n */\nfunction max (arr) {\n const isNestedArray = arr[0] instanceof Array;\n if (isNestedArray) {\n return arr.reduce((carry, a) => carry.map((x, i) => Math.max(x, a[i])),\n Array(...Array(arr[0].length)).map(() => -Infinity));\n }\n return arr.every(d => d === null) ? null : Math.max(...arr);\n}\n\n/**\n * reducer function that gives the first value\n * @param {Array} arr array of values\n * @return {number} first value of the array\n */\nfunction first (arr) {\n return arr[0];\n}\n\n/**\n * reducer function that gives the last value\n * @param {Array} arr array of values\n * @return {number} last value of the array\n */\nfunction last (arr) {\n return arr[arr.length - 1];\n}\n\n/**\n * reducer function that gives the count value\n * @param {Array} arr array of values\n * @return {number} count of the array\n */\nfunction count (arr) {\n const isNestedArray = arr[0] instanceof Array;\n const len = arr.length;\n if (isNestedArray) {\n return Array(...Array(arr[0].length)).map(() => len);\n }\n return len;\n}\n\n/**\n * Calculates the variance of the input array.\n *\n * @param {Array.} arr - The input array.\n * @return {number} Returns the variance of the input array.\n */\nfunction variance (arr) {\n let mean = avg(arr);\n return avg(arr.map(num => (num - mean) ** 2));\n}\n\n/**\n * Calculates the square root of the variance of the input array.\n *\n * @param {Array.} arr - The input array.\n * @return {number} Returns the square root of the variance.\n */\nfunction std (arr) {\n return Math.sqrt(variance(arr));\n}\n\n\nconst fnList = {\n sum,\n avg,\n min,\n max,\n first,\n last,\n count,\n std\n};\n\nconst defaultReducerName = 'sum';\n\nexport {\n defaultReducerName,\n sum as defReducer,\n fnList,\n};\n","import { defReducer, fnList } from '../operator';\n\n/**\n * A page level storage which stores, registers, unregisters reducers for all the datamodel instances. There is only one\n * reducer store available in a page. All the datamodel instances receive same instance of reducer store. DataModel\n * out of the box provides handful of {@link reducer | reducers} which can be used as reducer funciton.\n *\n * @public\n * @namespace DataModel\n */\nclass ReducerStore {\n constructor () {\n this.store = new Map();\n this.store.set('defReducer', defReducer);\n\n Object.entries(fnList).forEach((key) => {\n this.store.set(key[0], key[1]);\n });\n }\n\n /**\n * Changes the `defaultReducer` globally. For all the fields which does not have `defAggFn` mentioned in schema, the\n * value of `defaultReducer` is used for aggregation.\n *\n * @public\n *\n * @param {string} [reducer='sum'] name of the default reducer. It picks up the definition from store by doing name\n * lookup. If no name is found then it takes `sum` as the default reducer.\n *\n * @return {ReducerStore} instance of the singleton store in page.\n */\n defaultReducer (...params) {\n if (params.length) {\n let reducer = params[0];\n if (typeof reducer === 'function') {\n this.store.set('defReducer', reducer);\n } else if (typeof reducer === 'string') {\n if (Object.keys(fnList).indexOf(reducer) !== -1) {\n this.store.set('defReducer', fnList[reducer]);\n }\n }\n return this;\n }\n\n return this.store.get('defReducer');\n }\n\n /**\n *\n * Registers a {@link reducer | reducer}.\n * A {@link reducer | reducer} has to be registered before it is used.\n *\n * @example\n * // find the mean squared value of a given set\n * const reducerStore = DataModel.Reducers();\n *\n * reducers.register('meanSquared', (arr) => {\n * const squaredVal = arr.map(item => item * item);\n * let sum = 0;\n * for (let i = 0, l = squaredVal.length; i < l; i++) {\n * sum += squaredVal[i++];\n * }\n *\n * return sum;\n * })\n *\n * // datamodel (dm) is already prepared with cars.json\n * const dm1 = dm.groupBy(['origin'], {\n * accleration: 'meanSquared'\n * });\n *\n * @public\n *\n * @param {string} name formal name for a reducer. If the given name already exists in store it is overridden by new\n * definition.\n * @param {Function} reducer definition of {@link reducer} function.\n *\n * @return {Function} function for unregistering the reducer.\n */\n register (name, reducer) {\n if (typeof name === 'string' && typeof reducer === 'function') {\n this.store.set(name, reducer);\n }\n\n return () => { this.__unregister(name); };\n }\n\n __unregister (name) {\n if (this.store.has(name)) {\n this.store.delete(name);\n }\n }\n\n resolve (name) {\n if (name instanceof Function) {\n return name;\n }\n return this.store.get(name);\n }\n}\n\nconst reducerStore = (function () {\n let store = null;\n\n function getStore () {\n if (store === null) {\n store = new ReducerStore();\n }\n return store;\n }\n return getStore();\n}());\n\nexport default reducerStore;\n","import { extend2 } from '../utils';\nimport { rowDiffsetIterator } from './row-diffset-iterator';\nimport DataModel from '../export';\nimport reducerStore from '../utils/reducer-store';\n\n/**\n * This function sanitize the user given field and return a common Array structure field\n * list\n * @param {DataModel} dataModel the dataModel operating on\n * @param {Array} fieldArr user input of field Array\n * @return {Array} arrays of field name\n */\nfunction getFieldArr (dataModel, fieldArr) {\n const retArr = [];\n const fieldStore = dataModel.getPartialFieldspace();\n const dimensions = fieldStore.getDimension();\n const measures = fieldStore.getMeasure();\n\n Object.entries(dimensions).forEach(([key]) => {\n if (fieldArr && fieldArr.length) {\n if (fieldArr.indexOf(key) !== -1) {\n retArr.push(key);\n }\n } else {\n retArr.push(key);\n }\n });\n\n Object.entries(measures).forEach(([key]) => {\n if (measures[key].subType() === 'discrete') {\n if (fieldArr && fieldArr.length) {\n if (fieldArr.indexOf(key) !== -1) {\n retArr.push(key);\n }\n } else {\n retArr.push(key);\n }\n }\n });\n return retArr;\n}\n\n/**\n * This sanitize the reducer provide by the user and create a common type of object.\n * user can give function Also\n * @param {DataModel} dataModel dataModel to worked on\n * @param {Object|function} [reducers={}] reducer provided by the users\n * @return {Object} object containing reducer function for every measure\n */\nfunction getReducerObj (dataModel, reducers = {}) {\n const retObj = {};\n const pReducers = reducers;\n const fieldStore = dataModel.getPartialFieldspace();\n const measures = fieldStore.getMeasure();\n let reducer = reducerStore.defaultReducer();\n if (typeof reducers === 'function') {\n reducer = reducers;\n }\n Object.entries(measures).forEach(([key]) => {\n if (typeof reducers[key] === 'string') {\n pReducers[key] = reducerStore.resolve(pReducers[key]) ? reducerStore.resolve(pReducers[key]) : reducer;\n }\n if (typeof reducers[key] !== 'function') {\n pReducers[key] = undefined;\n }\n retObj[key] = pReducers[key] || reducerStore.resolve(measures[key].defAggFn()) || reducer;\n });\n return retObj;\n}\n\n/**\n * main function which perform the group-by operations which reduce the measures value is the\n * fields are common according to the reducer function provided\n * @param {DataModel} dataModel the dataModel to worked\n * @param {Array} fieldArr fields according to which the groupby should be worked\n * @param {Object|Function} reducers reducers function\n * @param {DataModel} existingDataModel Existing datamodel instance\n * @return {DataModel} new dataModel with the group by\n */\nfunction groupBy (dataModel, fieldArr, reducers, existingDataModel) {\n const sFieldArr = getFieldArr(dataModel, fieldArr);\n const reducerObj = getReducerObj(dataModel, reducers);\n const fieldStore = dataModel.getPartialFieldspace();\n const fieldStoreObj = fieldStore.fieldsObj();\n const dbName = fieldStore.name;\n const dimensionArr = [];\n const measureArr = [];\n const schema = [];\n const hashMap = {};\n const data = [];\n let newDataModel;\n // Prepare the schema\n Object.entries(fieldStoreObj).forEach(([key, value]) => {\n if (sFieldArr.indexOf(key) !== -1 || reducerObj[key]) {\n schema.push(extend2({}, value.schema));\n if (value.schema.type === 'measure' && value.schema.subtype !== 'discrete') {\n measureArr.push(key);\n } else if (value.schema.type === 'dimension' || value.schema.subtype === 'discrete') {\n dimensionArr.push(key);\n }\n }\n });\n // Prepare the data\n let rowCount = 0;\n rowDiffsetIterator(dataModel._rowDiffset, (i) => {\n let hash = '';\n dimensionArr.forEach((_) => {\n hash = `${hash}-${fieldStoreObj[_].data[i]}`;\n });\n if (hashMap[hash] === undefined) {\n hashMap[hash] = rowCount;\n data.push({});\n dimensionArr.forEach((_) => {\n data[rowCount][_] = fieldStoreObj[_].data[i];\n });\n measureArr.forEach((_) => {\n data[rowCount][_] = [fieldStoreObj[_].data[i]];\n });\n rowCount += 1;\n } else {\n measureArr.forEach((_) => {\n data[hashMap[hash]][_].push(fieldStoreObj[_].data[i]);\n });\n }\n });\n // reduction\n data.forEach((row) => {\n const tuple = row;\n measureArr.forEach((_) => {\n tuple[_] = reducerObj[_](row[_]);\n });\n });\n if (existingDataModel) {\n existingDataModel.__calculateFieldspace();\n newDataModel = existingDataModel;\n }\n else {\n newDataModel = new DataModel(data, schema, { name: dbName });\n }\n return newDataModel;\n}\n\nexport { groupBy, getFieldArr, getReducerObj };\n","import { getCommonSchema } from './get-common-schema';\n\n/**\n * The filter function used in natural join.\n * It generates a function that will have the logic to join two\n * DataModel instances by the process of natural join.\n *\n * @param {DataModel} dm1 - The left DataModel instance.\n * @param {DataModel} dm2 - The right DataModel instance.\n * @return {Function} Returns a function that is used in cross-product operation.\n */\nexport function naturalJoinFilter (dm1, dm2) {\n const dm1FieldStore = dm1.getFieldspace();\n const dm2FieldStore = dm2.getFieldspace();\n // const dm1FieldStoreName = dm1FieldStore.name;\n // const dm2FieldStoreName = dm2FieldStore.name;\n const commonSchemaArr = getCommonSchema(dm1FieldStore, dm2FieldStore);\n\n return (dm1Fields, dm2Fields) => {\n let retainTuple = true;\n commonSchemaArr.forEach((fieldName) => {\n if (dm1Fields[fieldName].value ===\n dm2Fields[fieldName].value && retainTuple) {\n retainTuple = true;\n } else {\n retainTuple = false;\n }\n });\n return retainTuple;\n };\n}\n","import DataModel from '../export';\nimport { extend2 } from '../utils';\nimport { rowDiffsetIterator } from './row-diffset-iterator';\nimport { isArrEqual } from '../utils/helper';\n/**\n * Performs the union operation between two dm instances.\n *\n * @param {dm} dm1 - The first dm instance.\n * @param {dm} dm2 - The second dm instance.\n * @return {dm} Returns the newly created dm after union operation.\n */\nexport function union (dm1, dm2) {\n const hashTable = {};\n const schema = [];\n const schemaNameArr = [];\n const data = [];\n const dm1FieldStore = dm1.getFieldspace();\n const dm2FieldStore = dm2.getFieldspace();\n const dm1FieldStoreFieldObj = dm1FieldStore.fieldsObj();\n const dm2FieldStoreFieldObj = dm2FieldStore.fieldsObj();\n const name = `${dm1FieldStore.name} union ${dm2FieldStore.name}`;\n\n // For union the columns should match otherwise return a clone of the dm1\n if (!isArrEqual(dm1._colIdentifier.split(',').sort(), dm2._colIdentifier.split(',').sort())) {\n return null;\n }\n\n // Prepare the schema\n (dm1._colIdentifier.split(',')).forEach((fieldName) => {\n const field = dm1FieldStoreFieldObj[fieldName];\n schema.push(extend2({}, field.schema));\n schemaNameArr.push(field.schema.name);\n });\n\n /**\n * The helper function to create the data.\n *\n * @param {dm} dm - The dm instance for which the data is inserted.\n * @param {Object} fieldsObj - The fieldStore object format.\n */\n function prepareDataHelper (dm, fieldsObj) {\n rowDiffsetIterator(dm._rowDiffset, (i) => {\n const tuple = {};\n let hashData = '';\n schemaNameArr.forEach((schemaName) => {\n const value = fieldsObj[schemaName].data[i];\n hashData += `-${value}`;\n tuple[schemaName] = value;\n });\n if (!hashTable[hashData]) {\n data.push(tuple);\n hashTable[hashData] = true;\n }\n });\n }\n\n // Prepare the data\n prepareDataHelper(dm1, dm1FieldStoreFieldObj);\n prepareDataHelper(dm2, dm2FieldStoreFieldObj);\n\n return new DataModel(data, schema, { name });\n}\n","import { crossProduct } from './cross-product';\nimport { JOINS } from '../constants';\nimport { union } from './union';\n\n\nexport function leftOuterJoin (dataModel1, dataModel2, filterFn) {\n return crossProduct(dataModel1, dataModel2, filterFn, false, JOINS.LEFTOUTER);\n}\n\nexport function rightOuterJoin (dataModel1, dataModel2, filterFn) {\n return crossProduct(dataModel2, dataModel1, filterFn, false, JOINS.RIGHTOUTER);\n}\n\nexport function fullOuterJoin (dataModel1, dataModel2, filterFn) {\n return union(leftOuterJoin(dataModel1, dataModel2, filterFn), rightOuterJoin(dataModel1, dataModel2, filterFn));\n}\n","import { extend2 } from '../utils';\n\n /**\n * The base class for every field type.\n * It provides some common functionalities.\n */\nclass PartialField {\n\n /**\n * Sets basic setups to each Field instance.\n *\n * @param {string} name - The name or identifier of the field.\n * @param {Array} data - The data array.\n * @param {Object} schema - The schema of the data type.\n */\n constructor(name, data, schema) {\n this.name = name;\n this.data = data || [];\n this.schema = schema;\n this.fieldDescription = schema.description;\n this.fieldType = schema.type;\n this.sanitize();\n }\n\n /**\n * Sanitizes the field data.\n *\n * @return {PartialField} - Returns the instance of the current context for chaining.\n */\n sanitize () {\n this.data = this.data.map(d => this.parsed(this.parse(d)));\n return this;\n }\n\n /**\n * The post parsing hook for field instance.\n *\n * @param {*} val - The value to be parsed.\n * @return {*} Returns the parsed value.\n */\n parsed (val) {\n return val;\n }\n\n /**\n * Generates and returns the domain for the field.\n *\n * @abstract\n */\n domain() {\n throw new Error('Not yet implemented!');\n }\n\n subType() {\n return null;\n }\n\n\n /**\n * Parse the input value before using.\n *\n * @abstract\n */\n parse () {\n throw new Error('Not yet implemented!');\n }\n\n /**\n * Creates brand new copy of current field instance. To avoid optimization issue\n * pass the required data otherwise current data would be copied which might\n * be expensive.\n *\n * @param {Array} data - The input data, if provided current data will not be cloned.\n * @return {PartialField} Returns the cloned field instance.\n */\n clone(data) {\n data = data || extend2([], this.data);\n const schema = extend2({}, this.schema);\n // Here call the constructor to create an instance of\n // the current field class type e.g. Measure, Dimension etc.\n return new this.constructor(this.name, data, schema);\n }\n\n /**\n * @return {string} Name of the field\n */\n fieldName() {\n return this.name;\n }\n\n /**\n * @return {string} Type of the field\n */\n type() {\n return this.fieldType;\n }\n\n /**\n * @return {description} Name of the field\n */\n description() {\n return this.fieldDescription;\n }\n}\n\nexport default PartialField;\n","import PartialField from './partial-field';\nimport { generateMeasureDomain, formatNumber } from '../utils';\nimport { defaultReducerName } from '../operator/group-by-function';\n\n/**\n * Represents measure field type.\n *\n * @extends PartialField\n */\nclass Measure extends PartialField {\n\n /**\n * Creates new Measure field instance.\n *\n * @param {string} name - The name of the field.\n * @param {Array} data - An array containing the field data.\n * @param {Object} schema - The schema for the field.\n */\n constructor(name, data, schema) {\n super(name, data, schema);\n this.fieldUnit = schema.unit;\n this.fieldScale = schema.scale;\n this.fieldDefAggFn = schema.defAggFn || defaultReducerName;\n this.fieldNumberformat = schema.numberFormat instanceof Function ? schema.numberFormat : formatNumber;\n }\n\n /**\n * Returns the domain for the measure field.\n *\n * @override\n * @return {Array} Returns min and max values from measure values.\n */\n domain() {\n return generateMeasureDomain(this.data);\n }\n\n /**\n * A hook which is called for every entry(cell) of the column.\n *\n * @todo Fix the null data e.g. NaN value.\n *\n * @param {*} val - The current entry present in the column while iteration.\n * @return {number | null} Returns the parsed number value of content of cell or null.\n */\n parse (val) {\n val = parseFloat(val, 10);\n return Number.isNaN(val) ? null : val;\n }\n\n /**\n * Getter for unit value of the field.\n *\n * @return {string} Returns unit of the field.\n */\n unit() {\n return this.fieldUnit;\n }\n\n /**\n * Getter for scale value of the field.\n *\n * @return {string} Returns scale of the field.\n */\n scale() {\n return this.fieldScale;\n }\n\n /**\n * Getter for number format value of the field.\n *\n * @return {string} Returns number format of the field.\n */\n numberFormat() {\n const formatter = this.fieldNumberformat;\n return val => formatter(val);\n }\n\n /**\n * Getter for aggregation function of the field.\n *\n * @return {Function} Returns aggregation function of the field.\n */\n defAggFn() {\n return this.fieldDefAggFn;\n }\n}\n\nexport default Measure;\n","/**\n * Generates domain for measure field.\n *\n * @param {Array} data - The array of data.\n * @return {Array} Returns the measure domain.\n */\nexport default (data) => {\n let min = Number.POSITIVE_INFINITY;\n let max = Number.NEGATIVE_INFINITY;\n\n data.forEach((d) => {\n if (d < min) {\n min = d;\n }\n if (d > max) {\n max = d;\n }\n });\n\n return [min, max];\n};\n","import PartialField from './partial-field';\nimport { uniqueValues } from '../utils';\n\n/**\n * Represents dimension field type.\n *\n * @extends PartialField\n */\nclass Dimension extends PartialField {\n\n /**\n * Returns the domain for the dimension field.\n *\n * @override\n * @return {Array} Returns the unique values from dimension values.\n */\n domain() {\n return uniqueValues(this.data);\n }\n\n /**\n * A hook which is called for every entry(cell) of the column.\n *\n * @todo Fix the null data e.g. undefined or null etc.\n *\n * @param {*} val - The current entry present in the column while iteration.\n * @return {string} Returns the string representation of the value.\n */\n parse (val) {\n val = (val === undefined || val === null) ? '' : val.toString();\n return val.trim();\n }\n\n /**\n * Saves the cardinality of the dimensional values after parsing the data.\n *\n * @param {string} val - The parsed value.\n * @return {string} Returns the input val.\n */\n parsed (val) {\n this._unique = this._unique || {};\n const unique = this._unique;\n if (val in unique) {\n unique[val]++;\n } else {\n unique[val] = 1;\n }\n return val;\n }\n}\n\nexport default Dimension;\n","import { DimensionSubtype } from '../enums';\nimport Dimension from './dimension';\n\n/**\n * Represents categorical field subtype.\n *\n * @extends Dimension\n */\nclass Categorical extends Dimension {\n\n /**\n * Creates new Categorical field instance.\n *\n * @param {string} name - The name of the field.\n * @param {Array} data - An array containing the field data.\n * @param {Object} schema - The schema for the field.\n */\n constructor(name, data, schema) {\n super(name, data, schema);\n this.subtype = DimensionSubtype.CATEGORICAL;\n }\n\n /**\n * Getter for subType value of the field.\n *\n * @return {string} Returns subType of the field.\n */\n subType() {\n return this.subtype;\n }\n}\n\nexport default Categorical;\n","import { DimensionSubtype } from '../enums';\nimport Dimension from './dimension';\nimport { DateTimeFormatter, getMinDiff } from '../utils';\n\n\n/**\n * Represents datetime field subtype.\n *\n * @extends Dimension\n */\nclass DateTime extends Dimension {\n\n /**\n * Creates new DateTime field instance.\n *\n * @param {string} name - The name of the field.\n * @param {Array} data - An array containing the field data.\n * @param {Object} schema - The schema for the field.\n */\n constructor(name, data, schema) {\n super(name, data, schema);\n this.subtype = DimensionSubtype.TEMPORAL;\n this.minDiff = getMinDiff(this.data);\n }\n\n /**\n * Getter for subType value of the field.\n *\n * @return {string} Returns subType of the field.\n */\n subType() {\n return this.subtype;\n }\n\n getMinDiff () {\n return this.minDiff;\n }\n /**\n * A hook which is called for every entry(cell) of the column.\n *\n * @param {*} val - The current entry present in the column while iteration.\n * @return {number} Returns the total timestamps in millisecond.\n */\n parse(val) {\n if (this.schema.format) {\n this._dtf = this._dtf || new DateTimeFormatter(this.schema.format);\n return this._dtf.getNativeDate(val).getTime();\n }\n\n // If format is not present then it means the value is such that the it could be directly passed to date\n // constructor\n return +new Date(val);\n }\n}\n\nexport default DateTime;\n","import Measure from './measure';\n\n/**\n * Represents categorical field subtype.\n *\n * @extends Measure\n */\nclass DiscreteMeasure extends Measure {\n constructor(name, data, schema, bin) {\n super(name, data, schema);\n this.bin = bin;\n this.subtype = 'discrete';\n }\n\n /**\n * A hook which is called for every entry(cell) of the column.\n *\n * @todo Fix the null data e.g. undefined or null etc.\n *\n * @param {*} val - The current entry present in the column while iteration.\n * @return {string} Returns the string representation of the value.\n */\n parse (val) {\n val = (val === undefined || val === null) ? '' : val.toString();\n return val.trim();\n }\n\n bins() {\n return this.bin;\n }\n subType() {\n return this.subtype;\n }\n}\n\nexport default DiscreteMeasure;\n","import { FieldType, DimensionSubtype } from './enums';\nimport { Measure, Categorical, DateTime, DiscreteMeasure } from './fields';\n\n/**\n * Creates a field instance according to the provided data and schema.\n *\n * @todo Add logic for GEO dimension subtype.\n *\n * @param {Array} data - The field data array.\n * @param {Object} schema - The field schema object.\n * @return {Field} Returns the newly created field instance.\n */\nfunction createUnitField (data, schema) {\n switch (schema.type) {\n case FieldType.MEASURE:\n switch (schema.subtype) {\n case 'discrete':\n return new DiscreteMeasure(schema.name, data, schema, schema.bins);\n default:\n return new Measure(schema.name, data, schema);\n }\n case FieldType.DIMENSION:\n default:\n switch (schema.subtype) {\n case DimensionSubtype.CATEGORICAL:\n return new Categorical(schema.name, data, schema);\n case DimensionSubtype.TEMPORAL:\n return new DateTime(schema.name, data, schema);\n case DimensionSubtype.GEO:\n return new Categorical(schema.name, data, schema);\n default:\n return new Categorical(schema.name, data, schema);\n }\n }\n}\n\n/**\n * Creates the field instances with input data and schema.\n *\n * @param {Array} dataColumn - The data array for fields.\n * @param {Array} schema - The schema array for fields.\n * @param {Array} headers - The array of header names.\n * @return {Array.} Returns an array of newly created field instances.\n */\nfunction createFields (dataColumn, schema, headers) {\n const headersObj = {};\n\n if (!(headers && headers.length)) {\n headers = schema.map(item => item.name);\n }\n\n headers.forEach((header, i) => {\n headersObj[header] = i;\n });\n\n return schema.map(item => createUnitField(dataColumn[headersObj[item.name]], item));\n}\n\nexport default createFields;\n","import { DataFormat } from './enums';\n\nexport default {\n dataFormat: DataFormat.AUTO\n};\n","import { columnMajor } from '../utils';\n\n/**\n * Parses and converts data formatted in DSV array to a manageable internal format.\n *\n * @param {Array.} arr - A 2D array containing of the DSV data.\n * @param {Object} options - Option to control the behaviour of the parsing.\n * @param {boolean} [options.firstRowHeader=true] - Whether the first row of the dsv data is header or not.\n * @return {Array} Returns an array of headers and column major data.\n * @example\n *\n * // Sample input data:\n * const data = [\n * [\"a\", \"b\", \"c\"],\n * [1, 2, 3],\n * [4, 5, 6],\n * [7, 8, 9]\n * ];\n */\nfunction DSVArr (arr, options) {\n const defaultOption = {\n firstRowHeader: true,\n };\n options = Object.assign({}, defaultOption, options);\n\n let header;\n const columns = [];\n const push = columnMajor(columns);\n\n if (options.firstRowHeader) {\n // If header present then mutate the array.\n // Do in-place mutation to save space.\n header = arr.splice(0, 1)[0];\n } else {\n header = [];\n }\n\n arr.forEach(field => push(...field));\n\n return [header, columns];\n}\n\nexport default DSVArr;\n","var EOL = {},\n EOF = {},\n QUOTE = 34,\n NEWLINE = 10,\n RETURN = 13;\n\nfunction objectConverter(columns) {\n return new Function(\"d\", \"return {\" + columns.map(function(name, i) {\n return JSON.stringify(name) + \": d[\" + i + \"]\";\n }).join(\",\") + \"}\");\n}\n\nfunction customConverter(columns, f) {\n var object = objectConverter(columns);\n return function(row, i) {\n return f(object(row), i, columns);\n };\n}\n\n// Compute unique columns in order of discovery.\nfunction inferColumns(rows) {\n var columnSet = Object.create(null),\n columns = [];\n\n rows.forEach(function(row) {\n for (var column in row) {\n if (!(column in columnSet)) {\n columns.push(columnSet[column] = column);\n }\n }\n });\n\n return columns;\n}\n\nexport default function(delimiter) {\n var reFormat = new RegExp(\"[\\\"\" + delimiter + \"\\n\\r]\"),\n DELIMITER = delimiter.charCodeAt(0);\n\n function parse(text, f) {\n var convert, columns, rows = parseRows(text, function(row, i) {\n if (convert) return convert(row, i - 1);\n columns = row, convert = f ? customConverter(row, f) : objectConverter(row);\n });\n rows.columns = columns || [];\n return rows;\n }\n\n function parseRows(text, f) {\n var rows = [], // output rows\n N = text.length,\n I = 0, // current character index\n n = 0, // current line number\n t, // current token\n eof = N <= 0, // current token followed by EOF?\n eol = false; // current token followed by EOL?\n\n // Strip the trailing newline.\n if (text.charCodeAt(N - 1) === NEWLINE) --N;\n if (text.charCodeAt(N - 1) === RETURN) --N;\n\n function token() {\n if (eof) return EOF;\n if (eol) return eol = false, EOL;\n\n // Unescape quotes.\n var i, j = I, c;\n if (text.charCodeAt(j) === QUOTE) {\n while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE);\n if ((i = I) >= N) eof = true;\n else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true;\n else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }\n return text.slice(j + 1, i - 1).replace(/\"\"/g, \"\\\"\");\n }\n\n // Find next delimiter or newline.\n while (I < N) {\n if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true;\n else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }\n else if (c !== DELIMITER) continue;\n return text.slice(j, i);\n }\n\n // Return last token before EOF.\n return eof = true, text.slice(j, N);\n }\n\n while ((t = token()) !== EOF) {\n var row = [];\n while (t !== EOL && t !== EOF) row.push(t), t = token();\n if (f && (row = f(row, n++)) == null) continue;\n rows.push(row);\n }\n\n return rows;\n }\n\n function format(rows, columns) {\n if (columns == null) columns = inferColumns(rows);\n return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {\n return columns.map(function(column) {\n return formatValue(row[column]);\n }).join(delimiter);\n })).join(\"\\n\");\n }\n\n function formatRows(rows) {\n return rows.map(formatRow).join(\"\\n\");\n }\n\n function formatRow(row) {\n return row.map(formatValue).join(delimiter);\n }\n\n function formatValue(text) {\n return text == null ? \"\"\n : reFormat.test(text += \"\") ? \"\\\"\" + text.replace(/\"/g, \"\\\"\\\"\") + \"\\\"\"\n : text;\n }\n\n return {\n parse: parse,\n parseRows: parseRows,\n format: format,\n formatRows: formatRows\n };\n}\n","import dsv from \"./dsv\";\n\nvar csv = dsv(\",\");\n\nexport var csvParse = csv.parse;\nexport var csvParseRows = csv.parseRows;\nexport var csvFormat = csv.format;\nexport var csvFormatRows = csv.formatRows;\n","import dsv from \"./dsv\";\n\nvar tsv = dsv(\"\\t\");\n\nexport var tsvParse = tsv.parse;\nexport var tsvParseRows = tsv.parseRows;\nexport var tsvFormat = tsv.format;\nexport var tsvFormatRows = tsv.formatRows;\n","import { dsvFormat as d3Dsv } from 'd3-dsv';\nimport DSVArr from './dsv-arr';\n\n/**\n * Parses and converts data formatted in DSV string to a manageable internal format.\n *\n * @todo Support to be given for https://tools.ietf.org/html/rfc4180.\n * @todo Sample implementation https://github.com/knrz/CSV.js/.\n *\n * @param {string} str - The input DSV string.\n * @param {Object} options - Option to control the behaviour of the parsing.\n * @param {boolean} [options.firstRowHeader=true] - Whether the first row of the dsv string data is header or not.\n * @param {string} [options.fieldSeparator=\",\"] - The separator of two consecutive field.\n * @return {Array} Returns an array of headers and column major data.\n * @example\n *\n * // Sample input data:\n * const data = `\n * a,b,c\n * 1,2,3\n * 4,5,6\n * 7,8,9\n * `\n */\nfunction DSVStr (str, options) {\n const defaultOption = {\n firstRowHeader: true,\n fieldSeparator: ','\n };\n options = Object.assign({}, defaultOption, options);\n\n const dsv = d3Dsv(options.fieldSeparator);\n return DSVArr(dsv.parseRows(str), options);\n}\n\nexport default DSVStr;\n","import { columnMajor } from '../utils';\n\n/**\n * Parses and converts data formatted in JSON to a manageable internal format.\n *\n * @param {Array.} arr - The input data formatted in JSON.\n * @return {Array.} Returns an array of headers and column major data.\n * @example\n *\n * // Sample input data:\n * const data = [\n * {\n * \"a\": 1,\n * \"b\": 2,\n * \"c\": 3\n * },\n * {\n * \"a\": 4,\n * \"b\": 5,\n * \"c\": 6\n * },\n * {\n * \"a\": 7,\n * \"b\": 8,\n * \"c\": 9\n * }\n * ];\n */\nfunction FlatJSON (arr) {\n const header = {};\n let i = 0;\n let insertionIndex;\n const columns = [];\n const push = columnMajor(columns);\n\n arr.forEach((item) => {\n const fields = [];\n for (let key in item) {\n if (key in header) {\n insertionIndex = header[key];\n } else {\n header[key] = i++;\n insertionIndex = i - 1;\n }\n fields[insertionIndex] = item[key];\n }\n push(...fields);\n });\n\n return [Object.keys(header), columns];\n}\n\nexport default FlatJSON;\n","import FlatJSON from './flat-json';\nimport DSVArr from './dsv-arr';\nimport DSVStr from './dsv-str';\nimport { isArray, isObject, isString } from '../utils';\n\n/**\n * Parses the input data and detect the format automatically.\n *\n * @param {string|Array} data - The input data.\n * @param {Object} options - An optional config specific to data format.\n * @return {Array.} Returns an array of headers and column major data.\n */\nfunction Auto (data, options) {\n let converter;\n\n if (isString(data)) {\n converter = DSVStr;\n } else if (isArray(data) && isArray(data[0])) {\n converter = DSVArr;\n } else if (isArray(data) && (data.length === 0 || isObject(data[0]))) {\n converter = FlatJSON;\n } else {\n throw new Error('Couldn\\'t detect the data format');\n }\n\n return converter(data, options);\n}\n\nexport default Auto;\n","import { FieldType, FilteringMode } from './enums';\nimport Field from './fields/field';\nimport fieldStore from './field-store';\nimport Value from './value';\nimport {\n rowDiffsetIterator\n} from './operator';\nimport { DM_DERIVATIVES, LOGICAL_OPERATORS } from './constants';\nimport createFields from './field-creator';\nimport defaultConfig from './default-config';\nimport * as converter from './converter';\n\n/**\n * Prepares the selection data.\n */\nfunction prepareSelectionData (fields, i) {\n const resp = {};\n for (let field of fields) {\n resp[field.name] = new Value(field.data[i], field);\n }\n return resp;\n}\n\nexport function prepareJoinData (fields) {\n const resp = {};\n Object.keys(fields).forEach((key) => { resp[key] = new Value(fields[key], key); });\n return resp;\n}\n\nexport const updateFields = ([rowDiffset, colIdentifier], partialFieldspace, fieldStoreName) => {\n let collID = colIdentifier.length ? colIdentifier.split(',') : [];\n let partialFieldMap = partialFieldspace.fieldsObj();\n let newFields = collID.map(coll => new Field(partialFieldMap[coll], rowDiffset));\n return fieldStore.createNamespace(newFields, fieldStoreName);\n};\n\nexport const persistDerivation = (model, operation, config = {}, criteriaFn) => {\n let derivative;\n if (operation !== DM_DERIVATIVES.COMPOSE) {\n derivative = {\n op: operation,\n meta: config,\n criteria: criteriaFn\n };\n model._derivation.push(derivative);\n }\n else {\n derivative = [...criteriaFn];\n model._derivation.length = 0;\n model._derivation.push(...derivative);\n }\n};\n\nexport const selectHelper = (rowDiffset, fields, selectFn, config) => {\n const newRowDiffSet = [];\n let lastInsertedValue = -1;\n let { mode } = config;\n let li;\n let checker = index => selectFn(prepareSelectionData(fields, index), index);\n if (mode === FilteringMode.INVERSE) {\n checker = index => !selectFn(prepareSelectionData(fields, index));\n }\n rowDiffsetIterator(rowDiffset, (i) => {\n if (checker(i)) {\n if (lastInsertedValue !== -1 && i === (lastInsertedValue + 1)) {\n li = newRowDiffSet.length - 1;\n newRowDiffSet[li] = `${newRowDiffSet[li].split('-')[0]}-${i}`;\n } else {\n newRowDiffSet.push(`${i}`);\n }\n lastInsertedValue = i;\n }\n });\n return newRowDiffSet.join(',');\n};\n\nexport const filterPropagationModel = (model, propModels, config = {}) => {\n const operation = config.operation || LOGICAL_OPERATORS.AND;\n const filterByMeasure = config.filterByMeasure || false;\n let fns = [];\n if (!propModels.length) {\n fns = [() => false];\n } else {\n fns = propModels.map(propModel => ((dataModel) => {\n const dataObj = dataModel.getData();\n const schema = dataObj.schema;\n const fieldsConfig = dataModel.getFieldsConfig();\n const fieldsSpace = dataModel.getFieldspace().fieldsObj();\n const data = dataObj.data;\n const domain = Object.values(fieldsConfig).reduce((acc, v) => {\n acc[v.def.name] = fieldsSpace[v.def.name].domain();\n return acc;\n }, {});\n\n return (fields) => {\n const include = !data.length ? false : data.some(row => schema.every((propField) => {\n if (!(propField.name in fields)) {\n return true;\n }\n const value = fields[propField.name].valueOf();\n if (filterByMeasure && propField.type === FieldType.MEASURE) {\n return value >= domain[propField.name][0] && value <= domain[propField.name][1];\n }\n\n if (propField.type !== FieldType.DIMENSION) {\n return true;\n }\n const idx = fieldsConfig[propField.name].index;\n return row[idx] === fields[propField.name].valueOf();\n }));\n return include;\n };\n })(propModel));\n }\n\n let filteredModel;\n if (operation === LOGICAL_OPERATORS.AND) {\n const clonedModel = model.clone(false, false);\n filteredModel = clonedModel.select(fields => fns.every(fn => fn(fields)), {\n saveChild: false,\n mode: FilteringMode.ALL\n });\n } else {\n filteredModel = model.clone(false, false).select(fields => fns.some(fn => fn(fields)), {\n mode: FilteringMode.ALL,\n saveChild: false\n });\n }\n\n return filteredModel;\n};\n\nexport const cloneWithSelect = (sourceDm, selectFn, selectConfig, cloneConfig) => {\n const cloned = sourceDm.clone(cloneConfig.saveChild);\n const rowDiffset = selectHelper(\n cloned._rowDiffset,\n cloned.getPartialFieldspace().fields,\n selectFn,\n selectConfig\n );\n cloned._rowDiffset = rowDiffset;\n cloned.__calculateFieldspace().calculateFieldsConfig();\n // Store reference to child model and selector function\n if (cloneConfig.saveChild) {\n persistDerivation(cloned, DM_DERIVATIVES.SELECT, { config: selectConfig }, selectFn);\n }\n\n return cloned;\n};\n\nexport const cloneWithProject = (sourceDm, projField, config, allFields) => {\n const cloned = sourceDm.clone(config.saveChild);\n let projectionSet = projField;\n if (config.mode === FilteringMode.INVERSE) {\n projectionSet = allFields.filter(fieldName => projField.indexOf(fieldName) === -1);\n }\n // cloned._colIdentifier = sourceDm._colIdentifier.split(',')\n // .filter(coll => projectionSet.indexOf(coll) !== -1).join();\n cloned._colIdentifier = projectionSet.join(',');\n cloned.__calculateFieldspace().calculateFieldsConfig();\n // Store reference to child model and projection fields\n if (config.saveChild) {\n persistDerivation(\n cloned,\n DM_DERIVATIVES.PROJECT,\n { projField, config, actualProjField: projectionSet },\n null\n );\n }\n\n return cloned;\n};\n\nexport const updateData = (relation, data, schema, options) => {\n options = Object.assign(Object.assign({}, defaultConfig), options);\n const converterFn = converter[options.dataFormat];\n\n if (!(converterFn && typeof converterFn === 'function')) {\n throw new Error(`No converter function found for ${options.dataFormat} format`);\n }\n\n const [header, formattedData] = converterFn(data, options);\n const fieldArr = createFields(formattedData, schema, header);\n\n // This will create a new fieldStore with the fields\n const nameSpace = fieldStore.createNamespace(fieldArr, options.name);\n relation._partialFieldspace = nameSpace;\n // If data is provided create the default colIdentifier and rowDiffset\n relation._rowDiffset = formattedData.length && formattedData[0].length ? `0-${formattedData[0].length - 1}` : '';\n relation._colIdentifier = (schema.map(_ => _.name)).join();\n return relation;\n};\n\nexport const fieldInSchema = (schema, field) => {\n let i = 0;\n\n for (; i < schema.length; ++i) {\n if (field === schema[i].name) {\n return {\n type: schema[i].subtype || schema[i].type,\n index: i\n };\n }\n }\n return null;\n};\n\n\nexport const getOperationArguments = (child) => {\n const derivation = child._derivation;\n let params = [];\n let operation;\n if (derivation && derivation.length === 1) {\n operation = derivation[0].op;\n switch (operation) {\n case DM_DERIVATIVES.SELECT:\n params = [derivation[0].criteria];\n break;\n case DM_DERIVATIVES.PROJECT:\n params = [derivation[0].meta.actualProjField];\n break;\n case DM_DERIVATIVES.GROUPBY:\n operation = 'groupBy';\n params = [derivation[0].meta.groupByString.split(','), derivation[0].criteria];\n break;\n default:\n break;\n }\n }\n\n return {\n operation,\n params\n };\n};\n\nconst applyExistingOperationOnModel = (propModel, dataModel) => {\n const { operation, params } = getOperationArguments(dataModel);\n let selectionModel = propModel[0];\n let rejectionModel = propModel[1];\n if (operation && params.length) {\n selectionModel = propModel[0][operation](...params, {\n saveChild: false\n });\n rejectionModel = propModel[1][operation](...params, {\n saveChild: false\n });\n }\n return [selectionModel, rejectionModel];\n};\n\nconst getFilteredModel = (propModel, path) => {\n for (let i = 0, len = path.length; i < len; i++) {\n const model = path[i];\n propModel = applyExistingOperationOnModel(propModel, model);\n }\n return propModel;\n};\n\nconst propagateIdentifiers = (dataModel, propModel, config = {}, propModelInf = {}) => {\n const nonTraversingModel = propModelInf.nonTraversingModel;\n const excludeModels = propModelInf.excludeModels || [];\n\n if (dataModel === nonTraversingModel) {\n return;\n }\n\n const propagate = excludeModels.length ? excludeModels.indexOf(dataModel) === -1 : true;\n\n propagate && dataModel.handlePropagation(propModel, config);\n\n const children = dataModel._children;\n children.forEach((child) => {\n let [selectionModel, rejectionModel] = applyExistingOperationOnModel(propModel, child);\n propagateIdentifiers(child, [selectionModel, rejectionModel], config, propModelInf);\n });\n};\n\nexport const getRootGroupByModel = (model) => {\n if (model._parent && model._derivation.find(d => d.op !== 'group')) {\n return getRootGroupByModel(model._parent);\n }\n return model;\n};\n\nexport const getRootDataModel = (model) => {\n if (model._parent) {\n return getRootDataModel(model._parent);\n }\n return model;\n};\n\nexport const getPathToRootModel = (model, path = []) => {\n if (model._parent !== null) {\n path.push(model);\n getPathToRootModel(model._parent, path);\n }\n return path;\n};\n\nexport const propagateToAllDataModels = (identifiers, rootModels, propagationInf, config) => {\n let criteria;\n let propModel;\n const { propagationNameSpace, propagateToSource } = propagationInf;\n const propagationSourceId = propagationInf.sourceId;\n const propagateInterpolatedValues = config.propagateInterpolatedValues;\n const filterFn = (entry) => {\n const filter = config.filterFn || (() => true);\n return filter(entry, config);\n };\n\n let criterias = [];\n\n if (identifiers === null && config.persistent !== true) {\n criterias = [{\n criteria: []\n }];\n } else {\n let actionCriterias = Object.values(propagationNameSpace.mutableActions);\n if (propagateToSource !== false) {\n actionCriterias = actionCriterias.filter(d => d.config.sourceId !== propagationSourceId);\n }\n\n const filteredCriteria = actionCriterias.filter(filterFn).map(action => action.config.criteria);\n\n const excludeModels = [];\n\n if (propagateToSource !== false) {\n const sourceActionCriterias = Object.values(propagationNameSpace.mutableActions);\n\n sourceActionCriterias.forEach((actionInf) => {\n const actionConf = actionInf.config;\n if (actionConf.applyOnSource === false && actionConf.action === config.action &&\n actionConf.sourceId !== propagationSourceId) {\n excludeModels.push(actionInf.model);\n criteria = sourceActionCriterias.filter(d => d !== actionInf).map(d => d.config.criteria);\n criteria.length && criterias.push({\n criteria,\n models: actionInf.model,\n path: getPathToRootModel(actionInf.model)\n });\n }\n });\n }\n\n\n criteria = [].concat(...[...filteredCriteria, identifiers]).filter(d => d !== null);\n criterias.push({\n criteria,\n excludeModels: [...excludeModels, ...config.excludeModels || []]\n });\n }\n\n const rootModel = rootModels.model;\n\n const propConfig = Object.assign({\n sourceIdentifiers: identifiers,\n propagationSourceId\n }, config);\n\n const rootGroupByModel = rootModels.groupByModel;\n if (propagateInterpolatedValues && rootGroupByModel) {\n propModel = filterPropagationModel(rootGroupByModel, criteria, {\n filterByMeasure: propagateInterpolatedValues\n });\n propagateIdentifiers(rootGroupByModel, propModel, propConfig);\n }\n\n criterias.forEach((inf) => {\n const propagationModel = filterPropagationModel(rootModel, inf.criteria);\n const path = inf.path;\n\n if (path) {\n const filteredModel = getFilteredModel(propagationModel, path.reverse());\n inf.models.handlePropagation(filteredModel, propConfig);\n } else {\n propagateIdentifiers(rootModel, propagationModel, propConfig, {\n excludeModels: inf.excludeModels,\n nonTraversingModel: propagateInterpolatedValues && rootGroupByModel\n });\n }\n });\n};\n\nexport const propagateImmutableActions = (propagationNameSpace, rootModels, propagationInf) => {\n const immutableActions = propagationNameSpace.immutableActions;\n\n for (const action in immutableActions) {\n const actionInf = immutableActions[action];\n const actionConf = actionInf.config;\n const propagationSourceId = propagationInf.config.sourceId;\n const filterImmutableAction = propagationInf.propConfig.filterImmutableAction ?\n propagationInf.propConfig.filterImmutableAction(actionConf, propagationInf.config) : true;\n if (actionConf.sourceId !== propagationSourceId && filterImmutableAction) {\n const criteriaModel = actionConf.criteria;\n propagateToAllDataModels(criteriaModel, rootModels, {\n propagationNameSpace,\n propagateToSource: false,\n sourceId: propagationSourceId\n }, actionConf);\n }\n }\n};\n\nexport const addToPropNamespace = (propagationNameSpace, config = {}, model) => {\n let sourceNamespace;\n const isMutableAction = config.isMutableAction;\n const criteria = config.criteria;\n const key = `${config.action}-${config.sourceId}`;\n\n if (isMutableAction) {\n sourceNamespace = propagationNameSpace.mutableActions;\n } else {\n sourceNamespace = propagationNameSpace.immutableActions;\n }\n\n if (criteria === null) {\n delete sourceNamespace[key];\n } else {\n sourceNamespace[key] = {\n model,\n config\n };\n }\n\n return this;\n};\n","import { FilteringMode } from './enums';\nimport { getUniqueId } from './utils';\nimport { persistDerivation, updateFields, cloneWithSelect, cloneWithProject, updateData } from './helper';\nimport { crossProduct, difference, naturalJoinFilter, union } from './operator';\nimport { DM_DERIVATIVES } from './constants';\n\n/**\n * Relation provides the definitions of basic operators of relational algebra like *selection*, *projection*, *union*,\n * *difference* etc.\n *\n * It is extended by {@link DataModel} to inherit the functionalities of relational algebra concept.\n *\n * @class\n * @public\n * @module Relation\n * @namespace DataModel\n */\nclass Relation {\n\n /**\n * Creates a new Relation instance by providing underlying data and schema.\n *\n * @private\n *\n * @param {Object | string | Relation} data - The input tabular data in dsv or json format or\n * an existing Relation instance object.\n * @param {Array} schema - An array of data schema.\n * @param {Object} [options] - The optional options.\n */\n constructor (...params) {\n let source;\n\n this._parent = null;\n this._derivation = [];\n this._children = [];\n\n if (params.length === 1 && ((source = params[0]) instanceof Relation)) {\n // parent datamodel was passed as part of source\n this._colIdentifier = source._colIdentifier;\n this._rowDiffset = source._rowDiffset;\n this._parent = source;\n this._partialFieldspace = this._parent._partialFieldspace;\n this._fieldStoreName = getUniqueId();\n this.__calculateFieldspace().calculateFieldsConfig();\n } else {\n updateData(this, ...params);\n this._fieldStoreName = this._partialFieldspace.name;\n this.__calculateFieldspace().calculateFieldsConfig();\n this._propagationNameSpace = {\n mutableActions: {},\n immutableActions: {}\n };\n }\n }\n\n /**\n * Retrieves the {@link Schema | schema} details for every {@link Field | field} as an array.\n *\n * @public\n *\n * @return {Array.} Array of fields schema.\n * ```\n * [\n * { name: 'Name', type: 'dimension' },\n * { name: 'Miles_per_Gallon', type: 'measure', numberFormat: (val) => `${val} miles / gallon` },\n * { name: 'Cylinder', type: 'dimension' },\n * { name: 'Displacement', type: 'measure', defAggFn: 'max' },\n * { name: 'HorsePower', type: 'measure', defAggFn: 'max' },\n * { name: 'Weight_in_lbs', type: 'measure', defAggFn: 'avg', },\n * { name: 'Acceleration', type: 'measure', defAggFn: 'avg' },\n * { name: 'Year', type: 'dimension', subtype: 'datetime', format: '%Y' },\n * { name: 'Origin' }\n * ]\n * ```\n */\n getSchema () {\n return this.getFieldspace().fields.map(d => d.schema);\n }\n\n /**\n * Returns the name of the {@link DataModel} instance. If no name was specified during {@link DataModel}\n * initialization, then it returns a auto-generated name.\n *\n * @public\n *\n * @return {string} Name of the DataModel instance.\n */\n getName() {\n return this._fieldStoreName;\n }\n\n getFieldspace () {\n return this._fieldspace;\n }\n\n __calculateFieldspace () {\n this._fieldspace = updateFields([this._rowDiffset, this._colIdentifier],\n this.getPartialFieldspace(), this._fieldStoreName);\n return this;\n }\n\n getPartialFieldspace () {\n return this._partialFieldspace;\n }\n\n /**\n * Performs {@link link_of_cross_product | cross-product} between two {@link DataModel} instances and returns a\n * new {@link DataModel} instance containing the results. This operation is also called theta join.\n *\n * Cross product takes two set and create one set where each value of one set is paired with each value of another\n * set.\n *\n * This method takes an optional predicate which filters the generated result rows. If the predicate returns true\n * the combined row is included in the resulatant table.\n *\n * @example\n * let originDM = dm.project(['Origin','Origin_Formal_Name']);\n * let carsDM = dm.project(['Name','Miles_per_Gallon','Origin'])\n *\n * console.log(carsDM.join(originDM)));\n *\n * console.log(carsDM.join(originDM,\n * obj => obj.[originDM.getName()].Origin === obj.[carsDM.getName()].Origin));\n *\n * @text\n * This is chained version of `join` operator. `join` can also be used as\n * {@link link_to_join_op | functional operator}.\n *\n * @public\n *\n * @param {DataModel} joinWith - The DataModel to be joined with the current instance DataModel.\n * @param {SelectionPredicate} filterFn - The predicate function that will filter the result of the crossProduct.\n *\n * @return {DataModel} New DataModel instance created after joining.\n */\n join (joinWith, filterFn) {\n return crossProduct(this, joinWith, filterFn);\n }\n\n /**\n * {@link natural_join | Natural join} is a special kind of cross-product join where filtering of rows are performed\n * internally by resolving common fields are from both table and the rows with common value are included.\n *\n * @example\n * let originDM = dm.project(['Origin','Origin_Formal_Name']);\n * let carsDM = dm.project(['Name','Miles_per_Gallon','Origin'])\n *\n * console.log(carsDM.naturalJoin(originDM));\n *\n * @text\n * This is chained version of `naturalJoin` operator. `naturalJoin` can also be used as\n * {@link link_to_join_op | functional operator}.\n *\n * @public\n *\n * @param {DataModel} joinWith - The DataModel with which the current instance of DataModel on which the method is\n * called will be joined.\n * @return {DataModel} New DataModel instance created after joining.\n */\n naturalJoin (joinWith) {\n return crossProduct(this, joinWith, naturalJoinFilter(this, joinWith), true);\n }\n\n /**\n * {@link link_to_union | Union} operation can be termed as vertical stacking of all rows from both the DataModel\n * instances, provided that both of the {@link DataModel} instances should have same column names.\n *\n * @example\n * console.log(EuropeanMakerDM.union(USAMakerDM));\n *\n * @text\n * This is chained version of `naturalJoin` operator. `naturalJoin` can also be used as\n * {@link link_to_join_op | functional operator}.\n *\n * @public\n *\n * @param {DataModel} unionWith - DataModel instance for which union has to be applied with the instance on which\n * the method is called\n *\n * @return {DataModel} New DataModel instance with the result of the operation\n */\n union (unionWith) {\n return union(this, unionWith);\n }\n\n /**\n * {@link link_to_difference | Difference } operation only include rows which are present in the datamodel on which\n * it was called but not on the one passed as argument.\n *\n * @example\n * console.log(highPowerDM.difference(highExpensiveDM));\n *\n * @text\n * This is chained version of `naturalJoin` operator. `naturalJoin` can also be used as\n * {@link link_to_join_op | functional operator}.\n *\n * @public\n *\n * @param {DataModel} differenceWith - DataModel instance for which difference has to be applied with the instance\n * on which the method is called\n * @return {DataModel} New DataModel instance with the result of the operation\n */\n difference (differenceWith) {\n return difference(this, differenceWith);\n }\n\n /**\n * {@link link_to_selection | Selection} is a row filtering operation. It expects an predicate and an optional mode\n * which control which all rows should be included in the resultant DataModel instance.\n *\n * {@link SelectionPredicate} is a function which returns a boolean value. For selection opearation the selection\n * function is called for each row of DataModel instance with the current row passed as argument.\n *\n * After executing {@link SelectionPredicate} the rows are labeled as either an entry of selection set or an entry\n * of rejection set.\n *\n * {@link FilteringMode} operates on the selection and rejection set to determine which one would reflect in the\n * resulatant datamodel.\n *\n * @warning\n * Selection and rejection set is only a logical idea for concept explanation purpose.\n *\n * @example\n * // with selection mode NORMAL:\n * const normDt = dt.select(fields => fields.Origin.value === \"USA\")\n * console.log(normDt));\n *\n * // with selection mode INVERSE:\n * const inverDt = dt.select(fields => fields.Origin.value === \"USA\", { mode: DataModel.FilteringMode.INVERSE })\n * console.log(inverDt);\n *\n * // with selection mode ALL:\n * const dtArr = dt.select(fields => fields.Origin.value === \"USA\", { mode: DataModel.FilteringMode.ALL })\n * // print the selected parts\n * console.log(dtArr[0]);\n * // print the inverted parts\n * console.log(dtArr[1]);\n *\n * @text\n * This is chained version of `select` operator. `select` can also be used as\n * {@link link_to_join_op | functional operator}.\n *\n * @public\n *\n * @param {SelectionPredicate} selectFn - Predicate funciton which is called for each row with the current row\n * ```\n * function (row, i) { ... }\n * ```\n * @param {Object} [config] - The configuration object to control the inclusion exclusion of a row in resultant\n * DataModel instance\n * @param {FilteringMode} [config.mode=FilteringMode.NORMAL] - The mode of the selection\n *\n * @return {DataModel} Returns the new DataModel instance(s) after operation.\n */\n select (selectFn, config) {\n const defConfig = {\n mode: FilteringMode.NORMAL,\n saveChild: true\n };\n config = Object.assign({}, defConfig, config);\n\n const cloneConfig = { saveChild: config.saveChild };\n let oDm;\n\n if (config.mode === FilteringMode.ALL) {\n const selectDm = cloneWithSelect(\n this,\n selectFn,\n { mode: FilteringMode.NORMAL },\n cloneConfig\n );\n const rejectDm = cloneWithSelect(\n this,\n selectFn,\n { mode: FilteringMode.INVERSE },\n cloneConfig\n );\n oDm = [selectDm, rejectDm];\n } else {\n oDm = cloneWithSelect(\n this,\n selectFn,\n config,\n cloneConfig\n );\n }\n\n return oDm;\n }\n\n /**\n * Retrieves a boolean value if the current {@link DataModel} instance has data.\n *\n * @example\n * const schema = [\n * { name: 'CarName', type: 'dimension' },\n * { name: 'HorsePower', type: 'measure' },\n * { name: \"Origin\", type: 'dimension' }\n * ];\n * const data = [];\n *\n * const dt = new DataModel(schema, data);\n * console.log(dt.isEmpty());\n *\n * @public\n *\n * @return {Boolean} True if the datamodel has no data, otherwise false.\n */\n isEmpty () {\n return !this._rowDiffset.length || !this._colIdentifier.length;\n }\n\n /**\n * Creates a clone from the current DataModel instance with child parent relationship.\n *\n * @private\n * @param {boolean} [saveChild=true] - Whether the cloned instance would be recorded in the parent instance.\n * @return {DataModel} - Returns the newly cloned DataModel instance.\n */\n clone (saveChild = true, linkParent = true) {\n let retDataModel;\n if (linkParent === false) {\n const dataObj = this.getData({\n getAllFields: true\n });\n const data = dataObj.data;\n const schema = dataObj.schema;\n const jsonData = data.map((row) => {\n const rowObj = {};\n schema.forEach((field, i) => {\n rowObj[field.name] = row[i];\n });\n return rowObj;\n });\n retDataModel = new this.constructor(jsonData, schema);\n }\n else {\n retDataModel = new this.constructor(this);\n }\n\n if (saveChild) {\n this._children.push(retDataModel);\n }\n return retDataModel;\n }\n\n /**\n * {@link Projection} is filter column (field) operation. It expects list of fields' name and either include those\n * or exclude those based on {@link FilteringMode} on the resultant variable.\n *\n * Projection expects array of fields name based on which it creates the selection and rejection set. All the field\n * whose name is present in array goes in selection set and rest of the fields goes in rejection set.\n *\n * {@link FilteringMode} operates on the selection and rejection set to determine which one would reflect in the\n * resulatant datamodel.\n *\n * @warning\n * Selection and rejection set is only a logical idea for concept explanation purpose.\n *\n * @example\n * const dm = new DataModel(schema, data);\n *\n * // with projection mode NORMAL:\n * const normDt = dt.project([\"Name\", \"HorsePower\"]);\n * console.log(normDt.getData());\n *\n * // with projection mode INVERSE:\n * const inverDt = dt.project([\"Name\", \"HorsePower\"], { mode: DataModel.FilteringMode.INVERSE })\n * console.log(inverDt.getData());\n *\n * // with selection mode ALL:\n * const dtArr = dt.project([\"Name\", \"HorsePower\"], { mode: DataModel.FilteringMode.ALL })\n * // print the normal parts\n * console.log(dtArr[0].getData());\n * // print the inverted parts\n * console.log(dtArr[1].getData());\n *\n * @text\n * This is chained version of `select` operator. `select` can also be used as\n * {@link link_to_join_op | functional operator}.\n *\n * @public\n *\n * @param {Array.} projField - An array of column names in string or regular expression.\n * @param {Object} [config] - An optional config to control the creation of new DataModel\n * @param {FilteringMode} [config.mode=FilteringMode.NORMAL] - Mode of the projection\n *\n * @return {DataModel} Returns the new DataModel instance after operation.\n */\n project (projField, config) {\n const defConfig = {\n mode: FilteringMode.NORMAL,\n saveChild: true\n };\n config = Object.assign({}, defConfig, config);\n const fieldConfig = this.getFieldsConfig();\n const allFields = Object.keys(fieldConfig);\n const { mode } = config;\n\n let normalizedProjField = projField.reduce((acc, field) => {\n if (field.constructor.name === 'RegExp') {\n acc.push(...allFields.filter(fieldName => fieldName.search(field) !== -1));\n } else if (field in fieldConfig) {\n acc.push(field);\n }\n return acc;\n }, []);\n\n normalizedProjField = Array.from(new Set(normalizedProjField)).map(field => field.trim());\n let dataModel;\n\n if (mode === FilteringMode.ALL) {\n let projectionClone = cloneWithProject(this, normalizedProjField, {\n mode: FilteringMode.NORMAL,\n saveChild: config.saveChild\n }, allFields);\n let rejectionClone = cloneWithProject(this, normalizedProjField, {\n mode: FilteringMode.INVERSE,\n saveChild: config.saveChild\n }, allFields);\n dataModel = [projectionClone, rejectionClone];\n } else {\n let projectionClone = cloneWithProject(this, normalizedProjField, config, allFields);\n dataModel = projectionClone;\n }\n\n return dataModel;\n }\n\n getFieldsConfig () {\n return this._fieldConfig;\n }\n\n calculateFieldsConfig () {\n this._fieldConfig = this._fieldspace.fields.reduce((acc, fieldDef, i) => {\n acc[fieldDef.name] = {\n index: i,\n def: { name: fieldDef._ref.name, type: fieldDef._ref.fieldType, subtype: fieldDef._ref.subType() }\n };\n return acc;\n }, {});\n return this;\n }\n\n\n /**\n * Frees up the resources associated with the current DataModel instance and breaks all the links instance has in\n * the DAG.\n *\n * @public\n */\n dispose () {\n this._parent.removeChild(this);\n this._parent = null;\n }\n\n /**\n * Removes the specified child {@link DataModel} from the child list of the current {@link DataModel} instance.\n *\n * @example\n * const schema = [\n * { name: 'Name', type: 'dimension' },\n * { name: 'HorsePower', type: 'measure' },\n * { name: \"Origin\", type: 'dimension' }\n * ];\n *\n * const data = [\n * { Name: \"chevrolet chevelle malibu\", Horsepower: 130, Origin: \"USA\" },\n * { Name: \"citroen ds-21 pallas\", Horsepower: 115, Origin: \"Europe\" },\n * { Name: \"datsun pl510\", Horsepower: 88, Origin: \"Japan\" },\n * { Name: \"amc rebel sst\", Horsepower: 150, Origin: \"USA\"},\n * ]\n *\n * const dt = new DataModel(schema, data);\n *\n * const dt2 = dt.select(fields => fields.Origin.value === \"USA\")\n * dt.removeChild(dt2);\n *\n * @private\n *\n * @param {DataModel} child - Delegates the parent to remove this child.\n */\n removeChild (child) {\n let idx = this._children.findIndex(sibling => sibling === child);\n idx !== -1 ? this._children.splice(idx, 1) : true;\n }\n\n /**\n * Adds the specified {@link DataModel} as a parent for the current {@link DataModel} instance.\n *\n * The optional criteriaQueue is an array containing the history of transaction performed on parent\n * {@link DataModel} to get the current one.\n *\n * @param {DataModel} parent - The datamodel instance which will act as parent.\n * @param {Array} criteriaQueue - Queue contains in-between operation meta-data.\n */\n addParent (parent, criteriaQueue = []) {\n persistDerivation(this, DM_DERIVATIVES.COMPOSE, null, criteriaQueue);\n this._parent = parent;\n parent._children.push(this);\n }\n}\n\nexport default Relation;\n","/* eslint-disable default-case */\n\nimport { FieldType } from './enums';\nimport {\n persistDerivation,\n getRootGroupByModel,\n propagateToAllDataModels,\n getRootDataModel,\n propagateImmutableActions,\n addToPropNamespace\n} from './helper';\nimport { DM_DERIVATIVES, PROPAGATION } from './constants';\nimport {\n dataBuilder,\n rowDiffsetIterator,\n groupBy\n} from './operator';\nimport { createBinnedFieldData } from './operator/bucket-creator';\nimport Relation from './relation';\nimport reducerStore from './utils/reducer-store';\nimport createFields from './field-creator';\n\n/**\n * DataModel is an in-browser representation of tabular data. It supports\n * {@link https://en.wikipedia.org/wiki/Relational_algebra | relational algebra} operators as well as generic data\n * processing opearators.\n * DataModel extends {@link Relation} class which defines all the relational algebra opreators. DataModel gives\n * definition of generic data processing operators which are not relational algebra complient.\n *\n * @public\n * @class\n * @extends Relation\n * @memberof Datamodel\n */\nclass DataModel extends Relation {\n /**\n * Creates a new DataModel instance by providing data and schema. Data could be in the form of\n * - Flat JSON\n * - DSV String\n * - 2D Array\n *\n * By default DataModel finds suitable adapter to serialize the data. DataModel also expects a\n * {@link Schema | schema} for identifying the variables present in data.\n *\n * @constructor\n * @example\n * const data = loadData('cars.csv');\n * const schema = [\n * { name: 'Name', type: 'dimension' },\n * { name: 'Miles_per_Gallon', type: 'measure', unit : 'cm', scale: '1000', numberformat: val => `${val}G`},\n * { name: 'Cylinders', type: 'dimension' },\n * { name: 'Displacement', type: 'measure' },\n * { name: 'Horsepower', type: 'measure' },\n * { name: 'Weight_in_lbs', type: 'measure' },\n * { name: 'Acceleration', type: 'measure' },\n * { name: 'Year', type: 'dimension', subtype: 'datetime', format: '%Y' },\n * { name: 'Origin', type: 'dimension' }\n * ];\n * const dm = new DataModel(data, schema, { name: 'Cars' });\n * table(dm);\n *\n * @public\n *\n * @param {Array. | string | Array.} data Input data in any of the mentioned formats\n * @param {Array.} schema Defination of the variables. Order of the variables in data and order of the\n * variables in schema has to be same.\n * @param {object} [options] Optional arguments to specify more settings regarding the creation part\n * @param {string} [options.name] Name of the datamodel instance. If no name is given an auto generated name is\n * assigned to the instance.\n * @param {string} [options.fieldSeparator=','] specify field separator type if the data is of type dsv string.\n */\n constructor (...args) {\n super(...args);\n\n this._onPropagation = [];\n this._sortingDetails = [];\n }\n\n /**\n * Reducers are simple functions which reduces an array of numbers to a representative number of the set.\n * Like an array of numbers `[10, 20, 5, 15]` can be reduced to `12.5` if average / mean reducer function is\n * applied. All the measure fields in datamodel (variables in data) needs a reducer to handle aggregation.\n *\n * @public\n *\n * @return {ReducerStore} Singleton instance of {@link ReducerStore}.\n */\n static get Reducers () {\n return reducerStore;\n }\n\n /**\n * Retrieve the data attached to an instance in JSON format.\n *\n * @example\n * // DataModel instance is already prepared and assigned to dm variable\n * const data = dm.getData({\n * order: 'column',\n * formatter: {\n * origin: (val) => val === 'European Union' ? 'EU' : val;\n * }\n * });\n * console.log(data);\n *\n * @public\n *\n * @param {Object} [options] Options to control how the raw data is to be returned.\n * @param {string} [options.order='row'] Defines if data is retieved in row order or column order. Possible values\n * are `'rows'` and `'columns'`\n * @param {Function} [options.formatter=null] Formats the output data. This expects an object, where the keys are\n * the name of the variable needs to be formatted. The formatter function is called for each row passing the\n * value of the cell for a particular row as arguments. The formatter is a function in the form of\n * `function (value, rowId, schema) => { ... }`\n * Know more about {@link Fomatter}.\n *\n * @return {Array} Returns a multidimensional array of the data with schema. The return format looks like\n * ```\n * {\n * data,\n * schema\n * }\n * ```\n */\n getData (options) {\n const defOptions = {\n order: 'row',\n formatter: null,\n withUid: false,\n getAllFields: false,\n sort: []\n };\n options = Object.assign({}, defOptions, options);\n const fields = this.getPartialFieldspace().fields;\n\n const dataGenerated = dataBuilder.call(\n this,\n this.getPartialFieldspace().fields,\n this._rowDiffset,\n options.getAllFields ? fields.map(d => d.name).join() : this._colIdentifier,\n options.sort,\n {\n columnWise: options.order === 'column',\n addUid: !!options.withUid\n }\n );\n\n if (!options.formatter) {\n return dataGenerated;\n }\n\n const { formatter } = options;\n const { data, schema, uids } = dataGenerated;\n const fieldNames = schema.map((e => e.name));\n const fmtFieldNames = Object.keys(formatter);\n const fmtFieldIdx = fmtFieldNames.reduce((acc, next) => {\n const idx = fieldNames.indexOf(next);\n if (idx !== -1) {\n acc.push([idx, formatter[next]]);\n }\n return acc;\n }, []);\n\n if (options.order === 'column') {\n fmtFieldIdx.forEach((elem) => {\n const fIdx = elem[0];\n const fmtFn = elem[1];\n\n data[fIdx].forEach((datum, datumIdx) => {\n data[fIdx][datumIdx] = fmtFn.call(\n undefined,\n datum,\n uids[datumIdx],\n schema[fIdx]\n );\n });\n });\n } else {\n data.forEach((datum, datumIdx) => {\n fmtFieldIdx.forEach((elem) => {\n const fIdx = elem[0];\n const fmtFn = elem[1];\n\n datum[fIdx] = fmtFn.call(\n undefined,\n datum[fIdx],\n uids[datumIdx],\n schema[fIdx]\n );\n });\n });\n }\n\n return dataGenerated;\n }\n\n /**\n * Groups the data using particular dimensions and by reducing measures. It expects a list of dimensions using which\n * it projects the datamodel and perform aggregations to reduce the duplicate tuples. Refer this\n * {@link link_to_one_example_with_group_by | document} to know the intuition behind groupBy.\n *\n * DataModel by default provides definition of few {@link reducer | Reducers}.\n * {@link ReducerStore | User defined reducers} can also be registered.\n *\n * This is the chained implementation of `groupBy`.\n * `groupBy` also supports {@link link_to_compose_groupBy | composability}\n *\n * @example\n * const groupedDM = dm.groupBy(['Year'], { horsepower: 'max' } );\n * console.log(groupedDm);\n *\n * @public\n *\n * @param {Array.} fieldsArr - Array containing the name of dimensions\n * @param {Object} [reducers={}] - A map whose key is the variable name and value is the name of the reducer. If its\n * not passed, or any variable is ommitted from the object, default aggregation function is used from the\n * schema of the variable.\n *\n * @return {DataModel} Returns a new DataModel instance after performing the groupby.\n */\n groupBy (fieldsArr, reducers = {}, config = { saveChild: true }) {\n const groupByString = `${fieldsArr.join()}`;\n let params = [this, fieldsArr, reducers];\n const newDataModel = groupBy(...params);\n\n if (config.saveChild) {\n this._children.push(newDataModel);\n persistDerivation(\n newDataModel,\n DM_DERIVATIVES.GROUPBY,\n { fieldsArr, groupByString, defaultReducer: reducerStore.defaultReducer() },\n reducers\n );\n }\n\n newDataModel._parent = this;\n return newDataModel;\n }\n\n /**\n * Performs sorting operation on the current {@link DataModel} instance according to the specified sorting details.\n * Like every other operator it doesn't mutate the current DataModel instance on which it was called, instead\n * returns a new DataModel instance containing the sorted data.\n *\n * DataModel support multi level sorting by listing the variables using which sorting needs to be performed and\n * the type of sorting `ASC` or `DESC`.\n *\n * In the following example, data is sorted by `Origin` field in `DESC` order in first level followed by another\n * level of sorting by `Acceleration` in `ASC` order.\n *\n * @example\n * // here dm is the pre-declared DataModel instance containing the data of 'cars.json' file\n * let sortedDm = dm.sort([\n * [\"Origin\", \"DESC\"]\n * [\"Acceleration\"] // Default value is ASC\n * ]);\n *\n * console.log(dm.getData());\n * console.log(sortedDm.getData());\n *\n * // Sort with a custom sorting function\n * sortedDm = dm.sort([\n * [\"Origin\", \"DESC\"]\n * [\"Acceleration\", (a, b) => a - b] // Custom sorting function\n * ]);\n *\n * console.log(dm.getData());\n * console.log(sortedDm.getData());\n *\n * @text\n * DataModel also provides another sorting mechanism out of the box where sort is applied to a variable using\n * another variable which determines the order.\n * Like the above DataModel contains three fields `Origin`, `Name` and `Acceleration`. Now, the data in this\n * model can be sorted by `Origin` field according to the average value of all `Acceleration` for a\n * particular `Origin` value.\n *\n * @example\n * // here dm is the pre-declared DataModel instance containing the data of 'cars.json' file\n * const sortedDm = dm.sort([\n * ['Origin', ['Acceleration', (a, b) => avg(...a.Acceleration) - avg(...b.Acceleration)]]\n * ]);\n *\n * console.log(dm.getData());\n * console.log(sortedDm.getData());\n *\n * @public\n *\n * @param {Array.} sortingDetails - Sorting details based on which the sorting will be performed.\n * @return {DataModel} Returns a new instance of DataModel with sorted data.\n */\n sort (sortingDetails) {\n const rawData = this.getData({\n order: 'row',\n sort: sortingDetails\n });\n const header = rawData.schema.map(field => field.name);\n const dataInCSVArr = [header].concat(rawData.data);\n\n const sortedDm = new this.constructor(dataInCSVArr, rawData.schema, { dataFormat: 'DSVArr' });\n sortedDm._sortingDetails = sortingDetails;\n return sortedDm;\n }\n\n addField (field) {\n const fieldName = field.fieldName();\n this._colIdentifier += `,${fieldName}`;\n const partialFieldspace = this._partialFieldspace;\n\n if (!partialFieldspace.fieldsObj()[field.fieldName()]) {\n partialFieldspace.fields.push(field);\n } else {\n const fieldIndex = partialFieldspace.fields.findIndex(fieldinst => fieldinst.name === fieldName);\n fieldIndex >= 0 && (partialFieldspace.fields[fieldIndex] = field);\n }\n\n this.__calculateFieldspace().calculateFieldsConfig();\n return this;\n }\n\n /**\n * Creates a new variable calculated from existing variable. This method expects the defination of the newly created\n * variable and a function which resolves the value of the new variable from existing variables.\n *\n * Can create a new measure based on existing variables\n * @example\n * // DataModel already prepared and assigned to dm vairable;\n * const newDm = dataModel.calculateVariable({\n * name: 'powerToWeight',\n * type: 'measure'\n * }, ['horsepower', 'weight_in_lbs', (hp, weight) => hp / weight ]);\n *\n *\n * Can create a new dimension based on existing variables\n * @example\n * // DataModel already prepared and assigned to dm vairable;\n * const child = dataModel.calculateVariable(\n * {\n * name: 'Efficiency',\n * type: 'dimension'\n * }, ['horsepower', (hp) => {\n * if (hp < 80) { return 'low'; },\n * else if (hp < 120) { return 'moderate'; }\n * else { return 'high' }\n * }]);\n *\n * @public\n *\n * @param {Schema} schema: Schema of newly defined variable\n * @param {VariableResolver} resolver: Resolver format to resolve the current variable\n *\n * @return {DataModel} Instance of DataModel with the new field\n */\n calculateVariable (schema, dependency, config = { saveChild: true, replaceVar: false }) {\n const fieldsConfig = this.getFieldsConfig();\n const depVars = dependency.slice(0, dependency.length - 1);\n const retrieveFn = dependency[dependency.length - 1];\n\n if (fieldsConfig[schema.name] && !config.replaceVar) {\n throw new Error(`${schema.name} field already exists in model.`);\n }\n const depFieldIndices = depVars.map((field) => {\n const fieldSpec = fieldsConfig[field];\n if (!fieldSpec) {\n // @todo dont throw error here, use warning in production mode\n throw new Error(`${field} is not a valid column name.`);\n }\n return fieldSpec.index;\n });\n\n let clone = this.clone();\n\n const fs = clone.getFieldspace().fields;\n const suppliedFields = depFieldIndices.map(idx => fs[idx]);\n\n const computedValues = [];\n rowDiffsetIterator(clone._rowDiffset, (i) => {\n const fieldsData = suppliedFields.map(field => field.data[i]);\n computedValues[i] = retrieveFn(...fieldsData, i, fs);\n });\n const [field] = createFields([computedValues], [schema], [schema.name]);\n clone.addField(field);\n\n if (config.saveChild) {\n persistDerivation(clone, DM_DERIVATIVES.CAL_VAR, { config: schema, fields: depVars }, retrieveFn);\n }\n\n return clone;\n }\n\n /**\n * Propagates changes across all the connected DataModel instances.\n *\n * @param {Array} identifiers - A list of identifiers that were interacted with.\n * @param {Object} payload - The interaction specific details.\n *\n * @return {DataModel} DataModel instance.\n */\n propagate (identifiers, config = {}, addToNameSpace, propConfig = {}) {\n const isMutableAction = config.isMutableAction;\n const propagationSourceId = config.sourceId;\n const payload = config.payload;\n const rootModel = getRootDataModel(this);\n const propagationNameSpace = rootModel._propagationNameSpace;\n const rootGroupByModel = getRootGroupByModel(this);\n const rootModels = {\n groupByModel: rootGroupByModel,\n model: rootModel\n };\n\n addToNameSpace && addToPropNamespace(propagationNameSpace, config, this);\n propagateToAllDataModels(identifiers, rootModels, { propagationNameSpace, sourceId: propagationSourceId },\n Object.assign({\n payload\n }, config));\n\n if (isMutableAction) {\n propagateImmutableActions(propagationNameSpace, rootModels, {\n config,\n propConfig\n }, this);\n }\n\n return this;\n }\n\n /**\n * Associates a callback with an event name.\n *\n * @param {string} eventName - The name of the event.\n * @param {Function} callback - The callback to invoke.\n * @return {DataModel} Returns this current DataModel instance itself.\n */\n on (eventName, callback) {\n switch (eventName) {\n case PROPAGATION:\n this._onPropagation.push(callback);\n break;\n }\n return this;\n }\n\n /**\n * Unsubscribes the callbacks for the provided event name.\n *\n * @param {string} eventName - The name of the event to unsubscribe.\n * @return {DataModel} Returns the current DataModel instance itself.\n */\n unsubscribe (eventName) {\n switch (eventName) {\n case PROPAGATION:\n this._onPropagation = [];\n break;\n\n }\n return this;\n }\n\n /**\n * This method is used to invoke the method associated with propagation.\n *\n * @param {Object} payload The interaction payload.\n * @param {DataModel} identifiers The propagated DataModel.\n * @memberof DataModel\n */\n handlePropagation (propModel, payload) {\n let propListeners = this._onPropagation;\n propListeners.forEach(fn => fn.call(this, propModel, payload));\n }\n\n /**\n * Perfoms binning on a measure field based on a binning configuration. This method does not aggregate the number of\n * rows present in DataModel instance after binning, it just adds a new field with the binned value. Refer binning\n * {@link example_of_binning | example} to have a intuition of what binning is and the use case.\n *\n * Binning can be configured by\n * - providing custom bin configuration with non uniform buckets\n * - providing bin count\n * - providing each bin size\n *\n * When custom buckets are provided as part of binning configuration\n * @example\n * // DataModel already prepared and assigned to dm vairable\n * const buckets = {\n * start: 30\n * stops: [80, 100, 110]\n * };\n * const config = { buckets, name: 'binnedHP' }\n * const binDM = dataModel.bin('horsepower', config);\\\n *\n * @text\n * When `binCount` is defined as part of binning configuration\n * @example\n * // DataModel already prepared and assigned to dm vairable\n * const config = { binCount: 5, name: 'binnedHP' }\n * const binDM = dataModel.bin('horsepower', config);\n *\n * @text\n * When `binSize` is defined as part of binning configuration\n * @example\n * // DataModel already prepared and assigned to dm vairable\n * const config = { binSize: 200, name: 'binnedHorsepower' }\n * const binDM = dataModel.bin('horsepower', config);\n *\n * @public\n *\n * @param {String} name Name of measure which will be used to create bin\n * @param {Object} config Config required for bin creation\n * @param {Array.} config.bucketObj.stops Defination of bucket ranges. Two subsequent number from arrays\n * are picked and a range is created. The first number from range is inclusive and the second number from range\n * is exclusive.\n * @param {Number} [config.bucketObj.startAt] Force the start of the bin from a particular number.\n * If not mentioned, the start of the bin or the lower domain of the data if stops is not mentioned, else its\n * the first value of the stop.\n * @param {Number} config.binSize Bucket size for each bin\n * @param {Number} config.binCount Number of bins which will be created\n * @param {String} config.name Name of the new binned field to be created\n *\n * @returns {DataModel} Instance of new DataModel with the newly created bin.\n */\n bin (measureName, config = { }) {\n const clone = this.clone();\n const binFieldName = config.name || `${measureName}_binned`;\n if (this.getFieldsConfig()[binFieldName] || !this.getFieldsConfig()[measureName]) {\n throw new Error(`Field ${measureName} already exists.`);\n }\n const field = this._partialFieldspace.fields.find(currfield => currfield.name === measureName);\n const dataSet = createBinnedFieldData(field, this._rowDiffset, config);\n const binField = createFields([dataSet.data], [\n {\n name: binFieldName,\n type: FieldType.MEASURE,\n subtype: 'discrete', // @todo : DimensionSubtype\n bins: {\n range: dataSet.range,\n mid: dataSet.mid\n }\n }], [binFieldName])[0];\n clone.addField(binField);\n persistDerivation(clone, DM_DERIVATIVES.BIN, { measureName, config, binFieldName }, null);\n return clone;\n }\n}\n\nexport default DataModel;\n","import { fnList } from '../operator/group-by-function';\n\nexport const { sum, avg, min, max, first, last, count, std: sd } = fnList;\n","import DataModel from './datamodel';\nimport {\n compose,\n bin,\n select,\n project,\n groupby as groupBy,\n calculateVariable,\n sort,\n crossProduct,\n difference,\n naturalJoin,\n leftOuterJoin,\n rightOuterJoin,\n fullOuterJoin,\n union\n} from './operator';\nimport * as Stats from './stats';\nimport * as enums from './enums';\nimport { DateTimeFormatter } from './utils';\nimport { DataFormat, FilteringMode } from './constants';\nimport pkg from '../package.json';\n\nDataModel.Operators = {\n compose,\n bin,\n select,\n project,\n groupBy,\n calculateVariable,\n sort,\n crossProduct,\n difference,\n naturalJoin,\n leftOuterJoin,\n rightOuterJoin,\n fullOuterJoin,\n union\n};\nDataModel.Stats = Stats;\nObject.assign(DataModel, enums);\nDataModel.DateTimeFormatter = DateTimeFormatter;\nDataModel.DataFormat = DataFormat;\nDataModel.FilteringMode = FilteringMode;\nDataModel.version = pkg.version;\n\nexport default DataModel;\n","\n/**\n * DataModel's opearators are exposed as composable functional operators as well as chainable operators. Chainable\n * operators are called on the instances of {@link Datamodel} and {@link Relation} class.\n *\n * Those same operators can be used as composable operators from `DataModel.Operators` namespace.\n *\n * All these operators have similar behaviour. All these operators when called with the argument returns a function\n * which expects a DataModel instance.\n *\n * @public\n * @module Operators\n * @namespace DataModel\n */\n\n/**\n * This is functional version of selection operator. {@link link_to_selection | Selection} is a row filtering operation.\n * It takes {@link SelectionPredicate | predicate} for filtering criteria and returns a function.\n * The returned function is called with the DataModel instance on which the action needs to be performed.\n *\n * {@link SelectionPredicate} is a function which returns a boolean value. For selection opearation the selection\n * function is called for each row of DataModel instance with the current row passed as argument.\n *\n * After executing {@link SelectionPredicate} the rows are labeled as either an entry of selection set or an entry\n * of rejection set.\n *\n * {@link FilteringMode} operates on the selection and rejection set to determine which one would reflect in the\n * resulatant datamodel.\n *\n * @warning\n * [Warn] Selection and rejection set is only a logical idea for concept explanation purpose.\n *\n * @error\n * [Error] `FilteringMode.ALL` is not a valid working mode for functional version of `select`. Its only avialable on the\n * chained version.\n *\n * @example\n * const select = DataModel.Operators.select;\n * usaCarsFn = select(fields => fields.Origin.value === 'USA');\n * usaCarsDm = usaCarsFn(dm);\n * console.log(usaCarsDm);\n *\n * @public\n * @namespace DataModel\n * @module Operators\n *\n * @param {SelectionPredicate} selectFn - Predicate funciton which is called for each row with the current row\n * ```\n * function (row, i) { ... }\n * ```\n * @param {Object} [config] - The configuration object to control the inclusion exclusion of a row in resultant\n * DataModel instance\n * @param {FilteringMode} [config.mode=FilteringMode.NORMAL] - The mode of the selection\n *\n * @return {PreparatorFunction} Function which expects an instance of DataModel on which the operator needs to be\n * applied.\n */\nexport const select = (...args) => dm => dm.select(...args);\n\n/**\n * This is functional version of projection operator. {@link link_to_projection | Projection} is a column filtering\n * operation.It expects list of fields name and either include those or exclude those based on {@link FilteringMode} on\n * the resultant variable.It returns a function which is called with the DataModel instance on which the action needs\n * to be performed.\n *\n * Projection expects array of fields name based on which it creates the selection and rejection set. All the field\n * whose name is present in array goes in selection set and rest of the fields goes in rejection set.\n *\n * {@link FilteringMode} operates on the selection and rejection set to determine which one would reflect in the\n * resulatant datamodel.\n *\n * @warning\n * Selection and rejection set is only a logical idea for concept explanation purpose.\n *\n * @error\n * `FilteringMode.ALL` is not a valid working mode for functional version of `select`. Its only avialable on the\n * chained version.\n *\n * @public\n * @namespace DataModel\n * @module Operators\n *\n * @param {Array.} projField - An array of column names in string or regular expression.\n * @param {Object} [config] - An optional config to control the creation of new DataModel\n * @param {FilteringMode} [config.mode=FilteringMode.NORMAL] - Mode of the projection\n *\n * @return {PreparatorFunction} Function which expects an instance of DataModel on which the operator needs to be\n * applied.\n */\nexport const project = (...args) => dm => dm.project(...args);\n\n/**\n * This is functional version of binnig operator. Binning happens on a measure field based on a binning configuration.\n * Binning in DataModel does not aggregate the number of rows present in DataModel instance after binning, it just adds\n * a new field with the binned value. Refer binning {@link example_of_binning | example} to have a intuition of what\n * binning is and the use case.\n *\n * Binning can be configured by\n * - providing custom bin configuration with non uniform buckets\n * - providing bin count\n * - providing each bin size\n *\n * When custom buckets are provided as part of binning configuration\n * @example\n * // DataModel already prepared and assigned to dm vairable\n * const buckets = {\n * start: 30\n * stops: [80, 100, 110]\n * };\n * const config = { buckets, name: 'binnedHP' }\n * const binFn = bin('horsepower', config);\n * const binnedDm = binFn(dm);\n *\n * @text\n * When `binCount` is defined as part of binning configuration\n * @example\n * // DataModel already prepared and assigned to dm vairable\n * const config = { binCount: 5, name: 'binnedHP' }\n * const binFn = bin('horsepower', config);\n * const binnedDm = binFn(Dm);\n *\n * @text\n * When `binSize` is defined as part of binning configuration\n * @example\n * // DataModel already prepared and assigned to dm vairable\n * const config = { binSize: 200, name: 'binnedHorsepower' }\n * const binnedDm = dataModel.bin('horsepower', config);\n * const binnedDm = binFn(Dm);\n *\n * @public\n * @namespace DataModel\n * @module Operators\n *\n * @param {String} name Name of measure which will be used to create bin\n * @param {Object} config Config required for bin creation\n * @param {Array.} config.bucketObj.stops Defination of bucket ranges. Two subsequent number from arrays\n * are picked and a range is created. The first number from range is inclusive and the second number from range\n * is exclusive.\n * @param {Number} [config.bucketObj.startAt] Force the start of the bin from a particular number.\n * If not mentioned, the start of the bin or the lower domain of the data if stops is not mentioned, else its\n * the first value of the stop.\n * @param {Number} config.binSize Bucket size for each bin\n * @param {Number} config.binCount Number of bins which will be created\n * @param {String} config.name Name of the new binned field to be created\n *\n * @return {PreparatorFunction} Function which expects an instance of DataModel on which the operator needs to be\n * applied.\n */\nexport const bin = (...args) => dm => dm.bin(...args);\n\n/**\n * This is functional version of `groupBy` operator.Groups the data using particular dimensions and by reducing\n * measures. It expects a list of dimensions using which it projects the datamodel and perform aggregations to reduce\n * the duplicate tuples. Refer this {@link link_to_one_example_with_group_by | document} to know the intuition behind\n * groupBy.\n *\n * DataModel by default provides definition of few {@link reducer | Reducers}.\n * {@link ReducerStore | User defined reducers} can also be registered.\n *\n * This is the chained implementation of `groupBy`.\n * `groupBy` also supports {@link link_to_compose_groupBy | composability}\n *\n * @example\n * const groupBy = DataModel.Operators.groupBy;\n * const groupedFn = groupBy(['Year'], { horsepower: 'max' } );\n * groupedDM = groupByFn(dm);\n *\n * @public\n *\n * @param {Array.} fieldsArr - Array containing the name of dimensions\n * @param {Object} [reducers={}] - A map whose key is the variable name and value is the name of the reducer. If its\n * not passed, or any variable is ommitted from the object, default aggregation function is used from the\n * schema of the variable.\n *\n * @return {PreparatorFunction} Function which expects an instance of DataModel on which the operator needs to be\n * applied.\n */\nexport const groupBy = (...args) => dm => dm.groupBy(...args);\n\n/**\n * Enables composing operators to run multiple operations and save group of operataion as named opration on a DataModel.\n * The resulting DataModel will be the result of all the operation provided. The operations provided will be executed in\n * a serial manner ie. result of one operation will be the input for the next operations (like pipe operator in unix).\n *\n * Suported operations in compose are\n * - `select`\n * - `project`\n * - `groupBy`\n * - `bin`\n * - `compose`\n *\n * @example\n * const compose = DataModel.Operators.compose;\n * const select = DataModel.Operators.select;\n * const project = DataModel.Operators.project;\n *\n * let composedFn = compose(\n * select(fields => fields.netprofit.value <= 15),\n * project(['netprofit', 'netsales']));\n *\n * const dataModel = new DataModel(data1, schema1);\n *\n * let composedDm = composedFn(dataModel);\n *\n * @public\n * @namespace DataModel\n * @module Operators\n *\n * @param {Array.} operators: An array of operation that will be applied on the\n * datatable.\n *\n * @returns {DataModel} Instance of resultant DataModel\n */\nexport const compose = (...operations) =>\n (dm, config = { saveChild: true }) => {\n let currentDM = dm;\n let frstChild;\n const derivations = [];\n const saveChild = config.saveChild;\n\n operations.forEach((operation) => {\n currentDM = operation(currentDM);\n derivations.push(...currentDM._derivation);\n if (!frstChild) {\n frstChild = currentDM;\n }\n });\n\n saveChild && currentDM.addParent(dm, derivations);\n if (derivations.length > 1) {\n frstChild.dispose();\n }\n\n return currentDM;\n };\n","/**\n * Wrapper on calculateVariable() method of DataModel to behave\n * the pure-function functionality.\n *\n * @param {Array} args - The argument list.\n * @return {any} Returns the returned value of calling function.\n */\nexport const calculateVariable = (...args) => dm => dm.calculateVariable(...args);\n\n/**\n * Wrapper on sort() method of DataModel to behave\n * the pure-function functionality.\n *\n * @param {Array} args - The argument list.\n * @return {any} Returns the returned value of calling function.\n */\nexport const sort = (...args) => dm => dm.sort(...args);\n","import { crossProduct } from './cross-product';\nimport { naturalJoinFilter } from './natural-join-filter-function';\n\nexport function naturalJoin (dataModel1, dataModel2) {\n return crossProduct(dataModel1, dataModel2, naturalJoinFilter(dataModel1, dataModel2), true);\n}\n"],"sourceRoot":""} \ No newline at end of file diff --git a/package.json b/package.json index 3b70ec9..2371c8f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "datamodel", "description": "Relational algebra compliant in-memory tabular data store", "homepage": "https://github.com/chartshq/datamodel", - "version": "2.0.1", + "version": "2.0.2", "license": "MIT", "main": "dist/datamodel.js", "author": "Charts.com ",