headless
							
								
								
									
										3
									
								
								Makefile
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -1,5 +1,6 @@ | ||||
| .PHONY: build | ||||
| build: | ||||
| 	cp formats.png docz/docs/img/formats.png | ||||
| 	cd docz; npx -y pnpm build; cd .. | ||||
| 	rm -rf docs | ||||
| 	mv docz/build/ docs | ||||
| @ -7,7 +8,7 @@ build: | ||||
| 
 | ||||
| .PHONY: serve | ||||
| serve: | ||||
| 	cd docs; python -mSimpleHTTPServer; cd - | ||||
| 	cd docs; python -mSimpleHTTPServer || python3 -mhttp.server; cd - | ||||
| 
 | ||||
| .PHONY: index | ||||
| index: readme ## Rebuild site
 | ||||
|  | ||||
| @ -14,7 +14,7 @@ XLS (both '97-2004 and '95), and SpreadsheetML 2003. | ||||
| 
 | ||||
| Not all Clipboard APIs offer access to all clipboard types. | ||||
| 
 | ||||
| ## Browser | ||||
| ## Browser Reading (paste) | ||||
| 
 | ||||
| Clipboard data can be read from a `paste` event, accessible from the event | ||||
| `clipboardData` property: | ||||
| @ -26,7 +26,7 @@ document.onpaste = function(e) { | ||||
|   /* parse */ | ||||
|   var wb = XLSX.read(str, {type: "string"}); | ||||
|   /* DO SOMETHING WITH wb HERE */ | ||||
| } | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| `getData` accepts one argument: the desired MIME type. Chrome 103 supports: | ||||
| @ -62,7 +62,7 @@ function Clipboard() { | ||||
|       /* generate CSV for each "first worksheet" */ | ||||
|       var result = ws_arr.map(ws => XLSX.utils.sheet_to_csv(ws)); | ||||
|       setCSVs(result); | ||||
|     } | ||||
|     }; | ||||
|   }, []); | ||||
| 
 | ||||
|   return ( | ||||
| @ -72,6 +72,68 @@ function Clipboard() { | ||||
|       {csvs[2] && (<pre><b>Data from clipboard RTF  (text/rtf)</b><br/>{csvs[2]}</pre>)} | ||||
|       {csvs.every(x => !x) && <b>Copy data in Excel, click here, and paste (Control+V)</b>} | ||||
|     </> | ||||
|   ) | ||||
|   ); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ## Browser Writing (copy) | ||||
| 
 | ||||
| Clipboard data can be written from a `copy` event, accessible from the event | ||||
| `clipboardData` property: | ||||
| 
 | ||||
| ```js | ||||
| document.oncopy = function(e) { | ||||
|   /* get HTML of first worksheet in workbook */ | ||||
|   var str = XLSX.write(wb, {type: "string", bookType: "html"}); | ||||
|   /* set HTML clipboard data */ | ||||
|   e.clipboardData.setData('text/html', str); | ||||
| 
 | ||||
|   /* prevent the browser from copying the normal data */ | ||||
|   e.preventDefault(); | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| `setData` accepts two arguments: MIME type and new data. Chrome 103 supports: | ||||
| 
 | ||||
| | MIME type    | Data format                | | ||||
| |:-------------|:---------------------------| | ||||
| | `text/plain` | TSV (tab separated values) | | ||||
| | `text/html`  | HTML                       | | ||||
| 
 | ||||
| Browsers do not currently support assigning to the `text/rtf` clipboard type. | ||||
| 
 | ||||
| ### Live Demo | ||||
| 
 | ||||
| This demo creates a simple workbook from the following HTML table: | ||||
| 
 | ||||
| <table id="srcdata"> | ||||
|   <tr><td>SheetJS</td><td>Clipboard</td><td>Demo</td></tr> | ||||
|   <tr><td>bookType</td><td>RTF</td></tr> | ||||
|   <tr><td>source</td><td>HTML Table</td></tr> | ||||
| </table> | ||||
| 
 | ||||
| Create a new file in Excel then come back to this window.  Select the text | ||||
| below and copy (Control+C for Windows, Command+C for Mac).  Go back to the | ||||
| excel | ||||
| 
 | ||||
| ```jsx live | ||||
| function Clipboard() { | ||||
|   /* Set up copy handler */ | ||||
|   React.useEffect(async() => { | ||||
|     document.oncopy = function(e) { | ||||
|       /* generate workbook from table */ | ||||
|       var wb = XLSX.utils.table_to_book(document.getElementById("srcdata")); | ||||
|       /* get HTML of first worksheet in workbook */ | ||||
|       var str = XLSX.write(wb, {type: "string", bookType: "html"}); | ||||
|       /* set HTML clipboard data */ | ||||
|       e.clipboardData.setData('text/html', str); | ||||
|       /* prevent the browser from copying the normal data */ | ||||
|       e.preventDefault(); | ||||
|     }; | ||||
|   }, []); | ||||
| 
 | ||||
|   return ( | ||||
|     <b>Select this text, copy (Control+C), and paste in Excel</b> | ||||
|   ); | ||||
| } | ||||
| ``` | ||||
|  | ||||
							
								
								
									
										215
									
								
								docz/docs/04-getting-started/03-demos/07-headless.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						| @ -0,0 +1,215 @@ | ||||
| --- | ||||
| sidebar_position: 7 | ||||
| --- | ||||
| 
 | ||||
| # Headless Automation | ||||
| 
 | ||||
| Headless automation involves controlling "headless browsers" to access websites | ||||
| and submit or download data.  It is also possible to automate browsers using | ||||
| custom browser extensions. | ||||
| 
 | ||||
| The [SheetJS standalone script](../../installation/standalone) can be added to | ||||
| any website by inserting a `SCRIPT` tag.  Headless browsers usually provide | ||||
| utility functions for running custom snippets in the browser and passing data | ||||
| back to the automation script. | ||||
| 
 | ||||
| ## Use Case | ||||
| 
 | ||||
| This demo focuses on exporting table data to a workbook.  Headless browsers do | ||||
| not generally support passing objects between the browser context and the | ||||
| automation script, so the file data must be generated in the browser context | ||||
| and sent back to the automation script for saving in the filesystem.  Steps: | ||||
| 
 | ||||
| 1) Launch the headless browser and load the target webpage. | ||||
| 
 | ||||
| 2) Add the standalone SheetJS build to the page in a `SCRIPT` tag. | ||||
| 
 | ||||
| 3) Add a script to the page (in the browser context) that will: | ||||
| 
 | ||||
| - Make a workbook object from the first table using `XLSX.utils.table_to_book` | ||||
| - Generate the bytes for an XLSB file using `XLSX.write` | ||||
| - Send the bytes back to the automation script | ||||
| 
 | ||||
| 4) When the automation context receives data, save to a file | ||||
| 
 | ||||
| This demo exports data from <https://sheetjs.com/demos/table>. | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| It is also possible to parse files from the browser context, but parsing from | ||||
| the automation context is more performant and strongly recommended. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ## Puppeteer | ||||
| 
 | ||||
| Puppeteer enables headless Chromium automation for NodeJS.  Releases ship with | ||||
| an installer script.  Installation is straightforward: | ||||
| 
 | ||||
| ```bash | ||||
| npm i https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz puppeteer | ||||
| ``` | ||||
| 
 | ||||
| Binary strings are the favored data type.  They can be safely passed from the | ||||
| browser context to the automation script.  NodeJS provides an API to write | ||||
| binary strings to file (`fs.writeFileSync` using encoding `binary`). | ||||
| 
 | ||||
| To run the example, after installing the packages, save the following script to | ||||
| `SheetJSPuppeteer.js` and run `node SheetJSPuppeteer.js`.  Steps are commented: | ||||
| 
 | ||||
| ```js title="SheetJSPuppeteer.js" | ||||
| const fs = require("fs"); | ||||
| const puppeteer = require('puppeteer'); | ||||
| (async () => { | ||||
|   /* (1) Load the target page */ | ||||
|   const browser = await puppeteer.launch(); | ||||
|   const page = await browser.newPage(); | ||||
|   page.on("console", msg => console.log("PAGE LOG:", msg.text())); | ||||
|   await page.setViewport({width: 1920, height: 1080}); | ||||
|   await page.goto('https://sheetjs.com/demos/table'); | ||||
| 
 | ||||
|   /* (2) Load the standalone SheetJS build from the CDN */ | ||||
|   await page.addScriptTag({ url: 'https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js' }); | ||||
| 
 | ||||
|   /* (3) Run the snippet in browser and return data */ | ||||
|   const bin = await page.evaluate(() => { | ||||
|     /* NOTE: this function will be evaluated in the browser context. | ||||
|        `page`, `fs` and `puppeteer` are not available. | ||||
|        `XLSX` will be available thanks to step 2 */ | ||||
| 
 | ||||
|     /* find first table */ | ||||
|     var table = document.body.getElementsByTagName('table')[0]; | ||||
| 
 | ||||
|     /* call table_to_book on first table */ | ||||
|     var wb = XLSX.utils.table_to_book(table); | ||||
| 
 | ||||
|     /* generate XLSB and return binary string */ | ||||
|     return XLSX.write(wb, {type: "binary", bookType: "xlsb"}); | ||||
|   }); | ||||
| 
 | ||||
|   /* (4) write data to file */ | ||||
|   fs.writeFileSync("SheetJSPuppeteer.xlsb", bin, { encoding: "binary" }); | ||||
| 
 | ||||
|   await browser.close(); | ||||
| })(); | ||||
| ``` | ||||
| 
 | ||||
| ## Playwright | ||||
| 
 | ||||
| Playwright presents a unified scripting framework for Chromium, WebKit, and | ||||
| other browsers.  It draws inspiration from Puppeteer.  In fact, the example | ||||
| code is almost identical! | ||||
| 
 | ||||
| ```bash | ||||
| npm i https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz playwright | ||||
| ``` | ||||
| 
 | ||||
| To run the example, after installing the packages, save the following script to | ||||
| `SheetJSPlaywright.js` and run `node SheetJSPlaywright.js`.  Import divergences | ||||
| from the Puppeteer example are highlighted below: | ||||
| 
 | ||||
| ```js title="SheetJSPlaywright.js" | ||||
| const fs = require("fs"); | ||||
| // highlight-next-line | ||||
| const { webkit } = require('playwright'); // import desired browser | ||||
| (async () => { | ||||
|   /* (1) Load the target page */ | ||||
|   // highlight-next-line | ||||
|   const browser = await webkit.launch(); // launch desired browser | ||||
|   const page = await browser.newPage(); | ||||
|   page.on("console", msg => console.log("PAGE LOG:", msg.text())); | ||||
|   // highlight-next-line | ||||
|   await page.setViewportSize({width: 1920, height: 1080}); // different name :( | ||||
|   await page.goto('https://sheetjs.com/demos/table'); | ||||
| 
 | ||||
|   /* (2) Load the standalone SheetJS build from the CDN */ | ||||
|   await page.addScriptTag({ url: 'https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js' }); | ||||
| 
 | ||||
|   /* (3) Run the snippet in browser and return data */ | ||||
|   const bin = await page.evaluate(() => { | ||||
|     /* NOTE: this function will be evaluated in the browser context. | ||||
|        `page`, `fs` and the browser engine are not available. | ||||
|        `XLSX` will be available thanks to step 2 */ | ||||
| 
 | ||||
|     /* find first table */ | ||||
|     var table = document.body.getElementsByTagName('table')[0]; | ||||
| 
 | ||||
|     /* call table_to_book on first table */ | ||||
|     var wb = XLSX.utils.table_to_book(table); | ||||
| 
 | ||||
|     /* generate XLSB and return binary string */ | ||||
|     return XLSX.write(wb, {type: "binary", bookType: "xlsb"}); | ||||
|   }); | ||||
| 
 | ||||
|   /* (4) write data to file */ | ||||
|   fs.writeFileSync("SheetJSPlaywright.xlsb", bin, { encoding: "binary" }); | ||||
| 
 | ||||
|   await browser.close(); | ||||
| })(); | ||||
| ``` | ||||
| 
 | ||||
| 
 | ||||
| ## PhantomJS | ||||
| 
 | ||||
| PhantomJS is a headless web browser powered by WebKit.  Standalone binaries are | ||||
| available at <https://phantomjs.org/download.html> | ||||
| 
 | ||||
| :::warning  | ||||
| 
 | ||||
| This information is provided for legacy deployments.  PhantomJS development has | ||||
| been suspended and there are known vulnerabilities, so new projects should use | ||||
| alternatives.  For WebKit automation, new projects should use Playwright. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| Binary strings are the favored data type.  They can be safely passed from the | ||||
| browser context to the automation script.  PhantomJS provides an API to write | ||||
| binary strings to file (`fs.write` using mode `wb`). | ||||
| 
 | ||||
| To run the example, save the following script to `SheetJSPhantom.js` in the same | ||||
| folder as `phantomjs.exe` or `phantomjs` and run | ||||
| 
 | ||||
| ``` | ||||
| ./phantomjs SheetJSPhantom.js     ## macOS / Linux | ||||
| .\phantomjs.exe SheetJSPhantom.js ## windows | ||||
| ``` | ||||
| 
 | ||||
| The steps are marked in the comments: | ||||
| 
 | ||||
| ```js title="SheetJSPhantom.js" | ||||
| var page = require('webpage').create(); | ||||
| page.onConsoleMessage = function(msg) { console.log(msg); }; | ||||
| 
 | ||||
