From 045adba80d8d367d1b6e676e6500aea10c3db624 Mon Sep 17 00:00:00 2001
From: SheetJS <dev@sheetjs.com>
Date: Sun, 21 Aug 2022 20:51:51 -0400
Subject: [PATCH] parse ZIP64 length (fixes #2766 h/t @silvialeung)

---
 bits/18_cfb.js                                |  24 +-
 demos/README.md                               |  19 +-
 demos/angular2/.angular-cli.json              |  23 --
 demos/angular2/.eslintrc                      |   6 -
 demos/angular2/.gitattributes                 |   1 -
 demos/angular2/.gitignore                     |   8 -
 demos/angular2/Makefile                       |  34 ---
 demos/angular2/README.md                      | 147 +----------
 demos/angular2/ionic-app.module.ts            |  22 --
 demos/angular2/ionic.sh                       |  16 --
 demos/angular2/ionic.ts                       | 126 ---------
 demos/angular2/package.json                   |  39 ---
 demos/angular2/screen.png                     | Bin 95983 -> 0 bytes
 demos/angular2/src/app/app.module.ts          |  28 --
 demos/angular2/src/app/sheetjs.component.ts   |  64 -----
 .../src/environments/environment.prod.ts      |   3 -
 .../angular2/src/environments/environment.ts  |   3 -
 demos/angular2/src/index.html                 |  30 ---
 demos/angular2/src/main.ts                    |   3 -
 demos/angular2/src/styles.css                 |   1 -
 demos/angular2/src/tsconfig.app.json          |   9 -
 demos/angular2/tsconfig.json                  |  20 --
 demos/angular2/versions/angular.json-ng10     | 125 ---------
 demos/angular2/versions/angular.json-ng11     | 124 ---------
 demos/angular2/versions/angular.json-ng12     | 106 --------
 demos/angular2/versions/angular.json-ng13     | 106 --------
 demos/angular2/versions/angular.json-ng6      | 127 ---------
 demos/angular2/versions/angular.json-ng7      | 136 ----------
 demos/angular2/versions/angular.json-ng8      | 126 ---------
 demos/angular2/versions/angular.json-ng9      | 125 ---------
 demos/angular2/versions/package.json-ng10     |  39 ---
 demos/angular2/versions/package.json-ng11     |  39 ---
 demos/angular2/versions/package.json-ng12     |  39 ---
 demos/angular2/versions/package.json-ng13     |  39 ---
 demos/angular2/versions/package.json-ng2      |  37 ---
 demos/angular2/versions/package.json-ng4      |  38 ---
 demos/angular2/versions/package.json-ng5      |  38 ---
 demos/angular2/versions/package.json-ng6      |  39 ---
 demos/angular2/versions/package.json-ng7      |  39 ---
 demos/angular2/versions/package.json-ng8      |  39 ---
 demos/angular2/versions/package.json-ng9      |  39 ---
 demos/angular2/versions/polyfills.ts-ng10     |   1 -
 demos/angular2/versions/polyfills.ts-ng11     |   1 -
 demos/angular2/versions/polyfills.ts-ng12     |   1 -
 demos/angular2/versions/polyfills.ts-ng13     |   1 -
 demos/angular2/versions/polyfills.ts-ng2      |   3 -
 demos/angular2/versions/polyfills.ts-ng4      |   3 -
 demos/angular2/versions/polyfills.ts-ng5      |   3 -
 demos/angular2/versions/polyfills.ts-ng6      |   3 -
 demos/angular2/versions/polyfills.ts-ng7      |   3 -
 demos/angular2/versions/polyfills.ts-ng8      |   1 -
 demos/angular2/versions/polyfills.ts-ng9      |   1 -
 .../angular2/versions/tsconfig.app.json-ng10  |  14 -
 .../angular2/versions/tsconfig.app.json-ng11  |  14 -
 .../angular2/versions/tsconfig.app.json-ng12  |  14 -
 .../angular2/versions/tsconfig.app.json-ng13  |  14 -
 demos/angular2/versions/tsconfig.app.json-ng8 |  18 --
 demos/angular2/versions/tsconfig.app.json-ng9 |  14 -
 demos/function/.eslintrc                      |   7 -
 demos/function/AzureHTTPTrigger/function.json |  17 --
 demos/function/AzureHTTPTrigger/index.js      |  44 ----
 demos/function/Firebase/.gitignore            |  65 -----
 demos/function/Firebase/firebase.json         |   1 -
 demos/function/Firebase/functions/.gitignore  |   1 -
 demos/function/Firebase/functions/index.js    |  39 ---
 .../function/Firebase/functions/package.json  |  24 --
 demos/function/LambdaProxy/index.js           |  40 ---
 demos/function/LambdaProxy/template.yaml      |  18 --
 demos/function/Makefile                       |  28 --
 demos/function/README.md                      | 112 +-------
 demos/function/host.json                      |   3 -
 demos/function/local.settings.json            |  11 -
 demos/react/.gitignore                        |   4 -
 demos/react/Makefile                          |  24 --
 demos/react/NOTES.md                          |  22 --
 demos/react/README.md                         | 154 +----------
 demos/react/index.html                        |  29 ---
 demos/react/modify/.gitignore                 |  23 --
 demos/react/modify/README.md                  |  10 -
 demos/react/modify/package.json               |  36 ---
 demos/react/modify/public/index.html          |  43 ----
 demos/react/modify/src/components/App.tsx     | 107 --------
 demos/react/modify/src/index.tsx              |  12 -
 demos/react/modify/src/react-app-env.d.ts     |   1 -
 demos/react/modify/src/styles/App.css         |  14 -
 demos/react/modify/src/styles/index.css       |   8 -
 demos/react/modify/tsconfig.json              |  26 --
 demos/react/nexthdr.js                        |   3 -
 demos/react/pages/getServerSideProps.js       |  32 ---
 demos/react/pages/getStaticPaths.js           |  38 ---
 demos/react/pages/getStaticProps.js           |  32 ---
 demos/react/pages/index.js                    |  24 --
 demos/react/pages/sheets/[id].js              |  51 ----
 demos/react/public/sheetjs.xlsx               | Bin 10328 -> 0 bytes
 demos/react/sheetjs.js                        | 144 -----------
 demos/server/.gitignore                       |   2 -
 demos/server/Makefile                         |  29 ---
 demos/server/README.md                        | 207 +--------------
 demos/server/_cors.js                         |   4 -
 demos/server/_logit.js                        |   7 -
 demos/server/_request.js                      |   9 -
 demos/server/drash.ts                         |  68 -----
 demos/server/express.js                       |  65 -----
 demos/server/hapi.js                          |  67 -----
 demos/server/koa.js                           |  79 ------
 demos/server/koasub.js                        |  39 ---
 demos/server/nest.sh                          |  24 --
 demos/server/nodejs.js                        |  84 ------
 demos/server/sheetjs.controller.ts            |  19 --
 demos/server/sheetjs.csv                      |  19 --
 demos/server/sheetjs.module.ts                |  13 -
 demos/server/worker.js                        |  22 --
 demos/vue/Makefile                            |   3 -
 demos/vue/README.md                           |  83 +-----
 demos/vue/SheetJS-vue.js                      |  68 -----
 demos/vue/index2.html                         |  63 -----
 demos/vue/index3.html                         |  63 -----
 demos/vue/modify/.gitignore                   |  24 --
 demos/vue/modify/README.md                    |  10 -
 demos/vue/modify/index.html                   |  13 -
 demos/vue/modify/package.json                 |  21 --
 demos/vue/modify/src/App.vue                  | 241 ------------------
 demos/vue/modify/src/env.d.ts                 |   8 -
 demos/vue/modify/src/main.ts                  |   4 -
 demos/vue/modify/tsconfig.json                |  16 --
 demos/vue/modify/tsconfig.node.json           |   8 -
 demos/vue/modify/vite.config.ts               |   7 -
 demos/vue/shim.js                             |   1 -
 demos/vue/xlsx.full.min.js                    |   1 -
 demos/xspreadsheet/README.md                  |  60 +----
 demos/xspreadsheet/index.html                 | 135 ----------
 demos/xspreadsheet/shim.js                    |   1 -
 demos/xspreadsheet/xlsx.full.min.js           |   1 -
 demos/xspreadsheet/xlsxspread.js              |   2 +
 134 files changed, 65 insertions(+), 4907 deletions(-)
 delete mode 100644 demos/angular2/.angular-cli.json
 delete mode 100644 demos/angular2/.eslintrc
 delete mode 100644 demos/angular2/.gitattributes
 delete mode 100644 demos/angular2/.gitignore
 delete mode 100644 demos/angular2/Makefile
 delete mode 100644 demos/angular2/ionic-app.module.ts
 delete mode 100755 demos/angular2/ionic.sh
 delete mode 100644 demos/angular2/ionic.ts
 delete mode 100644 demos/angular2/package.json
 delete mode 100644 demos/angular2/screen.png
 delete mode 100644 demos/angular2/src/app/app.module.ts
 delete mode 100644 demos/angular2/src/app/sheetjs.component.ts
 delete mode 100644 demos/angular2/src/environments/environment.prod.ts
 delete mode 100644 demos/angular2/src/environments/environment.ts
 delete mode 100644 demos/angular2/src/index.html
 delete mode 100644 demos/angular2/src/main.ts
 delete mode 100644 demos/angular2/src/styles.css
 delete mode 100644 demos/angular2/src/tsconfig.app.json
 delete mode 100644 demos/angular2/tsconfig.json
 delete mode 100644 demos/angular2/versions/angular.json-ng10
 delete mode 100644 demos/angular2/versions/angular.json-ng11
 delete mode 100644 demos/angular2/versions/angular.json-ng12
 delete mode 100644 demos/angular2/versions/angular.json-ng13
 delete mode 100644 demos/angular2/versions/angular.json-ng6
 delete mode 100644 demos/angular2/versions/angular.json-ng7
 delete mode 100644 demos/angular2/versions/angular.json-ng8
 delete mode 100644 demos/angular2/versions/angular.json-ng9
 delete mode 100644 demos/angular2/versions/package.json-ng10
 delete mode 100644 demos/angular2/versions/package.json-ng11
 delete mode 100644 demos/angular2/versions/package.json-ng12
 delete mode 100644 demos/angular2/versions/package.json-ng13
 delete mode 100644 demos/angular2/versions/package.json-ng2
 delete mode 100644 demos/angular2/versions/package.json-ng4
 delete mode 100644 demos/angular2/versions/package.json-ng5
 delete mode 100644 demos/angular2/versions/package.json-ng6
 delete mode 100644 demos/angular2/versions/package.json-ng7
 delete mode 100644 demos/angular2/versions/package.json-ng8
 delete mode 100644 demos/angular2/versions/package.json-ng9
 delete mode 100644 demos/angular2/versions/polyfills.ts-ng10
 delete mode 100644 demos/angular2/versions/polyfills.ts-ng11
 delete mode 100644 demos/angular2/versions/polyfills.ts-ng12
 delete mode 100644 demos/angular2/versions/polyfills.ts-ng13
 delete mode 100644 demos/angular2/versions/polyfills.ts-ng2
 delete mode 100644 demos/angular2/versions/polyfills.ts-ng4
 delete mode 100644 demos/angular2/versions/polyfills.ts-ng5
 delete mode 100644 demos/angular2/versions/polyfills.ts-ng6
 delete mode 100644 demos/angular2/versions/polyfills.ts-ng7
 delete mode 100644 demos/angular2/versions/polyfills.ts-ng8
 delete mode 100644 demos/angular2/versions/polyfills.ts-ng9
 delete mode 100644 demos/angular2/versions/tsconfig.app.json-ng10
 delete mode 100644 demos/angular2/versions/tsconfig.app.json-ng11
 delete mode 100644 demos/angular2/versions/tsconfig.app.json-ng12
 delete mode 100644 demos/angular2/versions/tsconfig.app.json-ng13
 delete mode 100644 demos/angular2/versions/tsconfig.app.json-ng8
 delete mode 100644 demos/angular2/versions/tsconfig.app.json-ng9
 delete mode 100644 demos/function/.eslintrc
 delete mode 100644 demos/function/AzureHTTPTrigger/function.json
 delete mode 100644 demos/function/AzureHTTPTrigger/index.js
 delete mode 100644 demos/function/Firebase/.gitignore
 delete mode 100644 demos/function/Firebase/firebase.json
 delete mode 100644 demos/function/Firebase/functions/.gitignore
 delete mode 100644 demos/function/Firebase/functions/index.js
 delete mode 100644 demos/function/Firebase/functions/package.json
 delete mode 100644 demos/function/LambdaProxy/index.js
 delete mode 100644 demos/function/LambdaProxy/template.yaml
 delete mode 100644 demos/function/Makefile
 delete mode 100644 demos/function/host.json
 delete mode 100644 demos/function/local.settings.json
 delete mode 100644 demos/react/.gitignore
 delete mode 100644 demos/react/Makefile
 delete mode 100644 demos/react/NOTES.md
 delete mode 100644 demos/react/index.html
 delete mode 100644 demos/react/modify/.gitignore
 delete mode 100644 demos/react/modify/README.md
 delete mode 100644 demos/react/modify/package.json
 delete mode 100644 demos/react/modify/public/index.html
 delete mode 100644 demos/react/modify/src/components/App.tsx
 delete mode 100644 demos/react/modify/src/index.tsx
 delete mode 100644 demos/react/modify/src/react-app-env.d.ts
 delete mode 100644 demos/react/modify/src/styles/App.css
 delete mode 100644 demos/react/modify/src/styles/index.css
 delete mode 100644 demos/react/modify/tsconfig.json
 delete mode 100644 demos/react/nexthdr.js
 delete mode 100644 demos/react/pages/getServerSideProps.js
 delete mode 100644 demos/react/pages/getStaticPaths.js
 delete mode 100644 demos/react/pages/getStaticProps.js
 delete mode 100644 demos/react/pages/index.js
 delete mode 100644 demos/react/pages/sheets/[id].js
 delete mode 100644 demos/react/public/sheetjs.xlsx
 delete mode 100644 demos/react/sheetjs.js
 delete mode 100644 demos/server/.gitignore
 delete mode 100644 demos/server/Makefile
 delete mode 100644 demos/server/_cors.js
 delete mode 100644 demos/server/_logit.js
 delete mode 100644 demos/server/_request.js
 delete mode 100644 demos/server/drash.ts
 delete mode 100644 demos/server/express.js
 delete mode 100644 demos/server/hapi.js
 delete mode 100644 demos/server/koa.js
 delete mode 100644 demos/server/koasub.js
 delete mode 100755 demos/server/nest.sh
 delete mode 100644 demos/server/nodejs.js
 delete mode 100644 demos/server/sheetjs.controller.ts
 delete mode 100644 demos/server/sheetjs.csv
 delete mode 100644 demos/server/sheetjs.module.ts
 delete mode 100644 demos/server/worker.js
 delete mode 100644 demos/vue/Makefile
 delete mode 100644 demos/vue/SheetJS-vue.js
 delete mode 100644 demos/vue/index2.html
 delete mode 100644 demos/vue/index3.html
 delete mode 100644 demos/vue/modify/.gitignore
 delete mode 100644 demos/vue/modify/README.md
 delete mode 100644 demos/vue/modify/index.html
 delete mode 100644 demos/vue/modify/package.json
 delete mode 100644 demos/vue/modify/src/App.vue
 delete mode 100644 demos/vue/modify/src/env.d.ts
 delete mode 100644 demos/vue/modify/src/main.ts
 delete mode 100644 demos/vue/modify/tsconfig.json
 delete mode 100644 demos/vue/modify/tsconfig.node.json
 delete mode 100644 demos/vue/modify/vite.config.ts
 delete mode 120000 demos/vue/shim.js
 delete mode 120000 demos/vue/xlsx.full.min.js
 delete mode 100644 demos/xspreadsheet/index.html
 delete mode 120000 demos/xspreadsheet/shim.js
 delete mode 120000 demos/xspreadsheet/xlsx.full.min.js

diff --git a/bits/18_cfb.js b/bits/18_cfb.js
index 58dbe25..8ac3c6e 100644
--- a/bits/18_cfb.js
+++ b/bits/18_cfb.js
@@ -211,8 +211,15 @@ function parse_extra_field(blob/*:CFBlob*/)/*:any*/ {
 					if(flags & 4) p.ctime = blob.read_shift(4);
 				}
 				if(p.mtime) p.mt = new Date(p.mtime*1000);
-			}
-			break;
+			} break;
+			/* ZIP64 Extended Information Field */
+			case 0x0001: {
+				var sz1 = blob.read_shift(4), sz2 = blob.read_shift(4);
+				p.usz = (sz2 * Math.pow(2,32) + sz1);
+				sz1 = blob.read_shift(4); sz2 = blob.read_shift(4);
+				p.csz = (sz2 * Math.pow(2,32) + sz1);
+				// NOTE: volume fields are skipped
+			} break;
 		}
 		blob.l = tgt;
 		o[type] = p;
@@ -1401,6 +1408,11 @@ function parse_zip(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/
 
 		var L = blob.l;
 		blob.l = offset + 4;
+		/* ZIP64 lengths */
+		if(EF && EF[0x0001]) {
+			if((EF[0x0001]||{}).usz) usz = EF[0x0001].usz;
+			if((EF[0x0001]||{}).csz) csz = EF[0x0001].csz;
+		}
 		parse_local_file(blob, csz, usz, o, EF);
 		blob.l = L;
 	}
@@ -1430,7 +1442,13 @@ function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:C
 	if(efsz) {
 		var ef = parse_extra_field(/*::(*/blob.slice(blob.l, blob.l + efsz)/*:: :any)*/);
 		if((ef[0x5455]||{}).mt) date = ef[0x5455].mt;
-		if(((EF||{})[0x5455]||{}).mt) date = EF[0x5455].mt;
+		if((ef[0x0001]||{}).usz) _usz = ef[0x0001].usz;
+		if((ef[0x0001]||{}).csz) _csz = ef[0x0001].csz;
+		if(EF) {
+			if((EF[0x5455]||{}).mt) date = EF[0x5455].mt;
+			if((EF[0x0001]||{}).usz) _usz = ef[0x0001].usz;
+			if((EF[0x0001]||{}).csz) _csz = ef[0x0001].csz;
+		}
 	}
 	blob.l += efsz;
 
