Probabilistic N-Gram Dataset Merge

Developer
Size
19,294 Kb
Views
22,264

How do I make an probabilistic n-gram dataset merge?

What is a probabilistic n-gram dataset merge? How do you make a probabilistic n-gram dataset merge? This script and codes were developed by Ian Joubert on 01 November 2022, Tuesday.

Probabilistic N-Gram Dataset Merge Previews

Probabilistic N-Gram Dataset Merge - Script Codes HTML Codes

<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Probabilistic N-Gram Dataset Merge</title> <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/angular-material/0.8.2/angular-material.min.css'> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div class="myDemo"> <div class="myApp" ng-app="myApp" ng-controller="myController as myCtrl" layout="row" layout-padding> <!-- SIDE NAVIGATION SECTION A side navigation window where additional actions and links are loaded 1.) Merge Actions Navigation --> <aside> <md-sidenav class="sidenav-zone md-whiteframe-z1" md-component-id="mergeSettings"> <md-toolbar class="md-primary" layout="row" layout-align="center center"> <section layout="row" layout-fill> <h3 class="md-toolbar-tools">Merge Settings</h3> <md-button aria-label="Close Merge Settings" ng-click="myCtrl.closeSideNav()"> <ng-md-icon icon="cancel"></ng-md-icon> </md-button> </section> </md-toolbar> <md-content layout="column" layout-fill> <section layout-fill layout-padding> <ol layout-fill> <li> <md-button class="btn-std btn-std-smlpad md-primary" aria-label="Show Actions" ng-click="myCtrl.showMergeSettings('standardize')">Standardize</md-button> <span> field data by changing data to (a) <i>desired field types</i>, (b) <i>adjusting the data lengths</i>,(c) <i>removing whitespace</i> and (d) <i>lowercase</i> all text. Please select the field types for each field before standardizing, otherwise undesired results might occur. </span> </li> <li> <span>Select</span> <md-button class="btn-std btn-std-smlpad md-primary" aria-label="Show Actions" ng-click="myCtrl.showMergeSettings('match')">Matching</md-button> <span> fields on both the datasets. These fields will be used as the "primary key" for the merge process. These fields <i>needs to correspond 100% by data type</i> (eg. integer, number, string etc.) to ensure a good startingpoint for the merging process.</i> </span> </li> <li> <md-button class="btn-std btn-std-smlpad md-primary" aria-label="Show Actions" ng-click="myCtrl.showMergeSettings('index')">Indexing</md-button> <span> the data sets depends on <i>the order of indexes ("index keys")</i> of each field. Merging will de done in ascending index order, therefore, the higher the order (lower the index) the better the data needs to correspond. Each index that is selected as a key will be used to ensure a better match. </span> </li> <li> <span>Determine the </span> <md-button class="btn-std btn-std-smlpad md-primary" aria-label="Show Actions" ng-click="myCtrl.showMergeSettings('sort')">Sorting</md-button> <span> order for each index field by <i>changing the sort direction</i>. The direction of sorting could play a role on the speed in which the records are found. If more data correlates to one end and the sorting direction is starting at the opposite, this could lead to longer search times. </span> </li> </ol> </section> <footer layout="row" layout-align="end end" layout-padding flex></footer> </md-content> </md-sidenav> </aside>
<div flex="20"></div>
<!-- CENTER CONTENT SECTION The main content area that consist of: 1.) Title and Header 2.) Tabs - Upload, Process, Merge, Results -->
<section layout="column" flex> <!-- CONTENT HEADER --> <article layout="column" layout-align="center center" flex> <h1>Angular Demo Application</h1> <h3>Probabilistic N-Gram Dataset Merge</h3> <small>This Codepen was developed by: Ian Joubert</small> <strong><small>...in progress...</small></strong> <p> A Codepen to merge two datasets that is indiscriminately linked, using N-Gram probability testing.</p> </article> <!-- CONTENT TABS --> <md-tabs layout-fill> <!-- ##################################################################################################################################### --> <md-tab><!-- CONTENT TAB NO 1 - UPLOAD/FILE DROP --> <!-- Tab Title --> <md-tab-label> <h3>Upload</h3> </md-tab-label> <!-- Tab Header --> <div class="table" layout="column" layout-align="center center" layout-fill> <h3 class="sub-title" flex>Upload Files</h3> <span class="content" flex> Load your files to an Amazon Server or use the files already loaded. </span> <div class="notice" layout="row" ng-if="myCtrl.serverFiles.length === 0 && myCtrl.uploadedFiles.length === 0" layout-fill> <span flex> You have not uploaded or downloaded any files. Please do that before you continue. </span> </div> </div> <!-- Tab Content Zone 1.) File drops --> <div class="drop-zone" layout="row" layout-padding layout-fill> <div layout="column" layout-align="center center" flex> <h4 class="title" flex>Base Dataset File</h4> <div layout="column" layout-align="center center" layout-padding ng-file-drop ng-file-select ng-file-change="myCtrl.dropBox(baseFile, 'base')" ng-model="baseFile" drag-over-class="{accept:'dragover', reject:'dragover-err', delay:100}" class="drop-box" ng-multiple="false" allow-dir="true" ng-accept="'text/csv'" flex> Drop CSV file <h5>or click to select</h5> </div> <md-progress-linear class="md-accent" md-mode="determinate" value="{{myCtrl.progress.base}}"></md-progress-linear> </div> <div layout="column" layout-align="center center" flex> <h4 class="title" flex>Mixin Dataset File</h4> <div layout="column" layout-align="center center" layout-padding ng-file-drop ng-file-select ng-file-change="myCtrl.dropBox(mixinFile, 'mixin')" ng-model="mixinFile" drag-over-class="{accept:'dragover', reject:'dragover-err', delay:100}" class="drop-box" ng-multiple="false" allow-dir="true" ng-accept="'text/csv'" flex> Drop CSV file <h5>or click to select</h5> </div> <md-progress-linear class="md-accent" md-mode="determinate" value="{{myCtrl.progress.mixin}}"></md-progress-linear> </div> </div> <!-- Tab Content Zone 2.) Action Buttons --> <div class="action-zone" layout="row" layout-align="center center" layout-fill> <md-button class="btn-icon-raised md-raised md-primary" layout="row" layout-align="center center" aria-label="Get Files" ng-click="myCtrl.getFiles()" flex> <ng-md-icon layout-padding icon="folder"></ng-md-icon> <h4>Get files from server</h4> </md-button> <md-button class="btn-progress-flat" aria-label="Progress" ng-if="myCtrl.progress.files && myCtrl.showFilesProgress"> <md-progress-circular class="md-accent" md-mode="determinate" value="{{myCtrl.progress.files}}"></md-progress-circular> </md-button> </div> <!-- Tab Content Zone 3.) BASE File information --> <div class="file-zone table" layout="column" ng-if="myCtrl.uploadedFiles.length > 0" layout-fill> <h4 class="table-header" layout="row" layout-align="center center" layout-fill>Uploaded Files</h4> <ul layout="column" layout-fill> <li layout="column" layout-gt-md="row" ng-repeat="uploadedFile in myCtrl.uploadedFiles track by $index" layout-fill> <div class="tr" layout="row" layout-align="start center" flex> <div class="td-icon-btn"> <md-button aria-label="Delete" ng-click="myCtrl.deleteFile(uploadedFile)"> <ng-md-icon icon="delete"></ng-md-icon> </md-button> </div> <div class="td name" flex>{{uploadedFile.meta.name}}</div> </div> <div class="tr" layout="row" layout-align="start center"> <div class="td">{{uploadedFile.meta.numKBytes}}KB</div> <div class="td">{{uploadedFile.meta.numRecords}} records</div> <div class="td">{{uploadedFile.meta.numFields}} fields</div> <div class="td td-clear td-slct" ng-if="uploadedFile.meta.allocation">{{uploadedFile.meta.allocation}}</div> <div class="td-clear td-btn" layout="row" ng-if="!uploadedFile.meta.allocation"> <md-button aria-label="Base" ng-click="myCtrl.allocateFile(uploadedFile,'base')">Base</md-button> <md-button aria-label="Mixin" ng-click="myCtrl.allocateFile(uploadedFile,'mixin')">Mixin</md-button> </div> </div> </li> </ul> </div> <!-- Tab Content Zone 4.) Notifications --> <div class="notify-zone" layout="column" layout-padding ng-if="myCtrl.showUpdate.updateServer" layout-fill> <span layout="row" layout-align="center center" layout-fill>Updating server...</span> <md-progress-linear class="md-accent" md-mode="indeterminate"></md-progress-linear> </div> <!-- Tab Content Zone 5.) MIXIN File information --> <div class="file-zone table" layout="column" ng-if="myCtrl.serverFiles.length > 0" layout-fill> <h4 class="table-header" layout="row" layout-align="center center" layout-fill>Server Files</h4> <ul layout="column" layout-fill> <li layout="column" layout-gt-md="row" ng-repeat="serverFile in myCtrl.serverFiles track by $index" layout-fill> <div class="tr" layout="row" layout-align="start center" flex> <div class="td name" flex>{{serverFile.meta.name}}</div> </div> <div class="tr" layout="row" layout-align="start center"> <div class="td">{{serverFile.meta.numKBytes}}KB</div> <div class="td">{{serverFile.meta.numRecords}} records</div> <div class="td">{{serverFile.meta.numFields}} fields</div> <div class="td td-clear td-slct" ng-if="serverFile.meta.allocation">{{serverFile.meta.allocation}}</div> <div class="td-clear td-btn" layout="row" ng-if="!serverFile.meta.allocation"> <md-button aria-label="Allocate" ng-click="myCtrl.allocateFile(serverFile, 'base')">Base</md-button> <md-button aria-label="Allocate" ng-click="myCtrl.allocateFile(serverFile, 'mixin')">Mixin</md-button> </div> </div> </li> </ul> </div> </md-tab><!-- End of Tab --> <!-- ##################################################################################################################################### --> <!-- ##################################################################################################################################### --> <md-tab><!-- CONTENT TAB NO 2 - PREPARE --> <!-- Tab Title --> <md-tab-label> <h3>Prepare</h3> </md-tab-label> <!-- Tab Header --> <div class="table" layout="column" layout-align="center center" layout-fill> <h3 class="sub-title" flex>Prepare Datasets</h3> <span class="content" flex> <span>Before merging the two selected datasets, prepare the fields for a succesfull merge. All actions to prepare the datasets are located in the </span> <md-button class="btn-std md-primary" aria-label="Merge Settings" ng-click="myCtrl.toggleSideNav()" ng-disabled="!myCtrl.file.base.meta && !myCtrl.file.mixin.meta">Merge Settings</md-button> <span> side bar. Head over to the "Merge" tab, once the datasets are prepared to your satisfaction.</span> </span> <div class="notice" layout="row" ng-if="!myCtrl.file.base.meta && !myCtrl.file.mixin.meta" layout-fill> <span flex> You have not selected any datasets to be merged. Please allocate the "BASE" and "MIXIN" datasets for processing before you can continue. These allocations can be done under the "Upload" tab. </span> </div> </div> <!-- Tab Content Zone 1.) Data Tables --> <div class="data-zone table" layout="column" layout-gt-md="row" layout-margin ng-if="myCtrl.file.base.meta && myCtrl.file.mixin.meta" layout-fill> <!-- Table a.) BASE FILE DATASET --> <div class="data" layout="column" layout-fill> <header><!-- Table Title & Header --> <h4 class="title" layout="row" layout-align="center center" layout-fill>Base Dataset</h4> <h5 class="table-header" layout="row" layout-align="center center" layout-fill>{{myCtrl.file.base.meta.name}}</h5> <!-- Table Actions Progress Bar --> <div class="notify-zone" layout="column" layout-padding ng-if="myCtrl.showUpdate.processBase" layout-fill> <span layout="row" layout-align="center center" layout-fill>Processing base data...</span> <md-progress-linear class="md-accent" md-mode="indeterminate"></md-progress-linear> </div> </header> <main><!-- Table Content --> <ul layout="column" layout-fill> <!-- Table content header row --> <li class="tr" layout="row" layout-align="start center"> <div class="th col-50">Index</div> <div class="th" layout-fill>Field</div> <div class="th" layout-fill>Data</div> <div class="th col-90" ng-if="myCtrl.mergeActions.standardize">Type</div> <div class="th col-50" ng-if="myCtrl.mergeActions.match || myCtrl.mergeActions.index">Key</div> </li> <!-- Table content (Primary Key Action) --> <!-- Hidden --> <li class="tr key-header" layout="row" layout-align="start center" ng-if="myCtrl.showPrimaryKey.base" layout-fill> <div class="th" flex>{{myCtrl.numPrimaryKeys.base}} Primary Key</div> </li> <!-- Hidden --> <li class="tr key" layout="row" layout-align="start center" ng-repeat="field in myCtrl.file.base.meta.fields track by $index" ng-if="field.primaryKey"> <div class="td td-icon-only col-50" layout="row"> <span>{{$index+1}}</span> <div class="icon" ng-if="field.primaryKey"> <ng-md-icon icon="vpn_key"></ng-md-icon> </div> </div> <div class="td" flex>{{field.value}}</div> <div class="td" flex> {{ myCtrl.testEmpty( myCtrl.file.base.data[myCtrl.recordNo.base][field.value] ) }} </div> <div class="col-90" layout="row" ng-if="myCtrl.mergeActions.standardize"> <md-select ng-model="field.type" layout-fill> <md-select-label layout-fill>{{ field.type ? field.type : '--?--' }}</md-select-label> <md-option ng-repeat="dataType in myCtrl.fieldTypes" ng-value="dataType">{{dataType}}</md-option> </md-select> </div> <div class="td-check col-50" layout="row" ng-if="myCtrl.mergeActions.match"> <md-checkbox ng-model="field.primaryKey" aria-label="Primary Key" ng-change="myCtrl.setPrimaryKey(myCtrl.file.base,field)"></md-checkbox> </div> </li> <!-- Hidden --> <li class="tr key-header" layout="row" layout-align="start center" ng-if="myCtrl.showIndexKey.base" layout-fill> <div class="th" flex>{{myCtrl.numIndexKeys.base}} Index Key{{(myCtrl.numIndexKeys.base>1)?'s':''}}</div> </li> <!-- Table content --> <li class="tr" layout="row" layout-align="start center" ng-repeat="field in myCtrl.file.base.meta.fields track by $index" ng-if="!field.primaryKey"> <!-- Hidden --> <div class="col-50" layout="row" ng-if="myCtrl.mergeActions.index"> <md-select ng-model="field.index"> <md-select-label>{{ $index+1 }}</md-select-label> <md-option ng-repeat="(key, value) in myCtrl.file.base.meta.fields track by $index" ng-if="value.primaryKey === false || !value.primaryKey" ng-value="key" ng-click="myCtrl.setIndexKeyOrder(myCtrl.file.base.meta.fields, field, key)">{{key+1}} </md-option> </md-select> </div> <!-- Visible --> <div class="td td-icon-only col-50" layout="row" ng-if="!myCtrl.mergeActions.index"> <span>{{$index+1}}</span> <div class="icon" ng-if="field.indexKey"> <ng-md-icon icon="vpn_key"></ng-md-icon> </div> </div> <div class="td" flex>{{field.value}}</div> <div class="td" flex> {{ myCtrl.testEmpty( myCtrl.file.base.data[myCtrl.recordNo.base][field.value] ) }} </div> <!-- Hidden --> <div class="col-90" layout="row" ng-if="myCtrl.mergeActions.standardize"> <md-select ng-model="field.type" layout-fill> <md-select-label layout-fill>{{ field.type ? field.type : '--?--' }}</md-select-label> <md-option ng-repeat="dataType in myCtrl.fieldTypes" ng-value="dataType">{{dataType}}</md-option> </md-select> </div> <!-- Hidden --> <div class="td-check col-50" layout="row" ng-if="myCtrl.mergeActions.match"> <md-checkbox ng-model="field.primaryKey" aria-label="Primary Key" ng-change="myCtrl.setPrimaryKey(myCtrl.file.base,field)"></md-checkbox> </div> <!-- Hidden --> <div class="td-check col-50" layout="row" ng-if="myCtrl.mergeActions.index"> <md-checkbox ng-model="field.indexKey" aria-label="Index Key" ng-change="myCtrl.setIndexKey(myCtrl.file.base,field)"></md-checkbox> </div> </li> </ul> </main> <!-- Table Footer --> <footer class="td" layout="row" layout-align="center center" layout-fill> <md-button class="btn-icon-only" aria-label="Previous" ng-click="myCtrl.changeRecord('subtract','base')"> <ng-md-icon icon="arrow_back"></ng-md-icon> </md-button> <span> RECORDS {{(myCtrl.recordNo.base + 1) + '/' + myCtrl.file.base.data.length}} </span> <md-button class="btn-icon-only" aria-label="Next" ng-click="myCtrl.changeRecord('add','base')"> <ng-md-icon icon="arrow_forward"></ng-md-icon> </md-button> </footer> </div> <!-- Table a.) MIXIN FILE DATASET --> <div class="data" layout="column" layout-fill> <header><!-- Table Title & Header --> <h4 class="title" layout="row" layout-align="center center" layout-fill>Mixin Dataset</h4> <h5 class="table-header" layout="row" layout-align="center center" layout-fill>{{myCtrl.file.mixin.meta.name}}</h5> <div class="notify-zone" layout="column" layout-padding ng-if="myCtrl.showUpdate.processMixin" layout-fill> <span layout="row" layout-align="center center" layout-fill>Processing mixin data...</span> <md-progress-linear class="md-accent" md-mode="indeterminate"></md-progress-linear> </div> </header> <main><!-- Table Content --> <ul layout="column" layout-fill> <!-- Table content header row --> <li class="tr" layout="row" layout-align="start center"> <div class="th col-50">Index</div> <div class="th" layout-fill>Field</div> <div class="th" layout-fill>Data</div> <div class="th col-90" ng-if="myCtrl.mergeActions.standardize">Type</div> <div class="th col-50" ng-if="myCtrl.mergeActions.match || myCtrl.mergeActions.index">Key</div> <div class="th col-50" ng-if="myCtrl.mergeActions.sort">Sort</div> </li> <!-- Table content (Primary Key Action) --> <!-- Hidden --> <li class="tr key-header" layout="row" layout-align="start center" ng-if="myCtrl.showPrimaryKey.mixin" layout-fill> <div class="th" flex>{{myCtrl.numPrimaryKeys.mixin}} Primary Key</div> </li> <!-- Hidden --> <li class="tr key" layout="row" layout-align="start center" ng-repeat="field in myCtrl.file.mixin.meta.fields track by $index" ng-if="field.primaryKey"> <div class="td td-icon-only col-50" layout="row"> <span>{{$index+1}}</span> <div class="icon" ng-if="field.primaryKey"> <ng-md-icon icon="vpn_key"></ng-md-icon> </div> </div> <div class="td" flex>{{field.value}}</div> <div class="td" flex> {{ myCtrl.testEmpty( myCtrl.file.mixin.data[myCtrl.recordNo.mixin][field.value] ) }} </div> <div class="col-90" layout="row" ng-if="myCtrl.mergeActions.standardize"> <md-select ng-model="field.type" layout-fill> <md-select-label layout-fill>{{ field.type ? field.type : '--?--' }}</md-select-label> <md-option ng-repeat="dataType in myCtrl.fieldTypes" ng-value="dataType">{{dataType}}</md-option> </md-select> </div> <div class="td-check col-50" layout="row" ng-if="myCtrl.mergeActions.match"> <md-checkbox ng-model="field.primaryKey" aria-label="Primary Key" ng-change="myCtrl.setPrimaryKey(myCtrl.file.mixin,field)"></md-checkbox> </div> <div class="td-icon-btn col-50" layout="row" layout-align="center center" ng-if="myCtrl.mergeActions.sort"> <md-button aria-label="Sort Order" ng-click="myCtrl.setSortOrder(field)"> <ng-md-icon icon="{{field.sortOrder.icon}}"></ng-md-icon> </md-button> </div> </li> <!-- Hidden --> <li class="tr key-header" layout="row" layout-align="start center" ng-if="myCtrl.showIndexKey.mixin" layout-fill> <div class="th" flex>{{myCtrl.numIndexKeys.mixin}} Index Key{{(myCtrl.numIndexKeys.mixin>1)?'s':''}}</div> </li> <!-- Table content --> <li class="tr" layout="row" layout-align="start center" ng-repeat="field in myCtrl.file.mixin.meta.fields track by $index" ng-if="!field.primaryKey"> <!-- Hidden --> <div class="col-50" layout="row" ng-if="myCtrl.mergeActions.index"> <md-select ng-model="field.index"> <md-select-label>{{ $index+1 }}</md-select-label> <md-option ng-repeat="(key, value) in myCtrl.file.mixin.meta.fields track by $index" ng-if="value.primaryKey === false || !value.primaryKey" ng-value="key" ng-click="myCtrl.setIndexKeyOrder(myCtrl.file.mixin.meta.fields, field, key)">{{key+1}} </md-option> </md-select> </div> <!-- Visible --> <div class="td td-icon-only col-50" layout="row" ng-if="!myCtrl.mergeActions.index"> <span>{{$index+1}}</span> <div class="icon" ng-if="field.indexKey"> <ng-md-icon icon="vpn_key"></ng-md-icon> </div> </div> <div class="td" flex>{{field.value}}</div> <div class="td" flex> {{ myCtrl.testEmpty( myCtrl.file.mixin.data[myCtrl.recordNo.mixin][field.value] ) }} </div> <!-- Hidden --> <div class="col-90" layout="row" ng-if="myCtrl.mergeActions.standardize"> <md-select ng-model="field.type" layout-fill> <md-select-label layout-fill>{{ field.type ? field.type : '--?--' }}</md-select-label> <md-option ng-repeat="dataType in myCtrl.fieldTypes" ng-value="dataType">{{dataType}}</md-option> </md-select> </div> <!-- Hidden --> <div class="td-check col-50" layout="row" ng-if="myCtrl.mergeActions.match"> <md-checkbox ng-model="field.primaryKey" aria-label="Primary Key" ng-change="myCtrl.setPrimaryKey(myCtrl.file.mixin,field)"></md-checkbox> </div> <!-- Hidden --> <div class="td-icon-btn col-50" layout="row" layout-align="center center" ng-if="myCtrl.mergeActions.sort"> <md-button aria-label="Sort Order" ng-click="myCtrl.setSortOrder(field)"> <ng-md-icon icon="{{field.sortOrder.icon}}"></ng-md-icon> </md-button> </div> <!-- Hidden --> <div class="td-check col-50" layout="row" ng-if="myCtrl.mergeActions.index"> <md-checkbox ng-model="field.indexKey" aria-label="Index Key" ng-change="myCtrl.setIndexKey(myCtrl.file.mixin,field)"></md-checkbox> </div> </li> </ul> </main> <!-- Table Footer --> <footer class="td" layout="row" layout-align="center center" layout-fill> <md-button class="btn-icon-only" aria-label="Previous" ng-click="myCtrl.changeRecord('subtract','mixin')"> <ng-md-icon icon="arrow_back"></ng-md-icon> </md-button> <span> RECORDS {{(myCtrl.recordNo.mixin+1) + '/' + myCtrl.file.mixin.data.length}} </span> <md-button class="btn-icon-only" aria-label="Next" ng-click="myCtrl.changeRecord('add','mixin')"> <ng-md-icon icon="arrow_forward"></ng-md-icon> </md-button> </footer> </div> </div><!-- End of Tab Content Zone 1.) Data Tables --> <!-- Tab Content Zone 2.) Action Buttons --> <div class="action-zone" layout="row" layout-align="center center" layout-fill> <md-button class="btn-icon-raised md-raised md-primary" layout="row" layout-align="center center" aria-label="Standardize" ng-click="myCtrl.standardizeData()" ng-show="myCtrl.mergeActions.standardize" flex> <ng-md-icon layout-padding icon="redo"></ng-md-icon> <h4>Standardize</h4> </md-button> <md-button class="btn-icon-raised md-raised md-primary" layout="row" layout-align="center center" aria-label="Match" ng-click="myCtrl.processPrimaryKey()" ng-show="myCtrl.mergeActions.match" flex> <ng-md-icon layout-padding icon="swap_horiz"></ng-md-icon> <h4>Matching</h4> </md-button> <md-button class="btn-icon-raised md-raised md-primary" layout="row" layout-align="center center" aria-label="Index" ng-click="myCtrl.processIndexKey()" ng-show="myCtrl.mergeActions.index" flex> <ng-md-icon layout-padding icon="swap_vert"></ng-md-icon> <h4>Indexing</h4> </md-button> <md-button class="btn-icon-raised md-raised md-primary" layout="row" layout-align="center center" aria-label="Sort" ng-click="myCtrl.processSort()" ng-show="myCtrl.mergeActions.sort" flex> <ng-md-icon layout-padding icon="sort"></ng-md-icon> <h4>Sorting</h4> </md-button> </div> <!-- Tab Content Zone 3.) Footer & Navigation --> <div class="td" layout="column" ng-if="myCtrl.file.base.meta && myCtrl.file.mixin.meta" layout-fill> <div class="tab-footer-nav" layout="row" layout-align="center center" layout-fill> <md-button class="btn-icon-only" layout="row" layout-align="center center" aria-label="Previous 100" ng-click="myCtrl.changeRecord('add','','minus100')"> <ng-md-icon icon="arrow_back"></ng-md-icon> -100 </md-button> <div flex></div> <md-button class="btn-icon-only" aria-label="Previous" ng-click="myCtrl.changeRecord('subtract')"> <ng-md-icon icon="arrow_back"></ng-md-icon> </md-button> <span>ALL RECORDS</span> <md-button class="btn-icon-only" aria-label="Next" ng-click="myCtrl.changeRecord('add')"> <ng-md-icon icon="arrow_forward"></ng-md-icon> </md-button> <div flex></div> <md-button class="btn-icon-only" layout="row" layout-align="center center" aria-label="Next 100" ng-click="myCtrl.changeRecord('add','','plus100')"> +100 <ng-md-icon icon="arrow_forward"></ng-md-icon> </md-button> </div> </div> </md-tab><!-- End of Tab --> <!-- ##################################################################################################################################### --> <!-- ##################################################################################################################################### --> <md-tab md-on-select="myCtrl.checkData()"><!-- CONTENT TAB NO 3 - MERGE DATASETS --> <!-- Tab Title --> <md-tab-label> <h3>Merge</h3> </md-tab-label> <!-- Tab Header --> <div class="table" layout="column" layout-align="center center" layout-fill> <h3 class="sub-title" flex>Merge Datasets</h3> <span class="content" flex> Merge two datasets using the settings as applied from the "Prepare" tab. The merge is conducted in stages and (depending on file size) could take a few minutes. Each stage is logged for errors and accuracy, which will be published in the results. </span> <div class="notice" layout="row" layout-align="center center" layout-fill> <span layout="row" layout-align="center center" layout-fill ng-if="!myCtrl.file.base.meta.fields[0].type && !myCtrl.file.mixin.meta.fields[0].type && !myCtrl.showPrimaryKey.base && !myCtrl.showIndexKey.base && !myCtrl.file.mixin.meta.fields[0].sortOrder.value">You have not setup the datasets properly, please head over to the "Prepare" tab and click on the "Merge Settings" button.</span> </div> <div class="notice" layout="row" layout-align="center center" layout-fill> <div class="img-elem"> <ng-md-icon class="red" layout-padding icon="cancel" ng-if="!myCtrl.checked.dataSets"></ng-md-icon> <ng-md-icon class="green" layout-padding icon="check_circle" ng-if="myCtrl.checked.dataSets"></ng-md-icon> <span>Datasets</span> <ng-md-icon layout-padding icon="storage"></ng-md-icon> </div> <div class="img-elem"> <ng-md-icon class="red" layout-padding icon="cancel" ng-if="!myCtrl.checked.typeError"></ng-md-icon> <ng-md-icon class="green" layout-padding icon="check_circle" ng-if="myCtrl.checked.typeError"></ng-md-icon> <span>Standardize</span> <ng-md-icon layout-padding icon="redo"></ng-md-icon> </div> <div class="img-elem"> <ng-md-icon class="red" layout-padding icon="cancel" ng-if="!myCtrl.checked.primary"></ng-md-icon> <ng-md-icon class="green" layout-padding icon="check_circle" ng-if="myCtrl.checked.primary"></ng-md-icon> <span>Matching</span> <ng-md-icon layout-padding icon="swap_horiz"></ng-md-icon> </div> <div class="img-elem"> <ng-md-icon class="red" layout-padding icon="cancel" ng-if="!myCtrl.checked.index"></ng-md-icon> <ng-md-icon class="green" layout-padding icon="check_circle" ng-if="myCtrl.checked.index"></ng-md-icon> <span>Indexing</span> <ng-md-icon layout-padding icon="swap_vert"></ng-md-icon> </div> <div class="img-elem"> <ng-md-icon class="red" layout-padding icon="cancel" ng-if="!myCtrl.checked.sort"></ng-md-icon> <ng-md-icon class="green" layout-padding icon="check_circle" ng-if="myCtrl.checked.sort"></ng-md-icon> <span>Sorting</span> <ng-md-icon layout-padding icon="sort"></ng-md-icon> </div> </div> </div> <!-- Tab Content Zone 1.) Data Tables --> <div class="data-zone table" layout="column" layout-margin ng-if="myCtrl.checked.all" layout-fill> <!-- Table a.) BASE FILE DATASET --> <div class="data" layout="column" layout-fill> <header><!-- Table Title & Header --> <h4 class="title" layout="row" layout-align="center center" layout-fill>Base Sorting Table</h4> <!-- Table Actions Progress Bar --> <div class="notify-zone" layout="column" layout-padding ng-if="myCtrl.showUpdate.processBase" layout-fill> <span layout="row" layout-align="center center" layout-fill>Processing base data...</span> <md-progress-linear class="md-accent" md-mode="indeterminate"></md-progress-linear> </div> </header> <main><!-- Table Content --> <ul layout="column" layout-fill> <!-- Table content header row --> <li class="tr" layout="row" layout-align="start center"> <div class="th col-50-fixed">Row</div> <div class="th" ng-repeat="cellHeader in myCtrl.baseSortingable.tableUnique[0] track by $index" flex>Cell {{$index+1}}</div> </li> <!-- Table content --> <li class="tr" layout="row" layout-align="start center" ng-repeat="tableRow in myCtrl.baseSortingable.tableUnique | skip:myCtrl.skipNum.base | limitTo:myCtrl.showNum.base"> <div class="td col-50-fixed">{{tableRow.rowIndex+1}}</div> <div class="td" ng-repeat="tableCell in tableRow track by $index" flex>{{(!tableCell ? '---' : tableCell)}}</div> </li> </ul> </main> <!-- Table Footer --> <footer class="td" layout="row" layout-align="center center" layout-fill> <form name="tableManagerBase" layout="row" layout-fill> <md-input-container> <label>Show</label> <input name="showNum" ng-model="myCtrl.showNum.base"> </md-input-container> <md-input-container> <label>Skip</label> <input name="skipNum" ng-model="myCtrl.skipNum.base"> </md-input-container> </form> </footer> </div> <!-- Table a.) MIXIN FILE DATASET --> <div class="data" layout="column" layout-fill> <header><!-- Table Title & Header --> <h4 class="title" layout="row" layout-align="center center" layout-fill>Mixin Sorting Table</h4> <!-- Table Actions Progress Bar --> <div class="notify-zone" layout="column" layout-padding ng-if="myCtrl.showUpdate.processBase" layout-fill> <span layout="row" layout-align="center center" layout-fill>Processing base data...</span> <md-progress-linear class="md-accent" md-mode="indeterminate"></md-progress-linear> </div> </header> <main><!-- Table Content --> <ul layout="column" layout-fill> <!-- Table content header row --> <li class="tr" layout="row" layout-align="start center"> <div class="th col-50-fixed">Row</div> <div class="th" ng-repeat="cellHeader in myCtrl.mixinSortingable.tableUnique[0] track by $index" flex>Cell {{$index+1}}</div> </li> <!-- Table content --> <li class="tr" layout="row" layout-align="start center" ng-repeat="tableRow in myCtrl.mixinSortingable.tableUnique | skip:myCtrl.skipNum.mixin | limitTo:myCtrl.showNum.mixin"> <div class="td col-50-fixed">{{tableRow.rowIndex+1}}</div> <div class="td" ng-repeat="tableCell in tableRow track by $index" flex>{{(!tableCell ? '---' : tableCell)}}</div> </li> </ul> </main> <!-- Table Footer --> <footer class="td" layout="row" layout-align="center center" layout-fill> <form name="tableManagerMixin" layout="row" layout-fill> <md-input-container> <label>Show</label> <input name="showNum" ng-model="myCtrl.showNum.mixin"> </md-input-container> <md-input-container> <label>Skip</label> <input name="skipNum" ng-model="myCtrl.skipNum.mixin"> </md-input-container> </form> </footer> </div> </div><!-- End of Tab Content Zone 1.) Data Tables --> <!-- Tab Content Zone 2.) Action Buttons --> <div class="action-zone" layout="row" layout-align="center center" layout-fill> <md-button class="btn-icon-raised md-raised md-primary" layout="row" layout-align="center center" aria-label="Get Files" ng-click="myCtrl.showBottomSheet($event)" ng-disabled="!myCtrl.checked.all" flex> <ng-md-icon layout-padding icon="folder"></ng-md-icon> <h4>Merge Datasets</h4> </md-button> </div> </md-tab><!-- End of Tab --> <!-- ##################################################################################################################################### --> </md-tabs>
</section>
<div flex="20"></div>
</div>
</div>
<!-- BOTTOM SHEET TEMPLATE
#####################################################################################################################################
<md-bottom-sheet class="bottom-zone md-grid" ng-init="progress=$parent.myCtrl.progress"> <md-list layout="row" layout-align="center center"> <md-item layout="column" layout-align="center center" ng-if="progress.sort>0"> <ng-md-icon icon="cancel" ng-if="progress.sort<100"></ng-md-icon> <ng-md-icon icon="check_circle" ng-if="progress.sort===100"></ng-md-icon> <div class="progress"> <md-progress-circular class="md-primary" md-mode="determinate" value="{{progress.sort}}"></md-progress-circular> </div> <div class="item">Sorting</div> </md-item> <md-item layout="column" layout-align="center center" ng-if="progress.compare>0"> <ng-md-icon icon="cancel" ng-if="progress.compare<100"></ng-md-icon> <ng-md-icon icon="check_circle" ng-if="progress.compare===100"></ng-md-icon> <div class="progress"> <md-progress-circular class="md-primary" md-mode="determinate" value="{{progress.compare}}"></md-progress-circular> </div> <div class="item">Comparing</div> </md-item> <md-item layout="column" layout-align="center center" ng-if="progress.merge>0"> <ng-md-icon icon="cancel" ng-if="progress.merge<100"></ng-md-icon> <ng-md-icon icon="check_circle" ng-if="progress.merge===100"></ng-md-icon> <div class="progress"> <md-progress-circular class="md-primary" md-mode="determinate" value="{{progress.merge}}"></md-progress-circular> </div> <div class="item">Merging</div> </md-item> </md-list>
</md-bottom-sheet>
--> <script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js'></script>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-animate.js'></script>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-aria.js'></script>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-messages.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular-material/0.8.2/angular-material.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/danialfarid-angular-file-upload/3.0.7/angular-file-upload-all.min.js'></script>
<script src='http://cdn.jsdelivr.net/angular-material-icons/0.4.0/angular-material-icons.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.1.0/papaparse.min.js'></script>
<script src='https://sdk.amazonaws.com/js/aws-sdk-2.1.15.min.js'></script> <script src="js/index.js"></script>
</body>
</html>

