From e025db0c06dc41b88319f1be2a8b7e4802ea25f7 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Fri, 19 Mar 2021 18:44:33 +0100 Subject: [PATCH 01/43] Configurable notebook name --- netpyne_ui/__init__.py | 3 ++- .../components/general/NetPyNEPythonConsole.js | 17 ++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/netpyne_ui/__init__.py b/netpyne_ui/__init__.py index cb0bf72e..40ebdb1a 100644 --- a/netpyne_ui/__init__.py +++ b/netpyne_ui/__init__.py @@ -1,6 +1,7 @@ import logging + from jupyter_geppetto.webapi import RouteManager from netpyne_ui import api -RouteManager.add_controller(api.NetPyNEController) \ No newline at end of file +RouteManager.add_controller(api.NetPyNEController) diff --git a/webapp/components/general/NetPyNEPythonConsole.js b/webapp/components/general/NetPyNEPythonConsole.js index ffe17bae..d519d05d 100644 --- a/webapp/components/general/NetPyNEPythonConsole.js +++ b/webapp/components/general/NetPyNEPythonConsole.js @@ -4,19 +4,22 @@ import PythonConsole from '@geppettoengine/geppetto-client/js/components/interface/pythonConsole/PythonConsole'; export class NetPyNEPythonConsole extends Component { - componentDidMount () { - } - shouldComponentUpdate () { + shouldComponentUpdate() { return false; } - componentWillUnmount () { - console.info('unmounting python console'); + componentWillUnmount() { + console.info("unmounting python console"); + } + + componentDidMount() { + } - render () { - return ; + render() { + const notebookName = GEPPETTO_CONFIGURATION.notebookName || "notebook.ipynb"; + return } } From 7702ff8843e5abdf6e04fedcc4914c0faf17885b Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Mon, 22 Mar 2021 10:50:45 +0100 Subject: [PATCH 02/43] Create notebook inside workspace --- netpyne_ui/api.py | 82 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/netpyne_ui/api.py b/netpyne_ui/api.py index 91cac361..b612c192 100644 --- a/netpyne_ui/api.py +++ b/netpyne_ui/api.py @@ -10,6 +10,7 @@ from notebook.base.handlers import IPythonHandler from netpyne_ui.constants import NETPYNE_WORKDIR, UPLOAD_FOLDER_NAME, ALLOWED_EXTENSIONS, UPLOAD_FOLDER_PATH + def allowed_file(filename, allowed_extensions=ALLOWED_EXTENSIONS): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in allowed_extensions @@ -18,7 +19,8 @@ def allowed_file(filename, allowed_extensions=ALLOWED_EXTENSIONS): def send_files(handler, file_path, filename): with open(file_path, "rb") as f: handler.set_header('Content-Type', 'application/force-download') - handler.set_header('Content-Disposition', f"attachment; filename={filename}") + handler.set_header('Content-Disposition', + f"attachment; filename={filename}") try: while True: @@ -26,7 +28,7 @@ def send_files(handler, file_path, filename): if _buffer: handler.write(_buffer) else: - return + return except: handler.set_status(500, f"Error sending files") @@ -35,36 +37,40 @@ def get_file_paths(handler): file_paths = False if 'uri' in handler.request.arguments: file_paths = [] - tmp_file_paths = [path.decode('utf-8') for path in handler.request.arguments['uri']] + tmp_file_paths = [path.decode('utf-8') + for path in handler.request.arguments['uri']] for path in tmp_file_paths: if os.path.exists(path): file_paths.append(path) - + return file_paths + class NetPyNEController: # pytest: no cover @post('/uploads') def uploads(handler: IPythonHandler): files = handler.request.files files_saved = 0 - + if len(files) == 0 or 'file' not in files: - handler.set_status(400, f"Can't find 'file' or filename is empty. Files received {len(files)}") + handler.set_status( + 400, f"Can't find 'file' or filename is empty. Files received {len(files)}") else: for f in files['file']: if not allowed_file(f.filename): - logging.warn(f"Can't store file {f.filename}. Extension not allowed") + logging.warn( + f"Can't store file {f.filename}. Extension not allowed") continue - ## Save to file + # Save to file filename = f.filename file_path = os.path.join(UPLOAD_FOLDER_PATH, filename) - + with open(file_path, 'wb') as zf: zf.write(f['body']) - + files_saved += 1 if filename.endswith('.zip'): @@ -78,34 +84,70 @@ def uploads(handler: IPythonHandler): elif filename.endswith('.gz'): with gzip.open(file_path, "rb") as gz, open(file_path.replace('.gz', ''), 'wb') as ff: shutil.copyfileobj(gz, ff) - - handler.set_status(200, f"Number of files saved: {files_saved}. Number of files sent: {len(files['file'])}") + + handler.set_status( + 200, f"Number of files saved: {files_saved}. Number of files sent: {len(files['file'])}") handler.finish() - + @get('/downloads') def downloads(handler: IPythonHandler): file_paths = get_file_paths(handler) - + if file_paths: - + if len(file_paths) == 0: handler.set_status(400, f"Files not found.") handler.finish() return if len(file_paths) == 1: - send_files(handler, file_paths[0], file_paths[0].split('/')[-1]) - - else : + send_files(handler, file_paths[0], + file_paths[0].split('/')[-1]) + + else: with TemporaryDirectory() as dir_path: tar_gz_file_name = f'{str(uuid.uuid4())}.tar.gz' tar_gz_file_path = os.path.join(dir_path, tar_gz_file_name) with tarfile.open(tar_gz_file_path, mode='w:gz') as tar: for file_path in file_paths: - tar.add(file_path, os.path.join('download', file_path.split('/')[-1])) + tar.add(file_path, os.path.join( + 'download', file_path.split('/')[-1])) send_files(handler, tar_gz_file_path, tar_gz_file_name) - + handler.finish() + + +def create_notebook(filename): + import nbformat as nbf + from nbformat.v4.nbbase import new_notebook + from nbformat import sign + import codecs + + directory = os.path.dirname(filename) + if not os.path.exists(directory): + os.makedirs(directory) + nb0 = new_notebook(cells=[nbf.v4.new_markdown_cell("""# Welcome to the NetPyNE-ui! + + """), + nbf.v4.new_code_cell( + 'netpyne_geppetto.netParams'), + nbf.v4.new_code_cell( + 'netpyne_geppetto.simConfig') + ], metadata={"kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }}) + + f = codecs.open(filename, encoding='utf-8', mode='w') + + nbf.write(nb0, filename) + f.close() + + +# TODO move to jupyter geppetto, using notebook dir path +if os.path.exists('workspace') and not os.path.exists('workspace/notebook.ipynb'): + create_notebook('workspace/notebook.ipynb') From 3554b83d5f8fb82251a9abdc62e5996026a6b83e Mon Sep 17 00:00:00 2001 From: Lucas Rebscher Date: Tue, 18 May 2021 19:31:05 +0200 Subject: [PATCH 03/43] Reduce eslint errors --- webapp/.eslintignore | 3 +- webapp/.eslintrc.js | 14 ++++++ webapp/components/topbar/SwitchPageButton.js | 43 ++++++++-------- webapp/package-lock.json | 52 ++++++++++++++------ webapp/package.json | 8 ++- webapp/redux/actions/general.js | 46 +++++++++++++---- 6 files changed, 118 insertions(+), 48 deletions(-) diff --git a/webapp/.eslintignore b/webapp/.eslintignore index 1d81b61d..f38f43ea 100644 --- a/webapp/.eslintignore +++ b/webapp/.eslintignore @@ -6,4 +6,5 @@ META-INF/* **/tests/jest-puppeteer/**/*.js **/*min.js geppetto-client/** -node_modules/** \ No newline at end of file +node_modules/** +webpack.*.js diff --git a/webapp/.eslintrc.js b/webapp/.eslintrc.js index f95a2637..1d15adc6 100644 --- a/webapp/.eslintrc.js +++ b/webapp/.eslintrc.js @@ -10,7 +10,17 @@ module.exports = { // Tweak some rules to our preferences 'space-before-function-paren': ['error', 'always'], + 'react/prop-types': 1, 'no-console': 0, + 'import/extensions': 0, + 'max-len': ['error', { code: 140 }], + 'no-eval': 1, + eqeqeq: 1, + 'no-plusplus': 1, + 'react/destructuring-assignment': 1, + 'no-param-reassign': 1, + 'vars-on-top': 1, + 'no-use-before-define': 1, }, globals: { page: true, @@ -24,5 +34,9 @@ module.exports = { patchRequire: true, window: true, GEPPETTO: true, + document: true, + $: true, + IPython: true, + fetch: true, }, }; diff --git a/webapp/components/topbar/SwitchPageButton.js b/webapp/components/topbar/SwitchPageButton.js index d66aacb0..78657cb6 100644 --- a/webapp/components/topbar/SwitchPageButton.js +++ b/webapp/components/topbar/SwitchPageButton.js @@ -38,11 +38,30 @@ class SwitchPageButton extends Component { } }; + getExploreLabel () { + const { + automaticInstantiation, + automaticSimulation, + } = this.props; + const instantiate = automaticInstantiation || this.props.modelState === MODEL_STATE.NOT_INSTANTIATED; + if (instantiate && automaticSimulation) { + return TOPBAR_CONSTANTS.CREATE_AND_SIMULATE_NETWORK; + } + if (instantiate) { + return TOPBAR_CONSTANTS.CREATE_NETWORK; + } + if (automaticSimulation) { + console.debug('Bad option combination: can\'t auto simulate without auto instantiate'); + } + return TOPBAR_CONSTANTS.EXPLORE_EXISTING_NETWORK; + } + render () { const { classes, modelState, editModelPage, + simulateNetwork, } = this.props; const disableSimulate = modelState === MODEL_STATE.SIMULATED; return ( @@ -61,7 +80,7 @@ class SwitchPageButton extends Component { id="launchSimulationButton" className={classes.rocket} size="small" - onClick={() => this.props.simulateNetwork()} + onClick={() => simulateNetwork()} disabled={disableSimulate} style={{ opacity: disableSimulate ? 0.5 : 1 }} > @@ -77,32 +96,14 @@ class SwitchPageButton extends Component { size="small" className={classes.button} onClick={this.handleClick.bind(this)} - endIcon={} + endIcon={} > - {this.props.editModelPage ? this.getExploreLabel() : TOPBAR_CONSTANTS.BACK_TO_EDITION} + {editModelPage ? this.getExploreLabel() : TOPBAR_CONSTANTS.BACK_TO_EDITION} ); } - - getExploreLabel () { - const { - automaticInstantiation, - automaticSimulation, - } = this.props; - const instantiate = automaticInstantiation || this.props.modelState === MODEL_STATE.NOT_INSTANTIATED; - if (instantiate && automaticSimulation) { - return TOPBAR_CONSTANTS.CREATE_AND_SIMULATE_NETWORK; - } - if (instantiate) { - return TOPBAR_CONSTANTS.CREATE_NETWORK; - } - if (automaticSimulation) { - console.debug('Bad option combination: can\'t auto simulate without auto instantiate'); - } - return TOPBAR_CONSTANTS.EXPLORE_EXISTING_NETWORK; - } } export default withStyles(styles)(SwitchPageButton); diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 31d1be14..f9eb7e42 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -1211,6 +1211,17 @@ "object-assign": "^4.1.1", "prop-types": "^15.6.2" } + }, + "react-dom": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + } } } }, @@ -7161,6 +7172,17 @@ "object-assign": "^4.1.1", "prop-types": "^15.6.2" } + }, + "react-dom": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + } } } }, @@ -8451,6 +8473,17 @@ "react-is": "^16.6.0", "react-lifecycles-compat": "^3.0.0" } + }, + "redux": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz", + "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", + "requires": { + "lodash": "^4.2.1", + "lodash-es": "^4.2.1", + "loose-envify": "^1.1.0", + "symbol-observable": "^1.0.3" + } } } }, @@ -13144,14 +13177,6 @@ "requires": { "dnd-core": "^11.1.3" } - }, - "redux": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.0.tgz", - "integrity": "sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g==", - "requires": { - "@babel/runtime": "^7.9.2" - } } } }, @@ -13341,14 +13366,11 @@ } }, "redux": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz", - "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.0.tgz", + "integrity": "sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g==", "requires": { - "lodash": "^4.2.1", - "lodash-es": "^4.2.1", - "loose-envify": "^1.1.0", - "symbol-observable": "^1.0.3" + "@babel/runtime": "^7.9.2" } }, "regenerate": { diff --git a/webapp/package.json b/webapp/package.json index 888a1dec..82cf8eb5 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -15,11 +15,15 @@ "dependencies": { "@babel/plugin-proposal-class-properties": "^7.8.3", "@geppettoengine/geppetto-client": "git+https://git@github.com/openworm/geppetto-client.git#hotfix/html-viewer", + "@material-ui/core": "^4.11.4", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.51", "less-vars-to-js": "^1.3.0", "react": "^17.0.1", - "react-redux": "^7.2.0" + "react-dom": "^16.4.0", + "react-redux": "^7.2.0", + "react-sortable-tree": "^2.8.0", + "redux": "^4.1.0" }, "devDependencies": { "@babel/core": "^7.4.5", @@ -74,4 +78,4 @@ ] } } -} \ No newline at end of file +} diff --git a/webapp/redux/actions/general.js b/webapp/redux/actions/general.js index 53ce0f68..fdef3776 100644 --- a/webapp/redux/actions/general.js +++ b/webapp/redux/actions/general.js @@ -1,5 +1,5 @@ import { setWidgets } from '../../components/layout/actions'; -import { EDIT_WIDGETS, PYTHON_CONSOLE_WIDGET, WidgetStatus } from '../../constants'; +import { PYTHON_CONSOLE_WIDGET, WidgetStatus } from '../../constants'; // Action Types export const UPDATE_CARDS = 'UPDATE_CARDS'; @@ -34,18 +34,46 @@ export const editModel = { type: EDIT_MODEL }; export const resetModel = { type: RESET_MODEL }; -export const pythonCall = (cmd, args) => ({ type: PYTHON_CALL, cmd, args }); +export const pythonCall = (cmd, args) => ({ + type: PYTHON_CALL, + cmd, + args, +}); -export const deleteNetParamsObj = (payload) => ({ type: DELETE_NETPARAMS_OBJ, payload }); +export const deleteNetParamsObj = (payload) => ({ + type: DELETE_NETPARAMS_OBJ, + payload, +}); export const closeDialog = { type: CLOSE_DIALOG }; -export const openDialog = (payload) => ({ type: OPEN_DIALOG, payload }); +export const openDialog = (payload) => ({ + type: OPEN_DIALOG, + payload, +}); -export const setTheme = (themeName) => ({ type: SET_THEME, payload: themeName }); +export const setTheme = (themeName) => ({ + type: SET_THEME, + payload: themeName, +}); -export const loadTutorial = (tutFile) => ({ type: LOAD_TUTORIAL, payload: tutFile }); +export const loadTutorial = (tutFile) => ({ + type: LOAD_TUTORIAL, + payload: tutFile, +}); -export const changeAutomaticInstantiation = (payload) => ({ type: AUTOMATIC_INSTANTIATION, payload }); -export const changeAutomaticSimulation = (payload) => ({ type: AUTOMATIC_SIMULATION, payload }); +export const changeAutomaticInstantiation = (payload) => ({ + type: AUTOMATIC_INSTANTIATION, + payload, +}); +export const changeAutomaticSimulation = (payload) => ({ + type: AUTOMATIC_SIMULATION, + payload, +}); -export const setDefaultWidgets = setWidgets({ [PYTHON_CONSOLE_WIDGET.id]: { ...PYTHON_CONSOLE_WIDGET, panelName: PYTHON_CONSOLE_WIDGET.defaultPanel, status: WidgetStatus.ACTIVE } }); +export const setDefaultWidgets = setWidgets({ + [PYTHON_CONSOLE_WIDGET.id]: { + ...PYTHON_CONSOLE_WIDGET, + panelName: PYTHON_CONSOLE_WIDGET.defaultPanel, + status: WidgetStatus.ACTIVE, + }, +}); From 7e6f9cac43588e615651a027ec8471f481f13df5 Mon Sep 17 00:00:00 2001 From: Lucas Rebscher Date: Wed, 19 May 2021 10:51:51 +0200 Subject: [PATCH 04/43] Reduce eslint errors --- tests/frontend/e2e/.eslintrc.js | 4 +- webapp/.eslintrc.js | 42 ++++++- webapp/components/general/Dialog.js | 8 +- webapp/components/general/ExpansionPanel.js | 7 +- webapp/components/general/Filter.js | 1 - webapp/components/general/HTMLViewer.js | 14 +-- webapp/components/general/List.js | 115 +++++++++-------- .../components/general/NetPyNECoordsRange.js | 28 +++-- webapp/components/general/NetPyNEField.js | 15 ++- webapp/components/general/NetPyNEHome.js | 3 - webapp/components/general/NetPyNEIcons.js | 2 - webapp/components/general/NetPyNEThumbnail.js | 4 +- .../general/PythonControlledCapability.js | 12 +- webapp/components/general/RulePath.js | 7 +- webapp/components/general/Select.js | 6 +- webapp/components/general/Slider.js | 57 --------- webapp/components/general/Splash.js | 17 ++- webapp/package.json | 1 + webapp/redux/middleware/plotMiddleware.js | 118 +++++++++--------- .../middleware/rulesOperationsMiddleware.js | 26 ++-- webapp/redux/middleware/utils.js | 4 +- webapp/redux/reducers/drawer.js | 12 +- webapp/redux/reducers/notebook.js | 4 +- webapp/redux/reducers/topbar.js | 12 +- 24 files changed, 264 insertions(+), 255 deletions(-) delete mode 100644 webapp/components/general/Slider.js diff --git a/tests/frontend/e2e/.eslintrc.js b/tests/frontend/e2e/.eslintrc.js index 7e6f09b8..9310b33f 100644 --- a/tests/frontend/e2e/.eslintrc.js +++ b/tests/frontend/e2e/.eslintrc.js @@ -17,6 +17,6 @@ module.exports = { pvdr: true, net1: true, CanvasContainer: true, - patchRequire: true + patchRequire: true, } -}; \ No newline at end of file +}; diff --git a/webapp/.eslintrc.js b/webapp/.eslintrc.js index 1d15adc6..95cf8781 100644 --- a/webapp/.eslintrc.js +++ b/webapp/.eslintrc.js @@ -13,7 +13,7 @@ module.exports = { 'react/prop-types': 1, 'no-console': 0, 'import/extensions': 0, - 'max-len': ['error', { code: 140 }], + 'max-len': ['warn', { code: 140 }], 'no-eval': 1, eqeqeq: 1, 'no-plusplus': 1, @@ -21,6 +21,37 @@ module.exports = { 'no-param-reassign': 1, 'vars-on-top': 1, 'no-use-before-define': 1, + 'no-unused-vars': 1, + 'import/no-unresolved': 1, + 'import/named': 1, + 'react/jsx-props-no-spreading': 1, + 'no-nested-ternary': 1, + 'no-return-assign': 1, + 'react/no-array-index-key': 1, + 'react/sort-comp': 1, + 'consistent-return': 1, + 'import/prefer-default-export': 1, + 'react/no-unused-state': 1, + 'jsx-a11y/alt-text': 1, + 'no-restricted-syntax': 1, + 'no-underscore-dangle': 1, + 'no-restricted-globals': 1, + camelcase: 1, + 'max-classes-per-file': 1, + 'jsx-a11y/click-events-have-key-events': 1, + 'jsx-a11y/no-static-element-interactions': 1, + 'prefer-destructuring': 1, + 'no-redeclare': 1, + 'import/no-webpack-loader-syntax': 1, + 'global-require': 1, + 'default-case': 1, + 'react/prefer-stateless-function': 1, + 'block-scoped-var': 1, + 'no-var': 1, + 'no-shadow': 1, + 'react/no-did-update-set-state': 1, + 'react/no-string-refs': 1, + 'no-multi-assign': 1, }, globals: { page: true, @@ -33,10 +64,17 @@ module.exports = { CanvasContainer: true, patchRequire: true, window: true, - GEPPETTO: true, document: true, $: true, IPython: true, fetch: true, + Blob: true, + FormData: true, + Event: true, + jQuery: true, + define: true, + // geppetto + Instances: true, + GEPPETTO: true, }, }; diff --git a/webapp/components/general/Dialog.js b/webapp/components/general/Dialog.js index 3498c599..bb9c798c 100644 --- a/webapp/components/general/Dialog.js +++ b/webapp/components/general/Dialog.js @@ -11,8 +11,8 @@ import Link from '@material-ui/core/Link'; import Icon from '@material-ui/core/Icon'; import { withStyles } from '@material-ui/core/styles'; import { secondaryColor, bgLight } from '../../theme'; -import logo_netpyne from '../../static/netpyne-logo_white.png'; -import logo_metacell from '../../static/metacell_new.png'; +import logoNetpyne from '../../static/netpyne-logo_white.png'; +import logoMetaCell from '../../static/metacell_new.png'; const styles = (theme) => ({ paper: { @@ -23,7 +23,7 @@ const styles = (theme) => ({ const AboutContent = withStyles(styles)(({ classes }) => ( - + NetPyNE-UI v0.6.0 @@ -66,7 +66,7 @@ const AboutContent = withStyles(styles)(({ classes }) => ( width: 150, padding: '10px', }} - src={logo_metacell} + src={logoMetaCell} /> diff --git a/webapp/components/general/ExpansionPanel.js b/webapp/components/general/ExpansionPanel.js index f8cf2708..76b6807d 100644 --- a/webapp/components/general/ExpansionPanel.js +++ b/webapp/components/general/ExpansionPanel.js @@ -10,7 +10,10 @@ import Tooltip from './Tooltip'; const styles = ({ spacing }) => ({ button: { marginRight: 0 } }); class NetPyNEAccordion extends Component { - state = { expanded: false }; + constructor (props) { + super(props); + this.state = { expanded: false }; + } render () { const { @@ -24,7 +27,7 @@ class NetPyNEAccordion extends Component { this.setState({ expanded: !this.state.expanded }), + onClick: () => this.setState((prevState) => ({ expanded: !prevState.expanded })), className: classes.button, }} expandIcon={( diff --git a/webapp/components/general/Filter.js b/webapp/components/general/Filter.js index 8f0b1924..b9f046d0 100644 --- a/webapp/components/general/Filter.js +++ b/webapp/components/general/Filter.js @@ -31,7 +31,6 @@ class Filter extends Component { onClose={() => this.setState({ open: false })} onOpen={() => this.setState({ open: true })} className={classes.filter} - clearOnEscape autoComplete openOnFocus diff --git a/webapp/components/general/HTMLViewer.js b/webapp/components/general/HTMLViewer.js index c078e83f..63738554 100644 --- a/webapp/components/general/HTMLViewer.js +++ b/webapp/components/general/HTMLViewer.js @@ -27,17 +27,13 @@ class CustomHTMLViewer extends Component { this.resizeIfNeeded(); } - componentWillUnmount () { - clearTimeout(this.timer); - window.removeEventListener('resize', this.delayedResize); - } - componentDidUpdate () { this.resizeIfNeeded(); } - wasParentResized (dimensions) { - return dimensions.width !== this.dimensions.width || dimensions.height !== this.dimensions.height; + componentWillUnmount () { + clearTimeout(this.timer); + window.removeEventListener('resize', this.delayedResize); } getParentSize () { @@ -52,6 +48,10 @@ class CustomHTMLViewer extends Component { return this.containerRef.current.children[0].children[0].children[0]; } + wasParentResized (dimensions) { + return dimensions.width !== this.dimensions.width || dimensions.height !== this.dimensions.height; + } + adjustSVGSize () { const svg = this.getSvgComponent(); if (svg) { diff --git a/webapp/components/general/List.js b/webapp/components/general/List.js index 48af67ed..8cc08327 100644 --- a/webapp/components/general/List.js +++ b/webapp/components/general/List.js @@ -41,11 +41,12 @@ class ListComponent extends Component { break; case 'list(list(float))': var valid = true; - value.split(',').forEach((element) => { - if (!element.match(/^-?\d*(\.\d+)?$/)) { - valid = false; - } - }); + value.split(',') + .forEach((element) => { + if (!element.match(/^-?\d*(\.\d+)?$/)) { + valid = false; + } + }); if (value.endsWith(',')) { valid = false; } @@ -63,35 +64,36 @@ class ListComponent extends Component { valid = false; } else if ( (value.match(/{/g) || []).length != 1 - || (value.match(/}/g) || []).length != 1 + || (value.match(/}/g) || []).length != 1 ) { valid = false; } else if ( value.indexOf('{') > value.indexOf('}') - || !value.endsWith('}') + || !value.endsWith('}') ) { valid = false; } else { const subDict = value.match(/\{(.*?)\}/)[1]; if ( (subDict.match(/:/g) || []).length - 1 - != (subDict.match(/,/g) || []).length + != (subDict.match(/,/g) || []).length ) { valid = false; } else { - subDict.split(',').forEach((element) => { - if ( - (element.match(/:/g) || []).length != 1 - || element.startsWith(':') - || element.endsWith(':') - ) { - valid = false; - } - }); + subDict.split(',') + .forEach((element) => { + if ( + (element.match(/:/g) || []).length != 1 + || element.startsWith(':') + || element.endsWith(':') + ) { + valid = false; + } + }); const reminder = value.replace(`{${subDict}}`, ''); if ( (reminder.match(/:/g) || []).length != 1 - || !reminder.endsWith(':') + || !reminder.endsWith(':') ) { valid = false; } @@ -106,28 +108,33 @@ class ListComponent extends Component { } getErrorMessage () { - switch (this.props.realType) { + let message; + const { realType } = this.props; + switch (realType) { case 'list(float)': - var message = 'Only float numbers are allowed.'; + message = 'Only float numbers are allowed.'; break; case 'list(list(float))': - var message = 'Only comma separated float numbers are allowed.'; + message = 'Only comma separated float numbers are allowed.'; break; case 'dict': - var message = 'Key:Value pairs must be separated by colon : '; + message = 'Key:Value pairs must be separated by colon : '; break; case 'dict(dict)': - var message = 'Incorrect format. Example -> v_soma : { sec: soma, loc: 0.5, var: v}'; + message = 'Incorrect format. Example -> v_soma : { sec: soma, loc: 0.5, var: v}'; break; default: - var message = 'No a valid value'; + message = 'No a valid value'; break; } return message; } handleNewItemChange (event) { - this.setState({ newItemValue: event.target.value, newItemErrorText: '' }); + this.setState({ + newItemValue: event.target.value, + newItemErrorText: '', + }); } addChild () { @@ -190,7 +197,10 @@ class ListComponent extends Component { convertToPython (children) { // Update State - this.setState({ children, newItemValue: '' }); + this.setState({ + children, + newItemValue: '', + }); if (this.props.realType == 'dict' || this.props.realType == 'dict(dict)') { var newValue = children; @@ -247,32 +257,33 @@ class ListComponent extends Component { } render () { - const childrenWithExtraProp = Object.keys(this.state.children).map( - (key, index) => { - key = key.toString(); - if (this.props.realType == 'dict') { - var value = `${key} : ${JSON.stringify(this.state.children[key])}`; - } else if (this.props.realType == 'dict(dict)') { - var value = `${key - }: ${ - JSON.stringify(this.state.children[key]) - .replace(/["']/g, '') - .replace(/[:]/g, ': ') - .replace(/[,]/g, ', ')}`; - } else { - var value = this.state.children[key]; - } - return ( - this.removeChild(key)} - color="primary" - /> - ); - }, - ); + const childrenWithExtraProp = Object.keys(this.state.children) + .map( + (key, index) => { + key = key.toString(); + if (this.props.realType == 'dict') { + var value = `${key} : ${JSON.stringify(this.state.children[key])}`; + } else if (this.props.realType == 'dict(dict)') { + var value = `${key + }: ${ + JSON.stringify(this.state.children[key]) + .replace(/["']/g, '') + .replace(/[:]/g, ': ') + .replace(/[,]/g, ', ')}`; + } else { + var value = this.state.children[key]; + } + return ( + this.removeChild(key)} + color="primary" + /> + ); + }, + ); const { classes } = this.props; return ( diff --git a/webapp/components/general/NetPyNECoordsRange.js b/webapp/components/general/NetPyNECoordsRange.js index eacf42c4..d206efb8 100644 --- a/webapp/components/general/NetPyNECoordsRange.js +++ b/webapp/components/general/NetPyNECoordsRange.js @@ -22,6 +22,11 @@ export default class NetPyNECoordsRange extends Component { this.updateTimer = setTimeout(updateMethod, 1000); } + componentDidMount () { + this._isMounted = true; + this.updateLayout(); + } + componentDidUpdate (prevProps, prevState) { if (this.props.name != prevProps.name) { this.triggerUpdate(() => { @@ -43,20 +48,23 @@ export default class NetPyNECoordsRange extends Component { } } - componentDidMount () { - this._isMounted = true; - this.updateLayout(); - } - updateLayout () { - const message = `netpyne_geppetto.${this.props.model}['${this.props.name}']${(this.props.conds != undefined) ? `['${this.props.conds}']` : ''}`; + const { + items, + model, + conds, + name, + } = this.props; + + const message = `netpyne_geppetto.${model}['${name}']${(conds !== undefined) + ? `['${conds}']` : ''}`; Utils - .evalPythonMessage(`[key in ${message} for key in ['${this.props.items[0].value}', '${this.props.items[1].value}']]`) + .evalPythonMessage(`[key in ${message} for key in ['${items[0].value}', '${items[1].value}']]`) .then((response) => { if (response[0] && this._isMounted === true) { - this.setState({ rangeType: this.props.items[0].value }); + this.setState({ rangeType: items[0].value }); } else if (response[1] && this._isMounted === true) { - this.setState({ rangeType: this.props.items[1].value }); + this.setState({ rangeType: items[1].value }); } else if (this._isMounted === true) { this.setState({ rangeType: undefined }); } @@ -107,7 +115,7 @@ export default class NetPyNECoordsRange extends Component { convertToPython={(state) => { if (!state[state.lastUpdated].toString() .endsWith('.') - && ((!isNaN(parseFloat(state[min]))) && (!isNaN(parseFloat(state[max]))))) { + && ((!isNaN(parseFloat(state[min]))) && (!isNaN(parseFloat(state[max]))))) { return [parseFloat(state[min]), parseFloat(state[max])]; } }} diff --git a/webapp/components/general/NetPyNEField.js b/webapp/components/general/NetPyNEField.js index eb3bd89f..76a3ea0f 100644 --- a/webapp/components/general/NetPyNEField.js +++ b/webapp/components/general/NetPyNEField.js @@ -138,19 +138,18 @@ export default class NetPyNEField extends Component { extraProps.type = type; } - if (name == 'PythonControlledControl') { - var realType = Utils.getMetadataField(this.props.id, 'type'); + let realType; + if (name === 'PythonControlledControl') { + realType = Utils.getMetadataField(this.props.id, 'type'); extraProps.realType = realType; } - const hintText = Utils.getMetadataField(this.props.id, 'hintText'); - - let default_value = Utils.getMetadataField(this.props.id, 'default'); - if (default_value) { + let defaultValue = Utils.getMetadataField(this.props.id, 'default'); + if (defaultValue) { if (realType === 'dict' || realType === 'dict(dict)') { - default_value = JSON.parse(default_value); + defaultValue = JSON.parse(defaultValue); } - extraProps.default = default_value; + extraProps.default = defaultValue; } const options = Utils.getMetadataField(this.props.id, 'options'); diff --git a/webapp/components/general/NetPyNEHome.js b/webapp/components/general/NetPyNEHome.js index a3bc2426..8cc23873 100644 --- a/webapp/components/general/NetPyNEHome.js +++ b/webapp/components/general/NetPyNEHome.js @@ -1,5 +1,4 @@ import React from 'react'; -import Icon from '@material-ui/core/Icon'; import { makeStyles } from '@material-ui/core/styles'; import Tooltip from './Tooltip'; @@ -33,5 +32,3 @@ export default ({ handleClick, selection }) => { ); }; - -const styles = {}; diff --git a/webapp/components/general/NetPyNEIcons.js b/webapp/components/general/NetPyNEIcons.js index ef0433a2..36710a83 100644 --- a/webapp/components/general/NetPyNEIcons.js +++ b/webapp/components/general/NetPyNEIcons.js @@ -23,7 +23,6 @@ export function MechIcon (props) { - ); } @@ -32,6 +31,5 @@ export function ArrowRightIcon (props) { - ); } diff --git a/webapp/components/general/NetPyNEThumbnail.js b/webapp/components/general/NetPyNEThumbnail.js index eab82311..709d7964 100644 --- a/webapp/components/general/NetPyNEThumbnail.js +++ b/webapp/components/general/NetPyNEThumbnail.js @@ -50,7 +50,9 @@ export default class NetPyNEThumbnail extends React.Component { paramPath, paramName: name, }); - tonDelete && onDelete(); + if (onDelete) { + onDelete(); + } } this.setState({ dialogOpen: false }); } diff --git a/webapp/components/general/PythonControlledCapability.js b/webapp/components/general/PythonControlledCapability.js index 20f25c89..5ce8abc3 100644 --- a/webapp/components/general/PythonControlledCapability.js +++ b/webapp/components/general/PythonControlledCapability.js @@ -317,7 +317,11 @@ define((require) => { break; default: wrappedComponentProps.onChange = this.handleChange; - wrappedComponentProps.value = (typeof this.state.value === 'object' && this.state.value !== null && !Array.isArray(this.state.value)) ? JSON.stringify(this.state.value) : this.state.value; + wrappedComponentProps.value = (typeof this.state.value === 'object' + && this.state.value !== null + && !Array.isArray(this.state.value)) + ? JSON.stringify(this.state.value) + : this.state.value; // Fix case with multiple values: need to set an empty list in case the value is undefined wrappedComponentProps.value = (wrappedComponentProps.multiple && wrappedComponentProps.value !== undefined @@ -452,7 +456,9 @@ define((require) => { wrappedComponentProps.id = cleanAttributeValue(wrappedComponentProps.id); wrappedComponentProps.onChange = this.handleChange; - wrappedComponentProps.value = wrappedComponentProps.multiple && this.state.value !== undefined && !this.state.value ? [] : this.state.value; + wrappedComponentProps.value = wrappedComponentProps.multiple + && this.state.value !== undefined + && !this.state.value ? [] : this.state.value; delete wrappedComponentProps.model; delete wrappedComponentProps.postProcessItems; delete wrappedComponentProps.validate; @@ -486,5 +492,5 @@ function getNameFromWrappedComponent (WrappedComponent) { * Due to close integration with Python commands, characters []'". can be part of an id attribute. */ function cleanAttributeValue (value) { - return value.replace(/[\[\]'.]+/g, ''); + return value.replace(/[[\]'.]+/g, ''); } diff --git a/webapp/components/general/RulePath.js b/webapp/components/general/RulePath.js index 0c260c9c..faef9cc2 100644 --- a/webapp/components/general/RulePath.js +++ b/webapp/components/general/RulePath.js @@ -25,10 +25,13 @@ const styles = ({ }); class RulePath extends Component { - state = { open: false }; - textAreaRef = createRef(); + constructor (props) { + super(props); + this.state = { open: false }; + } + copyCodeToClipboard = () => { const el = this.textAreaRef.current; diff --git a/webapp/components/general/Select.js b/webapp/components/general/Select.js index 61ee8a74..170c738c 100644 --- a/webapp/components/general/Select.js +++ b/webapp/components/general/Select.js @@ -1,9 +1,9 @@ -import React, { Component } from 'react'; +import React from 'react'; import InputLabel from '@material-ui/core/InputLabel'; import FormControl from '@material-ui/core/FormControl'; import MuiSelect from '@material-ui/core/Select'; -export default class Select extends Component { +class Select extends React.Component { render () { let value = this.props.value || ''; if (this.props.multiple && value.constructor.name != 'Array') { @@ -30,3 +30,5 @@ export default class Select extends Component { ); } } + +export default Select; diff --git a/webapp/components/general/Slider.js b/webapp/components/general/Slider.js deleted file mode 100644 index a04909e9..00000000 --- a/webapp/components/general/Slider.js +++ /dev/null @@ -1,57 +0,0 @@ -import React, { Component } from 'react'; -import Slider from '@material-ui/core/Slider'; -import TextField from '@material-ui/core/TextField'; - -/** - * The slider bar can have a set minimum and maximum, and the value can be - * obtained through the value parameter fired on an onChange event. - */ -export default class NetPyNESlider extends Component { - constructor (props) { - super(props); - this.state = { value: 0.5 }; - } - - componentDidUpdate (prevProps, prevState) { - if (this.props.value != undefined && prevProps.value != this.props.value) { - this.setState({ value: this.props.value }); - } - } - - handleSlider = (event, value) => { - this.setState({ value }); - - this.props.onChange(event, null, value); - }; - - render () { - return ( -
-

- {this.props.label} -

- - - this.handleSlider(event, event.target.value)} - /> - -
- ); - } -} diff --git a/webapp/components/general/Splash.js b/webapp/components/general/Splash.js index 4e78356c..c18d8cd3 100644 --- a/webapp/components/general/Splash.js +++ b/webapp/components/general/Splash.js @@ -1,12 +1,9 @@ -import React, { Component } from 'react'; +import React from 'react'; import Box from '@material-ui/core/Box'; -export default class Splash extends Component { - render () { - return ( - - - - ); - } -} +const Splash = () => ( + + + +); +export default Splash; diff --git a/webapp/package.json b/webapp/package.json index 82cf8eb5..bb9d02e1 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -18,6 +18,7 @@ "@material-ui/core": "^4.11.4", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.51", + "jquery": "^3.6.0", "less-vars-to-js": "^1.3.0", "react": "^17.0.1", "react-dom": "^16.4.0", diff --git a/webapp/redux/middleware/plotMiddleware.js b/webapp/redux/middleware/plotMiddleware.js index 0c78fee2..8c861042 100644 --- a/webapp/redux/middleware/plotMiddleware.js +++ b/webapp/redux/middleware/plotMiddleware.js @@ -18,6 +18,64 @@ window.plotCache = {}; const isDisabled = (widget, plots) => !plots[widget.method.plotKey] ?? true; +const setPlotToWindow = (plotId, data) => { + if (data === '') { + console.log('No plot to show'); + return; + } + window.plotCache[plotId] = data; +}; + +const plotFigure = async (plotId, plotMethod, plotType = false, theme) => { + try { + let response = await Promise.race([ + Utils.evalPythonMessage(NETPYNE_COMMANDS.plotFigure, [plotMethod, plotType, theme], false), + new Promise((resolve, reject) => { + setTimeout(() => { + resolve(null); + }, 30000); + })]); + + console.log('Plot response received for', plotId); + if (!response) { + return null; + } + + // TODO Fix this, use just JSON + if (typeof response === 'string') { + if (response.startsWith('{') && response.endsWith('}')) { + if (processError(response, plotId)) { + console.error(processError(response, plotId)); + return null; + } + } + if (response.startsWith('[') && response.endsWith(']')) { + response = eval(response); + } + } + if (plotMethod.startsWith('iplot')) { + let htmlText = response.replace ? response.replace(/\\n/g, '') + .replace(/\\/g, '') : ''; + if (plotId === 'rxdConcentrationPlot') { + // FIXME: How can we center the bokeh plots when sizing_mode='scale_height' + htmlText = htmlText.replace('', ''); + } + return htmlText; + } + if (response?.length !== undefined) { + return response[0]; + } + if (response === -1) { + return null; + } + return response; + } catch (error) { + console.error(error); + } + + return null; +}; + export default (store) => (next) => (action) => { async function setWidget (widget) { const { @@ -46,7 +104,7 @@ export default (store) => (next) => (action) => { && widget.status === WidgetStatus.ACTIVE && !widget.initialized) { setWidget(widget) - .then((widget) => (widget ? next(action) : null)); + .then((w) => (w ? next(action) : null)); } next(action); break; @@ -97,7 +155,7 @@ export default (store) => (next) => (action) => { if (!store.getState().general.editMode) { for (const widget of Object.values(PLOT_WIDGETS)) { setWidget(widget) - .then((widget) => (widget ? next(addWidget(widget)) : null)); + .then((w) => (w ? next(addWidget(w)) : null)); } } break; @@ -107,59 +165,3 @@ export default (store) => (next) => (action) => { } } }; - -const plotFigure = async (plotId, plotMethod, plotType = false, theme) => { - try { - let response = await Promise.race([ - Utils.evalPythonMessage(NETPYNE_COMMANDS.plotFigure, [plotMethod, plotType, theme], false), - new Promise((resolve, reject) => { - setTimeout(() => { - resolve(null); - }, 30000); - })]); - - console.log('Plot response received for', plotId); - if (!response) { - return null; - } - - // TODO Fix this, use just JSON - if (typeof response === 'string') { - if (response.startsWith('{') && response.endsWith('}')) { - if (processError(response, plotId)) { - console.error(processError(response, plotId)); - return; - } - } - if (response.startsWith('[') && response.endsWith(']')) { - response = eval(response); - } - } - if (plotMethod.startsWith('iplot')) { - let htmlText = response.replace ? response.replace(/\\n/g, '') - .replace(/\\/g, '') : ''; - if (plotId === 'rxdConcentrationPlot') { - // FIXME: How can we center the bokeh plots when sizing_mode='scale_height' - htmlText = htmlText.replace('', ''); - } - return htmlText; - } - if (response?.length !== undefined) { - return response[0]; - } - if (response === -1) { - return null; - } - return response; - } catch (error) { - console.error(error); - } -}; - -const setPlotToWindow = (plotId, data) => { - if (data === '') { - console.log('No plot to show'); - return; - } - window.plotCache[plotId] = data; -}; diff --git a/webapp/redux/middleware/rulesOperationsMiddleware.js b/webapp/redux/middleware/rulesOperationsMiddleware.js index 7cdb9edc..455b8faa 100644 --- a/webapp/redux/middleware/rulesOperationsMiddleware.js +++ b/webapp/redux/middleware/rulesOperationsMiddleware.js @@ -2,6 +2,19 @@ import { DELETE_NETPARAMS_OBJ, updateCards } from '../actions/general'; import Utils from '../../Utils'; import { NETPYNE_COMMANDS } from '../../constants'; +function deleteNetPyNEObj (paramName, paramPath, next, action) { + Utils.evalPythonMessage(NETPYNE_COMMANDS.deleteParam, [paramPath, paramName]).then((response) => { + if (response) { + /* + * var model = this.state.value; + * delete model[name]; + * this.setState({ value: model, selectedPopulation: undefined, populationDeleted: name }, () => this.props.updateCards()); + */ + next(action); + } + }); +} + export default (store) => (next) => (action) => { switch (action.type) { case DELETE_NETPARAMS_OBJ: { @@ -17,16 +30,3 @@ export default (store) => (next) => (action) => { } } }; - -function deleteNetPyNEObj (paramName, paramPath, next, action) { - Utils.evalPythonMessage(NETPYNE_COMMANDS.deleteParam, [paramPath, paramName]).then((response) => { - if (response) { - /* - * var model = this.state.value; - * delete model[name]; - * this.setState({ value: model, selectedPopulation: undefined, populationDeleted: name }, () => this.props.updateCards()); - */ - next(action); - } - }); -} diff --git a/webapp/redux/middleware/utils.js b/webapp/redux/middleware/utils.js index 49fc6cb4..37a947e6 100644 --- a/webapp/redux/middleware/utils.js +++ b/webapp/redux/middleware/utils.js @@ -3,10 +3,10 @@ const createFileName = (name) => name + getTimeStamp(); const getTimeStamp = () => new Date().toGMTString().replace(',', '').replace(/[ ,:]/g, '_'); const unescapeText = (text) => { - text = text.replace(/\\\\/g, '\\').replace(/\\\'/g, "'").replace(/\\\"/g, '"').split('\\n') + const unescaped = text.replace(/\\\\/g, '\\').replace(/\\'/g, "'").replace(/\\"/g, '"').split('\\n') .join('\n') .substring(1); - return text.substring(0, text.length - 1); + return unescaped.substring(0, unescaped.length - 1); }; const forceBlobDownload = (blob, filename) => { diff --git a/webapp/redux/reducers/drawer.js b/webapp/redux/reducers/drawer.js index 2869817f..d50b5af1 100644 --- a/webapp/redux/reducers/drawer.js +++ b/webapp/redux/reducers/drawer.js @@ -4,12 +4,6 @@ import { OPEN_DRAWER_DIALOG_BOX, CLOSE_DRAWER_DIALOG_BOX } from '../actions/draw // Default state for general export const DRAWER_DEFAULT_STATE = { dialogBoxOpen: false }; -// reducer -export default (state = DRAWER_DEFAULT_STATE, action) => ({ - ...state, - ...reduceError(state, action), -}); - // reducer function function reduceError (state, action) { switch (action.type) { @@ -22,3 +16,9 @@ function reduceError (state, action) { } } } + +// reducer +export default (state = DRAWER_DEFAULT_STATE, action) => ({ + ...state, + ...reduceError(state, action), +}); diff --git a/webapp/redux/reducers/notebook.js b/webapp/redux/reducers/notebook.js index 8660cc17..b463523b 100644 --- a/webapp/redux/reducers/notebook.js +++ b/webapp/redux/reducers/notebook.js @@ -5,8 +5,6 @@ export const NOTEBOOK_DEFAULT_STATE = { isNotebookReady: false, }; -export default (state = {}, action) => ({ ...state, ...reduceNotebook(state, action) }); - function reduceNotebook (state = {}, action) { switch (action.type) { case TYPES.LOAD_NOTEBOOK: @@ -29,3 +27,5 @@ function reduceNotebook (state = {}, action) { return state; } } + +export default (state = {}, action) => ({ ...state, ...reduceNotebook(state, action) }); diff --git a/webapp/redux/reducers/topbar.js b/webapp/redux/reducers/topbar.js index 4dc78903..36e084eb 100644 --- a/webapp/redux/reducers/topbar.js +++ b/webapp/redux/reducers/topbar.js @@ -12,12 +12,6 @@ export const TOPBAR_DEFAULT_STATE = { }; // reducer -export default (state = { ...TOPBAR_DEFAULT_STATE }, action) => ({ - ...state, - ...reduceTopbar(state, action), -}); - -// reducer function function reduceTopbar (state, action) { switch (action.type) { case OPEN_TOPBAR_DIALOG: @@ -33,3 +27,9 @@ function reduceTopbar (state, action) { } } } + +export default (state = { ...TOPBAR_DEFAULT_STATE }, action) => ({ + ...state, + ...reduceTopbar(state, action), +}); +// reducer function From aff661758939e7c230b867d13bfc84b21e9255a3 Mon Sep 17 00:00:00 2001 From: Lucas Rebscher Date: Wed, 19 May 2021 10:52:22 +0200 Subject: [PATCH 05/43] Reduce eslint errors --- .../definition/cellRules/NetPyNECellRules.js | 1 + .../cellRules/SelectCellTemplate.js | 1 - .../cellRules/sections/NetPyNESection.js | 1 - .../connectivity/NetPyNEConnectivityRules.js | 2 +- .../definition/plots/NetPyNEInclude.js | 1 - .../definition/populations/Dimensions.js | 3 +- .../populations/NetPyNEPopulations.js | 2 +- .../NetPyNEStimulationTarget.js | 4 +- webapp/components/drawer/Drawer.js | 1 - webapp/components/index.js | 10 +++- .../instantiation/NetPyNEInstantiated.js | 44 +++++++-------- webapp/components/topbar/Topbar.js | 10 +++- .../components/topbar/dialogs/ActionDialog.js | 5 +- .../topbar/dialogs/ImportCellParams.js | 2 +- .../topbar/dialogs/ImportExportHLS.js | 4 +- webapp/components/topbar/dialogs/LoadFile.js | 6 +-- .../topbar/dialogs/UploadDownloadFiles.js | 54 ++++++++++++------- 17 files changed, 90 insertions(+), 61 deletions(-) diff --git a/webapp/components/definition/cellRules/NetPyNECellRules.js b/webapp/components/definition/cellRules/NetPyNECellRules.js index adc161a4..f1e2310b 100644 --- a/webapp/components/definition/cellRules/NetPyNECellRules.js +++ b/webapp/components/definition/cellRules/NetPyNECellRules.js @@ -804,6 +804,7 @@ export default class NetPyNECellRules extends React.Component { break; } default: { + break; } } return 'undefined'; diff --git a/webapp/components/definition/cellRules/SelectCellTemplate.js b/webapp/components/definition/cellRules/SelectCellTemplate.js index ff38d6cd..8b000a25 100644 --- a/webapp/components/definition/cellRules/SelectCellTemplate.js +++ b/webapp/components/definition/cellRules/SelectCellTemplate.js @@ -79,7 +79,6 @@ export default class NetPyNENewPlot extends React.Component { id="emptyCellTemplate" key="Empty" value="Empty" - onClick={() => this.handleSelection('Empty')} > Empty cell diff --git a/webapp/components/definition/cellRules/sections/NetPyNESection.js b/webapp/components/definition/cellRules/sections/NetPyNESection.js index 67f7dc2c..ce33e805 100644 --- a/webapp/components/definition/cellRules/sections/NetPyNESection.js +++ b/webapp/components/definition/cellRules/sections/NetPyNESection.js @@ -276,7 +276,6 @@ export default class NetPyNESection extends React.Component { showLabels style={{ borderRadius: '4px' }} value={this.state.selectedIndex} - showLabels > {bottomNavigationItems} diff --git a/webapp/components/definition/connectivity/NetPyNEConnectivityRules.js b/webapp/components/definition/connectivity/NetPyNEConnectivityRules.js index b1992425..a11db1fd 100644 --- a/webapp/components/definition/connectivity/NetPyNEConnectivityRules.js +++ b/webapp/components/definition/connectivity/NetPyNEConnectivityRules.js @@ -246,7 +246,7 @@ export default class NetPyNEConnectivityRules extends Component { /> )); - var selectedConnectivityRule = undefined; + var selectedConnectivityRule; if ( this.state.selectedConnectivityRule !== undefined && Object.keys(model) diff --git a/webapp/components/definition/plots/NetPyNEInclude.js b/webapp/components/definition/plots/NetPyNEInclude.js index 07d36fcf..3b84de23 100644 --- a/webapp/components/definition/plots/NetPyNEInclude.js +++ b/webapp/components/definition/plots/NetPyNEInclude.js @@ -330,7 +330,6 @@ export default class NetPyNEInclude extends Component { if (clone.groups.indexOf(name) > -1) { // when selecting individuals, remove population selection clone.groups.splice(clone.groups.indexOf(name), 1); } - } else { } clone.exclusive = false; if (clone.groups.indexOf('allCells') > -1 && name != 'allNetStims') { diff --git a/webapp/components/definition/populations/Dimensions.js b/webapp/components/definition/populations/Dimensions.js index 798f42ab..ee1b4611 100644 --- a/webapp/components/definition/populations/Dimensions.js +++ b/webapp/components/definition/populations/Dimensions.js @@ -74,8 +74,7 @@ class DimensionsComponent extends Component { updateLayout () { const requests = this.popDimensionsOptions.map((popDimensionsOption) => // FIXME Better to wrap calls rather than directly accessing objects - Utils - .evalPythonMessage(`'${popDimensionsOption.value}' in netpyne_geppetto.netParams.popParams['${this.state.modelName}']`)); + Utils.evalPythonMessage(`'${popDimensionsOption.value}' in netpyne_geppetto.netParams.popParams['${this.state.modelName}']`)); // Get population dimension by asking each for each key Promise.all(requests) diff --git a/webapp/components/definition/populations/NetPyNEPopulations.js b/webapp/components/definition/populations/NetPyNEPopulations.js index 07e4d08a..d89773a4 100644 --- a/webapp/components/definition/populations/NetPyNEPopulations.js +++ b/webapp/components/definition/populations/NetPyNEPopulations.js @@ -247,7 +247,7 @@ export default class NetPyNEPopulations extends React.Component { /> )); - var selectedPopulation = undefined; + var selectedPopulation; if ( this.state.selectedPopulation !== undefined && Object.keys(model) diff --git a/webapp/components/definition/stimulationTargets/NetPyNEStimulationTarget.js b/webapp/components/definition/stimulationTargets/NetPyNEStimulationTarget.js index 87558155..590a1828 100644 --- a/webapp/components/definition/stimulationTargets/NetPyNEStimulationTarget.js +++ b/webapp/components/definition/stimulationTargets/NetPyNEStimulationTarget.js @@ -57,7 +57,7 @@ export default class NetPyNEStimulationTarget extends React.Component { } async handleStimSourceSelection (selectedStimSourceName) { - return await Utils.evalPythonMessage( + return Utils.evalPythonMessage( `'NetStim' == netpyne_geppetto.netParams.stimSourceParams['${ selectedStimSourceName }']['type']`, @@ -147,7 +147,7 @@ export default class NetPyNEStimulationTarget extends React.Component { }; postProcessMenuItems = (pythonData, selectedStimSourceName) => { - if ((selectedStimSourceName != Object) & (selectedStimSourceName != '')) { + if ((selectedStimSourceName != Object) && (selectedStimSourceName != '')) { this.isStimSourceTypeNetStim(selectedStimSourceName); } return pythonData.map((name) => ( diff --git a/webapp/components/drawer/Drawer.js b/webapp/components/drawer/Drawer.js index c1969959..33b31d2e 100644 --- a/webapp/components/drawer/Drawer.js +++ b/webapp/components/drawer/Drawer.js @@ -37,7 +37,6 @@ const DrawerItem = ({ button key={id} dense - disableGutters disabled={disabled} className={widget ? classes.selected : classes.unselected} diff --git a/webapp/components/index.js b/webapp/components/index.js index f4efa798..6ab2bc24 100644 --- a/webapp/components/index.js +++ b/webapp/components/index.js @@ -123,7 +123,9 @@ export const NetPyNECellRule = connect( updates: state.general.updates, }), (dispatch) => ({ - openTopbarDialog: (cellTemplateName) => dispatch(openTopbarDialog(TOPBAR_CONSTANTS.IMPORT_CELL_TEMPLATE, { cellRuleName: cellTemplateName })), + openTopbarDialog: (cellTemplateName) => dispatch( + openTopbarDialog(TOPBAR_CONSTANTS.IMPORT_CELL_TEMPLATE, { cellRuleName: cellTemplateName }), + ), updateCards: () => dispatch(updateCards), }), )(_NetPyNECellRule); @@ -301,7 +303,11 @@ export const Dialog = connect( export const SelectCellTemplate = connect( null, - (dispatch) => ({ openTopbarDialog: (cellTemplateName) => dispatch(openTopbarDialog(TOPBAR_CONSTANTS.IMPORT_CELL_TEMPLATE, { cellRuleName: cellTemplateName })) }), + (dispatch) => ({ + openTopbarDialog: (cellTemplateName) => dispatch( + openTopbarDialog(TOPBAR_CONSTANTS.IMPORT_CELL_TEMPLATE, { cellRuleName: cellTemplateName }), + ), + }), )(_SelectCellTemplate); // ---------------------------------------------------------------------------------------- // diff --git a/webapp/components/instantiation/NetPyNEInstantiated.js b/webapp/components/instantiation/NetPyNEInstantiated.js index ed4b0dd4..a0e6adf8 100644 --- a/webapp/components/instantiation/NetPyNEInstantiated.js +++ b/webapp/components/instantiation/NetPyNEInstantiated.js @@ -28,6 +28,19 @@ export default class NetPyNEInstantiated extends React.Component { this.controlPanelToggle = this.controlPanelToggle.bind(this); } + componentDidMount () { + this.canvasRef.current.engine.setLinesThreshold(10000); + this.canvasRef.current.displayAllInstances(); + this.updateBtnsWithTheme('', this.state.canvasBtnCls); + window.addEventListener('resize', this.delayedResize.bind(this)); + this.resizeIfNeeded(); + this.updateInstances(); + + GEPPETTO.on(GEPPETTO.Events.Control_panel_close, () => { + this.setState({ bringItToFront: 0 }); + }); + } + componentDidUpdate (prevProps, prevState) { this.resizeIfNeeded(); const { theme } = this.props; @@ -43,25 +56,21 @@ export default class NetPyNEInstantiated extends React.Component { } } - componentDidMount () { - this.canvasRef.current.engine.setLinesThreshold(10000); - this.canvasRef.current.displayAllInstances(); - this.updateBtnsWithTheme('', this.state.canvasBtnCls); - window.addEventListener('resize', this.delayedResize.bind(this)); - this.resizeIfNeeded(); - this.updateInstances(); - - GEPPETTO.on(GEPPETTO.Events.Control_panel_close, () => { - this.setState({ bringItToFront: 0 }); - }); - } - componentWillUnmount () { GEPPETTO.off(GEPPETTO.Events.Control_panel_close); clearTimeout(this.timer); window.removeEventListener('resize', this.delayedResize); } + updateBtnsWithTheme = (removeClass, addClass) => { + const element = document.getElementById('CanvasContainer_component'); + if (removeClass) { + element.classList.remove(removeClass); + } + element.classList.add(addClass); + this.setState({ canvasBtnCls: addClass }); + }; + updateInstances () { if (Instances.network) { // update canvas only if there are instances to show @@ -82,7 +91,7 @@ export default class NetPyNEInstantiated extends React.Component { } resizeCanvas () { - this.setState({ update: this.state.update++ }); + this.setState((prevState) => ({ update: prevState.update + 1 })); } resizeIfNeeded () { @@ -109,13 +118,6 @@ export default class NetPyNEInstantiated extends React.Component { return node.parentNode.getBoundingClientRect(); } - updateBtnsWithTheme = (removeClass, addClass) => { - const element = document.getElementById('CanvasContainer_component'); - removeClass && element.classList.remove(removeClass); - element.classList.add(addClass); - this.setState({ canvasBtnCls: addClass }); - }; - controlPanelToggle () { if (!this.state.controlPanelInitialized) { this.setState({ controlPanelInitialized: true }); diff --git a/webapp/components/topbar/Topbar.js b/webapp/components/topbar/Topbar.js index 0dbe5433..7d42da0c 100644 --- a/webapp/components/topbar/Topbar.js +++ b/webapp/components/topbar/Topbar.js @@ -32,10 +32,13 @@ const styles = () => ({ }); class Topbar extends Component { - state = { openSnackBar: false }; - snackBarMessage = ''; + constructor (props) { + super(props); + this.state = { openSnackBar: false }; + } + menuHandler (click) { if (!click) { return; @@ -172,6 +175,9 @@ class Topbar extends Component { /> ); break; + default: + content =
; + break; } } diff --git a/webapp/components/topbar/dialogs/ActionDialog.js b/webapp/components/topbar/dialogs/ActionDialog.js index a1e635ca..8e1969b7 100644 --- a/webapp/components/topbar/dialogs/ActionDialog.js +++ b/webapp/components/topbar/dialogs/ActionDialog.js @@ -17,7 +17,10 @@ const styles = () => ({ }); class ActionDialog extends React.Component { - state = { hide: !this.props.openErrorDialogBox && !this.props.openDialog }; + constructor (props) { + super(props); + this.state = { hide: !this.props.openErrorDialogBox && !this.props.openDialog }; + } performAction = () => { if (this.props.command) { diff --git a/webapp/components/topbar/dialogs/ImportCellParams.js b/webapp/components/topbar/dialogs/ImportCellParams.js index b8c79e6d..5d7ae803 100644 --- a/webapp/components/topbar/dialogs/ImportCellParams.js +++ b/webapp/components/topbar/dialogs/ImportCellParams.js @@ -75,7 +75,7 @@ class ImportCellParams extends React.Component { newState.modFolder = fieldValue.path; break; default: - throw ('Not a valid parameter!'); + throw Error('Not a valid parameter!'); } } this.setState(newState); diff --git a/webapp/components/topbar/dialogs/ImportExportHLS.js b/webapp/components/topbar/dialogs/ImportExportHLS.js index 8afd9c3a..533ebfa9 100644 --- a/webapp/components/topbar/dialogs/ImportExportHLS.js +++ b/webapp/components/topbar/dialogs/ImportExportHLS.js @@ -120,14 +120,14 @@ class ImportExportHLS extends React.Component { newState.loadMod = true; break; default: - throw ('Not a valid parameter!'); + throw Error('Not a valid parameter!'); } } this.setState({ ...newState }); } getDirAndModuleFromPath (fullpath) { - const fileName = fullpath.replace(/^.*[\\\/]/, ''); + const fileName = fullpath.replace(/^.*[\\/]/, ''); const moduleName = fileName.replace(/\.[^/.]+$/, ''); const dirPath = fullpath.split(fileName) .slice(0, -1) diff --git a/webapp/components/topbar/dialogs/LoadFile.js b/webapp/components/topbar/dialogs/LoadFile.js index af100ece..483a091c 100644 --- a/webapp/components/topbar/dialogs/LoadFile.js +++ b/webapp/components/topbar/dialogs/LoadFile.js @@ -74,7 +74,7 @@ class LoadFile extends React.Component { closeExplorerDialog (fieldValue) { const newState = { explorerDialogOpen: false }; if (fieldValue) { - const fileName = fieldValue.path.replace(/^.*[\\\/]/, ''); + const fileName = fieldValue.path.replace(/^.*[\\/]/, ''); const path = fieldValue.path .split(fileName) .slice(0, -1) @@ -89,7 +89,7 @@ class LoadFile extends React.Component { newState.jsonPath = path; break; default: - throw 'Not a valid parameter!'; + throw Error('Not a valid parameter!'); } } this.setState(newState); @@ -211,7 +211,7 @@ class LoadFile extends React.Component { noBackground label="Compile mod files" checked={this.state.compileMod} - onChange={() => this.setState({ compileMod: !this.state.compileMod })} + onChange={() => this.setState((prevState) => ({ compileMod: !prevState.compileMod }))} /> diff --git a/webapp/components/topbar/dialogs/UploadDownloadFiles.js b/webapp/components/topbar/dialogs/UploadDownloadFiles.js index 80d0eef2..79d190c7 100644 --- a/webapp/components/topbar/dialogs/UploadDownloadFiles.js +++ b/webapp/components/topbar/dialogs/UploadDownloadFiles.js @@ -57,6 +57,13 @@ class UploadDownloadFile extends React.Component { this.message = ''; } + onUploadFileArrayChange = (event) => { + const { files } = event.target; + if (this.maxSelectFile(files) && this.checkMimeType(files) && this.checkFileSize(files)) { + this.setState({ uploadFiles: files }); + } + }; + initialState () { return { open: true, @@ -185,13 +192,6 @@ class UploadDownloadFile extends React.Component { return true; } - onUploadFileArrayChange = (event) => { - const { files } = event.target; - if (this.maxSelectFile(files) && this.checkMimeType(files) && this.checkFileSize(files)) { - this.setState({ uploadFiles: files }); - } - }; - closeExplorerDialog (selectedNodes) { const state = { explorerDialogOpen: false }; if (selectedNodes) { @@ -221,12 +221,24 @@ class UploadDownloadFile extends React.Component { } render () { + let buttonLabel; + let title; + let content; const { classes } = this.props; const { mode } = this.props; + const { + open, + explorerDialogOpen, + uploadFiles: uploadFiles1, + downloadPathsDisplayText, + downloadPaths, + filterFiles, + } = this.state; + switch (mode) { case 'UPLOAD': - var content = ( + content = (
@@ -243,16 +255,15 @@ class UploadDownloadFile extends React.Component {
); - var buttonLabel = 'Upload'; - var title = 'Upload files'; + buttonLabel = 'Upload'; + title = 'Upload files'; break; case 'DOWNLOAD': - var content = ( - + content = ( this.changeDownloadFilePathsDisplayText(event.target.value)} label="Files:" helperText="Select files to download" @@ -272,8 +283,11 @@ class UploadDownloadFile extends React.Component { /> ); - var buttonLabel = 'DOWNLOAD'; - var title = 'Download files'; + buttonLabel = 'DOWNLOAD'; + title = 'Download files'; + break; + + default: break; } @@ -282,7 +296,7 @@ class UploadDownloadFile extends React.Component { this.closeDialog()} > {title} @@ -294,7 +308,9 @@ class UploadDownloadFile extends React.Component { this.closeExplorerDialog(multiSelection)} /> From 505afd6db087de3d68fb02a5381b35c1b1fcbd50 Mon Sep 17 00:00:00 2001 From: Lucas Rebscher Date: Wed, 19 May 2021 11:05:57 +0200 Subject: [PATCH 06/43] Reduce eslint errors --- webapp/.eslintrc.js | 4 ++++ .../definition/cellRules/NetPyNECellRules.js | 3 +++ .../connectivity/NetPyNEConnectivityRules.js | 3 ++- .../definition/plots/NetPyNEInclude.js | 24 ++++++++++--------- .../definition/populations/Dimensions.js | 1 + .../populations/NetPyNEPopulations.js | 3 ++- .../NetPyNEStimulationSources.js | 1 + .../NetPyNEStimulationTargets.js | 1 + .../definition/synapses/NetPyNESynapses.js | 1 + webapp/components/general/Filter.js | 5 +++- .../instantiation/NetPyNEInstantiated.js | 1 + webapp/components/topbar/SwitchPageButton.js | 7 +++++- webapp/components/topbar/Topbar.js | 3 ++- 13 files changed, 41 insertions(+), 16 deletions(-) diff --git a/webapp/.eslintrc.js b/webapp/.eslintrc.js index 95cf8781..e8a4ea8d 100644 --- a/webapp/.eslintrc.js +++ b/webapp/.eslintrc.js @@ -52,6 +52,10 @@ module.exports = { 'react/no-did-update-set-state': 1, 'react/no-string-refs': 1, 'no-multi-assign': 1, + 'guard-for-in': 1, + 'no-unused-expressions': 1, + 'no-control-regex': 1, + 'no-loop-func': 1, }, globals: { page: true, diff --git a/webapp/components/definition/cellRules/NetPyNECellRules.js b/webapp/components/definition/cellRules/NetPyNECellRules.js index f1e2310b..52f9549b 100644 --- a/webapp/components/definition/cellRules/NetPyNECellRules.js +++ b/webapp/components/definition/cellRules/NetPyNECellRules.js @@ -86,6 +86,7 @@ export default class NetPyNECellRules extends React.Component { handleNewCellRule (defaultCellRules) { const key = Object.keys(defaultCellRules)[0]; const value = defaultCellRules[key]; + // eslint-disable-next-line react/no-access-state-in-setstate const model = { ...this.state.value }; // Get New Available ID @@ -608,6 +609,7 @@ export default class NetPyNECellRules extends React.Component { name, ]) .then((response) => { + // eslint-disable-next-line react/no-access-state-in-setstate const model = this.state.value; delete model[this.state.selectedCellRule].secs[ this.state.selectedSection @@ -627,6 +629,7 @@ export default class NetPyNECellRules extends React.Component { name, ]) .then((response) => { + // eslint-disable-next-line react/no-access-state-in-setstate const model = this.state.value; delete model[this.state.selectedCellRule].secs[name]; this.setState({ diff --git a/webapp/components/definition/connectivity/NetPyNEConnectivityRules.js b/webapp/components/definition/connectivity/NetPyNEConnectivityRules.js index a11db1fd..34716a26 100644 --- a/webapp/components/definition/connectivity/NetPyNEConnectivityRules.js +++ b/webapp/components/definition/connectivity/NetPyNEConnectivityRules.js @@ -34,7 +34,7 @@ export default class NetPyNEConnectivityRules extends Component { this.handleRenameChildren = this.handleRenameChildren.bind(this); } - handleToggle = () => this.setState({ drawerOpen: !this.state.drawerOpen }); + handleToggle = () => this.setState((prevState) => ({ drawerOpen: !prevState.drawerOpen })); selectPage (page) { this.setState({ page }); @@ -55,6 +55,7 @@ export default class NetPyNEConnectivityRules extends Component { // Get Key and Value const key = Object.keys(defaultConnectivityRules)[0]; const value = defaultConnectivityRules[key]; + // eslint-disable-next-line react/no-access-state-in-setstate const model = { ...this.state.value }; // Get New Available ID diff --git a/webapp/components/definition/plots/NetPyNEInclude.js b/webapp/components/definition/plots/NetPyNEInclude.js index 3b84de23..fbf7b8c6 100644 --- a/webapp/components/definition/plots/NetPyNEInclude.js +++ b/webapp/components/definition/plots/NetPyNEInclude.js @@ -67,11 +67,12 @@ export default class NetPyNEInclude extends Component { let answer = ''; if (include.exclusive) { return `${include.exclusive} -- ${data.gids} cells -- all NetStims`; - } if (include.groups.indexOf('allCells') > -1) { + } + if (include.groups.indexOf('allCells') > -1) { if (include.groups.indexOf('allNetStims') == -1) { return `allCells -- ${data.gids} cells`; } - return `${'all' + ' -- '}${data.gids} cells -- all NetStims`; + return `all -- ${data.gids} cells -- all NetStims`; } include.groups.forEach((group) => { if (group != 'allNetStims') { @@ -171,15 +172,15 @@ export default class NetPyNEInclude extends Component { }); if ((open || this.state.mainPopoverOpen) && !(open && this.state.mainPopoverOpen)) { - this.setState({ + this.setState((prevState) => ({ mainPopoverOpen: open, secondPopoverOpen: clone, - anchorEl: target || this.state.anchorEl, - }); + anchorEl: target || prevState.anchorEl, + })); } if (!open) { this.sendToPython(); - this.setState({ label: this.whoIsIncluded(this.state.include, this.state.data) }); + this.setState((prevState) => ({ label: this.whoIsIncluded(prevState.include, prevState.data) })); } }; @@ -195,11 +196,10 @@ export default class NetPyNEInclude extends Component { }); if (!this.checkEqual(clone, this.state.secondPopoverOpen)) { - this.setState({ + this.setState((prevState) => ({ secondPopoverOpen: clone, - anchorEl2: target || this.state.anchorEl, - }); - } else { + anchorEl2: target || prevState.anchorEl, + })); } }; @@ -318,6 +318,7 @@ export default class NetPyNEInclude extends Component { }; handleSecondaryMenusClick = (group, name, item) => { + // eslint-disable-next-line react/no-access-state-in-setstate const clone = { ...this.state.include }; if (group == 'gids') { clone[group].indexOf(item) == -1 ? clone[group].push(item) : clone[group].splice(clone[group].indexOf(item), 1); @@ -341,7 +342,8 @@ export default class NetPyNEInclude extends Component { IsSecondaryMenuChecked = (group, name, index) => { if (group == 'gids') { return this.state.include[group].indexOf(index) > -1; - } if (group == 'popids') { + } + if (group == 'popids') { if (name in this.state.include[group]) { return this.state.include[group][name].indexOf(index) > -1; } diff --git a/webapp/components/definition/populations/Dimensions.js b/webapp/components/definition/populations/Dimensions.js index ee1b4611..8ad00df6 100644 --- a/webapp/components/definition/populations/Dimensions.js +++ b/webapp/components/definition/populations/Dimensions.js @@ -74,6 +74,7 @@ class DimensionsComponent extends Component { updateLayout () { const requests = this.popDimensionsOptions.map((popDimensionsOption) => // FIXME Better to wrap calls rather than directly accessing objects + // eslint-disable-next-line implicit-arrow-linebreak Utils.evalPythonMessage(`'${popDimensionsOption.value}' in netpyne_geppetto.netParams.popParams['${this.state.modelName}']`)); // Get population dimension by asking each for each key diff --git a/webapp/components/definition/populations/NetPyNEPopulations.js b/webapp/components/definition/populations/NetPyNEPopulations.js index d89773a4..14a65022 100644 --- a/webapp/components/definition/populations/NetPyNEPopulations.js +++ b/webapp/components/definition/populations/NetPyNEPopulations.js @@ -33,7 +33,7 @@ export default class NetPyNEPopulations extends React.Component { this.handleRenameChildren = this.handleRenameChildren.bind(this); } - handleToggle = () => this.setState({ drawerOpen: !this.state.drawerOpen }); + handleToggle = () => this.setState((prevState) => ({ drawerOpen: !prevState.drawerOpen })); hasSelectedPopulationBeenRenamed (prevState, currentState) { const currentModel = prevState.value; @@ -145,6 +145,7 @@ export default class NetPyNEPopulations extends React.Component { // Get Key and Value const key = Object.keys(defaultPopulationValues)[0]; const value = defaultPopulationValues[key]; + // eslint-disable-next-line react/no-access-state-in-setstate const model = { ...this.state.value }; // Get New Available ID diff --git a/webapp/components/definition/stimulationSources/NetPyNEStimulationSources.js b/webapp/components/definition/stimulationSources/NetPyNEStimulationSources.js index bb277db8..4ee95d64 100644 --- a/webapp/components/definition/stimulationSources/NetPyNEStimulationSources.js +++ b/webapp/components/definition/stimulationSources/NetPyNEStimulationSources.js @@ -45,6 +45,7 @@ export default class NetPyNEStimulationSources extends Component { const defaultStimulationSources = { stim_source: { type: 'NetStim' } }; const key = Object.keys(defaultStimulationSources)[0]; const value = defaultStimulationSources[key]; + // eslint-disable-next-line react/no-access-state-in-setstate const model = { ...this.state.value }; const StimulationSourceId = Utils.getAvailableKey(model, key); const newStimulationSource = { diff --git a/webapp/components/definition/stimulationTargets/NetPyNEStimulationTargets.js b/webapp/components/definition/stimulationTargets/NetPyNEStimulationTargets.js index 27a1d5a7..5a7131cb 100644 --- a/webapp/components/definition/stimulationTargets/NetPyNEStimulationTargets.js +++ b/webapp/components/definition/stimulationTargets/NetPyNEStimulationTargets.js @@ -50,6 +50,7 @@ export default class NetPyNEStimulationTargets extends Component { }; const key = Object.keys(defaultStimulationTargets)[0]; const value = defaultStimulationTargets[key]; + // eslint-disable-next-line react/no-access-state-in-setstate const model = { ...this.state.value }; const StimulationTargetId = Utils.getAvailableKey(model, key); const newStimulationTarget = { diff --git a/webapp/components/definition/synapses/NetPyNESynapses.js b/webapp/components/definition/synapses/NetPyNESynapses.js index aedee597..5a726cff 100644 --- a/webapp/components/definition/synapses/NetPyNESynapses.js +++ b/webapp/components/definition/synapses/NetPyNESynapses.js @@ -43,6 +43,7 @@ export default class NetPyNESynapses extends Component { const defaultSynapses = { Synapse: { mod: 'Exp2Syn' } }; const key = Object.keys(defaultSynapses)[0]; const value = defaultSynapses[key]; + // eslint-disable-next-line react/no-access-state-in-setstate const model = { ...this.state.value }; const SynapseId = Utils.getAvailableKey(model, key); const newSynapse = { name: SynapseId, ...value }; diff --git a/webapp/components/general/Filter.js b/webapp/components/general/Filter.js index b9f046d0..f407a421 100644 --- a/webapp/components/general/Filter.js +++ b/webapp/components/general/Filter.js @@ -18,7 +18,10 @@ const styles = ({ spacing, shape }) => ({ listbox: { color: 'white', maxHeight: '20vh' }, }); class Filter extends Component { - state = { open: false } + constructor (props) { + super(props); + this.state = { open: false }; + } render () { const { diff --git a/webapp/components/instantiation/NetPyNEInstantiated.js b/webapp/components/instantiation/NetPyNEInstantiated.js index a0e6adf8..1be0a4c5 100644 --- a/webapp/components/instantiation/NetPyNEInstantiated.js +++ b/webapp/components/instantiation/NetPyNEInstantiated.js @@ -114,6 +114,7 @@ export default class NetPyNEInstantiated extends React.Component { if (this.canvasRef.current === null) { return false; } + // eslint-disable-next-line react/no-find-dom-node const node = ReactDOM.findDOMNode(this); return node.parentNode.getBoundingClientRect(); } diff --git a/webapp/components/topbar/SwitchPageButton.js b/webapp/components/topbar/SwitchPageButton.js index 78657cb6..46a54945 100644 --- a/webapp/components/topbar/SwitchPageButton.js +++ b/webapp/components/topbar/SwitchPageButton.js @@ -25,6 +25,11 @@ const styles = ({ }); class SwitchPageButton extends Component { + constructor (props) { + super(props); + this.handleClick = this.handleClick.bind(this); + } + handleClick = (event) => { const instantiate = this.props.automaticInstantiation || this.props.modelState === MODEL_STATE.NOT_INSTANTIATED; if (!this.props.editModelPage) { @@ -95,7 +100,7 @@ class SwitchPageButton extends Component { variant="contained" size="small" className={classes.button} - onClick={this.handleClick.bind(this)} + onClick={this.handleClick} endIcon={} > {editModelPage ? this.getExploreLabel() : TOPBAR_CONSTANTS.BACK_TO_EDITION} diff --git a/webapp/components/topbar/Topbar.js b/webapp/components/topbar/Topbar.js index 7d42da0c..b6549aea 100644 --- a/webapp/components/topbar/Topbar.js +++ b/webapp/components/topbar/Topbar.js @@ -37,6 +37,7 @@ class Topbar extends Component { constructor (props) { super(props); this.state = { openSnackBar: false }; + this.menuHandler = this.menuHandler.bind(this); } menuHandler (click) { @@ -186,7 +187,7 @@ class Topbar extends Component {
From a512ed9fceecf0d2c3a609e9afcab0f531e1b521 Mon Sep 17 00:00:00 2001 From: Lucas Rebscher Date: Wed, 19 May 2021 15:42:02 +0200 Subject: [PATCH 07/43] #263 Remove obsolete clearSim method --- netpyne_ui/netpyne_geppetto.py | 52 ++-------------------------------- 1 file changed, 2 insertions(+), 50 deletions(-) diff --git a/netpyne_ui/netpyne_geppetto.py b/netpyne_ui/netpyne_geppetto.py index bd0a6a64..30aefbd0 100644 --- a/netpyne_ui/netpyne_geppetto.py +++ b/netpyne_ui/netpyne_geppetto.py @@ -16,7 +16,6 @@ from netpyne.metadata import metadata from netpyne_ui.netpyne_model_interpreter import NetPyNEModelInterpreter from pygeppetto.model.model_serializer import GeppettoModelSerializer -import matplotlib.pyplot as plt from pygeppetto import ui import numpy as np import neuron @@ -329,12 +328,9 @@ def deleteModel(self, modelParams): return utils.getJSONError("Error while exporting the NetPyNE model", sys.exc_info()) try: - # This function fails is some keys don't exists - # sim.clearAll() - # TODO: as part of #264 we should remove the method and use clearAll intstead - self.clearSim() + sim.clearAll() except: - pass + logging.exception("Failed to clear simulation") return utils.getJSONReply() @@ -740,50 +736,6 @@ def propagate_syn_mech_rename(self, new, old): else: self.netParams.stimTargetParams[label]['synMech'] = new - def clearSim(self): - # clean up - sim.pc.barrier() - sim.pc.gid_clear() # clear previous gid settings - - # clean cells and simData in all nodes - sim.clearObj([cell.__dict__ if hasattr(cell, '__dict__') else cell for cell in sim.net.cells]) - if 'stims' in list(sim.simData.keys()): - sim.clearObj([stim for stim in sim.simData['stims']]) - - for key in list(sim.simData.keys()): del sim.simData[key] - - if hasattr(sim, 'net'): - for c in sim.net.cells: del c - for p in sim.net.pops: del p - if hasattr(sim.net, 'params'): - del sim.net.params - - # clean cells and simData gathered in master node - if sim.rank == 0: - if hasattr(sim.net, 'allCells'): - sim.clearObj([cell.__dict__ if hasattr(cell, '__dict__') else cell for cell in sim.net.allCells]) - if hasattr(sim, 'allSimData'): - if 'stims' in list(sim.allSimData.keys()): - sim.clearObj([stim for stim in sim.allSimData['stims']]) - for key in list(sim.allSimData.keys()): del sim.allSimData[key] - del sim.allSimData - - import matplotlib - matplotlib.pyplot.clf() - matplotlib.pyplot.close('all') - - if hasattr(sim, 'net'): - if hasattr(sim.net, 'allCells'): - for c in sim.net.allCells: del c - del sim.net.allCells - if hasattr(sim.net, 'allPops'): - for p in sim.net.allPops: del p - - del sim.net - - import gc; - gc.collect() - def create_celltype_from_template(self, label="CellType", conds={}, cell_template_name="Blank"): try: with redirect_stdout(sys.__stdout__): From 2dad8e4a4ec0ee71d9cf6e4f5c4e76348bc0b717 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Fri, 18 Jun 2021 15:50:25 +0200 Subject: [PATCH 08/43] workspace installaztion made optional --- utilities/install.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/utilities/install.py b/utilities/install.py index 8075fb79..13722104 100644 --- a/utilities/install.py +++ b/utilities/install.py @@ -75,6 +75,7 @@ def compile_mod(): def main(netpyne_branch, workspace_branch, pygeppetto_branch=None, jupyter_geppetto_branch=None, skipNpm=False, skipTest=False, development=False): cprint("Installing requirements") + print(workspace_branch) execute(cmd=['pip', 'install', '-r', 'requirements.txt'], cwd=ROOT_DIR) if not os.path.exists(DEPS_DIR): @@ -112,10 +113,11 @@ def main(netpyne_branch, workspace_branch, pygeppetto_branch=None, jupyter_geppe execute(cmd=['pip', 'install', '-e', '.', '--no-deps'], cwd=ROOT_DIR) os.chdir(ROOT_DIR) - cprint("Cloning workspace") - clone(repository=WORKSPACE, branch_or_tag=workspace_branch, folder=WORKSPACE_DIR, cwdp=ROOT_DIR) - cprint("Compiling workspace modules") - compile_mod() + if workspace_branch: + cprint("Cloning workspace") + clone(repository=WORKSPACE, branch_or_tag=workspace_branch, folder=WORKSPACE_DIR, cwdp=ROOT_DIR) + cprint("Compiling workspace modules") + compile_mod() if not skipNpm and os.path.exists(os.path.join(DEPS_DIR, JUPYTER_DIR)): cprint("Building Jupyter Geppetto extension...") From de432fb45297bfc6edebd8ad136bedf6d8c34b23 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Fri, 18 Jun 2021 15:51:02 +0200 Subject: [PATCH 09/43] Delete workspace folder --- workspace | 1 - 1 file changed, 1 deletion(-) delete mode 160000 workspace diff --git a/workspace b/workspace deleted file mode 160000 index f1d5dac9..00000000 --- a/workspace +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f1d5dac95ab6c4a2868f072490b239bb1842d789 From a8d0e9ca2089b9a025f9a19e2c73819fe739e8d8 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Fri, 18 Jun 2021 16:42:12 +0200 Subject: [PATCH 10/43] Small import fix --- netpyne_ui/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netpyne_ui/api.py b/netpyne_ui/api.py index b612c192..41a6a5b9 100644 --- a/netpyne_ui/api.py +++ b/netpyne_ui/api.py @@ -8,7 +8,7 @@ from tempfile import TemporaryDirectory from jupyter_geppetto.webapi import get, post from notebook.base.handlers import IPythonHandler -from netpyne_ui.constants import NETPYNE_WORKDIR, UPLOAD_FOLDER_NAME, ALLOWED_EXTENSIONS, UPLOAD_FOLDER_PATH +from netpyne_ui.constants import ALLOWED_EXTENSIONS, UPLOAD_FOLDER_PATH def allowed_file(filename, allowed_extensions=ALLOWED_EXTENSIONS): From 98d7e81107ada16a516146903209c897ab0c9f53 Mon Sep 17 00:00:00 2001 From: Lucas Rebscher Date: Mon, 21 Jun 2021 10:05:18 +0200 Subject: [PATCH 11/43] #328 Remove workspace folder & improve install.py --- .gitignore | 3 ++- utilities/install.py | 17 +++++++++++++---- workspace | 1 - 3 files changed, 15 insertions(+), 6 deletions(-) delete mode 160000 workspace diff --git a/.gitignore b/.gitignore index 8e8498bb..e3d873d8 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,5 @@ utilities/x86_64 .idea *.iml x86_64 -.jupyter-config \ No newline at end of file +.jupyter-config +venv \ No newline at end of file diff --git a/utilities/install.py b/utilities/install.py index 8075fb79..8f9d5870 100644 --- a/utilities/install.py +++ b/utilities/install.py @@ -34,7 +34,7 @@ def cprint(string): def execute(cmd, cwd='.', *args, **kwargs): exit_code = subprocess.call(cmd, cwd=cwd, *args, **kwargs) if exit_code != 0: - raise SystemExit('Error installing NetPyNE-UI') + raise SystemExit(f'Error installing NetPyNE-UI - Command {cmd} failed with code {exit_code} in directory {cwd}') # by default clones branch (which can be passed as a parameter python install.py branch test_branch) @@ -46,13 +46,22 @@ def clone(repository, folder=None, branch_or_tag=None, cwdp=DEPS_DIR, recursive= if folder and os.path.exists(os.path.join(cwdp, folder)): print(f'Skipping clone of {repository}: folder exists') else: + exit_code = 0 if recursive: - subprocess.call(['git', 'clone', '--recursive', repository], cwd=cwdp) + exit_code = subprocess.call(['git', 'clone', '--recursive', repository], cwd=cwdp) else: if folder: - subprocess.call(['git', 'clone', repository, folder], cwd=cwdp) + exit_code = subprocess.call(['git', 'clone', repository, folder], cwd=cwdp) else: - subprocess.call(['git', 'clone', repository], cwd=cwdp) + exit_code = subprocess.call(['git', 'clone', repository], cwd=cwdp) + + if exit_code != 0: + raise SystemExit(f'Failed to clone repository {repository} into {folder}') + + if not os.path.exists(os.path.join(cwdp, folder, '.git')): + print(f'Skipping checkout of {repository}: folder is not a git repository') + return + if branch_or_tag: checkout(folder, branch_or_tag, cwdp) diff --git a/workspace b/workspace deleted file mode 160000 index f1d5dac9..00000000 --- a/workspace +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f1d5dac95ab6c4a2868f072490b239bb1842d789 From 10e6675ed71e4a5389da557906b4312facd975d1 Mon Sep 17 00:00:00 2001 From: Lucas Rebscher Date: Mon, 21 Jun 2021 10:16:16 +0200 Subject: [PATCH 12/43] Use notebook tornado 6.1 with notebook 6.4.0 ERROR: notebook 6.4.0 has requirement tornado>=6.1, but you'll have tornado 6.0.4 which is incompatible. --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7d232b46..47883e7a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -85,7 +85,7 @@ scipy==1.4.1 Send2Trash==1.5.0 terminado==0.8.3 testpath==0.4.4 -tornado==6.0.4 +tornado==6.1.0 traitlets==4.3.3 typing-extensions==3.7.4.2 urllib3==1.25.9 From 152b062a4ff785daaff0c7a8474ed60df343d29f Mon Sep 17 00:00:00 2001 From: Lucas Rebscher Date: Wed, 23 Jun 2021 12:22:10 +0200 Subject: [PATCH 13/43] #326 Allow json extension in upload --- netpyne_ui/api.py | 2 +- netpyne_ui/constants.py | 2 +- webapp/components/topbar/dialogs/UploadDownloadFiles.js | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/netpyne_ui/api.py b/netpyne_ui/api.py index 91cac361..7a64c1d0 100644 --- a/netpyne_ui/api.py +++ b/netpyne_ui/api.py @@ -8,7 +8,7 @@ from tempfile import TemporaryDirectory from jupyter_geppetto.webapi import get, post from notebook.base.handlers import IPythonHandler -from netpyne_ui.constants import NETPYNE_WORKDIR, UPLOAD_FOLDER_NAME, ALLOWED_EXTENSIONS, UPLOAD_FOLDER_PATH +from netpyne_ui.constants import ALLOWED_EXTENSIONS, UPLOAD_FOLDER_PATH def allowed_file(filename, allowed_extensions=ALLOWED_EXTENSIONS): return '.' in filename and \ diff --git a/netpyne_ui/constants.py b/netpyne_ui/constants.py index 283d781c..adb20518 100644 --- a/netpyne_ui/constants.py +++ b/netpyne_ui/constants.py @@ -3,7 +3,7 @@ UPLOAD_FOLDER_NAME = 'uploads' NETPYNE_WORKDIR = 'workspace' -ALLOWED_EXTENSIONS = ["py", "zip", "gz", ".tar.gz", "pdf", "txt", "xls", "png", "jpeg", "hoc"] +ALLOWED_EXTENSIONS = ["py", "zip", "gz", ".tar.gz", "pdf", "txt", "xls", "png", "jpeg", "hoc", "json"] HERE = os.path.dirname(os.path.abspath(__file__)) ROOT = os.path.dirname(HERE) UPLOAD_FOLDER_PATH = os.path.join(ROOT, NETPYNE_WORKDIR, UPLOAD_FOLDER_NAME) diff --git a/webapp/components/topbar/dialogs/UploadDownloadFiles.js b/webapp/components/topbar/dialogs/UploadDownloadFiles.js index 79d190c7..7e6a8c69 100644 --- a/webapp/components/topbar/dialogs/UploadDownloadFiles.js +++ b/webapp/components/topbar/dialogs/UploadDownloadFiles.js @@ -15,6 +15,8 @@ import { withStyles } from '@material-ui/core/styles'; import InputAdornment from '@material-ui/core/InputAdornment'; import FileBrowser from '../../general/FileBrowser'; +const ACCEPTED_EXTENSIONS = '.py .zip .gz .tar.gz .pdf .txt .xls .png .jpeg .json'; + const styles = ({ spacing, typography, @@ -78,7 +80,6 @@ class UploadDownloadFile extends React.Component { async uploadFiles () { const { uploadFiles } = this.state; const formData = new FormData(); - const data = {}; this.setState({ open: false }); GEPPETTO.trigger(GEPPETTO.Events.Show_spinner, 'UPLOADING FILES'); @@ -216,7 +217,6 @@ class UploadDownloadFile extends React.Component { this.setState({ downloadPaths: [text], downloadPathsDisplayText: text, - }); } @@ -251,7 +251,7 @@ class UploadDownloadFile extends React.Component {
-

Accept: .py .zip .gz .tar.gz .pdf .txt .xls .png .jpeg

+

{`Accept: ${ACCEPTED_EXTENSIONS}`}

); From 340d3616fcbbf2fbc16ad0672547c8b8bd209fe6 Mon Sep 17 00:00:00 2001 From: Lucas Rebscher Date: Fri, 2 Jul 2021 09:34:41 +0200 Subject: [PATCH 14/43] Bump up NEURON version to 8.0.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 47883e7a..911f818c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,7 +44,7 @@ nbconvert==5.6.1 nbformat==5.0.6 neuromllite==0.1.9 netpyne==1.0.0.2 -NEURON==7.8.1.1 +NEURON==8.0.0 numpy==1.18.5 oauthlib==3.0.1 ordered-set==4.0.2 From 06b9edc8e2e5744fb657f0e70fa59f6e668b735c Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Fri, 2 Jul 2021 10:18:40 +0200 Subject: [PATCH 15/43] Allow netpyne only to be installed from source --- utilities/install.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/utilities/install.py b/utilities/install.py index 13722104..c4138598 100644 --- a/utilities/install.py +++ b/utilities/install.py @@ -108,6 +108,11 @@ def main(netpyne_branch, workspace_branch, pygeppetto_branch=None, jupyter_geppe execute(cmd=['pip', 'install', '-e', '.'], cwd=ROOT_DIR) else: + + if netpyne_branch and netpyne_branch != 'master': + cprint("Installing netpyne") + clone(repository=NETPYNE, branch_or_tag=netpyne_branch) + execute(cmd=['pip', 'install', '-e', '.'], cwd=os.path.join(DEPS_DIR, NETPYNE_DIR)) # install requirements cprint("Installing UI python package...") execute(cmd=['pip', 'install', '-e', '.', '--no-deps'], cwd=ROOT_DIR) From 1670a27f84c0838626075c0a6e47a5decc0e3456 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Fri, 2 Jul 2021 10:19:41 +0200 Subject: [PATCH 16/43] Allow netpyne only to be installed from source --- utilities/install.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utilities/install.py b/utilities/install.py index 8f9d5870..95ddc5b0 100644 --- a/utilities/install.py +++ b/utilities/install.py @@ -117,6 +117,10 @@ def main(netpyne_branch, workspace_branch, pygeppetto_branch=None, jupyter_geppe else: # install requirements + if netpyne_branch and netpyne_branch != 'master': + cprint("Installing netpyne") + clone(repository=NETPYNE, branch_or_tag=netpyne_branch) + execute(cmd=['pip', 'install', '-e', '.'], cwd=os.path.join(DEPS_DIR, NETPYNE_DIR)) cprint("Installing UI python package...") execute(cmd=['pip', 'install', '-e', '.', '--no-deps'], cwd=ROOT_DIR) From f6d014c996ba5213643cb33ee40e1cd9c453df31 Mon Sep 17 00:00:00 2001 From: Muhaddatha Abdulghani Date: Wed, 7 Jul 2021 12:33:33 -0400 Subject: [PATCH 17/43] remove phantom.js --- webapp/package-lock.json | 639 --------------------------------------- webapp/package.json | 1 - 2 files changed, 640 deletions(-) diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 77dbd258..6d5f2ada 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -2447,15 +2447,6 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, "asn1.js": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", @@ -2495,12 +2486,6 @@ } } }, - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true - }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -2586,12 +2571,6 @@ "webpack-log": "^1.2.0" } }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true - }, "axe-core": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.2.0.tgz", @@ -3047,15 +3026,6 @@ "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", "dev": true }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, "bezier-js": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/bezier-js/-/bezier-js-4.1.1.tgz", @@ -3206,15 +3176,6 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", "dev": true }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.x.x" - } - }, "bootstrap": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz", @@ -3542,12 +3503,6 @@ "rsvp": "^4.8.4" } }, - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", - "dev": true - }, "casperjs": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/casperjs/-/casperjs-1.1.4.tgz", @@ -4382,15 +4337,6 @@ } } }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "requires": { - "boom": "2.x.x" - } - }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -4910,23 +4856,6 @@ "integrity": "sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw==", "dev": true }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, "dat.gui": { "version": "0.7.7", "resolved": "https://registry.npmjs.org/dat.gui/-/dat.gui-0.7.7.tgz", @@ -5341,16 +5270,6 @@ "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.2.tgz", "integrity": "sha512-eZoZPPJcUHnfRZ0PjLvx2qBordSiO8ofC3vt+qACLM95u+4DovnbYNpQtJh0DNsWj8RnxrQytD4WA8gj5cRIaQ==" }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "edges-to-adjacency-list": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/edges-to-adjacency-list/-/edges-to-adjacency-list-1.0.0.tgz", @@ -6540,84 +6459,6 @@ "resolved": "https://registry.npmjs.org/extract-frustum-planes/-/extract-frustum-planes-1.0.0.tgz", "integrity": "sha1-l9VwP/BWTIw8aDjKxF+ee8UsnvU=" }, - "extract-zip": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.5.0.tgz", - "integrity": "sha1-ksz22B73Cp+kwXRxFMzvbYaIpsQ=", - "dev": true, - "requires": { - "concat-stream": "1.5.0", - "debug": "0.7.4", - "mkdirp": "0.5.0", - "yauzl": "2.4.1" - }, - "dependencies": { - "concat-stream": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.0.tgz", - "integrity": "sha1-U/fUPFHF5D+ByP3QMyHGMb5o1hE=", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "~2.0.0", - "typedarray": "~0.0.5" - } - }, - "debug": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", - "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", - "dev": true - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", - "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, "falafel": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.2.4.tgz", @@ -6697,15 +6538,6 @@ } } }, - "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, "fetch-jsonp": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/fetch-jsonp/-/fetch-jsonp-1.1.3.tgz", @@ -7057,12 +6889,6 @@ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, "form-data": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", @@ -7152,19 +6978,6 @@ } } }, - "fs-extra": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", - "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -7207,24 +7020,6 @@ "resolved": "https://registry.npmjs.org/gamma/-/gamma-0.1.0.tgz", "integrity": "sha1-MxVkNAO/J5BsqAqzfDbs6UQO8zA=" }, - "generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "dev": true, - "requires": { - "is-property": "^1.0.2" - } - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "^1.0.0" - } - }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -7269,23 +7064,6 @@ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, "gl-axes3d": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/gl-axes3d/-/gl-axes3d-1.5.3.tgz", @@ -8073,45 +7851,6 @@ } } }, - "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "commander": "^2.9.0", - "is-my-json-valid": "^2.12.4", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -8229,28 +7968,6 @@ "minimalistic-assert": "^1.0.1" } }, - "hasha": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", - "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", - "dev": true, - "requires": { - "is-stream": "^1.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" - } - }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -8287,12 +8004,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, "hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -8552,17 +8263,6 @@ "micromatch": "^3.1.10" } }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, "https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", @@ -9014,25 +8714,6 @@ "resolved": "https://registry.npmjs.org/is-mobile/-/is-mobile-2.2.2.tgz", "integrity": "sha512-wW/SXnYJkTjs++tVK5b6kVITZpAZPtUrt9SF80vvxGiF/Oywal+COk1jlRkiVq15RFNEQKQY31TkV24/1T5cVg==" }, - "is-my-ip-valid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", - "dev": true - }, - "is-my-json-valid": { - "version": "2.20.5", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.5.tgz", - "integrity": "sha512-VTPuvvGQtxvCeghwspQu1rBgjYUT6FGxPlvFKbYuFtgc4ADsX3U5ihZOYN0qyU6u+d4X9xXb0IT5O6QpXKt87A==", - "dev": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" - } - }, "is-negative-zero": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", @@ -9103,12 +8784,6 @@ "isobject": "^3.0.1" } }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, "is-regex": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", @@ -9146,12 +8821,6 @@ "has-symbols": "^1.0.2" } }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, "is-what": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", @@ -9197,12 +8866,6 @@ "whatwg-fetch": ">=0.10.0" } }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, "istanbul-lib-coverage": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", @@ -9375,12 +9038,6 @@ "esprima": "^4.0.0" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -9397,12 +9054,6 @@ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -9414,12 +9065,6 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, "json2mq": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", @@ -9442,41 +9087,6 @@ "minimist": "^1.2.5" } }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonpointer": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.1.0.tgz", - "integrity": "sha512-CXcRvMyTlnR53xMcKnuMzfCA5i/nfblTnnr74CZb6C4vG39eu6w51t7nKmU5MfLfbTgGItliNyjO/ciNPDqClg==", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, "jss": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/jss/-/jss-10.6.0.tgz", @@ -9597,12 +9207,6 @@ "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz", "integrity": "sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew==" }, - "kew": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", - "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", - "dev": true - }, "killable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", @@ -9614,15 +9218,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, "language-subtag-registry": { "version": "0.3.21", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", @@ -10722,12 +10317,6 @@ "resolved": "https://registry.npmjs.org/numeric/-/numeric-1.2.6.tgz", "integrity": "sha1-dlsCvvl5iPz4gNTrPza4D6MTNao=" }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -11169,12 +10758,6 @@ "sha.js": "^2.4.8" } }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -11197,39 +10780,6 @@ "typedarray-pool": "^1.0.0" } }, - "phantomjs": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/phantomjs/-/phantomjs-2.1.7.tgz", - "integrity": "sha1-xpEPZ5NcNyhbYRQyn8LyfV8+MTQ=", - "dev": true, - "requires": { - "extract-zip": "~1.5.0", - "fs-extra": "~0.26.4", - "hasha": "^2.2.0", - "kew": "~0.7.0", - "progress": "~1.1.8", - "request": "~2.67.0", - "request-progress": "~2.0.1", - "which": "~1.2.2" - }, - "dependencies": { - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, - "which": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, "pick-by-alias": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pick-by-alias/-/pick-by-alias-1.2.0.tgz", @@ -12758,103 +12308,6 @@ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, - "request": { - "version": "2.67.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.67.0.tgz", - "integrity": "sha1-ivdHgOK/EeoK6aqWXBHxGv0nJ0I=", - "dev": true, - "requires": { - "aws-sign2": "~0.6.0", - "bl": "~1.0.0", - "caseless": "~0.11.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~1.0.0-rc3", - "har-validator": "~2.0.2", - "hawk": "~3.1.0", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "node-uuid": "~1.4.7", - "oauth-sign": "~0.8.0", - "qs": "~5.2.0", - "stringstream": "~0.0.4", - "tough-cookie": "~2.2.0", - "tunnel-agent": "~0.4.1" - }, - "dependencies": { - "bl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.0.3.tgz", - "integrity": "sha1-/FQhoo/UImA2w7OJGmaiW8ZNIm4=", - "dev": true, - "requires": { - "readable-stream": "~2.0.5" - } - }, - "form-data": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz", - "integrity": "sha1-rjFduaSQf6BlUCMEpm13M0de43w=", - "dev": true, - "requires": { - "async": "^2.0.1", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.11" - } - }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "qs": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.1.tgz", - "integrity": "sha1-gB/uAw4LlFDWOFrcSKTMVbRK7fw=", - "dev": true - }, - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "request-progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", - "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", - "dev": true, - "requires": { - "throttleit": "^1.0.0" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -13674,15 +13127,6 @@ } } }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "requires": { - "hoek": "2.x.x" - } - }, "sockjs": { "version": "0.3.21", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", @@ -13874,31 +13318,6 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, "ssri": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz", @@ -14112,12 +13531,6 @@ "safe-buffer": "~5.1.0" } }, - "stringstream": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", - "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", - "dev": true - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -14627,12 +14040,6 @@ "resolved": "https://registry.npmjs.org/three-trackballcontrols/-/three-trackballcontrols-0.0.8.tgz", "integrity": "sha512-9my4rB/ILaJw8E6khOcC6d8F8kEe6BvRtCer9bFJGZOh9txy4BqzwPrG7d8YCKK9MfcyTUoLsB5LKIsbtsZRTg==" }, - "throttleit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", - "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", - "dev": true - }, "through2": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", @@ -14813,12 +14220,6 @@ "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", "dev": true }, - "tough-cookie": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz", - "integrity": "sha1-yDoYMPTl7wuT7yo0iOck+N4Basc=", - "dev": true - }, "triangulate-hypercube": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/triangulate-hypercube/-/triangulate-hypercube-1.0.1.tgz", @@ -14871,12 +14272,6 @@ "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true - }, "turntable-camera-controller": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/turntable-camera-controller/-/turntable-camera-controller-3.0.1.tgz", @@ -14887,12 +14282,6 @@ "gl-vec3": "^1.0.2" } }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, "two-product": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/two-product/-/two-product-1.0.2.tgz", @@ -15480,25 +14869,6 @@ "resolved": "https://registry.npmjs.org/velocity.java/-/velocity.java-1.3.1.tgz", "integrity": "sha1-pv64A5jLVkzkKslrShjlKDc6Ld4=" }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, "vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", @@ -16213,15 +15583,6 @@ "decamelize": "^1.2.0" } }, - "yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", - "dev": true, - "requires": { - "fd-slicer": "~1.0.1" - } - }, "zero-crossings": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/zero-crossings/-/zero-crossings-1.0.1.tgz", diff --git a/webapp/package.json b/webapp/package.json index bb9d02e1..91a489fd 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -58,7 +58,6 @@ "json-loader": "^0.5.4", "less-loader": "^5.0.0", "mini-css-extract-plugin": "^0.7.0", - "phantomjs": "^2.1.7", "raw-loader": "^0.5.1", "slimerjs": "^1.0.0", "source-map-loader": "^0.2.3", From 905ad138c4e686fa7210940a94a73e4700082d22 Mon Sep 17 00:00:00 2001 From: Muhaddatha Date: Tue, 20 Jul 2021 13:21:18 -0400 Subject: [PATCH 18/43] #191 add versions --- webapp/components/general/Dialog.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/webapp/components/general/Dialog.js b/webapp/components/general/Dialog.js index 1f086645..1db469b8 100644 --- a/webapp/components/general/Dialog.js +++ b/webapp/components/general/Dialog.js @@ -25,9 +25,15 @@ const AboutContent = withStyles(styles)(({ classes }) => ( - + NetPyNE-UI v0.7.0 + + NetPyNE v0.9.6 + + + Neuron v8.0.0 + From d23dff524ef0a164f90798aa5132d8001898f170 Mon Sep 17 00:00:00 2001 From: Muhaddatha Date: Tue, 20 Jul 2021 13:35:53 -0400 Subject: [PATCH 19/43] #201 use suggested file name when exporting Python --- netpyne_ui/netpyne_geppetto.py | 41 ++++++++++++++++---------------- webapp/redux/middleware/utils.js | 11 +++------ 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/netpyne_ui/netpyne_geppetto.py b/netpyne_ui/netpyne_geppetto.py index 30aefbd0..0d68be8c 100644 --- a/netpyne_ui/netpyne_geppetto.py +++ b/netpyne_ui/netpyne_geppetto.py @@ -596,39 +596,40 @@ def header(title, spacer='-'): fname = args['fileName'] if args['fileName'][-3:] == '.py' else args['fileName'] + '.py' with open(fname, 'w') as script: - script.write('from netpyne import specs, sim\n') - script.write(header('documentation')) - script.write("''' Script generated with NetPyNE-UI. Please visit:\n") - script.write(" - https://www.netpyne.org\n - https://github.com/MetaCell/NetPyNE-UI\n'''\n") - script.write(header('script', spacer='=')) - script.write('netParams = specs.NetParams()\n') - script.write('simConfig = specs.SimConfig()\n') - script.write(header('single value attributes')) + script.write("from netpyne import specs, sim\n") + script.write(header("documentation")) + script.write("Script generated with NetPyNE-UI. Please visit:\n") + script.write(" - https://www.netpyne.org\n - https://github.com/MetaCell/NetPyNE-UI\n\n") + script.write(header("script", spacer="=")) + script.write("netParams = specs.NetParams()\n") + script.write("simConfig = specs.SimConfig()\n") + script.write(header("single value attributes")) for attr, value in list(self.netParams.__dict__.items()): if attr not in params: if value != getattr(specs.NetParams(), attr): - script.write('netParams.' + attr + ' = ') - script.write(convert2bool(json.dumps(value, indent=4)) + '\n') + script.write("netParams." + attr + " = ") + script.write(convert2bool(json.dumps(value, indent=4)) + "\n") - script.write(header('network attributes')) + script.write(header("network attributes")) for param in params: for key, value in list(getattr(self.netParams, param).items()): - script.write("netParams." + param + "['" + key + "'] = ") - script.write(convert2bool(json.dumps(value, indent=4)) + '\n') + script.write("netParams." + param + "[" + key + "] = ") + script.write(convert2bool(json.dumps(value, indent=4)) + "\n") - script.write(header('network configuration')) + script.write(header("network configuration")) for attr, value in list(self.simConfig.__dict__.items()): if value != getattr(specs.SimConfig(), attr): - script.write('simConfig.' + attr + ' = ') - script.write(convert2bool(json.dumps(value, indent=4)) + '\n') + script.write("simConfig." + attr + " = ") + script.write(convert2bool(json.dumps(value, indent=4)) + "\n") - script.write(header('create simulate analyze network')) - script.write('# sim.createSimulateAnalyze(netParams=netParams, simConfig=simConfig)\n') + script.write(header("create simulate analyze network")) + script.write("# sim.createSimulateAnalyze(netParams=netParams, simConfig=simConfig)\n") - script.write(header('end script', spacer='=')) + script.write(header("end script", spacer="=")) with open(fname) as f: - return f.read() + exportInfo = {"fileContent": f.read(), "fileName": fname} + return exportInfo except: return utils.getJSONError("Error while importing the NetPyNE model", sys.exc_info()) diff --git a/webapp/redux/middleware/utils.js b/webapp/redux/middleware/utils.js index 37a947e6..cf346a78 100644 --- a/webapp/redux/middleware/utils.js +++ b/webapp/redux/middleware/utils.js @@ -1,7 +1,3 @@ -const createFileName = (name) => name + getTimeStamp(); - -const getTimeStamp = () => new Date().toGMTString().replace(',', '').replace(/[ ,:]/g, '_'); - const unescapeText = (text) => { const unescaped = text.replace(/\\\\/g, '\\').replace(/\\'/g, "'").replace(/\\"/g, '"').split('\\n') .join('\n') @@ -32,8 +28,7 @@ export const downloadJsonResponse = (jsonData) => { forceBlobDownload(blob, filename); }; -export const downloadPythonResponse = (textData) => { - const filename = `${createFileName('NetPyNE_init_')}.py`; - const blob = new Blob([unescapeText(textData)], { type: 'text/plain;charset=utf-8' }); - forceBlobDownload(blob, filename); +export const downloadPythonResponse = (exportInfo) => { + const blob = new Blob([unescapeText(exportInfo.fileContent)], { type: 'text/plain;charset=utf-8' }); + forceBlobDownload(blob, exportInfo.fileName); }; From fca916d18c44331e570abd7e3452ab521f9931d0 Mon Sep 17 00:00:00 2001 From: Lucas Rebscher Date: Wed, 21 Jul 2021 16:57:56 +0200 Subject: [PATCH 20/43] #201 Use Base64 encoding to transfer file content --- netpyne_ui/netpyne_geppetto.py | 15 ++++++++++++--- webapp/package-lock.json | 5 +++++ webapp/package.json | 1 + webapp/redux/middleware/utils.js | 14 +++++++------- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/netpyne_ui/netpyne_geppetto.py b/netpyne_ui/netpyne_geppetto.py index 0d68be8c..a08ad310 100644 --- a/netpyne_ui/netpyne_geppetto.py +++ b/netpyne_ui/netpyne_geppetto.py @@ -9,6 +9,7 @@ import subprocess import logging import re +import base64 from netpyne import specs, sim, analysis from netpyne.specs.utils import validateFunction @@ -593,8 +594,15 @@ def header(title, spacer='-'): params = ['popParams', 'cellParams', 'synMechParams'] params += ['connParams', 'stimSourceParams', 'stimTargetParams'] - fname = args['fileName'] if args['fileName'][-3:] == '.py' else args['fileName'] + '.py' + fname = args['fileName'] + if not fname: + # default option + fname = 'output.py' + + if not fname[-3:] == '.py': + fname = f"{fname}.py" + # TODO: use methods offered by netpyne to create this script! with open(fname, 'w') as script: script.write("from netpyne import specs, sim\n") script.write(header("documentation")) @@ -628,8 +636,9 @@ def header(title, spacer='-'): script.write(header("end script", spacer="=")) with open(fname) as f: - exportInfo = {"fileContent": f.read(), "fileName": fname} - return exportInfo + file_b64 = base64.b64encode(bytes(f.read(), 'utf-8')).decode() + export_info = {"fileContent": file_b64, "fileName": fname} + return export_info except: return utils.getJSONError("Error while importing the NetPyNE model", sys.exc_info()) diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 6d5f2ada..456ab4ea 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -9018,6 +9018,11 @@ "resolved": "https://registry.npmjs.org/jquery-ui-bundle/-/jquery-ui-bundle-1.12.1.tgz", "integrity": "sha1-1r4uTDd0lOI3ixyuKSCpHRGC2MQ=" }, + "js-base64": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.6.1.tgz", + "integrity": "sha512-Frdq2+tRRGLQUIQOgsIGSCd1VePCS2fsddTG5dTCqR0JHgltXWfsxnY0gIXPoMeRmdom6Oyq+UMOFg5suduOjQ==" + }, "js-cookie": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", diff --git a/webapp/package.json b/webapp/package.json index 91a489fd..160ed395 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -19,6 +19,7 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.51", "jquery": "^3.6.0", + "js-base64": "^3.6.1", "less-vars-to-js": "^1.3.0", "react": "^17.0.1", "react-dom": "^16.4.0", diff --git a/webapp/redux/middleware/utils.js b/webapp/redux/middleware/utils.js index cf346a78..c36a25a0 100644 --- a/webapp/redux/middleware/utils.js +++ b/webapp/redux/middleware/utils.js @@ -1,9 +1,8 @@ -const unescapeText = (text) => { - const unescaped = text.replace(/\\\\/g, '\\').replace(/\\'/g, "'").replace(/\\"/g, '"').split('\\n') - .join('\n') - .substring(1); - return unescaped.substring(0, unescaped.length - 1); -}; +import { Base64 } from 'js-base64'; + +const getTimeStamp = () => new Date().toGMTString().replace(',', '').replace(/[ ,:]/g, '_'); + +const createFileName = (name) => name + getTimeStamp(); const forceBlobDownload = (blob, filename) => { const url = window.URL.createObjectURL(blob); @@ -29,6 +28,7 @@ export const downloadJsonResponse = (jsonData) => { }; export const downloadPythonResponse = (exportInfo) => { - const blob = new Blob([unescapeText(exportInfo.fileContent)], { type: 'text/plain;charset=utf-8' }); + const content = Base64.decode(exportInfo.fileContent); + const blob = new Blob([content], { type: 'text/plain;charset=utf-8' }); forceBlobDownload(blob, exportInfo.fileName); }; From c73fe400a88d683e5c474ab4c3e6313092921a09 Mon Sep 17 00:00:00 2001 From: Muhaddatha Date: Mon, 26 Jul 2021 10:29:42 -0400 Subject: [PATCH 21/43] #357 install js-base64 --- node_modules/@types/js-base64/LICENSE | 21 ++ node_modules/@types/js-base64/README.md | 3 + node_modules/@types/js-base64/package.json | 40 +++ node_modules/js-base64/LICENSE.md | 27 ++ node_modules/js-base64/README.md | 175 ++++++++++++ node_modules/js-base64/base64.d.ts | 135 +++++++++ node_modules/js-base64/base64.js | 317 +++++++++++++++++++++ node_modules/js-base64/base64.mjs | 297 +++++++++++++++++++ node_modules/js-base64/package.json | 70 +++++ package-lock.json | 21 ++ 10 files changed, 1106 insertions(+) create mode 100755 node_modules/@types/js-base64/LICENSE create mode 100755 node_modules/@types/js-base64/README.md create mode 100755 node_modules/@types/js-base64/package.json create mode 100644 node_modules/js-base64/LICENSE.md create mode 100644 node_modules/js-base64/README.md create mode 100644 node_modules/js-base64/base64.d.ts create mode 100644 node_modules/js-base64/base64.js create mode 100644 node_modules/js-base64/base64.mjs create mode 100644 node_modules/js-base64/package.json create mode 100644 package-lock.json diff --git a/node_modules/@types/js-base64/LICENSE b/node_modules/@types/js-base64/LICENSE new file mode 100755 index 00000000..9e841e7a --- /dev/null +++ b/node_modules/@types/js-base64/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/node_modules/@types/js-base64/README.md b/node_modules/@types/js-base64/README.md new file mode 100755 index 00000000..0432cc5d --- /dev/null +++ b/node_modules/@types/js-base64/README.md @@ -0,0 +1,3 @@ +This is a stub types definition for @types/js-base64 (https://github.com/dankogai/js-base64#readme). + +js-base64 provides its own type definitions, so you don't need @types/js-base64 installed! \ No newline at end of file diff --git a/node_modules/@types/js-base64/package.json b/node_modules/@types/js-base64/package.json new file mode 100755 index 00000000..9dadc2de --- /dev/null +++ b/node_modules/@types/js-base64/package.json @@ -0,0 +1,40 @@ +{ + "_from": "@types/js-base64", + "_id": "@types/js-base64@3.3.1", + "_inBundle": false, + "_integrity": "sha512-Zw33oQNAvDdAN9b0IE5stH0y2MylYvtU7VVTKEJPxhyM2q57CVaNJhtJW258ah24NRtaiA23tptUmVn3dmTKpw==", + "_location": "/@types/js-base64", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "@types/js-base64", + "name": "@types/js-base64", + "escapedName": "@types%2fjs-base64", + "scope": "@types", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#DEV:/", + "#USER" + ], + "_resolved": "https://registry.npmjs.org/@types/js-base64/-/js-base64-3.3.1.tgz", + "_shasum": "36c2d6dc126277ea28a4d0599d0cafbf547b51e6", + "_spec": "@types/js-base64", + "_where": "/home/muhaddatha/Desktop/Work/NetPyNE-UI", + "author": "", + "bundleDependencies": false, + "dependencies": { + "js-base64": "*" + }, + "deprecated": "This is a stub types definition. js-base64 provides its own type definitions, so you do not need this installed.", + "description": "Stub TypeScript definitions entry for js-base64, which provides its own types definitions", + "license": "MIT", + "main": "", + "name": "@types/js-base64", + "scripts": {}, + "typings": null, + "version": "3.3.1" +} diff --git a/node_modules/js-base64/LICENSE.md b/node_modules/js-base64/LICENSE.md new file mode 100644 index 00000000..fd579a40 --- /dev/null +++ b/node_modules/js-base64/LICENSE.md @@ -0,0 +1,27 @@ +Copyright (c) 2014, Dan Kogai +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of {{{project}}} nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/node_modules/js-base64/README.md b/node_modules/js-base64/README.md new file mode 100644 index 00000000..d21f49ac --- /dev/null +++ b/node_modules/js-base64/README.md @@ -0,0 +1,175 @@ +[![build status](https://secure.travis-ci.org/dankogai/js-base64.png)](http://travis-ci.org/dankogai/js-base64) + +# base64.js + +Yet another [Base64] transcoder. + +[Base64]: http://en.wikipedia.org/wiki/Base64 + +## HEADS UP + +In version 3.0 `js-base64` switch to ES2015 module so it is no longer compatible with legacy browsers like IE (see below). And since version 3.3 it is written in TypeScript. Now `base64.mjs` is compiled from `base64.ts` then `base64.js` is generated from `base64.mjs`. + +## Install + +```shell +$ npm install --save js-base64 +``` + +## Usage + +### In Browser + +Locally… + +```html + +``` + +… or Directly from CDN. In which case you don't even need to install. + +```html + +``` + +This good old way loads `Base64` in the global context (`window`). Though `Base64.noConflict()` is made available, you should consider using ES6 Module to avoid tainting `window`. + +### As an ES6 Module + +locally… + +```javascript +import { Base64 } from 'js-base64'; +``` + +```javascript +// or if you prefer no Base64 namespace +import { encode, decode } from 'js-base64'; +``` + +or even remotely. + +```html + +``` + +```html + +``` + +### node.js (commonjs) + +```javascript +const {Base64} = require('js-base64'); +``` + +Unlike the case above, the global context is no longer modified. + +You can also use [esm] to `import` instead of `require`. + +[esm]: https://github.com/standard-things/esm + +```javascript +require=require('esm')(module); +import {Base64} from 'js-base64'; +``` + +## SYNOPSIS + +```javascript +let latin = 'dankogai'; +let utf8 = '小飼弾' +let u8s = new Uint8Array([100,97,110,107,111,103,97,105]); +Base64.encode(latin); // ZGFua29nYWk= +Base64.encode(latin, true)); // ZGFua29nYWk skips padding +Base64.encodeURI(latin)); // ZGFua29nYWk +Base64.btoa(latin); // ZGFua29nYWk= +Base64.btoa(utf8); // raises exception +Base64.fromUint8Array(u8s); // ZGFua29nYWk= +Base64.fromUint8Array(u8s, true); // ZGFua29nYW which is URI safe +Base64.encode(utf8); // 5bCP6aO85by+ +Base64.encode(utf8, true) // 5bCP6aO85by- +Base64.encodeURI(utf8); // 5bCP6aO85by- +``` + +```javascript +Base64.decode( 'ZGFua29nYWk=');// dankogai +Base64.decode( 'ZGFua29nYWk'); // dankogai +Base64.atob( 'ZGFua29nYWk=');// dankogai +Base64.atob( '5bCP6aO85by+');// '小飼弾' which is nonsense +Base64.toUint8Array('ZGFua29nYWk=');// u8s above +Base64.decode( '5bCP6aO85by+');// 小飼弾 +// note .decodeURI() is unnecessary since it accepts both flavors +Base64.decode( '5bCP6aO85by-');// 小飼弾 +``` + +```javascript +Base64.isValid(0); // false: 0 is not string +Base64.isValid(''); // true: a valid Base64-encoded empty byte +Base64.isValid('ZA=='); // true: a valid Base64-encoded 'd' +Base64.isValid('Z A='); // true: whitespaces are okay +Base64.isValid('ZA'); // true: padding ='s can be omitted +Base64.isValid('++'); // true: can be non URL-safe +Base64.isValid('--'); // true: or URL-safe +Base64.isValid('+-'); // false: can't mix both +``` + +### Built-in Extensions + +By default `Base64` leaves built-in prototypes untouched. But you can extend them as below. + +```javascript +// you have to explicitly extend String.prototype +Base64.extendString(); +// once extended, you can do the following +'dankogai'.toBase64(); // ZGFua29nYWk= +'小飼弾'.toBase64(); // 5bCP6aO85by+ +'小飼弾'.toBase64(true); // 5bCP6aO85by- +'小飼弾'.toBase64URI(); // 5bCP6aO85by- ab alias of .toBase64(true) +'小飼弾'.toBase64URL(); // 5bCP6aO85by- an alias of .toBase64URI() +'ZGFua29nYWk='.fromBase64(); // dankogai +'5bCP6aO85by+'.fromBase64(); // 小飼弾 +'5bCP6aO85by-'.fromBase64(); // 小飼弾 +'5bCP6aO85by-'.toUint8Array();// u8s above +``` + +```javascript +// you have to explicitly extend String.prototype +Base64.extendString(); +// once extended, you can do the following +u8s.toBase64(); // 'ZGFua29nYWk=' +u8s.toBase64URI(); // 'ZGFua29nYWk' +u8s.toBase64URL(); // 'ZGFua29nYWk' an alias of .toBase64URI() +``` + +```javascript +// extend all at once +Base64.extendBuiltins() +``` + +## `.decode()` vs `.atob` (and `.encode()` vs `btoa()`) + +Suppose you have: + +``` +var pngBase64 = + "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="; +``` + +Which is a Base64-encoded 1x1 transparent PNG, **DO NOT USE** `Base64.decode(pngBase64)`.  Use `Base64.atob(pngBase64)` instead.  `Base64.decode()` decodes to UTF-8 string while `Base64.atob()` decodes to bytes, which is compatible to browser built-in `atob()` (Which is absent in node.js).  The same rule applies to the opposite direction. + +Or even better, `Base64.toUint8Array(pngBase64)`. + +### If you really, really need an ES5 version + +You can transpiles to an ES5 that runs on IE11. Do the following in your shell. + +```shell +$ make base64.es5.js +``` diff --git a/node_modules/js-base64/base64.d.ts b/node_modules/js-base64/base64.d.ts new file mode 100644 index 00000000..3c29c290 --- /dev/null +++ b/node_modules/js-base64/base64.d.ts @@ -0,0 +1,135 @@ +/** + * base64.ts + * + * Licensed under the BSD 3-Clause License. + * http://opensource.org/licenses/BSD-3-Clause + * + * References: + * http://en.wikipedia.org/wiki/Base64 + * + * @author Dan Kogai (https://github.com/dankogai) + */ +declare const version = "3.6.1"; +/** + * @deprecated use lowercase `version`. + */ +declare const VERSION = "3.6.1"; +/** + * polyfill version of `btoa` + */ +declare const btoaPolyfill: (bin: string) => string; +/** + * does what `window.btoa` of web browsers do. + * @param {String} bin binary string + * @returns {string} Base64-encoded string + */ +declare const _btoa: (bin: string) => string; +/** + * converts a Uint8Array to a Base64 string. + * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 §5 + * @returns {string} Base64 string + */ +declare const fromUint8Array: (u8a: Uint8Array, urlsafe?: boolean) => string; +/** + * @deprecated should have been internal use only. + * @param {string} src UTF-8 string + * @returns {string} UTF-16 string + */ +declare const utob: (u: string) => string; +/** + * converts a UTF-8-encoded string to a Base64 string. + * @param {boolean} [urlsafe] if `true` make the result URL-safe + * @returns {string} Base64 string + */ +declare const encode: (src: string, urlsafe?: boolean) => string; +/** + * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 §5. + * @returns {string} Base64 string + */ +declare const encodeURI: (src: string) => string; +/** + * @deprecated should have been internal use only. + * @param {string} src UTF-16 string + * @returns {string} UTF-8 string + */ +declare const btou: (b: string) => string; +/** + * polyfill version of `atob` + */ +declare const atobPolyfill: (asc: string) => string; +/** + * does what `window.atob` of web browsers do. + * @param {String} asc Base64-encoded string + * @returns {string} binary string + */ +declare const _atob: (asc: string) => string; +/** + * converts a Base64 string to a Uint8Array. + */ +declare const toUint8Array: (a: string) => Uint8Array; +/** + * converts a Base64 string to a UTF-8 string. + * @param {String} src Base64 string. Both normal and URL-safe are supported + * @returns {string} UTF-8 string + */ +declare const decode: (src: string) => string; +/** + * check if a value is a valid Base64 string + * @param {String} src a value to check + */ +declare const isValid: (src: any) => boolean; +/** + * extend String.prototype with relevant methods + */ +declare const extendString: () => void; +/** + * extend Uint8Array.prototype with relevant methods + */ +declare const extendUint8Array: () => void; +/** + * extend Builtin prototypes with relevant methods + */ +declare const extendBuiltins: () => void; +declare const gBase64: { + version: string; + VERSION: string; + atob: (asc: string) => string; + atobPolyfill: (asc: string) => string; + btoa: (bin: string) => string; + btoaPolyfill: (bin: string) => string; + fromBase64: (src: string) => string; + toBase64: (src: string, urlsafe?: boolean) => string; + encode: (src: string, urlsafe?: boolean) => string; + encodeURI: (src: string) => string; + encodeURL: (src: string) => string; + utob: (u: string) => string; + btou: (b: string) => string; + decode: (src: string) => string; + isValid: (src: any) => boolean; + fromUint8Array: (u8a: Uint8Array, urlsafe?: boolean) => string; + toUint8Array: (a: string) => Uint8Array; + extendString: () => void; + extendUint8Array: () => void; + extendBuiltins: () => void; +}; +export { version }; +export { VERSION }; +export { _atob as atob }; +export { atobPolyfill }; +export { _btoa as btoa }; +export { btoaPolyfill }; +export { decode as fromBase64 }; +export { encode as toBase64 }; +export { utob }; +export { encode }; +export { encodeURI }; +export { encodeURI as encodeURL }; +export { btou }; +export { decode }; +export { isValid }; +export { fromUint8Array }; +export { toUint8Array }; +export { extendString }; +export { extendUint8Array }; +export { extendBuiltins }; +export { gBase64 as Base64 }; diff --git a/node_modules/js-base64/base64.js b/node_modules/js-base64/base64.js new file mode 100644 index 00000000..8120c2de --- /dev/null +++ b/node_modules/js-base64/base64.js @@ -0,0 +1,317 @@ + + +// +// THIS FILE IS AUTOMATICALLY GENERATED! DO NOT EDIT BY HAND! +// +;(function(global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + ? module.exports = factory() + : typeof define === 'function' && define.amd + ? define(factory) : + // cf. https://github.com/dankogai/js-base64/issues/119 + (function() { + // existing version for noConflict() + const _Base64 = global.Base64; + const gBase64 = factory(); + gBase64.noConflict = () => { + global.Base64 = _Base64; + return gBase64; + }; + if (global.Meteor) { // Meteor.js + Base64 = gBase64; + } + global.Base64 = gBase64; + })(); +}((typeof self !== 'undefined' ? self + : typeof window !== 'undefined' ? window + : typeof global !== 'undefined' ? global + : this +), function() { + 'use strict'; + +/** + * base64.ts + * + * Licensed under the BSD 3-Clause License. + * http://opensource.org/licenses/BSD-3-Clause + * + * References: + * http://en.wikipedia.org/wiki/Base64 + * + * @author Dan Kogai (https://github.com/dankogai) + */ +const version = '3.6.1'; +/** + * @deprecated use lowercase `version`. + */ +const VERSION = version; +const _hasatob = typeof atob === 'function'; +const _hasbtoa = typeof btoa === 'function'; +const _hasBuffer = typeof Buffer === 'function'; +const _TD = typeof TextDecoder === 'function' ? new TextDecoder() : undefined; +const _TE = typeof TextEncoder === 'function' ? new TextEncoder() : undefined; +const b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; +const b64chs = [...b64ch]; +const b64tab = ((a) => { + let tab = {}; + a.forEach((c, i) => tab[c] = i); + return tab; +})(b64chs); +const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/; +const _fromCC = String.fromCharCode.bind(String); +const _U8Afrom = typeof Uint8Array.from === 'function' + ? Uint8Array.from.bind(Uint8Array) + : (it, fn = (x) => x) => new Uint8Array(Array.prototype.slice.call(it, 0).map(fn)); +const _mkUriSafe = (src) => src + .replace(/[+\/]/g, (m0) => m0 == '+' ? '-' : '_') + .replace(/=+$/m, ''); +const _tidyB64 = (s) => s.replace(/[^A-Za-z0-9\+\/]/g, ''); +/** + * polyfill version of `btoa` + */ +const btoaPolyfill = (bin) => { + // console.log('polyfilled'); + let u32, c0, c1, c2, asc = ''; + const pad = bin.length % 3; + for (let i = 0; i < bin.length;) { + if ((c0 = bin.charCodeAt(i++)) > 255 || + (c1 = bin.charCodeAt(i++)) > 255 || + (c2 = bin.charCodeAt(i++)) > 255) + throw new TypeError('invalid character found'); + u32 = (c0 << 16) | (c1 << 8) | c2; + asc += b64chs[u32 >> 18 & 63] + + b64chs[u32 >> 12 & 63] + + b64chs[u32 >> 6 & 63] + + b64chs[u32 & 63]; + } + return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc; +}; +/** + * does what `window.btoa` of web browsers do. + * @param {String} bin binary string + * @returns {string} Base64-encoded string + */ +const _btoa = _hasbtoa ? (bin) => btoa(bin) + : _hasBuffer ? (bin) => Buffer.from(bin, 'binary').toString('base64') + : btoaPolyfill; +const _fromUint8Array = _hasBuffer + ? (u8a) => Buffer.from(u8a).toString('base64') + : (u8a) => { + // cf. https://stackoverflow.com/questions/12710001/how-to-convert-uint8-array-to-base64-encoded-string/12713326#12713326 + const maxargs = 0x1000; + let strs = []; + for (let i = 0, l = u8a.length; i < l; i += maxargs) { + strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs))); + } + return _btoa(strs.join('')); + }; +/** + * converts a Uint8Array to a Base64 string. + * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 §5 + * @returns {string} Base64 string + */ +const fromUint8Array = (u8a, urlsafe = false) => urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a); +// This trick is found broken https://github.com/dankogai/js-base64/issues/130 +// const utob = (src: string) => unescape(encodeURIComponent(src)); +// reverting good old fationed regexp +const cb_utob = (c) => { + if (c.length < 2) { + var cc = c.charCodeAt(0); + return cc < 0x80 ? c + : cc < 0x800 ? (_fromCC(0xc0 | (cc >>> 6)) + + _fromCC(0x80 | (cc & 0x3f))) + : (_fromCC(0xe0 | ((cc >>> 12) & 0x0f)) + + _fromCC(0x80 | ((cc >>> 6) & 0x3f)) + + _fromCC(0x80 | (cc & 0x3f))); + } + else { + var cc = 0x10000 + + (c.charCodeAt(0) - 0xD800) * 0x400 + + (c.charCodeAt(1) - 0xDC00); + return (_fromCC(0xf0 | ((cc >>> 18) & 0x07)) + + _fromCC(0x80 | ((cc >>> 12) & 0x3f)) + + _fromCC(0x80 | ((cc >>> 6) & 0x3f)) + + _fromCC(0x80 | (cc & 0x3f))); + } +}; +const re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; +/** + * @deprecated should have been internal use only. + * @param {string} src UTF-8 string + * @returns {string} UTF-16 string + */ +const utob = (u) => u.replace(re_utob, cb_utob); +// +const _encode = _hasBuffer + ? (s) => Buffer.from(s, 'utf8').toString('base64') + : _TE + ? (s) => _fromUint8Array(_TE.encode(s)) + : (s) => _btoa(utob(s)); +/** + * converts a UTF-8-encoded string to a Base64 string. + * @param {boolean} [urlsafe] if `true` make the result URL-safe + * @returns {string} Base64 string + */ +const encode = (src, urlsafe = false) => urlsafe + ? _mkUriSafe(_encode(src)) + : _encode(src); +/** + * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 §5. + * @returns {string} Base64 string + */ +const encodeURI = (src) => encode(src, true); +// This trick is found broken https://github.com/dankogai/js-base64/issues/130 +// const btou = (src: string) => decodeURIComponent(escape(src)); +// reverting good old fationed regexp +const re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g; +const cb_btou = (cccc) => { + switch (cccc.length) { + case 4: + var cp = ((0x07 & cccc.charCodeAt(0)) << 18) + | ((0x3f & cccc.charCodeAt(1)) << 12) + | ((0x3f & cccc.charCodeAt(2)) << 6) + | (0x3f & cccc.charCodeAt(3)), offset = cp - 0x10000; + return (_fromCC((offset >>> 10) + 0xD800) + + _fromCC((offset & 0x3FF) + 0xDC00)); + case 3: + return _fromCC(((0x0f & cccc.charCodeAt(0)) << 12) + | ((0x3f & cccc.charCodeAt(1)) << 6) + | (0x3f & cccc.charCodeAt(2))); + default: + return _fromCC(((0x1f & cccc.charCodeAt(0)) << 6) + | (0x3f & cccc.charCodeAt(1))); + } +}; +/** + * @deprecated should have been internal use only. + * @param {string} src UTF-16 string + * @returns {string} UTF-8 string + */ +const btou = (b) => b.replace(re_btou, cb_btou); +/** + * polyfill version of `atob` + */ +const atobPolyfill = (asc) => { + // console.log('polyfilled'); + asc = asc.replace(/\s+/g, ''); + if (!b64re.test(asc)) + throw new TypeError('malformed base64.'); + asc += '=='.slice(2 - (asc.length & 3)); + let u24, bin = '', r1, r2; + for (let i = 0; i < asc.length;) { + u24 = b64tab[asc.charAt(i++)] << 18 + | b64tab[asc.charAt(i++)] << 12 + | (r1 = b64tab[asc.charAt(i++)]) << 6 + | (r2 = b64tab[asc.charAt(i++)]); + bin += r1 === 64 ? _fromCC(u24 >> 16 & 255) + : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255) + : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255); + } + return bin; +}; +/** + * does what `window.atob` of web browsers do. + * @param {String} asc Base64-encoded string + * @returns {string} binary string + */ +const _atob = _hasatob ? (asc) => atob(_tidyB64(asc)) + : _hasBuffer ? (asc) => Buffer.from(asc, 'base64').toString('binary') + : atobPolyfill; +// +const _toUint8Array = _hasBuffer + ? (a) => _U8Afrom(Buffer.from(a, 'base64')) + : (a) => _U8Afrom(_atob(a), c => c.charCodeAt(0)); +/** + * converts a Base64 string to a Uint8Array. + */ +const toUint8Array = (a) => _toUint8Array(_unURI(a)); +// +const _decode = _hasBuffer + ? (a) => Buffer.from(a, 'base64').toString('utf8') + : _TD + ? (a) => _TD.decode(_toUint8Array(a)) + : (a) => btou(_atob(a)); +const _unURI = (a) => _tidyB64(a.replace(/[-_]/g, (m0) => m0 == '-' ? '+' : '/')); +/** + * converts a Base64 string to a UTF-8 string. + * @param {String} src Base64 string. Both normal and URL-safe are supported + * @returns {string} UTF-8 string + */ +const decode = (src) => _decode(_unURI(src)); +/** + * check if a value is a valid Base64 string + * @param {String} src a value to check + */ +const isValid = (src) => { + if (typeof src !== 'string') + return false; + const s = src.replace(/\s+/g, '').replace(/=+$/, ''); + return !/[^\s0-9a-zA-Z\+/]/.test(s) || !/[^\s0-9a-zA-Z\-_]/.test(s); +}; +// +const _noEnum = (v) => { + return { + value: v, enumerable: false, writable: true, configurable: true + }; +}; +/** + * extend String.prototype with relevant methods + */ +const extendString = function () { + const _add = (name, body) => Object.defineProperty(String.prototype, name, _noEnum(body)); + _add('fromBase64', function () { return decode(this); }); + _add('toBase64', function (urlsafe) { return encode(this, urlsafe); }); + _add('toBase64URI', function () { return encode(this, true); }); + _add('toBase64URL', function () { return encode(this, true); }); + _add('toUint8Array', function () { return toUint8Array(this); }); +}; +/** + * extend Uint8Array.prototype with relevant methods + */ +const extendUint8Array = function () { + const _add = (name, body) => Object.defineProperty(Uint8Array.prototype, name, _noEnum(body)); + _add('toBase64', function (urlsafe) { return fromUint8Array(this, urlsafe); }); + _add('toBase64URI', function () { return fromUint8Array(this, true); }); + _add('toBase64URL', function () { return fromUint8Array(this, true); }); +}; +/** + * extend Builtin prototypes with relevant methods + */ +const extendBuiltins = () => { + extendString(); + extendUint8Array(); +}; +const gBase64 = { + version: version, + VERSION: VERSION, + atob: _atob, + atobPolyfill: atobPolyfill, + btoa: _btoa, + btoaPolyfill: btoaPolyfill, + fromBase64: decode, + toBase64: encode, + encode: encode, + encodeURI: encodeURI, + encodeURL: encodeURI, + utob: utob, + btou: btou, + decode: decode, + isValid: isValid, + fromUint8Array: fromUint8Array, + toUint8Array: toUint8Array, + extendString: extendString, + extendUint8Array: extendUint8Array, + extendBuiltins: extendBuiltins, +}; + + // + // export Base64 to the namespace + // + // ES5 is yet to have Object.assign() that may make transpilers unhappy. + // gBase64.Base64 = Object.assign({}, gBase64); + gBase64.Base64 = {}; + Object.keys(gBase64).forEach(k => gBase64.Base64[k] = gBase64[k]); + return gBase64; +})); + + diff --git a/node_modules/js-base64/base64.mjs b/node_modules/js-base64/base64.mjs new file mode 100644 index 00000000..eb3e56cf --- /dev/null +++ b/node_modules/js-base64/base64.mjs @@ -0,0 +1,297 @@ +/** + * base64.ts + * + * Licensed under the BSD 3-Clause License. + * http://opensource.org/licenses/BSD-3-Clause + * + * References: + * http://en.wikipedia.org/wiki/Base64 + * + * @author Dan Kogai (https://github.com/dankogai) + */ +const version = '3.6.1'; +/** + * @deprecated use lowercase `version`. + */ +const VERSION = version; +const _hasatob = typeof atob === 'function'; +const _hasbtoa = typeof btoa === 'function'; +const _hasBuffer = typeof Buffer === 'function'; +const _TD = typeof TextDecoder === 'function' ? new TextDecoder() : undefined; +const _TE = typeof TextEncoder === 'function' ? new TextEncoder() : undefined; +const b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; +const b64chs = [...b64ch]; +const b64tab = ((a) => { + let tab = {}; + a.forEach((c, i) => tab[c] = i); + return tab; +})(b64chs); +const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/; +const _fromCC = String.fromCharCode.bind(String); +const _U8Afrom = typeof Uint8Array.from === 'function' + ? Uint8Array.from.bind(Uint8Array) + : (it, fn = (x) => x) => new Uint8Array(Array.prototype.slice.call(it, 0).map(fn)); +const _mkUriSafe = (src) => src + .replace(/[+\/]/g, (m0) => m0 == '+' ? '-' : '_') + .replace(/=+$/m, ''); +const _tidyB64 = (s) => s.replace(/[^A-Za-z0-9\+\/]/g, ''); +/** + * polyfill version of `btoa` + */ +const btoaPolyfill = (bin) => { + // console.log('polyfilled'); + let u32, c0, c1, c2, asc = ''; + const pad = bin.length % 3; + for (let i = 0; i < bin.length;) { + if ((c0 = bin.charCodeAt(i++)) > 255 || + (c1 = bin.charCodeAt(i++)) > 255 || + (c2 = bin.charCodeAt(i++)) > 255) + throw new TypeError('invalid character found'); + u32 = (c0 << 16) | (c1 << 8) | c2; + asc += b64chs[u32 >> 18 & 63] + + b64chs[u32 >> 12 & 63] + + b64chs[u32 >> 6 & 63] + + b64chs[u32 & 63]; + } + return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc; +}; +/** + * does what `window.btoa` of web browsers do. + * @param {String} bin binary string + * @returns {string} Base64-encoded string + */ +const _btoa = _hasbtoa ? (bin) => btoa(bin) + : _hasBuffer ? (bin) => Buffer.from(bin, 'binary').toString('base64') + : btoaPolyfill; +const _fromUint8Array = _hasBuffer + ? (u8a) => Buffer.from(u8a).toString('base64') + : (u8a) => { + // cf. https://stackoverflow.com/questions/12710001/how-to-convert-uint8-array-to-base64-encoded-string/12713326#12713326 + const maxargs = 0x1000; + let strs = []; + for (let i = 0, l = u8a.length; i < l; i += maxargs) { + strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs))); + } + return _btoa(strs.join('')); + }; +/** + * converts a Uint8Array to a Base64 string. + * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 §5 + * @returns {string} Base64 string + */ +const fromUint8Array = (u8a, urlsafe = false) => urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a); +// This trick is found broken https://github.com/dankogai/js-base64/issues/130 +// const utob = (src: string) => unescape(encodeURIComponent(src)); +// reverting good old fationed regexp +const cb_utob = (c) => { + if (c.length < 2) { + var cc = c.charCodeAt(0); + return cc < 0x80 ? c + : cc < 0x800 ? (_fromCC(0xc0 | (cc >>> 6)) + + _fromCC(0x80 | (cc & 0x3f))) + : (_fromCC(0xe0 | ((cc >>> 12) & 0x0f)) + + _fromCC(0x80 | ((cc >>> 6) & 0x3f)) + + _fromCC(0x80 | (cc & 0x3f))); + } + else { + var cc = 0x10000 + + (c.charCodeAt(0) - 0xD800) * 0x400 + + (c.charCodeAt(1) - 0xDC00); + return (_fromCC(0xf0 | ((cc >>> 18) & 0x07)) + + _fromCC(0x80 | ((cc >>> 12) & 0x3f)) + + _fromCC(0x80 | ((cc >>> 6) & 0x3f)) + + _fromCC(0x80 | (cc & 0x3f))); + } +}; +const re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; +/** + * @deprecated should have been internal use only. + * @param {string} src UTF-8 string + * @returns {string} UTF-16 string + */ +const utob = (u) => u.replace(re_utob, cb_utob); +// +const _encode = _hasBuffer + ? (s) => Buffer.from(s, 'utf8').toString('base64') + : _TE + ? (s) => _fromUint8Array(_TE.encode(s)) + : (s) => _btoa(utob(s)); +/** + * converts a UTF-8-encoded string to a Base64 string. + * @param {boolean} [urlsafe] if `true` make the result URL-safe + * @returns {string} Base64 string + */ +const encode = (src, urlsafe = false) => urlsafe + ? _mkUriSafe(_encode(src)) + : _encode(src); +/** + * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 §5. + * @returns {string} Base64 string + */ +const encodeURI = (src) => encode(src, true); +// This trick is found broken https://github.com/dankogai/js-base64/issues/130 +// const btou = (src: string) => decodeURIComponent(escape(src)); +// reverting good old fationed regexp +const re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g; +const cb_btou = (cccc) => { + switch (cccc.length) { + case 4: + var cp = ((0x07 & cccc.charCodeAt(0)) << 18) + | ((0x3f & cccc.charCodeAt(1)) << 12) + | ((0x3f & cccc.charCodeAt(2)) << 6) + | (0x3f & cccc.charCodeAt(3)), offset = cp - 0x10000; + return (_fromCC((offset >>> 10) + 0xD800) + + _fromCC((offset & 0x3FF) + 0xDC00)); + case 3: + return _fromCC(((0x0f & cccc.charCodeAt(0)) << 12) + | ((0x3f & cccc.charCodeAt(1)) << 6) + | (0x3f & cccc.charCodeAt(2))); + default: + return _fromCC(((0x1f & cccc.charCodeAt(0)) << 6) + | (0x3f & cccc.charCodeAt(1))); + } +}; +/** + * @deprecated should have been internal use only. + * @param {string} src UTF-16 string + * @returns {string} UTF-8 string + */ +const btou = (b) => b.replace(re_btou, cb_btou); +/** + * polyfill version of `atob` + */ +const atobPolyfill = (asc) => { + // console.log('polyfilled'); + asc = asc.replace(/\s+/g, ''); + if (!b64re.test(asc)) + throw new TypeError('malformed base64.'); + asc += '=='.slice(2 - (asc.length & 3)); + let u24, bin = '', r1, r2; + for (let i = 0; i < asc.length;) { + u24 = b64tab[asc.charAt(i++)] << 18 + | b64tab[asc.charAt(i++)] << 12 + | (r1 = b64tab[asc.charAt(i++)]) << 6 + | (r2 = b64tab[asc.charAt(i++)]); + bin += r1 === 64 ? _fromCC(u24 >> 16 & 255) + : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255) + : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255); + } + return bin; +}; +/** + * does what `window.atob` of web browsers do. + * @param {String} asc Base64-encoded string + * @returns {string} binary string + */ +const _atob = _hasatob ? (asc) => atob(_tidyB64(asc)) + : _hasBuffer ? (asc) => Buffer.from(asc, 'base64').toString('binary') + : atobPolyfill; +// +const _toUint8Array = _hasBuffer + ? (a) => _U8Afrom(Buffer.from(a, 'base64')) + : (a) => _U8Afrom(_atob(a), c => c.charCodeAt(0)); +/** + * converts a Base64 string to a Uint8Array. + */ +const toUint8Array = (a) => _toUint8Array(_unURI(a)); +// +const _decode = _hasBuffer + ? (a) => Buffer.from(a, 'base64').toString('utf8') + : _TD + ? (a) => _TD.decode(_toUint8Array(a)) + : (a) => btou(_atob(a)); +const _unURI = (a) => _tidyB64(a.replace(/[-_]/g, (m0) => m0 == '-' ? '+' : '/')); +/** + * converts a Base64 string to a UTF-8 string. + * @param {String} src Base64 string. Both normal and URL-safe are supported + * @returns {string} UTF-8 string + */ +const decode = (src) => _decode(_unURI(src)); +/** + * check if a value is a valid Base64 string + * @param {String} src a value to check + */ +const isValid = (src) => { + if (typeof src !== 'string') + return false; + const s = src.replace(/\s+/g, '').replace(/=+$/, ''); + return !/[^\s0-9a-zA-Z\+/]/.test(s) || !/[^\s0-9a-zA-Z\-_]/.test(s); +}; +// +const _noEnum = (v) => { + return { + value: v, enumerable: false, writable: true, configurable: true + }; +}; +/** + * extend String.prototype with relevant methods + */ +const extendString = function () { + const _add = (name, body) => Object.defineProperty(String.prototype, name, _noEnum(body)); + _add('fromBase64', function () { return decode(this); }); + _add('toBase64', function (urlsafe) { return encode(this, urlsafe); }); + _add('toBase64URI', function () { return encode(this, true); }); + _add('toBase64URL', function () { return encode(this, true); }); + _add('toUint8Array', function () { return toUint8Array(this); }); +}; +/** + * extend Uint8Array.prototype with relevant methods + */ +const extendUint8Array = function () { + const _add = (name, body) => Object.defineProperty(Uint8Array.prototype, name, _noEnum(body)); + _add('toBase64', function (urlsafe) { return fromUint8Array(this, urlsafe); }); + _add('toBase64URI', function () { return fromUint8Array(this, true); }); + _add('toBase64URL', function () { return fromUint8Array(this, true); }); +}; +/** + * extend Builtin prototypes with relevant methods + */ +const extendBuiltins = () => { + extendString(); + extendUint8Array(); +}; +const gBase64 = { + version: version, + VERSION: VERSION, + atob: _atob, + atobPolyfill: atobPolyfill, + btoa: _btoa, + btoaPolyfill: btoaPolyfill, + fromBase64: decode, + toBase64: encode, + encode: encode, + encodeURI: encodeURI, + encodeURL: encodeURI, + utob: utob, + btou: btou, + decode: decode, + isValid: isValid, + fromUint8Array: fromUint8Array, + toUint8Array: toUint8Array, + extendString: extendString, + extendUint8Array: extendUint8Array, + extendBuiltins: extendBuiltins, +}; +// makecjs:CUT // +export { version }; +export { VERSION }; +export { _atob as atob }; +export { atobPolyfill }; +export { _btoa as btoa }; +export { btoaPolyfill }; +export { decode as fromBase64 }; +export { encode as toBase64 }; +export { utob }; +export { encode }; +export { encodeURI }; +export { encodeURI as encodeURL }; +export { btou }; +export { decode }; +export { isValid }; +export { fromUint8Array }; +export { toUint8Array }; +export { extendString }; +export { extendUint8Array }; +export { extendBuiltins }; +// and finally, +export { gBase64 as Base64 }; diff --git a/node_modules/js-base64/package.json b/node_modules/js-base64/package.json new file mode 100644 index 00000000..0475a56a --- /dev/null +++ b/node_modules/js-base64/package.json @@ -0,0 +1,70 @@ +{ + "_from": "js-base64@*", + "_id": "js-base64@3.6.1", + "_inBundle": false, + "_integrity": "sha512-Frdq2+tRRGLQUIQOgsIGSCd1VePCS2fsddTG5dTCqR0JHgltXWfsxnY0gIXPoMeRmdom6Oyq+UMOFg5suduOjQ==", + "_location": "/js-base64", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "js-base64@*", + "name": "js-base64", + "escapedName": "js-base64", + "rawSpec": "*", + "saveSpec": null, + "fetchSpec": "*" + }, + "_requiredBy": [ + "/@types/js-base64" + ], + "_resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.6.1.tgz", + "_shasum": "555aae398b74694b4037af1f8a5a6209d170efbe", + "_spec": "js-base64@*", + "_where": "/home/muhaddatha/Desktop/Work/NetPyNE-UI/node_modules/@types/js-base64", + "author": { + "name": "Dan Kogai" + }, + "bugs": { + "url": "https://github.com/dankogai/js-base64/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Yet another Base64 transcoder in pure-JS", + "devDependencies": { + "@types/node": "^14.0.26", + "esm": "^3.2.25", + "mocha": "^8.0.0", + "typescript": "^3.9.7" + }, + "exports": { + ".": { + "import": "./base64.mjs", + "require": "./base64.js" + }, + "./package.json": "./package.json" + }, + "files": [ + "base64.js", + "base64.mjs", + "base64.d.ts" + ], + "homepage": "https://github.com/dankogai/js-base64#readme", + "keywords": [ + "base64", + "binary" + ], + "license": "BSD-3-Clause", + "main": "base64.js", + "module": "base64.mjs", + "name": "js-base64", + "repository": { + "type": "git", + "url": "git+https://github.com/dankogai/js-base64.git" + }, + "scripts": { + "test": "make clean && make test" + }, + "types": "base64.d.ts", + "version": "3.6.1" +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..cfdf7274 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,21 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@types/js-base64": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/js-base64/-/js-base64-3.3.1.tgz", + "integrity": "sha512-Zw33oQNAvDdAN9b0IE5stH0y2MylYvtU7VVTKEJPxhyM2q57CVaNJhtJW258ah24NRtaiA23tptUmVn3dmTKpw==", + "dev": true, + "requires": { + "js-base64": "*" + } + }, + "js-base64": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.6.1.tgz", + "integrity": "sha512-Frdq2+tRRGLQUIQOgsIGSCd1VePCS2fsddTG5dTCqR0JHgltXWfsxnY0gIXPoMeRmdom6Oyq+UMOFg5suduOjQ==", + "dev": true + } + } +} From 2268f3044d3f8884264ece856d53cddad7ee1a38 Mon Sep 17 00:00:00 2001 From: Muhaddatha Date: Mon, 26 Jul 2021 10:35:28 -0400 Subject: [PATCH 22/43] #357 prevent netwoork creation or simulation --- .../components/instantiation/NetPyNEInstantiated.js | 2 +- webapp/components/topbar/menuConfiguration.js | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/webapp/components/instantiation/NetPyNEInstantiated.js b/webapp/components/instantiation/NetPyNEInstantiated.js index 1be0a4c5..67409d3c 100644 --- a/webapp/components/instantiation/NetPyNEInstantiated.js +++ b/webapp/components/instantiation/NetPyNEInstantiated.js @@ -72,7 +72,7 @@ export default class NetPyNEInstantiated extends React.Component { }; updateInstances () { - if (Instances.network) { + if (typeof Instances !== 'undefined' && Instances.network) { // update canvas only if there are instances to show this.canvasRef.current.engine.setLinesThreshold(25000); this.canvasRef.current.engine.updateSceneWithNewInstances( diff --git a/webapp/components/topbar/menuConfiguration.js b/webapp/components/topbar/menuConfiguration.js index fdf5a220..7af2c762 100644 --- a/webapp/components/topbar/menuConfiguration.js +++ b/webapp/components/topbar/menuConfiguration.js @@ -279,14 +279,7 @@ export default { }; export const getViewMenu = (props) => { - const instantiate = props.automaticInstantiation || props.modelState === MODEL_STATE.NOT_INSTANTIATED; const networkAction = () => { - if (instantiate && props.automaticSimulation) { - return createAndSimulateNetwork; - } - if (instantiate) { - return createNetwork; - } return showNetwork; }; @@ -335,7 +328,7 @@ export const getModelMenu = (props) => ( list: [ { label: 'Automatic creation', - icon: props.automaticInstantiation ? checkedIcon : 'fa', + icon: !props.automaticInstantiation ? checkedIcon : 'fa', action: { handlerAction: 'redux', parameters: [changeAutomaticInstantiation, true], @@ -343,7 +336,7 @@ export const getModelMenu = (props) => ( }, { label: 'Manual creation', - icon: !props.automaticInstantiation ? checkedIcon : 'fa', + icon: props.automaticInstantiation ? checkedIcon : 'fa', action: { handlerAction: 'redux', parameters: [changeAutomaticInstantiation, false], From db57b0bbab9c26575d8b931acdbb817e9204780c Mon Sep 17 00:00:00 2001 From: Lucas Rebscher Date: Tue, 27 Jul 2021 09:13:45 +0200 Subject: [PATCH 23/43] #369 Fix bug in getPlot --- netpyne_ui/netpyne_geppetto.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netpyne_ui/netpyne_geppetto.py b/netpyne_ui/netpyne_geppetto.py index a08ad310..09e67985 100644 --- a/netpyne_ui/netpyne_geppetto.py +++ b/netpyne_ui/netpyne_geppetto.py @@ -429,7 +429,7 @@ def getPlot(self, plotName, LFPflavour, theme='gui'): # This arg brings dark theme. But some plots are broken by it args['theme'] = theme - if plotName in ("iplotConn", "iplot2Dnet") and sim.net.allCells: + if plotName in ("iplotConn", "iplot2Dnet") and hasattr(sim, 'net') and sim.net.allCells: # To prevent unresponsive kernel, we don't show conns if they become too many num_conn = sum([len(cell.conns) for cell in sim.net.allCells if cell.conns]) if num_conn > NUM_CONN_LIMIT: From e96d1840d7170ee65e9509365ca51595e0e2acbf Mon Sep 17 00:00:00 2001 From: Muhaddatha Date: Tue, 27 Jul 2021 13:15:02 -0400 Subject: [PATCH 24/43] #357 remove node_modules files --- node_modules/@types/js-base64/LICENSE | 21 -- node_modules/@types/js-base64/README.md | 3 - node_modules/@types/js-base64/package.json | 40 --- node_modules/js-base64/LICENSE.md | 27 -- node_modules/js-base64/README.md | 175 ------------ node_modules/js-base64/base64.d.ts | 135 --------- node_modules/js-base64/base64.js | 317 --------------------- node_modules/js-base64/base64.mjs | 297 ------------------- node_modules/js-base64/package.json | 70 ----- 9 files changed, 1085 deletions(-) delete mode 100755 node_modules/@types/js-base64/LICENSE delete mode 100755 node_modules/@types/js-base64/README.md delete mode 100755 node_modules/@types/js-base64/package.json delete mode 100644 node_modules/js-base64/LICENSE.md delete mode 100644 node_modules/js-base64/README.md delete mode 100644 node_modules/js-base64/base64.d.ts delete mode 100644 node_modules/js-base64/base64.js delete mode 100644 node_modules/js-base64/base64.mjs delete mode 100644 node_modules/js-base64/package.json diff --git a/node_modules/@types/js-base64/LICENSE b/node_modules/@types/js-base64/LICENSE deleted file mode 100755 index 9e841e7a..00000000 --- a/node_modules/@types/js-base64/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - MIT License - - Copyright (c) Microsoft Corporation. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE diff --git a/node_modules/@types/js-base64/README.md b/node_modules/@types/js-base64/README.md deleted file mode 100755 index 0432cc5d..00000000 --- a/node_modules/@types/js-base64/README.md +++ /dev/null @@ -1,3 +0,0 @@ -This is a stub types definition for @types/js-base64 (https://github.com/dankogai/js-base64#readme). - -js-base64 provides its own type definitions, so you don't need @types/js-base64 installed! \ No newline at end of file diff --git a/node_modules/@types/js-base64/package.json b/node_modules/@types/js-base64/package.json deleted file mode 100755 index 9dadc2de..00000000 --- a/node_modules/@types/js-base64/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "_from": "@types/js-base64", - "_id": "@types/js-base64@3.3.1", - "_inBundle": false, - "_integrity": "sha512-Zw33oQNAvDdAN9b0IE5stH0y2MylYvtU7VVTKEJPxhyM2q57CVaNJhtJW258ah24NRtaiA23tptUmVn3dmTKpw==", - "_location": "/@types/js-base64", - "_phantomChildren": {}, - "_requested": { - "type": "tag", - "registry": true, - "raw": "@types/js-base64", - "name": "@types/js-base64", - "escapedName": "@types%2fjs-base64", - "scope": "@types", - "rawSpec": "", - "saveSpec": null, - "fetchSpec": "latest" - }, - "_requiredBy": [ - "#DEV:/", - "#USER" - ], - "_resolved": "https://registry.npmjs.org/@types/js-base64/-/js-base64-3.3.1.tgz", - "_shasum": "36c2d6dc126277ea28a4d0599d0cafbf547b51e6", - "_spec": "@types/js-base64", - "_where": "/home/muhaddatha/Desktop/Work/NetPyNE-UI", - "author": "", - "bundleDependencies": false, - "dependencies": { - "js-base64": "*" - }, - "deprecated": "This is a stub types definition. js-base64 provides its own type definitions, so you do not need this installed.", - "description": "Stub TypeScript definitions entry for js-base64, which provides its own types definitions", - "license": "MIT", - "main": "", - "name": "@types/js-base64", - "scripts": {}, - "typings": null, - "version": "3.3.1" -} diff --git a/node_modules/js-base64/LICENSE.md b/node_modules/js-base64/LICENSE.md deleted file mode 100644 index fd579a40..00000000 --- a/node_modules/js-base64/LICENSE.md +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2014, Dan Kogai -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of {{{project}}} nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/node_modules/js-base64/README.md b/node_modules/js-base64/README.md deleted file mode 100644 index d21f49ac..00000000 --- a/node_modules/js-base64/README.md +++ /dev/null @@ -1,175 +0,0 @@ -[![build status](https://secure.travis-ci.org/dankogai/js-base64.png)](http://travis-ci.org/dankogai/js-base64) - -# base64.js - -Yet another [Base64] transcoder. - -[Base64]: http://en.wikipedia.org/wiki/Base64 - -## HEADS UP - -In version 3.0 `js-base64` switch to ES2015 module so it is no longer compatible with legacy browsers like IE (see below). And since version 3.3 it is written in TypeScript. Now `base64.mjs` is compiled from `base64.ts` then `base64.js` is generated from `base64.mjs`. - -## Install - -```shell -$ npm install --save js-base64 -``` - -## Usage - -### In Browser - -Locally… - -```html - -``` - -… or Directly from CDN. In which case you don't even need to install. - -```html - -``` - -This good old way loads `Base64` in the global context (`window`). Though `Base64.noConflict()` is made available, you should consider using ES6 Module to avoid tainting `window`. - -### As an ES6 Module - -locally… - -```javascript -import { Base64 } from 'js-base64'; -``` - -```javascript -// or if you prefer no Base64 namespace -import { encode, decode } from 'js-base64'; -``` - -or even remotely. - -```html - -``` - -```html - -``` - -### node.js (commonjs) - -```javascript -const {Base64} = require('js-base64'); -``` - -Unlike the case above, the global context is no longer modified. - -You can also use [esm] to `import` instead of `require`. - -[esm]: https://github.com/standard-things/esm - -```javascript -require=require('esm')(module); -import {Base64} from 'js-base64'; -``` - -## SYNOPSIS - -```javascript -let latin = 'dankogai'; -let utf8 = '小飼弾' -let u8s = new Uint8Array([100,97,110,107,111,103,97,105]); -Base64.encode(latin); // ZGFua29nYWk= -Base64.encode(latin, true)); // ZGFua29nYWk skips padding -Base64.encodeURI(latin)); // ZGFua29nYWk -Base64.btoa(latin); // ZGFua29nYWk= -Base64.btoa(utf8); // raises exception -Base64.fromUint8Array(u8s); // ZGFua29nYWk= -Base64.fromUint8Array(u8s, true); // ZGFua29nYW which is URI safe -Base64.encode(utf8); // 5bCP6aO85by+ -Base64.encode(utf8, true) // 5bCP6aO85by- -Base64.encodeURI(utf8); // 5bCP6aO85by- -``` - -```javascript -Base64.decode( 'ZGFua29nYWk=');// dankogai -Base64.decode( 'ZGFua29nYWk'); // dankogai -Base64.atob( 'ZGFua29nYWk=');// dankogai -Base64.atob( '5bCP6aO85by+');// '小飼弾' which is nonsense -Base64.toUint8Array('ZGFua29nYWk=');// u8s above -Base64.decode( '5bCP6aO85by+');// 小飼弾 -// note .decodeURI() is unnecessary since it accepts both flavors -Base64.decode( '5bCP6aO85by-');// 小飼弾 -``` - -```javascript -Base64.isValid(0); // false: 0 is not string -Base64.isValid(''); // true: a valid Base64-encoded empty byte -Base64.isValid('ZA=='); // true: a valid Base64-encoded 'd' -Base64.isValid('Z A='); // true: whitespaces are okay -Base64.isValid('ZA'); // true: padding ='s can be omitted -Base64.isValid('++'); // true: can be non URL-safe -Base64.isValid('--'); // true: or URL-safe -Base64.isValid('+-'); // false: can't mix both -``` - -### Built-in Extensions - -By default `Base64` leaves built-in prototypes untouched. But you can extend them as below. - -```javascript -// you have to explicitly extend String.prototype -Base64.extendString(); -// once extended, you can do the following -'dankogai'.toBase64(); // ZGFua29nYWk= -'小飼弾'.toBase64(); // 5bCP6aO85by+ -'小飼弾'.toBase64(true); // 5bCP6aO85by- -'小飼弾'.toBase64URI(); // 5bCP6aO85by- ab alias of .toBase64(true) -'小飼弾'.toBase64URL(); // 5bCP6aO85by- an alias of .toBase64URI() -'ZGFua29nYWk='.fromBase64(); // dankogai -'5bCP6aO85by+'.fromBase64(); // 小飼弾 -'5bCP6aO85by-'.fromBase64(); // 小飼弾 -'5bCP6aO85by-'.toUint8Array();// u8s above -``` - -```javascript -// you have to explicitly extend String.prototype -Base64.extendString(); -// once extended, you can do the following -u8s.toBase64(); // 'ZGFua29nYWk=' -u8s.toBase64URI(); // 'ZGFua29nYWk' -u8s.toBase64URL(); // 'ZGFua29nYWk' an alias of .toBase64URI() -``` - -```javascript -// extend all at once -Base64.extendBuiltins() -``` - -## `.decode()` vs `.atob` (and `.encode()` vs `btoa()`) - -Suppose you have: - -``` -var pngBase64 = - "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="; -``` - -Which is a Base64-encoded 1x1 transparent PNG, **DO NOT USE** `Base64.decode(pngBase64)`.  Use `Base64.atob(pngBase64)` instead.  `Base64.decode()` decodes to UTF-8 string while `Base64.atob()` decodes to bytes, which is compatible to browser built-in `atob()` (Which is absent in node.js).  The same rule applies to the opposite direction. - -Or even better, `Base64.toUint8Array(pngBase64)`. - -### If you really, really need an ES5 version - -You can transpiles to an ES5 that runs on IE11. Do the following in your shell. - -```shell -$ make base64.es5.js -``` diff --git a/node_modules/js-base64/base64.d.ts b/node_modules/js-base64/base64.d.ts deleted file mode 100644 index 3c29c290..00000000 --- a/node_modules/js-base64/base64.d.ts +++ /dev/null @@ -1,135 +0,0 @@ -/** - * base64.ts - * - * Licensed under the BSD 3-Clause License. - * http://opensource.org/licenses/BSD-3-Clause - * - * References: - * http://en.wikipedia.org/wiki/Base64 - * - * @author Dan Kogai (https://github.com/dankogai) - */ -declare const version = "3.6.1"; -/** - * @deprecated use lowercase `version`. - */ -declare const VERSION = "3.6.1"; -/** - * polyfill version of `btoa` - */ -declare const btoaPolyfill: (bin: string) => string; -/** - * does what `window.btoa` of web browsers do. - * @param {String} bin binary string - * @returns {string} Base64-encoded string - */ -declare const _btoa: (bin: string) => string; -/** - * converts a Uint8Array to a Base64 string. - * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 §5 - * @returns {string} Base64 string - */ -declare const fromUint8Array: (u8a: Uint8Array, urlsafe?: boolean) => string; -/** - * @deprecated should have been internal use only. - * @param {string} src UTF-8 string - * @returns {string} UTF-16 string - */ -declare const utob: (u: string) => string; -/** - * converts a UTF-8-encoded string to a Base64 string. - * @param {boolean} [urlsafe] if `true` make the result URL-safe - * @returns {string} Base64 string - */ -declare const encode: (src: string, urlsafe?: boolean) => string; -/** - * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 §5. - * @returns {string} Base64 string - */ -declare const encodeURI: (src: string) => string; -/** - * @deprecated should have been internal use only. - * @param {string} src UTF-16 string - * @returns {string} UTF-8 string - */ -declare const btou: (b: string) => string; -/** - * polyfill version of `atob` - */ -declare const atobPolyfill: (asc: string) => string; -/** - * does what `window.atob` of web browsers do. - * @param {String} asc Base64-encoded string - * @returns {string} binary string - */ -declare const _atob: (asc: string) => string; -/** - * converts a Base64 string to a Uint8Array. - */ -declare const toUint8Array: (a: string) => Uint8Array; -/** - * converts a Base64 string to a UTF-8 string. - * @param {String} src Base64 string. Both normal and URL-safe are supported - * @returns {string} UTF-8 string - */ -declare const decode: (src: string) => string; -/** - * check if a value is a valid Base64 string - * @param {String} src a value to check - */ -declare const isValid: (src: any) => boolean; -/** - * extend String.prototype with relevant methods - */ -declare const extendString: () => void; -/** - * extend Uint8Array.prototype with relevant methods - */ -declare const extendUint8Array: () => void; -/** - * extend Builtin prototypes with relevant methods - */ -declare const extendBuiltins: () => void; -declare const gBase64: { - version: string; - VERSION: string; - atob: (asc: string) => string; - atobPolyfill: (asc: string) => string; - btoa: (bin: string) => string; - btoaPolyfill: (bin: string) => string; - fromBase64: (src: string) => string; - toBase64: (src: string, urlsafe?: boolean) => string; - encode: (src: string, urlsafe?: boolean) => string; - encodeURI: (src: string) => string; - encodeURL: (src: string) => string; - utob: (u: string) => string; - btou: (b: string) => string; - decode: (src: string) => string; - isValid: (src: any) => boolean; - fromUint8Array: (u8a: Uint8Array, urlsafe?: boolean) => string; - toUint8Array: (a: string) => Uint8Array; - extendString: () => void; - extendUint8Array: () => void; - extendBuiltins: () => void; -}; -export { version }; -export { VERSION }; -export { _atob as atob }; -export { atobPolyfill }; -export { _btoa as btoa }; -export { btoaPolyfill }; -export { decode as fromBase64 }; -export { encode as toBase64 }; -export { utob }; -export { encode }; -export { encodeURI }; -export { encodeURI as encodeURL }; -export { btou }; -export { decode }; -export { isValid }; -export { fromUint8Array }; -export { toUint8Array }; -export { extendString }; -export { extendUint8Array }; -export { extendBuiltins }; -export { gBase64 as Base64 }; diff --git a/node_modules/js-base64/base64.js b/node_modules/js-base64/base64.js deleted file mode 100644 index 8120c2de..00000000 --- a/node_modules/js-base64/base64.js +++ /dev/null @@ -1,317 +0,0 @@ - - -// -// THIS FILE IS AUTOMATICALLY GENERATED! DO NOT EDIT BY HAND! -// -;(function(global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' - ? module.exports = factory() - : typeof define === 'function' && define.amd - ? define(factory) : - // cf. https://github.com/dankogai/js-base64/issues/119 - (function() { - // existing version for noConflict() - const _Base64 = global.Base64; - const gBase64 = factory(); - gBase64.noConflict = () => { - global.Base64 = _Base64; - return gBase64; - }; - if (global.Meteor) { // Meteor.js - Base64 = gBase64; - } - global.Base64 = gBase64; - })(); -}((typeof self !== 'undefined' ? self - : typeof window !== 'undefined' ? window - : typeof global !== 'undefined' ? global - : this -), function() { - 'use strict'; - -/** - * base64.ts - * - * Licensed under the BSD 3-Clause License. - * http://opensource.org/licenses/BSD-3-Clause - * - * References: - * http://en.wikipedia.org/wiki/Base64 - * - * @author Dan Kogai (https://github.com/dankogai) - */ -const version = '3.6.1'; -/** - * @deprecated use lowercase `version`. - */ -const VERSION = version; -const _hasatob = typeof atob === 'function'; -const _hasbtoa = typeof btoa === 'function'; -const _hasBuffer = typeof Buffer === 'function'; -const _TD = typeof TextDecoder === 'function' ? new TextDecoder() : undefined; -const _TE = typeof TextEncoder === 'function' ? new TextEncoder() : undefined; -const b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; -const b64chs = [...b64ch]; -const b64tab = ((a) => { - let tab = {}; - a.forEach((c, i) => tab[c] = i); - return tab; -})(b64chs); -const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/; -const _fromCC = String.fromCharCode.bind(String); -const _U8Afrom = typeof Uint8Array.from === 'function' - ? Uint8Array.from.bind(Uint8Array) - : (it, fn = (x) => x) => new Uint8Array(Array.prototype.slice.call(it, 0).map(fn)); -const _mkUriSafe = (src) => src - .replace(/[+\/]/g, (m0) => m0 == '+' ? '-' : '_') - .replace(/=+$/m, ''); -const _tidyB64 = (s) => s.replace(/[^A-Za-z0-9\+\/]/g, ''); -/** - * polyfill version of `btoa` - */ -const btoaPolyfill = (bin) => { - // console.log('polyfilled'); - let u32, c0, c1, c2, asc = ''; - const pad = bin.length % 3; - for (let i = 0; i < bin.length;) { - if ((c0 = bin.charCodeAt(i++)) > 255 || - (c1 = bin.charCodeAt(i++)) > 255 || - (c2 = bin.charCodeAt(i++)) > 255) - throw new TypeError('invalid character found'); - u32 = (c0 << 16) | (c1 << 8) | c2; - asc += b64chs[u32 >> 18 & 63] - + b64chs[u32 >> 12 & 63] - + b64chs[u32 >> 6 & 63] - + b64chs[u32 & 63]; - } - return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc; -}; -/** - * does what `window.btoa` of web browsers do. - * @param {String} bin binary string - * @returns {string} Base64-encoded string - */ -const _btoa = _hasbtoa ? (bin) => btoa(bin) - : _hasBuffer ? (bin) => Buffer.from(bin, 'binary').toString('base64') - : btoaPolyfill; -const _fromUint8Array = _hasBuffer - ? (u8a) => Buffer.from(u8a).toString('base64') - : (u8a) => { - // cf. https://stackoverflow.com/questions/12710001/how-to-convert-uint8-array-to-base64-encoded-string/12713326#12713326 - const maxargs = 0x1000; - let strs = []; - for (let i = 0, l = u8a.length; i < l; i += maxargs) { - strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs))); - } - return _btoa(strs.join('')); - }; -/** - * converts a Uint8Array to a Base64 string. - * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 §5 - * @returns {string} Base64 string - */ -const fromUint8Array = (u8a, urlsafe = false) => urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a); -// This trick is found broken https://github.com/dankogai/js-base64/issues/130 -// const utob = (src: string) => unescape(encodeURIComponent(src)); -// reverting good old fationed regexp -const cb_utob = (c) => { - if (c.length < 2) { - var cc = c.charCodeAt(0); - return cc < 0x80 ? c - : cc < 0x800 ? (_fromCC(0xc0 | (cc >>> 6)) - + _fromCC(0x80 | (cc & 0x3f))) - : (_fromCC(0xe0 | ((cc >>> 12) & 0x0f)) - + _fromCC(0x80 | ((cc >>> 6) & 0x3f)) - + _fromCC(0x80 | (cc & 0x3f))); - } - else { - var cc = 0x10000 - + (c.charCodeAt(0) - 0xD800) * 0x400 - + (c.charCodeAt(1) - 0xDC00); - return (_fromCC(0xf0 | ((cc >>> 18) & 0x07)) - + _fromCC(0x80 | ((cc >>> 12) & 0x3f)) - + _fromCC(0x80 | ((cc >>> 6) & 0x3f)) - + _fromCC(0x80 | (cc & 0x3f))); - } -}; -const re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; -/** - * @deprecated should have been internal use only. - * @param {string} src UTF-8 string - * @returns {string} UTF-16 string - */ -const utob = (u) => u.replace(re_utob, cb_utob); -// -const _encode = _hasBuffer - ? (s) => Buffer.from(s, 'utf8').toString('base64') - : _TE - ? (s) => _fromUint8Array(_TE.encode(s)) - : (s) => _btoa(utob(s)); -/** - * converts a UTF-8-encoded string to a Base64 string. - * @param {boolean} [urlsafe] if `true` make the result URL-safe - * @returns {string} Base64 string - */ -const encode = (src, urlsafe = false) => urlsafe - ? _mkUriSafe(_encode(src)) - : _encode(src); -/** - * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 §5. - * @returns {string} Base64 string - */ -const encodeURI = (src) => encode(src, true); -// This trick is found broken https://github.com/dankogai/js-base64/issues/130 -// const btou = (src: string) => decodeURIComponent(escape(src)); -// reverting good old fationed regexp -const re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g; -const cb_btou = (cccc) => { - switch (cccc.length) { - case 4: - var cp = ((0x07 & cccc.charCodeAt(0)) << 18) - | ((0x3f & cccc.charCodeAt(1)) << 12) - | ((0x3f & cccc.charCodeAt(2)) << 6) - | (0x3f & cccc.charCodeAt(3)), offset = cp - 0x10000; - return (_fromCC((offset >>> 10) + 0xD800) - + _fromCC((offset & 0x3FF) + 0xDC00)); - case 3: - return _fromCC(((0x0f & cccc.charCodeAt(0)) << 12) - | ((0x3f & cccc.charCodeAt(1)) << 6) - | (0x3f & cccc.charCodeAt(2))); - default: - return _fromCC(((0x1f & cccc.charCodeAt(0)) << 6) - | (0x3f & cccc.charCodeAt(1))); - } -}; -/** - * @deprecated should have been internal use only. - * @param {string} src UTF-16 string - * @returns {string} UTF-8 string - */ -const btou = (b) => b.replace(re_btou, cb_btou); -/** - * polyfill version of `atob` - */ -const atobPolyfill = (asc) => { - // console.log('polyfilled'); - asc = asc.replace(/\s+/g, ''); - if (!b64re.test(asc)) - throw new TypeError('malformed base64.'); - asc += '=='.slice(2 - (asc.length & 3)); - let u24, bin = '', r1, r2; - for (let i = 0; i < asc.length;) { - u24 = b64tab[asc.charAt(i++)] << 18 - | b64tab[asc.charAt(i++)] << 12 - | (r1 = b64tab[asc.charAt(i++)]) << 6 - | (r2 = b64tab[asc.charAt(i++)]); - bin += r1 === 64 ? _fromCC(u24 >> 16 & 255) - : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255) - : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255); - } - return bin; -}; -/** - * does what `window.atob` of web browsers do. - * @param {String} asc Base64-encoded string - * @returns {string} binary string - */ -const _atob = _hasatob ? (asc) => atob(_tidyB64(asc)) - : _hasBuffer ? (asc) => Buffer.from(asc, 'base64').toString('binary') - : atobPolyfill; -// -const _toUint8Array = _hasBuffer - ? (a) => _U8Afrom(Buffer.from(a, 'base64')) - : (a) => _U8Afrom(_atob(a), c => c.charCodeAt(0)); -/** - * converts a Base64 string to a Uint8Array. - */ -const toUint8Array = (a) => _toUint8Array(_unURI(a)); -// -const _decode = _hasBuffer - ? (a) => Buffer.from(a, 'base64').toString('utf8') - : _TD - ? (a) => _TD.decode(_toUint8Array(a)) - : (a) => btou(_atob(a)); -const _unURI = (a) => _tidyB64(a.replace(/[-_]/g, (m0) => m0 == '-' ? '+' : '/')); -/** - * converts a Base64 string to a UTF-8 string. - * @param {String} src Base64 string. Both normal and URL-safe are supported - * @returns {string} UTF-8 string - */ -const decode = (src) => _decode(_unURI(src)); -/** - * check if a value is a valid Base64 string - * @param {String} src a value to check - */ -const isValid = (src) => { - if (typeof src !== 'string') - return false; - const s = src.replace(/\s+/g, '').replace(/=+$/, ''); - return !/[^\s0-9a-zA-Z\+/]/.test(s) || !/[^\s0-9a-zA-Z\-_]/.test(s); -}; -// -const _noEnum = (v) => { - return { - value: v, enumerable: false, writable: true, configurable: true - }; -}; -/** - * extend String.prototype with relevant methods - */ -const extendString = function () { - const _add = (name, body) => Object.defineProperty(String.prototype, name, _noEnum(body)); - _add('fromBase64', function () { return decode(this); }); - _add('toBase64', function (urlsafe) { return encode(this, urlsafe); }); - _add('toBase64URI', function () { return encode(this, true); }); - _add('toBase64URL', function () { return encode(this, true); }); - _add('toUint8Array', function () { return toUint8Array(this); }); -}; -/** - * extend Uint8Array.prototype with relevant methods - */ -const extendUint8Array = function () { - const _add = (name, body) => Object.defineProperty(Uint8Array.prototype, name, _noEnum(body)); - _add('toBase64', function (urlsafe) { return fromUint8Array(this, urlsafe); }); - _add('toBase64URI', function () { return fromUint8Array(this, true); }); - _add('toBase64URL', function () { return fromUint8Array(this, true); }); -}; -/** - * extend Builtin prototypes with relevant methods - */ -const extendBuiltins = () => { - extendString(); - extendUint8Array(); -}; -const gBase64 = { - version: version, - VERSION: VERSION, - atob: _atob, - atobPolyfill: atobPolyfill, - btoa: _btoa, - btoaPolyfill: btoaPolyfill, - fromBase64: decode, - toBase64: encode, - encode: encode, - encodeURI: encodeURI, - encodeURL: encodeURI, - utob: utob, - btou: btou, - decode: decode, - isValid: isValid, - fromUint8Array: fromUint8Array, - toUint8Array: toUint8Array, - extendString: extendString, - extendUint8Array: extendUint8Array, - extendBuiltins: extendBuiltins, -}; - - // - // export Base64 to the namespace - // - // ES5 is yet to have Object.assign() that may make transpilers unhappy. - // gBase64.Base64 = Object.assign({}, gBase64); - gBase64.Base64 = {}; - Object.keys(gBase64).forEach(k => gBase64.Base64[k] = gBase64[k]); - return gBase64; -})); - - diff --git a/node_modules/js-base64/base64.mjs b/node_modules/js-base64/base64.mjs deleted file mode 100644 index eb3e56cf..00000000 --- a/node_modules/js-base64/base64.mjs +++ /dev/null @@ -1,297 +0,0 @@ -/** - * base64.ts - * - * Licensed under the BSD 3-Clause License. - * http://opensource.org/licenses/BSD-3-Clause - * - * References: - * http://en.wikipedia.org/wiki/Base64 - * - * @author Dan Kogai (https://github.com/dankogai) - */ -const version = '3.6.1'; -/** - * @deprecated use lowercase `version`. - */ -const VERSION = version; -const _hasatob = typeof atob === 'function'; -const _hasbtoa = typeof btoa === 'function'; -const _hasBuffer = typeof Buffer === 'function'; -const _TD = typeof TextDecoder === 'function' ? new TextDecoder() : undefined; -const _TE = typeof TextEncoder === 'function' ? new TextEncoder() : undefined; -const b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; -const b64chs = [...b64ch]; -const b64tab = ((a) => { - let tab = {}; - a.forEach((c, i) => tab[c] = i); - return tab; -})(b64chs); -const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/; -const _fromCC = String.fromCharCode.bind(String); -const _U8Afrom = typeof Uint8Array.from === 'function' - ? Uint8Array.from.bind(Uint8Array) - : (it, fn = (x) => x) => new Uint8Array(Array.prototype.slice.call(it, 0).map(fn)); -const _mkUriSafe = (src) => src - .replace(/[+\/]/g, (m0) => m0 == '+' ? '-' : '_') - .replace(/=+$/m, ''); -const _tidyB64 = (s) => s.replace(/[^A-Za-z0-9\+\/]/g, ''); -/** - * polyfill version of `btoa` - */ -const btoaPolyfill = (bin) => { - // console.log('polyfilled'); - let u32, c0, c1, c2, asc = ''; - const pad = bin.length % 3; - for (let i = 0; i < bin.length;) { - if ((c0 = bin.charCodeAt(i++)) > 255 || - (c1 = bin.charCodeAt(i++)) > 255 || - (c2 = bin.charCodeAt(i++)) > 255) - throw new TypeError('invalid character found'); - u32 = (c0 << 16) | (c1 << 8) | c2; - asc += b64chs[u32 >> 18 & 63] - + b64chs[u32 >> 12 & 63] - + b64chs[u32 >> 6 & 63] - + b64chs[u32 & 63]; - } - return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc; -}; -/** - * does what `window.btoa` of web browsers do. - * @param {String} bin binary string - * @returns {string} Base64-encoded string - */ -const _btoa = _hasbtoa ? (bin) => btoa(bin) - : _hasBuffer ? (bin) => Buffer.from(bin, 'binary').toString('base64') - : btoaPolyfill; -const _fromUint8Array = _hasBuffer - ? (u8a) => Buffer.from(u8a).toString('base64') - : (u8a) => { - // cf. https://stackoverflow.com/questions/12710001/how-to-convert-uint8-array-to-base64-encoded-string/12713326#12713326 - const maxargs = 0x1000; - let strs = []; - for (let i = 0, l = u8a.length; i < l; i += maxargs) { - strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs))); - } - return _btoa(strs.join('')); - }; -/** - * converts a Uint8Array to a Base64 string. - * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 §5 - * @returns {string} Base64 string - */ -const fromUint8Array = (u8a, urlsafe = false) => urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a); -// This trick is found broken https://github.com/dankogai/js-base64/issues/130 -// const utob = (src: string) => unescape(encodeURIComponent(src)); -// reverting good old fationed regexp -const cb_utob = (c) => { - if (c.length < 2) { - var cc = c.charCodeAt(0); - return cc < 0x80 ? c - : cc < 0x800 ? (_fromCC(0xc0 | (cc >>> 6)) - + _fromCC(0x80 | (cc & 0x3f))) - : (_fromCC(0xe0 | ((cc >>> 12) & 0x0f)) - + _fromCC(0x80 | ((cc >>> 6) & 0x3f)) - + _fromCC(0x80 | (cc & 0x3f))); - } - else { - var cc = 0x10000 - + (c.charCodeAt(0) - 0xD800) * 0x400 - + (c.charCodeAt(1) - 0xDC00); - return (_fromCC(0xf0 | ((cc >>> 18) & 0x07)) - + _fromCC(0x80 | ((cc >>> 12) & 0x3f)) - + _fromCC(0x80 | ((cc >>> 6) & 0x3f)) - + _fromCC(0x80 | (cc & 0x3f))); - } -}; -const re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; -/** - * @deprecated should have been internal use only. - * @param {string} src UTF-8 string - * @returns {string} UTF-16 string - */ -const utob = (u) => u.replace(re_utob, cb_utob); -// -const _encode = _hasBuffer - ? (s) => Buffer.from(s, 'utf8').toString('base64') - : _TE - ? (s) => _fromUint8Array(_TE.encode(s)) - : (s) => _btoa(utob(s)); -/** - * converts a UTF-8-encoded string to a Base64 string. - * @param {boolean} [urlsafe] if `true` make the result URL-safe - * @returns {string} Base64 string - */ -const encode = (src, urlsafe = false) => urlsafe - ? _mkUriSafe(_encode(src)) - : _encode(src); -/** - * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 §5. - * @returns {string} Base64 string - */ -const encodeURI = (src) => encode(src, true); -// This trick is found broken https://github.com/dankogai/js-base64/issues/130 -// const btou = (src: string) => decodeURIComponent(escape(src)); -// reverting good old fationed regexp -const re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g; -const cb_btou = (cccc) => { - switch (cccc.length) { - case 4: - var cp = ((0x07 & cccc.charCodeAt(0)) << 18) - | ((0x3f & cccc.charCodeAt(1)) << 12) - | ((0x3f & cccc.charCodeAt(2)) << 6) - | (0x3f & cccc.charCodeAt(3)), offset = cp - 0x10000; - return (_fromCC((offset >>> 10) + 0xD800) - + _fromCC((offset & 0x3FF) + 0xDC00)); - case 3: - return _fromCC(((0x0f & cccc.charCodeAt(0)) << 12) - | ((0x3f & cccc.charCodeAt(1)) << 6) - | (0x3f & cccc.charCodeAt(2))); - default: - return _fromCC(((0x1f & cccc.charCodeAt(0)) << 6) - | (0x3f & cccc.charCodeAt(1))); - } -}; -/** - * @deprecated should have been internal use only. - * @param {string} src UTF-16 string - * @returns {string} UTF-8 string - */ -const btou = (b) => b.replace(re_btou, cb_btou); -/** - * polyfill version of `atob` - */ -const atobPolyfill = (asc) => { - // console.log('polyfilled'); - asc = asc.replace(/\s+/g, ''); - if (!b64re.test(asc)) - throw new TypeError('malformed base64.'); - asc += '=='.slice(2 - (asc.length & 3)); - let u24, bin = '', r1, r2; - for (let i = 0; i < asc.length;) { - u24 = b64tab[asc.charAt(i++)] << 18 - | b64tab[asc.charAt(i++)] << 12 - | (r1 = b64tab[asc.charAt(i++)]) << 6 - | (r2 = b64tab[asc.charAt(i++)]); - bin += r1 === 64 ? _fromCC(u24 >> 16 & 255) - : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255) - : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255); - } - return bin; -}; -/** - * does what `window.atob` of web browsers do. - * @param {String} asc Base64-encoded string - * @returns {string} binary string - */ -const _atob = _hasatob ? (asc) => atob(_tidyB64(asc)) - : _hasBuffer ? (asc) => Buffer.from(asc, 'base64').toString('binary') - : atobPolyfill; -// -const _toUint8Array = _hasBuffer - ? (a) => _U8Afrom(Buffer.from(a, 'base64')) - : (a) => _U8Afrom(_atob(a), c => c.charCodeAt(0)); -/** - * converts a Base64 string to a Uint8Array. - */ -const toUint8Array = (a) => _toUint8Array(_unURI(a)); -// -const _decode = _hasBuffer - ? (a) => Buffer.from(a, 'base64').toString('utf8') - : _TD - ? (a) => _TD.decode(_toUint8Array(a)) - : (a) => btou(_atob(a)); -const _unURI = (a) => _tidyB64(a.replace(/[-_]/g, (m0) => m0 == '-' ? '+' : '/')); -/** - * converts a Base64 string to a UTF-8 string. - * @param {String} src Base64 string. Both normal and URL-safe are supported - * @returns {string} UTF-8 string - */ -const decode = (src) => _decode(_unURI(src)); -/** - * check if a value is a valid Base64 string - * @param {String} src a value to check - */ -const isValid = (src) => { - if (typeof src !== 'string') - return false; - const s = src.replace(/\s+/g, '').replace(/=+$/, ''); - return !/[^\s0-9a-zA-Z\+/]/.test(s) || !/[^\s0-9a-zA-Z\-_]/.test(s); -}; -// -const _noEnum = (v) => { - return { - value: v, enumerable: false, writable: true, configurable: true - }; -}; -/** - * extend String.prototype with relevant methods - */ -const extendString = function () { - const _add = (name, body) => Object.defineProperty(String.prototype, name, _noEnum(body)); - _add('fromBase64', function () { return decode(this); }); - _add('toBase64', function (urlsafe) { return encode(this, urlsafe); }); - _add('toBase64URI', function () { return encode(this, true); }); - _add('toBase64URL', function () { return encode(this, true); }); - _add('toUint8Array', function () { return toUint8Array(this); }); -}; -/** - * extend Uint8Array.prototype with relevant methods - */ -const extendUint8Array = function () { - const _add = (name, body) => Object.defineProperty(Uint8Array.prototype, name, _noEnum(body)); - _add('toBase64', function (urlsafe) { return fromUint8Array(this, urlsafe); }); - _add('toBase64URI', function () { return fromUint8Array(this, true); }); - _add('toBase64URL', function () { return fromUint8Array(this, true); }); -}; -/** - * extend Builtin prototypes with relevant methods - */ -const extendBuiltins = () => { - extendString(); - extendUint8Array(); -}; -const gBase64 = { - version: version, - VERSION: VERSION, - atob: _atob, - atobPolyfill: atobPolyfill, - btoa: _btoa, - btoaPolyfill: btoaPolyfill, - fromBase64: decode, - toBase64: encode, - encode: encode, - encodeURI: encodeURI, - encodeURL: encodeURI, - utob: utob, - btou: btou, - decode: decode, - isValid: isValid, - fromUint8Array: fromUint8Array, - toUint8Array: toUint8Array, - extendString: extendString, - extendUint8Array: extendUint8Array, - extendBuiltins: extendBuiltins, -}; -// makecjs:CUT // -export { version }; -export { VERSION }; -export { _atob as atob }; -export { atobPolyfill }; -export { _btoa as btoa }; -export { btoaPolyfill }; -export { decode as fromBase64 }; -export { encode as toBase64 }; -export { utob }; -export { encode }; -export { encodeURI }; -export { encodeURI as encodeURL }; -export { btou }; -export { decode }; -export { isValid }; -export { fromUint8Array }; -export { toUint8Array }; -export { extendString }; -export { extendUint8Array }; -export { extendBuiltins }; -// and finally, -export { gBase64 as Base64 }; diff --git a/node_modules/js-base64/package.json b/node_modules/js-base64/package.json deleted file mode 100644 index 0475a56a..00000000 --- a/node_modules/js-base64/package.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "_from": "js-base64@*", - "_id": "js-base64@3.6.1", - "_inBundle": false, - "_integrity": "sha512-Frdq2+tRRGLQUIQOgsIGSCd1VePCS2fsddTG5dTCqR0JHgltXWfsxnY0gIXPoMeRmdom6Oyq+UMOFg5suduOjQ==", - "_location": "/js-base64", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "js-base64@*", - "name": "js-base64", - "escapedName": "js-base64", - "rawSpec": "*", - "saveSpec": null, - "fetchSpec": "*" - }, - "_requiredBy": [ - "/@types/js-base64" - ], - "_resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.6.1.tgz", - "_shasum": "555aae398b74694b4037af1f8a5a6209d170efbe", - "_spec": "js-base64@*", - "_where": "/home/muhaddatha/Desktop/Work/NetPyNE-UI/node_modules/@types/js-base64", - "author": { - "name": "Dan Kogai" - }, - "bugs": { - "url": "https://github.com/dankogai/js-base64/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "Yet another Base64 transcoder in pure-JS", - "devDependencies": { - "@types/node": "^14.0.26", - "esm": "^3.2.25", - "mocha": "^8.0.0", - "typescript": "^3.9.7" - }, - "exports": { - ".": { - "import": "./base64.mjs", - "require": "./base64.js" - }, - "./package.json": "./package.json" - }, - "files": [ - "base64.js", - "base64.mjs", - "base64.d.ts" - ], - "homepage": "https://github.com/dankogai/js-base64#readme", - "keywords": [ - "base64", - "binary" - ], - "license": "BSD-3-Clause", - "main": "base64.js", - "module": "base64.mjs", - "name": "js-base64", - "repository": { - "type": "git", - "url": "git+https://github.com/dankogai/js-base64.git" - }, - "scripts": { - "test": "make clean && make test" - }, - "types": "base64.d.ts", - "version": "3.6.1" -} From 9afabe61408b6b1813b77f44d1cd546f43af8ca1 Mon Sep 17 00:00:00 2001 From: Muhaddatha Date: Tue, 27 Jul 2021 13:15:59 -0400 Subject: [PATCH 25/43] #357 check for null variable --- webapp/components/instantiation/NetPyNEInstantiated.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/components/instantiation/NetPyNEInstantiated.js b/webapp/components/instantiation/NetPyNEInstantiated.js index 67409d3c..fd91c0d2 100644 --- a/webapp/components/instantiation/NetPyNEInstantiated.js +++ b/webapp/components/instantiation/NetPyNEInstantiated.js @@ -72,7 +72,7 @@ export default class NetPyNEInstantiated extends React.Component { }; updateInstances () { - if (typeof Instances !== 'undefined' && Instances.network) { + if (window.Instances != null && window.Instances.network) { // update canvas only if there are instances to show this.canvasRef.current.engine.setLinesThreshold(25000); this.canvasRef.current.engine.updateSceneWithNewInstances( From cbd774d04f63d53db8122a5d531d8440d7d13c97 Mon Sep 17 00:00:00 2001 From: Lucas Rebscher Date: Wed, 28 Jul 2021 09:38:38 +0200 Subject: [PATCH 26/43] #357 Disable automaticInstantiation by default --- webapp/components/topbar/menuConfiguration.js | 12 ++++++++++-- webapp/redux/reducers/general.js | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/webapp/components/topbar/menuConfiguration.js b/webapp/components/topbar/menuConfiguration.js index 7af2c762..24dd3ac6 100644 --- a/webapp/components/topbar/menuConfiguration.js +++ b/webapp/components/topbar/menuConfiguration.js @@ -280,6 +280,14 @@ export default { export const getViewMenu = (props) => { const networkAction = () => { + if (props.automaticInstantiation && props.automaticSimulation) { + return createAndSimulateNetwork; + } + + if (props.automaticInstantiation) { + return createNetwork; + } + return showNetwork; }; @@ -328,7 +336,7 @@ export const getModelMenu = (props) => ( list: [ { label: 'Automatic creation', - icon: !props.automaticInstantiation ? checkedIcon : 'fa', + icon: props.automaticInstantiation ? checkedIcon : 'fa', action: { handlerAction: 'redux', parameters: [changeAutomaticInstantiation, true], @@ -336,7 +344,7 @@ export const getModelMenu = (props) => ( }, { label: 'Manual creation', - icon: props.automaticInstantiation ? checkedIcon : 'fa', + icon: !props.automaticInstantiation ? checkedIcon : 'fa', action: { handlerAction: 'redux', parameters: [changeAutomaticInstantiation, false], diff --git a/webapp/redux/reducers/general.js b/webapp/redux/reducers/general.js index 04843381..7556fbfa 100644 --- a/webapp/redux/reducers/general.js +++ b/webapp/redux/reducers/general.js @@ -12,7 +12,7 @@ export const GENERAL_DEFAULT_STATE = { dialogTitle: '', dialogMessage: '', automaticSimulation: false, - automaticInstantiation: true, + automaticInstantiation: false, theme: 'gui', }; From b14fca7d47173870b1157b4fba85426f0b12e29b Mon Sep 17 00:00:00 2001 From: Muhaddatha Date: Wed, 28 Jul 2021 15:03:12 -0400 Subject: [PATCH 27/43] #191 use primary color for app versions --- webapp/components/general/Dialog.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/webapp/components/general/Dialog.js b/webapp/components/general/Dialog.js index 1db469b8..63e2f154 100644 --- a/webapp/components/general/Dialog.js +++ b/webapp/components/general/Dialog.js @@ -25,14 +25,14 @@ const AboutContent = withStyles(styles)(({ classes }) => ( - + NetPyNE-UI v0.7.0 - + NetPyNE v0.9.6 - - Neuron v8.0.0 + + NEURON v8.0.0 @@ -64,7 +64,7 @@ const AboutContent = withStyles(styles)(({ classes }) => ( - NetPyNE-UI is being developed in collaboration with: + NetPyNE-UI is being developed by the State Univeristy of New York Downstate (Dura-Bernal Lab) in collaboration with: Date: Wed, 28 Jul 2021 16:25:04 -0400 Subject: [PATCH 28/43] #374 remove explore view options --- webapp/components/topbar/menuConfiguration.js | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/webapp/components/topbar/menuConfiguration.js b/webapp/components/topbar/menuConfiguration.js index 24dd3ac6..74d17270 100644 --- a/webapp/components/topbar/menuConfiguration.js +++ b/webapp/components/topbar/menuConfiguration.js @@ -331,45 +331,6 @@ export const getModelMenu = (props) => ( parameters: [props.modelState === MODEL_STATE.NOT_INSTANTIATED ? createAndSimulateNetwork : simulateNetwork], }, }, - { - label: 'Explore view options', - list: [ - { - label: 'Automatic creation', - icon: props.automaticInstantiation ? checkedIcon : 'fa', - action: { - handlerAction: 'redux', - parameters: [changeAutomaticInstantiation, true], - }, - }, - { - label: 'Manual creation', - icon: !props.automaticInstantiation ? checkedIcon : 'fa', - action: { - handlerAction: 'redux', - parameters: [changeAutomaticInstantiation, false], - }, - }, - , - { - label: 'Automatic simulation', - icon: props.automaticSimulation ? checkedIcon : 'fa', - action: { - handlerAction: 'redux', - parameters: [changeAutomaticSimulation, true], - }, - }, - { - label: 'Manual simulation', - icon: !props.automaticSimulation ? checkedIcon : 'fa', - action: { - handlerAction: 'redux', - parameters: [changeAutomaticSimulation, false], - }, - }, - ], - }, - ] ); From b5f1a749ce9fcc0aa11c167fc7b2074930688f17 Mon Sep 17 00:00:00 2001 From: Muhaddatha Date: Wed, 28 Jul 2021 16:59:05 -0400 Subject: [PATCH 29/43] #347 add create and simulate option in model menu --- webapp/components/topbar/menuConfiguration.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/webapp/components/topbar/menuConfiguration.js b/webapp/components/topbar/menuConfiguration.js index 74d17270..7b41872a 100644 --- a/webapp/components/topbar/menuConfiguration.js +++ b/webapp/components/topbar/menuConfiguration.js @@ -331,6 +331,13 @@ export const getModelMenu = (props) => ( parameters: [props.modelState === MODEL_STATE.NOT_INSTANTIATED ? createAndSimulateNetwork : simulateNetwork], }, }, + { + label: TOPBAR_CONSTANTS.CREATE_AND_SIMULATE_NETWORK, + action: { + handlerAction: 'redux', + parameters: [createAndSimulateNetwork], + } + } ] ); From bd0e2d7b85eb15fc28c9dffc353caa11f3e06de5 Mon Sep 17 00:00:00 2001 From: Muhaddatha Date: Thu, 29 Jul 2021 11:03:43 -0400 Subject: [PATCH 30/43] #347 create split button component --- webapp/components/general/SplitButton.js | 75 ++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 webapp/components/general/SplitButton.js diff --git a/webapp/components/general/SplitButton.js b/webapp/components/general/SplitButton.js new file mode 100644 index 00000000..8e2b9318 --- /dev/null +++ b/webapp/components/general/SplitButton.js @@ -0,0 +1,75 @@ +import React from 'react'; +import Grid from '@material-ui/core/Grid'; +import Button from '@material-ui/core/Button'; +import ButtonGroup from '@material-ui/core/ButtonGroup'; +import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown'; +import ClickAwayListener from '@material-ui/core/ClickAwayListener'; +import Grow from '@material-ui/core/Grow'; +import Paper from '@material-ui/core/Paper'; +import Popper from '@material-ui/core/Popper'; +import MenuItem from '@material-ui/core/MenuItem'; +import MenuList from '@material-ui/core/MenuList'; + +export default function SplitButton(props) { + const { options, handleClick, icon } = props; + const [open, setOpen] = React.useState(false); + const anchorRef = React.useRef(null); + const [selectedIndex, setSelectedIndex] = React.useState(0); + + const handleItemClick = (event) => { + setSelectedIndex(0); + handleClick(options[0]); + } + + const handleMenuItemClick = (index) => { + setSelectedIndex(index); + setOpen(false); + handleClick(options[index]); + } + + const handleToggle = () => { + setOpen((prevOpen) => !prevOpen); + } + + const handleClose = (event) => { + if (anchorRef.current && anchorRef.current.contains(event.target)) { + return; + } + setOpen(false); + } + + return( + + + + + + + + {({TransitionProps, placement}) => ( + + + + + {options.map((option, index) => + ( {setSelectedIndex(index); handleMenuItemClick(index)}}> + {option} + + ))} + + + + + )} + + + + ); +} \ No newline at end of file From dd531dc83c8e9188f62a80fd78c4ed4b3651fb80 Mon Sep 17 00:00:00 2001 From: Muhaddatha Date: Thu, 29 Jul 2021 11:04:13 -0400 Subject: [PATCH 31/43] #347 use split button in top bar component --- webapp/components/topbar/SwitchPageButton.js | 48 +++++++------------- 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/webapp/components/topbar/SwitchPageButton.js b/webapp/components/topbar/SwitchPageButton.js index 46a54945..2ceef5e9 100644 --- a/webapp/components/topbar/SwitchPageButton.js +++ b/webapp/components/topbar/SwitchPageButton.js @@ -1,11 +1,10 @@ import React, { Component } from 'react'; import { withStyles } from '@material-ui/core/styles'; -import Button from '@material-ui/core/Button'; -import IconButton from '@material-ui/core/IconButton'; import { Tooltip } from 'netpyne/components'; import Icon from '../general/NetPyNEIcons'; import { TOPBAR_CONSTANTS, MODEL_STATE } from '../../constants'; +import SplitButton from '../general/SplitButton'; const styles = ({ palette, @@ -24,15 +23,21 @@ const styles = ({ icon: { color: palette.common.white }, }); +const editOptions = ["Create network", "Create and simulate", "Simulate"]; +const exploreOptions = ["Simulate", "Back to edit"]; + class SwitchPageButton extends Component { constructor (props) { super(props); this.handleClick = this.handleClick.bind(this); } - handleClick = (event) => { + handleClick = (selectedOption) => { const instantiate = this.props.automaticInstantiation || this.props.modelState === MODEL_STATE.NOT_INSTANTIATED; - if (!this.props.editModelPage) { + if(selectedOption === editOptions[2]){ + this.props.simulateNetwork(); + } + else if (!this.props.editModelPage) { this.props.switchToEditModelPage(); } else if (instantiate && this.props.automaticSimulation) { this.props.createAndSimulateNetwork(); @@ -71,41 +76,20 @@ class SwitchPageButton extends Component { const disableSimulate = modelState === MODEL_STATE.SIMULATED; return (
- { - editModelPage ? null - - : ( + {editModelPage ? + this.handleClick(selectedOption)}/> : + this.handleClick(selectedOption)} icon={<> - - simulateNetwork()} - disabled={disableSimulate} - style={{ opacity: disableSimulate ? 0.5 : 1 }} - > - - - + + - ) + } + /> } - -
); } From 28e89753268b8bc4c147f1c0a751fed90cf8c865 Mon Sep 17 00:00:00 2001 From: Muhaddatha Date: Thu, 29 Jul 2021 11:26:03 -0400 Subject: [PATCH 32/43] #191 add links to about box --- webapp/components/general/Dialog.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/webapp/components/general/Dialog.js b/webapp/components/general/Dialog.js index 63e2f154..66378389 100644 --- a/webapp/components/general/Dialog.js +++ b/webapp/components/general/Dialog.js @@ -25,15 +25,15 @@ const AboutContent = withStyles(styles)(({ classes }) => ( - + NetPyNE-UI v0.7.0 - - + + NetPyNE v0.9.6 - - + + NEURON v8.0.0 - + @@ -64,7 +64,8 @@ const AboutContent = withStyles(styles)(({ classes }) => ( - NetPyNE-UI is being developed by the State Univeristy of New York Downstate (Dura-Bernal Lab) in collaboration with: + NetPyNE-UI is being developed by the State Univeristy of New York Downstate (Dura-Bernal Lab) + in collaboration with: Date: Mon, 2 Aug 2021 10:47:49 -0400 Subject: [PATCH 33/43] #347 linting fix + add 'back to edit' button --- webapp/components/general/SplitButton.js | 126 ++++++++++-------- webapp/components/topbar/SwitchPageButton.js | 55 +++++--- webapp/components/topbar/menuConfiguration.js | 4 +- 3 files changed, 107 insertions(+), 78 deletions(-) diff --git a/webapp/components/general/SplitButton.js b/webapp/components/general/SplitButton.js index 8e2b9318..83283d61 100644 --- a/webapp/components/general/SplitButton.js +++ b/webapp/components/general/SplitButton.js @@ -10,66 +10,78 @@ import Popper from '@material-ui/core/Popper'; import MenuItem from '@material-ui/core/MenuItem'; import MenuList from '@material-ui/core/MenuList'; -export default function SplitButton(props) { - const { options, handleClick, icon } = props; - const [open, setOpen] = React.useState(false); - const anchorRef = React.useRef(null); - const [selectedIndex, setSelectedIndex] = React.useState(0); +export default function SplitButton (props) { + const { options, handleClick, icon } = props; + const [open, setOpen] = React.useState(false); + const anchorRef = React.useRef(null); + const [selectedIndex, setSelectedIndex] = React.useState(0); - const handleItemClick = (event) => { - setSelectedIndex(0); - handleClick(options[0]); - } + const handleItemClick = (event) => { + setSelectedIndex(0); + handleClick(options[0]); + }; - const handleMenuItemClick = (index) => { - setSelectedIndex(index); - setOpen(false); - handleClick(options[index]); - } + const handleMenuItemClick = (index) => { + setSelectedIndex(index); + setOpen(false); + handleClick(options[index]); + }; - const handleToggle = () => { - setOpen((prevOpen) => !prevOpen); - } + const handleToggle = () => { + setOpen((prevOpen) => !prevOpen); + }; - const handleClose = (event) => { - if (anchorRef.current && anchorRef.current.contains(event.target)) { - return; - } - setOpen(false); + const handleClose = (event) => { + if (anchorRef.current && anchorRef.current.contains(event.target)) { + return; } + setOpen(false); + }; - return( - - - - - - - - {({TransitionProps, placement}) => ( - - - - - {options.map((option, index) => - ( {setSelectedIndex(index); handleMenuItemClick(index)}}> - {option} - - ))} - - - - - )} - - - - ); -} \ No newline at end of file + return ( + + + + + + + + {({ TransitionProps, placement }) => ( + + + + + {options.map((option, index) => ( + { + setSelectedIndex(index); handleMenuItemClick(index); + }} + > + {option} + + ))} + + + + + )} + + + + ); +} diff --git a/webapp/components/topbar/SwitchPageButton.js b/webapp/components/topbar/SwitchPageButton.js index 2ceef5e9..3e47bb89 100644 --- a/webapp/components/topbar/SwitchPageButton.js +++ b/webapp/components/topbar/SwitchPageButton.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import { withStyles } from '@material-ui/core/styles'; +import Button from '@material-ui/core/Button'; import { Tooltip } from 'netpyne/components'; import Icon from '../general/NetPyNEIcons'; import { TOPBAR_CONSTANTS, MODEL_STATE } from '../../constants'; @@ -12,7 +13,9 @@ const styles = ({ spacing, typography, }) => ({ - container: {}, + container: { + display: 'flex', + }, button: { textTransform: 'uppercase', letterSpacing: 2, @@ -23,8 +26,8 @@ const styles = ({ icon: { color: palette.common.white }, }); -const editOptions = ["Create network", "Create and simulate", "Simulate"]; -const exploreOptions = ["Simulate", "Back to edit"]; +const editOptions = ['Create network', 'Create and simulate', 'Simulate']; +const exploreOptions = ['Simulate', 'Back to edit']; class SwitchPageButton extends Component { constructor (props) { @@ -34,10 +37,9 @@ class SwitchPageButton extends Component { handleClick = (selectedOption) => { const instantiate = this.props.automaticInstantiation || this.props.modelState === MODEL_STATE.NOT_INSTANTIATED; - if(selectedOption === editOptions[2]){ + if (selectedOption === editOptions[2]) { this.props.simulateNetwork(); - } - else if (!this.props.editModelPage) { + } else if (!this.props.editModelPage) { this.props.switchToEditModelPage(); } else if (instantiate && this.props.automaticSimulation) { this.props.createAndSimulateNetwork(); @@ -76,20 +78,35 @@ class SwitchPageButton extends Component { const disableSimulate = modelState === MODEL_STATE.SIMULATED; return (
- {editModelPage ? - this.handleClick(selectedOption)}/> : - this.handleClick(selectedOption)} icon={<> - this.handleClick(selectedOption)} /> + : ( + <> + this.handleClick(selectedOption)} + icon={( + <> + + + + + + + )} + /> + + + )}
); } diff --git a/webapp/components/topbar/menuConfiguration.js b/webapp/components/topbar/menuConfiguration.js index 7b41872a..2ab0c0f8 100644 --- a/webapp/components/topbar/menuConfiguration.js +++ b/webapp/components/topbar/menuConfiguration.js @@ -336,8 +336,8 @@ export const getModelMenu = (props) => ( action: { handlerAction: 'redux', parameters: [createAndSimulateNetwork], - } - } + }, + }, ] ); From 14ab223e7c041cfa407458eead849e1ade58a091 Mon Sep 17 00:00:00 2001 From: Muhaddatha Date: Mon, 2 Aug 2021 12:53:31 -0400 Subject: [PATCH 34/43] #347 small fixes, style simulate button --- webapp/components/general/SplitButton.js | 19 ++++++- webapp/components/topbar/SwitchPageButton.js | 58 +++++++++++--------- webapp/constants.js | 2 +- 3 files changed, 49 insertions(+), 30 deletions(-) diff --git a/webapp/components/general/SplitButton.js b/webapp/components/general/SplitButton.js index 83283d61..645b20b7 100644 --- a/webapp/components/general/SplitButton.js +++ b/webapp/components/general/SplitButton.js @@ -9,6 +9,7 @@ import Paper from '@material-ui/core/Paper'; import Popper from '@material-ui/core/Popper'; import MenuItem from '@material-ui/core/MenuItem'; import MenuList from '@material-ui/core/MenuList'; +import { secondaryColor } from '../../theme'; export default function SplitButton (props) { const { options, handleClick, icon } = props; @@ -41,10 +42,22 @@ export default function SplitButton (props) { return ( - - this.handleClick(selectedOption)} icon={( - <> - - - - - - + + + )} /> - )}
diff --git a/webapp/constants.js b/webapp/constants.js index 6002c4c1..f7a9d740 100644 --- a/webapp/constants.js +++ b/webapp/constants.js @@ -59,7 +59,7 @@ export const TOPBAR_CONSTANTS = { CREATE_AND_SIMULATE_NETWORK: 'Create and simulate network', SIMULATE: 'Simulate network', EXPLORE_EXISTING_NETWORK: 'Explore model', - BACK_TO_EDITION: 'Back to edit', + BACK_TO_EDITION: 'BACK TO EDIT', NEW_PAGE: 'NEW_PAGE', }; From ae6bf802b828601bdbbc8c593e16de41e0a4e4fe Mon Sep 17 00:00:00 2001 From: Muhaddatha Date: Mon, 2 Aug 2021 13:12:20 -0400 Subject: [PATCH 35/43] #347 remove borders on simulate button --- webapp/components/general/SplitButton.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/webapp/components/general/SplitButton.js b/webapp/components/general/SplitButton.js index 645b20b7..0c5be4e5 100644 --- a/webapp/components/general/SplitButton.js +++ b/webapp/components/general/SplitButton.js @@ -9,7 +9,6 @@ import Paper from '@material-ui/core/Paper'; import Popper from '@material-ui/core/Popper'; import MenuItem from '@material-ui/core/MenuItem'; import MenuList from '@material-ui/core/MenuList'; -import { secondaryColor } from '../../theme'; export default function SplitButton (props) { const { options, handleClick, icon } = props; @@ -47,13 +46,6 @@ export default function SplitButton (props) { color="primary" ref={anchorRef} aria-label="split button" - style={{ - borderStyle: 'outset', - borderTopColor: secondaryColor, - borderRightColor: secondaryColor, - borderLeftColor: 'grey', - borderBottomColor: 'black', - }} >