diff --git a/demos/README.md b/demos/README.md
index 98db244..e7df176 100644
--- a/demos/README.md
+++ b/demos/README.md
@@ -26,23 +26,23 @@ can be installed with Bash on Windows or with `cygwin`.
 - [`IndexedDB`](https://docs.sheetjs.com/docs/demos/database#indexeddb)
 
 **Frameworks**
+- [`Angular 2+ and Ionic`](https://docs.sheetjs.com/docs/demos/angular)
+- [`React`](https://docs.sheetjs.com/docs/demos/react)
+- [`VueJS`](https://docs.sheetjs.com/docs/demos/vue)
 - [`Angular.JS`](https://docs.sheetjs.com/docs/demos/legacy#angularjs)
-- [`Angular 2+ and Ionic`](angular2/)
 - [`Knockout`](https://docs.sheetjs.com/docs/demos/legacy#knockoutjs)
-- [`React and NextJS`](react/)
-- [`VueJS`](vue/)
 
 **Front-End UI Components**
 - [`canvas-datagrid`](https://docs.sheetjs.com/docs/demos/grid#canvas-datagrid)
-- [`x-spreadsheet`](xspreadsheet/)
-- [`react-data-grid`](react/modify/)
-- [`vue3-table-light`](vue/modify/)
+- [`x-spreadsheet`](https://docs.sheetjs.com/docs/demos/grid#x-spreadsheet)
+- [`react-data-grid`](https://docs.sheetjs.com/docs/demos/grid#react-data-grid)
+- [`vue3-table-lite`](https://docs.sheetjs.com/docs/demos/grid#vue3-table-lite)
 - [`angular-ui-grid`](https://docs.sheetjs.com/docs/demos/grid#angular-ui-grid)
 
 **Platforms and Integrations**
 - [`Command-Line Tools`](https://docs.sheetjs.com/docs/demos/cli)
 - [`iOS and Android Mobile Applications`](https://docs.sheetjs.com/docs/demos/mobile)
-- [`NodeJS Server-Side Processing`](server/)
+- [`NodeJS Server-Side Processing`](https://docs.sheetjs.com/docs/demos/server#nodejs)
 - [`Content Management and Static Sites`](https://docs.sheetjs.com/docs/demos/content)
 - [`Electron`](https://docs.sheetjs.com/docs/demos/desktop#electron)
 - [`NW.js`](https://docs.sheetjs.com/docs/demos/desktop#nwjs)
@@ -54,8 +54,9 @@ can be installed with Bash on Windows or with `cygwin`.
 - [`SalesForce Lightning Web Components`](https://docs.sheetjs.com/docs/demos/salesforce)
 - [`Excel JavaScript API`](https://docs.sheetjs.com/docs/demos/excel)
 - [`Headless Automation`](https://docs.sheetjs.com/docs/demos/headless)
-- [`Swift JSC and Other JavaScript Engines`](https://docs.sheetjs.com/docs/demos/engines)
-- [`"serverless" functions`](function/)
+- [`Other JavaScript Engines`](https://docs.sheetjs.com/docs/demos/engines)
+- [`Azure Functions and Storage`](https://docs.sheetjs.com/docs/demos/azure)
+- [`Amazon Web Services`](https://docs.sheetjs.com/docs/demos/aws)
 - [`Databases and Structured Data Stores`](https://docs.sheetjs.com/docs/demos/database)
 - [`NoSQL and Unstructured Data Stores`](https://docs.sheetjs.com/docs/demos/nosql)
 - [`Legacy Internet Explorer`](https://docs.sheetjs.com/docs/demos/legacy#internet-explorer)
diff --git a/demos/angular2/.angular-cli.json b/demos/angular2/.angular-cli.json
deleted file mode 100644
index 35d76d7..0000000
--- a/demos/angular2/.angular-cli.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
-  "project": {
-    "name": "angular2"
-  },
-  "apps": [
-    {
-      "root": "src",
-      "outDir": "dist",
-      "index": "index.html",
-      "main": "main.ts",
-      "polyfills": "polyfills.ts",
-      "test": "test.ts",
-      "tsconfig": "tsconfig.app.json",
-      "prefix": "app",
-      "scripts": []
-    }
-  ],
-  "defaults": {
-    "styleExt": "css",
-    "component": {}
-  }
-}
diff --git a/demos/angular2/.eslintrc b/demos/angular2/.eslintrc
deleted file mode 100644
index 31ada8c..0000000
--- a/demos/angular2/.eslintrc
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-	"parser": "@typescript-eslint/parser",
-	"extends": [
-		"eslint:recommended"
-	]
-}
diff --git a/demos/angular2/.gitattributes b/demos/angular2/.gitattributes
deleted file mode 100644
index 80fa1f4..0000000
--- a/demos/angular2/.gitattributes
+++ /dev/null
@@ -1 +0,0 @@
-*.*-ng*           linguist-generated=true binary
diff --git a/demos/angular2/.gitignore b/demos/angular2/.gitignore
deleted file mode 100644
index f1fd2db..0000000
--- a/demos/angular2/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-dist
-hooks
-SheetJSIonic
-SheetJSNS
-angular.json
-tsconfig.app.json
-src/polyfills.ts
-.angular
diff --git a/demos/angular2/Makefile b/demos/angular2/Makefile
deleted file mode 100644
index b37e495..0000000
--- a/demos/angular2/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-.PHONY: ng2 ng4 ng5 ng6 ng7 ng8 ng9 ng10 ng11 ng12 ng13
-ng2 ng4 ng5 ng6 ng7 ng8 ng9 ng10 ng11 ng12 ng13:
-	rm -f angular.json tsconfig.app.json src/polyfills.ts
-	cp versions/package.json-$@ package.json
-	if [ -e versions/angular.json-$@ ]; then cp versions/angular.json-$@ angular.json; fi
-	if [ -e versions/tsconfig.app.json-$@ ]; then cp versions/tsconfig.app.json-$@ tsconfig.app.json; fi
-	if [ -e versions/polyfills.ts-$@ ]; then cp versions/polyfills.ts-$@ src/polyfills.ts; fi
-	rm -rf node_modules
-	if [ ! -e node_modules ]; then mkdir node_modules; fi
-	npm install
-	if [ ! -e node_modules/xlsx ]; then cd node_modules; ln -s ../../../ xlsx; cd -; fi
-	npm run build
-
-.PHONY: refresh
-refresh: ## refresh the `xlsx` symlink to force angular to rebuild
-	rm -rf .angular/
-	rm -f node_modules/xlsx
-	cd node_modules; ln -s ../../../ xlsx; cd -
-	touch node_modules/xlsx
-
-.PHONY: all
-all:
-	for i in 2 4 5 6 7 8 9 10 11 12 13; do make ng$$i; done
-
-.PHONY: ionic
-ionic:
-	bash ./ionic.sh
-
-.PHONY: ios android browser
-ios browser: ionic
-	cd SheetJSIonic; ionic cordova emulate $@ </dev/null; cd -
-android: ionic
-	cd SheetJSIonic; ionic cordova prepare $@ </dev/null; ionic cordova emulate $@ </dev/null; cd -
-
diff --git a/demos/angular2/README.md b/demos/angular2/README.md
index 746d448..68bd4b8 100644
--- a/demos/angular2/README.md
+++ b/demos/angular2/README.md
@@ -1,148 +1,11 @@
 # Angular 2+
 
-The ESM build can be imported directly from TS code with:
+[The new demo](https://docs.sheetjs.com/docs/demos/angular) has an updated
+exposition for legacy and modern deployments alike.
 
-```typescript
-import { read, utils, writeFileXLSX } from 'xlsx';
-```
+The ecosystem demos were grouped by type in the new demo site:
 
-This demo uses an array of arrays (type `Array<Array<any>>`) as the core state.
-The component template includes a file input element, a table that updates with
-the data, and a button to export the data.
-
-Other scripts in this demo show:
-- `ionic` deployment for iOS, android, and browser
-- `nativescript` deployment for iOS and android
-
-## Array of Arrays
-
-`Array<Array<any>>` neatly maps to a table with `ngFor`:
-
-```html
-<table class="sjs-table">
-  <tr *ngFor="let row of data">
-    <td *ngFor="let val of row">
-      {{val}}
-    </td>
-  </tr>
-</table>
-```
-
-The `aoa_to_sheet` utility function returns a worksheet.  Exporting is simple:
-
-```typescript
-/* generate worksheet */
-const ws: XLSX.WorkSheet = XLSX.utils.aoa_to_sheet(this.data);
-
-/* generate workbook and add the worksheet */
-const wb: XLSX.WorkBook = XLSX.utils.book_new();
-XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
-
-/* save to file */
-XLSX.writeFile(wb, 'SheetJS.xlsx');
-```
-
-`sheet_to_json` with the option `header:1` makes importing simple:
-
-```typescript
-/* <input type="file" (change)="onFileChange($event)" multiple="false" /> */
-/* ... (within the component class definition) ... */
-  onFileChange(evt: any) {
-    /* wire up file reader */
-    const target: DataTransfer = <DataTransfer>(evt.target);
-    if (target.files.length !== 1) throw new Error('Cannot use multiple files');
-    const reader: FileReader = new FileReader();
-    reader.onload = (e: any) => {
-      /* read workbook */
-      const ab: ArrayBuffer = e.target.result;
-      const wb: XLSX.WorkBook = XLSX.read(ab);
-
-      /* grab first sheet */
-      const wsname: string = wb.SheetNames[0];
-      const ws: XLSX.WorkSheet = wb.Sheets[wsname];
-
-      /* save data */
-      this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header: 1}));
-    };
-    reader.readAsArrayBuffer(target.files[0]);
-  }
-```
-
-## Switching between Angular versions
-
-Modules that work with Angular 2 largely work as-is with Angular 4+.  Switching
-between versions is mostly a matter of installing the correct version of the
-core and associated modules.  This demo includes `package.json-angular#` files
-for every major version of Angular up to 12.
-
-To test a particular Angular version, overwrite `package.json`:
-
-```bash
-# switch to Angular 2
-$ cp package.json-ng2 package.json
-$ npm install
-$ ng serve
-```
-
-Note: when running the demos, Angular 2 requires Node <= 14.  This is due to a
-tooling issue with `ng` and does not affect browser use.
-
-## XLSX Symbolic Link
-
-In this tree, `node_modules/xlsx` is a link pointing back to the root.  This
-enables testing the development version of the library.  In order to use this
-demo in other applications, add the `xlsx` dependency:
-
-```bash
-$ npm install --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
-```
-
-## SystemJS Configuration
-
-The default angular-cli configuration requires no additional configuration.
-
-Some deployments use the SystemJS loader, which does require configuration.
-[SystemJS](https://docs.sheetjs.com/docs/demos/bundler#systemjs)
-demo in the SheetJS CE docs describe the required settings.
-
-## Ionic
-
-<img src="screen.png" width="400px"/>
-
-Reproducing the full project is a little bit tricky.  The included `ionic.sh`
-script performs the necessary installation steps.
-
-`Array<Array<any>>` neatly maps to a table with `ngFor`:
-
-```html
-<ion-grid>
-  <ion-row *ngFor="let row of data">
-    <ion-col *ngFor="let val of row">
-      {{val}}
-    </ion-col>
-  </ion-row>
-</ion-grid>
-```
-
-
-`@ionic-native/file` reads and writes files on devices. `readAsArrayBuffer`
-returns `ArrayBuffer` objects suitable for `array` type, and `array` type can
-be converted to blobs that can be exported with `writeFile`:
-
-```typescript
-/* read a workbook */
-const ab: ArrayBuffer = await this.file.readAsArrayBuffer(url, filename);
-const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'array'});
-
-/* write a workbook */
-const wbout: ArrayBuffer = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
-let blob = new Blob([wbout], {type: 'application/octet-stream'});
-this.file.writeFile(url, filename, blob, {replace: true});
-```
-
-## NativeScript
-
-[The new demo](https://docs.sheetjs.com/docs/demos/mobile#nativescript)
-is updated for NativeScript 8 and uses more idiomatic data patterns.
+- [NativeScript](https://docs.sheetjs.com/docs/demos/mobile#nativescript) is now part of "iOS and Android Apps"
+- [Ionic](https://docs.sheetjs.com/docs/demos/mobile#ionic) is now part of "iOS and Android Apps"
 
 [![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
diff --git a/demos/angular2/ionic-app.module.ts b/demos/angular2/ionic-app.module.ts
deleted file mode 100644
index 5d92df0..0000000
--- a/demos/angular2/ionic-app.module.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
-/* vim: set ts=2: */
-/* NOTE: this file exists because `File` must be added as a provider */
-import { NgModule } from '@angular/core';
-import { BrowserModule } from '@angular/platform-browser';
-import { RouteReuseStrategy } from '@angular/router';
-
-import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
-
-import { AppComponent } from './app.component';
-import { AppRoutingModule } from './app-routing.module';
-
-import { File } from '@ionic-native/file/ngx';
-
-@NgModule({
-  declarations: [AppComponent],
-  entryComponents: [],
-  imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
-  providers: [File, { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
-  bootstrap: [AppComponent],
-})
-export class AppModule {}
diff --git a/demos/angular2/ionic.sh b/demos/angular2/ionic.sh
deleted file mode 100755
index c12a32e..0000000
--- a/demos/angular2/ionic.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-if [ ! -e SheetJSIonic ]; then
-	ionic start SheetJSIonic blank --type angular --cordova --quiet --no-git --no-link --confirm </dev/null
-	cd SheetJSIonic
-	ionic cordova platform add browser --confirm </dev/null
-	ionic cordova platform add ios --confirm </dev/null
-	ionic cordova platform add android --confirm </dev/null
-	ionic cordova plugin add cordova-plugin-file </dev/null
-	npm install --save @ionic-native/core
-	npm install --save @ionic-native/file
-	npm install --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
-	cp ../ionic-app.module.ts src/app/app.module.ts
-	cd -
-fi
-
-cp ionic.ts SheetJSIonic/src/app/home/home.page.ts
diff --git a/demos/angular2/ionic.ts b/demos/angular2/ionic.ts
deleted file mode 100644
index fedc321..0000000
--- a/demos/angular2/ionic.ts
+++ /dev/null
@@ -1,126 +0,0 @@
-/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
-/* vim: set ts=2: */
-import { Component } from '@angular/core';
-import { File } from '@ionic-native/file/ngx';
-import * as XLSX from 'xlsx';
-
-
-type AOA = any[][];
-
-@Component({
-  selector: 'app-home',
-  //templateUrl: 'home.page.html',
-  styleUrls: ['home.page.scss'],
-  template: `
-<ion-header>
-  <ion-toolbar>
-    <ion-title>SheetJS Ionic Demo</ion-title>
-  </ion-toolbar>
-</ion-header>
-
-<ion-content [fullscreen]="true">
-  <ion-header collapse="condense">
-    <ion-toolbar>
-      <ion-title>SheetJS Demo</ion-title>
-    </ion-toolbar>
-  </ion-header>
-
-  <ion-grid>
-    <ion-row *ngFor="let row of data">
-      <ion-col *ngFor="let val of row">
-        {{val}}
-      </ion-col>
-    </ion-row>
-  </ion-grid>
-</ion-content>
-
-<ion-footer padding>
-  <input type="file" (change)="onFileChange($event)" multiple="false" />
-  <button ion-button color="secondary" (click)="import()">Import Data</button>
-  <button ion-button color="secondary" (click)="export()">Export Data</button>
-</ion-footer>
-`
-})
-
-export class HomePage {
-  data: any[][] = [[1,2,3],[4,5,6]];
-  constructor(public file: File) {}
-
-  read(ab: ArrayBuffer) {
-    /* read workbook */
-    const wb: XLSX.WorkBook = XLSX.read(new Uint8Array(ab), {type: 'array'});
-
-    /* grab first sheet */
-    const wsname: string = wb.SheetNames[0];
-    const ws: XLSX.WorkSheet = wb.Sheets[wsname];
-
-    /* save data */
-    this.data = (XLSX.utils.sheet_to_json(ws, {header: 1}) as AOA);
-  };
-
-  write(): XLSX.WorkBook {
-    /* generate worksheet */
-    const ws: XLSX.WorkSheet = XLSX.utils.aoa_to_sheet(this.data);
-
-    /* generate workbook and add the worksheet */
-    const wb: XLSX.WorkBook = XLSX.utils.book_new();
-    XLSX.utils.book_append_sheet(wb, ws, 'SheetJS');
-
-    return wb;
-  };
-
-  /* File Input element for browser */
-  onFileChange(evt: any) {
-    /* wire up file reader */
-    const target: DataTransfer = (evt.target as DataTransfer);
-    if (target.files.length !== 1) { throw new Error('Cannot use multiple files'); }
-    const reader: FileReader = new FileReader();
-    reader.onload = (e: any) => {
-      const ab: ArrayBuffer = e.target.result;
-      this.read(ab);
-    };
-    reader.readAsArrayBuffer(target.files[0]);
-  };
-
-  /* Import button for mobile */
-  async import() {
-    try {
-      const target: string = this.file.documentsDirectory || this.file.externalDataDirectory || this.file.dataDirectory || '';
-      const dentry = await this.file.resolveDirectoryUrl(target);
-      const url: string = dentry.nativeURL || '';
-      alert(`Attempting to read SheetJSIonic.xlsx from ${url}`);
-      const ab: ArrayBuffer = await this.file.readAsArrayBuffer(url, 'SheetJSIonic.xlsx');
-      this.read(ab);
-    } catch(e) {
-      const m: string = e.message;
-      alert(m.match(/It was determined/) ? 'Use File Input control' : `Error: ${m}`);
-    }
-  };
-
-  /* Export button */
-  async export() {
-    const wb: XLSX.WorkBook = this.write();
-    const filename = 'SheetJSIonic.xlsx';
-    try {
-      /* generate Blob */
-      const wbout: ArrayBuffer = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
-
-      /* find appropriate path for mobile */
-      const target: string = this.file.documentsDirectory || this.file.externalDataDirectory || this.file.dataDirectory || '';
-      const dentry = await this.file.resolveDirectoryUrl(target);
-      const url: string = dentry.nativeURL || '';
-
-      /* attempt to save blob to file */
-      await this.file.writeFile(url, filename, wbout, {replace: true});
-      alert(`Wrote to SheetJSIonic.xlsx in ${url}`);
-    } catch(e) {
-      if(e.message.match(/It was determined/)) {
-        /* in the browser, use writeFile */
-        XLSX.writeFile(wb, filename);
-      } else {
-        alert(`Error: ${e.message}`);
-      }
-    }
-  };
-}
-
diff --git a/demos/angular2/package.json b/demos/angular2/package.json
deleted file mode 100644
index a214cef..0000000
--- a/demos/angular2/package.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-  "name": "angular13",
-  "version": "0.0.0",
-  "license": "MIT",
-  "scripts": {
-    "ng": "ng",
-    "start": "ng serve",
-    "build": "ng build"
-  },
-  "private": true,
-  "dependencies": {
-    "@angular/animations": "~13.2.0",
-    "@angular/common": "~13.2.0",
-    "@angular/compiler": "~13.2.0",
-
-    "@angular/core": "~13.2.0",
-    "@angular/forms": "~13.2.0",
-
-    "@angular/platform-browser": "~13.2.0",
-    "@angular/platform-browser-dynamic": "~13.2.0",
-
-    "@angular/router": "~13.2.0",
-
-
-    "rxjs": "~7.5.0",
-    "tslib": "^2.3.0",
-    "zone.js": "~0.11.4"
-  },
-  "devDependencies": {
-    "@angular-devkit/build-angular": "~13.2.1",
-    "@angular/cli": "~13.2.1",
-    "@angular/compiler-cli": "~13.2.0",
-
-    "@types/node": "^12.11.1",
-
-
-    "typescript": "~4.5.2"
-  }
-}
diff --git a/demos/angular2/screen.png b/demos/angular2/screen.png
deleted file mode 100644
index 18963733cfc5909e99d89b579f07baf054fe4ef9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 95983
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
TSJa~a0RAb;L1jxHo4)xE6;A%>

diff --git a/demos/angular2/src/app/app.module.ts b/demos/angular2/src/app/app.module.ts
deleted file mode 100644
index d7bb39a..0000000
--- a/demos/angular2/src/app/app.module.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { BrowserModule } from '@angular/platform-browser';
-import { NgModule } from '@angular/core';
-
-import { SheetJSComponent } from './sheetjs.component';
-
-
-import { Component } from '@angular/core';
-
-@Component({
-	selector: 'app-root',
-	template: `<sheetjs></sheetjs>`
-})
-export class AppComponent {
-	title = 'test';
-}
-
-@NgModule({
-	declarations: [
-		SheetJSComponent,
-		AppComponent
-	],
-	imports: [
-		BrowserModule
-	],
-	providers: [],
-	bootstrap: [AppComponent]
-})
-export class AppModule { }
diff --git a/demos/angular2/src/app/sheetjs.component.ts b/demos/angular2/src/app/sheetjs.component.ts
deleted file mode 100644
index 0015d61..0000000
--- a/demos/angular2/src/app/sheetjs.component.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
-/* vim: set ts=2: */
-import { Component } from '@angular/core';
-
-import { WorkBook, WorkSheet, WritingOptions, read, writeFileXLSX as writeFile, utils, version, set_cptable } from 'xlsx';
-//import * as cpexcel from 'xlsx/dist/cpexcel.full.mjs';
-//set_cptable(cpexcel);
-
-type AOA = any[][];
-
-@Component({
-	selector: 'sheetjs',
-	template: `
-	<pre><b>Version: {{ver}}</b></pre>
-	<input type="file" (change)="onFileChange($event)" multiple="false" />
-	<table class="sjs-table">
-		<tr *ngFor="let row of data">
-			<td *ngFor="let val of row">
-				{{val}}
-			</td>
-		</tr>
-	</table>
-	<button (click)="export()">Export!</button>
-	`
-})
-
-export class SheetJSComponent {
-	data: AOA = [ [1, 2], [3, 4] ];
-	wopts: WritingOptions = { bookType: 'xlsx', type: 'array' };
-	fileName: string = 'SheetJS.xlsx';
-	ver: string = version;
-
-	onFileChange(evt: any) {
-		/* wire up file reader */
-		const target: DataTransfer = <DataTransfer>(evt.target);
-		if (target.files.length !== 1) throw new Error('Cannot use multiple files');
-		const reader: FileReader = new FileReader();
-		reader.onload = (e: any) => {
-			/* read workbook */
-			const ab: ArrayBuffer = e.target.result;
-			const wb: WorkBook = read(ab);
-
-			/* grab first sheet */
-			const wsname: string = wb.SheetNames[0];
-			const ws: WorkSheet = wb.Sheets[wsname];
-
-			/* save data */
-			this.data = <AOA>(utils.sheet_to_json(ws, {header: 1}));
-		};
-		reader.readAsArrayBuffer(target.files[0]);
-	}
-
-	export(): void {
-		/* generate worksheet */
-		const ws: WorkSheet = utils.aoa_to_sheet(this.data);
-
-		/* generate workbook and add the worksheet */
-		const wb: WorkBook = utils.book_new();
-		utils.book_append_sheet(wb, ws, 'Sheet1');
-
-		/* save to file */
-		writeFile(wb, this.fileName);
-	}
-}
diff --git a/demos/angular2/src/environments/environment.prod.ts b/demos/angular2/src/environments/environment.prod.ts
deleted file mode 100644
index 3612073..0000000
--- a/demos/angular2/src/environments/environment.prod.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export const environment = {
-  production: true
-};
diff --git a/demos/angular2/src/environments/environment.ts b/demos/angular2/src/environments/environment.ts
deleted file mode 100644
index ffe8aed..0000000
--- a/demos/angular2/src/environments/environment.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export const environment = {
-  production: false
-};
diff --git a/demos/angular2/src/index.html b/demos/angular2/src/index.html
deleted file mode 100644
index bc806fb..0000000
--- a/demos/angular2/src/index.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html>
-<!-- xlsx.js (C) 2013-present  SheetJS http://sheetjs.com -->
-<!-- vim: set ts=2: -->
-<html lang="en">
-<head>
-	<title>SheetJS + Angular 2+</title>
-  <base href="/">
-
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-</head>
-<body>
-<pre>
-<b><a href="http://sheetjs.com">SheetJS + Angular 2+ demo</a></b>
-
-The core library can be used as-is in angular applications.
-The <a href="https://github.com/sheetjs/js-xlsx">Community Edition README</a> details some common use cases.
-We also have some <a href="http://sheetjs.com/demos/">more public demos</a>
-
-This demo shows `SheetJSComponent` which provides:
-- File input button with an event handler to parse the workbook
-- `data` property: array of arrays
-- Simple angular table which binds to the `data` property
-- `export` function that exports the `data` property to a new file.
-
-<a href="https://obamawhitehouse.archives.gov/sites/default/files/omb/budget/fy2014/assets/receipts.xls">Sample Spreadsheet</a>
-</pre>
-
-<app-root></app-root>
-</body>
-</html>
diff --git a/demos/angular2/src/main.ts b/demos/angular2/src/main.ts
deleted file mode 100644
index d3da1bb..0000000
--- a/demos/angular2/src/main.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
-import { AppModule } from './app/app.module';
-platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/demos/angular2/src/styles.css b/demos/angular2/src/styles.css
deleted file mode 100644
index 90d4ee0..0000000
--- a/demos/angular2/src/styles.css
+++ /dev/null
@@ -1 +0,0 @@
-/* You can add global styles to this file, and also import other style files */
diff --git a/demos/angular2/src/tsconfig.app.json b/demos/angular2/src/tsconfig.app.json
deleted file mode 100644
index 321e0d7..0000000
--- a/demos/angular2/src/tsconfig.app.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "extends": "../tsconfig.json",
-  "compilerOptions": {
-    "outDir": "../out-tsc/app",
-    "module": "es2015",
-    "baseUrl": "",
-    "types": []
-  }
-}
diff --git a/demos/angular2/tsconfig.json b/demos/angular2/tsconfig.json
deleted file mode 100644
index a35a8ee..0000000
--- a/demos/angular2/tsconfig.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "compileOnSave": false,
-  "compilerOptions": {
-    "outDir": "./dist/out-tsc",
-    "baseUrl": "src",
-    "sourceMap": true,
-    "declaration": false,
-    "moduleResolution": "node",
-    "emitDecoratorMetadata": true,
-    "experimentalDecorators": true,
-    "target": "es5",
-    "typeRoots": [
-      "node_modules/@types"
-    ],
-    "lib": [
-      "es2016",
-      "dom"
-    ]
-  }
-}
diff --git a/demos/angular2/versions/angular.json-ng10 b/demos/angular2/versions/angular.json-ng10
deleted file mode 100644
index 9e7228c..0000000
--- a/demos/angular2/versions/angular.json-ng10
+++ /dev/null
@@ -1,125 +0,0 @@
-{
-  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
-  "version": 1,
-  "newProjectRoot": "projects",
-  "projects": {
-    "sheetjs": {
-      "root": "",
-      "sourceRoot": "src",
-      "projectType": "application",
-      "prefix": "app",
-      "schematics": {},
-      "architect": {
-        "build": {
-          "builder": "@angular-devkit/build-angular:browser",
-          "options": {
-            "outputPath": "dist/sheetjs",
-            "index": "src/index.html",
-            "main": "src/main.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "tsconfig.app.json",
-            "aot": true,
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": []
-          },
-          "configurations": {
-            "production": {
-              "fileReplacements": [
-                {
-                  "replace": "src/environments/environment.ts",
-                  "with": "src/environments/environment.prod.ts"
-                }
-              ],
-              "optimization": true,
-              "outputHashing": "all",
-              "sourceMap": false,
-              "extractCss": true,
-              "namedChunks": false,
-              "extractLicenses": true,
-              "vendorChunk": false,
-              "buildOptimizer": true,
-              "budgets": [
-                {
-                  "type": "initial",
-                  "maximumWarning": "2mb",
-                  "maximumError": "5mb"
-                },
-                {
-                  "type": "anyComponentStyle",
-                  "maximumWarning": "6kb",
-                  "maximumError": "10kb"
-                }
-              ]
-            }
-          }
-        },
-        "serve": {
-          "builder": "@angular-devkit/build-angular:dev-server",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          },
-          "configurations": {
-            "production": {
-              "browserTarget": "sheetjs:build:production"
-            }
-          }
-        },
-        "extract-i18n": {
-          "builder": "@angular-devkit/build-angular:extract-i18n",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          }
-        },
-        "test": {
-          "builder": "@angular-devkit/build-angular:karma",
-          "options": {
-            "main": "src/test.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "tsconfig.spec.json",
-            "karmaConfig": "karma.conf.js",
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": []
-          }
-        },
-        "lint": {
-          "builder": "@angular-devkit/build-angular:tslint",
-          "options": {
-            "tsConfig": [
-              "tsconfig.app.json",
-              "tsconfig.spec.json",
-              "e2e/tsconfig.json"
-            ],
-            "exclude": [
-              "**/node_modules/**"
-            ]
-          }
-        },
-        "e2e": {
-          "builder": "@angular-devkit/build-angular:protractor",
-          "options": {
-            "protractorConfig": "e2e/protractor.conf.js",
-            "devServerTarget": "sheetjs:serve"
-          },
-          "configurations": {
-            "production": {
-              "devServerTarget": "sheetjs:serve:production"
-            }
-          }
-        }
-      }
-    }
-  },
-  "defaultProject": "sheetjs"
-}
diff --git a/demos/angular2/versions/angular.json-ng11 b/demos/angular2/versions/angular.json-ng11
deleted file mode 100644
index a1563c1..0000000
--- a/demos/angular2/versions/angular.json-ng11
+++ /dev/null
@@ -1,124 +0,0 @@
-{
-  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
-  "version": 1,
-  "newProjectRoot": "projects",
-  "projects": {
-    "sheetjs": {
-      "root": "",
-      "sourceRoot": "src",
-      "projectType": "application",
-      "prefix": "app",
-      "schematics": {},
-      "architect": {
-        "build": {
-          "builder": "@angular-devkit/build-angular:browser",
-          "options": {
-            "outputPath": "dist/sheetjs",
-            "index": "src/index.html",
-            "main": "src/main.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "tsconfig.app.json",
-            "aot": true,
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": []
-          },
-          "configurations": {
-            "production": {
-              "fileReplacements": [
-                {
-                  "replace": "src/environments/environment.ts",
-                  "with": "src/environments/environment.prod.ts"
-                }
-              ],
-              "optimization": true,
-              "outputHashing": "all",
-              "sourceMap": false,
-              "namedChunks": false,
-              "extractLicenses": true,
-              "vendorChunk": false,
-              "buildOptimizer": true,
-              "budgets": [
-                {
-                  "type": "initial",
-                  "maximumWarning": "2mb",
-                  "maximumError": "5mb"
-                },
-                {
-                  "type": "anyComponentStyle",
-                  "maximumWarning": "6kb",
-                  "maximumError": "10kb"
-                }
-              ]
-            }
-          }
-        },
-        "serve": {
-          "builder": "@angular-devkit/build-angular:dev-server",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          },
-          "configurations": {
-            "production": {
-              "browserTarget": "sheetjs:build:production"
-            }
-          }
-        },
-        "extract-i18n": {
-          "builder": "@angular-devkit/build-angular:extract-i18n",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          }
-        },
-        "test": {
-          "builder": "@angular-devkit/build-angular:karma",
-          "options": {
-            "main": "src/test.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "tsconfig.spec.json",
-            "karmaConfig": "karma.conf.js",
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": []
-          }
-        },
-        "lint": {
-          "builder": "@angular-devkit/build-angular:tslint",
-          "options": {
-            "tsConfig": [
-              "tsconfig.app.json",
-              "tsconfig.spec.json",
-              "e2e/tsconfig.json"
-            ],
-            "exclude": [
-              "**/node_modules/**"
-            ]
-          }
-        },
-        "e2e": {
-          "builder": "@angular-devkit/build-angular:protractor",
-          "options": {
-            "protractorConfig": "e2e/protractor.conf.js",
-            "devServerTarget": "sheetjs:serve"
-          },
-          "configurations": {
-            "production": {
-              "devServerTarget": "sheetjs:serve:production"
-            }
-          }
-        }
-      }
-    }
-  },
-  "defaultProject": "sheetjs"
-}
diff --git a/demos/angular2/versions/angular.json-ng12 b/demos/angular2/versions/angular.json-ng12
deleted file mode 100644
index 69d02ea..0000000
--- a/demos/angular2/versions/angular.json-ng12
+++ /dev/null
@@ -1,106 +0,0 @@
-{
-  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
-  "version": 1,
-  "newProjectRoot": "projects",
-  "projects": {
-    "sheetjs": {
-      "root": "",
-      "sourceRoot": "src",
-      "projectType": "application",
-      "prefix": "app",
-      "schematics": {
-        "@schematics/angular:application": {
-          "strict": true
-        }
-      },
-      "architect": {
-        "build": {
-          "builder": "@angular-devkit/build-angular:browser",
-          "options": {
-            "outputPath": "dist/sheetjs",
-            "index": "src/index.html",
-            "main": "src/main.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "tsconfig.app.json",
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": []
-          },
-          "configurations": {
-            "production": {
-              "budgets": [
-                {
-                  "type": "initial",
-                  "maximumWarning": "500kb",
-                  "maximumError": "2mb"
-                },
-                {
-                  "type": "anyComponentStyle",
-                  "maximumWarning": "2kb",
-                  "maximumError": "4kb"
-                }
-              ],
-              "fileReplacements": [
-                {
-                  "replace": "src/environments/environment.ts",
-                  "with": "src/environments/environment.prod.ts"
-                }
-              ],
-              "outputHashing": "all"
-            },
-            "development": {
-              "buildOptimizer": false,
-              "optimization": false,
-              "vendorChunk": true,
-              "extractLicenses": false,
-              "sourceMap": true,
-              "namedChunks": true
-            }
-          },
-          "defaultConfiguration": "production"
-        },
-        "serve": {
-          "builder": "@angular-devkit/build-angular:dev-server",
-          "configurations": {
-            "production": {
-              "browserTarget": "sheetjs:build:production"
-            },
-            "development": {
-              "browserTarget": "sheetjs:build:development"
-            }
-          },
-          "defaultConfiguration": "development"
-        },
-        "extract-i18n": {
-          "builder": "@angular-devkit/build-angular:extract-i18n",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          }
-        },
-        "test": {
-          "builder": "@angular-devkit/build-angular:karma",
-          "options": {
-            "main": "src/test.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "tsconfig.spec.json",
-            "karmaConfig": "karma.conf.js",
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": []
-          }
-        }
-      }
-    }
-  },
-  "defaultProject": "sheetjs"
-}
diff --git a/demos/angular2/versions/angular.json-ng13 b/demos/angular2/versions/angular.json-ng13
deleted file mode 100644
index 69d02ea..0000000
--- a/demos/angular2/versions/angular.json-ng13
+++ /dev/null
@@ -1,106 +0,0 @@
-{
-  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
-  "version": 1,
-  "newProjectRoot": "projects",
-  "projects": {
-    "sheetjs": {
-      "root": "",
-      "sourceRoot": "src",
-      "projectType": "application",
-      "prefix": "app",
-      "schematics": {
-        "@schematics/angular:application": {
-          "strict": true
-        }
-      },
-      "architect": {
-        "build": {
-          "builder": "@angular-devkit/build-angular:browser",
-          "options": {
-            "outputPath": "dist/sheetjs",
-            "index": "src/index.html",
-            "main": "src/main.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "tsconfig.app.json",
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": []
-          },
-          "configurations": {
-            "production": {
-              "budgets": [
-                {
-                  "type": "initial",
-                  "maximumWarning": "500kb",
-                  "maximumError": "2mb"
-                },
-                {
-                  "type": "anyComponentStyle",
-                  "maximumWarning": "2kb",
-                  "maximumError": "4kb"
-                }
-              ],
-              "fileReplacements": [
-                {
-                  "replace": "src/environments/environment.ts",
-                  "with": "src/environments/environment.prod.ts"
-                }
-              ],
-              "outputHashing": "all"
-            },
-            "development": {
-              "buildOptimizer": false,
-              "optimization": false,
-              "vendorChunk": true,
-              "extractLicenses": false,
-              "sourceMap": true,
-              "namedChunks": true
-            }
-          },
-          "defaultConfiguration": "production"
-        },
-        "serve": {
-          "builder": "@angular-devkit/build-angular:dev-server",
-          "configurations": {
-            "production": {
-              "browserTarget": "sheetjs:build:production"
-            },
-            "development": {
-              "browserTarget": "sheetjs:build:development"
-            }
-          },
-          "defaultConfiguration": "development"
-        },
-        "extract-i18n": {
-          "builder": "@angular-devkit/build-angular:extract-i18n",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          }
-        },
-        "test": {
-          "builder": "@angular-devkit/build-angular:karma",
-          "options": {
-            "main": "src/test.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "tsconfig.spec.json",
-            "karmaConfig": "karma.conf.js",
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": []
-          }
-        }
-      }
-    }
-  },
-  "defaultProject": "sheetjs"
-}
diff --git a/demos/angular2/versions/angular.json-ng6 b/demos/angular2/versions/angular.json-ng6
deleted file mode 100644
index 30e40df..0000000
--- a/demos/angular2/versions/angular.json-ng6
+++ /dev/null
@@ -1,127 +0,0 @@
-{
-  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
-  "version": 1,
-  "newProjectRoot": "projects",
-  "projects": {
-    "sheetjs": {
-      "root": "",
-      "sourceRoot": "src",
-      "projectType": "application",
-      "prefix": "app",
-      "schematics": {},
-      "architect": {
-        "build": {
-          "builder": "@angular-devkit/build-angular:browser",
-          "options": {
-            "outputPath": "dist/sheetjs",
-            "index": "src/index.html",
-            "main": "src/main.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "src/tsconfig.app.json",
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": []
-          },
-          "configurations": {
-            "production": {
-              "fileReplacements": [
-                {
-                  "replace": "src/environments/environment.ts",
-                  "with": "src/environments/environment.prod.ts"
-                }
-              ],
-              "optimization": true,
-              "outputHashing": "all",
-              "sourceMap": false,
-              "extractCss": true,
-              "namedChunks": false,
-              "aot": true,
-              "extractLicenses": true,
-              "vendorChunk": false,
-              "buildOptimizer": true
-            }
-          }
-        },
-        "serve": {
-          "builder": "@angular-devkit/build-angular:dev-server",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          },
-          "configurations": {
-            "production": {
-              "browserTarget": "sheetjs:build:production"
-            }
-          }
-        },
-        "extract-i18n": {
-          "builder": "@angular-devkit/build-angular:extract-i18n",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          }
-        },
-        "test": {
-          "builder": "@angular-devkit/build-angular:karma",
-          "options": {
-            "main": "src/test.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "src/tsconfig.spec.json",
-            "karmaConfig": "src/karma.conf.js",
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": [],
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ]
-          }
-        },
-        "lint": {
-          "builder": "@angular-devkit/build-angular:tslint",
-          "options": {
-            "tsConfig": [
-              "src/tsconfig.app.json",
-              "src/tsconfig.spec.json"
-            ],
-            "exclude": [
-              "**/node_modules/**"
-            ]
-          }
-        }
-      }
-    },
-    "sheetjs-e2e": {
-      "root": "e2e/",
-      "projectType": "application",
-      "architect": {
-        "e2e": {
-          "builder": "@angular-devkit/build-angular:protractor",
-          "options": {
-            "protractorConfig": "e2e/protractor.conf.js",
-            "devServerTarget": "sheetjs:serve"
-          },
-          "configurations": {
-            "production": {
-              "devServerTarget": "sheetjs:serve:production"
-            }
-          }
-        },
-        "lint": {
-          "builder": "@angular-devkit/build-angular:tslint",
-          "options": {
-            "tsConfig": "e2e/tsconfig.e2e.json",
-            "exclude": [
-              "**/node_modules/**"
-            ]
-          }
-        }
-      }
-    }
-  },
-  "defaultProject": "sheetjs"
-}
diff --git a/demos/angular2/versions/angular.json-ng7 b/demos/angular2/versions/angular.json-ng7
deleted file mode 100644
index be12951..0000000
--- a/demos/angular2/versions/angular.json-ng7
+++ /dev/null
@@ -1,136 +0,0 @@
-{
-  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
-  "version": 1,
-  "newProjectRoot": "projects",
-  "projects": {
-    "sheetjs": {
-      "root": "",
-      "sourceRoot": "src",
-      "projectType": "application",
-      "prefix": "app",
-      "schematics": {},
-      "architect": {
-        "build": {
-          "builder": "@angular-devkit/build-angular:browser",
-          "options": {
-            "outputPath": "dist/sheetjs",
-            "index": "src/index.html",
-            "main": "src/main.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "src/tsconfig.app.json",
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": [],
-            "es5BrowserSupport": true
-          },
-          "configurations": {
-            "production": {
-              "fileReplacements": [
-                {
-                  "replace": "src/environments/environment.ts",
-                  "with": "src/environments/environment.prod.ts"
-                }
-              ],
-              "optimization": true,
-              "outputHashing": "all",
-              "sourceMap": false,
-              "extractCss": true,
-              "namedChunks": false,
-              "aot": true,
-              "extractLicenses": true,
-              "vendorChunk": false,
-              "buildOptimizer": true,
-              "budgets": [
-                {
-                  "type": "initial",
-                  "maximumWarning": "2mb",
-                  "maximumError": "5mb"
-                }
-              ]
-            }
-          }
-        },
-        "serve": {
-          "builder": "@angular-devkit/build-angular:dev-server",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          },
-          "configurations": {
-            "production": {
-              "browserTarget": "sheetjs:build:production"
-            }
-          }
-        },
-        "extract-i18n": {
-          "builder": "@angular-devkit/build-angular:extract-i18n",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          }
-        },
-        "test": {
-          "builder": "@angular-devkit/build-angular:karma",
-          "options": {
-            "main": "src/test.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "src/tsconfig.spec.json",
-            "karmaConfig": "src/karma.conf.js",
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": [],
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ]
-          }
-        },
-        "lint": {
-          "builder": "@angular-devkit/build-angular:tslint",
-          "options": {
-            "tsConfig": [
-              "src/tsconfig.app.json",
-              "src/tsconfig.spec.json"
-            ],
-            "exclude": [
-              "**/node_modules/**"
-            ]
-          }
-        }
-      }
-    },
-    "sheetjs-e2e": {
-      "root": "e2e/",
-      "projectType": "application",
-      "prefix": "",
-      "architect": {
-        "e2e": {
-          "builder": "@angular-devkit/build-angular:protractor",
-          "options": {
-            "protractorConfig": "e2e/protractor.conf.js",
-            "devServerTarget": "sheetjs:serve"
-          },
-          "configurations": {
-            "production": {
-              "devServerTarget": "sheetjs:serve:production"
-            }
-          }
-        },
-        "lint": {
-          "builder": "@angular-devkit/build-angular:tslint",
-          "options": {
-            "tsConfig": "e2e/tsconfig.e2e.json",
-            "exclude": [
-              "**/node_modules/**"
-            ]
-          }
-        }
-      }
-    }
-  },
-  "defaultProject": "sheetjs"
-}
diff --git a/demos/angular2/versions/angular.json-ng8 b/demos/angular2/versions/angular.json-ng8
deleted file mode 100644
index de608c0..0000000
--- a/demos/angular2/versions/angular.json-ng8
+++ /dev/null
@@ -1,126 +0,0 @@
-{
-  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
-  "version": 1,
-  "newProjectRoot": "projects",
-  "projects": {
-    "sheetjs": {
-      "root": "",
-      "sourceRoot": "src",
-      "projectType": "application",
-      "prefix": "app",
-      "schematics": {},
-      "architect": {
-        "build": {
-          "builder": "@angular-devkit/build-angular:browser",
-          "options": {
-            "outputPath": "dist/sheetjs",
-            "index": "src/index.html",
-            "main": "src/main.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "tsconfig.app.json",
-            "aot": false,
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": []
-          },
-          "configurations": {
-            "production": {
-              "fileReplacements": [
-                {
-                  "replace": "src/environments/environment.ts",
-                  "with": "src/environments/environment.prod.ts"
-                }
-              ],
-              "optimization": true,
-              "outputHashing": "all",
-              "sourceMap": false,
-              "extractCss": true,
-              "namedChunks": false,
-              "aot": true,
-              "extractLicenses": true,
-              "vendorChunk": false,
-              "buildOptimizer": true,
-              "budgets": [
-                {
-                  "type": "initial",
-                  "maximumWarning": "2mb",
-                  "maximumError": "5mb"
-                },
-                {
-                  "type": "anyComponentStyle",
-                  "maximumWarning": "6kb",
-                  "maximumError": "10kb"
-                }
-              ]
-            }
-          }
-        },
-        "serve": {
-          "builder": "@angular-devkit/build-angular:dev-server",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          },
-          "configurations": {
-            "production": {
-              "browserTarget": "sheetjs:build:production"
-            }
-          }
-        },
-        "extract-i18n": {
-          "builder": "@angular-devkit/build-angular:extract-i18n",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          }
-        },
-        "test": {
-          "builder": "@angular-devkit/build-angular:karma",
-          "options": {
-            "main": "src/test.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "tsconfig.spec.json",
-            "karmaConfig": "karma.conf.js",
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": []
-          }
-        },
-        "lint": {
-          "builder": "@angular-devkit/build-angular:tslint",
-          "options": {
-            "tsConfig": [
-              "tsconfig.app.json",
-              "tsconfig.spec.json",
-              "e2e/tsconfig.json"
-            ],
-            "exclude": [
-              "**/node_modules/**"
-            ]
-          }
-        },
-        "e2e": {
-          "builder": "@angular-devkit/build-angular:protractor",
-          "options": {
-            "protractorConfig": "e2e/protractor.conf.js",
-            "devServerTarget": "sheetjs:serve"
-          },
-          "configurations": {
-            "production": {
-              "devServerTarget": "sheetjs:serve:production"
-            }
-          }
-        }
-      }
-    }
-  },
-  "defaultProject": "sheetjs"
-}
diff --git a/demos/angular2/versions/angular.json-ng9 b/demos/angular2/versions/angular.json-ng9
deleted file mode 100644
index 9e7228c..0000000
--- a/demos/angular2/versions/angular.json-ng9
+++ /dev/null
@@ -1,125 +0,0 @@
-{
-  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
-  "version": 1,
-  "newProjectRoot": "projects",
-  "projects": {
-    "sheetjs": {
-      "root": "",
-      "sourceRoot": "src",
-      "projectType": "application",
-      "prefix": "app",
-      "schematics": {},
-      "architect": {
-        "build": {
-          "builder": "@angular-devkit/build-angular:browser",
-          "options": {
-            "outputPath": "dist/sheetjs",
-            "index": "src/index.html",
-            "main": "src/main.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "tsconfig.app.json",
-            "aot": true,
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": []
-          },
-          "configurations": {
-            "production": {
-              "fileReplacements": [
-                {
-                  "replace": "src/environments/environment.ts",
-                  "with": "src/environments/environment.prod.ts"
-                }
-              ],
-              "optimization": true,
-              "outputHashing": "all",
-              "sourceMap": false,
-              "extractCss": true,
-              "namedChunks": false,
-              "extractLicenses": true,
-              "vendorChunk": false,
-              "buildOptimizer": true,
-              "budgets": [
-                {
-                  "type": "initial",
-                  "maximumWarning": "2mb",
-                  "maximumError": "5mb"
-                },
-                {
-                  "type": "anyComponentStyle",
-                  "maximumWarning": "6kb",
-                  "maximumError": "10kb"
-                }
-              ]
-            }
-          }
-        },
-        "serve": {
-          "builder": "@angular-devkit/build-angular:dev-server",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          },
-          "configurations": {
-            "production": {
-              "browserTarget": "sheetjs:build:production"
-            }
-          }
-        },
-        "extract-i18n": {
-          "builder": "@angular-devkit/build-angular:extract-i18n",
-          "options": {
-            "browserTarget": "sheetjs:build"
-          }
-        },
-        "test": {
-          "builder": "@angular-devkit/build-angular:karma",
-          "options": {
-            "main": "src/test.ts",
-            "polyfills": "src/polyfills.ts",
-            "tsConfig": "tsconfig.spec.json",
-            "karmaConfig": "karma.conf.js",
-            "assets": [
-              "src/favicon.ico",
-              "src/assets"
-            ],
-            "styles": [
-              "src/styles.css"
-            ],
-            "scripts": []
-          }
-        },
-        "lint": {
-          "builder": "@angular-devkit/build-angular:tslint",
-          "options": {
-            "tsConfig": [
-              "tsconfig.app.json",
-              "tsconfig.spec.json",
-              "e2e/tsconfig.json"
-            ],
-            "exclude": [
-              "**/node_modules/**"
-            ]
-          }
-        },
-        "e2e": {
-          "builder": "@angular-devkit/build-angular:protractor",
-          "options": {
-            "protractorConfig": "e2e/protractor.conf.js",
-            "devServerTarget": "sheetjs:serve"
-          },
-          "configurations": {
-            "production": {
-              "devServerTarget": "sheetjs:serve:production"
-            }
-          }
-        }
-      }
-    }
-  },
-  "defaultProject": "sheetjs"
-}
diff --git a/demos/angular2/versions/package.json-ng10 b/demos/angular2/versions/package.json-ng10
deleted file mode 100644
index fff68df..0000000
--- a/demos/angular2/versions/package.json-ng10
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-  "name": "angular10",
-  "version": "0.0.0",
-  "license": "MIT",
-  "scripts": {
-    "ng": "ng",
-    "start": "ng serve",
-    "build": "ng build"
-  },
-  "private": true,
-  "dependencies": {
-    "@angular/animations": "~10.2.4",
-    "@angular/common": "~10.2.4",
-    "@angular/compiler": "~10.2.4",
-
-    "@angular/core": "~10.2.4",
-    "@angular/forms": "~10.2.4",
-
-    "@angular/platform-browser": "~10.2.4",
-    "@angular/platform-browser-dynamic": "~10.2.4",
-
-    "@angular/router": "~10.2.4",
-
-
-    "rxjs": "~6.6.0",
-    "tslib": "^2.0.0",
-    "zone.js": "~0.10.2"
-  },
-  "devDependencies": {
-    "@angular-devkit/build-angular": "~0.1002.3",
-    "@angular/cli": "~10.2.3",
-    "@angular/compiler-cli": "~10.2.4",
-
-    "@types/node": "^12.11.1",
-    "ts-node": "~8.3.0",
-    "tslint": "~6.1.0",
-    "typescript": "~4.0.2"
-  }
-}
diff --git a/demos/angular2/versions/package.json-ng11 b/demos/angular2/versions/package.json-ng11
deleted file mode 100644
index 9bb80a8..0000000
--- a/demos/angular2/versions/package.json-ng11
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-  "name": "angular11",
-  "version": "0.0.0",
-  "license": "MIT",
-  "scripts": {
-    "ng": "ng",
-    "start": "ng serve",
-    "build": "ng build"
-  },
-  "private": true,
-  "dependencies": {
-    "@angular/animations": "~11.2.14",
-    "@angular/common": "~11.2.14",
-    "@angular/compiler": "~11.2.14",
-
-    "@angular/core": "~11.2.14",
-    "@angular/forms": "~11.2.14",
-
-    "@angular/platform-browser": "~11.2.14",
-    "@angular/platform-browser-dynamic": "~11.2.14",
-
-    "@angular/router": "~11.2.14",
-
-
-    "rxjs": "~6.6.0",
-    "tslib": "^2.0.0",
-    "zone.js": "~0.11.3"
-  },
-  "devDependencies": {
-    "@angular-devkit/build-angular": "~0.1102.13",
-    "@angular/cli": "~11.2.14",
-    "@angular/compiler-cli": "~11.2.14",
-
-    "@types/node": "^12.11.1",
-    "ts-node": "~8.3.0",
-    "tslint": "~6.1.0",
-    "typescript": "~4.1.5"
-  }
-}
diff --git a/demos/angular2/versions/package.json-ng12 b/demos/angular2/versions/package.json-ng12
deleted file mode 100644
index 74df6c5..0000000
--- a/demos/angular2/versions/package.json-ng12
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-  "name": "angular12",
-  "version": "0.0.0",
-  "license": "MIT",
-  "scripts": {
-    "ng": "ng",
-    "start": "ng serve",
-    "build": "ng build"
-  },
-  "private": true,
-  "dependencies": {
-    "@angular/animations": "~12.2.0",
-    "@angular/common": "~12.2.0",
-    "@angular/compiler": "~12.2.0",
-
-    "@angular/core": "~12.2.0",
-    "@angular/forms": "~12.2.0",
-
-    "@angular/platform-browser": "~12.2.0",
-    "@angular/platform-browser-dynamic": "~12.2.0",
-
-    "@angular/router": "~12.2.0",
-
-
-    "rxjs": "~6.6.0",
-    "tslib": "^2.3.0",
-    "zone.js": "~0.11.4"
-  },
-  "devDependencies": {
-    "@angular-devkit/build-angular": "~12.2.7",
-    "@angular/cli": "~12.2.7",
-    "@angular/compiler-cli": "~12.2.0",
-
-    "@types/node": "^12.11.1",
-
-
-    "typescript": "~4.3.5"
-  }
-}
diff --git a/demos/angular2/versions/package.json-ng13 b/demos/angular2/versions/package.json-ng13
deleted file mode 100644
index a214cef..0000000
--- a/demos/angular2/versions/package.json-ng13
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-  "name": "angular13",
-  "version": "0.0.0",
-  "license": "MIT",
-  "scripts": {
-    "ng": "ng",
-    "start": "ng serve",
-    "build": "ng build"
-  },
-  "private": true,
-  "dependencies": {
-    "@angular/animations": "~13.2.0",
-    "@angular/common": "~13.2.0",
-    "@angular/compiler": "~13.2.0",
-
-    "@angular/core": "~13.2.0",
-    "@angular/forms": "~13.2.0",
-
-    "@angular/platform-browser": "~13.2.0",
-    "@angular/platform-browser-dynamic": "~13.2.0",
-
-    "@angular/router": "~13.2.0",
-
-
-    "rxjs": "~7.5.0",
-    "tslib": "^2.3.0",
-    "zone.js": "~0.11.4"
-  },
-  "devDependencies": {
-    "@angular-devkit/build-angular": "~13.2.1",
-    "@angular/cli": "~13.2.1",
-    "@angular/compiler-cli": "~13.2.0",
-
-    "@types/node": "^12.11.1",
-
-
-    "typescript": "~4.5.2"
-  }
-}
diff --git a/demos/angular2/versions/package.json-ng2 b/demos/angular2/versions/package.json-ng2
deleted file mode 100644
index c6cdfe9..0000000
--- a/demos/angular2/versions/package.json-ng2
+++ /dev/null
@@ -1,37 +0,0 @@
-{
-  "name": "angular2",
-  "version": "0.0.0",
-  "license": "MIT",
-  "scripts": {
-    "ng": "ng",
-    "start": "ng serve",
-    "build": "ng build"
-  },
-  "private": true,
-  "dependencies": {
-    "@angular/common": "~2.4.1",
-    "@angular/compiler": "~2.4.1",
-    "@angular/compiler-cli": "^2.4.1",
-    "@angular/core": "~2.4.1",
-    "@angular/forms": "~2.4.1",
-    "@angular/http": "~2.4.1",
-    "@angular/platform-browser": "~2.4.1",
-    "@angular/platform-browser-dynamic": "~2.4.1",
-    "@angular/platform-server": "^2.4.1",
-    "@angular/router": "~3.4.0",
-    "core-js": "^2.4.1",
-    "reflect-metadata": "^0.1.8",
-    "rxjs": "^5.0.2",
-    "systemjs": "0.19.40",
-    "zone.js": "^0.7.4"
-  },
-  "devDependencies": {
-    "@angular/cli": "1.1.2",
-    "@angular/compiler-cli": "^2.0.0",
-    "@angular/language-service": "^2.0.0",
-    "@types/node": "~6.0.60",
-    "ts-node": "~3.0.4",
-    "tslint": "~5.3.2",
-    "typescript": "~2.3.3"
-  }
-}
diff --git a/demos/angular2/versions/package.json-ng4 b/demos/angular2/versions/package.json-ng4
deleted file mode 100644
index 2891383..0000000
--- a/demos/angular2/versions/package.json-ng4
+++ /dev/null
@@ -1,38 +0,0 @@
-{
-  "name": "angular4",
-  "version": "0.0.0",
-  "license": "MIT",
-  "scripts": {
-    "ng": "ng",
-    "start": "ng serve",
-    "build": "ng build"
-  },
-  "private": true,
-  "dependencies": {
-    "@angular/animations": "^4.0.0",
-    "@angular/common": "^4.0.0",
-    "@angular/compiler": "^4.0.0",
-
-    "@angular/core": "^4.0.0",
-    "@angular/forms": "^4.0.0",
-    "@angular/http": "^4.0.0",
-    "@angular/platform-browser": "^4.0.0",
-    "@angular/platform-browser-dynamic": "^4.0.0",
-
-    "@angular/router": "^4.0.0",
-    "core-js": "^2.4.1",
-
-    "rxjs": "^5.1.0",
-
-    "zone.js": "^0.8.4"
-  },
-  "devDependencies": {
-    "@angular/cli": "1.1.2",
-    "@angular/compiler-cli": "^4.0.0",
-    "@angular/language-service": "^4.0.0",
-    "@types/node": "~6.0.60",
-    "ts-node": "~3.0.4",
-    "tslint": "~5.3.2",
-    "typescript": "~2.3.3"
-  }
-}
diff --git a/demos/angular2/versions/package.json-ng5 b/demos/angular2/versions/package.json-ng5
deleted file mode 100644
index 1f62707..0000000
--- a/demos/angular2/versions/package.json-ng5
+++ /dev/null
@@ -1,38 +0,0 @@
-{
-  "name": "angular5",
-  "version": "0.0.0",
-  "license": "MIT",
-  "scripts": {
-    "ng": "ng",
-    "start": "ng serve",
-    "build": "ng build"
-  },
-  "private": true,
-  "dependencies": {
-    "@angular/animations": "^5.0.0",
-    "@angular/common": "^5.0.0",
-    "@angular/compiler": "^5.0.0",
-
-    "@angular/core": "^5.0.0",
-    "@angular/forms": "^5.0.0",
-    "@angular/http": "^5.0.0",
-    "@angular/platform-browser": "^5.0.0",
-    "@angular/platform-browser-dynamic": "^5.0.0",
-
-    "@angular/router": "^5.0.0",
-    "core-js": "^2.4.1",
-
-    "rxjs": "^5.5.2",
-
-    "zone.js": "^0.8.14"
-  },
-  "devDependencies": {
-    "@angular/cli": "^1.5.3",
-    "@angular/compiler-cli": "^5.0.0",
-    "@angular/language-service": "^5.0.0",
-    "@types/node": "~6.0.60",
-    "ts-node": "~3.2.0",
-    "tslint": "~5.7.0",
-    "typescript": "~2.4.2"
-  }
-}
diff --git a/demos/angular2/versions/package.json-ng6 b/demos/angular2/versions/package.json-ng6
deleted file mode 100644
index a6df172..0000000
--- a/demos/angular2/versions/package.json-ng6
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-  "name": "angular6",
-  "version": "0.0.0",
-  "license": "MIT",
-  "scripts": {
-    "ng": "ng",
-    "start": "ng serve",
-    "build": "ng build"
-  },
-  "private": true,
-  "dependencies": {
-    "@angular/animations": "^6.1.0",
-    "@angular/common": "^6.1.0",
-    "@angular/compiler": "^6.1.0",
-
-    "@angular/core": "^6.1.0",
-    "@angular/forms": "^6.1.0",
-    "@angular/http": "^6.1.0",
-    "@angular/platform-browser": "^6.1.0",
-    "@angular/platform-browser-dynamic": "^6.1.0",
-
-    "@angular/router": "^6.1.0",
-    "core-js": "^2.5.4",
-
-    "rxjs": "~6.2.0",
-
-    "zone.js": "~0.8.26"
-  },
-  "devDependencies": {
-    "@angular-devkit/build-angular": "~0.8.0",
-    "@angular/cli": "~6.2.9",
-    "@angular/compiler-cli": "^6.1.0",
-    "@angular/language-service": "^6.1.0",
-    "@types/node": "~8.9.4",
-    "ts-node": "~7.0.0",
-    "tslint": "~5.11.0",
-    "typescript": "~2.9.2"
-  }
-}
diff --git a/demos/angular2/versions/package.json-ng7 b/demos/angular2/versions/package.json-ng7
deleted file mode 100644
index 841dab7..0000000
--- a/demos/angular2/versions/package.json-ng7
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-  "name": "angular7",
-  "version": "0.0.0",
-  "license": "MIT",
-  "scripts": {
-    "ng": "ng",
-    "start": "ng serve",
-    "build": "ng build"
-  },
-  "private": true,
-  "dependencies": {
-    "@angular/animations": "~7.2.0",
-    "@angular/common": "~7.2.0",
-    "@angular/compiler": "~7.2.0",
-
-    "@angular/core": "~7.2.0",
-    "@angular/forms": "~7.2.0",
-
-    "@angular/platform-browser": "~7.2.0",
-    "@angular/platform-browser-dynamic": "~7.2.0",
-
-    "@angular/router": "~7.2.0",
-    "core-js": "^2.5.4",
-
-    "rxjs": "~6.3.3",
-    "tslib": "^1.9.0",
-    "zone.js": "~0.8.26"
-  },
-  "devDependencies": {
-    "@angular-devkit/build-angular": "~0.13.0",
-    "@angular/cli": "~7.3.10",
-    "@angular/compiler-cli": "~7.2.0",
-    "@angular/language-service": "~7.2.0",
-    "@types/node": "~8.9.4",
-    "ts-node": "~7.0.0",
-    "tslint": "~5.11.0",
-    "typescript": "~3.2.2"
-  }
-}
diff --git a/demos/angular2/versions/package.json-ng8 b/demos/angular2/versions/package.json-ng8
deleted file mode 100644
index 5643841..0000000
--- a/demos/angular2/versions/package.json-ng8
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-  "name": "angular8",
-  "version": "0.0.0",
-  "license": "MIT",
-  "scripts": {
-    "ng": "ng",
-    "start": "ng serve",
-    "build": "ng build"
-  },
-  "private": true,
-  "dependencies": {
-    "@angular/animations": "~8.2.14",
-    "@angular/common": "~8.2.14",
-    "@angular/compiler": "~8.2.14",
-
-    "@angular/core": "~8.2.14",
-    "@angular/forms": "~8.2.14",
-
-    "@angular/platform-browser": "~8.2.14",
-    "@angular/platform-browser-dynamic": "~8.2.14",
-
-    "@angular/router": "~8.2.14",
-
-
-    "rxjs": "~6.4.0",
-    "tslib": "^1.10.0",
-    "zone.js": "~0.9.1"
-  },
-  "devDependencies": {
-    "@angular-devkit/build-angular": "~0.803.29",
-    "@angular/cli": "~8.3.29",
-    "@angular/compiler-cli": "~8.2.14",
-    "@angular/language-service": "~8.2.14",
-    "@types/node": "~8.9.4",
-    "ts-node": "~7.0.0",
-    "tslint": "~5.15.0",
-    "typescript": "~3.5.3"
-  }
-}
diff --git a/demos/angular2/versions/package.json-ng9 b/demos/angular2/versions/package.json-ng9
deleted file mode 100644
index fe6c382..0000000
--- a/demos/angular2/versions/package.json-ng9
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-  "name": "angular9",
-  "version": "0.0.0",
-  "license": "MIT",
-  "scripts": {
-    "ng": "ng",
-    "start": "ng serve",
-    "build": "ng build"
-  },
-  "private": true,
-  "dependencies": {
-    "@angular/animations": "~9.1.13",
-    "@angular/common": "~9.1.13",
-    "@angular/compiler": "~9.1.13",
-
-    "@angular/core": "~9.1.13",
-    "@angular/forms": "~9.1.13",
-
-    "@angular/platform-browser": "~9.1.13",
-    "@angular/platform-browser-dynamic": "~9.1.13",
-
-    "@angular/router": "~9.1.13",
-
-
-    "rxjs": "~6.5.4",
-    "tslib": "^1.10.0",
-    "zone.js": "~0.10.2"
-  },
-  "devDependencies": {
-    "@angular-devkit/build-angular": "~0.901.15",
-    "@angular/cli": "~9.1.15",
-    "@angular/compiler-cli": "~9.1.13",
-
-    "@types/node": "^12.11.1",
-    "ts-node": "~8.3.0",
-    "tslint": "~6.1.0",
-    "typescript": "~3.8.3"
-  }
-}
diff --git a/demos/angular2/versions/polyfills.ts-ng10 b/demos/angular2/versions/polyfills.ts-ng10
deleted file mode 100644
index 741c886..0000000
--- a/demos/angular2/versions/polyfills.ts-ng10
+++ /dev/null
@@ -1 +0,0 @@
-import 'zone.js/dist/zone';
diff --git a/demos/angular2/versions/polyfills.ts-ng11 b/demos/angular2/versions/polyfills.ts-ng11
deleted file mode 100644
index 741c886..0000000
--- a/demos/angular2/versions/polyfills.ts-ng11
+++ /dev/null
@@ -1 +0,0 @@
-import 'zone.js/dist/zone';
diff --git a/demos/angular2/versions/polyfills.ts-ng12 b/demos/angular2/versions/polyfills.ts-ng12
deleted file mode 100644
index aa09a9f..0000000
--- a/demos/angular2/versions/polyfills.ts-ng12
+++ /dev/null
@@ -1 +0,0 @@
-import 'zone.js';
diff --git a/demos/angular2/versions/polyfills.ts-ng13 b/demos/angular2/versions/polyfills.ts-ng13
deleted file mode 100644
index aa09a9f..0000000
--- a/demos/angular2/versions/polyfills.ts-ng13
+++ /dev/null
@@ -1 +0,0 @@
-import 'zone.js';
diff --git a/demos/angular2/versions/polyfills.ts-ng2 b/demos/angular2/versions/polyfills.ts-ng2
deleted file mode 100644
index 2143ebf..0000000
--- a/demos/angular2/versions/polyfills.ts-ng2
+++ /dev/null
@@ -1,3 +0,0 @@
-import 'core-js/es6/reflect';
-import 'core-js/es7/reflect';
-import 'zone.js/dist/zone';
diff --git a/demos/angular2/versions/polyfills.ts-ng4 b/demos/angular2/versions/polyfills.ts-ng4
deleted file mode 100644
index 2143ebf..0000000
--- a/demos/angular2/versions/polyfills.ts-ng4
+++ /dev/null
@@ -1,3 +0,0 @@
-import 'core-js/es6/reflect';
-import 'core-js/es7/reflect';
-import 'zone.js/dist/zone';
diff --git a/demos/angular2/versions/polyfills.ts-ng5 b/demos/angular2/versions/polyfills.ts-ng5
deleted file mode 100644
index 2143ebf..0000000
--- a/demos/angular2/versions/polyfills.ts-ng5
+++ /dev/null
@@ -1,3 +0,0 @@
-import 'core-js/es6/reflect';
-import 'core-js/es7/reflect';
-import 'zone.js/dist/zone';
diff --git a/demos/angular2/versions/polyfills.ts-ng6 b/demos/angular2/versions/polyfills.ts-ng6
deleted file mode 100644
index 2143ebf..0000000
--- a/demos/angular2/versions/polyfills.ts-ng6
+++ /dev/null
@@ -1,3 +0,0 @@
-import 'core-js/es6/reflect';
-import 'core-js/es7/reflect';
-import 'zone.js/dist/zone';
diff --git a/demos/angular2/versions/polyfills.ts-ng7 b/demos/angular2/versions/polyfills.ts-ng7
deleted file mode 100644
index 2143ebf..0000000
--- a/demos/angular2/versions/polyfills.ts-ng7
+++ /dev/null
@@ -1,3 +0,0 @@
-import 'core-js/es6/reflect';
-import 'core-js/es7/reflect';
-import 'zone.js/dist/zone';
diff --git a/demos/angular2/versions/polyfills.ts-ng8 b/demos/angular2/versions/polyfills.ts-ng8
deleted file mode 100644
index 741c886..0000000
--- a/demos/angular2/versions/polyfills.ts-ng8
+++ /dev/null
@@ -1 +0,0 @@
-import 'zone.js/dist/zone';
diff --git a/demos/angular2/versions/polyfills.ts-ng9 b/demos/angular2/versions/polyfills.ts-ng9
deleted file mode 100644
index 741c886..0000000
--- a/demos/angular2/versions/polyfills.ts-ng9
+++ /dev/null
@@ -1 +0,0 @@
-import 'zone.js/dist/zone';
diff --git a/demos/angular2/versions/tsconfig.app.json-ng10 b/demos/angular2/versions/tsconfig.app.json-ng10
deleted file mode 100644
index f758d98..0000000
--- a/demos/angular2/versions/tsconfig.app.json-ng10
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "extends": "./tsconfig.json",
-  "compilerOptions": {
-    "outDir": "./out-tsc/app",
-    "types": []
-  },
-  "files": [
-    "src/main.ts",
-    "src/polyfills.ts"
-  ],
-  "include": [
-    "src/**/*.d.ts"
-  ]
-}
diff --git a/demos/angular2/versions/tsconfig.app.json-ng11 b/demos/angular2/versions/tsconfig.app.json-ng11
deleted file mode 100644
index f758d98..0000000
--- a/demos/angular2/versions/tsconfig.app.json-ng11
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "extends": "./tsconfig.json",
-  "compilerOptions": {
-    "outDir": "./out-tsc/app",
-    "types": []
-  },
-  "files": [
-    "src/main.ts",
-    "src/polyfills.ts"
-  ],
-  "include": [
-    "src/**/*.d.ts"
-  ]
-}
diff --git a/demos/angular2/versions/tsconfig.app.json-ng12 b/demos/angular2/versions/tsconfig.app.json-ng12
deleted file mode 100644
index f758d98..0000000
--- a/demos/angular2/versions/tsconfig.app.json-ng12
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "extends": "./tsconfig.json",
-  "compilerOptions": {
-    "outDir": "./out-tsc/app",
-    "types": []
-  },
-  "files": [
-    "src/main.ts",
-    "src/polyfills.ts"
-  ],
-  "include": [
-    "src/**/*.d.ts"
-  ]
-}
diff --git a/demos/angular2/versions/tsconfig.app.json-ng13 b/demos/angular2/versions/tsconfig.app.json-ng13
deleted file mode 100644
index f758d98..0000000
--- a/demos/angular2/versions/tsconfig.app.json-ng13
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "extends": "./tsconfig.json",
-  "compilerOptions": {
-    "outDir": "./out-tsc/app",
-    "types": []
-  },
-  "files": [
-    "src/main.ts",
-    "src/polyfills.ts"
-  ],
-  "include": [
-    "src/**/*.d.ts"
-  ]
-}
diff --git a/demos/angular2/versions/tsconfig.app.json-ng8 b/demos/angular2/versions/tsconfig.app.json-ng8
deleted file mode 100644
index 565a11a..0000000
--- a/demos/angular2/versions/tsconfig.app.json-ng8
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "extends": "./tsconfig.json",
-  "compilerOptions": {
-    "outDir": "./out-tsc/app",
-    "types": []
-  },
-  "files": [
-    "src/main.ts",
-    "src/polyfills.ts"
-  ],
-  "include": [
-    "src/**/*.ts"
-  ],
-  "exclude": [
-    "src/test.ts",
-    "src/**/*.spec.ts"
-  ]
-}
diff --git a/demos/angular2/versions/tsconfig.app.json-ng9 b/demos/angular2/versions/tsconfig.app.json-ng9
deleted file mode 100644
index f758d98..0000000
--- a/demos/angular2/versions/tsconfig.app.json-ng9
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "extends": "./tsconfig.json",
-  "compilerOptions": {
-    "outDir": "./out-tsc/app",
-    "types": []
-  },
-  "files": [
-    "src/main.ts",
-    "src/polyfills.ts"
-  ],
-  "include": [
-    "src/**/*.d.ts"
-  ]
-}
diff --git a/demos/function/.eslintrc b/demos/function/.eslintrc
deleted file mode 100644
index dbf6551..0000000
--- a/demos/function/.eslintrc
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-	"env": { "shared-node-browser":true },
-	"parserOptions": {
-		"ecmaVersion": 8
-	},
-	"plugins": [ "html", "json" ]
-}
diff --git a/demos/function/AzureHTTPTrigger/function.json b/demos/function/AzureHTTPTrigger/function.json
deleted file mode 100644
index 7c64ea6..0000000
--- a/demos/function/AzureHTTPTrigger/function.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "disabled": false,
-  "bindings": [
-    {
-      "authLevel": "function",
-      "type": "httpTrigger",
-      "direction": "in",
-      "dataType": "binary",
-      "name": "req"
-    },
-    {
-      "type": "http",
-      "direction": "out",
-      "name": "res"
-    }
-  ]
-}
diff --git a/demos/function/AzureHTTPTrigger/index.js b/demos/function/AzureHTTPTrigger/index.js
deleted file mode 100644
index c39d77c..0000000
--- a/demos/function/AzureHTTPTrigger/index.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
-/* eslint-env node */
-// base64 sheetjs.xlsb | curl -F "data=@-;filename=test.xlsb" http://localhost:7262/api/AzureHTTPTrigger
-
-const XLSX = require('xlsx');
-const formidable = require('formidable');
-const Readable = require('stream').Readable;
-var fs = require('fs');
-
-/* formidable expects the request object to be a stream */
-const streamify = (req) => {
-	if(typeof req.on !== 'undefined') return req;
-	const s = new Readable();
-	s._read = ()=>{};
-	s.push(new Buffer(req.body));
-	s.push(null);
-	Object.assign(s, req);
-	return s;
-};
-
-module.exports = (context, req) => {
-	const form = new formidable.IncomingForm();
-	form.parse(streamify(req), (err, fields, files) => {
-		/* grab the first file */
-		var f = Object.values(files)[0];
-		if(!f) {
-			context.res = { status: 400, body: "Must submit a file for processing!" };
-		} else {
-			/* file is stored in a temp directory, so we can point to that and read it */
-			const wb = XLSX.read(f.path, {type:"file"});
-
-			/* convert to specified output type -- default CSV */
-			const ext = (fields.bookType || "csv").toLowerCase();
-			const out = XLSX.write(wb, {type:"string", bookType:ext});
-
-			context.res = {
-				status: 200,
-				headers: { "Content-Disposition": `attachment; filename="download.${ext}";` },
-				body: out
-			};
-		}
-		context.done();
-	});
-};
diff --git a/demos/function/Firebase/.gitignore b/demos/function/Firebase/.gitignore
deleted file mode 100644
index f9ed3da..0000000
--- a/demos/function/Firebase/.gitignore
+++ /dev/null
@@ -1,65 +0,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-firebase-debug.log*
-
-# Firebase cache
-.firebase/
-
-# Firebase config
-
-# Uncomment this if you'd like others to create their own Firebase project.
-# For a team working on the same Firebase project(s), it is recommended to leave
-# it commented so all members can deploy to the same project(s) in .firebaserc.
-.firebaserc
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (http://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variables file
-.env
diff --git a/demos/function/Firebase/firebase.json b/demos/function/Firebase/firebase.json
deleted file mode 100644
index 0967ef4..0000000
--- a/demos/function/Firebase/firebase.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
diff --git a/demos/function/Firebase/functions/.gitignore b/demos/function/Firebase/functions/.gitignore
deleted file mode 100644
index 40b878d..0000000
--- a/demos/function/Firebase/functions/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-node_modules/
\ No newline at end of file
diff --git a/demos/function/Firebase/functions/index.js b/demos/function/Firebase/functions/index.js
deleted file mode 100644
index d14b499..0000000
--- a/demos/function/Firebase/functions/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const functions = require('firebase-functions');
-const Busboy = require('busboy');
-const XLSX = require('xlsx');
-
-// // Create and Deploy Your First Cloud Functions
-// // https://firebase.google.com/docs/functions/write-firebase-functions
-//
-exports.helloWorld = functions.https.onRequest((request, response) => {
- response.send("Hello from Firebase!");
-});
-
-exports.main = functions.https.onRequest((req, res) => {
-  var bb = new Busboy({
-    headers: {
-      'content-type': req.headers['content-type']
-    }
-  });
-  let fields = {};
-  let files = {};
-  bb.on('field', (fieldname, val) => {
-    fields[fieldname] = val;
-  });
-  bb.on('file', (fieldname, file, filename) => {
-    var buffers = [];
-    file.on('data', (data) => {
-      buffers.push(data);
-    });
-    file.on('end', () => {
-      files[fieldname] = [Buffer.concat(buffers), filename];
-    });
-  });
-  bb.on('finish', () => {
-    let f = files[Object.keys(files)[0]];
-    const wb = XLSX.read(f[0], { type: "buffer" });
-    // Convert to CSV
-    res.send(XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]));
-  });
-  bb.end(req.body)
-});
diff --git a/demos/function/Firebase/functions/package.json b/demos/function/Firebase/functions/package.json
deleted file mode 100644
index 53238b4..0000000
--- a/demos/function/Firebase/functions/package.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-  "name": "functions",
-  "description": "Cloud Functions for Firebase",
-  "scripts": {
-    "serve": "firebase emulators:start --only functions",
-    "shell": "firebase functions:shell",
-    "start": "npm run shell",
-    "deploy": "firebase deploy --only functions",
-    "logs": "firebase functions:log"
-  },
-  "engines": {
-    "node": "8"
-  },
-  "dependencies": {
-    "busboy": "^0.3.1",
-    "firebase-admin": "^8.6.0",
-    "firebase-functions": "^3.3.0",
-    "xlsx": "^0.16.2"
-  },
-  "devDependencies": {
-    "firebase-functions-test": "^0.1.6"
-  },
-  "private": true
-}
diff --git a/demos/function/LambdaProxy/index.js b/demos/function/LambdaProxy/index.js
deleted file mode 100644
index 5d82404..0000000
--- a/demos/function/LambdaProxy/index.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
-/* eslint-env node */
-// base64 sheetjs.xlsb | curl -F "data=@-;filename=test.xlsb" http://localhost:3000/LambdaProxy
-
-'use strict';
-var XLSX = require('xlsx');
-var Busboy = require('busboy');
-
-exports.handler = function(event, context, callback) {
-	/* set up busboy */
-	var ctype = event.headers['Content-Type']||event.headers['content-type'];
-	var bb = new Busboy({headers:{'content-type':ctype}});
-
-	/* busboy is evented; accumulate the fields and files manually */
-	var fields = {}, files = {};
-	bb.on('error', function(err) { console.log('err', err); callback(err); });
-	bb.on('field', function(fieldname, val) {fields[fieldname] = val });
-	bb.on('file', function(fieldname, file, filename) {
-		/* concatenate the individual data buffers */
-		var buffers = [];
-		file.on('data', function(data) { buffers.push(data); });
-		file.on('end', function() { files[fieldname] = [Buffer.concat(buffers), filename]; });
-	});
-
-	/* on the finish event, all of the fields and files are ready */
-	bb.on('finish', function() {
-		/* grab the first file */
-		var f = files[Object.keys(files)[0]];
-		if(!f) callback(new Error("Must submit a file for processing!"));
-
-		/* f[0] is a buffer, convert to string and interpret as Base64 */
-		var wb = XLSX.read(f[0].toString(), {type:"base64"});
-
-		/* grab first worksheet and convert to CSV */
-		var ws = wb.Sheets[wb.SheetNames[0]];
-		callback(null, { body: XLSX.utils.sheet_to_csv(ws) });
-	});
-
-	bb.end(event.body);
-};
diff --git a/demos/function/LambdaProxy/template.yaml b/demos/function/LambdaProxy/template.yaml
deleted file mode 100644
index 43ef45a..0000000
--- a/demos/function/LambdaProxy/template.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-AWSTemplateFormatVersion : '2010-09-09'
-Transform: AWS::Serverless-2016-10-31
-
-Description: Sample Lambda API Gateway Normalizer
-Resources:
-  LambdaProxy:
-    Type: AWS::Serverless::Function
-    Properties:
-      Runtime: nodejs6.10
-      Handler: index.handler
-      BinaryMediaTypes: '*/*'
-      Events:
-        Api:
-          Type: Api
-          Properties:
-            Path: /LambdaProxy
-            Method: any
-            BinaryMediaTypes: '*/*'
diff --git a/demos/function/Makefile b/demos/function/Makefile
deleted file mode 100644
index 1588319..0000000
--- a/demos/function/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-.PHONY: aws
-aws: lambda-proxy
-
-.PHONY: lambda-proxy
-lambda-proxy:
-	cd LambdaProxy; mkdir -p node_modules; npm install https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz busboy; sam local start-api; cd -
-
-.PHONY: init-azure
-init-azure:
-	cd AzureHTTPTrigger; mkdir -p node_modules; npm install https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz formidable fs
-
-.PHONY: azure
-azure: init-azure
-	func start
-
-.PHONY: azure-server
-azure-server:
-	mkdir -p /tmp/azurite
-	azurite -l /tmp/azurite
-
-FILES=$(filter-out xlsx.full.min.js,$(wildcard *.js)) $(wildcard *.html)
-.PHONY: lint
-lint: $(FILES)
-	eslint $(FILES)
-
-.PHONY: clean
-clean:
-	rm -f *.db *.xlsx *.csv
diff --git a/demos/function/README.md b/demos/function/README.md
index c5cd76a..238afbc 100644
--- a/demos/function/README.md
+++ b/demos/function/README.md
@@ -1,113 +1,9 @@
 # "Serverless" Functions
 