Probabilistic N-Gram Dataset Merge - Script Codes CSS Codes

.myDemo { background: rgba(0, 0, 0, 0.1); font-size: 1.2em; height: auto; min-height: 100%;
}
.myDemo .myApp { position: relative;
}
.col-50-fixed { width: 50px;
}
.col-50 { min-width: 50px;
}
.col-70 { min-width: 70px;
}
.col-90 { min-width: 90px;
}
.col-110 { min-width: 110px;
}
.title { color: #673ab7; margin: 8px 0 4px;
}
.sub-title { color: rgba(0, 0, 0, 0.6); margin: 4px;
}
.content { text-align: center; padding: 4px 0;
}
.notice { text-align: center; font-size: 0.8em; color: #673ab7;
}
.red { fill: #c80000 !important;
}
.green { fill: #008c00 !important;
}
.table { color: rgba(0, 0, 0, 0.4); margin: 8px 0;
}
.table ul { margin: 0; padding: 0;
}
.table-header { color: rgba(0, 0, 0, 0.4); margin-bottom: 4px;
}
.table-header h1, .table-header h2, .table-header h3, .table-header h4, .table-header h5 { margin: 0; padding: 0;
}
.tr { margin: 2px 0;
}
.td { background-color: rgba(0, 0, 0, 0.03); padding: 8px; margin: 0 2px; font-size: 0.8em; color: rgba(0, 0, 0, 0.4);
}
footer.td { margin: 4px 0 0;
}
.td-clear { background-color: transparent;
}
.td-icon-btn .md-button { padding: 0;
}
.td-icon-btn .md-button ng-md-icon { fill: rgba(0, 0, 0, 0.4); padding-right: 4px;
}
.td-icon-btn .md-button svg { padding-top: 2px;
}
.td-icon-btn .md-button.md-default-theme:focus { transition: background-color 1s ease; background-color: transparent;
}
.td-icon-only { position: relative;
}
.td-icon-only .icon { position: absolute; top: 5px; right: 4px;
}
.td-icon-only ng-md-icon { fill: rgba(0, 0, 0, 0.2);
}
.td-icon-only svg { transform: scale(0.9, 0.9);
}
.td-btn button { text-transform: none; text-transform: capitalize;
}
.td-slct { color: #673ab7; font-weight: bold;
}
.td-check md-checkbox { margin: 0 2px;
}
.th { text-transform: uppercase; font-size: 0.6em; margin-right: 4px; text-align: center; font-weight: bold; color: rgba(0, 0, 0, 0.4);
}
.btn-std { text-transform: none;
}
.btn-std.md-button.md-default-theme:focus { transition: background-color 1s ease; background-color: transparent;
}
.btn-std-smlpad { padding: 2px 4px;
}
.btn-icon-raised { text-transform: none;
}
.btn-icon-raised ng-md-icon { fill: #fff;
}
.btn-icon-raised svg { padding-top: 2px;
}
.btn-icon-raised h1, .btn-icon-raised h2, .btn-icon-raised h3, .btn-icon-raised h4, .btn-icon-raised h5 { margin: 0; padding: 0;
}
.btn-icon-only { padding: 2px;
}
.btn-icon-only ng-md-icon { fill: rgba(0, 0, 0, 0.4);
}
.btn-icon-only svg { padding-top: 2px;
}
.btn-icon-only.md-button.md-default-theme:focus { transition: background-color 1s ease; background-color: transparent;
}
.btn-progress-flat { background-color: rgba(0, 0, 0, 0.05);
}
.btn-progress-clear { background-color: transparent;
}
.img-elem { background-color: rgba(0, 0, 0, 0.05); position: relative; margin: 24px 4px 4px; padding: 8px 8px 18px;
}
.img-elem ng-md-icon:last-child { fill: rgba(0, 0, 0, 0.4);
}
.img-elem ng-md-icon:last-child svg { width: 60px; height: 60px;
}
.img-elem ng-md-icon:first-child, .img-elem ng-md-icon:nth-child(2) { fill: rgba(0, 0, 0, 0.2); position: absolute; right: -14px; top: -12px;
}
.img-elem span { color: rgba(0, 0, 0, 0.4); width: 100%; position: absolute; bottom: 4px; left: 0px;
}
.drop-zone .md-container { height: 3px;
}
.notify-zone { padding-top: 0;
}
.notify-zone span { color: rgba(224, 64, 251, 0.3); font-size: 0.8em;
}
.notify-zone md-progress-linear { height: 3px;
}
.notify-zone .md-container { height: 3px;
}
.data-zone .table-header { text-transform: uppercase;
}
.data-zone .data { padding: 0 8px;
}
.data-zone .key-header .th { color: #fff; padding: 4px; background-color: rgba(0, 0, 0, 0.2); margin: 0;
}
.data-zone .key { margin-bottom: 16px;
}
.sidenav-zone { min-width: 40%; font-size: 1em;
}
.sidenav-zone md-toolbar ng-md-icon { fill: rgba(255, 255, 255, 0.2);
}
.sidenav-zone md-toolbar button { padding: 0 16px;
}
.sidenav-zone ol { list-style: decimal-leading-zero; font-size: 1em;
}
.sidenav-zone ol li { margin-bottom: 4px; font-size: 0.8em; line-height: 1.4; padding-right: 20px;
}
.bottom-zone md-list { padding: 24px 0 8px;
}
.bottom-zone .item { margin: 4px 0; text-align: center; font-size: 0.8em; color: rgba(0, 0, 0, 0.4); font-weight: bold;
}
.bottom-zone ng-md-icon { position: absolute; transform: scale(1.6, 1.6) translate(24px, 9px); fill: rgba(0, 0, 0, 0.2);
}
.bottom-zone.md-grid md-item { height: inherit; margin: 0; max-width: 100px;
}
.md-button.md-default-theme[disabled], .md-button.md-default-theme.md-raised[disabled], .md-button.md-default-theme.md-fab[disabled] { color: #fff; background-color: rgba(0, 0, 0, 0.05);
}
md-select { margin: 0 0 0 4px;
}
md-select .md-select-label { min-width: 0; padding-right: 24px; padding-left: 8px;
}
md-select .md-select-label span { padding: 0;
}
article h1 { color: #673ab7; margin: 8px 0 4px;
}
article h3 { color: rgba(0, 0, 0, 0.6); margin: 8px 0 4px;
}
article small { color: rgba(0, 0, 0, 0.2);
}
article p { color: rgba(0, 0, 0, 0.4); text-align: center; line-height: 1.2em;
}
.message { color: rgba(0, 0, 0, 0.2); margin-left: 4px;
}
.drop-box { background: rgba(0, 0, 0, 0.05); border: 5px dashed rgba(0, 0, 0, 0.1); color: rgba(0, 0, 0, 0.2); margin: 0; width: 100%;
}
.drop-box h5 { margin: 0;
}
.dragover { border: 5px dashed rgba(103, 58, 183, 0.3);
}
.dragover-err { border: 5px dashed rgba(255, 0, 0, 0.3);
}
.md-header .md-header-items-container { background-color: rgba(0, 0, 0, 0.05);
}
.md-header md-tabs-ink-bar { height: 3px;
}

