CRUD (React)

DataViews supports CRUD (create, read, update, destroy) data operations.

This example uses React.

Description
index.html
app.js
data.js
locale.js
Pager.js
styles.css

DataViews supports CRUD (create, read, update, destroy) data operations.

This demo shows how to apply remote data operations. To use remote data operations, implement callback methods to inform the dataView about the operation.

The callback methods only have one parameter. You can use any transport protocol in the callback. If the callback is successful, call params.success(); if the callback fails (or there is an error), call params.failed().

Note that the server's response is randomly successful or failed.

Try adding a new record with the "Add new record" button, or update and delete entries with their respective icons.

This demo calls some API items from the internet, make sure your internet connection is working and runing this demo with HTTP or HTTPS protocol.

DataViews supports CRUD (create, read, update, destroy) data operations. This demo shows how to apply remote data operations. To use remote data operations, implement callback methods to inform the dataView about the operation. The callback methods only have one parameter. You can use any transport protocol in the callback. If the callback is successful, call params.success(); if the callback fails (or there is an error), call params.failed(). Note that the server's response is randomly successful or failed. Try adding a new record with the "Add new record" button, or update and delete entries with their respective icons. This demo calls some API items from the internet, make sure your internet connection is working and runing this demo with HTTP or HTTPS protocol.
<!DOCTYPE html> <html lang="en"> <head> <base href="/dataviewsjs/demos/en/sample/Features/DataBinding/CRUD/react/" /> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="keywords" content="crud" /> <meta name="description" content="DataViews supports CRUD (create, read, update, destroy) data operations." /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>CRUD | Features | MESCIUS DataViewsJS React Demos</title> <link href="/dataviewsjs/demos/node_modules/normalize.css/normalize.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/static/css/base.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/static/css/bootstrap-snippet.min.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/static/css/pageui.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/static/dataviews/gc.dataviews.core.min.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/static/dataviews/gc.dataviews.grid.min.css" rel="stylesheet" type="text/css" /> <link href="styles.css" rel="stylesheet" type="text/css" /> <script src="/dataviewsjs/demos/static/js/app-polyfills.min.js" type="text/javascript"></script> <script type="text/javascript"> window.process = { env: { NODE_ENV: 'production', USE_NPM: false, USE_CDN: false, SITE_ROOT: '/dataviewsjs/demos', FRAMEWORK: 'react', DVJS_LICENSE_KEY: 'E348418822993781#B0EWvwY4dNNVQqJHUDpFROVWe5ZWNYFlVQFmRsJWRht4Z6lDO4Vla7YUaXhEWxd7Z5YXMuRnY7tWTQRHSlVnaYlXNhlEOpdkZ0FHWYJ5QKd6VXN5aR3ieGhUav9kZTBXWahkYBhEVutmZ72CbjdlZvV5TVdGdiplQsZXe95kUmNmZVF5cJ3mcypWNyx4UydESE3UblxGZyE7KQ94R4BjbUxUewsiaoREMxRDNllWREV6Voh4Q4dDZPRjWrIzUJl4TERXcQZWMHp4Sp9WaMZzN5o6StJmVDJXcwIVVmR6UMVGOlxUW8RmTxZDZTJWVN5GZqJHZuVDMkVGSW3WdxNzKCdDdSB7TzY7cqlnMU5GVyNzNP9WMyhDRvEEOFdkQORDM4dFVlFFWqFWSyMjNQJiOiMlIsISQyIkQ9YjQxIiOigkIsUTM7YjNxYTM0IicfJye&amp;Qf35VfikFVVljI0IyQiwiIxYHITp4c7VWaWFGdhRkI0IiTis7W0ICZyBlIsIiNxUTN6ADI8EDMxMjMwIjI0ICdyNkIsIyc59yc5l6YzVWbuoCLwpmLzVXajNXZt9iKs2WauMXdpN6cl5mLqwSbvNmLzVXajNXZt9iKsAnau26YuMXdpN6cl5mLqwSbvNmL6VGZ9RXajVGchJ7ZuoCLuNmLt36YukHdpNWZwFmcn9iKs46bj9Se4l6YlBXYydmLqwicr9ybj9Se4l6YlBXYydmLqwCcq9ybj9Se4l6YlBXYydmLqIiOiMXbEJCLiMVVJN4UF5kI0ISYONkIsUWdyRnOiwmdFJCLiEDO7MTO9IjM8gTM4gDNzIiOiQWSisnOiQkIsISP3EkVxBVUHFDMplzLlVUdGd7cI9UeIt4SshESzV7NvY7ZxlDOuNTb5tzLr', SJS_LICENSE_KEY: 'E518585142165236#B0wm4nx4QzdlTHRTSOFzcvVnaJdjSnNEeXdTMUtSUzk6bU94QuVXNwZVZjd4SzYjcadXRIVEMzEXTThkVyR7R85UayoHZZBTYQ5mZyh4Shd6VxFXazF4cBNGRG5WTvUGTsV4T6knQYRzKxxUdk9EarplU7d6VLF6KIR7bPJ5N6ZUMWZWaURGRKRDbLJDN5YjSN5mUoxmaxonSD56LEh7Y7RXenpmTvomevZlV9dkaysCO7hTRQFHcGRWQyc5LI9kQmB7QwR4Z7ZHOR3CSXp6SiFWYzFXeXZUSp94K8VDTkFjdwl4KptSYlRWcDxmNE5kS6kzdrkVcNJXROVGbLJkcTNGRzIER8tmd4YGNhh7dxAnMvIHRv46VtBXS4U5KvJ6dZJ6M5p4TxIjd9I5QSpXTTV6SDZXb7lzaL56ZiojITJCLikTQxUTQFV4NiojIIJCLyETO7UzM7kTO0IicfJye&amp;Qf35VfikkR9IkI0IyQiwiIyEjL6ByUKBCZhVmcwNlI0IiTis7W0ICZyBlIsISNwkTN6ADI8EDMxMjMwIjI0ICdyNkIsIyc59yc5l6YzVWbuoCLwpmLzVXajNXZt9iKs2WauMXdpN6cl5mLqwSbvNmLzVXajNXZt9iKsAnau26YuMXdpN6cl5mLqwSbvNmL6VGZ9RXajVGchJ7ZuoCLuNmLt36YukHdpNWZwFmcn9iKs46bj9Se4l6YlBXYydmLqwicr9ybj9Se4l6YlBXYydmLqwCcq9ybj9Se4l6YlBXYydmLqIiOiMXbEJCLiMVVJN4UF5kI0ISYONkIsUWdyRnOiwmdFJCLiYzMyUjNxIDNxUDO5gTM5IiOiQWSiwSfdtlOicGbmJCLlNHbhZmOiI7ckJye0ICbuFkI1pjIEJCLi4TPRtGOhtWWEFWd4IDOLRVRvx4SyMGcDhTW6n4ep', }, }; </script> <script src="/dataviewsjs/demos/node_modules/lodash/lodash.min.js" type="text/javascript"></script> <script src="/dataviewsjs/demos/node_modules/jquery/dist/jquery.min.js" type="text/javascript"></script> <script src="/dataviewsjs/demos/static/js/license.js" type="text/javascript"></script> <script src="/dataviewsjs/demos/node_modules/systemjs/dist/system.js" type="text/javascript"></script> <script src="systemjs.config.js" type="text/javascript"></script> </head> <body class="theme-default"> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> <script type="text/javascript"> System.import('./app.js'); </script> </body> </html>
import React from 'react'; import ReactDOM from 'react-dom'; import DataView, { getControlByElement } from '@grapecity/dataviews.react'; import { GridLayout } from '@grapecity/dataviews.grid'; import Pager from './Pager'; import { dataSource } from './data'; import locale from './locale'; const cols = [ { id: 'editCol', width: 70, action: [ { name: 'edit', presenter: '<button class="edit-btn action-btn" data-action="edit"><span class="edit-icon"></span></button>', }, ], }, { id: 'id', caption: 'Order Id', dataField: 'Transaction_Id', dataType: 'number', allowEditing: false, width: 80, }, { id: 'product', caption: 'Product', dataField: 'Product', width: 300, }, { id: 'price', caption: 'Item Price', dataField: 'Price', dataType: 'number', width: '*', }, { id: 'quantity', caption: 'Quantity', dataField: 'Quantity', dataType: 'number', width: '*', }, { id: 'name', caption: 'Name', dataField: 'Name', width: '*', }, { id: 'country', caption: 'Country', dataField: 'Country', width: '*', }, { id: 'detail', caption: 'Detail', dataField: 'Product_Detail', width: '*', }, { id: 'deleteCol', width: 50, action: [ { name: 'delete', presenter: '<button class="delete-btn action-btn" data-action="delete"><span>✖</span></button>', handler: deleteItem, }, ], }, ]; // action column handler function deleteItem(args) { const dataView = getControlByElement(document.body); const rowId = dataView.getRowId(args.hitInfo); const dataItem = dataView.getItem(rowId); if (dataItem && dataItem.item) { const sourceIndex = dataItem.item.sourceIndex; if (sourceIndex >= 0) { dataView.data.removeDataItems(sourceIndex); } } } const layout = new GridLayout({ colWidth: 80, showColHeader: false, showRowHeader: false, rowHeight: 36, pageSize: 10, allowEditing: true, editMode: 'popup', autoAddRowPosition: 'top', headerRow: { visible: true, height: 40, separateColumn: false, renderer: ` <button id="btnAddNew" class="btn btn-sm"> <span class="add-icon"></span> <span>${locale.addNew}</span> </button>`, }, }); class App extends React.Component { constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); this.handleEditing = this.handleEditing.bind(this); } handleClick(e) { let element = e.target; while (element) { if ($(element).is('#btnAddNew')) { const dataView = getControlByElement(document.body); const addNewRecordID = `${dataView.uid}-autorow`; dataView.startEditing(addNewRecordID); break; } element = element.parentNode; } } handleEditing(args) { if ((args.status === 'endEditing' && args.isNewRow) || args.status === 'cancelEditing') { const dataView = getControlByElement(document.body); if (dataView.options.allowAutoAddRow) { dataView.options.allowAutoAddRow = false; dataView.invalidate(); } } } render() { return ( <div className="main-container" onClick={this.handleClick}> <DataView id="grid" className="grid" data={dataSource} cols={cols} layout={layout} onEditing={this.handleEditing} /> <Pager /> </div> ); } } ReactDOM.render(<App />, document.getElementById('root'));
import _ from 'lodash'; import locale from './locale'; const baseUrl = `${process.env.SITE_ROOT}/remotedata/api/records`; export const dataSource = { loadRange(params) { $.ajax({ // pageSize and startPageIndex only works when paging component is referenced, if control // do find the paging component, pageSize and pageIndex will be undefined. url: getRecords(params.pageIndex === undefined ? undefined : params.pageSize * params.pageIndex, params.pageSize), crossDomain: true, success(result) { const data = result.m_Item2; const total = result.m_Item1; params.success(data, total); }, error(xhr, status) { params.failed(); if (status !== 'abort') { alert(locale.loadFailed); } }, }); }, create(params) { const dataItem = _.clone(params.dataItem); $.ajax({ url: baseUrl, type: 'POST', data: dataItem, success(data) { dataItem.Transaction_Id = data.Transaction_Id; params.success(dataItem); }, error(xhr, status) { params.failed(); alert(locale.addFailed); }, }); }, delete(params) { $.ajax({ url: `${baseUrl}/${params.dataItem.Transaction_Id}`, type: 'DELETE', success() { const deleteCount = 1; params.success(deleteCount); }, error(xhr, status) { params.failed(); alert(locale.deleteFailed); }, }); }, update(params) { $.ajax({ url: `${baseUrl}/${params.dataItem.Transaction_Id}`, type: 'PUT', data: params.dataItem, success(data) { params.success(data); }, error(xhr, status) { params.failed(); alert(locale.updateFailed); }, }); }, }; function getRecords(start, count) { const result = []; if (start !== undefined) { result.push(`start=${start}`); } if (count !== undefined) { result.push(`count=${count}`); } if (result.length > 0) { return `${baseUrl}?${result.join('&')}`; } return baseUrl; }
module.exports = { loadFailed: 'Failed to load data from remote web site.', addFailed: 'add item on server side failed.', deleteFailed: 'delete item on server side failed.', updateFailed: 'update item on server side failed.', addNew: ' Add new record', };
import React from 'react'; import DataView from '@grapecity/dataviews.react'; const pageControllerStub = { getStatus() { return { pageIndex: 0, pageSize: 10, maxItems: 0, maxPages: 0 }; }, first() {}, previous() {}, next() {}, last() {}, goToPage() {}, statusChanged: { addHandler() {}, removeHandler() {}, }, }; const PagerImpl = ({ ctrl, status, page, onPageChange }) => { const activePage = status.pageIndex + 1; const pageNum = page === undefined ? activePage : page; const handlePageChange = (e) => { const { key, keyCode, target } = e; const usedKey = key || keyCode; if (usedKey === 'Enter' || usedKey === 13) { const nextPage = target.value; if (nextPage > 0 && nextPage <= status.maxPages) { ctrl.goToPage(nextPage - 1); } else { onPageChange(activePage); } } }; const handlePageBlur = (e) => { const { target } = e; const nextPage = target.value; if (nextPage > 0 && nextPage <= status.maxPages) { ctrl.goToPage(nextPage - 1); } else { onPageChange(activePage); } }; const handleGoFirst = () => { ctrl.first(); onPageChange(1); }; const handleGoPrevious = () => { ctrl.previous(); onPageChange(activePage - 1); }; const handleGoNext = () => { ctrl.next(); onPageChange(activePage + 1); }; const handleGoLast = () => { ctrl.last(); onPageChange(status.maxPages); }; const end = Math.min((status.pageIndex + 1) * status.pageSize, status.maxItems); const start = Math.min(status.pageIndex * status.pageSize + 1, end); const c1 = status.pageIndex === 0 ? ' intangible' : ''; const c2 = status.pageIndex >= status.maxPages - 1 ? ' intangible' : ''; return ( <div id="page-nav"> <div className="left-part"> <button id="firstBtn" disabled={!!c1} className={`button${c1}`} onClick={handleGoFirst}> <span className="fa fa-step-backward" /> </button> <button id="previousBtn" disabled={!!c1} className={`button${c1}`} onClick={handleGoPrevious}> <span className="fa fa-chevron-left" /> </button> <div className="divider" /> <div className="content"> {' page '} <input id="currentPage-input" value={pageNum} onChange={(e) => onPageChange(e.target.value)} onKeyDown={handlePageChange} onBlur={handlePageBlur} /> {' of '} <span id="totalPages">{status.maxPages}</span> </div> <div className="divider" /> <button id="nextBtn" disabled={!!c2} className={`button${c2}`} onClick={handleGoNext}> <span className="fa fa-chevron-right" /> </button> <button id="lastBtn" disabled={!!c2} className={`button${c2}`} onClick={handleGoLast}> <span className="fa fa-step-forward" /> </button> </div> <div className="right-part"> <div className="content"> Rows <span id="startIndex">{start}</span> - <span id="endIndex">{end}</span> of{' '} <span id="totalItems">{status.maxItems}</span> </div> </div> </div> ); }; class Pager extends React.Component { constructor(props) { super(props); const ctrl = this.findCtrl(); this.state = { ctrl, status: ctrl.getStatus(), page: undefined, }; this.handleStatusChange = this.handleStatusChange.bind(this); } findCtrl() { if (this.props.pageController) { return this.props.pageController; } const dataView = DataView.getControlByElement(document.body); return (dataView ? dataView.data.pageController : undefined) || pageControllerStub; } componentDidMount() { const retry = () => { if (this.state.ctrl !== pageControllerStub) { this.state.ctrl.statusChanged.addHandler(this.handleStatusChange); return; } const ctrl = this.findCtrl(); if (ctrl !== pageControllerStub) { ctrl.statusChanged.addHandler(this.handleStatusChange); this.setState({ ctrl, status: ctrl.getStatus() }); return; } setTimeout(retry, 10); }; retry(); } componentWillUnmount() { this.state.ctrl.statusChanged.removeHandler(this.handleStatusChange); } handleStatusChange(newStatus) { this.setState({ status: newStatus }); } render() { return ( <PagerImpl ctrl={this.state.ctrl} status={this.state.status} page={this.state.page} onPageChange={(page) => this.setState({ page })} /> ); } } export default Pager;
.main-container { display: flex; flex-direction: column; width: 100%; height: 100%; } #grid { width: 100%; height: calc(100% - 43px); min-height: 300px; flex-grow: 0; flex-shrink: 0; } .gc-action-area { text-align: center; } .gc-header-row-cell { background-color: #eaeaea; display: flex; align-items: center; } #btnAddNew { display: flex; align-items: center; border-radius: 5px; margin: 5px; } .add-icon { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7CAAAOwgEVKEqAAAAAB3RJTUUH3QsJATErA49PDwAAAgBJREFUOMut1T1IVWEYB/DfPfdKXxTRkFFD0KUhDUIotEYHl0KkoKlF+qBIoqGGloZoq6EPpaAiCGmIDDVaa4sgSYSyaIiiEEkSK4REr7flOXA63NsH9MCBw/s+z//5/r+Fjo4ONWQrdmMvmlGN8wJe4QEe4WXesJADXImTOI05PMczTMf9GrRhB5bgAi7hewpQyoCtQy/24V4oj6gt28PpOWxDDyazgKvRhz04hluYV19GcABPcDlKcRAzKWBP1Oswbvo7mcd1LOAGRnG+WC6Xm3EH93E204BUVmEX1mMqALIyhs04hKEEneHtIio1ItmCAdzG2hr3lbCdR2eCLjyNkOulVox6/6ijMxoYXQmaYjSyqa7AJjRGqgUk2IgN8TVk9KuB0VQKxS85j+3RnG9YHg6WRepVfEI33mZsppEkoVDxn6QUgI2588fYidnYiruRxX5MhM7nnM0aLJYwjtaoU1rHWbyL/4k4X8SHGkDpjrdhPMFgzFlLnSwaoiQLWFpHpyUwBhMMh9GpGI+8vI797q4TXTFsGzBcLJfLU9HpE/iIFzmDObyPu4UagEdwJohiIN3l3gi7Lxr1J3JIS3E0yGEAV0VkMIPjeIhr6A+K8hv66seV4IAefM3z4WTUaSy4rj1HsJXY5dYYpWKQyS8EW/iHJ6AaGaVPwBDe5A1/AgojgwuRXC6BAAAAAElFTkSuQmCC"); background-repeat: no-repeat; border: 0; color: transparent; cursor: pointer; height: 20px; margin-right: 5px; padding: 0; width: 20px; } .edit-icon { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAAAVJJREFUOBGV0ksrRGEcx/FjhmJBLGyUCElRyuUNaIp4B1ayUd6AjbLxjixtZBALElGuRQmRSwkpl+/3zDmTOcYY//qcy3P5nfM85wRBEKRgdWEaDd5QcXvu7o9jL/2v+MQeamGVHTLLYCffROdFzlZFJLwpdWih8w6GnCEDl1MJy6CilabVQffYQjtmMI9n9GMZLsXwH2XABzwfw1cfwwjasI8erMMHObagnGiZ7lMeMYhNDKMet2jEDqpQEBIH0J6vNa4yWME4DK3BG05QEJIMiNeaZeAoljCJA3TgHFdwXrgnyQAbbXvHNoawgSmsYgCH8IuFXyYZQHuY7IY9wSf24QiGuKkv8GcL36JYAH3hRrnWa/iHNkVtbmQ1mrGL9G8B9OVDTrn2186iE3N4wAJKzac7Vy7H6oZLcp8ukELZFYc4YQKXcIP/Vd+fWMfMVmd/AZ8ZSPZy3VL5AAAAAElFTkSuQmCC"); } .save-icon { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAUUlEQVQ4T2NkYGD4z0AeWMDAwJDISIEBIGsXIBuAyzCQOAjAXAriJzAwMMwHCZJrANzAoWEAehyhhAm6F0iJUHCgjhow2MKAlCiEq6U0NzIAAGhyJqIFiXmZAAAAAElFTkSuQmCC"); } .cancel-icon { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAv0lEQVQ4T6WT7RHBQBRFTyqgA3RAB0rQASoQHShBOtAJKpASlKAD5mR2Z3YIJrvvV5K3e+59H6kojAo4AZuEMwV2wBKYh+8tcAEa4J5qCngGyBY4hsu/fHlmHw9EgO8PYBwSKulMZUMnNbBOHC18TgERaiJefHciyFJGoZy6D6Cy5XwLIbeQnPUBzP2DmLecRkBORBdtLkBRp9c1MTeKAC7ZGbjmOogLl9XEjzEO7YH/wiRdpKEAHRyAVekUOuEXS4Mk/lKeo50AAAAASUVORK5CYII="); } .action-btn { background-color: transparent; border: 0; display: inline-block; line-height: 1.5rem; font-size: 1.5rem; text-align: center; vertical-align: middle; padding: 0; outline: none; } .action-btn span { display: block; height: 16px; width: 16px; } /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkZlYXR1cmVzL0RhdGFCaW5kaW5nL0NSVUQvcmVhY3Qvc3R5bGVzLnNjc3MiLCJGZWF0dXJlcy9EYXRhQmluZGluZy9DUlVEL3JlYWN0L3N0eWxlcy5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7RUFDRSxhQUFBO0VBQ0Esc0JBQUE7RUFDQSxXQUFBO0VBQ0EsWUFBQTtBQ0NGOztBREVBO0VBQ0UsV0FBQTtFQUNBLHlCQUFBO0VBQ0EsaUJBQUE7RUFDQSxZQUFBO0VBQ0EsY0FBQTtBQ0NGOztBREVBO0VBQ0Usa0JBQUE7QUNDRjs7QURFQTtFQUNFLHlCQUFBO0VBQ0EsYUFBQTtFQUNBLG1CQUFBO0FDQ0Y7O0FERUE7RUFDRSxhQUFBO0VBQ0EsbUJBQUE7RUFDQSxrQkFBQTtFQUNBLFdBQUE7QUNDRjs7QURFQTtFQUNFLDYyQkFBQTtFQUNBLDRCQUFBO0VBQ0EsU0FBQTtFQUNBLGtCQUFBO0VBQ0EsZUFBQTtFQUNBLFlBQUE7RUFDQSxpQkFBQTtFQUNBLFVBQUE7RUFDQSxXQUFBO0FDQ0Y7O0FERUE7RUFDRSxpa0NBQUE7QUNDRjs7QURFQTtFQUNFLGlPQUFBO0FDQ0Y7O0FERUE7RUFDRSxxWEFBQTtBQ0NGOztBREVBO0VBQ0UsNkJBQUE7RUFDQSxTQUFBO0VBQ0EscUJBQUE7RUFDQSxtQkFBQTtFQUNBLGlCQUFBO0VBQ0Esa0JBQUE7RUFDQSxzQkFBQTtFQUNBLFVBQUE7RUFDQSxhQUFBO0FDQ0Y7O0FERUE7RUFDRSxjQUFBO0VBQ0EsWUFBQTtFQUNBLFdBQUE7QUNDRiIsImZpbGUiOiJGZWF0dXJlcy9EYXRhQmluZGluZy9DUlVEL3JlYWN0L3N0eWxlcy5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIubWFpbi1jb250YWluZXIge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xufVxuXG4jZ3JpZCB7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IGNhbGMoMTAwJSAtIDQzcHgpO1xuICBtaW4taGVpZ2h0OiAzMDBweDtcbiAgZmxleC1ncm93OiAwO1xuICBmbGV4LXNocmluazogMDtcbn1cblxuLmdjLWFjdGlvbi1hcmVhIHtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xufVxuXG4uZ2MtaGVhZGVyLXJvdy1jZWxsIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2VhZWFlYTtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbn1cblxuI2J0bkFkZE5ldyB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGJvcmRlci1yYWRpdXM6IDVweDtcbiAgbWFyZ2luOiA1cHg7XG59XG5cbi5hZGQtaWNvbiB7XG4gIGJhY2tncm91bmQ6IHVybCgnZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFCUUFBQUFVQ0FZQUFBQ05pUjBOQUFBQUJtSkxSMFFBL3dEL0FQK2d2YWVUQUFBQUNYQklXWE1BQUE3Q0FBQU93Z0VWS0VxQUFBQUFCM1JKVFVVSDNRc0pBVEVyQTQ5UER3QUFBZ0JKUkVGVU9NdXQxVDFJVldFWUIvRGZQZmRLWHhUUmtGRkQwS1VoRFVJb3RFWUhsMEtrb0tsRitxQklvcUdHbG9ab3E2RVBwYUFpQ0dtSUREVmFhNHNnU1lTeWFJaWlFRWtTSzRSRXI3ZmxPWEE2M05zSDlNQ0J3L3Mrei8vNS9yK0ZqbzRPTldRcmRtTXZtbEdOOHdKZTRRRWU0V1hlc0pBRFhJbVRPSTA1UE1jelRNZjlHclJoQjViZ0FpN2hld3BReW9DdFF5LzI0VjRvajZndDI4UHBPV3hERHlhemdLdlJoejA0aGx1WVYxOUdjQUJQY0RsS2NSQXpLV0JQMU9zd2J2bzdtY2QxTE9BR1JuRytXQzZYbTNFSDkzRTIwNEJVVm1FWDFtTXFBTEl5aHMwNGhLRUVuZUh0SWlvMUl0bUNBZHpHMmhyM2xiQ2RSMmVDTGp5TmtPdWxWb3g2LzZpak14b1lYUW1hWWpTeXFhN0FKalJHcWdVazJJZ044VFZrOUt1QjBWUUt4Uzg1aiszUm5HOVlIZzZXUmVwVmZFSTMzbVpzcHBFa29WRHhuNlFVZ0kyNTg4ZllpZG5ZaXJ1UnhYNU1oTTdubk0wYUxKWXdqdGFvVTFySFdieUwvNGs0WDhTSEdrRHBqcmRoUE1GZ3pGbExuU3dhb2lRTFdGcEhweVV3QmhNTWg5R3BHSSs4dkk3OTdxNFRYVEZzR3pCY0xKZkxVOUhwRS9pSUZ6bURPYnlQdTRVYWdFZHdKb2hpSU4zbDNnaTdMeHIxSjNKSVMzRTB5R0VBVjBWa01JUGplSWhyNkErSzhodjY2c2VWNElBZWZNM3o0V1RVYVN5NHJqMUhzSlhZNWRZWXBXS1F5UzhFVy9pSEo2QWFHYVZQd0JEZTVBMS9BZ29qZ3d1UlhDNkJBQUFBQUVsRlRrU3VRbUNDJyk7XG4gIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gIGJvcmRlcjogMDtcbiAgY29sb3I6IHRyYW5zcGFyZW50O1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGhlaWdodDogMjBweDtcbiAgbWFyZ2luLXJpZ2h0OiA1cHg7XG4gIHBhZGRpbmc6IDA7XG4gIHdpZHRoOiAyMHB4O1xufVxuXG4uZWRpdC1pY29uIHtcbiAgYmFja2dyb3VuZDogdXJsKCdkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJBQUFBQVFDQVlBQUFBZjgvOWhBQUFBQVhOU1IwSUFyczRjNlFBQUFBbHdTRmx6QUFBTEV3QUFDeE1CQUpxY0dBQUFBVmxwVkZoMFdFMU1PbU52YlM1aFpHOWlaUzU0YlhBQUFBQUFBRHg0T25odGNHMWxkR0VnZUcxc2JuTTZlRDBpWVdSdlltVTZibk02YldWMFlTOGlJSGc2ZUcxd2RHczlJbGhOVUNCRGIzSmxJRFV1TkM0d0lqNEtJQ0FnUEhKa1pqcFNSRVlnZUcxc2JuTTZjbVJtUFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eE9UazVMekF5THpJeUxYSmtaaTF6ZVc1MFlYZ3Ribk1qSWo0S0lDQWdJQ0FnUEhKa1pqcEVaWE5qY21sd2RHbHZiaUJ5WkdZNllXSnZkWFE5SWlJS0lDQWdJQ0FnSUNBZ0lDQWdlRzFzYm5NNmRHbG1aajBpYUhSMGNEb3ZMMjV6TG1Ga2IySmxMbU52YlM5MGFXWm1MekV1TUM4aVBnb2dJQ0FnSUNBZ0lDQThkR2xtWmpwUGNtbGxiblJoZEdsdmJqNHhQQzkwYVdabU9rOXlhV1Z1ZEdGMGFXOXVQZ29nSUNBZ0lDQThMM0prWmpwRVpYTmpjbWx3ZEdsdmJqNEtJQ0FnUEM5eVpHWTZVa1JHUGdvOEwzZzZlRzF3YldWMFlUNEtUTUluV1FBQUFWSkpSRUZVT0JHVjBrc3JSR0VjeC9GamhtSkJMR3lVQ0VsUnl1VU5hSXA0QjFheVVkNkFqYkx4aml4dFpCQUxFbEd1UlFtUlN3a3BsKy8zekRtVE9jWVkvL3FjeTNQNW5mTTg1d1JCRUtSZ2RXRWFEZDVRY1h2dTdvOWpMLzJ2K01RZWFtR1ZIVExMWUNmZlJPZEZ6bFpGSkx3cGRXaWg4dzZHbkNFRGwxTUp5NkNpbGFiVlFmZllRanRtTUk5bjlHTVpMc1h3SDJYQUJ6d2Z3MWNmd3dqYXNJOGVyTU1IT2JhZ25HaVo3bE1lTVloTkRLTWV0MmpFRHFwUUVCSUgwSjZ2TmE0eVdNRTRESzNCRzA1UUVKSU1pTmVhWmVBb2xqQ0pBM1RnSEZkd1hyZ255UUFiYlh2SE5vYXdnU21zWWdDSDhJdUZYeVlaUUh1WTdJWTl3U2YyNFFpR3VLa3Y4R2NMMzZKWUFIM2hScm5XYS9pSE5rVnRibVExbXJHTDlHOEI5T1ZEVHJuMjE4NmlFM040d0FKS3phYzdWeTdINm9aTGNwOHVrRUxaRlljNFlRS1hjSVAvVmQrZldNZk1WbWQvQVo4WlNQWnkzVkw1QUFBQUFFbEZUa1N1UW1DQycpO1xufVxuXG4uc2F2ZS1pY29uIHtcbiAgYmFja2dyb3VuZDogdXJsKCdkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJBQUFBQVFDQVlBQUFBZjgvOWhBQUFBVVVsRVFWUTRUMk5rWUdENHowQWVXTURBd0pESVNJRUJJR3NYSUJ1QXl6Q1FPQWpBWEFyaUp6QXdNTXdIQ1pKckFOekFvV0VBZWh5aGhBbTZGMGlKVUhDZ2pob3cyTUtBbENpRXE2VTBOeklBQUdoeUpxSUZpWG1aQUFBQUFFbEZUa1N1UW1DQycpO1xufVxuXG4uY2FuY2VsLWljb24ge1xuICBiYWNrZ3JvdW5kOiB1cmwoJ2RhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQkFBQUFBUUNBWUFBQUFmOC85aEFBQUF2MGxFUVZRNFQ2V1Q3UkhCUUJSRlR5cWdBM1JBQjByUUFTb1FIU2hCT3RBSktwQVNsS0FENW1SMlozWUlKcnZ2VjVLM2UrNTlINmtvakFvNEFadUVNd1Yyd0JLWWgrOHRjQUVhNEo1cUNuZ0d5Qlk0aHN1L2ZIbG1IdzlFZ084UFlCd1NLdWxNWlVNbk5iQk9IQzE4VGdFUmFpSmVmSGNpeUZKR29aeTZENkN5NVh3TEliZVFuUFVCelAyRG1MZWNSa0JPUkJkdExrQlJwOWMxTVRlS0FDN1pHYmptT29nTGw5WEVqekVPN1lIL3dpUmRwS0VBSFJ5QVZla1VPdUVYUzRNay9sS2VvNTBBQUFBQVNVVk9SSzVDWUlJPScpO1xufVxuXG4uYWN0aW9uLWJ0biB7XG4gIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuICBib3JkZXI6IDA7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgbGluZS1oZWlnaHQ6IDEuNXJlbTtcbiAgZm9udC1zaXplOiAxLjVyZW07XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbiAgcGFkZGluZzogMDtcbiAgb3V0bGluZTogbm9uZTtcbn1cblxuLmFjdGlvbi1idG4gc3BhbiB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBoZWlnaHQ6IDE2cHg7XG4gIHdpZHRoOiAxNnB4O1xufVxuIiwiLm1haW4tY29udGFpbmVyIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMTAwJTtcbn1cblxuI2dyaWQge1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiBjYWxjKDEwMCUgLSA0M3B4KTtcbiAgbWluLWhlaWdodDogMzAwcHg7XG4gIGZsZXgtZ3JvdzogMDtcbiAgZmxleC1zaHJpbms6IDA7XG59XG5cbi5nYy1hY3Rpb24tYXJlYSB7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbn1cblxuLmdjLWhlYWRlci1yb3ctY2VsbCB7XG4gIGJhY2tncm91bmQtY29sb3I6ICNlYWVhZWE7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG59XG5cbiNidG5BZGROZXcge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBib3JkZXItcmFkaXVzOiA1cHg7XG4gIG1hcmdpbjogNXB4O1xufVxuXG4uYWRkLWljb24ge1xuICBiYWNrZ3JvdW5kOiB1cmwoXCJkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJRQUFBQVVDQVlBQUFDTmlSME5BQUFBQm1KTFIwUUEvd0QvQVArZ3ZhZVRBQUFBQ1hCSVdYTUFBQTdDQUFBT3dnRVZLRXFBQUFBQUIzUkpUVVVIM1FzSkFURXJBNDlQRHdBQUFnQkpSRUZVT011dDFUMUlWV0VZQi9EZlBmZEtYeFRSa0ZGRDBLVWhEVUlvdEVZSGwwS2tvS2xGK3FCSW9xR0dsb1pvcTZFUHBhQWlDR21JRERWYWE0c2dTWVN5YUlpaUVFa1NLNFJFcjdmbE9YQTYzTnNIOU1DQncvcyt6Ly81L3IrRmpvNE9OV1FyZG1Ndm1sR044d0plNFFFZTRXWGVzSkFEWEltVE9JMDVQTWN6VE1mOUdyUmhCNWJnQWk3aGV3cFF5b0N0UXkvMjRWNG9qNmd0MjhQcE9XeEREeWF6Z0t2Umh6MDRobHVZVjE5R2NBQlBjRGxLY1JBektXQlAxT3N3YnZvN21jZDFMT0FHUm5HK1dDNlhtM0VIOTNFMjA0QlVWbUVYMW1NcUFMSXloczA0aEtFRW5lSHRJaW8xSXRtQ0FkekcyaHIzbGJDZFIyZUNManlOa091bFZveDYvNmlqTXhvWVhRbWFZalN5cWE3QUpqUkdxZ1VrMklnTjhUVms5S3VCMFZRS3hTODVqKzNSbkc5WUhnNldSZXBWZkVJMzNtWnNwcEVrb1ZEeG42UVVnSTI1ODhmWWlkbllpcnVSeFg1TWhNN25uTTBhTEpZd2p0YW9VMXJIV2J5TC80azRYOFNIR2tEcGpyZGhQTUZnekZsTG5Td2FvaVFMV0ZwSHB5VXdCaE1NaDlHcEdJKzh2STc5N3E0VFhURnNHekJjTEpmTFU5SHBFL2lJRnptRE9ieVB1NFVhZ0Vkd0pvaGlJTjNsM2dpN0x4cjFKM0pJUzNFMHlHRUFWMFZrTUlQamVJaHI2QStLOGh2NjZzZVY0SUFlZk0zejRXVFVhU3k0cmoxSHNKWFk1ZFlZcFdLUXlTOEVXL2lISjZBYUdhVlB3QkRlNUExL0Fnb2pnd3VSWEM2QkFBQUFBRWxGVGtTdVFtQ0NcIik7XG4gIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gIGJvcmRlcjogMDtcbiAgY29sb3I6IHRyYW5zcGFyZW50O1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGhlaWdodDogMjBweDtcbiAgbWFyZ2luLXJpZ2h0OiA1cHg7XG4gIHBhZGRpbmc6IDA7XG4gIHdpZHRoOiAyMHB4O1xufVxuXG4uZWRpdC1pY29uIHtcbiAgYmFja2dyb3VuZDogdXJsKFwiZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFCQUFBQUFRQ0FZQUFBQWY4LzloQUFBQUFYTlNSMElBcnM0YzZRQUFBQWx3U0ZsekFBQUxFd0FBQ3hNQkFKcWNHQUFBQVZscFZGaDBXRTFNT21OdmJTNWhaRzlpWlM1NGJYQUFBQUFBQUR4NE9uaHRjRzFsZEdFZ2VHMXNibk02ZUQwaVlXUnZZbVU2Ym5NNmJXVjBZUzhpSUhnNmVHMXdkR3M5SWxoTlVDQkRiM0psSURVdU5DNHdJajRLSUNBZ1BISmtaanBTUkVZZ2VHMXNibk02Y21SbVBTSm9kSFJ3T2k4dmQzZDNMbmN6TG05eVp5OHhPVGs1THpBeUx6SXlMWEprWmkxemVXNTBZWGd0Ym5NaklqNEtJQ0FnSUNBZ1BISmtaanBFWlhOamNtbHdkR2x2YmlCeVpHWTZZV0p2ZFhROUlpSUtJQ0FnSUNBZ0lDQWdJQ0FnZUcxc2JuTTZkR2xtWmowaWFIUjBjRG92TDI1ekxtRmtiMkpsTG1OdmJTOTBhV1ptTHpFdU1DOGlQZ29nSUNBZ0lDQWdJQ0E4ZEdsbVpqcFBjbWxsYm5SaGRHbHZiajR4UEM5MGFXWm1Pazl5YVdWdWRHRjBhVzl1UGdvZ0lDQWdJQ0E4TDNKa1pqcEVaWE5qY21sd2RHbHZiajRLSUNBZ1BDOXlaR1k2VWtSR1BnbzhMM2c2ZUcxd2JXVjBZVDRLVE1JbldRQUFBVkpKUkVGVU9CR1Ywa3NyUkdFY3gvRmpobUpCTEd5VUNFbFJ5dVVOYUlwNEIxYXlVZDZBamJMeGppeHRaQkFMRWxHdVJRbVJTd2twbCsvM3pEbVRPY1lZLy9xY3kzUDVuZk04NXdSQkVLUmdkV0VhRGQ1UWNYdnU3bzlqTC8yditNUWVhbUdWSFRMTFlDZmZST2RGemxaRkpMd3BkV2loOHc2R25DRURsMU1KeTZDaWxhYlZRZmZZUWp0bU1JOW45R01aTHNYd0gyWEFCendmdzFjZnd3amFzSThlck1NSE9iYWduR2laN2xNZU1ZaE5ES01ldDJqRURxcFFFQklIMEo2dk5hNHlXTUU0REszQkcwNVFFSklNaU5lYVplQW9sakNKQTNUZ0hGZHdYcmdueVFBYmJYdkhOb2F3Z1Ntc1lnQ0g4SXVGWHlZWlFIdVk3SVk5d1NmMjRRaUd1S2t2OEdjTDM2SllBSDNoUnJuV2EvaUhOa1Z0Ym1RMW1yR0w5RzhCOU9WRFRybjIxODZpRTNONHdBSkt6YWM3Vnk3SDZvWkxjcDh1a0VMWkZZYzRZUUtYY0lQL1ZkK2ZXTWZNVm1kL0FaOFpTUFp5M1ZMNUFBQUFBRWxGVGtTdVFtQ0NcIik7XG59XG5cbi5zYXZlLWljb24ge1xuICBiYWNrZ3JvdW5kOiB1cmwoXCJkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJBQUFBQVFDQVlBQUFBZjgvOWhBQUFBVVVsRVFWUTRUMk5rWUdENHowQWVXTURBd0pESVNJRUJJR3NYSUJ1QXl6Q1FPQWpBWEFyaUp6QXdNTXdIQ1pKckFOekFvV0VBZWh5aGhBbTZGMGlKVUhDZ2pob3cyTUtBbENpRXE2VTBOeklBQUdoeUpxSUZpWG1aQUFBQUFFbEZUa1N1UW1DQ1wiKTtcbn1cblxuLmNhbmNlbC1pY29uIHtcbiAgYmFja2dyb3VuZDogdXJsKFwiZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFCQUFBQUFRQ0FZQUFBQWY4LzloQUFBQXYwbEVRVlE0VDZXVDdSSEJRQlJGVHlxZ0EzUkFCMHJRQVNvUUhTaEJPdEFKS3BBU2xLQUQ1bVIyWjNZSUpydnZWNUszZSs1OUg2a29qQW80QVp1RU13VjJ3QktZaCs4dGNBRWE0SjVxQ25nR3lCWTRoc3UvZkhsbUh3OUVnTzhQWUJ3U0t1bE1aVU1uTmJCT0hDMThUZ0VSYWlKZWZIY2l5RkpHb1p5NkQ2Q3k1WHdMSWJlUW5QVUJ6UDJEbUxlY1JrQk9SQmR0TGtCUnA5YzFNVGVLQUM3Wkdiam1Pb2dMbDlYRWp6RU83WUgvd2lSZHBLRUFIUnlBVmVrVU91RVhTNE1rL2xLZW81MEFBQUFBU1VWT1JLNUNZSUk9XCIpO1xufVxuXG4uYWN0aW9uLWJ0biB7XG4gIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuICBib3JkZXI6IDA7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgbGluZS1oZWlnaHQ6IDEuNXJlbTtcbiAgZm9udC1zaXplOiAxLjVyZW07XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbiAgcGFkZGluZzogMDtcbiAgb3V0bGluZTogbm9uZTtcbn1cblxuLmFjdGlvbi1idG4gc3BhbiB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBoZWlnaHQ6IDE2cHg7XG4gIHdpZHRoOiAxNnB4O1xufSJdfQ== */
(function () { const IS_PROD = window.process.env.NODE_ENV === 'production'; const USE_NPM = window.process.env.USE_NPM; const USE_CDN = window.process.env.USE_CDN; const SITE_ROOT = window.process.env.SITE_ROOT; const FRAMEWORK = window.process.env.FRAMEWORK; const ext = IS_PROD ? '.min.js' : '.js'; function js(name) { return name + ext; } function npm(t) { if (!t.file) { t.file = IS_PROD ? t.prod : t.dev; } const version = USE_CDN && t.version ? '@' + t.version : ''; const path = t.pkg + version + '/' + t.file; if (USE_CDN) { return 'https://unpkg.com/' + path; } return 'npm:' + path; } function dv(t) { if (USE_CDN || USE_NPM) { t.file = 'dist/' + t.file + '.min.js'; return npm(t); } return SITE_ROOT + '/static/dataviews/' + js(t.file); } const isTypeScript = FRAMEWORK === 'angular'; const babelConfig = { es2015: true, react: true, }; const meta = { js: { babelOptions: babelConfig, }, ts: { typescriptOptions: { tsconfig: true }, }, }; const map = { // gc.dataviews packages '@grapecity/dataviews.common': dv({pkg:'@grapecity/dataviews.common',file:'gc.dataviews.common',version:'1.8.17'}), '@grapecity/dataviews.core': dv({pkg:'@grapecity/dataviews.core',file:'gc.dataviews.core',version:'1.8.17'}), '@grapecity/dataviews.grid': dv({pkg:'@grapecity/dataviews.grid',file:'gc.dataviews.grid',version:'1.8.17'}), '@grapecity/dataviews.cardlayout': dv({pkg:'@grapecity/dataviews.cardlayout',file:'gc.dataviews.cardlayout',version:'1.8.17'}), '@grapecity/dataviews.masonry': dv({pkg:'@grapecity/dataviews.masonry',file:'gc.dataviews.masonry',version:'1.8.17'}), '@grapecity/dataviews.calendar': dv({pkg:'@grapecity/dataviews.calendar',file:'gc.dataviews.calendar',version:'1.8.17'}), '@grapecity/dataviews.timeline': dv({pkg:'@grapecity/dataviews.timeline',file:'gc.dataviews.timeline',version:'1.8.17'}), '@grapecity/dataviews.trellis': dv({pkg:'@grapecity/dataviews.trellis',file:'gc.dataviews.trellis',version:'1.8.17'}), '@grapecity/dataviews.gantt': dv({pkg:'@grapecity/dataviews.gantt',file:'gc.dataviews.gantt',version:'1.8.17'}), '@grapecity/dataviews.searchbox': dv({pkg:'@grapecity/dataviews.searchbox',file:'gc.dataviews.searchbox',version:'1.8.17'}), '@grapecity/dataviews.react': dv({pkg:'@grapecity/dataviews.react',file:'gc.dataviews.react',version:'1.8.17'}), '@grapecity/dataviews.vue': dv({pkg:'@grapecity/dataviews.vue',file:'gc.dataviews.vue',version:'1.8.17'}), '@grapecity/dataviews.angular': dv({pkg:'@grapecity/dataviews.angular',file:'gc.dataviews.angular',version:'1.8.17'}), '@grapecity/dataviews.csvexport': dv({pkg:'@grapecity/dataviews.angular',file:'gc.dataviews.csvexport',version:'1.8.17'}), // third-party libs react: npm({pkg:'react',prod:'umd/react.production.min.js',dev:'umd/react.development.js',version:'16.13.1'}), 'react-dom': npm({pkg:'react-dom',prod:'umd/react-dom.production.min.js',dev:'umd/react-dom.development.js',version:'16.13.1'}), 'react-router-dom': npm({pkg:'react-router-dom',prod:'umd/react-router-dom.min.js',dev:'umd/react-router-dom.js',version:'5.2.0'}), 'vue': npm({pkg:'vue',file:'dist/vue.js',version:'2.6.12'}), 'vue-router': npm({pkg:'vue-router',file:'dist/vue-router.js',version:'3.4.3'}), 'lodash': npm({pkg: 'lodash', file: js('lodash')}), 'zone.js': npm({pkg: 'zone.js', file: js('dist/zone')}), 'rxjs': npm({pkg: 'rxjs', file: js('bundles/rxjs.umd')}), 'rxjs/operators': npm({pkg:'rxjs-operators-bundle',prod:'dist/bundle.min.js',dev:'dist/bundle.js',version:'1.0.2'}), '@angular/core': npm({pkg: '@angular/core', file: js('bundles/core.umd')}), '@angular/common': npm({pkg: '@angular/common', file: js('bundles/common.umd')}), '@angular/compiler': npm({pkg: '@angular/compiler', file: js('bundles/compiler.umd')}), '@angular/platform-browser': npm({pkg: '@angular/platform-browser', file: js('bundles/platform-browser.umd')}), '@angular/platform-browser-dynamic': npm({pkg: '@angular/platform-browser-dynamic', file: js('bundles/platform-browser-dynamic.umd')}), '@angular/http': npm({pkg: '@angular/http', file: js('bundles/http.umd')}), '@angular/common/http': npm({pkg: '@angular/common', file: js('bundles/common-http.umd')}), '@angular/router': npm({pkg: '@angular/router', file: js('bundles/router.umd')}), '@angular/forms': npm({pkg: '@angular/forms', file: js('bundles/forms.umd')}), // systemjs plugins 'systemjs-plugin-json': npm({pkg:'systemjs-plugin-json',file:'json.js',version:'0.3.0'}), 'systemjs-plugin-css': npm({pkg:'systemjs-plugin-css',file:'css.js',version:'0.1.37'}), 'systemjs-plugin-babel': npm({pkg:'systemjs-plugin-babel',file:'plugin-babel.js',version:'0.0.25'}), 'systemjs-babel-build': npm({pkg:'systemjs-plugin-babel',file:'systemjs-babel-browser.js',version:'0.0.25'}), 'plugin-typescript': npm({pkg:'plugin-typescript',file:'lib/plugin.js',version:'8.0.0'}), 'typescript': npm({pkg:'typescript',file:'lib/typescript.js',version:'4.0.2'}), 'systemjs-vue-browser': npm({pkg:'systemjs-vue-browser',file:'index.js',version:'1.0.11'}), }; const config = { defaultJSExtensions: true, transpiler: isTypeScript ? 'plugin-typescript' : 'systemjs-plugin-babel', typescriptOptions: { tsconfig: true }, meta: { '*.json': {loader: 'systemjs-plugin-json'}, '*.css': {loader: 'systemjs-plugin-css'}, '*.vue': {loader: 'systemjs-vue-browser'}, '*.js': meta.js, '*.ts': meta.ts, 'app.js': { format: 'esm', babelOptions: babelConfig, }, 'typescript': { exports: 'ts', }, '@grapecity/dataviews.common': { format: 'amd', }, '@grapecity/dataviews.core': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.grid': { format: 'amd', deps: [ '@grapecity/dataviews.common', '@grapecity/dataviews.core', ], }, '@grapecity/dataviews.cardlayout': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.masonry': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.calendar': { format: 'amd', deps: [ '@grapecity/dataviews.common', '@grapecity/dataviews.core', ], }, '@grapecity/dataviews.timeline': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.trellis': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.gantt': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.searchbox': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.react': { format: 'amd', deps: [ 'react', '@grapecity/dataviews.common', '@grapecity/dataviews.core' ], }, '@grapecity/dataviews.vue': { format: 'amd', deps: [ 'vue', '@grapecity/dataviews.common', '@grapecity/dataviews.core' ], }, '@grapecity/dataviews.angular': { format: 'amd', deps: [ '@angular/core', '@grapecity/dataviews.common', '@grapecity/dataviews.core' ], }, '@grapecity/dataviews.csvexport': { format: 'amd', deps: [ '@grapecity/dataviews.common' ], }, }, paths: { // paths serve as alias 'npm:': SITE_ROOT + '/node_modules/', }, // map tells the System loader where to look for things map: map, // packages tells the System loader how to load when no filename and/or no extension packages: { '.': { defaultExtension: isTypeScript ? 'ts' : 'js' }, node_modules: { defaultExtension: 'js' }, } }; // fast format detection to avoid detection by source code using regexp Object.keys(map).filter(function (key) { return !config.meta[key]; }).forEach(function (key) { const path = map[key]; if (path.indexOf('/umd') >= 0 || path.indexOf('.umd') >= 0) { config.meta[key] = { format: 'amd' }; } if (path.indexOf('/cjs') >= 0) { config.meta[key] = { format: 'cjs' }; } }); System.config(config); })(this);