-Because the library is pure JS, the hard work of reading and writing files can
-be performed in the client browser or on the server side.  On the server side,
-the mechanical process is essentially independent from the data parsing or
-generation.  As a result, it is sometimes sensible to organize applications so
-that the "last mile" conversion between JSON data and spreadsheet files is
-independent from the main application.
+Cloud services are covered in separate demos:
 
-The straightforward architecture would split off the JSON data conversion as a
-separate microservice or application.  Since it is only needed when an import or
-export is requested, and since the process itself is relatively independent from
-the rest of a typical service, a "Serverless" architecture makes a great fit.
-Since the "function" is separate from the rest of the application, it can be
-integrated into a platform built in Java or Go or Python or another language!
+- [AWS](https://docs.sheetjs.com/docs/demos/aws)
+- [Azure](https://docs.sheetjs.com/docs/demos/azure)
 
-This demo discusses general architectures and provides examples for popular
-commercial systems and self-hosted alternatives.  The examples are merely
-intended to demonstrate very basic functionality.
+[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
 
-
-## Simple Strategies
-
-#### Data Normalization
-
-Most programming languages and platforms can process CSV or JSON but can't use
-XLS or XLSX or XLSB directly.  Form data from an HTTP POST request can be parsed
-and contained files can be converted to CSV or JSON.  The `XLSX.stream.to_csv`
-utility can stream rows to a standard HTTP response.  `XLSX.utils.sheet_to_json`
-can generate an array of objects that can be fed to another service.
-
-At the simplest level, a file on the filesystem can be converted using the bin
-script that ships with the NodeJS package:
-
-```bash
-$ xlsx /path/to/uploads/file > /tmp/new_csv_file
-```
-
-From a utility script, workbooks can be converted in two lines:
-
-```js
-var workbook = XLSX.readFile("path/to/file.xlsb");
-XLSX.writeFile(workbook, "output/path/file.csv");
-```
-
-#### Report Generation
-
-For an existing platform that already generates JSON or CSV or HTML output, the
-library can process the data and generate a new file with embellishments. The
-`XLSX.utils.sheet_add_json` and `XLSX.utils.sheet_add_aoa` functions can add
-data rows to an existing worksheet:
-
-```js
-var ws = XLSX.utils.aoa_to_sheet([
-	["Company Report"],
-	[],
-	["Item", "Cost"]
-]);
-XLSX.utils.sheet_add_json(ws, [
-	{ item: "Coffee", cost: 5 },
-	{ item: "Cake", cost: 20 }
-], { skipHeader: true, origin: -1, header: ["item", "cost"] });
-```
-
-
-## Deployment Targets
-
-The library is supported in Node versions starting from `0.8` as well as a
-myriad of ES3 and ES5 compatible JS engines.  All major services use Node
-versions beyond major release 4, so there should be no problem directly using
-the library in those environments.
-
-Note that most cloud providers proactively convert form data to UTF8 strings.
-This is especially problematic when dealing with XLSX and XLSB files, as they
-naturally contain codes that are not valid UTF8 characters.  As a result, these
-demos specifically handle Base64-encoded files only.  To test on the command
-line, use the `base64` tool to encode data before piping to `curl`:
-
-```
-base64 test.xlsb | curl -F "data=@-;filename=test.xlsb" http://localhost/
-```
-
-#### AWS Lambda
-
-Through the AWS Gateway API, Lambda functions can be triggered on HTTP requests.
-The `LambdaProxy` example reads files from form data and converts to CSV.
-
-When deploying on AWS, be sure to `npm install` locally and include the modules
-in the ZIP file.
-
-When reading form data, be sure to include the necessary binary types on the AWS API Gateway console.
-To do this, navigate to the "Binary Media Types" section in the settings tab of the console.
-For reading a file, you may need to add `"multipart/form-data"`.
-For downloading a file, you may need to add `"application/vnd.ms-excel"`.
-
-#### Azure Functions
-
-Azure supports many types of triggers.  The `AzureHTTPTrigger` shows an example
-HTTP trigger that converts the submitted file to CSV.
-
-When deploying on Azure, be sure to install the module from the remote console,
-as described in the "Azure Functions JavaScript developer guide".
-
-#### Firebase Functions
-
-Firebase functions can be triggered via HTTP requests, similar to a REST API.
-In the `Firebase` directory, the example function reads files sent through
-HTTP and converts it to a CSV and sends the response in the form of a string.
-
-To run this demo locally, run `npm i -g firebase-tools` to install the
-Firebase CLI and `npm i` to install the dependencies, then `firebase use --add`
-to connect to an existing Firebase project. Run `firebase emulators:start` to
-start the local server.
diff --git a/demos/function/host.json b/demos/function/host.json
deleted file mode 100644
index 81e35b7..0000000
--- a/demos/function/host.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "version": "2.0"
-}
\ No newline at end of file
diff --git a/demos/function/local.settings.json b/demos/function/local.settings.json
deleted file mode 100644
index 755966e..0000000
--- a/demos/function/local.settings.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "IsEncrypted": false,
-  "Values": {
-    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
-    "AzureWebJobsDashboard": "UseDevelopmentStorage=true"
-  },
-  "Host": {
-    "LocalHttpPort": 7262,
-    "CORS": "*"
-  }
-}
diff --git a/demos/react/.gitignore b/demos/react/.gitignore
deleted file mode 100644
index 228ee28..0000000
--- a/demos/react/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-SheetJS
-.next
-static/shim.js
-public/shim.js
diff --git a/demos/react/Makefile b/demos/react/Makefile
deleted file mode 100644
index da556c3..0000000
--- a/demos/react/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-.PHONY: react
-react: init ## Simple server for react and clones
-	python -mSimpleHTTPServer
-
-.PHONY: next
-next: init ## next.js demo
-	next
-
-.PHONY: native
-native: ## Build react-native project
-	bash ./native.sh
-
-.PHONY: ios
-ios: native ## react-native ios sim
-	cd SheetJS; cd ios; pod install; cd -; react-native run-ios --simulator="iPhone X"; cd -
-
-.PHONY: android
-android: native ## react-native android sim
-	cd SheetJS; react-native run-android; cd -
-
-.PHONY: init
-init: ## set up node_modules and symlink
-	mkdir -p node_modules
-	cd node_modules; if [ ! -e xlsx ]; then ln -s ../../../ xlsx; fi; cd -
diff --git a/demos/react/NOTES.md b/demos/react/NOTES.md
deleted file mode 100644
index ca6238e..0000000
--- a/demos/react/NOTES.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# Additional Notes
-
-## Java, React Native, Gradle versions
-
-This demo was tested and runs with React Native 0.62.2, Java 11, and Gradle
-3.5.2. Running `make native` will invoke `native.sh`, which uses a fixed version
-of React Native 0.62.2 to build and run the demo.
-
-Make sure you have the correct version of Java (11) installed, since 0.62.2 might
-not work with newer versions of Java.
-
-## Common Issues
-
-```
-ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-```
-
-Add `export JAVA_HOME=<directory>`, replacing `<directory>` with the location of
-your Java install, to your `.bashrc` or any other shell that you are using.
-
-
-
diff --git a/demos/react/README.md b/demos/react/README.md
index ffee578..428f391 100644
--- a/demos/react/README.md
+++ b/demos/react/README.md
@@ -1,154 +1,12 @@
 # React
 
-The `xlsx.core.min.js` and `xlsx.full.min.js` scripts are designed to be dropped
-into web pages with script tags:
+[The new demo](https://docs.sheetjs.com/docs/demos/react) has an updated
+exposition for legacy and modern deployments alike.
 
-```html
-<script src="xlsx.full.min.js"></script>
-```
+The ecosystem demos were grouped by type in the new demo site:
 
-The library can also be imported directly from JSX code with:
-
-```js
-import { read, utils, writeFileXLSX } from 'xlsx';
-```
-
-This demo shows a simple React component transpiled in the browser using Babel
-standalone library.  Since there is no standard React table model, this demo
-settles on the array of arrays approach.
-
-
-Other scripts in this demo show:
-- server-rendered React component (with `next.js`)
-- `react-native` deployment for iOS and android
-- [`react-data-grid` reading, modifying, and writing files](modify/)
-
-## How to run
-
-Run `make react` to run the browser demo for React, or run `make next` to run
-the server-rendered demo using `next.js`.
-
-## Internal State
-
-The simplest state representation is an array of arrays.  To avoid having the
-table component depend on the library, the column labels are precomputed.  The
-state in this demo is shaped like the following object:
-
-```js
-{
-  cols: [{ name: "A", key: 0 }, { name: "B", key: 1 }, { name: "C", key: 2 }],
-  data: [
-    [ "id",    "name", "value" ],
-    [    1, "sheetjs",    7262 ],
-    [    2, "js-xlsx",    6969 ]
-  ]
-}
-```
-
-`sheet_to_json` and `aoa_to_sheet` utility functions can convert between arrays
-of arrays and worksheets:
-
-```js
-/* convert from workbook to array of arrays */
-var first_worksheet = workbook.Sheets[workbook.SheetNames[0]];
-var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
-
-/* convert from array of arrays to workbook */
-var worksheet = XLSX.utils.aoa_to_sheet(data);
-var new_workbook = XLSX.utils.book_new();
-XLSX.utils.book_append_sheet(new_workbook, worksheet, "SheetJS");
-```
-
-The column objects can be generated with the `encode_col` utility function:
-
-```js
-function make_cols(refstr/*:string*/) {
-  var o = [];
-  var range = XLSX.utils.decode_range(refstr);
-  for(var i = 0; i <= range.e.c; ++i) {
-    o.push({name: XLSX.utils.encode_col(i), key:i});
-  }
-  return o;
-}
-```
-
-## React Native
-
-[The new demo](https://docs.sheetjs.com/docs/demos/mobile#react-native) uses
-up-to-date file I/O and file picker libraries.
-
-## Server-Rendered React Components with Next.js
-
-The demo reads from `public/sheetjs.xlsx`.  HTML output is generated using
-`XLSX.utils.sheet_to_html` and inserted with `dangerouslySetInnerHTML`:
-
-```jsx
-export default function Index({html, type}) { return (
-  // ...
-  <div dangerouslySetInnerHTML={{ __html: html }} />
-  // ...
-); }
-```
-
-Next currently offers 3 general strategies for server-side data fetching:
-
-#### "Server-Side Rendering" using `getServerSideProps`
-
-`/getServerSideProps` reads the file on each request.  The first worksheet is
-converted to HTML:
-
-```js
-export async function getServerSideProps() {
-  const wb = XLSX.readFile(path);
-  return { props: {
-    html: utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]])
-  }};
-}
-```
-
-#### "Static Site Generation" using `getStaticProps`
-
-`/getServerSideProps` reads the file at build time.  The first worksheet is
-converted to HTML:
-
-```js
-export async function getStaticProps() {
-  const wb = XLSX.readFile(path);
-  return { props: {
-    html: utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]])
-  }};
-}
-```
-
-#### "Static Site Generation with Dynamic Routes" using `getStaticPaths`
-
-`/getStaticPaths` reads the file at build time and generates a list of sheets.
-
-`/sheets/[id]` uses `getStaticPaths` to generate a path per sheet index:
-
-```js
-export async function getStaticPaths() {
-  const wb = XLSX.readFile(path);
-  return {
-    paths: wb.SheetNames.map((name, idx) => ({ params: { id: idx.toString()  } })),
-    fallback: false
-  };
-}
-```
-
-It also uses `getStaticProps` for the actual HTML generation:
-
-```js
-export async function getStaticProps(ctx) {
-  const wb = XLSX.readFile(path);
-  return { props: {
-    html: utils.sheet_to_html(wb.Sheets[wb.SheetNames[ctx.params.id]]),
-  }};
-}
-```
-
-## Additional Notes
-
-Some additional notes can be found in [`NOTES.md`](NOTES.md).
+- [server-rendered React components with `next.js`](https://docs.sheetjs.com/docs/demos/content#nextjs) is now part of "Content and Site Generation"
+- [`react-native` deployment for iOS and android](https://docs.sheetjs.com/docs/demos/mobile#react-native) is now part of "iOS and Android Apps"
+- [`react-data-grid` reading, modifying, and writing files](https://docs.sheetjs.com/docs/demo/grid#react-data-grid) is now part of "Data Grids and UI"
 
 [![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
diff --git a/demos/react/index.html b/demos/react/index.html
deleted file mode 100644
index 8487db4..0000000
--- a/demos/react/index.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<!-- xlsx.js (C) 2013-present  SheetJS http://sheetjs.com -->
-<!-- vim: set ts=2: -->
-<html lang="en" style="height: 100%">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<title>SheetJS React Demo</title>
-<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
-<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
-<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
-<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
-<script src="node_modules/xlsx/dist/shim.min.js"></script>
-<script src="node_modules/xlsx/dist/xlsx.full.min.js"></script>
-<style>body, #app { height: 100%; };</style>
-</head>
-<body>
-<div class="container-fluid">
-<h1><a href="http://sheetjs.com">SheetJS React Demo</a></h1>
-<br />
-<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a><br />
-<a href="https://github.com/SheetJS/js-xlsx/issues">Issues?  Something look weird?  Click here and report an issue</a><br /><br />
-</div>
-<div id="app" class="container-fluid"></div>
-<script type="text/babel" src="sheetjs.js"></script>
-<script type="text/babel">
-	ReactDOM.render( <SheetJSApp />, document.getElementById('app') );
-</script>
-</body>
-</html>
diff --git a/demos/react/modify/.gitignore b/demos/react/modify/.gitignore
deleted file mode 100644
index 4d29575..0000000
--- a/demos/react/modify/.gitignore
+++ /dev/null
@@ -1,23 +0,0 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-/node_modules
-/.pnp
-.pnp.js
-
-# testing
-/coverage
-
-# production
-/build
-
-# misc
-.DS_Store
-.env.local
-.env.development.local
-.env.test.local
-.env.production.local
-
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
diff --git a/demos/react/modify/README.md b/demos/react/modify/README.md
deleted file mode 100644
index 97180e0..0000000
--- a/demos/react/modify/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# react-modify
-
-This demo shows import and export with the `react-data-grid` table component.
-
-In the project directory, you can run:
-
-```bash
-$ npm install
-$ npm start
-```
diff --git a/demos/react/modify/package.json b/demos/react/modify/package.json
deleted file mode 100644
index dde42e3..0000000
--- a/demos/react/modify/package.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
-  "name": "react-modify-demo",
-  "dependencies": {
-    "@types/react": "^17.0.0",
-    "@types/react-dom": "^17.0.0",
-    "react": "^17.0.2",
-    "react-data-grid": "^7.0.0-beta.11",
-    "react-dom": "^17.0.2",
-    "react-scripts": "4.0.3",
-    "typescript": "^4.1.2",
-    "xlsx": "https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz"
-  },
-  "scripts": {
-    "start": "react-scripts start",
-    "build": "react-scripts build",
-    "eject": "react-scripts eject"
-  },
-  "eslintConfig": {
-    "extends": [
-      "react-app",
-      "react-app/jest"
-    ]
-  },
-  "browserslist": {
-    "production": [
-      ">0.2%",
-      "not dead",
-      "not op_mini all"
-    ],
-    "development": [
-      "last 1 chrome version",
-      "last 1 firefox version",
-      "last 1 safari version"
-    ]
-  }
-}
diff --git a/demos/react/modify/public/index.html b/demos/react/modify/public/index.html
deleted file mode 100644
index aa069f2..0000000
--- a/demos/react/modify/public/index.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8" />
-    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
-    <meta name="viewport" content="width=device-width, initial-scale=1" />
-    <meta name="theme-color" content="#000000" />
-    <meta
-      name="description"
-      content="Web site created using create-react-app"
-    />
-    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
-    <!--
-      manifest.json provides metadata used when your web app is installed on a
-      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-    -->
-    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
-    <!--
-      Notice the use of %PUBLIC_URL% in the tags above.
-      It will be replaced with the URL of the `public` folder during the build.
-      Only files inside the `public` folder can be referenced from the HTML.
-
-      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
-      work correctly both with client-side routing and a non-root public URL.
-      Learn how to configure a non-root public URL by running `npm run build`.
-    -->
-    <title>React App</title>
-  </head>
-  <body>
-    <noscript>You need to enable JavaScript to run this app.</noscript>
-    <div id="root"></div>
-    <!--
-      This HTML file is a template.
-      If you open it directly in the browser, you will see an empty page.
-
-      You can add webfonts, meta tags, or analytics to this file.
-      The build step will place the bundled scripts into the <body> tag.
-
-      To begin the development, run `npm start` or `yarn start`.
-      To create a production bundle, use `npm run build` or `yarn build`.
-    -->
-  </body>
-</html>
diff --git a/demos/react/modify/src/components/App.tsx b/demos/react/modify/src/components/App.tsx
deleted file mode 100644
index 7e979d5..0000000
--- a/demos/react/modify/src/components/App.tsx
+++ /dev/null
@@ -1,107 +0,0 @@
-import React, { useState, ChangeEvent } from "react";
-import DataGrid, { TextEditor } from "react-data-grid";
-import { read, utils, WorkSheet, writeFile } from "xlsx";
-
-import "../styles/App.css";
-
-type Row = any[]; /*{
-  [index: string]: string | number;
-};*/
-
-type Column = {
-  key: string;
-  name: string;
-  editor: typeof TextEditor;
-};
-
-type DataSet = {
-  [index: string]: WorkSheet;
-};
-
-function getRowsCols(
-  data: DataSet,
-  sheetName: string
-): {
-  rows: Row[];
-  columns: Column[];
-} {
-  const rows: Row[] = utils.sheet_to_json(data[sheetName], {header:1});
-  let columns: Column[] = [];
-
-  for (let row of rows) {
-    const keys: string[] = Object.keys(row);
-
-    if (keys.length > columns.length) {
-      columns = keys.map((key) => {
-        return { key, name: utils.encode_col(+key), editor: TextEditor };
-      });
-    }
-  }
-
-  return { rows, columns };
-}
-
-export default function App() {
-  const [rows, setRows] = useState<Row[]>([]);
-  const [columns, setColumns] = useState<Column[]>([]);
-  const [workBook, setWorkBook] = useState<DataSet>({} as DataSet);
-  const [sheets, setSheets] = useState<string[]>([]);
-  const [current, setCurrent] = useState<string>("");
-
-  const exportTypes = ["xlsx", "xlsb", "csv", "html"];
-
-  function selectSheet(name: string, reset = true) {
-    if(reset) workBook[current] = utils.json_to_sheet(rows, {
-      header: columns.map((col: Column) => col.key),
-      skipHeader: true
-    });
-
-    const { rows: new_rows, columns: new_columns } = getRowsCols(workBook, name);
-
-    setRows(new_rows);
-    setColumns(new_columns);
-    setCurrent(name);
-  }
-
-  async function handleFile(ev: ChangeEvent<HTMLInputElement>): Promise<void> {
-    const file = await ev.target.files?.[0]?.arrayBuffer();
-    const data = read(file);
-
-    setWorkBook(data.Sheets);
-    setSheets(data.SheetNames);
-  }
-
-  function saveFile(ext: string): void {
-    const wb = utils.book_new();
-
-    sheets.forEach((n) => {
-      utils.book_append_sheet(wb, workBook[n], n);
-    });
-
-    writeFile(wb, "sheet." + ext);
-  }
-
-  return (
-    <>
-      <input type="file" onChange={handleFile} />
-      <div className="flex-cont">
-        {sheets.map((sheet) => (
-          <button key={sheet} onClick={(e) => selectSheet(sheet)}>
-            {sheet}
-          </button>
-        ))}
-      </div>
-      <div className="flex-cont">
-        <b>Current Sheet: {current}</b>
-      </div>
-      <DataGrid columns={columns} rows={rows} onRowsChange={setRows} />
-      <div className="flex-cont">
-        {exportTypes.map((ext) => (
-          <button key={ext} onClick={() => saveFile(ext)}>
-            export [.{ext}]
-          </button>
-        ))}
-      </div>
-    </>
-  );
-}
diff --git a/demos/react/modify/src/index.tsx b/demos/react/modify/src/index.tsx
deleted file mode 100644
index 270ed1a..0000000
--- a/demos/react/modify/src/index.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import App from './components/App';
-
-import './styles/index.css';
-
-ReactDOM.render(
-  <React.StrictMode>
-    <App/>
-  </React.StrictMode>,
-  document.getElementById('root')
-);
diff --git a/demos/react/modify/src/react-app-env.d.ts b/demos/react/modify/src/react-app-env.d.ts
deleted file mode 100644
index 6431bc5..0000000
--- a/demos/react/modify/src/react-app-env.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="react-scripts" />
diff --git a/demos/react/modify/src/styles/App.css b/demos/react/modify/src/styles/App.css
deleted file mode 100644
index 28b9df9..0000000
--- a/demos/react/modify/src/styles/App.css
+++ /dev/null
@@ -1,14 +0,0 @@
-input {
-  margin: 0.5rem;
-}
-
-.flex-cont {
-  display: flex;
-  margin: 0.5rem;
-  justify-content: center;
-}
-
-.flex-cont button {
-    margin: 0.3rem;
-    padding: 0.2rem;
-}
diff --git a/demos/react/modify/src/styles/index.css b/demos/react/modify/src/styles/index.css
deleted file mode 100644
index 1532074..0000000
--- a/demos/react/modify/src/styles/index.css
+++ /dev/null
@@ -1,8 +0,0 @@
-body {
-  margin: 0;
-  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
-    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
-    sans-serif;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-}
diff --git a/demos/react/modify/tsconfig.json b/demos/react/modify/tsconfig.json
deleted file mode 100644
index 5136b52..0000000
--- a/demos/react/modify/tsconfig.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "compilerOptions": {
-    "target": "es5",
-    "lib": [
-      "dom",
-      "dom.iterable",
-      "esnext"
-    ],
-    "allowJs": true,
-    "skipLibCheck": true,
-    "esModuleInterop": true,
-    "allowSyntheticDefaultImports": true,
-    "forceConsistentCasingInFileNames": true,
-    "strict": true,
-    "noFallthroughCasesInSwitch": true,
-    "module": "esnext",
-    "moduleResolution": "node",
-    "resolveJsonModule": true,
-    "isolatedModules": true,
-    "noEmit": true,
-    "jsx": "react-jsx"
-  },
-  "include": [
-    "src"
-  ]
-}
diff --git a/demos/react/nexthdr.js b/demos/react/nexthdr.js
deleted file mode 100644
index 1ba3dc6..0000000
--- a/demos/react/nexthdr.js
+++ /dev/null
@@ -1,3 +0,0 @@
-/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
-import * as XLSX from 'xlsx';
-import React from 'react';
diff --git a/demos/react/pages/getServerSideProps.js b/demos/react/pages/getServerSideProps.js
deleted file mode 100644
index 55cd11f..0000000
--- a/demos/react/pages/getServerSideProps.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import Head from 'next/head';
-import { readFile, utils } from 'xlsx';
-import { join } from 'path';
-import { cwd } from 'process';
-
-export default function Index({html, type}) { return (
-<div>
-  <Head>
-    <meta httpEquiv="Content-Type" content="text/html; charset=UTF-8" />
-    <title>SheetJS Next.JS {type} Demo</title>
-    <script src="/shim.js"></script>
-    <style jsx>{`
-      body, #app { height: 100%; };
-    `}</style>
-  </Head>
-  <pre>
-<h3>SheetJS Next.JS {type} Demo</h3>
-This demo reads from /public/sheetjs.xlsx and generates HTML from the first sheet.
-  </pre>
-  <div dangerouslySetInnerHTML={{ __html: html }} />
-</div>
-); }
-
-export async function getServerSideProps() {
-  const wb = readFile(join(cwd(), "public", "sheetjs.xlsx"))
-  return {
-    props: {
-      type: "getStaticProps",
-      html: utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]),
-    },
-  }
-}
\ No newline at end of file
diff --git a/demos/react/pages/getStaticPaths.js b/demos/react/pages/getStaticPaths.js
deleted file mode 100644
index 3852295..0000000
--- a/demos/react/pages/getStaticPaths.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import Head from 'next/head';
-import Link from "next/link";
-import { readFile, utils } from 'xlsx';
-import { join } from 'path';
-import { cwd } from 'process';
-
-export default function Index({snames, type}) { return (
-<div>
-  <Head>
-    <meta httpEquiv="Content-Type" content="text/html; charset=UTF-8" />
-    <title>SheetJS Next.JS {type} Demo</title>
-    <script src="/shim.js"></script>
-    <style jsx>{`
-      body, #app { height: 100%; };
-    `}</style>
-  </Head>
-  <pre>
-<h3>SheetJS Next.JS {type} Demo</h3>
-This demo reads from /public/sheetjs.xlsx.  Each worksheet maps to a path:<br/><br/>
-{snames.map((sname, idx) => (<>
-  <Link key={idx} href="/sheets/[id]" as={`/sheets/${idx}`}><a>{`Sheet index=${idx} name="${sname}"`}</a></Link>
-  <br/>
-  <br/>
-</>))}
-
-  </pre>
-</div>
-); }
-
-export async function getStaticProps() {
-  const wb = readFile(join(cwd(), "public", "sheetjs.xlsx"))
-  return {
-    props: {
-      type: "getStaticPaths",
-      snames: wb.SheetNames,
-    },
-  }
-}
\ No newline at end of file
diff --git a/demos/react/pages/getStaticProps.js b/demos/react/pages/getStaticProps.js
deleted file mode 100644
index ca2e304..0000000
--- a/demos/react/pages/getStaticProps.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import Head from 'next/head';
-import { readFile, utils } from 'xlsx';
-import { join } from 'path';
-import { cwd } from 'process';
-
-export default function Index({html, type}) { return (
-<div>
-  <Head>
-    <meta httpEquiv="Content-Type" content="text/html; charset=UTF-8" />
-    <title>SheetJS Next.JS {type} Demo</title>
-    <script src="/shim.js"></script>
-    <style jsx>{`
-      body, #app { height: 100%; };
-    `}</style>
-  </Head>
-  <pre>
-<h3>SheetJS Next.JS {type} Demo</h3>
-This demo reads from /public/sheetjs.xlsx and generates HTML from the first sheet.
-  </pre>
-  <div dangerouslySetInnerHTML={{ __html: html }} />
-</div>
-); }
-
-export async function getStaticProps() {
-  const wb = readFile(join(cwd(), "public", "sheetjs.xlsx"))
-  return {
-    props: {
-      type: "getStaticProps",
-      html: utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]),
-    },
-  }
-}
\ No newline at end of file
diff --git a/demos/react/pages/index.js b/demos/react/pages/index.js
deleted file mode 100644
index c93bccd..0000000
--- a/demos/react/pages/index.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import Head from 'next/head';
-
-export default function Index() { return (
-<div>
-  <Head>
-    <meta httpEquiv="Content-Type" content="text/html; charset=UTF-8" />
-    <title>SheetJS Next.JS Demo</title>
-    <script src="/shim.js"></script>
-    <style jsx>{`
-      body, #app { height: 100%; };
-    `}</style>
-  </Head>
-  <pre>
-<h3>SheetJS Next.JS Demos</h3>
-All demos read from /public/sheetjs.xlsx.<br/>
-<br/>
-- <a href="/getStaticProps">getStaticProps</a><br/>
-<br/>
-- <a href="/getServerSideProps">getServerSideProps</a><br/>
-<br/>
-- <a href="/getStaticPaths">getStaticPaths</a><br/>
-  </pre>
-</div>
-); }
\ No newline at end of file
diff --git a/demos/react/pages/sheets/[id].js b/demos/react/pages/sheets/[id].js
deleted file mode 100644
index 530b675..0000000
--- a/demos/react/pages/sheets/[id].js
+++ /dev/null
@@ -1,51 +0,0 @@
-import Head from 'next/head';
-import { readFile, utils } from 'xlsx';
-import { join } from 'path';
-import { cwd } from 'process';
-
-export default function Index({html, type, name}) { return (
-<div>
-  <Head>
-    <meta httpEquiv="Content-Type" content="text/html; charset=UTF-8" />
-    <title>SheetJS Next.JS {type} Demo</title>
-    <script src="/shim.js"></script>
-    <style jsx>{`
-      body, #app { height: 100%; };
-    `}</style>
-  </Head>
-  <pre>
-<h3>SheetJS Next.JS {type} Demo</h3>
-This demo reads from /public/sheetjs.xlsx.<br/>
-<br/>
-<b>{name}</b>
-  </pre>
-  <div dangerouslySetInnerHTML={{ __html: html }} />
-</div>
-); }
-
-let cache = [];
-
-export async function getStaticProps(ctx) {
-  if(!cache || !cache.length) {
-    const wb = readFile(join(cwd(), "public", "sheetjs.xlsx"));
-    cache = wb.SheetNames.map((name) => ({ name, sheet: wb.Sheets[name] }));
-  }
-  const entry = cache[ctx.params.id];
-  return {
-    props: {
-      type: "getStaticPaths",
-      name: entry.name,
-      id: ctx.params.id.toString(),
-      html: entry.sheet ? utils.sheet_to_html(entry.sheet) : "",
-    },
-  }
-}
-
-export async function getStaticPaths() {
-  const wb = readFile(join(cwd(), "public", "sheetjs.xlsx"));
-  cache = wb.SheetNames.map((name) => ({ name, sheet: wb.Sheets[name] }));
-  return {
-    paths: wb.SheetNames.map((name, idx) => ({ params: { id: idx.toString()  } })),
-    fallback: false,
-  };
-}
diff --git a/demos/react/public/sheetjs.xlsx b/demos/react/public/sheetjs.xlsx
deleted file mode 100644
index 25496b9bf02e58b00d3610e257610798bf251d21..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 10328
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
UEDV@w007d@ADFD%)Ib0IA7+oOumAu6

diff --git a/demos/react/sheetjs.js b/demos/react/sheetjs.js
deleted file mode 100644
index cdb0237..0000000
--- a/demos/react/sheetjs.js
+++ /dev/null
@@ -1,144 +0,0 @@
-/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
-/* Notes:
-   - usage: `ReactDOM.render( <SheetJSApp />, document.getElementById('app') );`
-   - xlsx.full.min.js is loaded in the head of the HTML page
-   - this script should be referenced with type="text/babel"
-   - babel.js in-browser transpiler should be loaded before this script
-*/
-function SheetJSApp() {
-	const [data, setData] = React.useState([]);
-	const [cols, setCols] = React.useState([]);
-
-	const handleFile = (file) => {
-		const reader = new FileReader();
-		reader.onload = (e) => {
-			/* Parse data */
-			const ab = e.target.result;
-			const wb = XLSX.read(ab, {type:'array'});
-			/* Get first worksheet */
-			const wsname = wb.SheetNames[0];
-			const ws = wb.Sheets[wsname];
-			/* Convert array of arrays */
-			const data = XLSX.utils.sheet_to_json(ws, {header:1});
-			/* Update state */
-			setData(data);
-			setCols(make_cols(ws['!ref']))
-		};
-		reader.readAsArrayBuffer(file);
-	}
-
-	const exportFile = () => {
-		/* convert state to workbook */
-		const ws = XLSX.utils.aoa_to_sheet(data);
-		const wb = XLSX.utils.book_new();
-		XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
-		/* generate XLSX file and send to client */
-		XLSX.writeFile(wb, "sheetjs.xlsx")
-	};
-
-	return (
-	<DragDropFile handleFile={handleFile}>
-		<div className="row"><div className="col-xs-12">
-			<DataInput handleFile={handleFile} />
-		</div></div>
-		<div className="row"><div className="col-xs-12">
-			<button disabled={!data.length} className="btn btn-success" onClick={exportFile}>Export</button>
-		</div></div>
-		<div className="row"><div className="col-xs-12">
-			<OutTable data={data} cols={cols} />
-		</div></div>
-	</DragDropFile>
-	);
-}
-
-if(typeof module !== 'undefined') module.exports = SheetJSApp
-
-/* -------------------------------------------------------------------------- */
-
-/*
-  Simple HTML5 file drag-and-drop wrapper
-  usage: <DragDropFile handleFile={handleFile}>...</DragDropFile>
-    handleFile(file:File):void;
-*/
-
-function DragDropFile({ handleFile, children }) {
-	const suppress = (e) => { e.stopPropagation(); e.preventDefault(); };
-	const handleDrop = (e) => { e.stopPropagation(); e.preventDefault();
-		const files = e.dataTransfer.files;
-		if(files && files[0]) handleFile(files[0]);
-	};
-
-	return (
-		<div
-			onDrop={handleDrop}
-			onDragEnter={suppress}
-			onDragOver={suppress}
-		>
-		{children}
-		</div>
-	);
-}
-
-/*
-  Simple HTML5 file input wrapper
-  usage: <DataInput handleFile={callback} />
-    handleFile(file:File):void;
-*/
-
-function DataInput({ handleFile }) {
-	const handleChange = (e) => {
-		const files = e.target.files;
-		if(files && files[0]) handleFile(files[0]);
-	};
-
-	return (
-		<form className="form-inline">
-			<div className="form-group">
-				<label htmlFor="file">Drag or choose a spreadsheet file</label>
-				<br />
-				<input
-					type="file"
-					className="form-control"
-					id="file"
-					accept={SheetJSFT}
-					onChange={handleChange}
-				/>
-			</div>
-		</form>
-	)
-}
-
-/*
-  Simple HTML Table
-  usage: <OutTable data={data} cols={cols} />
-    data:Array<Array<any> >;
-    cols:Array<{name:string, key:number|string}>;
-*/
-function OutTable({ data, cols }) {
-	return (
-		<div className="table-responsive">
-			<table className="table table-striped">
-				<thead>
-					<tr>{cols.map((c) => <th key={c.key}>{c.name}</th>)}</tr>
-				</thead>
-				<tbody>
-					{data.map((r,i) => <tr key={i}>
-						{cols.map(c => <td key={c.key}>{ r[c.key] }</td>)}
-					</tr>)}
-				</tbody>
-			</table>
-		</div>
-	);
-}
-
-/* list of supported file types */
-const SheetJSFT = [
-	"xlsx", "xlsb", "xlsm", "xls", "xml", "csv", "txt", "ods", "fods", "uos", "sylk", "dif", "dbf", "prn", "qpw", "123", "wb*", "wq*", "html", "htm"
-].map(x => `.${x}`).join(",");
-
-/* generate an array of column objects */
-const make_cols = refstr => {
-	let o = [], C = XLSX.utils.decode_range(refstr).e.c + 1;
-	for(var i = 0; i < C; ++i) o[i] = {name:XLSX.utils.encode_col(i), key:i}
-	return o;
-};
diff --git a/demos/server/.gitignore b/demos/server/.gitignore
deleted file mode 100644
index 0bb4e01..0000000
--- a/demos/server/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-xlsx.full.min.js
-xlsx-demo
diff --git a/demos/server/Makefile b/demos/server/Makefile
deleted file mode 100644
index 9a340b6..0000000
--- a/demos/server/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-.PHONY: init
-init:
-	mkdir -p node_modules
-	cd node_modules; if [ ! -e xlsx ]; then ln -s ../../../ xlsx; fi; cd -
-
-.PHONY: request
-request: init ## request demo
-	node _request.js
-
-.PHONY: express
-express: init ## express demo
-	node express.js
-
-.PHONY: koa
-koa: init ## koa demo
-	node koa.js
-
-.PHONY: hapi
-hapi: init ## hapi demo
-	cp ../../dist/xlsx.full.min.js .
-	node hapi.js
-
-.PHONY: nest
-nest: init ## nest demo
-	bash -c ./nest.sh
-
-.PHONY: drash
-drash: ## drash demo
-	deno run --allow-net drash.ts
diff --git a/demos/server/README.md b/demos/server/README.md
index 41df3fd..4f03372 100644
--- a/demos/server/README.md
+++ b/demos/server/README.md
@@ -1,208 +1,11 @@
 # NodeJS Server Deployments
 
-This library is 100% pure JS.  This is great for compatibility but tends to lock
-up long-running processes.  In the web browser, Web Workers are used to offload
-work from the main browser thread.  In NodeJS, there are other strategies.  This
-demo shows a few different strategies applied to different server frameworks.
+[The new demo](https://docs.sheetjs.com/docs/demos/server) has a more focused
+discussion with examples for popular JS server-side frameworks.
 
-NOTE: these examples merely demonstrate the core concepts and do not include
-appropriate error checking or other production-level features.
-
-
-### Express Setup
-
-The following commands are required in order to test the [Express](https://github.com/expressjs/express) demo:
-
-```bash
-npm install express printj express-formidable https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
-node express.js
-```
-
-### Koa Setup
-
-The following commands are required in order to test the [Koa](https://github.com/koajs/koa) demo:
-
-```bash
-npm install koa printj formidable https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
-node koa.js
-```
-
-### Hapi Setup
-
-**Note: Hapi demo as written only works with Hapi version 16 and below.**
-
-The following commands are required in order to test the [Hapi](https://github.com/hapijs/hapi) demo:
-
-```bash
-npm install hapi@16.x printj tiny-worker https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
-node hapi.js
-```
-
-
-
-### Node Buffer
-
-The `read` and `write` functions can handle `Buffer` data with `type:"buffer"`.
-For example, the `request` library returns data in a buffer:
-
-```js
-var XLSX = require('xlsx'), request = require('request');
-request(url, {encoding: null}, function(err, res, data) {
-	if(err || res.statusCode !== 200) return;
-
-	/* data is a node Buffer that can be passed to XLSX.read */
-	var workbook = XLSX.read(data, {type:'buffer'});
-
-	/* DO SOMETHING WITH workbook HERE */
-});
-```
-
-The `readFile` / `writeFile` functions wrap `fs.{read,write}FileSync`:
-
-```js
-/* equivalent to `var wb = XLSX.readFile("sheetjs.xlsx");` */
-var buf = fs.readFileSync("sheetjs.xlsx");
-var wb = XLSX.read(buf, {type:'buffer'});
-```
-
-### Responding to Form Uploads
-
-Using `formidable`, files uploaded to forms are stored to temporary files that
-can be read with `readFile`:
-
-```js
-/* within the server callback function(request, response) { */
-var form = new formidable.IncomingForm();
-form.parse(req, function(err, fields, files) {
-	var f = files[Object.keys(files)[0]];
-	var workbook = XLSX.readFile(f.path);
-	/* DO SOMETHING WITH workbook HERE */
-});
-```
-
-The `node.js` demo shows a plain HTTP server that accepts file uploads and
-converts data to requested output format.
-
-### Example servers
-
-Each example server is expected to hold an array-of-arrays in memory.  They are
-expected to handle:
-
-- `POST /         ` accepts an encoded `file` and updates the internal storage
-- `GET  /?t=<type>` returns the internal storage in the specified type
-- `POST /?f=<name>` reads the local file and updates the internal storage
-- `GET  /?f=<name>` writes the file to the specified name
-
-Testing with cURL is straightforward:
-
-```bash
-# upload sheetjs.csv and update data
-curl -X POST -F "data=@sheetjs.csv" http://localhost:7262/
-# download data in SYLK format
-curl -X GET http://localhost:7262/?t=slk
-# read sheetjs.csv from the server directory
-curl -X POST http://localhost:7262/?f=sheetjs.csv
-# write sheetjs.xlsb in the XLSB format
-curl -X GET http://localhost:7262/?f=sheetjs.xlsb
-```
-
-
-## Main-process logic with express
-
-The most straightforward approach is to handle the data directly in HTTP event
-handlers.  The `buffer` type for `XLSX.read` and `XLSX.write` work with `http`
-module and with express directly.  The following snippet generates a workbook
-based on an array of arrays and sends it to the client:
-
-```js
-function send_aoa_to_client(req, res, data, bookType) {
-	/* generate workbook */
-	var ws = XLSX.utils.aoa_to_sheet(data);
-	var wb = XLSX.utils.book_new();
-	XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
-
-	/* generate buffer */
-	var buf = XLSX.write(wb, {type:'buffer', bookType:bookType || "xlsx"});
-
-	/* send to client */
-	res.status(200).send(buf);
-}
-```
-
-
-## fork with koa
-
-`child_process.fork` provides a light-weight and customizable way to offload
-work from the main server process.  This demo passes commands to a custom child
-process and the child passes back buffers of data.
-
-The main server script is `koa.js` and the worker script is `koasub.js`.  State
-is maintained in the worker script.
-
-
-
-## tiny-worker with hapi
-
-`tiny-worker` provides a Web Worker-like interface.  Binary strings and simple
-objects are readily passed across the Worker divide.
-
-The main server script is `hapi.js` and the worker script is `worker.js`.  State
-is maintained in the server script.
-
-Note: due to an issue with hapi payload parsing, the route `POST /file` is used
-to handle the case of reading from file, so the cURL test is:
-
-```bash
-# upload sheetjs.csv and update data
-curl -X POST -F "data=@sheetjs.csv" http://localhost:7262/
-# download data in SYLK format
-curl -X GET http://localhost:7262/?t=slk
-# read sheetjs.csv from the server directory
-curl -X POST http://localhost:7262/file?f=sheetjs.csv
-# write sheetjs.xlsb in the XLSB format
-curl -X GET http://localhost:7262/?f=sheetjs.xlsb
-```
-
-
-
-## NestJS
-
-[NestJS](https://nestjs.com/) is a Node.js framework for server-side web applications.
-
-This demo uses SheetJS to parse a spreadsheet via a POST API endpoint. The file
-arrives to the endpoint as body `form-data`, accessible using the `file` key.
-After parsing the file, CSV contents of the first worksheet will be returned.
-[Body parsing uses `multer`](https://docs.nestjs.com/techniques/file-upload).
-
-Before running the demo, the NestJS CLI tool must be installed.  The instruction
-is described in the NestJS ["First Steps"](https://docs.nestjs.com/first-steps):
-
-```bash
-npm i -g @nestjs/cli
-make nest
-```
-
-The demo can be tested using the `/sheetjs/upload-xlsx-file` endpoint:
-
-```bash
-curl -X POST -F "file=@test.xlsx" http://localhost:3000/sheetjs/upload-xlsx-file
-```
-
-The included [`nest.sh`](./nest.sh) script creates and configures the project.
-
-
-This demo creates a module and a controller.  The controller handles the actual
-requests (creating the endpoint) while the module is used to configure `multer`.
-
-
-
-## Deno
-
-[`Drash`](https://drash.land/drash/) is a Deno framework for Deno's HTTP server.
-
-The `drash.ts` demo responds to POST requests and responds with HTML previews.
-
-<https://s2c.deno.dev> is a live deployment of the service.
+Cloud services are covered in separate demos:
 
+- [AWS](https://docs.sheetjs.com/docs/demos/aws)
+- [Azure](https://docs.sheetjs.com/docs/demos/azure)
 
 [![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
diff --git a/demos/server/_cors.js b/demos/server/_cors.js
deleted file mode 100644
index 22b04c2..0000000
--- a/demos/server/_cors.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
-var cors = function(req, res) { res.header('Access-Control-Allow-Origin', '*'); };
-cors.mw = function(req, res, next) { cors(req, res); next(); };
-module.exports = cors;
diff --git a/demos/server/_logit.js b/demos/server/_logit.js
deleted file mode 100644
index 94f1a44..0000000
--- a/demos/server/_logit.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
-var sprintf = require('printj').sprintf;
-var logit = function(req, res) {
-	console.log(sprintf("%s %s %d", req.method, req.url, res.statusCode));
-};
-logit.mw = function(req, res, next) { logit(req, res); next(); }
-module.exports = logit;
diff --git a/demos/server/_request.js b/demos/server/_request.js
deleted file mode 100644
index 1e3aee0..0000000
--- a/demos/server/_request.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
-var XLSX = require('xlsx'), request = require('request');
-var url = 'http://www.freddiemac.com/pmms/2017/historicalweeklydata.xls'
-request(url, {encoding: null}, function(err, res, data) {
-	if(err || res.statusCode !== 200) return;
-	var wb = XLSX.read(data, {type:'buffer'});
-	var ws = wb.Sheets[wb.SheetNames[0]];
-	console.log(XLSX.utils.sheet_to_csv(ws, {blankrows:false}));
-});
diff --git a/demos/server/drash.ts b/demos/server/drash.ts
deleted file mode 100644
index 5446b66..0000000
--- a/demos/server/drash.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*! sheetjs (C) 2013-present SheetJS -- http://sheetjs.com */
-// @deno-types="https://cdn.sheetjs.com/xlsx-latest/package/types/index.d.ts"
-import { read, utils, set_cptable } from 'https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs';
-import * as cptable from 'https://cdn.sheetjs.com/xlsx-latest/package/dist/cpexcel.full.mjs';
-set_cptable(cptable);
-
-import * as Drash from "https://deno.land/x/drash@v2.5.4/mod.ts";
-
-
-// Create your resource
-
-class HomeResource extends Drash.Resource {
-  public paths = ["/"];
-
-  public POST(request: Drash.Request, response: Drash.Response) {
-    const file = request.bodyParam<Drash.Types.BodyFile>("file");
-    if (!file) throw new Error("File is required!");
-    var wb = read(file.content, {type: "buffer"});
-    return response.html( utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]));
-  }
-
-  public GET(request: Drash.Request, response: Drash.Response): void {
-    return response.html(`\
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>SheetJS Spreadsheet to HTML Conversion Service</title>
-    <meta charset="utf-8" />
-  </head>
-  <body>
-<pre><h3><a href="//sheetjs.com/">SheetJS</a> Spreadsheet Conversion Service</h3>
-<b>API</b>
-
-Send a POST request to https://s2c.deno.dev/ with the file in the "file" body parameter:
-
-$ curl -X POST -F"file=@test.xlsx" https://s2c.deno.dev/
-
-The response will be an HTML TABLE generated from the first worksheet.
-
-<b>Try it out!</b><form action="/" method="post" enctype="multipart/form-data">
-
-<input type="file" name="file" />
-
-Use the file input element to select a file, then click "Submit"
-
-<button type="submit">Submit</button>
-</form>
-</pre>
-  </body>
-</html>`,
-    );
-  }
-}
-
-// Create and run your server
-const server = new Drash.Server({
-  hostname: "",
-  port: 3000,
-  protocol: "http",
-  resources: [
-    HomeResource,
-  ],
-});
-
-server.run();
-
-console.log(`Server running at ${server.address}.`);
-
diff --git a/demos/server/express.js b/demos/server/express.js
deleted file mode 100644
index 2b50552..0000000
--- a/demos/server/express.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
-
-var fs = require('fs'), path = require('path'), URL = require('url');
-var express = require('express'), app = express();
-var sprintf = require('printj').sprintf;
-var logit = require('./_logit');
-var cors = require('./_cors');
-var data = "a,b,c\n1,2,3".split("\n").map(function(x) { return x.split(","); });
-var XLSX = require('xlsx');
-
-/* helper to generate the workbook object */
-function make_book() {
-	var ws = XLSX.utils.aoa_to_sheet(data);
-	var wb = XLSX.utils.book_new();
-	XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
-	return wb;
-}
-
-function get_data(req, res, type) {
-	var wb = make_book();
-	/* send buffer back */
-	res.status(200).send(XLSX.write(wb, {type:'buffer', bookType:type}));
-}
-
-function get_file(req, res, file) {
-	var wb = make_book();
-	/* write using XLSX.writeFile */
-	XLSX.writeFile(wb, file);
-	res.status(200).send("wrote to " + file + "\n");
-}
-
-function load_data(file) {
-	var wb = XLSX.readFile(file);
-	/* generate array of arrays */
-	data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], {header:1});
-	console.log(data);
-}
-
-function post_data(req, res) {
-	var keys = Object.keys(req.files), k = keys[0];
-	load_data(req.files[k].path);
-	res.status(200).send("ok\n");
-}
-
-function post_file(req, res, file) {
-	load_data(file);
-	res.status(200).send("ok\n");
-}
-app.use(logit.mw);
-app.use(cors.mw);
-app.use(require('express-formidable')());
-app.get('/', function(req, res, next) {
-	var url = URL.parse(req.url, true);
-	if(url.query.t) return get_data(req, res, url.query.t);
-	else if(url.query.f) return get_file(req, res, url.query.f);
-	res.status(403).end("Forbidden");
-});
-app.post('/', function(req, res, next) {
-	var url = URL.parse(req.url, true);
-	if(url.query.f) return post_file(req, res, url.query.f);
-	return post_data(req, res);
-});
-
-var port = +process.argv[2] || +process.env.PORT || 7262;
-app.listen(port, function() { console.log('Serving HTTP on port ' + port); });
diff --git a/demos/server/hapi.js b/demos/server/hapi.js
deleted file mode 100644
index a9db56b..0000000
--- a/demos/server/hapi.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
-var Hapi = require('hapi'), server = new Hapi.Server();
-var logit = require('./_logit');
-var Worker = require('tiny-worker');
-var fs = require('fs');
-var data = "a,b,c\n1,2,3".split("\n").map(x => x.split(","));
-
-function get_data(req, res, type) {
-	var work = new Worker('worker.js');
-	work.onmessage = function(e) {
-		if(e.data.err) console.log(e.data.err);
-		var buf = new Buffer(e.data.data, "binary");
-		return res(buf);
-	};
-	work.postMessage({action:"write", type:type, data:data});
-}
-
-function get_file(req, res, file) {
-	var work = new Worker('worker.js');
-	work.onmessage = function(e) {
-		fs.writeFileSync(file, e.data.data, 'binary');
-		return res("wrote to " + file + "\n");
-	};
-	work.postMessage({action:"write", file:file, data:data});
-}
-
-function post_file(req, res, file) {
-	var work = new Worker('worker.js');
-	work.onmessage = function(e) {
-		data = e.data.data;
-		return res("read from " + file + "\n");
-	};
-	work.postMessage({action:"read", file:file});
-}
-
-function post_data(req, res, type) {
-	var keys = Object.keys(req.payload), k = keys[0];
-	post_file(req, res, req.payload[k].path);
-}
-
-var port = 7262;
-server.connection({ host:'localhost', port: port});
-
-server.route({ method: 'GET', path: '/',
-handler: function(req, res) {
-	logit(req.raw.req, req.raw.res);
-	if(req.query.t) get_data(req, res, req.query.t);
-	else if(req.query.f) get_file(req, res, req.query.f);
-	else res('Forbidden').code(403);
-}});
-server.route({ method: 'POST', path: '/',
-config:{payload:{ output: 'file', parse: true, allow: 'multipart/form-data'}},
-handler: function(req, res) {
-	logit(req.raw.req, req.raw.res);
-	if(req.query.f) return post_file(req, res, req.query.f);
-	return post_data(req, res);
-}});
-server.route({ method: 'POST', path: '/file',
-handler: function(req, res) {
-	logit(req.raw.req, req.raw.res);
-	if(req.query.f) return post_file(req, res, req.query.f);
-	return post_data(req, res);
-}});
-server.start(function(err) {
-	if(err) throw err;
-	console.log('Serving HTTP on port ' + port);
-});
diff --git a/demos/server/koa.js b/demos/server/koa.js
deleted file mode 100644
index 1f1176d..0000000
--- a/demos/server/koa.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
-
-const Koa = require('koa'), app = new Koa();
-const { sprintf } = require('printj');
-const { IncomingForm } = require('formidable');
-const { fork } = require('child_process');
-const logit = require('./_logit');
-const subprocess = fork('koasub.js');
-
-const get_data = async (ctx, type) => {
-	await new Promise((resolve, reject) => {
-		const cb = (data) => {
-			ctx.response.body = Buffer(data);
-			subprocess.removeListener('message', cb);
-			resolve();
-		};
-		subprocess.on('message', cb);
-		subprocess.send(['get data', type]);
-	});
-};
-
-const get_file = async (ctx, file) => {
-	await new Promise((resolve, reject) => {
-		const cb = (data) => {
-			ctx.response.body = Buffer(data);
-			subprocess.removeListener('message', cb);
-			resolve();
-		};
-		subprocess.on('message', cb);
-		subprocess.send(['get file', file]);
-	});
-};
-
-const load_data = async (ctx, file) => {
-	await new Promise((resolve, reject) => {
-		const cb = (data) => {
-			ctx.response.body = "ok\n";
-			subprocess.removeListener('message', cb);
-			resolve();
-		};
-		subprocess.on('message', cb);
-		subprocess.send(['load data', file]);
-	});
-};
-
-const post_data = async (ctx) => {
-	const keys = Object.keys(ctx.request._files), k = keys[0];
-	await load_data(ctx, ctx.request._files[k].path);
-};
-
-app.use(async (ctx, next) => { logit(ctx.req, ctx.res); await next(); });
-app.use(async (ctx, next) => {
-	const form = new IncomingForm();
-	await new Promise((resolve, reject) => {
-		form.parse(ctx.req, (err, fields, files) => {
-			if(err) return reject(err);
-			ctx.request._fields = fields;
-			ctx.request._files = files;
-			resolve();
-		});
-	});
-	await next();
-});
-app.use(async (ctx, next) => {
-	if(ctx.request.method !== 'GET') await next();
-	else if(ctx.request.path !== '/') await next();
-	else if(ctx.request.query.t) await get_data(ctx, ctx.request.query.t);
-	else if(ctx.request.query.f) await get_file(ctx, ctx.request.query.f);
-	else ctx.throw(403, "Forbidden");
-});
-app.use(async (ctx, next) => {
-	if(ctx.request.method !== 'POST') await next();
-	else if(ctx.request.path !== '/') await next();
-	else if(ctx.request.query.f) await load_data(ctx, ctx.request.query.f);
-	else await post_data(ctx);
-});
-
-const port = +process.argv[2] || +process.env.PORT || 7262;
-app.listen(port, () => { console.log('Serving HTTP on port ' + port); });
diff --git a/demos/server/koasub.js b/demos/server/koasub.js
deleted file mode 100644
index 1eeb989..0000000
--- a/demos/server/koasub.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
-const XLSX = require('xlsx');
-let data = "a,b,c\n1,2,3".split("\n").map(x => x.split(","));
-process.on('message', ([m, data] = _) => {
-	switch(m) {
-		case 'load data': load_data(data); break;
-		case 'get data': get_data(data); break;
-		case 'get file': get_file(data); break;
-	}
-});
-
-function load_data(file) {
-	var wb = XLSX.readFile(file);
-	/* generate array of arrays */
-	data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], {header:1});
-	console.log(data);
-	process.send("done");
-}
-
-/* helper to generate the workbook object */
-function make_book() {
-	var ws = XLSX.utils.aoa_to_sheet(data);
-	var wb = XLSX.utils.book_new();
-	XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
-	return wb;
-}
-
-function get_data(type) {
-	var wb = make_book();
-	/* send buffer back */
-	process.send(XLSX.write(wb, {type:'buffer', bookType:type}));
-}
-
-function get_file(file) {
-	var wb = make_book();
-	/* write using XLSX.writeFile */
-	XLSX.writeFile(wb, file);
-	process.send("wrote to " + file + "\n");
-}
diff --git a/demos/server/nest.sh b/demos/server/nest.sh
deleted file mode 100755
index ce3f07d..0000000
--- a/demos/server/nest.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-
-# it is assumed that @nestjs/cli is installed globally
-
-if [ ! -e xlsx-demo ]; then
-	nest new -p npm xlsx-demo
-fi
-
-cd xlsx-demo
-npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
-npm i --save-dev @types/multer
-
-if [ ! -e src/sheetjs/sheetjs.module.ts ]; then
-	nest generate module sheetjs
-fi
-
-if [ ! -e src/sheetjs/sheetjs.controller.ts ]; then
-	nest generate controller sheetjs
-fi
-
-cp ../sheetjs.module.ts src/sheetjs/
-cp ../sheetjs.controller.ts src/sheetjs/
-mkdir -p upload
-npm run start
diff --git a/demos/server/nodejs.js b/demos/server/nodejs.js
deleted file mode 100644
index 7b54d37..0000000
--- a/demos/server/nodejs.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
-
-var http = require('http');
-var XLSX = require('xlsx');
-var formidable = require('formidable');
-var html = "";
-var PORT = 3000;
-
-var extmap = {};
-
-var server = http.createServer(function(req, res) {
-	if(req.method !== 'POST') return res.end(html);
-	var form = new formidable.IncomingForm();
-	form.parse(req, function(err, fields, files) {
-		var f = files[Object.keys(files)[0]];
-		var wb = XLSX.readFile(f.path);
-		var ext = (fields.bookType || "xlsx").toLowerCase();
-		res.setHeader('Content-Disposition', 'attachment; filename="download.' + (extmap[ext] || ext) + '";');
-		res.end(XLSX.write(wb, {type:"buffer", bookType:ext}));
-	});
-}).listen(PORT);
-
-html = [
-'<pre>',
-'<h3><a href="http://sheetjs.com/">SheetJS File Converter</a></h3>',
-'Upload a file to convert the contents to another format.',
-'',
-'<b>Form Fields</b>:',
-'- bookType: output format type (defaults to "XLSX")',
-'- basename: basename for output file (defaults to "download")',
-'',
-'<form method="POST" enctype="multipart/form-data" action="/">',
-'<input type="file" id="file" name="file"/>',
-'<select name="bookType">',
-[
-	["xlsb",  "XLSB"],
-	["xlsx",  "XLSX"],
-	["xlsm",  "XLSM"],
-	["biff8", "BIFF8 XLS"],
-	["biff5", "BIFF5 XLS"],
-	["biff2", "BIFF2 XLS"],
-	["xlml",  "SSML 2003"],
-	["ods",   "ODS"],
-	["fods",  "Flat ODS"],
-	["csv",   "CSV"],
-	["txt",   "Unicode Text"],
-	["sylk",  "Symbolic Link"],
-	["html",  "HTML"],
-	["dif",   "DIF"],
-	["dbf",   "DBF"],
-	["rtf",   "RTF"],
-	["prn",   "Lotus PRN"],
-	["eth",   "Ethercalc"],
-].map(function(x) { return '  <option value="' + x[0] + '">' + x[1] + '</option>'; }).join("\n"),
-'</select>',
-'<input type="submit" value="Submit Form">',
-'</form>',
-'',
-'<b>Form code:</b>',
-'&lt;form method="POST" enctype="multipart/form-data" action="/"&gt;',
-'&lt;input type="file" id="file" name="file"/&gt;',
-'&lt;select name="bookType"&gt',
-'&lt;!-- options here --&gt;',
-'&lt;/select&gt',
-'&lt;input type="submit" value="Submit Form"&gt;',
-'&lt;/form&gt;',
-'',
-'<b>fetch Code:</b>',
-'var blob = new Blob("1,2,3\\n4,5,6".split("")); // original file',
-'var fd = new FormData();',
-'fd.set("data", blob, "foo.bar");',
-'fd.set("bookType", "xlsb");',
-'var res = await fetch("/", {method:"POST", body:fd});',
-'var data = await res.arrayBuffer();',
-'</pre>'
-].join("\n");
-
-extmap = {
-	"biff2" : "xls",
-	"biff5" : "xls",
-	"biff8" : "xls",
-	"xlml"  : "xls"
-};
-console.log('listening on port ' + PORT);
diff --git a/demos/server/sheetjs.controller.ts b/demos/server/sheetjs.controller.ts
deleted file mode 100644
index bad90eb..0000000
--- a/demos/server/sheetjs.controller.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Controller, Logger, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
-import { FileInterceptor } from '@nestjs/platform-express';
-import { readFile, utils } from 'xlsx';
-
-@Controller('sheetjs')
-export class SheetjsController {
-  private readonly logger = new Logger(SheetjsController.name);
-
-  @Post('upload-xlsx-file')
-  @UseInterceptors(FileInterceptor('file'))
-  async uploadXlsxFile(@UploadedFile() file: Express.Multer.File) {
-    // Open the uploaded XLSX file and perform SheetJS operations
-    const workbook = readFile(file.path);
-    const firstSheet = workbook.Sheets[workbook.SheetNames[0]];
-    const output = utils.sheet_to_csv(firstSheet);
-    this.logger.log(output);
-    return output;
-  }
-}
diff --git a/demos/server/sheetjs.csv b/demos/server/sheetjs.csv
deleted file mode 100644
index eddbf8a..0000000
--- a/demos/server/sheetjs.csv
+++ /dev/null
@@ -1,19 +0,0 @@
-Text,Number,Rich,Span
-This is Bold,123,This is Bold,This is Bold
-This is Italic,234,This is Italic,This is Italic
-This is Underline,345,This is Underline,This is Underline
-This is Stricken,456,This is Stricken,This is Stricken
-This is 18 px,567,This is 18 px,This is 18 px
-This is superscript,678,This is superscript,This is superscript
-This is subscript,789,This is subscript,This is subscript
-This is red,135,This is red,This is red
-This is green,246,This is green,This is green
-This is Times,357,This is Times,This is Times
-This is BIU,159,This is 01324576 yes,This is BIU
-BG Green,255,White on Blue,Green on Black
-Standard Newline,W S,"BR
-New  line","Pre
-New line"
-Height,100,px (not pt),yeah
-Top Left,80,Middle Center,Bottom Right
-Top Right,60,Bottom Center,Bottom Left
diff --git a/demos/server/sheetjs.module.ts b/demos/server/sheetjs.module.ts
deleted file mode 100644
index 4dd9a53..0000000
--- a/demos/server/sheetjs.module.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Module } from '@nestjs/common';
-import { SheetjsController } from './sheetjs.controller';
-import { MulterModule } from '@nestjs/platform-express';
-
-@Module({
-  controllers: [SheetjsController],
-  imports: [
-    MulterModule.register({
-      dest: './upload',
-    }),
-  ],
-})
-export class SheetjsModule {}
diff --git a/demos/server/worker.js b/demos/server/worker.js
deleted file mode 100644
index c8e1a63..0000000
--- a/demos/server/worker.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
-var XLSX = require('xlsx');
-var fs = require('fs');
-
-onmessage = function(e) {
-	try { switch(e.data.action) {
-		case 'write':
-			var ws = XLSX.utils.aoa_to_sheet(e.data.data);
-			var wb = XLSX.utils.book_new();
-			XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
-			postMessage({data: XLSX.write(wb, {type:'binary', bookType:e.data.type || e.data.file.match(/\.([^\.]*)$/)[1]})});
-			break;
-		case 'read':
-			var wb;
-			if(e.data.file) wb = XLSX.readFile(e.data.file);
-			else wb = XLSX.read(e.data.data);
-			var ws = wb.Sheets[wb.SheetNames[0]];
-			postMessage({data: XLSX.utils.sheet_to_json(ws, {header:1})});
-			break;
-		default: throw "unknown action";
-	}} catch(e) { postMessage({err:e.message || e}); }
-};
diff --git a/demos/vue/Makefile b/demos/vue/Makefile
deleted file mode 100644
index 0adece9..0000000
--- a/demos/vue/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-.PHONY: vue
-vue: ## Simple server for vue
-	python -mSimpleHTTPServer || python3 -mhttp.server
diff --git a/demos/vue/README.md b/demos/vue/README.md
index c364a8a..6229e41 100644
--- a/demos/vue/README.md
+++ b/demos/vue/README.md
@@ -1,83 +1,12 @@
 # VueJS
 
-The `xlsx.core.min.js` and `xlsx.full.min.js` scripts are designed to be dropped
-into web pages with script tags:
+[The new demo](https://docs.sheetjs.com/docs/demos/vue) has an updated
+exposition for legacy and modern deployments alike.
 
-```html
-<script src="xlsx.full.min.js"></script>
-```
+The ecosystem demos were grouped by type in the new demo site:
 
-The library can also be imported directly from single-file components with:
-
-```js
-// full import
-import * as XLSX from 'xlsx';
-
-// named imports
-import { read, utils, writeFileXLSX } from 'xlsx';
-```
-
-This demo directly generates HTML using `sheet_to_html` and adds an element to
-a pre-generated template.  It also has a button for exporting as XLSX.
-
-Other scripts in this demo show:
-- server-rendered VueJS component (with `nuxt.js`)
-- `weex` deployment for iOS
-
-## Internal State
-
-The plain JS demo embeds state in the DOM.  Other demos use proper state.
-
-The simplest state representation is an array of arrays.  To avoid having the
-table component depend on the library, the column labels are precomputed.  The
-state in this demo is shaped like the following object:
-
-```js
-{
-  cols: [{ name: "A", key: 0 }, { name: "B", key: 1 }, { name: "C", key: 2 }],
-  data: [
-    [ "id",    "name", "value" ],
-    [    1, "sheetjs",    7262 ],
-    [    2, "js-xlsx",    6969 ]
-  ]
-}
-```
-
-`sheet_to_json` and `aoa_to_sheet` utility functions can convert between arrays
-of arrays and worksheets:
-
-```js
-/* convert from workbook to array of arrays */
-var first_worksheet = workbook.Sheets[workbook.SheetNames[0]];
-var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
-
-/* convert from array of arrays to workbook */
-var worksheet = XLSX.utils.aoa_to_sheet(data);
-var new_workbook = XLSX.utils.book_new();
-XLSX.utils.book_append_sheet(new_workbook, worksheet, "SheetJS");
-```
-
-The column objects can be generated with the `encode_col` utility function:
-
-```js
-function make_cols(refstr/*:string*/) {
-  var o = [];
-  var range = XLSX.utils.decode_range(refstr);
-  for(var i = 0; i <= range.e.c; ++i) {
-    o.push({name: XLSX.utils.encode_col(i), key:i});
-  }
-  return o;
-}
-```
-
-## Mobile Apps
-
-[The new demo](https://docs.sheetjs.com/docs/demos/mobile#quasar) uses the
-Quasar Framework in a VueJS + Vite project to generate a native iOS app.
-
-## Nuxt Content
-
-[The new demo](https://docs.sheetjs.com/docs/demos/content#nuxtjs) includes a
-complete example starting from `create-nuxt-app`.
+- [Nuxt Content](https://docs.sheetjs.com/docs/demos/content#nuxtjs) is now part of "Content and Site Generation"
+- [The new iOS app demo](https://docs.sheetjs.com/docs/demos/mobile#quasar) uses the Quasar Framework in a VueJS + Vite project to generate a native iOS app.
+- [`vue3-table-lite` reading, modifying, and writing files](https://docs.sheetjs.com/docs/demo/grid#vue3-table-lite) is now part of "Data Grids and UI"
 
 [![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
diff --git a/demos/vue/SheetJS-vue.js b/demos/vue/SheetJS-vue.js
deleted file mode 100644
index a21d563..0000000
--- a/demos/vue/SheetJS-vue.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
-var SheetJSFT = [
-	"xlsx", "xlsb", "xlsm", "xls", "xml", "csv", "txt", "ods", "fods", "uos", "sylk", "dif", "dbf", "prn", "qpw", "123", "wb*", "wq*", "html", "htm", "numbers"
-].map(function(x) { return "." + x; }).join(",");
-
-var SJSTemplate = [
-	'<div>',
-		'<input type="file" multiple="false" id="sheetjs-input" accept="' + SheetJSFT + '" @change="onchange" />',
-		'<br/>',
-		'<button type="button" id="export-table" style="visibility:hidden" @click="onexport">Export to XLSX</button>',
-		'<br/>',
-		'<div id="out-table"></div>',
-	'</div>'
-].join("");
-var component_struct = {
-	template: SJSTemplate,
-	methods: {
-		onchange: function(evt) {
-			var file;
-			var files = evt.target.files;
-
-			if (!files || files.length == 0) return;
-
-			file = files[0];
-
-			var reader = new FileReader();
-			reader.onload = function (e) {
-				// pre-process data
-				var binary = "";
-				var bytes = new Uint8Array(e.target.result);
-				var length = bytes.byteLength;
-				for (var i = 0; i < length; i++) {
-					binary += String.fromCharCode(bytes[i]);
-				}
-
-				/* read workbook */
-				var wb = XLSX.read(binary, {type: 'binary'});
-
-				/* grab first sheet */
-				var wsname = wb.SheetNames[0];
-				var ws = wb.Sheets[wsname];
-
-				/* generate HTML */
-				var HTML = XLSX.utils.sheet_to_html(ws);
-
-				/* update table */
-				document.getElementById('out-table').innerHTML = HTML;
-				/* show export button */
-				document.getElementById('export-table').style.visibility = "visible";
-			};
-
-			reader.readAsArrayBuffer(file);
-		},
-		onexport: function(evt) {
-			/* generate workbook object from table */
-			var wb = XLSX.utils.table_to_book(document.getElementById('out-table'));
-			/* generate file and force a download*/
-			XLSX.writeFile(wb, "sheetjs.xlsx");
-		}
-	}
-};
-var app;
-if(Vue.component) {
-	Vue.component('html-preview', component_struct);
-} else {
-	app = Vue.createApp({});
-	app.component('html-preview', component_struct);
-}
diff --git a/demos/vue/index2.html b/demos/vue/index2.html
deleted file mode 100644
index 1870671..0000000
--- a/demos/vue/index2.html
+++ /dev/null
@@ -1,63 +0,0 @@
-<!DOCTYPE html>
-<!-- xlsx.js (C) 2013-present  SheetJS http://sheetjs.com -->
-<!-- vim: set ts=2: -->
-<html>
-<head>
-	<title>SheetJS + VueJS2</title>
-	<!-- Vue 2 -->
-	<script src="https://unpkg.com/vue@2.x"></script>
-
-	<!-- Various shims -->
-	<script src="shim.js"></script>
-
-	<!-- SheetJS js-xlsx library -->
-	<script src="xlsx.full.min.js"></script>
-
-	<!-- SheetJS Vue components -->
-	<script src="SheetJS-vue.js"></script>
-
-<style>
-.grid1 {
-	width: 500px;
-	height: 400px;
-};
-</style>
-</head>
-<body>
-<pre>
-<b><a href="http://sheetjs.com">SheetJS + VueJS2 demo</a></b>
-
-The core library can be used as-is in Vue applications.
-The <a href="https://github.com/sheetjs/js-xlsx">Community Edition README</a> details some common use cases.
-We also have some <a href="http://sheetjs.com/demos/">more public demos</a>
-
-This demo shows a sample Vue component "html-preview" that:
-- displays a file input that accepts a spreadsheet file
-- draws the first worksheet of a submitted file as HTML
-- presents an export button to generate XLSX files
-
-<a href="https://obamawhitehouse.archives.gov/sites/default/files/omb/budget/fy2014/assets/receipts.xls">Sample Spreadsheet</a>
-</pre>
-<script type="text/javascript">
-	var _gaq = _gaq || [];
-	_gaq.push(['_setAccount', 'UA-36810333-1']);
-	_gaq.push(['_trackPageview']);
-
-	(function() {
-		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
-		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
-		var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
-	})();
-</script>
-
-<div id="app">
-	<html-preview></html-preview>
-</div>
-
-<script lang="javascript">
-if(Vue.component) var app = new Vue({ el: '#app' });
-else app.mount('#app');
-</script>
-</body>
-</html>
-
diff --git a/demos/vue/index3.html b/demos/vue/index3.html
deleted file mode 100644
index c095d70..0000000
--- a/demos/vue/index3.html
+++ /dev/null
@@ -1,63 +0,0 @@
-<!DOCTYPE html>
-<!-- xlsx.js (C) 2013-present  SheetJS http://sheetjs.com -->
-<!-- vim: set ts=2: -->
-<html>
-<head>
-	<title>SheetJS + VueJS3</title>
-	<!-- Vue 2 -->
-	<script src="https://unpkg.com/vue@3.x"></script>
-
-	<!-- Various shims -->
-	<script src="shim.js"></script>
-
-	<!-- SheetJS js-xlsx library -->
-	<script src="xlsx.full.min.js"></script>
-
-	<!-- SheetJS Vue components -->
-	<script src="SheetJS-vue.js"></script>
-
-<style>
-.grid1 {
-	width: 500px;
-	height: 400px;
-};
-</style>
-</head>
-<body>
-<pre>
-<b><a href="http://sheetjs.com">SheetJS + VueJS3 demo</a></b>
-
-The core library can be used as-is in Vue applications.
-The <a href="https://github.com/sheetjs/js-xlsx">Community Edition README</a> details some common use cases.
-We also have some <a href="http://sheetjs.com/demos/">more public demos</a>
-
-This demo shows a sample Vue component "html-preview" that:
-- displays a file input that accepts a spreadsheet file
-- draws the first worksheet of a submitted file as HTML
-- presents an export button to generate XLSX files
-
-<a href="https://obamawhitehouse.archives.gov/sites/default/files/omb/budget/fy2014/assets/receipts.xls">Sample Spreadsheet</a>
-</pre>
-<script type="text/javascript">
-	var _gaq = _gaq || [];
-	_gaq.push(['_setAccount', 'UA-36810333-1']);
-	_gaq.push(['_trackPageview']);
-
-	(function() {
-		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
-		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
-		var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
-	})();
-</script>
-
-<div id="app">
-	<html-preview></html-preview>
-</div>
-
-<script lang="javascript">
-if(Vue.component) var app = new Vue({ el: '#app' });
-else app.mount('#app');
-</script>
-</body>
-</html>
-
diff --git a/demos/vue/modify/.gitignore b/demos/vue/modify/.gitignore
deleted file mode 100644
index a547bf3..0000000
--- a/demos/vue/modify/.gitignore
+++ /dev/null
@@ -1,24 +0,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
-node_modules
-dist
-dist-ssr
-*.local
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/demos/vue/modify/README.md b/demos/vue/modify/README.md
deleted file mode 100644
index 4d76306..0000000
--- a/demos/vue/modify/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# vue-modify
-
-This demo shows import an export with `vue3-table-light` table component.
-
-In this directory, run
-
-```bash
-npm i
-npm run dev
-```
diff --git a/demos/vue/modify/index.html b/demos/vue/modify/index.html
deleted file mode 100644
index 867581c..0000000
--- a/demos/vue/modify/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <link rel="icon" type="image/svg+xml" href="favicon.svg" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>Vite App</title>
-  </head>
-  <body>
-    <div id="app"></div>
-    <script type="module" src="/src/main.ts"></script>
-  </body>
-</html>
diff --git a/demos/vue/modify/package.json b/demos/vue/modify/package.json
deleted file mode 100644
index e39cc11..0000000
--- a/demos/vue/modify/package.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "name": "vue-modify",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "dev": "vite --host",
-    "build": "vue-tsc --noEmit && vite build",
-    "preview": "vite preview"
-  },
-  "dependencies": {
-    "vue": "^3.2.25",
-    "vue3-table-lite": "^1.1.7-1",
-    "xlsx": "https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz"
-  },
-  "devDependencies": {
-    "@vitejs/plugin-vue": "^2.2.0",
-    "typescript": "^4.5.4",
-    "vite": "^2.8.0",
-    "vue-tsc": "^0.29.8"
-  }
-}
diff --git a/demos/vue/modify/src/App.vue b/demos/vue/modify/src/App.vue
deleted file mode 100644
index 2b1f5ec..0000000
--- a/demos/vue/modify/src/App.vue
+++ /dev/null
@@ -1,241 +0,0 @@
-<script setup lang="ts">
-import { ref } from "vue";
-import { read, utils, writeFile, WorkBook } from "xlsx";
-
-import VueTableLite from "vue3-table-lite/ts";
-
-type DataSet = {
-  [index: string]: WorkBook;
-};
-
-type Row = any[];
-
-type Column = {
-  field: string;
-  label: string;
-  display: (row: Row) => string;
-};
-
-const currFileName = ref<string>("");
-const currSheet = ref<string>("");
-const sheets = ref<string[]>([]);
-const workBook = ref<DataSet>({} as DataSet);
-const rows = ref<Row[]>([]);
-const columns = ref<Column[]>([]);
-
-const exportTypes: string[] = ["xlsx", "xlsb", "csv", "html"];
-
-let cell = 0;
-
-function resetCell() {
-  cell = 0;
-}
-
-function display(col: number): (row: Row) => string {
-  return function (row: Row) {
-    return `<span
-               style="user-select: none; display: block"
-               position="${Math.floor(cell++ / columns.value.length)}.${col}"
-               onblur="endEdit(event)"
-               ondblclick="startEdit(event)"
-               onkeydown="endEdit(event)">${row[col] ?? "&nbsp;"}</span>`;
-  };
-}
-
-window.startEdit = function (ev) {
-  ev.target.contentEditable = true;
-  ev.target.focus();
-};
-
-window.endEdit = function (ev) {
-  if (ev.key === undefined || ev.key === "Enter") {
-    const pos = ev.target.getAttribute("position").split(".");
-
-    ev.target.contentEditable = false;
-
-    rows.value[pos[0]][pos[1]] = ev.target.innerText;
-
-    workBook.value[currSheet.value] = utils.json_to_sheet(rows.value, {
-      header: columns.value.map((col: Column) => col.field),
-      skipHeader: true,
-    });
-  }
-};
-
-function getRowsCols(
-  data: DataSet,
-  sheetName: string
-): {
-  rows: Row[];
-  cols: Column[];
-} {
-  const rows: Row[] = utils.sheet_to_json(data[sheetName], { header: 1 });
-  let cols: Column[] = [];
-
-  for (let row of rows) {
-    const keys: string[] = Object.keys(row);
-
-    if (keys.length > cols.length) {
-      cols = keys.map((key) => {
-        return {
-          field: key,
-          label: utils.encode_col(+key),
-          display: display(key),
-        };
-      });
-    }
-  }
-
-  return { rows, cols };
-}
-
-async function importFile(ev: ChangeEvent<HTMLInputElement>): Promise<void> {
-  const file = ev.target.files[0];
-  const data = read(await file.arrayBuffer());
-
-  currFileName.value = file.name;
-  currSheet.value = data.SheetNames?.[0];
-  sheets.value = data.SheetNames;
-  workBook.value = data.Sheets;
-
-  selectSheet(currSheet.value);
-}
-
-function exportFile(type: string): void {
-  const wb = utils.book_new();
-
-  sheets.value.forEach((sheet) => {
-    utils.book_append_sheet(wb, workBook.value[sheet], sheet);
-  });
-
-  writeFile(wb, `sheet.${type}`);
-}
-
-function selectSheet(sheet: string): void {
-  const { rows: newRows, cols: newCols } = getRowsCols(workBook.value, sheet);
-
-  resetCell();
-
-  rows.value = newRows;
-  columns.value = newCols;
-  currSheet.value = sheet;
-}
-</script>
-
-<template>
-  <header class="imp-exp">
-    <div class="import">
-      <input type="file" id="import" @change="importFile" />
-      <label for="import">import</label>
-    </div>
-    <span>{{ currFileName || "vue-modify demo" }}</span>
-    <div class="export">
-      <span>export</span>
-      <ul>
-        <li v-for="type in exportTypes" @click="exportFile(type)">
-          {{ `.${type}` }}
-        </li>
-      </ul>
-    </div>
-  </header>
-  <div class="sheets">
-    <span
-      v-for="sheet in sheets"
-      @click="selectSheet(sheet)"
-      :class="[currSheet === sheet ? 'selected' : '']"
-    >
-      {{ sheet }}
-    </span>
-  </div>
-  <vue-table-lite
-    :is-static-mode="true"
-    :page-size="50"
-    :columns="columns"
-    :rows="rows"
-  ></vue-table-lite>
-</template>
-
-<style>
-.imp-exp {
-  display: flex;
-  justify-content: space-between;
-  padding: 0.5rem;
-  font-family: mono;
-  color: #212529;
-}
-
-.import {
-  font-size: medium;
-}
-
-.import input {
-  position: absolute;
-  opacity: 0;
-  cursor: pointer;
-}
-
-.import label {
-  background-color: white;
-  border: 1px solid;
-  padding: 0.3rem;
-}
-
-.export: hover {
-  border-bottom: none;
-}
-
-.export:hover ul {
-  display: block;
-}
-
-.export span {
-  padding: 0.3rem;
-  border: 1px solid;
-  cursor: pointer;
-}
-
-.export ul {
-  display: none;
-  position: absolute;
-  z-index: 5;
-  background-color: white;
-  list-style: none;
-  padding: 0.3rem;
-  border: 1px solid;
-  margin-top: 0.3rem;
-  border-top: none;
-}
-
-.export ul li {
-  padding: 0.3rem;
-  text-align: center;
-}
-
-.export ul li:hover {
-  background-color: lightgray;
-  cursor: pointer;
-}
-
-.sheets {
-  display: flex;
-  justify-content: center;
-  margin: 0.3rem;
-  color: #212529;
-}
-
-.sheets span {
-  border: 1px solid;
-  padding: 0.5rem;
-  margin: 0.3rem;
-}
-
-.sheets span:hover:not(.selected) {
-  background-color: lightgray;
-  cursor: pointer;
-}
-
-.selected {
-  background-color: #343a40;
-  color: white;
-}
-</style>
diff --git a/demos/vue/modify/src/env.d.ts b/demos/vue/modify/src/env.d.ts
deleted file mode 100644
index aafef95..0000000
--- a/demos/vue/modify/src/env.d.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-/// <reference types="vite/client" />
-
-declare module '*.vue' {
-  import type { DefineComponent } from 'vue'
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
-  const component: DefineComponent<{}, {}, any>
-  export default component
-}
diff --git a/demos/vue/modify/src/main.ts b/demos/vue/modify/src/main.ts
deleted file mode 100644
index 684d042..0000000
--- a/demos/vue/modify/src/main.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import { createApp } from 'vue';
-import App from './App.vue';
-
-createApp(App).mount('#app');
diff --git a/demos/vue/modify/tsconfig.json b/demos/vue/modify/tsconfig.json
deleted file mode 100644
index af31eb8..0000000
--- a/demos/vue/modify/tsconfig.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "compilerOptions": {
-    "target": "esnext",
-    "useDefineForClassFields": true,
-    "module": "esnext",
-    "moduleResolution": "node",
-    "strict": true,
-    "jsx": "preserve",
-    "sourceMap": true,
-    "resolveJsonModule": true,
-    "esModuleInterop": true,
-    "lib": ["esnext", "dom"]
-  },
-  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
-  "references": [{ "path": "./tsconfig.node.json" }]
-}
diff --git a/demos/vue/modify/tsconfig.node.json b/demos/vue/modify/tsconfig.node.json
deleted file mode 100644
index e993792..0000000
--- a/demos/vue/modify/tsconfig.node.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "compilerOptions": {
-    "composite": true,
-    "module": "esnext",
-    "moduleResolution": "node"
-  },
-  "include": ["vite.config.ts"]
-}
diff --git a/demos/vue/modify/vite.config.ts b/demos/vue/modify/vite.config.ts
deleted file mode 100644
index 315212d..0000000
--- a/demos/vue/modify/vite.config.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { defineConfig } from 'vite'
-import vue from '@vitejs/plugin-vue'
-
-// https://vitejs.dev/config/
-export default defineConfig({
-  plugins: [vue()]
-})
diff --git a/demos/vue/shim.js b/demos/vue/shim.js
deleted file mode 120000
index 7ec5819..0000000
--- a/demos/vue/shim.js
+++ /dev/null
@@ -1 +0,0 @@
-../../shim.js
\ No newline at end of file
diff --git a/demos/vue/xlsx.full.min.js b/demos/vue/xlsx.full.min.js
deleted file mode 120000
index dbca48d..0000000
--- a/demos/vue/xlsx.full.min.js
+++ /dev/null
@@ -1 +0,0 @@
-../../dist/xlsx.full.min.js
\ No newline at end of file
diff --git a/demos/xspreadsheet/README.md b/demos/xspreadsheet/README.md
index 2321769..5d21b9e 100644
--- a/demos/xspreadsheet/README.md
+++ b/demos/xspreadsheet/README.md
@@ -5,62 +5,14 @@ with other JS libraries such as data grids for previewing data.  With a familiar
 UI, [`x-spreadsheet`](https://myliang.github.io/x-spreadsheet/) is an excellent
 choice for developers looking for a modern editor.
 
-This demo is available at <https://oss.sheetjs.com/sheetjs/x-spreadsheet.html>
+[The new docs](https://docs.sheetjs.com/docs/demos/grid/#x-spreadsheet)
+include more detail and examples.
 
-## Obtaining the Library
+The original demo is available at <https://docs.sheetjs.com/xspreadsheet/>
 
-The `x-data-spreadsheet` NodeJS packages include a minified script that can be
-directly inserted as a script tag.  The unpkg CDN also serves this script:
+A hosted version of the `xlsxspread.js` script is available on the SheetJS CDN:
 
-```html
-<script src="https://unpkg.com/x-data-spreadsheet/dist/xspreadsheet.js"></script>
-```
-
-## Previewing Data
-
-The HTML document needs a container element:
-
-```html
-<div id="gridctr"></div>
-```
-
-Grid initialization is a one-liner:
-
-```js
-/* note that the browser build exposes the variable `x` */
-var grid = x_spreadsheet(document.getElementById("gridctr"));
-```
-
-The following function converts data from SheetJS to x-spreadsheet:
-
-```js
-/* load data */
-grid.loadData(stox(workbook_object));
-```
-
-`stox` is defined in [`xlsxspread.js`](./xlsxspread.js)
-
-## Editing
-
-`x-spreadsheet` handles the entire edit cycle. No intervention is necessary.
-
-## Saving Data
-
-`grid.getData()` returns an object that can be converted back to a worksheet:
-
-```js
-/* build workbook from the grid data */
-var new_wb = xtos(xspr.getData());
-
-/* generate download */
-XLSX.writeFile(new_wb, "SheetJS.xlsx");
-```
-
-`stox` is defined in [`xlsxspread.js`](./xlsxspread.js)
-
-## Additional Features
-
-This demo barely scratches the surface.  The underlying grid component includes
-many additional features that work with [SheetJS Pro](https://sheetjs.com/pro).
+- <https://cdn.sheetjs.com/xspreadsheet/xlsxspread.js> original script
+- <https://cdn.sheetjs.com/xspreadsheet/xlsxspread.min.js> minified
 
 [![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
diff --git a/demos/xspreadsheet/index.html b/demos/xspreadsheet/index.html
deleted file mode 100644
index dd80a43..0000000
--- a/demos/xspreadsheet/index.html
+++ /dev/null
@@ -1,135 +0,0 @@
-<!DOCTYPE html>
-<!-- xlsx.js (C) 2013-present  SheetJS http://sheetjs.com -->
-<!-- vim: set ts=2: -->
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<title>SheetJS + x-spreadsheet Live Demo</title>
-<style>
-#drop{
-	border:2px dashed #bbb;
-	-moz-border-radius:5px;
-	-webkit-border-radius:5px;
-	border-radius:5px;
-	padding:25px;
-	text-align:center;
-	font:20pt bold,"Vollkorn";color:#bbb
-}
-#b64data{
-	width:100%;
-}
-a { text-decoration: none }
-</style>
-<!-- x-spreadsheet stylesheet -->
-<link rel="stylesheet" href="https://unpkg.com/x-data-spreadsheet/dist/xspreadsheet.css"/>
-</head>
-<body>
-<pre>
-<b><a href="http://sheetjs.com">SheetJS Data Preview Live Demo</a></b>
-
-<a href="https://github.com/myliang/x-spreadsheet">x-spreadsheet component library</a>
-
-<a href="https://github.com/SheetJS/sheetjs">Source Code Repo</a>
-<a href="https://github.com/SheetJS/sheetjs/issues">Issues?  Something look weird?  Click here and report an issue</a>
-
-<div id="drop">Drop a spreadsheet file here to see sheet data</div>
-<input type="file" name="xlfile" id="xlf" /> ... or click here to select a file
-<textarea id="b64data">... or paste a base64-encoding here</textarea>
-</pre>
-<p><input type="submit" value="Export to XLSX!" id="xport" onclick="export_xlsx();"></p>
-<div id="htmlout"></div>
-<br />
-<script src="https://unpkg.com/x-data-spreadsheet/dist/xspreadsheet.js"></script>
-<script src="shim.js"></script>
-<script src="xlsx.full.min.js"></script>
-<script src="xlsxspread.js"></script>
-<script>
-/*jshint browser:true */
-/* eslint-env browser */
-/* eslint no-use-before-define:0 */
-/*global Uint8Array, Uint16Array, ArrayBuffer */
-/*global XLSX */
-
-var HTMLOUT = document.getElementById('htmlout');
-var xspr = x_spreadsheet(HTMLOUT);
-HTMLOUT.style.height = (window.innerHeight - 400) + "px";
-HTMLOUT.style.width = (window.innerWidth - 50) + "px";
-
-var process_wb = (function() {
-	var XPORT = document.getElementById('xport');
-
-	return function process_wb(wb) {
-		/* convert to x-spreadsheet form */
-		var data = stox(wb);
-
-		/* update x-spreadsheet */
-		xspr.loadData(data);
-		XPORT.disabled = false;
-
-		if(typeof console !== 'undefined') console.log("output", new Date());
-	};
-})();
-
-var do_file = (function() {
-	return function do_file(files) {
-		var f = files[0];
-		var reader = new FileReader();
-		reader.onload = function(e) {
-			if(typeof console !== 'undefined') console.log("onload", new Date());
-			var data = e.target.result;
-			data = new Uint8Array(data);
-			process_wb(XLSX.read(data, {type: 'array'}));
-		};
-		reader.readAsArrayBuffer(f);
-	};
-})();
-
-(function() {
-	var drop = document.getElementById('drop');
-	if(!drop.addEventListener) return;
-
-	function handleDrop(e) {
-		e.stopPropagation();
-		e.preventDefault();
-		do_file(e.dataTransfer.files);
-	}
-
-	function handleDragover(e) {
-		e.stopPropagation();
-		e.preventDefault();
-		e.dataTransfer.dropEffect = 'copy';
-	}
-
-	drop.addEventListener('dragenter', handleDragover, false);
-	drop.addEventListener('dragover', handleDragover, false);
-	drop.addEventListener('drop', handleDrop, false);
-})();
-
-(function() {
-	var xlf = document.getElementById('xlf');
-	if(!xlf.addEventListener) return;
-	function handleFile(e) { do_file(e.target.files); }
-	xlf.addEventListener('change', handleFile, false);
-})();
-
-function export_xlsx() {
-	var new_wb = xtos(xspr.getData());
-
-	/* write file and trigger a download */
-	XLSX.writeFile(new_wb, 'sheetjs.xlsx', {});
-}
-</script>
-<script type="text/javascript">
-/* eslint no-use-before-define:0 */
-	var _gaq = _gaq || [];
-	_gaq.push(['_setAccount', 'UA-36810333-1']);
-	_gaq.push(['_trackPageview']);
-
-	(function() {
-		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
-		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
-		var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
-	})();
-</script>
-</body>
-</html>
diff --git a/demos/xspreadsheet/shim.js b/demos/xspreadsheet/shim.js
deleted file mode 120000
index 7ec5819..0000000
--- a/demos/xspreadsheet/shim.js
+++ /dev/null
@@ -1 +0,0 @@
-../../shim.js
\ No newline at end of file
diff --git a/demos/xspreadsheet/xlsx.full.min.js b/demos/xspreadsheet/xlsx.full.min.js
deleted file mode 120000
index dbca48d..0000000
--- a/demos/xspreadsheet/xlsx.full.min.js
+++ /dev/null
@@ -1 +0,0 @@
-../../dist/xlsx.full.min.js
\ No newline at end of file
diff --git a/demos/xspreadsheet/xlsxspread.js b/demos/xspreadsheet/xlsxspread.js
index d4b88f9..cced956 100644
--- a/demos/xspreadsheet/xlsxspread.js
+++ b/demos/xspreadsheet/xlsxspread.js
@@ -2,6 +2,7 @@
 /* eslint-env browser */
 /*global XLSX */
 /*exported stox, xtos */
+console.log("The latest version of the xlsxspread.js script is at https://cdn.sheetjs.com/xspreadsheet/xlsxspread.js !")
 
 /**
  * Converts data from SheetJS to x-spreadsheet
@@ -129,3 +130,4 @@ function xtos(sdata) {
 
   return out;
 }
+