Probabilistic N-Gram Dataset Merge - Script Codes JS Codes

angular.module('myApp', ['ngMaterial', 'ngMessages', 'angularFileUpload', 'ngMdIcons'])
/*
*	Angular CONFIGURATION
*	The application configuration
*/	.config( function($mdThemingProvider, $provide) {	// Set the default theme colours	$mdThemingProvider.theme('default')	.primaryPalette('deep-purple')	.accentPalette('purple');	$mdThemingProvider.theme('myTheme')	.primaryPalette('grey');	// Override the default exception handler	$provide.decorator('$exceptionHandler', ['$log', '$delegate', function($log, $delegate) {	return function(exception, cause) { $log.error(exception, cause); $delegate(exception, cause);	}; }	]);	})	// End of Configuration
// ######################################################################################################################
/*
*	Angular CONTROLLER
*	The main angular controller with scoped properties and functions to manipulate the DOM
*/	.controller('myController',[ '$scope', '$mdToast', '$mdSidenav', '$interval', 'FileManager', 'Papa', 'ErrorManager', 'myConstant', '$mdBottomSheet', '$q',	// Controller Function	function($scope, $mdToast, $mdSidenav, $interval, FileManager, Papa, ErrorManager, myConstant, $mdBottomSheet, $q){	var self = this;	var Scope = $scope;	/*	* Controller PROPERTIES (On scope)	*/	self.uploadedFiles = [];	self.serverFiles = [];	self.file = {base:{},mixin:{}};	self.fileCopy = {};	self.progress = {};	self.showFilesProgress = true;	self.showUpdate = { updateServer:false, processBase:false, processMixin:false };	self.recordNo = {base:0,mixin:0};	self.mergeActions = {};	self.fieldTypes = ['string','number','integer','boolean'];	self.numPrimaryKeys = {base: 0, mixin: 0};	self.showPrimaryKey = {base: false, mixin: false};	self.numIndexKeys = {base: 0, mixin: 0};	self.showIndexKey = {base: false, mixin: false};	self.baseSortingable = [];	self.mixinSortingable = [];	self.showNum = {base: 5, mixin: 5};	self.skipNum = {base: 0, mixin: 0};	self.checked = {};	/*	* Controller FUNCTIONS (Constructors)	*/	// Angular CONTROLLER Function - Sort table constructor function	function SortingTable(dataSet){	var sortTable = this;	sortTable.table = [];	sortTable.tableUnique = [];	sortTable.data = dataSet.data;	sortTable.fields = dataSet.meta.fields;	sortTable.keys = [];	function getKeys(){	var primaryKeys = [];	var indexKeys = [];	var otherKeys = [];	if(!!sortTable.fields){	sortTable.fields.forEach(	function(field){	if( !!field.primaryKey ){ primaryKeys.push(field.value); }	else if( !!field.indexKey ){ indexKeys.push(field.value); }	else { otherKeys.push(field.value); }	}	);	}	sortTable.keys = primaryKeys.concat(indexKeys,otherKeys);	sortTable.sortKeys = primaryKeys.concat(indexKeys);	}	function buildTable(){	if(!!sortTable.data && !!sortTable.keys){	for( var rowIndex = 0; rowIndex < sortTable.data.length; rowIndex++ ){	var tableRow = [];	for( var key in sortTable.keys){	tableRow.push( sortTable.data[rowIndex][sortTable.keys[key]] );	}	tableRow.rowIndex = rowIndex;	sortTable.table.push(tableRow);	}	}	}	function removeDupes(){	var tempSortArray = [];	for(var row in sortTable.table){	var itemString = JSON.stringify(sortTable.table[row]);	if(tempSortArray.indexOf( itemString ) < 0){	tempSortArray.push( itemString );	sortTable.tableUnique.push( sortTable.table[row] );	}	}	}	getKeys();	buildTable();	removeDupes();	return sortTable;	}	// Angular CONTROLLER Function - Sort function constructor function customSort(sortTable, progress){ var data = sortTable.tableUnique; var fields = sortTable.fields; var keys = sortTable.sortKeys; var wait = 5000; var count = 0; sortData = function(item1,item2){	function sorting(){	progress.sort = Math.floor((item1.rowIndex/data.length)*100)+1;	console.info(progress); for(var number in keys){ var sortOrder = fields[number].sortOrder.value; var temp = item1; if(sortOrder === 'ascending'){ item1=item2; item2=temp; } if(item1[number] > item2[number]){ return -1; } if(item1[number] < item2[number]){ return 1; } }	return 0;	}	count++;	if(count%50 === 0){ setTimeout(function(){ console.info('waiting...'); sorting(); },wait); }	else{ sorting(); } }; if(data.length>0 && keys.length>0){ data.sort(sortData); } }	/*	* Controller FUNCTIONS (private)	*/	// Angular MATERIAL DESIGN TOAST ELEMENT - Display element for user notifications	function showToast(message){	$mdToast.show(	$mdToast.simple()	.content(message)	.position('top right')	.hideDelay(4000) );	}	// Angular CONTROLLER Function - Handle all errors in controller	function handleError(error){	showToast(error.message);	clearError(error);	}	// Angular CONTROLLER Function - Handle all errors in controller	function reportError(name, message, value){	return ErrorManager.addError(name, message, value);	}	// Angular CONTROLLER Function - Clearing a specific error in controller	function clearError(error){	ErrorManager.clearError(error);	}	// Angular CONTROLLER Function - Hide all the Merge Settings elements	function hideMergeSettings(){	var mergeActions = Object.keys(self.mergeActions);	mergeActions.forEach(function(action){	self.mergeActions[action] = false;	});	}	// Angular CONTROLLER Function - Check to see if keys are balanced	function checkFile(file){	dataSets = [];	Object.keys(self.file).forEach( function(item){	var dataSet = self.file[item];	if( Object.keys(dataSet).length > 0 ){ dataSets.push( dataSet ); }	} );	return dataSets;	}	// Angular CONTROLLER Function - Check to see if keys are balanced	function checkKeys(dataSets){	var keys = { totalPrimaryKeys:0,totalIndexKeys:0, error:[] };	keys.error.unEven = [];	if(!dataSets){ dataSets = checkFile(self.file); }	if( dataSets.length > 0 ){	(function numberOfKeys(dataSets){	dataSets.forEach(function(dataSet){	var fields = dataSet.meta.fields;	var allocation = dataSet.meta.allocation;	var numPrimaryKeys = 0, numIndexKeys = 0;	var value = {};	var lastDataset = ( dataSets.indexOf(dataSet) === dataSets.length-1 ) ? true : false;	for(var field in fields ){	if( fields[field].primaryKey ){ numPrimaryKeys++; }	if( fields[field].indexKey ){ numIndexKeys++; }	}	keys[allocation] = { numPrimaryKeys:numPrimaryKeys, numIndexKeys:numIndexKeys };	keys.totalPrimaryKeys = keys.totalPrimaryKeys + numPrimaryKeys;	keys.totalIndexKeys = keys.totalIndexKeys + numIndexKeys;	if(keys[allocation].numPrimaryKeys === 0){	value = {};	value[allocation] = true;	value.primary = true;	keys.error.push( reportError( 'keys','No primary keys',value ) );	}	if(keys[allocation].numIndexKeys === 0){	value = {};	value[allocation] = true;	value.index = true;	keys.error.push( reportError( 'keys','No index keys',value ) );	}	if(lastDataset && keys.totalPrimaryKeys % 2 !== 0){	value = { totalPrimaryKeys:keys.totalPrimaryKeys};	keys.error.unEven.push( reportError( 'keys','Uneven primary keys', value) );	}	if(lastDataset && keys.totalIndexKeys % 2 !== 0){	value = { totalIndexKeys:keys.totalIndexKeys};	keys.error.unEven.push( reportError( 'keys','Uneven index keys', value) );	}	});	})(dataSets);	}	if( keys.error.unEven.length === 0 ){ delete keys.error.unEven; }	if( Object.keys(keys.error).length === 0 ){ delete keys.error; }	return keys;	}	// Angular CONTROLLER Function - Check for INDEX-KEY errors	function checkIndexError(keys, allocation){	var errors = keys.error;	errors.forEach(function(error){	if(error.value[allocation] && error.value.index ){	self.showIndexKey[allocation] = false;	return handleError(error);	}	});	self.numIndexKeys[allocation] = keys[allocation].numIndexKeys;	self.showIndexKey[allocation] = true;	}	// Angular CONTROLLER Function - Check for SORT SETTING on primary fields	function checkSortOrder(dataSets){	var sort = {};	for(var dataSet in dataSets){	var fields = dataSets[dataSet].meta.fields;	var allocation = dataSets[dataSet].meta.allocation;	sort[allocation] = {fields:[]};	for( var item in fields ){	var field = fields[item];	if(field.value){	if( field.primaryKey && field.sortOrder.value ){ sort[allocation].primary = true; }	if( field.sortOrder.value ){ sort[allocation].fields.push( field.value); }	}	}	if( sort[allocation].fields.length === 0 ||	sort[allocation].fields.length < fields.length && !sort[allocation].primary ){ sort[allocation].error = true; }	}	return sort;	}	// Angular CONTROLLER Function - Check for TYPE on fields	function checkTypeError(dataSets){	var typeError = false;	for(var dataSet in dataSets){	var fields = dataSets[dataSet].meta.fields;	for( var item in fields ){	var field = fields[item];	if(field.type === null){ typeError = true; }	}	}	return typeError;	}	// Angular CONTROLLER Function - Mocking a progress bar	function mockProgress(variable, key, start ){	var deferred = $q.defer();	if(this.interval){ $interval.cancel(this.interval); }	this.value = variable;	this.value[key] = start;	this.interval = $interval(function() {	this.value[key] += 1;	if (this.value[key] === 100) { deferred.resolve( $interval.cancel(this.interval) ); }	}, 100);	return deferred.promise;	}	/*	* Controller FUNCTIONS (On scope)	*/	// ### Angular MATERIAL DESIGN ###	// Angular MATERIAL DESIGN SIDENAV ELEMENT - Close side navigation element	self.closeSideNav = function() {	$mdSidenav('mergeSettings')	.close()	.then(function(){ });	};	// Angular MATERIAL DESIGN SIDENAV ELEMENT - Open side navigation element	self.toggleSideNav = function() {	hideMergeSettings();	$mdSidenav('mergeSettings')	.toggle()	.then(function(){});	};	// ### Angular FILE UPLOAD ELEMENT ###	// Angular FILE UPLOAD ELEMENT - Loading file up to Amazon S3 Webservices via in browser HTML5 Form POST input	self.dropBox = function( droppedFile, allocation ){	var checkPromise = FileManager.S3Check(droppedFile[0]);	checkPromise.then(	function success(response){	if(!response.onServer){	var dropPromise = FileManager.S3Post(droppedFile[0]);	self.serverFiles.length = 0;	dropPromise.then(	function success(droppedFile){	self.allocateFile( droppedFile, allocation );	self.uploadedFiles.push(droppedFile);	self.progress.base = 0;	self.progress.mixin = 0;	self.getFiles('File uploaded to server', false);	},	function error(response){ console.info(response); },	function notify(progress){ self.progress[allocation] = progress; }	);	}	else if(!!response.onServer){	self.getFiles('File already on server', false);	}	}	);	};	// Angular FILE UPLOAD ELEMENT - Retrieving file from Amazon S3 Webservices via in browser authentication	self.getFiles = function( message, progress ){	var promise = FileManager.S3Get();	message = !!message ? message : 'Files received from server';	self.showFilesProgress = (arguments.length > 1) ? progress : true;	self.serverFiles.length = 0;	if(progress === false){ self.showUpdate.updateServer = true; }	promise.then(	function success(serverFiles){	if(serverFiles.length > 0){	self.serverFiles = serverFiles;	showToast(message);}	else {	self.serverFiles.length = 0;	showToast('No files on server');	}	self.progress.files = 0;	self.showUpdate.updateServer = false;	},	function error(response){ console.info(response); },	function notify(progress){ self.progress.files = progress; }	);	};	// Angular FILE UPLOAD ELEMENT - Deleting file from Amazon S3 Webservices via in browser authentication	self.deleteFile = function(file){	var promise = FileManager.S3Delete(file);	promise.then(	function success(response){	self.uploadedFiles.splice( self.uploadedFiles.indexOf(file),1 );	self.getFiles('File deleted from server', false); },	function error(response){ console.info(response); }	);	};	// ### Angular CONTROLLER ###	// Angular CONTROLLER Function - Showing the Merge Settings side navigation	self.showMergeSettings = function(action){	self.mergeActions[action] = true;	self.closeSideNav();	};	// Angular CONTROLLER Function - Add allocation to file	self.allocateFile = function( selectedFile, allocation ){	var files = self.uploadedFiles.concat(self.serverFiles);	var duplicates = [];	var ownIndex = files.indexOf(selectedFile);	var ownName = selectedFile.meta.name;	angular.forEach(files, function(file, index){	if( file.meta.allocation === allocation ){ delete file.meta.allocation; }	if( file.meta.name === ownName && index !== ownIndex ) { duplicates.push(index); }	});	angular.forEach(duplicates, function(index){	if( files[index].meta.allocation ){ delete files[index].meta.allocation; }	});	selectedFile.meta.allocation = allocation;	self.file[allocation] = selectedFile;	};	// Angular CONTROLLER Function - Check the selected datasets from the file arrays	self.checkData = function(){	var checked = {};	var dataSets = checkFile(self.file);	var keys = checkKeys();	var sortable = ( dataSets.length > 0 && dataSets[1].meta) ? dataSets[1].meta.allocation : undefined;	var sorting = checkSortOrder(dataSets);
/*	checked.dataSets = ( dataSets.length > 0 ) ? true : false;	checked.index = ( keys.totalIndexKeys % 2 === 0 && keys.totalIndexKeys !== 0 ) ? true : false;	checked.primary = ( keys.totalPrimaryKeys % 2 === 0 && keys.totalPrimaryKeys !== 0 ) ? true : false;	checked.sort = ( dataSets.length > 0 && sorting.error || sorting[sortable] && sorting[sortable].primary ) ? true : false;	checked.typeError = ( dataSets.length > 0 && !checkTypeError(dataSets) ) ? true : false;
*/	checked.dataSets = true;	checked.index = true;	checked.primary = true;	checked.sort = true;	checked.typeError = true;	self.checked = checked;	self.checked.all = checked.dataSets && checked.index && checked.primary && checked.sort && checked.typeError;	if(dataSets.length > 0 && self.checked.all){ self.baseSortingable = new SortingTable(dataSets[0]); }	if(dataSets.length > 0 && self.checked.all){ self.mixinSortingable = new SortingTable(dataSets[1]); }	console.info(self.mixinSortingable);	};	self.showBottomSheet = function($event) {	var progress = self.progress;	$mdBottomSheet.show({	parent: '.myApp',	template: myConstant.bottomSheetTemplate,	scope: Scope.$new(true),	});	customSort(self.mixinSortingable, progress);	};	// Angular CONTROLLER Function - Change the current database record number	self.changeRecord = function(action, allocation, more){	var record = self.recordNo;	var lastBaseRecord = self.file.base.data.length;	var lastMixinRecord = self.file.mixin.data.length;	if( action === 'add' && !more){	if(allocation){ record[allocation]++; }	else{ record.base++; record.mixin++; }	}	else if( action === 'subtract' && !more){	if(allocation){ record[allocation]--; }	else{ record.base--; record.mixin--; }	}	if(more === 'plus100'){ record.base = record.base + 100;	record.mixin = record.mixin + 100;	}	else if(more === 'minus100'){	record.base = record.base - 100;	record.mixin = record.mixin - 100;	}	record.base = (record.base <= 0) ? 0 : record.base;	record.base = (record.base >= lastBaseRecord) ? lastBaseRecord-1 : record.base;	record.mixin = (record.mixin <= 0) ? 0 : record.mixin;	record.mixin = (record.mixin >= lastMixinRecord) ? lastMixinRecord-1 : record.mixin;	};	// Angular CONTROLLER Function - test for empty inputs	self.testEmpty = function(value){	if (typeof value == 'undefined' || value === null || value === '') return '---';	if (typeof value == 'number' && isNaN(value)) return '---';	if (value instanceof Date && isNaN(Number(value))) return '---';	return value;	};	// Angular CONTROLLER Function - Merge Action 1.) STANDARDIZE	self.standardizeData = function(){	var dataSets = checkFile(self.file);	function standardizeType(fields, field, record){	var type = fields.getField(field).getType();	if(type){	switch(type){	case 'string':	record[field] = record[field].toLowerCase().trim();	break;	case 'number':	record[field] = Math.round(record[field]*10000)/10000;	break;	case 'integer':	record[field] = Math.round(record[field]);	break;	case 'boolean':	record[field] = ( String(record[field]).toLowerCase() === 'true' ) ? true : false;	break;	}	}	}	function iterateRecords(dataSets){	for(var item in dataSets){	var dataSet = dataSets[item];	var allocation = dataSet.meta.allocation;	var data = dataSet.data;	var fields = dataSet.meta.fields;	self.showUpdate['process' + allocation.slice(0,0).toUpperCase() + allocation.slice(1)] = true;	for( var i = 0; i < data.length; i++ ){	var currentRecord = data[i];	for( var field in currentRecord ){	standardizeType(fields, field, currentRecord);	}	}	self.showUpdate['process' + allocation.slice(0,0).toUpperCase() + allocation.slice(1)] = false;	}	}	iterateRecords(dataSets);	hideMergeSettings();	};	// Setting PRIMARY-KEY	self.setPrimaryKey = function(dataSet, field){	var fields = dataSet.meta.fields;	var allocation = dataSet.meta.allocation;	var keys = null;	field.primaryKey = true;	for(var i = 0; i < fields.length; i++){	if( fields[i].getValue() !== field.getValue() ){ fields[i].primaryKey = false; }	}	if (field.indexKey) {	delete field.indexKey;	keys = checkKeys([dataSet]);	if(!!keys.error){ checkIndexError(keys, allocation); }	else{	self.numIndexKeys[allocation] = keys[allocation].numIndexKeys;	self.showIndexKey[allocation] = true;	}	showToast('Deleting index key on field');	}	else{ keys = checkKeys([dataSet]); }	self.numPrimaryKeys[allocation] = keys[allocation].numPrimaryKeys;	self.showPrimaryKey[allocation] = true;	fields.splice( fields.indexOf(field),1 );	fields.unshift( field );	};	// Processing PRIMARY-KEY ("Matching" button)	self.processPrimaryKey = function(){	var keys = checkKeys();	if(!!keys.error && keys.error.unEven){	keys.error.unEven.forEach( function(error){ handleError(error); } );	}	else{ hideMergeSettings(); }	};	// Angular CONTROLLER Function - Merge Action 3.) INDEX-KEY ORDER	// Setting INDEX-KEY order	self.setIndexKeyOrder = function(fields, field, key){	var swoppedIndex = fields.indexOf(field);	var swoppedItem = fields.slice(key,key+1)[0];	fields.splice(key,1,field);	fields.splice(swoppedIndex,1,swoppedItem);	};	// Setting INDEX-KEY	self.setIndexKey = function(dataSet, field){	var fields = dataSet.meta.fields;	var allocation = dataSet.meta.allocation;	var keys = checkKeys([dataSet]);	if(field.primaryKey){	delete field.indexKey;	keys = checkKeys([dataSet]);	if(!!keys.error){ checkIndexError(keys, allocation); }	showToast('Key is primary key');	}	else if(!field.primaryKey) {	if(!!keys.error){ checkIndexError(keys, allocation); }	else{	self.numIndexKeys[allocation] = keys[allocation].numIndexKeys;	self.showIndexKey[allocation] = true;	}	}	};	// Processing INDEX-KEY	self.processIndexKey = function(){	var keys = checkKeys();	if(!!keys.error && keys.error.unEven){	keys.error.unEven.forEach(function(error){	handleError(error);	});	}	else{ hideMergeSettings(); }	};	// Angular CONTROLLER Function - Merge Action 4.) SORTING ORDER	// Setting sort order	self.setSortOrder = function(field){	if( field.sortOrder.value === 'ascending' ) {	field.sortOrder = {value: 'descending', icon: 'keyboard_arrow_down'};	}	else{ field.sortOrder = {value: 'ascending', icon: 'keyboard_arrow_up'}; }	};	self.processSort = function(){	console.info('Sorting data...');	hideMergeSettings();	};	}	// End of Controller Function	])	// End of Controller
// ######################################################################################################################
/*
*	Angular FACTORY
*	Factory to uplad and retrieve files from Amazon S3 Webservices
*/	.factory('FileManager', [ '$window', '$q', '$upload', 'myConstant', 'Papa',	// Factory Function	function($window, $q, $upload, myConstant, Papa) {	var self = this;	/*	* Factory Properties (Private)	*/	var BlobService = $window.Blob;	var S3Service = new $window.AWS.S3();	var awsConfigParams = {	accessKeyId: myConstant.awsLimitedAccessKeyId,	//Credentials is very specific	secretAccessKey: myConstant.awsLimitedAccessSecret	//and times-out after an hour;	};	/*	* Factory Functions (Private)	*/	// Extending metadata from one file to another	function ExtendFileMeta(targetFile, sourceFile){	var newFile = angular.extend({},targetFile);	angular.extend(newFile.meta, sourceFile);	return newFile;	}	/*	* Factory Functions (Public)	*/	// Amazon S3 Service in browser 'DELETE' request	self.S3Delete = function(file){	var deferred = $q.defer();	var params = { Bucket: myConstant.awsBucket, Key: myConstant.awsKey + file.meta.name };	var awsDelete = S3Service.deleteObject(params);	function deleteFileError(error){ deferred.reject(error); console.info(error); }	function deleteFileSuccess(response){	deferred.resolve(response);	}	awsDelete.on('success', deleteFileSuccess);	awsDelete.on('error', deleteFileError);	awsDelete.send();	return deferred.promise;	};	// Amazon S3 Service in browser 'GET' request	self.S3Check = function(file){	var deferred = $q.defer();	var fileName = file.name;	var awsBucketName = myConstant.awsBucket;	var awsMarker = myConstant.awsKey;	var awsBucket = S3Service.listObjects( { Bucket: awsBucketName, Marker: awsMarker } );	var getAllErrors = function(error){ deferred.reject(error); console.info(error); };	var fileObjects = [];	function getBucketSuccess(response){	fileObjects = response.data.Contents;	angular.forEach(fileObjects, function(fileObject){	var string = fileObject.Key;	var objectName = (string = string.split('/'))[string.length-1];	if(fileName === objectName){ deferred.resolve( {onServer:true} ); }	});	deferred.resolve( {onServer:false} );	}	awsBucket.on('success', getBucketSuccess);	awsBucket.on('error', getAllErrors);	awsBucket.send();	return deferred.promise;	};	// Amazon S3 Service in browser 'GET' request	self.S3Get = function () {	var deferred = $q.defer();	var awsBucketName = myConstant.awsBucket;	var awsMarker = myConstant.awsKey;	var awsType = myConstant.awsFileType;	var getAllErrors = function(error){ deferred.reject(error); console.info(error); };	var files = [];	var fileObjects = [];	var fileObjectsTotal = 0;	var fileCurrentURL = '';	var fileCount = -1;	// Getting single file for Amazon S3 bucket object	function getFile(fileObject){	var deferredFile = $q.defer();	var awsRequest = S3Service.getObject( { Bucket:awsBucketName, Key:fileObject.Key } );	function getFileSuccess(response){	var fileString = response.data.Body.toString();	deferredFile.resolve( new BlobService( [ fileString ] , { type:awsType } ) );	}	function getFileProgress(progress){	var newURL = progress.srcElement.responseURL;	if( fileCurrentURL !== newURL ) { fileCurrentURL = '' + newURL; fileCount++; }	var filePercent = Math.round( ( progress.loaded/progress.total * 100) / fileObjectsTotal );	var totalPercent = Math.round( ((100 / fileObjectsTotal) * fileCount) + filePercent );	deferred.notify(totalPercent);	}	awsRequest.on( 'success', getFileSuccess );	awsRequest.on( 'error', getAllErrors );	awsRequest.on( 'httpDownloadProgress', getFileProgress );	awsRequest.send();	return deferredFile.promise;	}	// Getting all fileobjects for current Amazon S3 bucket (RECURSIVELY)	function getFilesRecursive(counter){	var currentFile = {};	function getFileRecursiveError(error){	console.info(error);	counter++;	getFilesRecursive(counter);	}	function getFileRecursiveParseSuccess(parsedFile){	var newFile = ExtendFileMeta(parsedFile, currentFile);	var string = newFile.meta.Key;	newFile.meta.name = (string = string.split('/'))[string.length-1];	files.push(newFile);	counter++;	getFilesRecursive(counter);	}	function getFileRecursiveSuccess(serverFile){	var promise = Papa.parseFile(serverFile);	promise.then( getFileRecursiveParseSuccess );	}	if( fileObjects && counter < fileObjectsTotal ){	currentFile = fileObjects[counter];	var promise = getFile(currentFile);	promise.then( getFileRecursiveSuccess, getFileRecursiveError );	}	else if( fileObjects && counter === fileObjectsTotal ){ deferred.resolve(files); }	}	// Getting Amazon S3 bucket from server	function getAllFiles(){	var counter = 0;	var files = [];	var awsBucket = S3Service.listObjects( { Bucket: awsBucketName, Marker: awsMarker } );	function getBucketSuccess(response){	fileObjects = response.data.Contents;	fileObjectsTotal = fileObjects.length;	getFilesRecursive(counter);	}	awsBucket.on('success', getBucketSuccess);	awsBucket.on('error', getAllErrors);	awsBucket.send();	}	getAllFiles();	return deferred.promise;	};	// Amazon S3 Service in browser 'POST' form request	self.S3Post = function (file) {	var deferred = $q.defer();	var url = 'https://' + myConstant.awsBucket + '.s3.amazonaws.com';	var fields = {	key: myConstant.awsKey + file.name,	AWSAccessKeyId: myConstant.awsLimitedAccessKeyId,	acl: 'private',	policy: myConstant.awsPolicy,	signature: myConstant.awsSignature,	"Content-Type": file.type !== '' ? file.type : myConstant.awsFileType,	filename: file.name	};	function postFileProgress(event) { deferred.notify( parseInt(100.0 * event.loaded / event.total) ); }	function postFileSuccess(data, status, headers, config) {	var blob = config.file;	var promise = Papa.parseFile(blob);	promise.then(	function(parsedFile){	var newFile = ExtendFileMeta(parsedFile, file);	deferred.resolve(newFile);	}	);	}	if (file) { $upload	.upload({ url: url, method: 'POST', fields : fields, file: file })	.progress(postFileProgress)	.success(postFileSuccess);	}	return deferred.promise;	};	// Authenticate Amazon S3 service	S3Service.config.update(awsConfigParams);	// Return FileManager factory object	return self;	}])	// End of Factory
// ######################################################################################################################
/*
*	Angular FACTORY
*	Factory to parse uploaded CSV files into Javascript objects
*/	.factory('Papa', ['$window', '$q',	// Factory Function	function($window, $q) {	var Papa = $window.Papa;	var deferred = {};	/*	* Factory Properties (Private)	*/	var parseConfig = {	download: true,	delimiter: '', // auto-detect	newline: '', // auto-detect	header: true,	dynamicTyping: true,	encoding: '',	worker: false,	comments: false,	step: undefined,	complete: parseFileSuccess,	error: parseFileError,	skipEmptyLines: true,	chunk: undefined,	fastMode: true	};	/*	* Factory Functions (Private)	*/	// Papa parse Success Callback	function parseFileSuccess(parsedResult){	var fields = angular.copy(parsedResult.meta.fields);	function Field(value){	this.value = value;	this.type = null;	this.sortOrder = { value: undefined, icon: 'more_horiz' };	this.getType = function(){	return this.type;	};	this.getValue = function(){	return this.value;	};	return this;	}	fields.getField = function(name){	var found;	for( var i=0; i < this.length; i++ ){	if( this[i].value === name ){ found = this[i]; }	}	return found;	};	for( var i=0; i<fields.length; i++ ){	fields[i] = new Field( fields[i] );	}	parsedResult.meta.fields = fields;	parsedResult.meta.numRecords = parsedResult.data.length;	parsedResult.meta.numFields = parsedResult.meta.fields.length;	parsedResult.meta.numKBytes = Math.round(parsedResult.meta.cursor/1000);	deferred.resolve(parsedResult);	}	// Papa parse Error Callback	function parseFileError(error){ console.info('Parsed error: ', error); }	// Return the Factory Object	var parse = {	parseFile: function (file){	deferred = $q.defer();	Papa.parse(file, parseConfig);	return deferred.promise;	},	};	return parse;	}])	// End of Factory
// ######################################################################################################################
/*
*	Angular SERVICE (singleton)
*	Service to log and manage custom errors
*/	.service('ErrorManager', [	// Service Function	function() {	var self = this;	/*	* Service Functions (Private)	*/	function Error(name,message,value){	this.name = name;	this.message = message;	this.value = value;	}	function ErrorContext(error){	var context = '';	switch(error.name){	case 'keys':	context = 'Error Manage: Unknown keys error';	break;	}	return context;	}	/*	* Service Functions (Public)	*/	function ErrorQueue(){	var Errors = [];	this.addError = function(name,message,value){	var error = new Error(name,message,value);	var logged = ( Errors.indexOf(error) < 0 ) ? true : false;	if(!logged){ Errors.push(error); throw error; }	return error;	};	this.clearError = function(error){	return Errors.splice( Errors.indexOf(error) ,1)[0];	};	this.listError = function(name){	var found = [];	for(var item in Errors){	var error = Errors[item];	if(name && error.name === name){	found.push( this.clearError(error) );	}	}	return (found.length > 0) ? found : undefined;	};	}	return new ErrorQueue();	}])	// End of Service
// ######################################################################################################################
/*
*	Angular FILTER
*	Filter to skip number of items in repeater
*/	.filter('skip', function() { return function(inputArray, skipItems) {	skipItems = Number(skipItems);	inputArray = inputArray || [];	return inputArray.slice(skipItems); };	})	// End of Filter
// ######################################################################################################################
/*
*	Angular CONSTANT
*	Application constants used in factories and controllers
*/	.constant('myConstant',{	awsPolicy: 'ewogICJleHBpcmF0aW9uIjogIjIwMjAtMDEtMDFUMDA6MDA6MDBaIiwKICAiY29uZGl0aW9ucyI6IFsKICAgIHsiYnVja2V0IjogInBlbi1ma' +	'WxlLW1lcmdlIn0sCiAgICBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAiIl0sCiAgICB7ImFjbCI6ICJwcml2YXRlIn0sCiAgICBbInN0YXJ0cy13aXRoIiwgI' +	'iRDb250ZW50LVR5cGUiLCAiIl0sCiAgICBbInN0YXJ0cy13aXRoIiwgIiRmaWxlbmFtZSIsICIiXSwKICAgIFsiY29udGVudC1sZW5ndGgtcmFuZ2UiLCAwLCA1MjQyODgwMDBdCiAgXQp9',	awsSignature: 'lOUT7Rm9uHIdBtlnsfmbekKbYjY=',	awsLimitedAccessKeyId: 'AKIAIMUXD3NFR57NIXMQ',	//Credentials is for a very specific resource	awsLimitedAccessSecret: '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', //and times-out after an hour;	awsBucket: 'pen-file-merge',	awsKey: 'userfiles/',	awsFileType: 'text/csv',	bottomSheetTemplate:	'<md-bottom-sheet class="bottom-zone md-grid" ng-init="progress=$parent.myCtrl.progress"><md-list layout="row" layout-align="center center">' +	'<md-item layout="column" layout-align="center center" ng-if="progress.sort>0">' +	'<ng-md-icon class="red" icon="cancel" ng-if="progress.sort<100"></ng-md-icon>' +	'<ng-md-icon class="green" icon="check_circle" ng-if="progress.sort===100"></ng-md-icon>' +	'<div class="progress"><md-progress-circular class="md-primary" md-theme="myTheme" md-mode="determinate" value="{{progress.sort}}">' +	'</md-progress-circular></div>' +	'<div class="item">Sorting</div></md-item>' +	'<md-item layout="column" layout-align="center center" ng-if="progress.compare>0">' +	'<ng-md-icon class="red" icon="cancel" ng-if="progress.compare<100"></ng-md-icon>' +	'<ng-md-icon class="green" icon="check_circle" ng-if="progress.compare===100"></ng-md-icon>' +	'<div class="progress"><md-progress-circular class="md-primary" md-theme="myTheme" md-mode="determinate" value="{{progress.compare}}">' +	'</md-progress-circular></div>' +	'<div class="item">Comparing</div></md-item>' +	'<md-item layout="column" layout-align="center center" ng-if="progress.merge>0">' +	'<ng-md-icon class="red" icon="cancel" ng-if="progress.merge<100"></ng-md-icon>' +	'<ng-md-icon class="green" icon="check_circle" ng-if="progress.merge===100"></ng-md-icon>' +	'<div class="progress"><md-progress-circular class="md-primary" md-theme="myTheme" md-mode="determinate" value="{{progress.merge}}">' +	'</md-progress-circular></div>' +	'<div class="item">Merging</div></md-item>' +	'</md-list></md-bottom-sheet>'	});	// End of Constant
// ######################################################################################################################
Probabilistic N-Gram Dataset Merge - Script Codes
Probabilistic N-Gram Dataset Merge - Script Codes
Home Page Home
Developer Ian Joubert
Username Studira
Uploaded November 01, 2022
Rating 3
Size 19,294 Kb
Views 22,264
Do you need developer help for Probabilistic N-Gram Dataset Merge?

Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!

Ian Joubert (Studira) Script Codes
Create amazing art & images with AI!

Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!