| /* (1) Load the target page */ | ||||
| page.open('https://sheetjs.com/demos/table', function() { | ||||
| 
 | ||||
|   /* (2) Load the standalone SheetJS build from the CDN */ | ||||
|   page.includeJs("https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js", function() { | ||||
| 
 | ||||
|     /* (3) Run the snippet in browser and return data */ | ||||
|     var bin = page.evaluateJavaScript([ "function(){", | ||||
| 
 | ||||
|       /* find first table */ | ||||
|       "var table = document.body.getElementsByTagName('table')[0];", | ||||
| 
 | ||||
|       /* call table_to_book on first table */ | ||||
|       "var wb = XLSX.utils.table_to_book(table);", | ||||
| 
 | ||||
|       /* generate XLSB file and return binary string */ | ||||
|       "return XLSX.write(wb, {type: 'binary', bookType: 'xlsb'});", | ||||
|     "}" ].join("")); | ||||
| 
 | ||||
|     /* (4) write data to file */ | ||||
|     require("fs").write("SheetJSPhantomJS.xlsb", bin, "wb"); | ||||
| 
 | ||||
|     phantom.exit(); | ||||
|   }); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| :::caution | ||||
| 
 | ||||
| PhantomJS is very finicky and will hang if there are script errors.  It is | ||||
| strongly recommended to add verbose logging and to lint scripts before use. | ||||
| 
 | ||||
| ::: | ||||
| @ -41,7 +41,7 @@ The demo projects include small runnable examples and short explainers. | ||||
| - [`NetSuite SuiteScript`](./netsuite) | ||||
| - [`SalesForce Lightning Web Components`](./salesforce) | ||||
| - [`Excel JavaScript API`](./excel) | ||||
| - [`Headless Browsers`](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) | ||||
| - [`Headless Automation`](./headless) | ||||
| - [`Other JavaScript Engines`](https://github.com/SheetJS/SheetJS/tree/master/demos/altjs/) | ||||
| - [`"serverless" functions`](https://github.com/SheetJS/SheetJS/tree/master/demos/function/) | ||||
| - [`Databases and Key/Value Stores`](https://github.com/SheetJS/SheetJS/tree/master/demos/database/) | ||||
|  | ||||
| @ -818,13 +818,17 @@ is missing or no options are specified, the default name `Sheet1` is used. | ||||
| 
 | ||||
| #### Examples | ||||
| 
 | ||||
| The [Headless Demo](../getting-started/demos/headless) includes examples of | ||||
| server-side spreadsheet generation from HTML TABLE elements using headless | ||||
| Chromium ("Puppeteer") and other browsers ("Playwright") | ||||
| 
 | ||||
| Here are a few common scenarios (click on each subtitle to see the code): | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>HTML TABLE element in a webpage</b> (click to show)</summary> | ||||
| 
 | ||||
| ```html | ||||
| <!-- include the standalone script and shim.  this uses the UNPKG CDN --> | ||||
| <!-- include the standalone script and shim --> | ||||
| <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js"></script> | ||||
| <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script> | ||||
| 
 | ||||
| @ -897,95 +901,6 @@ chrome.runtime.onMessage.addListener(function(msg, sender, cb) { | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Server-Side HTML Tables with Headless Chrome</b> (click to show)</summary> | ||||
| 
 | ||||
| The [`headless` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) includes a complete demo to convert HTML | ||||
| files to XLSB workbooks.  The core idea is to add the script to the page, parse | ||||
| the table in the page context, generate a `base64` workbook and send it back | ||||
| for further processing: | ||||
| 
 | ||||
| ```js | ||||
| const XLSX = require("xlsx"); | ||||
| const { readFileSync } = require("fs"), puppeteer = require("puppeteer"); | ||||
| 
 | ||||
| const url = `https://sheetjs.com/demos/table`; | ||||
| 
 | ||||
| /* get the standalone build source (node_modules/xlsx/dist/xlsx.full.min.js) */ | ||||
| const lib = readFileSync(require.resolve("xlsx/dist/xlsx.full.min.js"), "utf8"); | ||||
| 
 | ||||
| (async() => { | ||||
|   /* start browser and go to web page */ | ||||
|   const browser = await puppeteer.launch(); | ||||
|   const page = await browser.newPage(); | ||||
|   await page.goto(url, {waitUntil: "networkidle2"}); | ||||
| 
 | ||||
|   /* inject library */ | ||||
|   await page.addScriptTag({content: lib}); | ||||
| 
 | ||||
|   /* this function `s5s` will be called by the script below, receiving the Base64-encoded file */ | ||||
|   await page.exposeFunction("s5s", async(b64) => { | ||||
|     const workbook = XLSX.read(b64, {type: "base64" }); | ||||
| 
 | ||||
|     /* DO SOMETHING WITH workbook HERE */ | ||||
|   }); | ||||
| 
 | ||||
|   /* generate XLSB file in webpage context and send back result */ | ||||
|   await page.addScriptTag({content: ` | ||||
|     /* call table_to_book on first table */ | ||||
|     var workbook = XLSX.utils.table_to_book(document.querySelector("TABLE")); | ||||
| 
 | ||||
|     /* generate XLSX file */ | ||||
|     var b64 = XLSX.write(workbook, {type: "base64", bookType: "xlsb"}); | ||||
| 
 | ||||
|     /* call "s5s" hook exposed from the node process */ | ||||
|     window.s5s(b64); | ||||
|   `}); | ||||
| 
 | ||||
|   /* cleanup */ | ||||
|   await browser.close(); | ||||
| })(); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Server-Side HTML Tables with Headless WebKit</b> (click to show)</summary> | ||||
| 
 | ||||
| The [`headless` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) includes a complete demo to convert HTML | ||||
| files to XLSB workbooks using [PhantomJS](https://phantomjs.org/). The core idea | ||||
| is to add the script to the page, parse the table in the page context, generate | ||||
| a `binary` workbook and send it back for further processing: | ||||
| 
 | ||||
| ```js | ||||
| var XLSX = require('xlsx'); | ||||
| var page = require('webpage').create(); | ||||
| 
 | ||||
| /* this code will be run in the page */ | ||||
| var code = [ "function(){", | ||||
|   /* call table_to_book on first table */ | ||||
|   "var wb = XLSX.utils.table_to_book(document.body.getElementsByTagName('table')[0]);", | ||||
| 
 | ||||
|   /* generate XLSB file and return binary string */ | ||||
|   "return XLSX.write(wb, {type: 'binary', bookType: 'xlsb'});", | ||||
| "}" ].join(""); | ||||
| 
 | ||||
| page.open('https://sheetjs.com/demos/table', function() { | ||||
|   /* Load the browser script from the UNPKG CDN */ | ||||
|   page.includeJs("https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js", function() { | ||||
|     /* The code will return an XLSB file encoded as binary string */ | ||||
|     var bin = page.evaluateJavaScript(code); | ||||
| 
 | ||||
|     var workbook = XLSX.read(bin, {type: "binary"}); | ||||
|     /* DO SOMETHING WITH workbook HERE */ | ||||
| 
 | ||||
|     phantom.exit(); | ||||
|   }); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>NodeJS HTML Tables without a browser</b> (click to show)</summary> | ||||
| 
 | ||||
|  | ||||
| @ -245,28 +245,34 @@ The [`extendscript` demo](../getting-started/demos/extendscript) includes a more | ||||
|   </TabItem> | ||||
|   <TabItem value="headless" label="Headless"> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>PhantomJS (Headless Webkit) File Generation</b> (click to show)</summary> | ||||
| The [`headless` demo](../getting-started/demos/headless) includes complete | ||||
| examples of converting HTML TABLE elements to XLSB workbooks using Puppeteer | ||||
| and other headless automation tools. | ||||
| 
 | ||||
| The [`headless` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/headless/) includes a complete demo to convert HTML | ||||
| files to XLSB workbooks using [PhantomJS](https://phantomjs.org/). PhantomJS | ||||
| `fs.write` supports writing files from the main process but has a different | ||||
| interface from the NodeJS `fs` module: | ||||
| Headless browsers may not have access to the filesystem, so `XLSX.writeFile` | ||||
| may fail.  It is strongly recommended to generate the file bytes in the browser | ||||
| context, send the bytes to the automation context, and write from automation. | ||||
| 
 | ||||
| Puppeteer and Playwright are NodeJS modules that support binary strings: | ||||
| 
 | ||||
| ```js | ||||
| var XLSX = require('xlsx'); | ||||
| var fs = require('fs'); | ||||
| /* from the browser context */ | ||||
| var bin = XLSX.write(workbook, { type:"binary", bookType: "xlsb" }); | ||||
| 
 | ||||
| /* generate a binary string */ | ||||
| var bin = XLSX.write(workbook, { type:"binary", bookType: "xlsx" }); | ||||
| /* write to file */ | ||||
| fs.write("test.xlsx", bin, "wb"); | ||||
| /* from the automation context */ | ||||
| fs.writeFileSync("SheetJSansHead.xlsb", bin, { encoding: "binary" }); | ||||
| ``` | ||||
| 
 | ||||
| Note: The section ["Processing HTML Tables"](./input#processing-html-tables) shows how | ||||
| to generate a workbook from HTML tables in a page in "Headless WebKit". | ||||
| PhantomJS `fs.write` supports writing files from the main process.  The mode | ||||
| `wb` supports binary strings: | ||||
| 
 | ||||
| </details> | ||||
| ```js | ||||
| /* from the browser context */ | ||||
| var bin = XLSX.write(workbook, { type:"binary", bookType: "xlsb" }); | ||||
| 
 | ||||
| /* from the automation context */ | ||||
| fs.write("SheetJSansHead.xlsb", bin, "wb"); | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
|  | ||||
| @ -426,9 +426,9 @@ explicitly flagged.  Combining the two checks yields a simple function: | ||||
| 
 | ||||
| ```js | ||||
| function wb_has_macro(wb/*:workbook*/)/*:boolean*/ { | ||||
| 	if(!!wb.vbaraw) return true; | ||||
| 	const sheets = wb.SheetNames.map((n) => wb.Sheets[n]); | ||||
| 	return sheets.some((ws) => !!ws && ws['!type']=='macro'); | ||||
|   if(!!wb.vbaraw) return true; | ||||
|   const sheets = wb.SheetNames.map((n) => wb.Sheets[n]); | ||||
|   return sheets.some((ws) => !!ws && ws['!type']=='macro'); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
|  | ||||
| @ -9,18 +9,27 @@ The `sheet_to_*` functions accept a worksheet and an optional options object. | ||||
| 
 | ||||
| The `*_to_sheet` functions accept a data object and an optional options object. | ||||
| 
 | ||||
| The `sheet_add_*` functions accept worksheet, data, and optional options. | ||||
| 
 | ||||
| The examples are based on the following worksheet: | ||||
| 
 | ||||
| ``` | ||||
| XXX| A | B | C | D | E | F | G | | ||||
| ---+---+---+---+---+---+---+---+ | ||||
|  1 | S | h | e | e | t | J | S | | ||||
|  2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | ||||
|  3 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | | ||||
| ``` | ||||
| <table> | ||||
| <tr><td>S</td><td>h</td><td>e</td><td>e</td><td>t</td><td>J</td><td>S</td></tr> | ||||
| <tr><td>1</td><td>2</td><td> </td><td> </td><td>5</td><td>6</td><td>7</td></tr> | ||||
| <tr><td>2</td><td>3</td><td> </td><td> </td><td>6</td><td>7</td><td>8</td></tr> | ||||
| <tr><td>3</td><td>4</td><td> </td><td> </td><td>7</td><td>8</td><td>9</td></tr> | ||||
| <tr><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>0</td></tr> | ||||
| </table> | ||||
| 
 | ||||
| 
 | ||||
| ### Array of Arrays Input | ||||
| 
 | ||||
| **Create a worksheet from an array of arrays** | ||||
| 
 | ||||
| ```js | ||||
| var ws = XLSX.utils.aoa_to_sheet(aoa, opts); | ||||
| ``` | ||||
| 
 | ||||
| `XLSX.utils.aoa_to_sheet` takes an array of arrays of JS values and returns a | ||||
| worksheet resembling the input data.  Numbers, Booleans and Strings are stored | ||||
| as the corresponding styles.  Dates are stored as date or numbers.  Array holes | ||||
| @ -34,19 +43,23 @@ other values are stored as strings.  The function takes an options argument: | ||||
| |`sheetStubs` |  false  | Create cell objects of type `z` for `null` values    | | ||||
| |`nullError`  |  false  | If true, emit `#NULL!` error cells for `null` values | | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| To generate the example sheet: | ||||
| The example worksheet can be generated with: | ||||
| 
 | ||||
| ```js | ||||
| var ws = XLSX.utils.aoa_to_sheet([ | ||||
|   "SheetJS".split(""), | ||||
|   [1,2,3,4,5,6,7], | ||||
|   [2,3,4,5,6,7,8] | ||||
|   ["S", "h", "e", "e", "t", "J", "S"], | ||||
|   [  1,   2,    ,    ,   5,   6,   7], | ||||
|   [  2,   3,    ,    ,   6,   7,   8], | ||||
|   [  3,   4,    ,    ,   7,   8,   9], | ||||
|   [  4,   5,   6,   7,   8,   9,   0] | ||||
| ]); | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| **Add data from an array of arrays to an existing worksheet** | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.sheet_add_aoa(ws, aoa, opts); | ||||
| ``` | ||||
| 
 | ||||
| `XLSX.utils.sheet_add_aoa` takes an array of arrays of JS values and updates an | ||||
| existing worksheet object.  It follows the same process as `aoa_to_sheet` and | ||||
| @ -71,22 +84,7 @@ accepts an options argument: | ||||
| | (default)        | Start from cell A1                                        | | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| Consider the worksheet: | ||||
| 
 | ||||
| ``` | ||||
| XXX| A | B | C | D | E | F | G | | ||||
| ---+---+---+---+---+---+---+---+ | ||||
|  1 | S | h | e | e | t | J | S | | ||||
|  2 | 1 | 2 |   |   | 5 | 6 | 7 | | ||||
|  3 | 2 | 3 |   |   | 6 | 7 | 8 | | ||||
|  4 | 3 | 4 |   |   | 7 | 8 | 9 | | ||||
|  5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | | ||||
| ``` | ||||
| 
 | ||||
| This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`: | ||||
| The example worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`: | ||||
| 
 | ||||
| ```js | ||||
| /* Initial row */ | ||||
| @ -102,10 +100,14 @@ XLSX.utils.sheet_add_aoa(ws, [[5,6,7], [6,7,8], [7,8,9]], {origin:{r:1, c:4}}); | ||||
| XLSX.utils.sheet_add_aoa(ws, [[4,5,6,7,8,9,0]], {origin: -1}); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Array of Objects Input | ||||
| 
 | ||||
| **Create a worksheet from an array of objects** | ||||
| 
 | ||||
| ```js | ||||
| var ws = XLSX.utils.json_to_sheet(aoo, opts); | ||||
| ``` | ||||
| 
 | ||||
| `XLSX.utils.json_to_sheet` takes an array of objects and returns a worksheet | ||||
| with automatically-generated "headers" based on the keys of the objects.  The | ||||
| default column order is determined by the first appearance of the field using | ||||
| @ -119,37 +121,69 @@ default column order is determined by the first appearance of the field using | ||||
| |`skipHeader` |  false  | If true, do not include header row in output         | | ||||
| |`nullError`  |  false  | If true, emit `#NULL!` error cells for `null` values | | ||||
| 
 | ||||
| - All fields from each row will be written.  If `header` is an array and it does | ||||
|   not contain a particular field, the key will be appended to the array. | ||||
| :::caution | ||||
| 
 | ||||
| All fields from each row will be written! `header` hints at a particular order | ||||
| but is not exclusive. To remove fields from the export, filter the data source. | ||||
| 
 | ||||
| Some data sources have special options to filter properties.  For example, | ||||
| MongoDB will add the `_id` field when finding data from a collection: | ||||
| 
 | ||||
| ```js | ||||
| const aoo_with_id = await coll.find({}).toArray(); | ||||
| const ws = XLSX.utils.json_to_sheet(aoo_with_id); // includes _id column | ||||
| ``` | ||||
| 
 | ||||
| This can be filtered out through the `projection` property: | ||||
| 
 | ||||
| ```js | ||||
| const aoo = await coll.find({}, {projection:{_id:0}}).toArray(); // no _id ! | ||||
| const ws = XLSX.utils.json_to_sheet(aoo); | ||||
| ``` | ||||
| 
 | ||||
| If a data source does not provide a filter option, it can be filtered manually: | ||||
| 
 | ||||
| ```js | ||||
| const aoo = data.map(obj => Object.fromEntries(Object.entries(obj).filter(r => headers.indexOf(r[0]) > -1))); | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| - If `header` is an array, missing keys will be added in order of first use. | ||||
| - Cell types are deduced from the type of each value.  For example, a `Date` | ||||
|   object will generate a Date cell, while a string will generate a Text cell. | ||||
| - Null values will be skipped by default.  If `nullError` is true, an error cell | ||||
|   corresponding to `#NULL!` will be written to the worksheet. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| The original sheet cannot be reproduced using plain objects since JS object keys | ||||
| The example sheet cannot be reproduced using plain objects since JS object keys | ||||
| must be unique. After replacing the second `e` and `S` with `e_1` and `S_1`: | ||||
| 
 | ||||
| ```js | ||||
| var ws = XLSX.utils.json_to_sheet([ | ||||
|   { S:1, h:2, e:3, e_1:4, t:5, J:6, S_1:7 }, | ||||
|   { S:2, h:3, e:4, e_1:5, t:6, J:7, S_1:8 } | ||||
|   { S:1, h:2,    ,      , t:5, J:6, S_1:7 }, | ||||
|   { S:2, h:3,    ,      , t:6, J:7, S_1:8 } | ||||
|   { S:3, h:4,    ,      , t:7, J:8, S_1:9 } | ||||
|   { S:4, h:5, e:6, e_1:7, t:8, J:9, S_1:0 } | ||||
| ], {header:["S","h","e","e_1","t","J","S_1"]}); | ||||
| ``` | ||||
| 
 | ||||
| Alternatively, the header row can be skipped: | ||||
| Alternatively, a different set of unique headers can be used with `skipHeader`: | ||||
| 
 | ||||
| ```js | ||||
| var ws = XLSX.utils.json_to_sheet([ | ||||
|   { A:"S", B:"h", C:"e", D:"e", E:"t", F:"J", G:"S" }, | ||||
|   { A: 1,  B: 2,  C: 3,  D: 4,  E: 5,  F: 6,  G: 7  }, | ||||
|   { A: 2,  B: 3,  C: 4,  D: 5,  E: 6,  F: 7,  G: 8  } | ||||
|   { A:  1, B:  2,      ,      , E:  5, F:  6, G:  7  }, | ||||
|   { A:  2, B:  3,      ,      , E:  6, F:  7, G:  8  } | ||||
|   { A:  3, B:  4,      ,      , E:  7, F:  8, G:  9  }, | ||||
|   { A:  4, B:  5, C:  6, D:  7, E:  8, F:  9, G:  0  }, | ||||
| ], {header:["A","B","C","D","E","F","G"], skipHeader:true}); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| **Add data from an array of objects to an existing worksheet** | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.sheet_add_json(ws, aoo, opts); | ||||
| ``` | ||||
| 
 | ||||
| `XLSX.utils.sheet_add_json` takes an array of objects and updates an existing | ||||
| worksheet object.  It follows the same process as `json_to_sheet` and accepts | ||||
| @ -175,22 +209,7 @@ an options argument: | ||||
| | (default)        | Start from cell A1                                        | | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| Consider the worksheet: | ||||
| 
 | ||||
| ``` | ||||
| XXX| A | B | C | D | E | F | G | | ||||
| ---+---+---+---+---+---+---+---+ | ||||
|  1 | S | h | e | e | t | J | S | | ||||
|  2 | 1 | 2 |   |   | 5 | 6 | 7 | | ||||
|  3 | 2 | 3 |   |   | 6 | 7 | 8 | | ||||
|  4 | 3 | 4 |   |   | 7 | 8 | 9 | | ||||
|  5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | | ||||
| ``` | ||||
| 
 | ||||
| This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`: | ||||
| This example worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`: | ||||
| 
 | ||||
| ```js | ||||
| /* Initial row */ | ||||
| @ -214,10 +233,49 @@ XLSX.utils.sheet_add_json(ws, [ | ||||
| ], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true, origin: -1}); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| :::note | ||||
| 
 | ||||
| If the `header` option is an array, `sheet_add_json` and `sheet_to_json` will | ||||
| append missing elements. | ||||
| 
 | ||||
| This design enables consistent header order across calls: | ||||
| 
 | ||||
| ```jsx live | ||||
| function SheetJSHeaderOrder() { | ||||
|   /* Use shared header */ | ||||
|   const header = []; | ||||
|   const ws1 = XLSX.utils.json_to_sheet([ {C: 2, D: 3}, ], {header}); | ||||
|   XLSX.utils.sheet_add_json(ws1, [ {D: 1, C: 4}, ], {header, origin: -1, skipHeader: true}); | ||||
| 
 | ||||
|   /* only use header in first call */ | ||||
|   const ws2 = XLSX.utils.json_to_sheet([ {C: 2, D: 3}, ], {header:[]}); | ||||
|   XLSX.utils.sheet_add_json(ws2, [ {D: 1, C: 4}, ], {origin: -1, skipHeader: true}); | ||||
| 
 | ||||
|   return (<pre> | ||||
|     <b>Objects</b> | ||||
|     {"\n[\n  { C: 2, D: 3 },\n  { D: 1, C: 4 } // different key order\n]\n"}<br/> | ||||
|     <b>Worksheet when same `header` array is passed to `sheet_add_json`</b> | ||||
|     <div dangerouslySetInnerHTML={{__html:XLSX.utils.sheet_to_html(ws1)}}/> | ||||
|     <i>New contents of `header`</i><br/> | ||||
|     {JSON.stringify(header)}<br/> | ||||
|     <br/> | ||||
|     <b>Worksheet when no `header` property is passed to `sheet_add_json`</b> | ||||
|     <div dangerouslySetInnerHTML={{__html:XLSX.utils.sheet_to_html(ws2)}}/> | ||||
|   </pre>) | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ### HTML Table Input | ||||
| 
 | ||||
| **Create a worksheet or workbook from an HTML DOM TABLE** | ||||
| 
 | ||||
| ```js | ||||
| var ws = XLSX.utils.table_to_sheet(elt, opts); | ||||
| var wb = XLSX.utils.table_to_book(elt, opts); | ||||
| ``` | ||||
| 
 | ||||
| `XLSX.utils.table_to_sheet` takes a table DOM element and returns a worksheet | ||||
| resembling the input table.  Numbers are parsed.  All other data will be stored | ||||
| as strings. | ||||
| @ -235,29 +293,47 @@ Both functions accept options arguments: | ||||
| |`display`    |  false   | If true, hidden rows and cells will not be parsed   | | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| To generate the example sheet, start with the HTML table: | ||||
| 
 | ||||
| ```html | ||||
| <table id="sheetjs"> | ||||
| <tr><td>S</td><td>h</td><td>e</td><td>e</td><td>t</td><td>J</td><td>S</td></tr> | ||||
| <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td></tr> | ||||
| <tr><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td></tr> | ||||
| </table> | ||||
| ``` | ||||
| 
 | ||||
| To process the table: | ||||
| To generate the example sheet, assuming the table has ID `sheetjs`: | ||||
| 
 | ||||
| ```js | ||||
| var tbl = document.getElementById('sheetjs'); | ||||
| var wb = XLSX.utils.table_to_book(tbl); | ||||
| var ws = XLSX.utils.table_to_sheet(tbl); | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| Note: `XLSX.read` can handle HTML represented as strings. | ||||
| :::note | ||||
| 
 | ||||
| `table_to_book` and `table_to_sheet` act on HTML DOM elements.  Starting from | ||||
| an HTML string, there are two parsing approaches: | ||||
| 
 | ||||
| A) Table Phantasm: create a DIV with the desired HTML. | ||||
| 
 | ||||
| ```js | ||||
| /* create element from the source */ | ||||
| var elt = document.createElement("div"); | ||||
| elt.innerHTML = html_source; | ||||
| document.body.appendChild(elt); | ||||
| 
 | ||||
| /* generate worksheet */ | ||||
| var ws = XLSX.utils.table_to_sheet(elt.getElementsByTagName("TABLE")[0]); | ||||
| 
 | ||||
| /* remove element */ | ||||
| document.body.removeChild(elt); | ||||
| ``` | ||||
| 
 | ||||
| B) Raw HTML: use `XLSX.read` to read the text in the same manner as CSV. | ||||
| 
 | ||||
| ```js | ||||
| var wb = XLSX.read(html_source, { type: "string" }); | ||||
| var ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| **Add data from a HTML DOM TABLE to an existing worksheet** | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.sheet_add_dom(ws, elt, opts); | ||||
| ``` | ||||
| 
 | ||||
| `XLSX.utils.sheet_add_dom` takes a table DOM element and updates an existing | ||||
| worksheet object.  It follows the same process as `table_to_sheet` and accepts | ||||
| @ -282,53 +358,74 @@ an options argument: | ||||
| | (default)        | Start from cell A1                                        | | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| A common use case for `sheet_add_dom` involves adding multiple tables to a | ||||
| single worksheet, usually with a few blank rows in between each table: | ||||
| 
 | ||||
| A small helper function can create gap rows between tables: | ||||
|  | ||||
| 
 | ||||
| ```js | ||||
| function create_gap_rows(ws, nrows) { | ||||
|   var ref = XLSX.utils.decode_range(ws["!ref"]);       // get original range | ||||
|   ref.e.r += nrows;                                    // add to ending row | ||||
|   ws["!ref"] = XLSX.utils.encode_range(ref);           // reassign row | ||||
| ```jsx live | ||||
| function MultiTable() { | ||||
|   const headers = ["Table 1", "Table2", "Table 3"]; | ||||
| 
 | ||||
|   /* Callback invoked when the button is clicked */ | ||||
|   const xport = React.useCallback(async () => { | ||||
|     /* This function creates gap rows */ | ||||
|     function create_gap_rows(ws, nrows) { | ||||
|       var ref = XLSX.utils.decode_range(ws["!ref"]);       // get original range | ||||
|       ref.e.r += nrows;                                    // add to ending row | ||||
|       ws["!ref"] = XLSX.utils.encode_range(ref);           // reassign row | ||||
|     } | ||||
| 
 | ||||
|     /* first table */ | ||||
|     const ws = XLSX.utils.aoa_to_sheet([[headers[0]]]); | ||||
|     XLSX.utils.sheet_add_dom(ws, document.getElementById('table1'), {origin: -1}); | ||||
|     create_gap_rows(ws, 1); // one row gap after first table | ||||
| 
 | ||||
|     /* second table */ | ||||
|     XLSX.utils.sheet_add_aoa(ws, [[headers[1]]], {origin: -1}); | ||||
|     XLSX.utils.sheet_add_dom(ws, document.getElementById('table2'), {origin: -1}); | ||||
|     create_gap_rows(ws, 2); // two rows gap after second table | ||||
| 
 | ||||
|     /* third table */ | ||||
|     XLSX.utils.sheet_add_aoa(ws, [[headers[2]]], {origin: -1}); | ||||
|     XLSX.utils.sheet_add_dom(ws, document.getElementById('table3'), {origin: -1}); | ||||
| 
 | ||||
|     /* create workbook and export */ | ||||
|     const wb = XLSX.utils.book_new(); | ||||
|     XLSX.utils.book_append_sheet(wb, ws, "Export"); | ||||
|     XLSX.writeFile(wb, "SheetJSMultiTablexport.xlsx"); | ||||
|   }); | ||||
| 
 | ||||
|   return ( | ||||
|     <> | ||||
|       <button onClick={xport}><b>Export XLSX!</b></button><br/><br/> | ||||
|       <b>{headers[0]}</b><br/> | ||||
|       <table id="table1"> | ||||
|         <tr><td>A2</td><td>B2</td></tr> | ||||
|         <tr><td>A3</td><td>B3</td></tr> | ||||
|       </table> | ||||
|       <b>{headers[1]}</b><br/> | ||||
|       <table id="table2"> | ||||
|         <tr><td>A6</td><td>B6</td><td>C6</td></tr> | ||||
|         <tr><td>A7</td><td>B7</td><td>C7</td></tr> | ||||
|       </table> | ||||
|       <br/> | ||||
|       <b>{headers[2]}</b><br/> | ||||
|       <table id="table3"> | ||||
|         <tr><td>A11</td><td>B11</td></tr> | ||||
|         <tr><td>A12</td><td>B12</td></tr> | ||||
|       </table> | ||||
|     </> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /* first table */ | ||||
| var ws = XLSX.utils.table_to_sheet(document.getElementById('table1')); | ||||
| create_gap_rows(ws, 1); // one row gap after first table | ||||
| 
 | ||||
| /* second table */ | ||||
| XLSX.utils.sheet_add_dom(ws, document.getElementById('table2'), {origin: -1}); | ||||
| create_gap_rows(ws, 3); // three rows gap after second table | ||||
| 
 | ||||
| /* third table */ | ||||
| XLSX.utils.sheet_add_dom(ws, document.getElementById('table3'), {origin: -1}); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Formulae Output | ||||
| 
 | ||||
| `XLSX.utils.sheet_to_formulae` generates an array of commands that represent | ||||
| how a person would enter data into an application.  Each entry is of the form | ||||
| `A1-cell-address=formula-or-value`.  String literals are prefixed with a `'` in | ||||
| accordance with Excel. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| For the example sheet: | ||||
| 
 | ||||
| ```js | ||||
| > var o = XLSX.utils.sheet_to_formulae(ws); | ||||
| > [o[0], o[5], o[10], o[15], o[20]]; | ||||
| [ 'A1=\'S', 'F1=\'J', 'D2=4', 'B3=3', 'G3=8' ] | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| ### Delimiter-Separated Output | ||||
| 
 | ||||
| ```js | ||||
| var csv = XLSX.utils.sheet_to_csv(ws, opts); | ||||
| ``` | ||||
| 
 | ||||
| As an alternative to the `writeFile` CSV type, `XLSX.utils.sheet_to_csv` also | ||||
| produces CSV output.  The function takes an options argument: | ||||
| 
 | ||||
| @ -351,26 +448,35 @@ produces CSV output.  The function takes an options argument: | ||||
|   Using `XLSX.write` with type `string` will also skip the mark. | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| Starting from the example worksheet: | ||||
| 
 | ||||
| For the example sheet: | ||||
| ```jsx live | ||||
| function SheetJSCSVTest() { | ||||
|   var ws = XLSX.utils.aoa_to_sheet([ | ||||
|     ["S", "h", "e", "e", "t", "J", "S"], | ||||
|     [  1,   2,    ,    ,   5,   6,   7], | ||||
|     [  2,   3,    ,    ,   6,   7,   8], | ||||
|     [  3,   4,    ,    ,   7,   8,   9], | ||||
|     [  4,   5,   6,   7,   8,   9,   0] | ||||
|   ]); | ||||
|   return ( <pre> | ||||
|     <b>Worksheet (as HTML)</b> | ||||
|     <div dangerouslySetInnerHTML={{__html: XLSX.utils.sheet_to_html(ws)}}/> | ||||
|     <b>XLSX.utils.sheet_to_csv(ws)</b><br/> | ||||
|     {XLSX.utils.sheet_to_csv(ws)}<br/><br/> | ||||
|     <b>XLSX.utils.sheet_to_csv(ws, {'{'} FS: "\t" {'}'})</b><br/> | ||||
|     {XLSX.utils.sheet_to_csv(ws, { FS: "\t" })}<br/><br/> | ||||
|     <b>XLSX.utils.sheet_to_csv(ws, {'{'} FS: ":", RS: "|" {'}'})</b><br/> | ||||
|     {XLSX.utils.sheet_to_csv(ws, { FS: ":", RS: "|" })}<br/> | ||||
|   </pre> ); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| **UTF-16 Text Output** | ||||
| 
 | ||||
| ```js | ||||
| > console.log(XLSX.utils.sheet_to_csv(ws)); | ||||
| S,h,e,e,t,J,S | ||||
| 1,2,3,4,5,6,7 | ||||
| 2,3,4,5,6,7,8 | ||||
| > console.log(XLSX.utils.sheet_to_csv(ws, {FS:"\t"})); | ||||
| S	h	e	e	t	J	S | ||||
| 1	2	3	4	5	6	7 | ||||
| 2	3	4	5	6	7	8 | ||||
| > console.log(XLSX.utils.sheet_to_csv(ws,{FS:":",RS:"|"})); | ||||
| S:h:e:e:t:J:S|1:2:3:4:5:6:7|2:3:4:5:6:7:8| | ||||
| var txt = XLSX.utils.sheet_to_txt(ws, opts); | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| #### UTF-16 Unicode Text | ||||
| 
 | ||||
| The `txt` output type uses the tab character as the field separator.  If the | ||||
| `codepage` library is available (included in full distribution but not core), | ||||
| @ -378,8 +484,13 @@ the output will be encoded in `CP1200` and the BOM will be prepended. | ||||
| 
 | ||||
| `XLSX.utils.sheet_to_txt` takes the same arguments as `sheet_to_csv`. | ||||
| 
 | ||||
| 
 | ||||
| ### HTML Output | ||||
| 
 | ||||
| ```js | ||||
| var html = XLSX.utils.sheet_to_html(ws, opts); | ||||
| ``` | ||||
| 
 | ||||
| As an alternative to the `writeFile` HTML type, `XLSX.utils.sheet_to_html` also | ||||
| produces HTML output.  The function takes an options argument: | ||||
| 
 | ||||
| @ -390,18 +501,31 @@ produces HTML output.  The function takes an options argument: | ||||
| |`header`     |          | Override header (default `html body`)               | | ||||
| |`footer`     |          | Override footer (default `/body /html`)             | | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| Starting from the example worksheet: | ||||
| 
 | ||||
| For the example sheet: | ||||
| ```jsx live | ||||
| function SheetJSHTML() { | ||||
|   var ws = XLSX.utils.aoa_to_sheet([ | ||||
|     ["S", "h", "e", "e", "t", "J", "S"], | ||||
|     [  1,   2,    ,    ,   5,   6,   7], | ||||
|     [  2,   3,    ,    ,   6,   7,   8], | ||||
|     [  3,   4,    ,    ,   7,   8,   9], | ||||
|     [  4,   5,   6,   7,   8,   9,   0] | ||||
|   ]); | ||||
|   return ( <pre> | ||||
|     <b>XLSX.utils.sheet_to_html(ws)</b> | ||||
|     <div dangerouslySetInnerHTML={{__html: XLSX.utils.sheet_to_html(ws)}}/> | ||||
|   </pre> ); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ### Array Output | ||||
| 
 | ||||
| ```js | ||||
| > console.log(XLSX.utils.sheet_to_html(ws)); | ||||
| // ... | ||||
| ``` | ||||
| </details> | ||||
| var arr = XLSX.utils.sheet_to_json(ws, opts); | ||||
| 
 | ||||
| ### JSON | ||||
| var aoa = XLSX.utils.sheet_to_json(ws, {header: 1, ...other_opts}); | ||||
| ``` | ||||
| 
 | ||||
| `XLSX.utils.sheet_to_json` generates different types of JS objects. The function | ||||
| takes an options argument: | ||||
| @ -452,46 +576,110 @@ takes an options argument: | ||||
| - If header is an array, the keys will not be disambiguated.  This can lead to | ||||
|   unexpected results if the array values are not unique! | ||||
| 
 | ||||
| For the example worksheet: | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Examples</b> (click to show)</summary> | ||||
| ```jsx live | ||||
| function SheetJSToJSON() { | ||||
|   /* original data */ | ||||
|   var ws = XLSX.utils.aoa_to_sheet([ | ||||
|     ["S", "h", "e", "e", "t", "J", "S"], | ||||
|     [  1,   2,    ,    ,   5,   6,   7], | ||||
|     [  2,   3,    ,    ,   6,   7,   8], | ||||
|     [  3,   4,    ,    ,   7,   8,   9], | ||||
|     [  4,   5,   6,   7,   8,   9,   0] | ||||
|   ]); | ||||
| 
 | ||||
| For the example sheet: | ||||
|   /* display JS objects with some whitespace */ | ||||
|   const aoo = o => o.map(r => "  " + JSON.stringify(r).replace(/,"/g, ', "').replace(/:/g, ": ").replace(/"([A-Za-z_]\w*)":/g, '$1:')).join("\n"); | ||||
|   const aoa = o => o.map(r => "  " + JSON.stringify(r).replace(/,/g, ', ').replace(/null/g, "")).join("\n"); | ||||
| 
 | ||||
| ```js | ||||
| > XLSX.utils.sheet_to_json(ws); | ||||
| [ { S: 1, h: 2, e: 3, e_1: 4, t: 5, J: 6, S_1: 7 }, | ||||
|   { S: 2, h: 3, e: 4, e_1: 5, t: 6, J: 7, S_1: 8 } ] | ||||
| 
 | ||||
| > XLSX.utils.sheet_to_json(ws, {header:"A"}); | ||||
| [ { A: 'S', B: 'h', C: 'e', D: 'e', E: 't', F: 'J', G: 'S' }, | ||||
|   { A: '1', B: '2', C: '3', D: '4', E: '5', F: '6', G: '7' }, | ||||
|   { A: '2', B: '3', C: '4', D: '5', E: '6', F: '7', G: '8' } ] | ||||
| 
 | ||||
| > XLSX.utils.sheet_to_json(ws, {header:["A","E","I","O","U","6","9"]}); | ||||
| [ { '6': 'J', '9': 'S', A: 'S', E: 'h', I: 'e', O: 'e', U: 't' }, | ||||
|   { '6': '6', '9': '7', A: '1', E: '2', I: '3', O: '4', U: '5' }, | ||||
|   { '6': '7', '9': '8', A: '2', E: '3', I: '4', O: '5', U: '6' } ] | ||||
| 
 | ||||
| > XLSX.utils.sheet_to_json(ws, {header:1}); | ||||
| [ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], | ||||
|   [ '1', '2', '3', '4', '5', '6', '7' ], | ||||
|   [ '2', '3', '4', '5', '6', '7', '8' ] ] | ||||
|   return ( <pre> | ||||
|     <b>Worksheet (as HTML)</b> | ||||
|     <div dangerouslySetInnerHTML={{__html: XLSX.utils.sheet_to_html(ws)}}/> | ||||
|     <b>XLSX.utils.sheet_to_json(ws, {'{'} header: 1 {'}'}) [array of arrays]</b><br/> | ||||
|     [<br/>{aoa(XLSX.utils.sheet_to_json(ws, { header: 1 }))}<br/>]<br/><br/> | ||||
|     <b>XLSX.utils.sheet_to_json(ws) [objects with header disambiguation]</b><br/> | ||||
|     [<br/>{aoo(XLSX.utils.sheet_to_json(ws))}<br/>]<br/><br/> | ||||
|     <b>XLSX.utils.sheet_to_json(ws, {'{'} header: "A" {'}'}) [column names as keys]</b><br/> | ||||
|     [<br/>{aoo(XLSX.utils.sheet_to_json(ws, { header: "A" }))}<br/>]<br/><br/> | ||||
|     <b>XLSX.utils.sheet_to_json(ws, {'{'} header: ["A","E","I","O","U","6","9"] {'}'})</b><br/> | ||||
|     [<br/>{aoo(XLSX.utils.sheet_to_json(ws, { header: ["A","E","I","O","U","6","9"] }))}<br/>]<br/> | ||||
|   </pre> ); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| Example showing the effect of `raw`: | ||||
| ### Formulae Output | ||||
| 
 | ||||
| ```js | ||||
| > ws['A2'].w = "3";                          // set A2 formatted string value | ||||
| 
 | ||||
| > XLSX.utils.sheet_to_json(ws, {header:1, raw:false}); | ||||
| [ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], | ||||
|   [ '3', '2', '3', '4', '5', '6', '7' ],     // <-- A2 uses the formatted string | ||||
|   [ '2', '3', '4', '5', '6', '7', '8' ] ] | ||||
| 
 | ||||
| > XLSX.utils.sheet_to_json(ws, {header:1}); | ||||
| [ [ 'S', 'h', 'e', 'e', 't', 'J', 'S' ], | ||||
|   [ 1, 2, 3, 4, 5, 6, 7 ],                   // <-- A2 uses the raw value | ||||
|   [ 2, 3, 4, 5, 6, 7, 8 ] ] | ||||
| var fmla_arr = XLSX.utils.sheet_to_formulae(ws); | ||||
| ``` | ||||
| 
 | ||||
| `XLSX.utils.sheet_to_formulae` generates an array of commands that represent | ||||
| how a person would enter data into an application. | ||||
| 
 | ||||
| Cells without formulae are written as `A1-cell-address=value`: | ||||
| 
 | ||||
| ``` | ||||
| A1=1                   // A1 is the numeric value 1 | ||||
| B1=TRUE                // B1 is the logical value TRUE | ||||
| ``` | ||||
| 
 | ||||
| String literals are prefixed with a `'` in accordance with Excel: | ||||
| 
 | ||||
| ``` | ||||
| A5='A4+A3              // A5 is the string "A4+A3" | ||||
| ``` | ||||
| 
 | ||||
| Cells with formulae are written as `A1-cell-address=formula`: | ||||
| 
 | ||||
| ``` | ||||
| A5=A4+A3               // A5 is a cell with formula =A4+A3 | ||||
| ``` | ||||
| 
 | ||||
| Array formulae are written as `A1-range=formula`.  They do not include the | ||||
| displayed curly braces: | ||||
| 
 | ||||
| ``` | ||||
| A4:B4=A2:B2*A3:B3      // A4:B4 array formula {=A2:B2*A3:B3} | ||||
| ``` | ||||
| 
 | ||||
| Single-cell array formulae are written with single-cell ranges: | ||||
| 
 | ||||
| ``` | ||||
| C4:C4=SUM(A2:A3*B2:B3) // C4 array formula {=SUM(A2:A3*B2:B3)} | ||||
| ``` | ||||
| 
 | ||||
| ```jsx live | ||||
| function SheetJSToJSON() { | ||||
|   var ws = XLSX.utils.aoa_to_sheet([ | ||||
|     ["A", "B", "C"], | ||||
|     [1, 2, { t: "n", f: "SUM(A2:B2)" }], | ||||
|     [3, 4, { t: "n", f: "A3+B3" }] | ||||
|   ]); | ||||
|   XLSX.utils.sheet_set_array_formula(ws, "A4:B4", "A2:B2*A3:B3"); | ||||
|   XLSX.utils.sheet_set_array_formula(ws, "C4", "SUM(A2:A3*B2:B3)"); | ||||
| 
 | ||||
|   var __html = `\ | ||||
| <i>Values</i> | ||||
| [ | ||||
|   ["A", "B", "C"], | ||||
|   [1,  2], | ||||
|   [3,  4] | ||||
| ] | ||||
| <i>Formulae</i> | ||||
| C2     =SUM(A2:B2) | ||||
| C3     =A3+B3 | ||||
| <i>Array Formulae</i> | ||||
| A4:B4  {=A2:B2*A3:B3} | ||||
| C4     {=SUM(A2:A3*B2:B3)} | ||||
| 
 | ||||
| `; | ||||
| 
 | ||||
|   return ( <pre> | ||||
|     <b>Original worksheet</b> | ||||
|     <div dangerouslySetInnerHTML={{__html}}/> | ||||
|     <b>XLSX.utils.sheet_to_formulae(ws).join("\n")</b><br/> | ||||
|     <br/>{XLSX.utils.sheet_to_formulae(ws).join("\n")} | ||||
|   </pre> ); | ||||
| } | ||||
| ``` | ||||
| </details> | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| --- | ||||
| sidebar_position: 1 | ||||
| hide_table_of_contents: true | ||||
| --- | ||||
| 
 | ||||
| # File Formats | ||||
| @ -39,7 +40,7 @@ sidebar_position: 1 | ||||
| | Works 6.x-9.x Spreadsheet (XLR)                              |   ✔   |       | | ||||
| | **Other Common Spreadsheet Output Formats**                  |:-----:|:-----:| | ||||
| | HTML Tables                                                  |   ✔   |   ✔   | | ||||
| | Rich Text Format tables (RTF)                                |       |   ✔   | | ||||
| | Rich Text Format tables (RTF)                                |   ✔   |   ✔   | | ||||
| | Ethercalc Record Format (ETH)                                |   ✔   |   ✔   | | ||||
| 
 | ||||
| Features not supported by a given file format will not be written.  Formats with | ||||
|  | ||||
| Before Width: | Height: | Size: 204 KiB After Width: | Height: | Size: 275 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docz/static/files/multitable.png
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| After Width: | Height: | Size: 25 KiB | 
| @ -1,534 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" | ||||
|  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> | ||||
| <!-- Generated by graphviz version 3.0.0 (20220226.1711) | ||||
|  --> | ||||
| <!-- Title: G Pages: 1 --> | ||||
| <svg width="836pt" height="816pt" | ||||
|  viewBox="0.00 0.00 835.92 815.55" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||||
| <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 811.55)"> | ||||
| <title>G</title> | ||||
| <polygon fill="white" stroke="transparent" points="-4,4 -4,-811.55 831.92,-811.55 831.92,4 -4,4"/> | ||||
| <!-- csf --> | ||||
| <g id="node1" class="node"> | ||||
| <title>csf</title> | ||||
| <ellipse fill="none" stroke="black" cx="413.33" cy="-403.68" rx="65.54" ry="65.54"/> | ||||
| <ellipse fill="none" stroke="black" cx="413.33" cy="-403.68" rx="69.52" ry="69.52"/> | ||||
| <text text-anchor="middle" x="413.33" y="-422.48" font-family="Indie Flower" font-size="14.00">Common</text> | ||||
| <text text-anchor="middle" x="413.33" y="-407.48" font-family="Indie Flower" font-size="14.00">Spreadsheet</text> | ||||
| <text text-anchor="middle" x="413.33" y="-392.48" font-family="Indie Flower" font-size="14.00">Format</text> | ||||
| <text text-anchor="middle" x="413.33" y="-377.48" font-family="Indie Flower" font-size="14.00">(JS Object)</text> | ||||
| </g> | ||||
| <!-- xls2 --> | ||||
| <g id="node2" class="node"> | ||||
| <title>xls2</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="790.45" cy="-403.68" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="790.45" y="-407.48" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="790.45" y="-392.48" font-family="Indie Flower" font-size="14.00">BIFF2</text> | ||||
| </g> | ||||
| <!-- csf->xls2 --> | ||||
| <g id="edge25" class="edge"> | ||||
| <title>csf->xls2</title> | ||||
| <path fill="none" stroke="#458b74" d="M482.94,-409.06C558.69,-411.11 677.75,-410.86 743.28,-408.33"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="743.48,-411.83 753.32,-407.91 743.18,-404.83 743.48,-411.83"/> | ||||
| </g> | ||||
| <!-- xls3 --> | ||||
| <g id="node3" class="node"> | ||||
| <title>xls3</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="781.53" cy="-485.19" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="781.53" y="-488.99" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="781.53" y="-473.99" font-family="Indie Flower" font-size="14.00">BIFF3</text> | ||||
| </g> | ||||
| <!-- csf->xls3 --> | ||||
| <g id="edge27" class="edge"> | ||||
| <title>csf->xls3</title> | ||||
| <path fill="none" stroke="#458b74" d="M480.13,-423.98C553.65,-442.35 669.94,-467.84 734.47,-479.53"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="733.91,-482.99 744.37,-481.29 735.14,-476.1 733.91,-482.99"/> | ||||
| </g> | ||||
| <!-- xls4 --> | ||||
| <g id="node4" class="node"> | ||||
| <title>xls4</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="755.21" cy="-562.84" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="755.21" y="-566.64" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="755.21" y="-551.64" font-family="Indie Flower" font-size="14.00">BIFF4</text> | ||||
| </g> | ||||
| <!-- csf->xls4 --> | ||||
| <g id="edge29" class="edge"> | ||||
| <title>csf->xls4</title> | ||||
| <path fill="none" stroke="#458b74" d="M474.16,-437.93C542.38,-471.96 651.29,-522.38 711.56,-547.6"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="710.58,-550.98 721.16,-551.57 713.25,-544.51 710.58,-550.98"/> | ||||
| </g> | ||||
| <!-- xls5 --> | ||||
| <g id="node5" class="node"> | ||||
| <title>xls5</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="712.74" cy="-632.97" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="712.74" y="-636.77" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="712.74" y="-621.77" font-family="Indie Flower" font-size="14.00">BIFF5</text> | ||||
| </g> | ||||
| <!-- csf->xls5 --> | ||||
| <g id="edge7" class="edge"> | ||||
| <title>csf->xls5</title> | ||||
| <path fill="none" stroke="blue" d="M465.32,-450.27C525.2,-498.75 622.04,-572.55 675.09,-609.83"/> | ||||
| <polygon fill="blue" stroke="blue" points="673.32,-612.87 683.53,-615.71 677.32,-607.12 673.32,-612.87"/> | ||||
| </g> | ||||
| <!-- xls8 --> | ||||
| <g id="node6" class="node"> | ||||
| <title>xls8</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="656.1" cy="-692.26" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="656.1" y="-696.06" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="656.1" y="-681.06" font-family="Indie Flower" font-size="14.00">BIFF8</text> | ||||
| </g> | ||||
| <!-- csf->xls8 --> | ||||
| <g id="edge9" class="edge"> | ||||
| <title>csf->xls8</title> | ||||
| <path fill="none" stroke="blue" d="M454.03,-460.41C502.64,-521.47 582.67,-616.11 626.05,-663.39"/> | ||||
| <polygon fill="blue" stroke="blue" points="623.57,-665.87 632.94,-670.83 628.71,-661.12 623.57,-665.87"/> | ||||
| </g> | ||||
| <!-- xlml --> | ||||
| <g id="node7" class="node"> | ||||
| <title>xlml</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="579.16" cy="-742.38" rx="47.25" ry="26.74"/> | ||||
| <text text-anchor="middle" x="579.16" y="-746.18" font-family="Indie Flower" font-size="14.00">SSML</text> | ||||
| <text text-anchor="middle" x="579.16" y="-731.18" font-family="Indie Flower" font-size="14.00">(2003/4)</text> | ||||
| </g> | ||||
| <!-- csf->xlml --> | ||||
| <g id="edge5" class="edge"> | ||||
| <title>csf->xlml</title> | ||||
| <path fill="none" stroke="blue" d="M439.11,-468.56C471.78,-540.11 527.17,-652.46 557.68,-708.4"/> | ||||
| <polygon fill="blue" stroke="blue" points="554.64,-710.14 562.54,-717.2 560.77,-706.76 554.64,-710.14"/> | ||||
| </g> | ||||
| <!-- xlsx --> | ||||
| <g id="node8" class="node"> | ||||
| <title>xlsx</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="491.7" cy="-772.57" rx="38.37" ry="26.74"/> | ||||
| <text text-anchor="middle" x="491.7" y="-776.37" font-family="Indie Flower" font-size="14.00">XLSX</text> | ||||
| <text text-anchor="middle" x="491.7" y="-761.37" font-family="Indie Flower" font-size="14.00">XLSM</text> | ||||
| </g> | ||||
| <!-- csf->xlsx --> | ||||
| <g id="edge1" class="edge"> | ||||
| <title>csf->xlsx</title> | ||||
| <path fill="none" stroke="blue" d="M422.54,-472.89C436.95,-551.07 463.73,-675.33 479.65,-736.35"/> | ||||
| <polygon fill="blue" stroke="blue" points="476.34,-737.52 482.3,-746.28 483.1,-735.72 476.34,-737.52"/> | ||||
| </g> | ||||
| <!-- xlsb --> | ||||
| <g id="node9" class="node"> | ||||
| <title>xlsb</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="403.76" cy="-780.68" rx="43.27" ry="26.74"/> | ||||
| <text text-anchor="middle" x="403.76" y="-784.48" font-family="Indie Flower" font-size="14.00">XLSB</text> | ||||
| <text text-anchor="middle" x="403.76" y="-769.48" font-family="Indie Flower" font-size="14.00">BIFF12</text> | ||||
| </g> | ||||
| <!-- csf->xlsb --> | ||||
| <g id="edge3" class="edge"> | ||||
| <title>csf->xlsb</title> | ||||
| <path fill="none" stroke="blue" d="M406.19,-473.13C402,-552.92 399.14,-680.89 400.48,-743.6"/> | ||||
| <polygon fill="blue" stroke="blue" points="396.99,-743.91 400.76,-753.81 403.99,-743.72 396.99,-743.91"/> | ||||
| </g> | ||||
| <!-- nums --> | ||||
| <g id="node10" class="node"> | ||||
| <title>nums</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="299.96" cy="-763.36" rx="55.49" ry="18"/> | ||||
| <text text-anchor="middle" x="299.96" y="-759.66" font-family="Indie Flower" font-size="14.00">NUMBERS</text> | ||||
| </g> | ||||
| <!-- csf->nums --> | ||||
| <g id="edge23" class="edge"> | ||||
| <title>csf->nums</title> | ||||
| <path fill="none" stroke="blue" d="M387.28,-468.45C359.87,-547.84 319.17,-678.77 304.78,-735.61"/> | ||||
| <polygon fill="blue" stroke="blue" points="301.37,-734.79 302.4,-745.33 308.18,-736.45 301.37,-734.79"/> | ||||
| </g> | ||||
| <!-- ods --> | ||||
| <g id="node11" class="node"> | ||||
| <title>ods</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="215.6" cy="-724.8" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="215.6" y="-721.1" font-family="Indie Flower" font-size="14.00">ODS</text> | ||||
| </g> | ||||
| <!-- csf->ods --> | ||||
| <g id="edge13" class="edge"> | ||||
| <title>csf->ods</title> | ||||
| <path fill="none" stroke="blue" d="M372.25,-460.14C326.52,-530.09 255.55,-646.35 227.44,-698.33"/> | ||||
| <polygon fill="blue" stroke="blue" points="224.3,-696.79 222.7,-707.26 230.48,-700.07 224.3,-696.79"/> | ||||
| </g> | ||||
| <!-- fods --> | ||||
| <g id="node12" class="node"> | ||||
| <title>fods</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="157.15" cy="-680.43" rx="36" ry="18"/> | ||||
| <text text-anchor="middle" x="157.15" y="-676.73" font-family="Indie Flower" font-size="14.00">FODS</text> | ||||
| </g> | ||||
| <!-- csf->fods --> | ||||
| <g id="edge15" class="edge"> | ||||
| <title>csf->fods</title> | ||||
| <path fill="none" stroke="blue" d="M362.1,-451.11C304.39,-510.17 213.75,-608.81 175.28,-655.09"/> | ||||
| <polygon fill="blue" stroke="blue" points="172.34,-653.15 168.72,-663.1 177.76,-657.58 172.34,-653.15"/> | ||||
| </g> | ||||
| <!-- html --> | ||||
| <g id="node14" class="node"> | ||||
| <title>html</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="103.98" cy="-619.37" rx="38.37" ry="26.74"/> | ||||
| <text text-anchor="middle" x="103.98" y="-623.17" font-family="Indie Flower" font-size="14.00">HTML</text> | ||||
| <text text-anchor="middle" x="103.98" y="-608.17" font-family="Indie Flower" font-size="14.00">Table</text> | ||||
| </g> | ||||
| <!-- csf->html --> | ||||
| <g id="edge50" class="edge"> | ||||
| <title>csf->html</title> | ||||
| <path fill="none" stroke="#458b74" d="M353.15,-439.08C288.12,-481.86 186.98,-552.76 135.84,-591.74"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="133.57,-589.07 127.78,-597.94 137.84,-594.62 133.57,-589.07"/> | ||||
| </g> | ||||
| <!-- csv --> | ||||
| <g id="node15" class="node"> | ||||
| <title>csv</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="67.87" cy="-554.93" rx="28.7" ry="18"/> | ||||
| <text text-anchor="middle" x="67.87" y="-551.23" font-family="Indie Flower" font-size="14.00">CSV</text> | ||||
| </g> | ||||
| <!-- csf->csv --> | ||||
| <g id="edge44" class="edge"> | ||||
| <title>csf->csv</title> | ||||
| <path fill="none" stroke="#458b74" d="M347.41,-426.68C272.23,-457.2 152.63,-510.03 97.48,-537.51"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="95.61,-534.54 88.27,-542.18 98.77,-540.79 95.61,-534.54"/> | ||||
| </g> | ||||
| <!-- txt --> | ||||
| <g id="node16" class="node"> | ||||
| <title>txt</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="43.84" cy="-479.16" rx="43.68" ry="26.74"/> | ||||
| <text text-anchor="middle" x="43.84" y="-482.96" font-family="Indie Flower" font-size="14.00">TXT</text> | ||||
| <text text-anchor="middle" x="43.84" y="-467.96" font-family="Indie Flower" font-size="14.00">UTF-16</text> | ||||
| </g> | ||||
| <!-- csf->txt --> | ||||
| <g id="edge46" class="edge"> | ||||
| <title>csf->txt</title> | ||||
| <path fill="none" stroke="#458b74" d="M344.05,-412.35C270.81,-425.26 157.16,-448.67 92.75,-464.28"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="91.72,-460.93 82.84,-466.72 93.39,-467.73 91.72,-460.93"/> | ||||
| </g> | ||||
| <!-- dbf --> | ||||
| <g id="node17" class="node"> | ||||
| <title>dbf</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="36.23" cy="-400.04" rx="28.7" ry="18"/> | ||||
| <text text-anchor="middle" x="36.23" y="-396.34" font-family="Indie Flower" font-size="14.00">DBF</text> | ||||
| </g> | ||||
| <!-- csf->dbf --> | ||||
| <g id="edge48" class="edge"> | ||||
| <title>csf->dbf</title> | ||||
| <path fill="none" stroke="#458b74" d="M343.77,-397.63C264.53,-394.72 137.86,-393.86 74.68,-396.12"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="74.22,-392.64 64.37,-396.55 74.51,-399.63 74.22,-392.64"/> | ||||
| </g> | ||||
| <!-- dif --> | ||||
| <g id="node18" class="node"> | ||||
| <title>dif</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="42.05" cy="-337.58" rx="27" ry="18"/> | ||||
| <text text-anchor="middle" x="42.05" y="-333.88" font-family="Indie Flower" font-size="14.00">DIF</text> | ||||
| </g> | ||||
| <!-- csf->dif --> | ||||
| <g id="edge32" class="edge"> | ||||
| <title>csf->dif</title> | ||||
| <path fill="none" stroke="#458b74" d="M345.74,-386.19C267.48,-370.06 141.4,-348.01 79.2,-339.91"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="79.42,-336.41 69.06,-338.65 78.55,-343.36 79.42,-336.41"/> | ||||
| </g> | ||||
| <!-- slk --> | ||||
| <g id="node19" class="node"> | ||||
| <title>slk</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="59.69" cy="-272.68" rx="33.29" ry="18"/> | ||||
| <text text-anchor="middle" x="59.69" y="-268.98" font-family="Indie Flower" font-size="14.00">SYLK</text> | ||||
| </g> | ||||
| <!-- csf->slk --> | ||||
| <g id="edge30" class="edge"> | ||||
| <title>csf->slk</title> | ||||
| <path fill="none" stroke="#458b74" d="M349.92,-374.46C277.49,-345.38 161.16,-302.63 100.09,-282.93"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="101.01,-279.55 90.42,-279.87 98.89,-286.23 101.01,-279.55"/> | ||||
| </g> | ||||
| <!-- prn --> | ||||
| <g id="node20" class="node"> | ||||
| <title>prn</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="89.74" cy="-210.01" rx="29.5" ry="18"/> | ||||
| <text text-anchor="middle" x="89.74" y="-206.31" font-family="Indie Flower" font-size="14.00">PRN</text> | ||||
| </g> | ||||
| <!-- csf->prn --> | ||||
| <g id="edge42" class="edge"> | ||||
| <title>csf->prn</title> | ||||
| <path fill="none" stroke="#458b74" d="M356.36,-363.32C288.77,-320.34 178.35,-254.72 123.22,-225.16"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="124.7,-221.99 114.22,-220.41 121.43,-228.18 124.7,-221.99"/> | ||||
| </g> | ||||
| <!-- rtf --> | ||||
| <g id="node21" class="node"> | ||||
| <title>rtf</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="127.35" cy="-157.84" rx="27.9" ry="18"/> | ||||
| <text text-anchor="middle" x="127.35" y="-154.14" font-family="Indie Flower" font-size="14.00">RTF</text> | ||||
| </g> | ||||
| <!-- csf->rtf --> | ||||
| <g id="edge40" class="edge"> | ||||
| <title>csf->rtf</title> | ||||
| <path fill="none" stroke="#458b74" d="M360.21,-358.02C298.04,-304.57 197.75,-218.36 151.79,-178.85"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="153.98,-176.12 144.12,-172.25 149.42,-181.43 153.98,-176.12"/> | ||||
| </g> | ||||
| <!-- wk1 --> | ||||
| <g id="node22" class="node"> | ||||
| <title>wk1</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="174.29" cy="-112" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="174.29" y="-108.3" font-family="Indie Flower" font-size="14.00">WK1</text> | ||||
| </g> | ||||
| <!-- csf->wk1 --> | ||||
| <g id="edge34" class="edge"> | ||||
| <title>csf->wk1</title> | ||||
| <path fill="none" stroke="#458b74" d="M373.36,-346.44C323.28,-281.83 239.2,-179.96 198.15,-134.79"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="200.59,-132.27 191.24,-127.28 195.44,-137.01 200.59,-132.27"/> | ||||
| </g> | ||||
| <!-- wk3 --> | ||||
| <g id="node24" class="node"> | ||||
| <title>wk3</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="230.73" cy="-73.72" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="230.73" y="-70.02" font-family="Indie Flower" font-size="14.00">WK3</text> | ||||
| </g> | ||||
| <!-- csf->wk3 --> | ||||
| <g id="edge18" class="edge"> | ||||
| <title>csf->wk3</title> | ||||
| <path fill="none" stroke="blue" d="M384.33,-340.17C346.31,-266.87 281.03,-149.9 249.12,-98.87"/> | ||||
| <polygon fill="blue" stroke="blue" points="251.89,-96.69 243.57,-90.13 245.98,-100.45 251.89,-96.69"/> | ||||
| </g> | ||||
| <!-- eth --> | ||||
| <g id="node32" class="node"> | ||||
| <title>eth</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="291.3" cy="-46.85" rx="28.7" ry="18"/> | ||||
| <text text-anchor="middle" x="291.3" y="-43.15" font-family="Indie Flower" font-size="14.00">ETH</text> | ||||
| </g> | ||||
| <!-- csf->eth --> | ||||
| <g id="edge51" class="edge"> | ||||
| <title>csf->eth</title> | ||||
| <path fill="none" stroke="#458b74" d="M395.89,-336.08C371.11,-256.68 326.85,-128.82 304.52,-73.62"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="307.67,-72.09 300.62,-64.19 301.21,-74.77 307.67,-72.09"/> | ||||
| </g> | ||||
| <!-- xls2->csf --> | ||||
| <g id="edge24" class="edge"> | ||||
| <title>xls2->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M753.25,-399.45C693.11,-396.65 573.17,-396.18 493.07,-398.05"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="492.92,-394.55 483.01,-398.3 493.1,-401.55 492.92,-394.55"/> | ||||
| </g> | ||||
| <!-- xls3->csf --> | ||||
| <g id="edge26" class="edge"> | ||||
| <title>xls3->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M747.79,-473.47C690.3,-457.8 571.89,-431.09 492.53,-415.44"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="493.05,-411.98 482.57,-413.5 491.71,-418.85 493.05,-411.98"/> | ||||
| </g> | ||||
| <!-- xls4->csf --> | ||||
| <g id="edge28" class="edge"> | ||||
| <title>xls4->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M726.87,-545.2C675,-517.77 563.3,-465.18 488.2,-432.32"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="489.34,-429 478.77,-428.22 486.55,-435.42 489.34,-429"/> | ||||
| </g> | ||||
| <!-- xls5->csf --> | ||||
| <g id="edge8" class="edge"> | ||||
| <title>xls5->csf</title> | ||||
| <path fill="none" stroke="blue" d="M690.61,-611.1C646.74,-573.63 547.39,-496.82 480.31,-447.87"/> | ||||
| <polygon fill="blue" stroke="blue" points="482.03,-444.8 471.88,-441.75 477.91,-450.46 482.03,-444.8"/> | ||||
| </g> | ||||
| <!-- xls8->csf --> | ||||
| <g id="edge10" class="edge"> | ||||
| <title>xls8->csf</title> | ||||
| <path fill="none" stroke="blue" d="M640.37,-667.64C606.25,-622.16 524.54,-524.1 469.01,-461.12"/> | ||||
| <polygon fill="blue" stroke="blue" points="471.62,-458.79 462.37,-453.62 466.38,-463.43 471.62,-458.79"/> | ||||
| </g> | ||||
| <!-- xlml->csf --> | ||||
| <g id="edge6" class="edge"> | ||||
| <title>xlml->csf</title> | ||||
| <path fill="none" stroke="blue" d="M570.33,-715.83C548.54,-663.98 492.39,-547.88 453.44,-472.8"/> | ||||
| <polygon fill="blue" stroke="blue" points="456.5,-471.11 448.78,-463.86 450.3,-474.34 456.5,-471.11"/> | ||||
| </g> | ||||
| <!-- xlsx->csf --> | ||||
| <g id="edge2" class="edge"> | ||||
| <title>xlsx->csf</title> | ||||
| <path fill="none" stroke="blue" d="M489.73,-745.57C481.38,-690.48 455.03,-563.36 435.43,-480.6"/> | ||||
| <polygon fill="blue" stroke="blue" points="438.8,-479.65 433.07,-470.74 431.99,-481.28 438.8,-479.65"/> | ||||
| </g> | ||||
| <!-- xlsb->csf --> | ||||
| <g id="edge4" class="edge"> | ||||
| <title>xlsb->csf</title> | ||||
| <path fill="none" stroke="blue" d="M408.15,-753.66C412.83,-697.93 416.76,-568.36 416.93,-483.47"/> | ||||
| <polygon fill="blue" stroke="blue" points="420.43,-483.35 416.94,-473.35 413.43,-483.35 420.43,-483.35"/> | ||||
| </g> | ||||
| <!-- nums->csf --> | ||||
| <g id="edge22" class="edge"> | ||||
| <title>nums->csf</title> | ||||
| <path fill="none" stroke="blue" d="M308.97,-745.49C327.76,-698.09 369.92,-567 394.67,-481.62"/> | ||||
| <polygon fill="blue" stroke="blue" points="398.05,-482.54 397.45,-471.96 391.32,-480.61 398.05,-482.54"/> | ||||
| </g> | ||||
| <!-- ods->csf --> | ||||
| <g id="edge12" class="edge"> | ||||
| <title>ods->csf</title> | ||||
| <path fill="none" stroke="blue" d="M229.64,-708.37C259.96,-665.94 331.65,-550.97 376.04,-475.01"/> | ||||
| <polygon fill="blue" stroke="blue" points="379.31,-476.35 381.31,-465.95 373.25,-472.83 379.31,-476.35"/> | ||||
| </g> | ||||
| <!-- fods->csf --> | ||||
| <g id="edge14" class="edge"> | ||||
| <title>fods->csf</title> | ||||
| <path fill="none" stroke="blue" d="M176.15,-665.09C215.32,-627.8 305.77,-531.13 363,-466.36"/> | ||||
| <polygon fill="blue" stroke="blue" points="365.83,-468.44 369.81,-458.62 360.57,-463.82 365.83,-468.44"/> | ||||
| </g> | ||||
| <!-- uos --> | ||||
| <g id="node13" class="node"> | ||||
| <title>uos</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="355.64" cy="-31" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="355.64" y="-27.3" font-family="Indie Flower" font-size="14.00">UOS</text> | ||||
| </g> | ||||
| <!-- uos->csf --> | ||||
| <g id="edge16" class="edge"> | ||||
| <title>uos->csf</title> | ||||
| <path fill="none" stroke="blue" d="M358.42,-48.98C366,-97.91 387.33,-235.76 401.07,-324.5"/> | ||||
| <polygon fill="blue" stroke="blue" points="397.63,-325.18 402.62,-334.53 404.55,-324.11 397.63,-325.18"/> | ||||
| </g> | ||||
| <!-- html->csf --> | ||||
| <g id="edge49" class="edge"> | ||||
| <title>html->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M134.59,-603.02C184.75,-571.6 285.28,-502.14 350.91,-454.07"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="353.15,-456.77 359.14,-448.02 349.01,-451.13 353.15,-456.77"/> | ||||
| </g> | ||||
| <!-- csv->csf --> | ||||
| <g id="edge43" class="edge"> | ||||
| <title>csv->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M94.2,-547.45C146.65,-528.05 265.66,-476.64 342.6,-440.79"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="344.2,-443.91 351.77,-436.5 341.23,-437.57 344.2,-443.91"/> | ||||
| </g> | ||||
| <!-- txt->csf --> | ||||
| <g id="edge45" class="edge"> | ||||
| <title>txt->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M87.49,-474.85C148.63,-464.96 260.72,-442.44 336.13,-425.2"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="337.1,-428.57 346.05,-422.92 335.52,-421.75 337.1,-428.57"/> | ||||
| </g> | ||||
| <!-- dbf->csf --> | ||||
| <g id="edge47" class="edge"> | ||||
| <title>dbf->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M64.23,-404.06C120.46,-407.82 248.93,-409.69 333.36,-408.54"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="333.48,-412.04 343.43,-408.39 333.37,-405.04 333.48,-412.04"/> | ||||
| </g> | ||||
| <!-- dif->csf --> | ||||
| <g id="edge39" class="edge"> | ||||
| <title>dif->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M66.36,-345.56C119.67,-358.46 248.86,-382.15 333.67,-395.22"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="333.37,-398.72 343.78,-396.76 334.43,-391.8 333.37,-398.72"/> | ||||
| </g> | ||||
| <!-- slk->csf --> | ||||
| <g id="edge31" class="edge"> | ||||
| <title>slk->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M83.29,-285.33C134.11,-307.67 255.79,-353.44 336.35,-381.18"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="335.37,-384.54 345.96,-384.47 337.64,-377.92 335.37,-384.54"/> | ||||
| </g> | ||||
| <!-- prn->csf --> | ||||
| <g id="edge41" class="edge"> | ||||
| <title>prn->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M107.26,-224.48C150.82,-254.64 265.79,-324.31 341.77,-367.42"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="340.4,-370.67 350.83,-372.54 343.85,-364.58 340.4,-370.67"/> | ||||
| </g> | ||||
| <!-- wk1->csf --> | ||||
| <g id="edge33" class="edge"> | ||||
| <title>wk1->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M184.31,-129.31C213.71,-170.98 300.37,-277.99 358.3,-345.42"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="355.68,-347.74 364.86,-353.03 360.98,-343.17 355.68,-347.74"/> | ||||
| </g> | ||||
| <!-- wksl --> | ||||
| <g id="node23" class="node"> | ||||
| <title>wksl</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="428.51" cy="-26.87" rx="35.21" ry="26.74"/> | ||||
| <text text-anchor="middle" x="428.51" y="-30.67" font-family="Indie Flower" font-size="14.00">WKS</text> | ||||
| <text text-anchor="middle" x="428.51" y="-15.67" font-family="Indie Flower" font-size="14.00">Lotus</text> | ||||
| </g> | ||||
| <!-- wksl->csf --> | ||||
| <g id="edge37" class="edge"> | ||||
| <title>wksl->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M427.42,-53.97C425.17,-109.67 419.97,-238.9 416.55,-323.7"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="413.05,-323.68 416.14,-333.82 420.04,-323.97 413.05,-323.68"/> | ||||
| </g> | ||||
| <!-- wk3->csf --> | ||||
| <g id="edge17" class="edge"> | ||||
| <title>wk3->csf</title> | ||||
| <path fill="none" stroke="blue" d="M237.03,-91.6C257.98,-137.18 324.61,-259.29 369.76,-336.57"/> | ||||
| <polygon fill="blue" stroke="blue" points="366.8,-338.45 374.88,-345.3 372.83,-334.91 366.8,-338.45"/> | ||||
| </g> | ||||
| <!-- wk4 --> | ||||
| <g id="node25" class="node"> | ||||
| <title>wk4</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="500.81" cy="-36.85" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="500.81" y="-33.15" font-family="Indie Flower" font-size="14.00">WK4</text> | ||||
| </g> | ||||
| <!-- wk4->csf --> | ||||
| <g id="edge19" class="edge"> | ||||
| <title>wk4->csf</title> | ||||
| <path fill="none" stroke="blue" d="M496.53,-54.79C484.99,-103.2 452.67,-238.7 431.88,-325.89"/> | ||||
| <polygon fill="blue" stroke="blue" points="428.44,-325.21 429.53,-335.75 435.25,-326.83 428.44,-325.21"/> | ||||
| </g> | ||||
| <!-- 123 --> | ||||
| <g id="node26" class="node"> | ||||
| <title>123</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="562.2" cy="-57.19" rx="27" ry="18"/> | ||||
| <text text-anchor="middle" x="562.2" y="-53.49" font-family="Indie Flower" font-size="14.00">123</text> | ||||
| </g> | ||||
| <!-- 123->csf --> | ||||
| <g id="edge20" class="edge"> | ||||
| <title>123->csf</title> | ||||
| <path fill="none" stroke="blue" d="M554.61,-74.85C534.7,-121.19 480.06,-248.36 444.86,-330.29"/> | ||||
| <polygon fill="blue" stroke="blue" points="441.61,-328.98 440.88,-339.55 448.04,-331.75 441.61,-328.98"/> | ||||
| </g> | ||||
| <!-- wksm --> | ||||
| <g id="node27" class="node"> | ||||
| <title>wksm</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="626.15" cy="-92.35" rx="38.78" ry="26.74"/> | ||||
| <text text-anchor="middle" x="626.15" y="-96.15" font-family="Indie Flower" font-size="14.00">WKS</text> | ||||
| <text text-anchor="middle" x="626.15" y="-81.15" font-family="Indie Flower" font-size="14.00">Works</text> | ||||
| </g> | ||||
| <!-- wksm->csf --> | ||||
| <g id="edge38" class="edge"> | ||||
| <title>wksm->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M609.45,-116.78C577.31,-163.8 505.87,-268.3 458.67,-337.35"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="455.5,-335.78 452.75,-346.01 461.28,-339.73 455.5,-335.78"/> | ||||
| </g> | ||||
| <!-- xlr --> | ||||
| <g id="node28" class="node"> | ||||
| <title>xlr</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="682.79" cy="-139.85" rx="27.9" ry="18"/> | ||||
| <text text-anchor="middle" x="682.79" y="-136.15" font-family="Indie Flower" font-size="14.00">XLR</text> | ||||
| </g> | ||||
| <!-- xlr->csf --> | ||||
| <g id="edge35" class="edge"> | ||||
| <title>xlr->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M667.14,-155.17C629.68,-191.84 533.36,-286.15 470.74,-347.47"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="467.97,-345.28 463.27,-354.78 472.87,-350.28 467.97,-345.28"/> | ||||
| </g> | ||||
| <!-- wq1 --> | ||||
| <g id="node29" class="node"> | ||||
| <title>wq1</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="725.17" cy="-191.62" rx="31.7" ry="18"/> | ||||
| <text text-anchor="middle" x="725.17" y="-187.92" font-family="Indie Flower" font-size="14.00">WQ1</text> | ||||
| </g> | ||||
| <!-- wq1->csf --> | ||||
| <g id="edge36" class="edge"> | ||||
| <title>wq1->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M704.71,-205.53C659.79,-236.08 550.87,-310.15 479.67,-358.56"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="477.48,-355.82 471.18,-364.34 481.42,-361.61 477.48,-355.82"/> | ||||
| </g> | ||||
| <!-- wq2 --> | ||||
| <g id="node30" class="node"> | ||||
| <title>wq2</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="760.41" cy="-256.21" rx="34.8" ry="26.74"/> | ||||
| <text text-anchor="middle" x="760.41" y="-260.01" font-family="Indie Flower" font-size="14.00">WQ2</text> | ||||
| <text text-anchor="middle" x="760.41" y="-245.01" font-family="Indie Flower" font-size="14.00">WB*</text> | ||||
| </g> | ||||
| <!-- wq2->csf --> | ||||
| <g id="edge11" class="edge"> | ||||
| <title>wq2->csf</title> | ||||
| <path fill="none" stroke="blue" d="M729.92,-269.16C676.06,-292.05 562.68,-340.22 487.26,-372.27"/> | ||||
| <polygon fill="blue" stroke="blue" points="485.63,-369.16 477.8,-376.29 488.37,-375.6 485.63,-369.16"/> | ||||
| </g> | ||||
| <!-- qpw --> | ||||
| <g id="node31" class="node"> | ||||
| <title>qpw</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="782.58" cy="-327.05" rx="32.49" ry="18"/> | ||||
| <text text-anchor="middle" x="782.58" y="-323.35" font-family="Indie Flower" font-size="14.00">QPW</text> | ||||
| </g> | ||||
| <!-- qpw->csf --> | ||||
| <g id="edge21" class="edge"> | ||||
| <title>qpw->csf</title> | ||||
| <path fill="none" stroke="blue" d="M752.05,-333.38C695.54,-345.11 573.04,-370.53 491.9,-387.38"/> | ||||
| <polygon fill="blue" stroke="blue" points="490.8,-384.03 481.72,-389.49 492.22,-390.88 490.8,-384.03"/> | ||||
| </g> | ||||
| <!-- eth->csf --> | ||||
| <g id="edge52" class="edge"> | ||||
| <title>eth->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M294.25,-65.07C306.72,-113.21 351.17,-245.78 382.2,-330.05"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="378.97,-331.41 385.72,-339.57 385.53,-328.98 378.97,-331.41"/> | ||||
| </g> | ||||
| </g> | ||||
| </svg> | ||||
| Before Width: | Height: | Size: 26 KiB | 
							
								
								
									
										
											BIN
										
									
								
								formats.png
									
									
									
									
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| Before Width: | Height: | Size: 204 KiB After Width: | Height: | Size: 275 KiB | 
| @ -1,6 +1,6 @@ | ||||
| digraph G { | ||||
| 	graph [mindist=0.1]; | ||||
| 	node [fontname="Indie Flower"]; | ||||
| 	node [fontname="Indie Flower",fontsize=22]; | ||||
| 	csf [shape=doublecircle,label="Common\nSpreadsheet\nFormat\n(JS Object)"]; | ||||
| 	subgraph XL { | ||||
| 		node  [style=filled,color="#00FF00"]; | ||||
| @ -85,6 +85,7 @@ digraph G { | ||||
| 		wksl -> csf | ||||
| 		wksm -> csf | ||||
| 		dif -> csf | ||||
| 		rtf -> csf | ||||
| 		csf -> rtf | ||||
| 		prn -> csf | ||||
| 		csf -> prn | ||||
|  | ||||
							
								
								
									
										410
									
								
								misc/formats.svg
									
									
									
									
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						| @ -4,531 +4,537 @@ | ||||
| <!-- Generated by graphviz version 3.0.0 (20220226.1711) | ||||
|  --> | ||||
| <!-- Title: G Pages: 1 --> | ||||
| <svg width="836pt" height="816pt" | ||||
|  viewBox="0.00 0.00 835.92 815.55" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||||
| <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 811.55)"> | ||||
| <svg width="1056pt" height="1033pt" | ||||
|  viewBox="0.00 0.00 1055.79 1032.90" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||||
| <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 1028.9)"> | ||||
| <title>G</title> | ||||
| <polygon fill="white" stroke="transparent" points="-4,4 -4,-811.55 831.92,-811.55 831.92,4 -4,4"/> | ||||
| <polygon fill="white" stroke="transparent" points="-4,4 -4,-1028.9 1051.79,-1028.9 1051.79,4 -4,4"/> | ||||
| <!-- csf --> | ||||
| <g id="node1" class="node"> | ||||
| <title>csf</title> | ||||
| <ellipse fill="none" stroke="black" cx="413.33" cy="-403.68" rx="65.54" ry="65.54"/> | ||||
| <ellipse fill="none" stroke="black" cx="413.33" cy="-403.68" rx="69.52" ry="69.52"/> | ||||
| <text text-anchor="middle" x="413.33" y="-422.48" font-family="Indie Flower" font-size="14.00">Common</text> | ||||
| <text text-anchor="middle" x="413.33" y="-407.48" font-family="Indie Flower" font-size="14.00">Spreadsheet</text> | ||||
| <text text-anchor="middle" x="413.33" y="-392.48" font-family="Indie Flower" font-size="14.00">Format</text> | ||||
| <text text-anchor="middle" x="413.33" y="-377.48" font-family="Indie Flower" font-size="14.00">(JS Object)</text> | ||||
| <ellipse fill="none" stroke="black" cx="523.61" cy="-511.58" rx="94.52" ry="94.52"/> | ||||
| <ellipse fill="none" stroke="black" cx="523.61" cy="-511.58" rx="98.51" ry="98.51"/> | ||||
| <text text-anchor="middle" x="523.61" y="-541.98" font-family="Indie Flower" font-size="22.00">Common</text> | ||||
| <text text-anchor="middle" x="523.61" y="-517.98" font-family="Indie Flower" font-size="22.00">Spreadsheet</text> | ||||
| <text text-anchor="middle" x="523.61" y="-493.98" font-family="Indie Flower" font-size="22.00">Format</text> | ||||
| <text text-anchor="middle" x="523.61" y="-469.98" font-family="Indie Flower" font-size="22.00">(JS Object)</text> | ||||
| </g> | ||||
| <!-- xls2 --> | ||||
| <g id="node2" class="node"> | ||||
| <title>xls2</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="790.45" cy="-403.68" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="790.45" y="-407.48" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="790.45" y="-392.48" font-family="Indie Flower" font-size="14.00">BIFF2</text> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="997.58" cy="-511.58" rx="50.41" ry="39.7"/> | ||||
| <text text-anchor="middle" x="997.58" y="-517.98" font-family="Indie Flower" font-size="22.00">XLS</text> | ||||
| <text text-anchor="middle" x="997.58" y="-493.98" font-family="Indie Flower" font-size="22.00">BIFF2</text> | ||||
| </g> | ||||
| <!-- csf->xls2 --> | ||||
| <g id="edge25" class="edge"> | ||||
| <title>csf->xls2</title> | ||||
| <path fill="none" stroke="#458b74" d="M482.94,-409.06C558.69,-411.11 677.75,-410.86 743.28,-408.33"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="743.48,-411.83 753.32,-407.91 743.18,-404.83 743.48,-411.83"/> | ||||
| <path fill="none" stroke="#458b74" d="M622.39,-517.19C717.42,-518.98 858.03,-518.67 937.37,-516.26"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="937.8,-519.75 947.68,-515.93 937.57,-512.76 937.8,-519.75"/> | ||||
| </g> | ||||
| <!-- xls3 --> | ||||
| <g id="node3" class="node"> | ||||
| <title>xls3</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="781.53" cy="-485.19" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="781.53" y="-488.99" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="781.53" y="-473.99" font-family="Indie Flower" font-size="14.00">BIFF3</text> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="985.74" cy="-616.89" rx="48.58" ry="39.7"/> | ||||
| <text text-anchor="middle" x="985.74" y="-623.29" font-family="Indie Flower" font-size="22.00">XLS</text> | ||||
| <text text-anchor="middle" x="985.74" y="-599.29" font-family="Indie Flower" font-size="22.00">BIFF3</text> | ||||
| </g> | ||||
| <!-- csf->xls3 --> | ||||
| <g id="edge27" class="edge"> | ||||
| <title>csf->xls3</title> | ||||
| <path fill="none" stroke="#458b74" d="M480.13,-423.98C553.65,-442.35 669.94,-467.84 734.47,-479.53"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="733.91,-482.99 744.37,-481.29 735.14,-476.1 733.91,-482.99"/> | ||||
| <path fill="none" stroke="#458b74" d="M618.68,-539C711.44,-561.98 849.59,-593.14 927.26,-608.33"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="926.87,-611.81 937.35,-610.27 928.19,-604.94 926.87,-611.81"/> | ||||
| </g> | ||||
| <!-- xls4 --> | ||||
| <g id="node4" class="node"> | ||||
| <title>xls4</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="755.21" cy="-562.84" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="755.21" y="-566.64" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="755.21" y="-551.64" font-family="Indie Flower" font-size="14.00">BIFF4</text> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="951.7" cy="-715.02" rx="48.17" ry="39.7"/> | ||||
| <text text-anchor="middle" x="951.7" y="-721.42" font-family="Indie Flower" font-size="22.00">XLS</text> | ||||
| <text text-anchor="middle" x="951.7" y="-697.42" font-family="Indie Flower" font-size="22.00">BIFF4</text> | ||||
| </g> | ||||
| <!-- csf->xls4 --> | ||||
| <g id="edge29" class="edge"> | ||||
| <title>csf->xls4</title> | ||||
| <path fill="none" stroke="#458b74" d="M474.16,-437.93C542.38,-471.96 651.29,-522.38 711.56,-547.6"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="710.58,-550.98 721.16,-551.57 713.25,-544.51 710.58,-550.98"/> | ||||
| <path fill="none" stroke="#458b74" d="M610.42,-559.05C696.65,-602.03 826.1,-663.17 898.26,-694.7"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="897.06,-697.99 907.63,-698.76 899.85,-691.57 897.06,-697.99"/> | ||||
| </g> | ||||
| <!-- xls5 --> | ||||
| <g id="node5" class="node"> | ||||
| <title>xls5</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="712.74" cy="-632.97" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="712.74" y="-636.77" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="712.74" y="-621.77" font-family="Indie Flower" font-size="14.00">BIFF5</text> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="895.8" cy="-805.05" rx="50.82" ry="39.7"/> | ||||
| <text text-anchor="middle" x="895.8" y="-811.45" font-family="Indie Flower" font-size="22.00">XLS</text> | ||||
| <text text-anchor="middle" x="895.8" y="-787.45" font-family="Indie Flower" font-size="22.00">BIFF5</text> | ||||
| </g> | ||||
| <!-- csf->xls5 --> | ||||
| <g id="edge7" class="edge"> | ||||
| <title>csf->xls5</title> | ||||
| <path fill="none" stroke="blue" d="M465.32,-450.27C525.2,-498.75 622.04,-572.55 675.09,-609.83"/> | ||||
| <polygon fill="blue" stroke="blue" points="673.32,-612.87 683.53,-615.71 677.32,-607.12 673.32,-612.87"/> | ||||
| <path fill="none" stroke="blue" d="M597.71,-577.15C672.23,-638.22 784.86,-726.59 848.21,-773.36"/> | ||||
| <polygon fill="blue" stroke="blue" points="846.31,-776.31 856.44,-779.4 850.45,-770.66 846.31,-776.31"/> | ||||
| </g> | ||||
| <!-- xls8 --> | ||||
| <g id="node6" class="node"> | ||||
| <title>xls8</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="656.1" cy="-692.26" rx="37.45" ry="26.74"/> | ||||
| <text text-anchor="middle" x="656.1" y="-696.06" font-family="Indie Flower" font-size="14.00">XLS</text> | ||||
| <text text-anchor="middle" x="656.1" y="-681.06" font-family="Indie Flower" font-size="14.00">BIFF8</text> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="821.3" cy="-880.41" rx="48.17" ry="39.7"/> | ||||
| <text text-anchor="middle" x="821.3" y="-886.81" font-family="Indie Flower" font-size="22.00">XLS</text> | ||||
| <text text-anchor="middle" x="821.3" y="-862.81" font-family="Indie Flower" font-size="22.00">BIFF8</text> | ||||
| </g> | ||||
| <!-- csf->xls8 --> | ||||
| <g id="edge9" class="edge"> | ||||
| <title>csf->xls8</title> | ||||
| <path fill="none" stroke="blue" d="M454.03,-460.41C502.64,-521.47 582.67,-616.11 626.05,-663.39"/> | ||||
| <polygon fill="blue" stroke="blue" points="623.57,-665.87 632.94,-670.83 628.71,-661.12 623.57,-665.87"/> | ||||
| <path fill="none" stroke="blue" d="M581.29,-591.97C641.33,-669.31 733.48,-782.86 784.4,-841.8"/> | ||||
| <polygon fill="blue" stroke="blue" points="781.8,-844.14 791,-849.39 787.09,-839.55 781.8,-844.14"/> | ||||
| </g> | ||||
| <!-- xlml --> | ||||
| <g id="node7" class="node"> | ||||
| <title>xlml</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="579.16" cy="-742.38" rx="47.25" ry="26.74"/> | ||||
| <text text-anchor="middle" x="579.16" y="-746.18" font-family="Indie Flower" font-size="14.00">SSML</text> | ||||
| <text text-anchor="middle" x="579.16" y="-731.18" font-family="Indie Flower" font-size="14.00">(2003/4)</text> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="721.05" cy="-942.48" rx="62.87" ry="39.7"/> | ||||
| <text text-anchor="middle" x="721.05" y="-948.88" font-family="Indie Flower" font-size="22.00">SSML</text> | ||||
| <text text-anchor="middle" x="721.05" y="-924.88" font-family="Indie Flower" font-size="22.00">(2003/4)</text> | ||||
| </g> | ||||
| <!-- csf->xlml --> | ||||
| <g id="edge5" class="edge"> | ||||
| <title>csf->xlml</title> | ||||
| <path fill="none" stroke="blue" d="M439.11,-468.56C471.78,-540.11 527.17,-652.46 557.68,-708.4"/> | ||||
| <polygon fill="blue" stroke="blue" points="554.64,-710.14 562.54,-717.2 560.77,-706.76 554.64,-710.14"/> | ||||
| <path fill="none" stroke="blue" d="M559.66,-603.72C598.81,-693.6 660.19,-826.63 694.96,-896.23"/> | ||||
| <polygon fill="blue" stroke="blue" points="691.86,-897.85 699.48,-905.21 698.11,-894.7 691.86,-897.85"/> | ||||
| </g> | ||||
| <!-- xlsx --> | ||||
| <g id="node8" class="node"> | ||||
| <title>xlsx</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="491.7" cy="-772.57" rx="38.37" ry="26.74"/> | ||||
| <text text-anchor="middle" x="491.7" y="-776.37" font-family="Indie Flower" font-size="14.00">XLSX</text> | ||||
| <text text-anchor="middle" x="491.7" y="-761.37" font-family="Indie Flower" font-size="14.00">XLSM</text> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="612.75" cy="-977.1" rx="43.68" ry="39.7"/> | ||||
| <text text-anchor="middle" x="612.75" y="-983.5" font-family="Indie Flower" font-size="22.00">XLSX</text> | ||||
| <text text-anchor="middle" x="612.75" y="-959.5" font-family="Indie Flower" font-size="22.00">XLSM</text> | ||||
| </g> | ||||
| <!-- csf->xlsx --> | ||||
| <g id="edge1" class="edge"> | ||||
| <title>csf->xlsx</title> | ||||
| <path fill="none" stroke="blue" d="M422.54,-472.89C436.95,-551.07 463.73,-675.33 479.65,-736.35"/> | ||||
| <polygon fill="blue" stroke="blue" points="476.34,-737.52 482.3,-746.28 483.1,-735.72 476.34,-737.52"/> | ||||
| <path fill="none" stroke="blue" d="M536.68,-609.66C553.49,-707.36 581.86,-853.31 599,-928.49"/> | ||||
| <polygon fill="blue" stroke="blue" points="595.68,-929.66 601.34,-938.61 602.5,-928.08 595.68,-929.66"/> | ||||
| </g> | ||||
| <!-- xlsb --> | ||||
| <g id="node9" class="node"> | ||||
| <title>xlsb</title> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="403.76" cy="-780.68" rx="43.27" ry="26.74"/> | ||||
| <text text-anchor="middle" x="403.76" y="-784.48" font-family="Indie Flower" font-size="14.00">XLSB</text> | ||||
| <text text-anchor="middle" x="403.76" y="-769.48" font-family="Indie Flower" font-size="14.00">BIFF12</text> | ||||
| <ellipse fill="#00ff00" stroke="#00ff00" cx="507.8" cy="-985.3" rx="54.39" ry="39.7"/> | ||||
| <text text-anchor="middle" x="507.8" y="-991.7" font-family="Indie Flower" font-size="22.00">XLSB</text> | ||||
| <text text-anchor="middle" x="507.8" y="-967.7" font-family="Indie Flower" font-size="22.00">BIFF12</text> | ||||
| </g> | ||||
| <!-- csf->xlsb --> | ||||
| <g id="edge3" class="edge"> | ||||
| <title>csf->xlsb</title> | ||||
| <path fill="none" stroke="blue" d="M406.19,-473.13C402,-552.92 399.14,-680.89 400.48,-743.6"/> | ||||
| <polygon fill="blue" stroke="blue" points="396.99,-743.91 400.76,-753.81 403.99,-743.72 396.99,-743.91"/> | ||||
| <path fill="none" stroke="blue" d="M514.71,-610.13C509.53,-709.25 504.98,-858.13 505.12,-935.15"/> | ||||
| <polygon fill="blue" stroke="blue" points="501.62,-935.54 505.17,-945.53 508.62,-935.51 501.62,-935.54"/> | ||||
| </g> | ||||
| <!-- nums --> | ||||
| <g id="node10" class="node"> | ||||
| <title>nums</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="299.96" cy="-763.36" rx="55.49" ry="18"/> | ||||
| <text text-anchor="middle" x="299.96" y="-759.66" font-family="Indie Flower" font-size="14.00">NUMBERS</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="371.79" cy="-960.59" rx="77.15" ry="22.76"/> | ||||
| <text text-anchor="middle" x="371.79" y="-954.99" font-family="Indie Flower" font-size="22.00">NUMBERS</text> | ||||
| </g> | ||||
| <!-- csf->nums --> | ||||
| <g id="edge23" class="edge"> | ||||
| <title>csf->nums</title> | ||||
| <path fill="none" stroke="blue" d="M387.28,-468.45C359.87,-547.84 319.17,-678.77 304.78,-735.61"/> | ||||
| <polygon fill="blue" stroke="blue" points="301.37,-734.79 302.4,-745.33 308.18,-736.45 301.37,-734.79"/> | ||||
| <path fill="none" stroke="blue" d="M486.66,-603.37C450.44,-704.18 398.22,-860.67 378.95,-927.99"/> | ||||
| <polygon fill="blue" stroke="blue" points="375.58,-927.06 376.25,-937.64 382.32,-928.95 375.58,-927.06"/> | ||||
| </g> | ||||
| <!-- ods --> | ||||
| <g id="node11" class="node"> | ||||
| <title>ods</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="215.6" cy="-724.8" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="215.6" y="-721.1" font-family="Indie Flower" font-size="14.00">ODS</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="258.58" cy="-904.55" rx="42.35" ry="22.76"/> | ||||
| <text text-anchor="middle" x="258.58" y="-898.95" font-family="Indie Flower" font-size="22.00">ODS</text> | ||||
| </g> | ||||
| <!-- csf->ods --> | ||||
| <g id="edge13" class="edge"> | ||||
| <title>csf->ods</title> | ||||
| <path fill="none" stroke="blue" d="M372.25,-460.14C326.52,-530.09 255.55,-646.35 227.44,-698.33"/> | ||||
| <polygon fill="blue" stroke="blue" points="224.3,-696.79 222.7,-707.26 230.48,-700.07 224.3,-696.79"/> | ||||
| <path fill="none" stroke="blue" d="M463.73,-590.35C402.62,-677.38 311.79,-813.17 274.9,-873.69"/> | ||||
| <polygon fill="blue" stroke="blue" points="271.81,-872.02 269.65,-882.39 277.81,-875.63 271.81,-872.02"/> | ||||
| </g> | ||||
| <!-- fods --> | ||||
| <g id="node12" class="node"> | ||||
| <title>fods</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="157.15" cy="-680.43" rx="36" ry="18"/> | ||||
| <text text-anchor="middle" x="157.15" y="-676.73" font-family="Indie Flower" font-size="14.00">FODS</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="182.28" cy="-840.45" rx="50.41" ry="22.76"/> | ||||
| <text text-anchor="middle" x="182.28" y="-834.85" font-family="Indie Flower" font-size="22.00">FODS</text> | ||||
| </g> | ||||
| <!-- csf->fods --> | ||||
| <g id="edge15" class="edge"> | ||||
| <title>csf->fods</title> | ||||
| <path fill="none" stroke="blue" d="M362.1,-451.11C304.39,-510.17 213.75,-608.81 175.28,-655.09"/> | ||||
| <polygon fill="blue" stroke="blue" points="172.34,-653.15 168.72,-663.1 177.76,-657.58 172.34,-653.15"/> | ||||
| <path fill="none" stroke="blue" d="M448.58,-576.09C371.6,-647.51 256.35,-759.37 206.55,-811.72"/> | ||||
| <polygon fill="blue" stroke="blue" points="204,-809.32 199.69,-819 209.1,-814.12 204,-809.32"/> | ||||
| </g> | ||||
| <!-- html --> | ||||
| <g id="node14" class="node"> | ||||
| <title>html</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="103.98" cy="-619.37" rx="38.37" ry="26.74"/> | ||||
| <text text-anchor="middle" x="103.98" y="-623.17" font-family="Indie Flower" font-size="14.00">HTML</text> | ||||
| <text text-anchor="middle" x="103.98" y="-608.17" font-family="Indie Flower" font-size="14.00">Table</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="118.85" cy="-758.21" rx="46.84" ry="39.7"/> | ||||
| <text text-anchor="middle" x="118.85" y="-764.61" font-family="Indie Flower" font-size="22.00">HTML</text> | ||||
| <text text-anchor="middle" x="118.85" y="-740.61" font-family="Indie Flower" font-size="22.00">Table</text> | ||||
| </g> | ||||
| <!-- csf->html --> | ||||
| <g id="edge50" class="edge"> | ||||
| <g id="edge51" class="edge"> | ||||
| <title>csf->html</title> | ||||
| <path fill="none" stroke="#458b74" d="M353.15,-439.08C288.12,-481.86 186.98,-552.76 135.84,-591.74"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="133.57,-589.07 127.78,-597.94 137.84,-594.62 133.57,-589.07"/> | ||||
| <path fill="none" stroke="#458b74" d="M436.33,-558.2C352,-607.43 227.75,-683.58 162.5,-726.37"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="160.5,-723.5 154.08,-731.93 164.35,-729.34 160.5,-723.5"/> | ||||
| </g> | ||||
| <!-- csv --> | ||||
| <g id="node15" class="node"> | ||||
| <title>csv</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="67.87" cy="-554.93" rx="28.7" ry="18"/> | ||||
| <text text-anchor="middle" x="67.87" y="-551.23" font-family="Indie Flower" font-size="14.00">CSV</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="79.84" cy="-678.11" rx="35.21" ry="22.76"/> | ||||
| <text text-anchor="middle" x="79.84" y="-672.51" font-family="Indie Flower" font-size="22.00">CSV</text> | ||||
| </g> | ||||
| <!-- csf->csv --> | ||||
| <g id="edge44" class="edge"> | ||||
| <g id="edge45" class="edge"> | ||||
| <title>csf->csv</title> | ||||
| <path fill="none" stroke="#458b74" d="M347.41,-426.68C272.23,-457.2 152.63,-510.03 97.48,-537.51"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="95.61,-534.54 88.27,-542.18 98.77,-540.79 95.61,-534.54"/> | ||||
| <path fill="none" stroke="#458b74" d="M429.15,-541.04C331.87,-575.47 185.16,-631.09 117.03,-659.87"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="115.39,-656.77 107.57,-663.91 118.14,-663.2 115.39,-656.77"/> | ||||
| </g> | ||||
| <!-- txt --> | ||||
| <g id="node16" class="node"> | ||||
| <title>txt</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="43.84" cy="-479.16" rx="43.68" ry="26.74"/> | ||||
| <text text-anchor="middle" x="43.84" y="-482.96" font-family="Indie Flower" font-size="14.00">TXT</text> | ||||
| <text text-anchor="middle" x="43.84" y="-467.96" font-family="Indie Flower" font-size="14.00">UTF-16</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="55.15" cy="-583.75" rx="55.31" ry="39.7"/> | ||||
| <text text-anchor="middle" x="55.15" y="-590.15" font-family="Indie Flower" font-size="22.00">TXT</text> | ||||
| <text text-anchor="middle" x="55.15" y="-566.15" font-family="Indie Flower" font-size="22.00">UTF-16</text> | ||||
| </g> | ||||
| <!-- csf->txt --> | ||||
| <g id="edge46" class="edge"> | ||||
| <g id="edge47" class="edge"> | ||||
| <title>csf->txt</title> | ||||
| <path fill="none" stroke="#458b74" d="M344.05,-412.35C270.81,-425.26 157.16,-448.67 92.75,-464.28"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="91.72,-460.93 82.84,-466.72 93.39,-467.73 91.72,-460.93"/> | ||||
| <path fill="none" stroke="#458b74" d="M425.12,-521.09C332.47,-533.58 196.55,-554.79 117.84,-569.24"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="116.78,-565.88 107.59,-571.15 118.06,-572.76 116.78,-565.88"/> | ||||
| </g> | ||||
| <!-- dbf --> | ||||
| <g id="node17" class="node"> | ||||
| <title>dbf</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="36.23" cy="-400.04" rx="28.7" ry="18"/> | ||||
| <text text-anchor="middle" x="36.23" y="-396.34" font-family="Indie Flower" font-size="14.00">DBF</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="50.78" cy="-478.57" rx="43.27" ry="22.76"/> | ||||
| <text text-anchor="middle" x="50.78" y="-472.97" font-family="Indie Flower" font-size="22.00">DBF</text> | ||||
| </g> | ||||
| <!-- csf->dbf --> | ||||
| <g id="edge48" class="edge"> | ||||
| <g id="edge49" class="edge"> | ||||
| <title>csf->dbf</title> | ||||
| <path fill="none" stroke="#458b74" d="M343.77,-397.63C264.53,-394.72 137.86,-393.86 74.68,-396.12"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="74.22,-392.64 64.37,-396.55 74.51,-399.63 74.22,-392.64"/> | ||||
| <path fill="none" stroke="#458b74" d="M425.45,-499.11C327.93,-490.46 182.02,-480.65 104.19,-477.83"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="104.24,-474.33 94.12,-477.5 104,-481.33 104.24,-474.33"/> | ||||
| </g> | ||||
| <!-- dif --> | ||||
| <g id="node18" class="node"> | ||||
| <title>dif</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="42.05" cy="-337.58" rx="27" ry="18"/> | ||||
| <text text-anchor="middle" x="42.05" y="-333.88" font-family="Indie Flower" font-size="14.00">DIF</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="64.07" cy="-395.46" rx="33.88" ry="22.76"/> | ||||
| <text text-anchor="middle" x="64.07" y="-389.86" font-family="Indie Flower" font-size="22.00">DIF</text> | ||||
| </g> | ||||
| <!-- csf->dif --> | ||||
| <g id="edge32" class="edge"> | ||||
| <title>csf->dif</title> | ||||
| <path fill="none" stroke="#458b74" d="M345.74,-386.19C267.48,-370.06 141.4,-348.01 79.2,-339.91"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="79.42,-336.41 69.06,-338.65 78.55,-343.36 79.42,-336.41"/> | ||||
| <path fill="none" stroke="#458b74" d="M429.2,-481.95C330.69,-455.07 180.59,-417.66 107.33,-402.16"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="108.02,-398.73 97.52,-400.12 106.6,-405.58 108.02,-398.73"/> | ||||
| </g> | ||||
| <!-- slk --> | ||||
| <g id="node19" class="node"> | ||||
| <title>slk</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="59.69" cy="-272.68" rx="33.29" ry="18"/> | ||||
| <text text-anchor="middle" x="59.69" y="-268.98" font-family="Indie Flower" font-size="14.00">SYLK</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="90.7" cy="-318.6" rx="40.11" ry="22.76"/> | ||||
| <text text-anchor="middle" x="90.7" y="-313" font-family="Indie Flower" font-size="22.00">SYLK</text> | ||||
| </g> | ||||
| <!-- csf->slk --> | ||||
| <g id="edge30" class="edge"> | ||||
| <title>csf->slk</title> | ||||
| <path fill="none" stroke="#458b74" d="M349.92,-374.46C277.49,-345.38 161.16,-302.63 100.09,-282.93"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="101.01,-279.55 90.42,-279.87 98.89,-286.23 101.01,-279.55"/> | ||||
| <path fill="none" stroke="#458b74" d="M435.66,-466.25C344.49,-423.52 205.65,-362.13 135.13,-333.78"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="136.23,-330.45 125.64,-330 133.64,-336.95 136.23,-330.45"/> | ||||
| </g> | ||||
| <!-- prn --> | ||||
| <g id="node20" class="node"> | ||||
| <title>prn</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="89.74" cy="-210.01" rx="29.5" ry="18"/> | ||||
| <text text-anchor="middle" x="89.74" y="-206.31" font-family="Indie Flower" font-size="14.00">PRN</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="133.25" cy="-242.74" rx="39.7" ry="22.76"/> | ||||
| <text text-anchor="middle" x="133.25" y="-237.14" font-family="Indie Flower" font-size="22.00">PRN</text> | ||||
| </g> | ||||
| <!-- csf->prn --> | ||||
| <g id="edge42" class="edge"> | ||||
| <g id="edge43" class="edge"> | ||||
| <title>csf->prn</title> | ||||
| <path fill="none" stroke="#458b74" d="M356.36,-363.32C288.77,-320.34 178.35,-254.72 123.22,-225.16"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="124.7,-221.99 114.22,-220.41 121.43,-228.18 124.7,-221.99"/> | ||||
| <path fill="none" stroke="#458b74" d="M445.43,-450.94C362.4,-391.42 234.63,-304.03 171.38,-264.02"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="172.86,-260.81 162.53,-258.47 169.14,-266.74 172.86,-260.81"/> | ||||
| </g> | ||||
| <!-- rtf --> | ||||
| <g id="node21" class="node"> | ||||
| <title>rtf</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="127.35" cy="-157.84" rx="27.9" ry="18"/> | ||||
| <text text-anchor="middle" x="127.35" y="-154.14" font-family="Indie Flower" font-size="14.00">RTF</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="186.96" cy="-177.94" rx="37.45" ry="22.76"/> | ||||
| <text text-anchor="middle" x="186.96" y="-172.34" font-family="Indie Flower" font-size="22.00">RTF</text> | ||||
| </g> | ||||
| <!-- csf->rtf --> | ||||
| <g id="edge40" class="edge"> | ||||
| <g id="edge41" class="edge"> | ||||
| <title>csf->rtf</title> | ||||
| <path fill="none" stroke="#458b74" d="M360.21,-358.02C298.04,-304.57 197.75,-218.36 151.79,-178.85"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="153.98,-176.12 144.12,-172.25 149.42,-181.43 153.98,-176.12"/> | ||||
| <path fill="none" stroke="#458b74" d="M457.39,-438.07C384.75,-363.31 271.41,-251.77 217.44,-202.62"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="219.68,-199.94 209.92,-195.84 214.99,-205.13 219.68,-199.94"/> | ||||
| </g> | ||||
| <!-- wk1 --> | ||||
| <g id="node22" class="node"> | ||||
| <title>wk1</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="174.29" cy="-112" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="174.29" y="-108.3" font-family="Indie Flower" font-size="14.00">WK1</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="247.81" cy="-126.11" rx="35.21" ry="22.76"/> | ||||
| <text text-anchor="middle" x="247.81" y="-120.51" font-family="Indie Flower" font-size="22.00">WK1</text> | ||||
| </g> | ||||
| <!-- csf->wk1 --> | ||||
| <g id="edge34" class="edge"> | ||||
| <title>csf->wk1</title> | ||||
| <path fill="none" stroke="#458b74" d="M373.36,-346.44C323.28,-281.83 239.2,-179.96 198.15,-134.79"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="200.59,-132.27 191.24,-127.28 195.44,-137.01 200.59,-132.27"/> | ||||
| <path fill="none" stroke="#458b74" d="M470.68,-427.98C411.03,-341.2 316.74,-210.42 272.33,-153.8"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="274.86,-151.35 265.9,-145.69 269.37,-155.7 274.86,-151.35"/> | ||||
| </g> | ||||
| <!-- wk3 --> | ||||
| <g id="node24" class="node"> | ||||
| <title>wk3</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="230.73" cy="-73.72" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="230.73" y="-70.02" font-family="Indie Flower" font-size="14.00">WK3</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="316.52" cy="-85.24" rx="37.45" ry="22.76"/> | ||||
| <text text-anchor="middle" x="316.52" y="-79.64" font-family="Indie Flower" font-size="22.00">WK3</text> | ||||
| </g> | ||||
| <!-- csf->wk3 --> | ||||
| <g id="edge18" class="edge"> | ||||
| <title>csf->wk3</title> | ||||
| <path fill="none" stroke="blue" d="M384.33,-340.17C346.31,-266.87 281.03,-149.9 249.12,-98.87"/> | ||||
| <polygon fill="blue" stroke="blue" points="251.89,-96.69 243.57,-90.13 245.98,-100.45 251.89,-96.69"/> | ||||
| <path fill="none" stroke="blue" d="M485.49,-420.28C440.94,-324 369.25,-177.81 335.28,-115.28"/> | ||||
| <polygon fill="blue" stroke="blue" points="338.25,-113.41 330.36,-106.34 332.11,-116.78 338.25,-113.41"/> | ||||
| </g> | ||||
| <!-- eth --> | ||||
| <g id="node32" class="node"> | ||||
| <title>eth</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="291.3" cy="-46.85" rx="28.7" ry="18"/> | ||||
| <text text-anchor="middle" x="291.3" y="-43.15" font-family="Indie Flower" font-size="14.00">ETH</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="392.47" cy="-56.11" rx="36.54" ry="22.76"/> | ||||
| <text text-anchor="middle" x="392.47" y="-50.51" font-family="Indie Flower" font-size="22.00">ETH</text> | ||||
| </g> | ||||
| <!-- csf->eth --> | ||||
| <g id="edge51" class="edge"> | ||||
| <g id="edge52" class="edge"> | ||||
| <title>csf->eth</title> | ||||
| <path fill="none" stroke="#458b74" d="M395.89,-336.08C371.11,-256.68 326.85,-128.82 304.52,-73.62"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="307.67,-72.09 300.62,-64.19 301.21,-74.77 307.67,-72.09"/> | ||||
| <path fill="none" stroke="#458b74" d="M501.66,-415.11C474.1,-312.13 428.15,-154.8 405.49,-87.94"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="408.76,-86.69 402.19,-78.38 402.14,-88.97 408.76,-86.69"/> | ||||
| </g> | ||||
| <!-- xls2->csf --> | ||||
| <g id="edge24" class="edge"> | ||||
| <title>xls2->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M753.25,-399.45C693.11,-396.65 573.17,-396.18 493.07,-398.05"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="492.92,-394.55 483.01,-398.3 493.1,-401.55 492.92,-394.55"/> | ||||
| <path fill="none" stroke="#458b74" d="M947.31,-507.23C872.79,-504.62 731.21,-504.14 632.3,-505.8"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="632.21,-502.31 622.27,-505.98 632.33,-509.3 632.21,-502.31"/> | ||||
| </g> | ||||
| <!-- xls3->csf --> | ||||
| <g id="edge26" class="edge"> | ||||
| <title>xls3->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M747.79,-473.47C690.3,-457.8 571.89,-431.09 492.53,-415.44"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="493.05,-411.98 482.57,-413.5 491.71,-418.85 493.05,-411.98"/> | ||||
| <path fill="none" stroke="#458b74" d="M940.26,-602.16C869.05,-583.17 729.27,-550.8 631.33,-530.2"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="631.89,-526.74 621.39,-528.12 630.46,-533.59 631.89,-526.74"/> | ||||
| </g> | ||||
| <!-- xls4->csf --> | ||||
| <g id="edge28" class="edge"> | ||||
| <title>xls4->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M726.87,-545.2C675,-517.77 563.3,-465.18 488.2,-432.32"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="489.34,-429 478.77,-428.22 486.55,-435.42 489.34,-429"/> | ||||
| <path fill="none" stroke="#458b74" d="M912.45,-691.74C847.68,-657.9 716.49,-594.96 624.46,-553.11"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="625.68,-549.82 615.13,-548.88 622.79,-556.19 625.68,-549.82"/> | ||||
| </g> | ||||
| <!-- xls5->csf --> | ||||
| <g id="edge8" class="edge"> | ||||
| <title>xls5->csf</title> | ||||
| <path fill="none" stroke="blue" d="M690.61,-611.1C646.74,-573.63 547.39,-496.82 480.31,-447.87"/> | ||||
| <polygon fill="blue" stroke="blue" points="482.03,-444.8 471.88,-441.75 477.91,-450.46 482.03,-444.8"/> | ||||
| <path fill="none" stroke="blue" d="M863.35,-774.19C807.96,-726.96 693.45,-635.97 612.71,-574.48"/> | ||||
| <polygon fill="blue" stroke="blue" points="614.59,-571.51 604.52,-568.25 610.36,-577.09 614.59,-571.51"/> | ||||
| </g> | ||||
| <!-- xls8->csf --> | ||||
| <g id="edge10" class="edge"> | ||||
| <title>xls8->csf</title> | ||||
| <path fill="none" stroke="blue" d="M640.37,-667.64C606.25,-622.16 524.54,-524.1 469.01,-461.12"/> | ||||
| <polygon fill="blue" stroke="blue" points="471.62,-458.79 462.37,-453.62 466.38,-463.43 471.62,-458.79"/> | ||||
| <path fill="none" stroke="blue" d="M798.28,-845.47C755.53,-787.92 662.57,-671.8 596.63,-592.85"/> | ||||
| <polygon fill="blue" stroke="blue" points="599.04,-590.27 589.93,-584.85 593.67,-594.76 599.04,-590.27"/> | ||||
| </g> | ||||
| <!-- xlml->csf --> | ||||
| <g id="edge6" class="edge"> | ||||
| <title>xlml->csf</title> | ||||
| <path fill="none" stroke="blue" d="M570.33,-715.83C548.54,-663.98 492.39,-547.88 453.44,-472.8"/> | ||||
| <polygon fill="blue" stroke="blue" points="456.5,-471.11 448.78,-463.86 450.3,-474.34 456.5,-471.11"/> | ||||
| <path fill="none" stroke="blue" d="M707.67,-903.71C680.6,-837.59 618.76,-701.21 574.17,-608.06"/> | ||||
| <polygon fill="blue" stroke="blue" points="577.26,-606.4 569.77,-598.9 570.95,-609.43 577.26,-606.4"/> | ||||
| </g> | ||||
| <!-- xlsx->csf --> | ||||
| <g id="edge2" class="edge"> | ||||
| <title>xlsx->csf</title> | ||||
| <path fill="none" stroke="blue" d="M489.73,-745.57C481.38,-690.48 455.03,-563.36 435.43,-480.6"/> | ||||
| <polygon fill="blue" stroke="blue" points="438.8,-479.65 433.07,-470.74 431.99,-481.28 438.8,-479.65"/> | ||||
| <path fill="none" stroke="blue" d="M609.18,-937.47C598.77,-867.34 571.02,-719.19 549.78,-617.52"/> | ||||
| <polygon fill="blue" stroke="blue" points="553.16,-616.59 547.68,-607.52 546.31,-618.03 553.16,-616.59"/> | ||||
| </g> | ||||
| <!-- xlsb->csf --> | ||||
| <g id="edge4" class="edge"> | ||||
| <title>xlsb->csf</title> | ||||
| <path fill="none" stroke="blue" d="M408.15,-753.66C412.83,-697.93 416.76,-568.36 416.93,-483.47"/> | ||||
| <polygon fill="blue" stroke="blue" points="420.43,-483.35 416.94,-473.35 413.43,-483.35 420.43,-483.35"/> | ||||
| <path fill="none" stroke="blue" d="M513.06,-945.86C518.39,-875.15 524.03,-724.54 525.75,-620.69"/> | ||||
| <polygon fill="blue" stroke="blue" points="529.26,-620.53 525.91,-610.47 522.26,-620.42 529.26,-620.53"/> | ||||
| </g> | ||||
| <!-- nums->csf --> | ||||
| <g id="edge22" class="edge"> | ||||
| <title>nums->csf</title> | ||||
| <path fill="none" stroke="blue" d="M308.97,-745.49C327.76,-698.09 369.92,-567 394.67,-481.62"/> | ||||
| <polygon fill="blue" stroke="blue" points="398.05,-482.54 397.45,-471.96 391.32,-480.61 398.05,-482.54"/> | ||||
| <path fill="none" stroke="blue" d="M382.8,-938.12C406.12,-880.29 460.03,-723.53 494.07,-617.04"/> | ||||
| <polygon fill="blue" stroke="blue" points="497.49,-617.81 497.19,-607.22 490.82,-615.68 497.49,-617.81"/> | ||||
| </g> | ||||
| <!-- ods->csf --> | ||||
| <g id="edge12" class="edge"> | ||||
| <title>ods->csf</title> | ||||
| <path fill="none" stroke="blue" d="M229.64,-708.37C259.96,-665.94 331.65,-550.97 376.04,-475.01"/> | ||||
| <polygon fill="blue" stroke="blue" points="379.31,-476.35 381.31,-465.95 373.25,-472.83 379.31,-476.35"/> | ||||
| <path fill="none" stroke="blue" d="M276.57,-883.88C315.28,-832.69 407.35,-697.62 467.54,-605.05"/> | ||||
| <polygon fill="blue" stroke="blue" points="470.58,-606.81 473.09,-596.51 464.71,-603 470.58,-606.81"/> | ||||
| </g> | ||||
| <!-- fods->csf --> | ||||
| <g id="edge14" class="edge"> | ||||
| <title>fods->csf</title> | ||||
| <path fill="none" stroke="blue" d="M176.15,-665.09C215.32,-627.8 305.77,-531.13 363,-466.36"/> | ||||
| <polygon fill="blue" stroke="blue" points="365.83,-468.44 369.81,-458.62 360.57,-463.82 365.83,-468.44"/> | ||||
| <path fill="none" stroke="blue" d="M207.98,-820.71C258.64,-776.41 372.85,-667.38 449.09,-591.41"/> | ||||
| <polygon fill="blue" stroke="blue" points="451.75,-593.71 456.35,-584.17 446.8,-588.76 451.75,-593.71"/> | ||||
| </g> | ||||
| <!-- uos --> | ||||
| <g id="node13" class="node"> | ||||
| <title>uos</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="355.64" cy="-31" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="355.64" y="-27.3" font-family="Indie Flower" font-size="14.00">UOS</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="474.39" cy="-40.17" rx="39.7" ry="22.76"/> | ||||
| <text text-anchor="middle" x="474.39" y="-34.57" font-family="Indie Flower" font-size="22.00">UOS</text> | ||||
| </g> | ||||
| <!-- uos->csf --> | ||||
| <g id="edge16" class="edge"> | ||||
| <title>uos->csf</title> | ||||
| <path fill="none" stroke="blue" d="M358.42,-48.98C366,-97.91 387.33,-235.76 401.07,-324.5"/> | ||||
| <polygon fill="blue" stroke="blue" points="397.63,-325.18 402.62,-334.53 404.55,-324.11 397.63,-325.18"/> | ||||
| <path fill="none" stroke="blue" d="M476.76,-62.91C483.06,-123.25 500.52,-290.5 512.26,-402.87"/> | ||||
| <polygon fill="blue" stroke="blue" points="508.78,-403.3 513.3,-412.89 515.74,-402.58 508.78,-403.3"/> | ||||
| </g> | ||||
| <!-- html->csf --> | ||||
| <g id="edge49" class="edge"> | ||||
| <g id="edge50" class="edge"> | ||||
| <title>html->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M134.59,-603.02C184.75,-571.6 285.28,-502.14 350.91,-454.07"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="353.15,-456.77 359.14,-448.02 349.01,-451.13 353.15,-456.77"/> | ||||
| <path fill="none" stroke="#458b74" d="M159.46,-738.34C223.1,-702.82 347.81,-627.46 433.41,-573.32"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="435.51,-576.13 442.09,-567.82 431.77,-570.22 435.51,-576.13"/> | ||||
| </g> | ||||
| <!-- csv->csf --> | ||||
| <g id="edge43" class="edge"> | ||||
| <g id="edge44" class="edge"> | ||||
| <title>csv->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M94.2,-547.45C146.65,-528.05 265.66,-476.64 342.6,-440.79"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="344.2,-443.91 351.77,-436.5 341.23,-437.57 344.2,-443.91"/> | ||||
| <path fill="none" stroke="#458b74" d="M112.7,-669.72C177.5,-648.8 324.08,-594.55 423.47,-555.34"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="424.92,-558.53 432.93,-551.6 422.35,-552.02 424.92,-558.53"/> | ||||
| </g> | ||||
| <!-- txt->csf --> | ||||
| <g id="edge45" class="edge"> | ||||
| <g id="edge46" class="edge"> | ||||
| <title>txt->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M87.49,-474.85C148.63,-464.96 260.72,-442.44 336.13,-425.2"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="337.1,-428.57 346.05,-422.92 335.52,-421.75 337.1,-428.57"/> | ||||
| <path fill="none" stroke="#458b74" d="M110.5,-579.8C185.7,-570.71 321.69,-550.18 417.04,-533.85"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="417.75,-537.28 427.01,-532.13 416.56,-530.38 417.75,-537.28"/> | ||||
| </g> | ||||
| <!-- dbf->csf --> | ||||
| <g id="edge47" class="edge"> | ||||
| <g id="edge48" class="edge"> | ||||
| <title>dbf->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M64.23,-404.06C120.46,-407.82 248.93,-409.69 333.36,-408.54"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="333.48,-412.04 343.43,-408.39 333.37,-405.04 333.48,-412.04"/> | ||||
| <path fill="none" stroke="#458b74" d="M92.04,-485.49C163.38,-493.37 311.94,-504.33 414.68,-509.78"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="414.62,-513.28 424.79,-510.3 414.98,-506.29 414.62,-513.28"/> | ||||
| </g> | ||||
| <!-- dif->csf --> | ||||
| <g id="edge39" class="edge"> | ||||
| <title>dif->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M66.36,-345.56C119.67,-358.46 248.86,-382.15 333.67,-395.22"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="333.37,-398.72 343.78,-396.76 334.43,-391.8 333.37,-398.72"/> | ||||
| <path fill="none" stroke="#458b74" d="M93.7,-406.64C157.66,-426.19 311.34,-465.78 416.51,-490.49"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="416,-493.96 426.53,-492.83 417.59,-487.15 416,-493.96"/> | ||||
| </g> | ||||
| <!-- slk->csf --> | ||||
| <g id="edge31" class="edge"> | ||||
| <title>slk->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M83.29,-285.33C134.11,-307.67 255.79,-353.44 336.35,-381.18"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="335.37,-384.54 345.96,-384.47 337.64,-377.92 335.37,-384.54"/> | ||||
| <path fill="none" stroke="#458b74" d="M118.64,-335.01C178.71,-365.35 322.62,-430.3 421.65,-472.47"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="420.52,-475.79 431.09,-476.48 423.26,-469.35 420.52,-475.79"/> | ||||
| </g> | ||||
| <!-- prn->csf --> | ||||
| <g id="edge41" class="edge"> | ||||
| <g id="edge42" class="edge"> | ||||
| <title>prn->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M107.26,-224.48C150.82,-254.64 265.79,-324.31 341.77,-367.42"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="340.4,-370.67 350.83,-372.54 343.85,-364.58 340.4,-370.67"/> | ||||
| <path fill="none" stroke="#458b74" d="M154.84,-261.78C206.46,-301.46 339.28,-393.89 430.59,-454.55"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="428.75,-457.53 439.02,-460.13 432.62,-451.69 428.75,-457.53"/> | ||||
| </g> | ||||
| <!-- rtf->csf --> | ||||
| <g id="edge40" class="edge"> | ||||
| <title>rtf->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M202.98,-198.44C245.23,-245.28 361.45,-361.64 441.72,-438.59"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="439.73,-441.53 449.37,-445.91 444.57,-436.47 439.73,-441.53"/> | ||||
| </g> | ||||
| <!-- wk1->csf --> | ||||
| <g id="edge33" class="edge"> | ||||
| <title>wk1->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M184.31,-129.31C213.71,-170.98 300.37,-277.99 358.3,-345.42"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="355.68,-347.74 364.86,-353.03 360.98,-343.17 355.68,-347.74"/> | ||||
| <path fill="none" stroke="#458b74" d="M259.28,-147.61C292.3,-199.97 388.7,-336.2 455.51,-426.34"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="452.7,-428.43 461.47,-434.37 458.32,-424.26 452.7,-428.43"/> | ||||
| </g> | ||||
| <!-- wksl --> | ||||
| <g id="node23" class="node"> | ||||
| <title>wksl</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="428.51" cy="-26.87" rx="35.21" ry="26.74"/> | ||||
| <text text-anchor="middle" x="428.51" y="-30.67" font-family="Indie Flower" font-size="14.00">WKS</text> | ||||
| <text text-anchor="middle" x="428.51" y="-15.67" font-family="Indie Flower" font-size="14.00">Lotus</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="567" cy="-39.6" rx="45.92" ry="39.7"/> | ||||
| <text text-anchor="middle" x="567" y="-46" font-family="Indie Flower" font-size="22.00">WKS</text> | ||||
| <text text-anchor="middle" x="567" y="-22" font-family="Indie Flower" font-size="22.00">Lotus</text> | ||||
| </g> | ||||
| <!-- wksl->csf --> | ||||
| <g id="edge37" class="edge"> | ||||
| <title>wksl->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M427.42,-53.97C425.17,-109.67 419.97,-238.9 416.55,-323.7"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="413.05,-323.68 416.14,-333.82 420.04,-323.97 413.05,-323.68"/> | ||||
| <path fill="none" stroke="#458b74" d="M563.34,-79.43C556.84,-150.09 543.09,-299.61 533.6,-402.83"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="530.1,-402.7 532.67,-412.98 537.07,-403.34 530.1,-402.7"/> | ||||
| </g> | ||||
| <!-- wk3->csf --> | ||||
| <g id="edge17" class="edge"> | ||||
| <title>wk3->csf</title> | ||||
| <path fill="none" stroke="blue" d="M237.03,-91.6C257.98,-137.18 324.61,-259.29 369.76,-336.57"/> | ||||
| <polygon fill="blue" stroke="blue" points="366.8,-338.45 374.88,-345.3 372.83,-334.91 366.8,-338.45"/> | ||||
| <path fill="none" stroke="blue" d="M323.83,-107.46C347.18,-163.91 419.76,-315.36 470.73,-415.98"/> | ||||
| <polygon fill="blue" stroke="blue" points="467.64,-417.62 475.29,-424.95 473.88,-414.45 467.64,-417.62"/> | ||||
| </g> | ||||
| <!-- wk4 --> | ||||
| <g id="node25" class="node"> | ||||
| <title>wk4</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="500.81" cy="-36.85" rx="30.59" ry="18"/> | ||||
| <text text-anchor="middle" x="500.81" y="-33.15" font-family="Indie Flower" font-size="14.00">WK4</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="655.24" cy="-56.25" rx="36.54" ry="22.76"/> | ||||
| <text text-anchor="middle" x="655.24" y="-50.65" font-family="Indie Flower" font-size="22.00">WK4</text> | ||||
| </g> | ||||
| <!-- wk4->csf --> | ||||
| <g id="edge19" class="edge"> | ||||
| <title>wk4->csf</title> | ||||
| <path fill="none" stroke="blue" d="M496.53,-54.79C484.99,-103.2 452.67,-238.7 431.88,-325.89"/> | ||||
| <polygon fill="blue" stroke="blue" points="428.44,-325.21 429.53,-335.75 435.25,-326.83 428.44,-325.21"/> | ||||
| <path fill="none" stroke="blue" d="M648.71,-78.83C631.69,-137.71 585.11,-298.83 553.84,-406.99"/> | ||||
| <polygon fill="blue" stroke="blue" points="550.47,-406.05 551.06,-416.63 557.2,-408 550.47,-406.05"/> | ||||
| </g> | ||||
| <!-- 123 --> | ||||
| <g id="node26" class="node"> | ||||
| <title>123</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="562.2" cy="-57.19" rx="27" ry="18"/> | ||||
| <text text-anchor="middle" x="562.2" y="-53.49" font-family="Indie Flower" font-size="14.00">123</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="725.42" cy="-82.72" rx="31.23" ry="22.76"/> | ||||
| <text text-anchor="middle" x="725.42" y="-77.12" font-family="Indie Flower" font-size="22.00">123</text> | ||||
| </g> | ||||
| <!-- 123->csf --> | ||||
| <g id="edge20" class="edge"> | ||||
| <title>123->csf</title> | ||||
| <path fill="none" stroke="blue" d="M554.61,-74.85C534.7,-121.19 480.06,-248.36 444.86,-330.29"/> | ||||
| <polygon fill="blue" stroke="blue" points="441.61,-328.98 440.88,-339.55 448.04,-331.75 441.61,-328.98"/> | ||||
| <path fill="none" stroke="blue" d="M715.27,-104.28C689.09,-159.93 617.94,-311.12 570.09,-412.81"/> | ||||
| <polygon fill="blue" stroke="blue" points="566.91,-411.34 565.82,-421.88 573.25,-414.32 566.91,-411.34"/> | ||||
| </g> | ||||
| <!-- wksm --> | ||||
| <g id="node27" class="node"> | ||||
| <title>wksm</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="626.15" cy="-92.35" rx="38.78" ry="26.74"/> | ||||
| <text text-anchor="middle" x="626.15" y="-96.15" font-family="Indie Flower" font-size="14.00">WKS</text> | ||||
| <text text-anchor="middle" x="626.15" y="-81.15" font-family="Indie Flower" font-size="14.00">Works</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="801.54" cy="-127.65" rx="50.41" ry="39.7"/> | ||||
| <text text-anchor="middle" x="801.54" y="-134.05" font-family="Indie Flower" font-size="22.00">WKS</text> | ||||
| <text text-anchor="middle" x="801.54" y="-110.05" font-family="Indie Flower" font-size="22.00">Works</text> | ||||
| </g> | ||||
| <!-- wksm->csf --> | ||||
| <g id="edge38" class="edge"> | ||||
| <title>wksm->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M609.45,-116.78C577.31,-163.8 505.87,-268.3 458.67,-337.35"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="455.5,-335.78 452.75,-346.01 461.28,-339.73 455.5,-335.78"/> | ||||
| <path fill="none" stroke="#458b74" d="M776.63,-162.06C734.46,-220.3 647.76,-340.08 587.68,-423.07"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="584.8,-421.08 581.77,-431.23 590.47,-425.19 584.8,-421.08"/> | ||||
| </g> | ||||
| <!-- xlr --> | ||||
| <g id="node28" class="node"> | ||||
| <title>xlr</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="682.79" cy="-139.85" rx="27.9" ry="18"/> | ||||
| <text text-anchor="middle" x="682.79" y="-136.15" font-family="Indie Flower" font-size="14.00">XLR</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="870.41" cy="-188.5" rx="34.8" ry="22.76"/> | ||||
| <text text-anchor="middle" x="870.41" y="-182.9" font-family="Indie Flower" font-size="22.00">XLR</text> | ||||
| </g> | ||||
| <!-- xlr->csf --> | ||||
| <g id="edge35" class="edge"> | ||||
| <title>xlr->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M667.14,-155.17C629.68,-191.84 533.36,-286.15 470.74,-347.47"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="467.97,-345.28 463.27,-354.78 472.87,-350.28 467.97,-345.28"/> | ||||
| <path fill="none" stroke="#458b74" d="M850.52,-207.03C803.74,-250.61 684.62,-361.59 603.85,-436.83"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="601.08,-434.62 596.15,-444 605.86,-439.74 601.08,-434.62"/> | ||||
| </g> | ||||
| <!-- wq1 --> | ||||
| <g id="node29" class="node"> | ||||
| <title>wq1</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="725.17" cy="-191.62" rx="31.7" ry="18"/> | ||||
| <text text-anchor="middle" x="725.17" y="-187.92" font-family="Indie Flower" font-size="14.00">WQ1</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="919.38" cy="-250.79" rx="37.45" ry="22.76"/> | ||||
| <text text-anchor="middle" x="919.38" y="-245.19" font-family="Indie Flower" font-size="22.00">WQ1</text> | ||||
| </g> | ||||
| <!-- wq1->csf --> | ||||
| <g id="edge36" class="edge"> | ||||
| <title>wq1->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M704.71,-205.53C659.79,-236.08 550.87,-310.15 479.67,-358.56"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="477.48,-355.82 471.18,-364.34 481.42,-361.61 477.48,-355.82"/> | ||||
| <path fill="none" stroke="#458b74" d="M894.02,-267.5C838.76,-303.91 705.19,-391.93 614.49,-451.7"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="612.55,-448.78 606.13,-457.21 616.4,-454.63 612.55,-448.78"/> | ||||
| </g> | ||||
| <!-- wq2 --> | ||||
| <g id="node30" class="node"> | ||||
| <title>wq2</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="760.41" cy="-256.21" rx="34.8" ry="26.74"/> | ||||
| <text text-anchor="middle" x="760.41" y="-260.01" font-family="Indie Flower" font-size="14.00">WQ2</text> | ||||
| <text text-anchor="middle" x="760.41" y="-245.01" font-family="Indie Flower" font-size="14.00">WB*</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="959.82" cy="-326.2" rx="41.02" ry="39.7"/> | ||||
| <text text-anchor="middle" x="959.82" y="-332.6" font-family="Indie Flower" font-size="22.00">WQ2</text> | ||||
| <text text-anchor="middle" x="959.82" y="-308.6" font-family="Indie Flower" font-size="22.00">WB*</text> | ||||
| </g> | ||||
| <!-- wq2->csf --> | ||||
| <g id="edge11" class="edge"> | ||||
| <title>wq2->csf</title> | ||||
| <path fill="none" stroke="blue" d="M729.92,-269.16C676.06,-292.05 562.68,-340.22 487.26,-372.27"/> | ||||
| <polygon fill="blue" stroke="blue" points="485.63,-369.16 477.8,-376.29 488.37,-375.6 485.63,-369.16"/> | ||||
| <path fill="none" stroke="blue" d="M922.26,-342.17C856.65,-370.05 719.17,-428.48 624.14,-468.86"/> | ||||
| <polygon fill="blue" stroke="blue" points="622.63,-465.7 614.79,-472.83 625.37,-472.14 622.63,-465.7"/> | ||||
| </g> | ||||
| <!-- qpw --> | ||||
| <g id="node31" class="node"> | ||||
| <title>qpw</title> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="782.58" cy="-327.05" rx="32.49" ry="18"/> | ||||
| <text text-anchor="middle" x="782.58" y="-323.35" font-family="Indie Flower" font-size="14.00">QPW</text> | ||||
| <ellipse fill="cyan" stroke="cyan" cx="987.11" cy="-412.49" rx="42.35" ry="22.76"/> | ||||
| <text text-anchor="middle" x="987.11" y="-406.89" font-family="Indie Flower" font-size="22.00">QPW</text> | ||||
| </g> | ||||
| <!-- qpw->csf --> | ||||
| <g id="edge21" class="edge"> | ||||
| <title>qpw->csf</title> | ||||
| <path fill="none" stroke="blue" d="M752.05,-333.38C695.54,-345.11 573.04,-370.53 491.9,-387.38"/> | ||||
| <polygon fill="blue" stroke="blue" points="490.8,-384.03 481.72,-389.49 492.22,-390.88 490.8,-384.03"/> | ||||
| <path fill="none" stroke="blue" d="M947.59,-420.94C877.99,-435.82 731.36,-467.17 630.19,-488.8"/> | ||||
| <polygon fill="blue" stroke="blue" points="629.29,-485.41 620.24,-490.93 630.75,-492.26 629.29,-485.41"/> | ||||
| </g> | ||||
| <!-- eth->csf --> | ||||
| <g id="edge52" class="edge"> | ||||
| <g id="edge53" class="edge"> | ||||
| <title>eth->csf</title> | ||||
| <path fill="none" stroke="#458b74" d="M294.25,-65.07C306.72,-113.21 351.17,-245.78 382.2,-330.05"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="378.97,-331.41 385.72,-339.57 385.53,-328.98 378.97,-331.41"/> | ||||
| <path fill="none" stroke="#458b74" d="M395.8,-78.94C409.08,-138.35 454.86,-300.58 487.94,-408.62"/> | ||||
| <polygon fill="#458b74" stroke="#458b74" points="484.62,-409.72 490.9,-418.25 491.31,-407.67 484.62,-409.72"/> | ||||
| </g> | ||||
| </g> | ||||
| </svg> | ||||
|  | ||||
| Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB | 
| Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.1 MiB |