├── .gitignore ├── LICENSE ├── README.md ├── cli.js ├── fonts ├── Roboto-Italic.ttf ├── Roboto-Medium.ttf ├── Roboto-MediumItalic.ttf └── Roboto-Regular.ttf ├── index.js ├── package.json ├── pdf-report-data-format.md ├── playground ├── configs │ ├── 1.pdf │ ├── anychart_cef093ee-4b81-4ef2-b1bc-b4a6e8db515a.svg │ ├── chart1.js │ ├── chart2.json │ ├── js.js │ ├── json.json │ ├── logo.txt │ ├── report.js │ ├── svg.svg │ ├── textByPath.svg │ └── xml.xml ├── css │ ├── bootstrap-theme.min.css │ ├── bootstrap.min.css │ └── index.css ├── img │ ├── 500.img │ └── any_logo.img ├── js │ ├── ace.js │ ├── bootstrap.min.js │ ├── html5shiv.min.js │ ├── index.js │ ├── jquery-3.1.1.min.js │ ├── respond.min.js │ ├── tv4.min.js │ └── xmllint.js └── template.html └── test ├── test.js └── tests ├── data-file.js ├── pdf-report.js ├── raster-image.js ├── status.js └── vector-image.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.swp 3 | .idea 4 | *.pid 5 | out/* 6 | *.swo 7 | *.pyc 8 | node_modules 9 | shared 10 | *.png 11 | images/ 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /cli.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyChart/Node.js-Report-Server/109fc24d62a3ba6dd0dd2771bb69cea98dd9e79c/cli.js -------------------------------------------------------------------------------- /fonts/Roboto-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyChart/Node.js-Report-Server/109fc24d62a3ba6dd0dd2771bb69cea98dd9e79c/fonts/Roboto-Italic.ttf -------------------------------------------------------------------------------- /fonts/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyChart/Node.js-Report-Server/109fc24d62a3ba6dd0dd2771bb69cea98dd9e79c/fonts/Roboto-Medium.ttf -------------------------------------------------------------------------------- /fonts/Roboto-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyChart/Node.js-Report-Server/109fc24d62a3ba6dd0dd2771bb69cea98dd9e79c/fonts/Roboto-MediumItalic.ttf -------------------------------------------------------------------------------- /fonts/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyChart/Node.js-Report-Server/109fc24d62a3ba6dd0dd2771bb69cea98dd9e79c/fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var express = require('express'); 4 | var bodyParser = require('body-parser'); 5 | var program = require('commander'); 6 | var uuidv4 = require('uuid/v4'); 7 | var fs = require('fs'); 8 | var vm = require('vm2'); 9 | var csv = require('csv'); 10 | var xlsx = require('xlsx'); 11 | var path = require('path'); 12 | var winston = require('winston'); 13 | var winstonDRF = require('winston-daily-rotate-file'); 14 | 15 | program 16 | .version('1.0.0') 17 | .option('-p, --port [value]', 'TCP port of server ', 3000) 18 | .option('-o, --output-dir [value]', 'Output directory', 'shared') 19 | .option('-d, --disable-scripts-executing [value]', 'Whether script execution disabled', false) 20 | .option('--log-level [value]', 'Level of logging. Possible values: error, warn, info, verbose, debug, silly', 'info') 21 | .option('--log-file [value]', 'Path to log file. File will created and will rotate by daily.', null) 22 | .option('--disable-playground [value]', 'Disable playground app.', false); 23 | 24 | program.parse(process.argv); 25 | 26 | var blankImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='; 27 | var allowableImageParams = ['aspect-ratio', 'height', 'width', 'background', 'border', 'blur', 'contrast', 'crop', 'frame', 'gamma', 'monochrome', 'negative', 'noise', 'quality']; 28 | 29 | //region --- Configure logs 30 | function tsFormat() {return (new Date()).toLocaleTimeString()} 31 | var logTransports = []; 32 | var logLevel = program.logLevel; 33 | var loggingToFile = !!program.logFile; 34 | if (program.logFile) { 35 | if (!path.isAbsolute(program.logFile)) { 36 | program.logFile = path.join(__dirname, program.logFile); 37 | } 38 | 39 | var logDirName = path.dirname(program.logFile); 40 | var logFileName = path.basename(program.logFile); 41 | fs.access(logDirName, fs.constants.F_OK | fs.constants.R_OK | fs.constants.W_OK, function(err) { 42 | if (err) { 43 | if (err.code === 'ENOENT') { 44 | fs.mkdirSync(logDirName); 45 | } else { 46 | loggingToFile = false; 47 | } 48 | } 49 | }); 50 | 51 | if (loggingToFile) { 52 | logTransports.push(new (winstonDRF)({ 53 | timestamp: tsFormat, 54 | datePattern: 'yyyy-MM-dd', 55 | prepend: true, 56 | filename: path.join(logDirName, '-' + logFileName), 57 | level: logLevel 58 | })) 59 | } 60 | } 61 | if (!loggingToFile) { 62 | logTransports.push(new (winston.transports.Console)({ 63 | timestamp: tsFormat, 64 | level: logLevel, 65 | colorize: true 66 | })); 67 | } 68 | var logger = new (winston.Logger)({ 69 | transports: logTransports 70 | }); 71 | logger.cli(); 72 | winston.addColors({error: 'red', warn: 'yellow', info: 'blue', verbose: 'grey', debug: 'black', silly: 'white'}); 73 | logger.verbose('log level:', logLevel); 74 | 75 | 76 | //endregion 77 | //region --- AnyChart module configure 78 | 79 | var anychart_nodejs = require('anychart-nodejs'); 80 | // var anychart_nodejs = require('../AnyChart-NodeJS'); 81 | 82 | //endregion 83 | //region --- Pdfmake configure 84 | var pdfMake = require('pdfmake'); 85 | var fontDescriptors = { 86 | Roboto: { 87 | normal: path.join(__dirname, 'fonts', 'Roboto-Regular.ttf'), 88 | bold: path.join(__dirname, 'fonts', 'Roboto-Medium.ttf'), 89 | italics: path.join(__dirname, 'fonts', 'Roboto-Italic.ttf'), 90 | bolditalics: path.join(__dirname, 'fonts', 'Roboto-Italic.ttf') 91 | } 92 | }; 93 | var printer = new pdfMake(fontDescriptors); 94 | 95 | 96 | //endregion 97 | //region --- Express server configure 98 | var app = express(); 99 | app.use(bodyParser.json()); 100 | app.use(bodyParser.urlencoded({parameterLimit: 100000, limit: '50mb', extended: true})); 101 | 102 | 103 | //endregion 104 | 105 | function partial(fn, var_args) { 106 | var args = Array.prototype.slice.call(arguments, 1); 107 | return function() { 108 | var newArgs = args.slice(); 109 | newArgs.push.apply(newArgs, arguments); 110 | return fn.apply(this, newArgs); 111 | }; 112 | } 113 | 114 | function applyImageParams(params, chartSettings) { 115 | for (var i = 0, len = allowableImageParams.length; i < len; i++) { 116 | var paramName = allowableImageParams[i]; 117 | var value = chartSettings[paramName]; 118 | if (value) 119 | params[paramName] = value 120 | } 121 | } 122 | 123 | function recursiveTraverse(obj, func) { 124 | if (Object.prototype.toString.call(obj) === '[object Array]') { 125 | for (var i = 0; i < obj.length; i++) { 126 | if (i in obj) 127 | recursiveTraverse(obj[i], func); 128 | } 129 | } else if (typeof obj === 'object') { 130 | for (var key in obj) { 131 | if (obj.hasOwnProperty(key)) { 132 | if (key === 'chart') { 133 | func(obj) 134 | } else { 135 | recursiveTraverse(obj[key], func) 136 | } 137 | } 138 | } 139 | } 140 | } 141 | 142 | function convertCharts(obj, callback) { 143 | var charts = []; 144 | 145 | recursiveTraverse(obj, function(config) { 146 | charts.push(config) 147 | }); 148 | var chartsToConvert = charts.length; 149 | 150 | var handler = function(config, index) { 151 | var key = 'chart'; 152 | var chartConfig = config[key]; 153 | var data = chartConfig.data; 154 | var dataType = chartConfig.dataType; 155 | var containerId = chartConfig.containerId || 'container'; 156 | 157 | if (dataType === 'javascript' && program.disableScriptsExecuting) { 158 | logger.warn('Script executing disabled.'); 159 | data = null; 160 | } 161 | 162 | if (data) { 163 | logger.info('----> PDF Report. Chart ' + index + ' exporting.'); 164 | var imgConvertCallback = partial(function imgConvertCallback(dataType, chartNum, userData, err, data) { 165 | logger.info('<---- PDF Report. Chart ' + chartNum + ' exporting.'); 166 | if (data) { 167 | config.image = 'data:image/png;base64,' + data.toString('base64'); 168 | } else { 169 | config.image = blankImage; 170 | logger.error('PDF Report. Convert %s to %s. Data: %s. Container id: %s. Chart was replaced with blank Image.', 171 | dataType.toUpperCase(), 'PDF', userData, containerId, err); 172 | } 173 | 174 | delete config[key]; 175 | chartsToConvert--; 176 | if (chartsToConvert === 0) { 177 | callback(obj) 178 | } 179 | }, dataType, index, data); 180 | 181 | var params = { 182 | outputType: 'png', 183 | dataType: dataType, 184 | // document: iframeDoc, 185 | containerId: containerId 186 | }; 187 | 188 | applyImageParams(params, chartConfig); 189 | anychart_nodejs.exportTo(data, params, imgConvertCallback); 190 | } else { 191 | config.image = blankImage; 192 | delete config[key]; 193 | logger.error('Chart data not found. Chart was replaced with blank Image. Convert %s to %s. Data: %s. Container id: %s.', 194 | dataType.toUpperCase(), 'PDF', data, containerId, err); 195 | } 196 | }; 197 | 198 | for (var i = 0, len = charts.length; i < len; i ++) { 199 | handler(charts[i], i); 200 | } 201 | 202 | if (chartsToConvert === 0) { 203 | callback(obj) 204 | } 205 | } 206 | 207 | function getContentType(type) { 208 | var contentType; 209 | switch (type) { 210 | case 'png': 211 | contentType = 'image/png'; 212 | break; 213 | case 'jpg': 214 | contentType = 'image/jpg'; 215 | break; 216 | case 'tiff': 217 | contentType = 'image/tiff'; 218 | break; 219 | case 'svg': 220 | contentType = 'image/svf+xml'; 221 | break; 222 | case 'pdf': 223 | contentType = 'application/pdf'; 224 | break; 225 | case 'ps': 226 | contentType = 'application/postscript'; 227 | break; 228 | case 'xlsx': 229 | contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; 230 | break; 231 | case 'csv': 232 | contentType = 'text/csv'; 233 | break; 234 | case 'json': 235 | contentType = 'application/json'; 236 | break; 237 | default: 238 | contentType = 'text/plain' 239 | } 240 | return contentType; 241 | } 242 | 243 | function sendResult(req, res, data, fileType) { 244 | var autoFileName = 'anychart_' + uuidv4() + '.' + fileType; 245 | var responseType = (req.body.response_type || 'file').toLowerCase(); 246 | var fileName = responseType === 'file' ? req.body.file_name || autoFileName : autoFileName; 247 | 248 | if (responseType === 'file') { 249 | res.writeHead(200, { 250 | 'Content-Type': getContentType(fileType), 251 | 'Content-Length': data.length, 252 | 'Content-Disposition': 'attachment; filename=' + fileName 253 | }); 254 | 255 | res.end(data); 256 | } else if (responseType === 'base64') { 257 | var base64Data = data.toString('base64'); 258 | var result = {data: base64Data}; 259 | 260 | res.set('Content-Type', getContentType('json')); 261 | res.send(JSON.stringify(result)); 262 | } else if (responseType === 'url') { 263 | var path = program.outputDir + '/' + autoFileName; 264 | fs.access(program.outputDir, fs.constants.F_OK | fs.constants.R_OK | fs.constants.W_OK, function(err) { 265 | if (err) { 266 | if (err.code === 'ENOENT') { 267 | fs.mkdirSync(program.outputDir); 268 | logger.info('Directory ' + program.outputDir + ' was created.'); 269 | } else { 270 | logger.error(err); 271 | return; 272 | } 273 | } 274 | 275 | fs.writeFile(path, data, function(err) { 276 | if (err) { 277 | logger.error(err); 278 | } else { 279 | logger.info('Written to file ' + path); 280 | 281 | res.set('Content-Type', getContentType('json')); 282 | res.send(JSON.stringify({'url': path})); 283 | } 284 | }); 285 | }); 286 | } 287 | } 288 | 289 | function generateOutput(req, res) { 290 | var dataType = req.body.data_type && req.body.data_type.toLowerCase(); 291 | var fileType = (req.body.file_type || 'png').toLowerCase(); 292 | var data = req.body.data; 293 | var containerId = req.body.containerId || 'container'; 294 | var resources = req.body.resources || []; 295 | 296 | if (dataType === 'javascript' && program.disableScriptsExecuting) { 297 | logger.warn('Script executing disabled.'); 298 | data = null; 299 | } 300 | 301 | if (data) { 302 | logger.info('----> Input. Convert %s to %s. Image.', dataType.toUpperCase(), fileType.toUpperCase()); 303 | var imgConvertCallback = partial(function imgConvertCallback(fileType, dataType, userData, err, data) { 304 | if (err) 305 | logger.error('Convert %s to %s. Data: %s. Container id: %s.', 306 | dataType.toUpperCase(), fileType.toUpperCase(), userData, containerId, err); 307 | else 308 | logger.info('<---- Output. Convert %s to %s. Image.', dataType.toUpperCase(), fileType.toUpperCase()); 309 | 310 | if (!data || err) { 311 | res.status(500).send({error: err ? err.message : 'Image generation error'}); 312 | } else { 313 | sendResult(req, res, data, fileType); 314 | } 315 | }, fileType, dataType, data); 316 | 317 | var params = { 318 | outputType: fileType, 319 | dataType: dataType, 320 | // document: iframeDoc, 321 | containerId: containerId, 322 | resources: resources 323 | }; 324 | 325 | applyImageParams(params, req.body); 326 | 327 | anychart_nodejs.exportTo(data, params, imgConvertCallback); 328 | } else { 329 | logger.error('Chart data not found. Convert %s to %s. Data: %s. Container id: %s.', 330 | dataType.toUpperCase(), fileType.toUpperCase(), data, containerId, err); 331 | res.status(500).send({error: 'Chart data not found'}); 332 | } 333 | } 334 | 335 | app.post('/pdf-report', function (req, res) { 336 | if (!program.disableScriptsExecuting) { 337 | try { 338 | var script = new vm.VM(); 339 | var data = script.run(req.body.data); 340 | script = null; 341 | } catch (e) { 342 | logger.error('PDF config evaluating failed. DataL %s', req.body.data, e); 343 | res.status(500).send({error: e.message}); 344 | return; 345 | } 346 | } else { 347 | logger.warn('Script executing disabled.'); 348 | res.status(500).send({error: 'Script executing disabled.'}); 349 | return; 350 | } 351 | 352 | convertCharts(data, function(dd) { 353 | try { 354 | var pdfDoc = printer.createPdfKitDocument(dd); 355 | var chunks = []; 356 | 357 | pdfDoc.on('data', function(chunk) { 358 | chunks.push(chunk); 359 | }); 360 | pdfDoc.on('end', function() { 361 | sendResult(req, res, Buffer.concat(chunks), 'pdf'); 362 | pdfDoc = null; 363 | }); 364 | pdfDoc.on('error', function(e) { 365 | logger.error('PDF generation error. Data: %s', req.body.data, e) 366 | }); 367 | pdfDoc.end(); 368 | } catch (e) { 369 | logger.error('PDF generation error. Data: %s', req.body.data, e); 370 | } 371 | }); 372 | }); 373 | 374 | app.post('/vector-image', function (req, res) { 375 | try { 376 | if (!req.body.file_type) 377 | req.body.file_type = 'pdf'; 378 | 379 | generateOutput(req, res); 380 | } catch (e) { 381 | logger.error('Vector image generation failed. Request body: %s.', req.body, e); 382 | } 383 | }); 384 | 385 | app.post('/raster-image', function (req, res) { 386 | try { 387 | generateOutput(req, res); 388 | } catch (e) { 389 | logger.error('Raster image generation failed. Request body: %s.', req.body, e); 390 | } 391 | }); 392 | 393 | app.post('/data-file', function (req, res) { 394 | try { 395 | var data = req.body.data; 396 | var fileType = (req.body.file_type || 'xlsx').toLowerCase(); 397 | 398 | if (fileType === 'xlsx') { 399 | csv.parse(data, function(err, data) { 400 | var ws = xlsx.utils.aoa_to_sheet(data); 401 | var wb = xlsx.utils.book_new(); 402 | wb.SheetNames.push('Sheet 1'); 403 | wb.Sheets['Sheet 1'] = ws; 404 | data = xlsx.write(wb, {'type': 'buffer'}); 405 | sendResult(req, res, data, fileType) 406 | }) 407 | } else if (fileType === 'csv') { 408 | sendResult(req, res, data, fileType) 409 | } 410 | } catch (e) { 411 | logger.error('Data file generation failed. Request body: %s.', req.body, e); 412 | } 413 | }); 414 | 415 | if (!program.disablePlayground) { 416 | app.use(express.static(path.join(__dirname, 'playground'))); 417 | app.get('/', function(req, res) { 418 | res.sendFile(path.join(__dirname + '/playground/template.html')); 419 | }); 420 | } 421 | 422 | app.get('/status', function (req, res) { 423 | res.send('ok'); 424 | }); 425 | 426 | app.listen(program.port, function () { 427 | logger.info('Export server listening on port ' + program.port + '!') 428 | }); 429 | 430 | if (global.gc) { 431 | setInterval(function() { 432 | global.gc() 433 | }, 3000); 434 | } 435 | 436 | module.exports = app; 437 | 438 | 439 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anychart-report-server", 3 | "title": "AnyChart Node.js Report Server", 4 | "description": "AnyChart Node.js Report Server is a lightweight web server that provides API for generating vector graphics (PDF, SVG, or PS), bitmap images (PNG, JPG, or TIFF), PDF reports, and data in CSV and XLSX (Excel). It uses the JavaScript code as well as JSON and XML configurations as input data. The server is very easy to install and customize, you can run it on any major platform: Linux, Windows, and macOS. It is ideal for creating report systems that send charts via email or social network sharing tools.", 5 | "main": "./index.js", 6 | "version": "1.0.14", 7 | "homepage": "https://www.anychart.com", 8 | "license": "Apache-2.0", 9 | "keywords": [ 10 | "PDF Report", 11 | "report system", 12 | "report server", 13 | "server-side rendering", 14 | "server charts", 15 | "email charts", 16 | "social network sharing tools", 17 | "chart export", 18 | "server-side chart generation" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/AnyChart/Node.js-Report-Server" 23 | }, 24 | "bugs": { 25 | "url": "https://github.com/AnyChart/Node.js-Report-Server/issues" 26 | }, 27 | "author": "AnyChart (http://anychart.com)", 28 | "scripts": { 29 | "postinstall": "node cli.js", 30 | "start": "node index.js", 31 | "test": "mocha" 32 | }, 33 | "bin": "./index.js", 34 | "dependencies": { 35 | "anychart-nodejs": "^1.3.1", 36 | "body-parser": "^1.18.2", 37 | "commander": "^2.12.2", 38 | "csv": "^1.2.1", 39 | "express": "^4.16.2", 40 | "fontfaceobserver": "^2.0.13", 41 | "pdfmake": "^0.1.34", 42 | "request": "^2.83.0", 43 | "uuid": "^3.1.0", 44 | "vm2": "^3.5.2", 45 | "winston": "^2.4.0", 46 | "winston-daily-rotate-file": "^1.7.2", 47 | "xlsx": "^0.10.9", 48 | "xmldom": "^0.1.27" 49 | }, 50 | "devDependencies": { 51 | "chai": "^3.5.0", 52 | "chai-http": "^3.0.0", 53 | "mocha": "^3.5.3" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /pdf-report-data-format.md: -------------------------------------------------------------------------------- 1 | #### Data 2 | Формат данных для pdf report - это self executing функция, которая возвращает объект формата [pdfmake](http://pdfmake.org/index.html#/gettingstarted). Ко всем возможностям *pdfmake* добавляется возможность вставлять в PDF документ anychart чарты. Чарт добавляется как поле *chart* которому соответсвует объект определенного формата. Объект, описывающий чарт имеет следующий формат: 3 | 4 | | Name | Possible values | Description | 5 | | ------------- | ------------- | ------------- | 6 | | data | javascript, JSON, XML, SVG string | Строка, определяющая непосредственно сам чарт. | 7 | | dataType | javascript, JSON, XML, SVG | Опеределяет тип данных в поле data | 8 | | containerId | any string | Определяет id контейнера который задан чарту в поле data. Этот id должен соответствовать контейнеру, в который будет отрисован чарт. | 9 | 10 | К чарту могут быть применены все свойства, которые можно применить к *image* в pdmake, смотрите пример ниже. 11 | 12 | #### Example 13 | Пример данных для pdf report 14 | 15 | ``` 16 | (function() { 17 | return { 18 | content: [ 19 | { 20 | "chart": { 21 | "data": "chart = anychart.line([1,2,3]); chart.container('custom_container_id').draw();", 22 | "dataType": "javascript", 23 | "containerId": "custom_container_id" 24 | }, 25 | "fit": [500, 500] 26 | } 27 | ] 28 | } 29 | })(); 30 | ``` 31 | Чтобы данные такого формата отправить на сервер, их необходимо превратить в строку. Самое простое - заинлайнить их и преобразовать в строку. 32 | 33 | ``` 34 | var data = "(function(){return {content:[{chart:{data: \"chart = anychart.line([1,2,3]); chart.container('custom_container_id').draw();\", dataType: 'javascript', containerId: 'custom_container_id'},fit: [500, 500]}]}})();" 35 | ``` 36 | Так же можно подгружать их из файла как текст, брать из html формы или каким-либо другим способом превращать в строку. 37 | 38 | Пример ajax запроса на сервер с помощью [jQuery.ajax()](http://api.jquery.com/jquery.ajax/) 39 | 40 | ``` 41 | $.ajax({ 42 | method: 'POST', 43 | dataType: 'json', 44 | url: '/pdf-report', 45 | data: { 46 | response_type: 'base64', 47 | data: data //from above snippet 48 | } 49 | }).done(function(resData) { 50 | //to do something 51 | }).fail(function(err) { 52 | //to do something 53 | }); 54 | ``` -------------------------------------------------------------------------------- /playground/configs/1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyChart/Node.js-Report-Server/109fc24d62a3ba6dd0dd2771bb69cea98dd9e79c/playground/configs/1.pdf -------------------------------------------------------------------------------- /playground/configs/chart2.json: -------------------------------------------------------------------------------- 1 | { 2 | "chart": { 3 | "bounds": { 4 | "top": 0, 5 | "left": 0, 6 | "width": 450, 7 | "height": 300 8 | }, 9 | "enabled": true, 10 | "title": { 11 | "enabled": true, 12 | "text": "Earnings Estimate" 13 | }, 14 | "tooltip": { 15 | "format": "${%Value}{groupsSeparator: }", 16 | "enabled": true 17 | }, 18 | "credits": { 19 | "text": "AnyChart", 20 | "url": "https://www.anychart.com/?utm_source=registered", 21 | "alt": "AnyChart - JavaScript Charts designed to be embedded and integrated", 22 | "imgAlt": "AnyChart - JavaScript Charts", 23 | "logoSrc": "https://static.anychart.com/logo.png", 24 | "enabled": false 25 | }, 26 | "selectMarqueeFill": { 27 | "color": "#d3d3d3", 28 | "opacity": 0.4 29 | }, 30 | "legend": { 31 | "enabled": true, 32 | "fontSize": 13, 33 | "padding": { 34 | "left": 0, 35 | "top": 0, 36 | "bottom": 20, 37 | "right": 0 38 | } 39 | }, 40 | "xScale": 0, 41 | "yScale": 1, 42 | "series": [ 43 | { 44 | "enabled": true, 45 | "seriesType": "column", 46 | "meta": {}, 47 | "name": "Avg", 48 | "selectFill": { 49 | "color": "#f48fb1", 50 | "opacity": 0.8 51 | }, 52 | "selectStroke": { 53 | "color": "#c2185b", 54 | "thickness": 1.5 55 | }, 56 | "data": [ 57 | { 58 | "x": "Jun-17", 59 | "value": 1.57 60 | }, 61 | { 62 | "x": "Sep-17", 63 | "value": 1.89 64 | }, 65 | { 66 | "x": "2017", 67 | "value": 8.94 68 | }, 69 | { 70 | "x": "2018", 71 | "value": 10.53 72 | } 73 | ], 74 | "xScale": 0, 75 | "yScale": 1 76 | }, 77 | { 78 | "enabled": true, 79 | "seriesType": "column", 80 | "meta": {}, 81 | "name": "High", 82 | "selectFill": { 83 | "color": "#f48fb1", 84 | "opacity": 0.8 85 | }, 86 | "selectStroke": { 87 | "color": "#c2185b", 88 | "thickness": 1.5 89 | }, 90 | "data": [ 91 | { 92 | "x": "Jun-17", 93 | "value": 1.68 94 | }, 95 | { 96 | "x": "Sep-17", 97 | "value": 2.18 98 | }, 99 | { 100 | "x": "2017", 101 | "value": 9.6 102 | }, 103 | { 104 | "x": "2018", 105 | "value": 12.49 106 | } 107 | ], 108 | "xScale": 0, 109 | "yScale": 1 110 | }, 111 | { 112 | "enabled": true, 113 | "seriesType": "column", 114 | "meta": {}, 115 | "name": "Low", 116 | "selectFill": { 117 | "color": "#f48fb1", 118 | "opacity": 0.8 119 | }, 120 | "selectStroke": { 121 | "color": "#c2185b", 122 | "thickness": 1.5 123 | }, 124 | "data": [ 125 | { 126 | "x": "Jun-17", 127 | "value": 1.5 128 | }, 129 | { 130 | "x": "Sep-17", 131 | "value": 1.61 132 | }, 133 | { 134 | "x": "2017", 135 | "value": 8.64 136 | }, 137 | { 138 | "x": "2018", 139 | "value": 9.16 140 | } 141 | ], 142 | "xScale": 0, 143 | "yScale": 1 144 | } 145 | ], 146 | "yAxes": [ 147 | { 148 | "enabled": false 149 | } 150 | ], 151 | "type": "column", 152 | "barGroupsPadding": 0.3 153 | } 154 | } -------------------------------------------------------------------------------- /playground/configs/js.js: -------------------------------------------------------------------------------- 1 | anychart.onDocumentReady(function () { 2 | var data = getData(); 3 | 4 | // create venn diagram 5 | chart = anychart.venn(data); 6 | 7 | // set chart stroke 8 | chart.stroke('2 #fff'); 9 | 10 | // set labels settings 11 | chart.labels().format('{%Name}'); 12 | 13 | // set font color for hover intersections labels 14 | chart.intersections().hovered().fill('black 0.25'); 15 | 16 | // set intersections labels settings 17 | chart.intersections().labels() 18 | .fontWeight('bold') 19 | .format('{%Name}'); 20 | 21 | // set legend settings 22 | chart.legend() 23 | .position('right') 24 | .itemsLayout('vertical') 25 | .padding({left: 35}); 26 | 27 | // set tooltip settings 28 | chart.tooltip().titleFormat('{%Name}'); 29 | 30 | // set container id for the chart 31 | chart.container('container'); 32 | // initiate chart drawing 33 | chart.draw(); 34 | }); 35 | 36 | function getData() { 37 | return [{ 38 | x: 'A', 39 | name: 'Data Science', 40 | value: 100, 41 | stroke: 'none', 42 | label: { 43 | fontColor: '#3b8ad8', 44 | fontSize: 14 45 | } 46 | }, { 47 | x: 'B', 48 | name: 'Computer Science', 49 | value: 25 50 | }, { 51 | x: 'C', 52 | name: 'Math and Statistics', 53 | value: 25 54 | }, { 55 | x: 'D', 56 | name: 'Subject Matter Expertise', 57 | value: 25 58 | }, { 59 | x: ['A', 'B'], 60 | name: 'Computer Science', 61 | value: 50 62 | }, { 63 | x: ['A', 'C'], 64 | name: 'Math and Statistics', 65 | value: 50 66 | }, { 67 | x: ['A', 'D'], 68 | name: 'Subject Matter Expertise', 69 | value: 50 70 | }, 71 | 72 | { 73 | x: ['B', 'C'], 74 | name: 'Machine\nLearning', 75 | value: 5 76 | }, { 77 | x: ['C', 'D'], 78 | name: 'Traditional\nResearch', 79 | value: 5 80 | }, { 81 | x: ['D', 'B'], 82 | name: 'Traditional\nSoftware', 83 | value: 5 84 | }, { 85 | x: ['B', 'C', 'D'], 86 | name: 'Unicorn', 87 | value: 5 88 | }]; 89 | } -------------------------------------------------------------------------------- /playground/configs/json.json: -------------------------------------------------------------------------------- 1 | { 2 | "chart": { 3 | "enabled": true, 4 | "title": { 5 | "enabled": true, 6 | "text": "Top 3 Products with Region Sales Data" 7 | }, 8 | "padding": { 9 | "left": 20, 10 | "top": 10, 11 | "bottom": 5, 12 | "right": 40 13 | }, 14 | "animation": { 15 | "enabled": false 16 | }, 17 | "tooltip": { 18 | "enabled": true, 19 | "format": "${%Value}", 20 | "anchor": "left-center", 21 | "offsetX": 5, 22 | "offsetY": 0, 23 | "positionMode": "point" 24 | }, 25 | "credits": { 26 | "enabled": false 27 | }, 28 | "legend": { 29 | "enabled": true, 30 | "fontSize": 13, 31 | "padding": { 32 | "left": 0, 33 | "top": 0, 34 | "bottom": 20, 35 | "right": 0 36 | } 37 | }, 38 | "xScale": 0, 39 | "yScale": 1, 40 | "series": [ 41 | { 42 | "enabled": true, 43 | "seriesType": "bar", 44 | "meta": {}, 45 | "name": "Florida", 46 | "normal": { 47 | "labels": { 48 | "enabled": true, 49 | "fontColor": "#fff", 50 | "format": "${%Value}{groupsSeparator: }", 51 | "position": "right-center", 52 | "anchor": "left-center", 53 | "offsetY": -65 54 | }, 55 | "outlierMarkers": { 56 | "enabled": null 57 | } 58 | }, 59 | "hovered": { 60 | "outlierMarkers": { 61 | "enabled": null 62 | } 63 | }, 64 | "selected": { 65 | "outlierMarkers": { 66 | "enabled": null 67 | } 68 | }, 69 | "data": [ 70 | { 71 | "x": "Nail polish", 72 | "value": 6814 73 | }, 74 | { 75 | "x": "Eyebrow pencil", 76 | "value": 7012 77 | }, 78 | { 79 | "x": "Lipstick", 80 | "value": 8814 81 | } 82 | ], 83 | "xScale": 0, 84 | "yScale": 1 85 | }, 86 | { 87 | "enabled": true, 88 | "seriesType": "bar", 89 | "meta": {}, 90 | "name": "Texas", 91 | "normal": { 92 | "labels": { 93 | "enabled": true, 94 | "fontColor": "#fff", 95 | "format": "${%Value}{groupsSeparator: }", 96 | "position": "right-center", 97 | "anchor": "left-center", 98 | "offsetY": -65 99 | }, 100 | "outlierMarkers": { 101 | "enabled": null 102 | } 103 | }, 104 | "hovered": { 105 | "outlierMarkers": { 106 | "enabled": null 107 | } 108 | }, 109 | "selected": { 110 | "outlierMarkers": { 111 | "enabled": null 112 | } 113 | }, 114 | "data": [ 115 | { 116 | "x": "Nail polish", 117 | "value": 3054 118 | }, 119 | { 120 | "x": "Eyebrow pencil", 121 | "value": 5067 122 | }, 123 | { 124 | "x": "Lipstick", 125 | "value": 9054 126 | } 127 | ], 128 | "xScale": 0, 129 | "yScale": 1 130 | }, 131 | { 132 | "enabled": true, 133 | "seriesType": "bar", 134 | "meta": {}, 135 | "name": "Arizona", 136 | "normal": { 137 | "labels": { 138 | "enabled": true, 139 | "fontColor": "#fff", 140 | "format": "${%Value}{groupsSeparator: }", 141 | "position": "right-center", 142 | "anchor": "left-center", 143 | "offsetY": -65 144 | }, 145 | "outlierMarkers": { 146 | "enabled": null 147 | } 148 | }, 149 | "hovered": { 150 | "outlierMarkers": { 151 | "enabled": null 152 | } 153 | }, 154 | "selected": { 155 | "outlierMarkers": { 156 | "enabled": null 157 | } 158 | }, 159 | "data": [ 160 | { 161 | "x": "Nail polish", 162 | "value": 4376 163 | }, 164 | { 165 | "x": "Eyebrow pencil", 166 | "value": 8987 167 | }, 168 | { 169 | "x": "Lipstick", 170 | "value": 4376 171 | } 172 | ], 173 | "xScale": 0, 174 | "yScale": 1 175 | }, 176 | { 177 | "enabled": true, 178 | "seriesType": "bar", 179 | "meta": {}, 180 | "name": "Nevada", 181 | "normal": { 182 | "labels": { 183 | "enabled": true, 184 | "fontColor": "#fff", 185 | "format": "${%Value}{groupsSeparator: }", 186 | "position": "right-center", 187 | "anchor": "left-center", 188 | "offsetY": -65 189 | }, 190 | "outlierMarkers": { 191 | "enabled": null 192 | } 193 | }, 194 | "hovered": { 195 | "outlierMarkers": { 196 | "enabled": null 197 | } 198 | }, 199 | "selected": { 200 | "outlierMarkers": { 201 | "enabled": null 202 | } 203 | }, 204 | "data": [ 205 | { 206 | "x": "Nail polish", 207 | "value": 4229 208 | }, 209 | { 210 | "x": "Eyebrow pencil", 211 | "value": 3932 212 | }, 213 | { 214 | "x": "Lipstick", 215 | "value": 9256 216 | } 217 | ], 218 | "xScale": 0, 219 | "yScale": 1 220 | } 221 | ], 222 | "xAxes": [ 223 | { 224 | "enabled": true, 225 | "labels": { 226 | "enabled": true, 227 | "padding": { 228 | "left": 0, 229 | "top": 0, 230 | "bottom": 20, 231 | "right": 0 232 | }, 233 | "rotation": -90 234 | } 235 | } 236 | ], 237 | "yAxes": [ 238 | { 239 | "enabled": true, 240 | "title": { 241 | "enabled": true, 242 | "text": "Revenue in Dollars" 243 | }, 244 | "labels": { 245 | "enabled": true, 246 | "format": "{%Value}{groupsSeparator: }" 247 | } 248 | } 249 | ], 250 | "scales": [ 251 | {}, 252 | { 253 | "minimum": 0, 254 | "softMinimum": null, 255 | "comparisonMode": "none" 256 | } 257 | ], 258 | "type": "bar-3d" 259 | } 260 | } -------------------------------------------------------------------------------- /playground/configs/logo.txt: -------------------------------------------------------------------------------- 1 | data:image/png;base64,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UK5vQ72gwaB4g8GqNc3o4W0GDQPEHg1Rru9HC2gwaB4g8H6j9RXN6ODtokeIPB+hkSRB9qvGMYxWL7H8DXd6He2iB4g8H6PaFPM2/AVzeh3tokeIPB+j2h+uCu70O9tEjxB4P0e0P1w17ejhbQYNA8wc/oekK95r3UyN6ONtBg0DxDkPVBzPQIEh5fZZ8s+WfLPlLo0HuTnB2qeYct7qYG9DvbRA8QeWUOScGnjd4OyFLzDlvdTE3od7aJHiDyg5JwaeF3g7IUvMOW91MTeh2tokeIPLKHJODTwu8Hap5hy3upib0OdtEDxBxZQ5JwaeF3g7IUvMOW91MDehztBg0DxB5Qck4NPC7wdqnmHLe6mBvQ520QPEHFlDknBp4XeDshS9w5b3UwN6HO2iB4g4sock4NPC7wdkKXmHLe6mhvQ720QPEHFByTg08LvB+QpeYct7qYG9DnbRA8QeWUAQHchFE7pppStZMen3LtOEsmaAnUAAAAM1MngIqBgfRZss+WbLNlnyn+Bmfh3oc7aJHiDyzSdfycraIHiDyzXO9tEBQfkXlHIeogP8Q1u+CHZoNAMwuxCObEhOf8LuJn29qfw9jyFPVgwAHXl17PQQ3Z2EPtQJaH+OLcIhASI7qdAd1JZ/2DLVUpSlOUpTlKUpSlKUpSlKUlQ176lOl2eBAY0hdQOn+aOayPeOyHQkPTsiCO4IUwui6KYXRTCmFMKYU1NTC6LouimF0XRTCmF0XRTC6LpD1JoBNGPEAkdT/UCiASAHjSED3AK7+f6Cx1Y+sZWHrGVjKxlYysZWMrGVjKxlYysZWMrGVjKxlYysfWMrGVjKx9dOTFNq/wDTj//aAAwDAQACAAMAAAAQ88888888888888888888888888888888888888888888888888888888888888888888888888888888zy26y3/y7/6yz9y088888884KnDiDARDDjDDDCE9z8888888vkV8888888888888tv8APPPPPPLk1PPPPPPPPMPPPPKa/PPPPPPPg1PPPPPPPPDzzzPKa/PPPPPPPo1PPPPPPPPP8s6/Ka/PPPPPPPg1PPPPOPsutb/f/Ka/PPPPPPPq1PPPPPUc9fH7f/KYvPPPPPPPh1PPPPPYwAPG+U/Ka/PPPPPPOl1Od9tvYwBIwgmPL6/PPPPPPKlV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 -------------------------------------------------------------------------------- /playground/configs/report.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | return { 3 | "pageMargins": [30, 70, 30, 20], 4 | "header": { 5 | "margin": [10, 10, 15, 0], 6 | "columns": [ 7 | { 8 | "margin": 0, 9 | "image": "data:image/png;base64,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UK5vQ72gwaB4g8GqNc3o4W0GDQPEHg1Rru9HC2gwaB4g8H6j9RXN6ODtokeIPB+hkSRB9qvGMYxWL7H8DXd6He2iB4g8H6PaFPM2/AVzeh3tokeIPB+j2h+uCu70O9tEjxB4P0e0P1w17ejhbQYNA8wc/oekK95r3UyN6ONtBg0DxDkPVBzPQIEh5fZZ8s+WfLPlLo0HuTnB2qeYct7qYG9DvbRA8QeWUOScGnjd4OyFLzDlvdTE3od7aJHiDyg5JwaeF3g7IUvMOW91MTeh2tokeIPLKHJODTwu8Hap5hy3upib0OdtEDxBxZQ5JwaeF3g7IUvMOW91MDehztBg0DxB5Qck4NPC7wdqnmHLe6mBvQ520QPEHFlDknBp4XeDshS9w5b3UwN6HO2iB4g4sock4NPC7wdkKXmHLe6mhvQ720QPEHFByTg08LvB+QpeYct7qYG9DnbRA8QeWUAQHchFE7pppStZMen3LtOEsmaAnUAAAAM1MngIqBgfRZss+WbLNlnyn+Bmfh3oc7aJHiDyzSdfycraIHiDyzXO9tEBQfkXlHIeogP8Q1u+CHZoNAMwuxCObEhOf8LuJn29qfw9jyFPVgwAHXl17PQQ3Z2EPtQJaH+OLcIhASI7qdAd1JZ/2DLVUpSlOUpTlKUpSlKUpSlKUlQ176lOl2eBAY0hdQOn+aOayPeOyHQkPTsiCO4IUwui6KYXRTCmFMKYU1NTC6LouimF0XRTCmF0XRTC6LpD1JoBNGPEAkdT/UCiASAHjSED3AK7+f6Cx1Y+sZWHrGVjKxlYysZWMrGVjKxlYysZWMrGVjKxlYysfWMrGVjKx9dOTFNq/wDTj//aAAwDAQACAAMAAAAQ88888888888888888888888888888888888888888888888888888888888888888888888888888888zy26y3/y7/6yz9y088888884KnDiDARDDjDDDCE9z8888888vkV8888888888888tv8APPPPPPLk1PPPPPPPPMPPPPKa/PPPPPPPg1PPPPPPPPDzzzPKa/PPPPPPPo1PPPPPPPPP8s6/Ka/PPPPPPPg1PPPPOPsutb/f/Ka/PPPPPPPq1PPPPPUc9fH7f/KYvPPPPPPPh1PPPPPYwAPG+U/Ka/PPPPPPOl1Od9tvYwBIwgmPL6/PPPPPPKlVKYg4eaQFgShgfK6/PPPPPPPtVKQgwfaQFgShgfK6/PPPPPPOvVKQgweSQFgUkgfKo/PPPPPPKlVKQgwfYQFgetwfKq/PPPPPPPlVOZDRat/+pBjgfKq/PPPPPPLXFPPPPPPPPPPPPPPaPPPPPPPKU5scdcdccccceeQQ9fPPPPPPPKZrz3zzz/zz/nz+mlfPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP/xAApEQABAgUDAwUAAwAAAAAAAAABALEQEWGRoTAx8HHR8SFBUcHhIGCB/9oACAEDAQE/EP6htoOpXlgvLBeWC8sF5YLywXlgvLBeWC8sF5YLywRKQvBACY0iAlR+F61DUlUV1RXVFdUV1RXVFdUV1RXVFdUV1RXVFdA+sl1PSYluChP3saFNQSvnyJKGgSA1i2TsI4naU9DCLJ+2vh/axvvQwiyftpAAI9jqnsFT2COYhQKGGGsb70MIsn7aWGePKoYYaxPvQwiyfsho4Z48qhhhrkV0MIsn7IfxGfVDqlsqWwRkQAzHssM8eVQww1ifehhFk/ZD+OWHju9QsM8eVQww1yK6GEWTxoEyEyiIyaey4weyAZstvQrLDoQ3OoWMeJcnwYYa4ldDCLJ40N1bvWD9issOhDc6hYx48ShhhrkV0MIsnjQ3ei3OsH7FZYdCG51Cxjx4lDDBXMroYRZPGhu9FudYP2Kyw6ENzqFjHjxKGGGuRXQwiyeNDdW51g/YrLDoQ3OoWMePEoYYa5FdDCLJ40AmCESGZy/FyFTIJK/4jCDcKsLKuLL03y6LcrKY/wAVUWVUWQgcSBn6CUMFcyugQEfBZCmKjGuGb9whM6n3oETXtunMkN/SLkB7LkB7LkB7LkB7LkB7LkB7LkB7LmB7LkB7LgB7LmB7LkB7IBNpRjA5Dcoxd5uidTAR80oVE1R2VHZUdv1UdlR2VHZUdlR2VHb9VFb9VHZUdv1D3Rt+r1fvxsEAAkP7T//EACcRAAECBQQCAwEBAQAAAAAAAAEAoRARYZGxMDHB0XHwIUFRIGDh/9oACAECAQE/EP8AIbxHwFUWKqbFVliqmxVTYqpsVU2KrbFVNiqmxVZYqssUQfJOxRPgdIb9H0F8hS8KssqyyrLKssqyyqLKssqyyrLKssqyyrLIj4wU7CXz9hG+gSv9FTD6RIIhTb6wh9EHb6D0ZWJnVnB4n/Gg9GViZ0iIOPwqouqy6FRT+IPE/wCNB6MrEzpNypKSbcweJ/xoPRlYmf7mpqaamLKDxP8AjQejKxM/18fGVW3Kq7lDYIRI/aalGDKDxP8AjQejKxM/0xOEYbHgpuYsIPE/40HoysbMairItIFNTiOx4KbmLLmDhP8AjQejKwsxO5hsJqcR2PBTcxbciDhPeNB6MrCzAo7w2k1OI7HgpuYsuRBwnvGg9GVhZgUd4bSanEdjwU3MWXIg4T3jQejKwswKO8NpNTiOx4KbmLLmDhPeNB6MrCzE/kqSLTCCc9j8Kibqib/8Ut5n5RHtFea6pG6MJk/MHCe8aBSLUZRJKmdckiju8aP3o2IU0fIL1kdr1kdr1kdr1kdr1kdr1kdr1kdr1kdr1kdr1kdr1kdr1kdosyyCCEyZMvz7RTjSKEkm+FXXHSrrjpV1x0q646VdcdKuuOlXXHSrrjpV1x0q646VdcdKuuOlXXHSl5kdEz+T/qf/xAAqEAACAAMGBgMBAQEAAAAAAAAAARFR8BAhMZHB8SBAQWGh0TBxsYHhgP/aAAgBAQABPxD/AJnggQEmaEOzEpM/xFd6Fd6Fd6FF6FF6Fd6FF6Fd6Fd6FZ6FZ6FR6Fd6Fd6FF6FJ6FP6FF6FF6Fd6Fd6Ff6Fd6Ff6FZ6C61bmj9Qogd9wTWAuSUttBLqIHXui7rIjDcb0E/mBmRc3mRc3mRc3mXzZFzeZFzeZFzeZFzeZFzeZFzeYozeYnM8yLm8yLm8yLm8yLm8yLm8yLm8yLmzIubzIubzO48xtzeYm5vMi5vMv6sdRmjC8fawYvBi7rmjEBkU0Rv5BkNTDIvF7uv9GYZxbd7IeBd9QxxWv1JVDzZZtI2kbSNpG0jaRtI2lb55s6NrG0jaRtI2kbSNpG0jaRtI2kbSGKKN2FKoeLyLi2cENj+ibTisSPEgjr5X2vwTiopx5BDFwiMfgNJX/BEdxJ4wPsYjgiVyvf3N82xtWyaSIsZxuK6/4wHHmU3CXVGAUpP7yGI2UG4t/Ymw2fQabf4hc5AQhEo/8XjoY5EQLDkDPEp8mLnfIWPE6i+ejdhlHkxcmZJJxgJIYrMipog7EVNDSaLhYcAjPE6i5AzxKvJi5MtiEJpPGfEooooomxV5m73Xg8qGeJ1F89G7DxKPJi5J4FHnwvoeH+nB5cM8TqLkDdWV+TFyTwKXMiiNkbPD/ThEhAqXcXIGavZR5MXJPAo87U7MTw/04GzgZUu4uQM8SjyYuSeBT5j4EeD+nB5SxUu4uQM8XeyjyYvjbQ1+JHui6aP6iPdCadlJmXF3B4f6cHl7HhdRcgZq9lHkxfG9e+JtBq4X+uN7m9ze5vcRjDJOM1ch4FHnYlZASPB/ThEaPE6i5Azd7KPJi+OtSMHD5H8DKRMhw+H+nCIzwuouQN1ZR5MXIyeZ/EMpMy+IxDFieD+nCIzwuouQM8SvyYvjrUjBw+Z/EMo87IiImLLv1/pweUDKl3F89E7DL3Z/Ji+OsSMA3a2ec/EMSLZCysRAWIt9NnkK3Gd36GVLuLkDOJTJhWvVKLY4TgiMugyjKf0VpoUpoVpoRaTwQzxTbiJrtZTJC04ahJD4AkXDKtNxceJ1FyBmU6YVvRUIq02RIkbKJOxTJGDhqEkPgidjdxUp+CkTDwPG6i5E1OkxW0yRXpvhpk7FGlxKhJDsidiRAauKlPw6M8LqL56N2HiU6YVtMkV6b4FgVydinSFw1CSHxxVKfig8TqL56N2HiV6YVtMkV6b4EUydpmBcNQkh2RRGJ2NlWm4oKl3FyBm7ynSYraZIr03w0ydpi04ahJDsizIEDoNFWm4KhMM8TqLkDPEr0wraZIr03wLArk7FGkYOGiSQ7Ir7L7atNwgPA8TqLkDMr0wraZIr03wLArk7FOkYCPBUJIdkUSJEiNlGm4UHgeJ1FyBupXpMVtMkV6b4FgVydiuSMCIcFQkh2ROxDsq03DAzxOouQN1KdMK3FJCUfoXyCxq/1f0b59G+fRvv0b79DoRJRGJFG7vY2lIlLosX+09G9vRvb0b29G9vQ4QaWJtQgvQxAq02hAnF3lRaFZaFRaFRaDhO6qkNLRjNG8zuzFwQPA8LqLkDdSnTCtaiNF9l5eKxoSa4YEBqASuIECA1EhxSeJ1FyBmU6YXPYO48TqL51KNtCCHi+xShKCauP9544m00dl2hAeAxyr/a5BeIAn/R+lLxerYMcBjH0J1TE8Ylj3smiDmYob7CS5xSbvaSI+yTwyBDMLKTh3X+C5CTX6SgL52QhaC2kL+sh2BqCNQaYgp3FJ3fZCYlFfef8gzcvo3L6Ny+jcvo3L6N0+jcvo3L6Ny+jdPo3L6Ny+jcvo3L6Ny+jcvo3L6Ny+jcPo3D6Nw+jcvo3D6Ny+igehlYODXP8gRZuN0WQj+DqbXBh69/2K5Cw5CCkhq7imjM9kOF4Ji/0xxmCgK8vWY30NZkZlmdxZicyzO4szuLMXUazO4syCazIJrM+jMjOsyM6zG5lmfRmNzLMTmWZ3FmNnVZkZvJGZZjZ1WYnMsxuZZivTfTqxBd2KM/qAqXxICO90ULoCnrE0EiwRBS5KBdKzuojaLNzWhQ2hQWhR2hUWhR2hR2hR2hR2hR2hR2hR2hR2hR2hR2hR2hR2hR2hR2hR2hR2hQWhR2hR2hR2hQWhf0gvp/gJEoJhCUMhqIlB/9Nf/Z", 10 | "width": 50, 11 | "height": 50 12 | }, 13 | { 14 | "text": "AnyChart", 15 | "margin": [0, 17, 0, 0], 16 | "fontWeight": "bold" 17 | }, 18 | { 19 | "width": "*", 20 | "alignment": "right", 21 | "text": "PDF Report sample", 22 | "margin": [0, 17, 0, 0] 23 | } 24 | ] 25 | }, 26 | "content": [ 27 | { 28 | "alignment": "center", 29 | "chart": { 30 | "data": "chart1.js", 31 | "dataType": "javascript", 32 | "containerId": "customId" 33 | }, 34 | "fit": [500, 400] 35 | }, 36 | { 37 | "columns": [ 38 | { 39 | "style": "tables", 40 | "table": { 41 | "headerRows": 1, 42 | "widths": [65, "*", "*", "*", "*"], 43 | "body": [ 44 | [ 45 | {"text": "Earnings History", "style": 'tableHeader'}, 46 | {"text": "Mar 31, 17", "style": 'tableHeader'}, 47 | {"text": "Dec 31, 16", "style": 'tableHeader'}, 48 | {"text": "Sep 30, 16", "style": 'tableHeader'}, 49 | {"text": "Jun 30, 16", "style": 'tableHeader'} 50 | ], 51 | [{"text": "EPS Actual", "alignment": "left"}, "2.10", "3.33", "1.67", "1.42"], 52 | [{"text": "EPS Estimate", "alignment": "left"}, "2.02", "3.21", "1.65", "1.38"], 53 | [{"text": "Difference", "alignment": "left"}, "0.08", "0.15", "0.01", "0.04"], 54 | [{"text": "Surprise, %", "alignment": "left"}, "4.0%", "4.7%", "0.6%", "2.9%"] 55 | ] 56 | }, 57 | "layout": { 58 | "hLineWidth": function(i, node) { 59 | return (i === 0 || i === node['table']['body']['length']) ? 1 : 0; 60 | }, 61 | "vLineWidth": function(i, node) { 62 | return 0; 63 | }, 64 | "fillColor": function(i, node) { 65 | return i === 0 ? '#7FDBFF' : null; 66 | } 67 | } 68 | }, 69 | { 70 | "style": "tables", 71 | "table": { 72 | "headerRows": 1, 73 | "widths": [65, "*", "*", "*", "*"], 74 | "body": [ 75 | [ 76 | {"text": "Earnings History", "style": 'tableHeader'}, 77 | {"text": "Mar 31, 17", "style": 'tableHeader'}, 78 | {"text": "Dec 31, 16", "style": 'tableHeader'}, 79 | {"text": "Sep 30, 16", "style": 'tableHeader'}, 80 | {"text": "Jun 30, 16", "style": 'tableHeader'} 81 | ], 82 | [{"text": "Average Estimate", "alignment": "left"}, "1.57", "1.89", "8.94", "10.53"], 83 | [{"text": "High Estimate", "alignment": "left"}, "1.68", "2.18", "9.60", "12.49"], 84 | [{"text": "Low Estimate", "alignment": "left"}, "1.50", "1.61", "8.64", "9.16"], 85 | [{"text": "Year Ago EPS", "alignment": "left"}, "1.42", "1.67", "8.31", "8.94"] 86 | ] 87 | }, 88 | "layout": { 89 | "hLineWidth": function(i, node) { 90 | return (i === 0 || i === node['table']['body']['length']) ? 1 : 0; 91 | }, 92 | "vLineWidth": function(i, node) { 93 | return 0; 94 | }, 95 | "fillColor": function(i, node) { 96 | return i === 0 ? '#7FDBFF' : null; 97 | } 98 | } 99 | } 100 | ], 101 | "columnGap": 10, 102 | "margin": [0, 20, 0, 10] 103 | }, 104 | { 105 | "text": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium, alias animi aperiam architecto autem consequatur dicta dignissimos exercitationem, laboriosam laborum natus necessitatibus neque obcaecati quaerat reiciendis, sequi tempora velit voluptatum. Architecto cumque dolorem ducimus harum iusto magnam omnis, sit voluptate. Ab adipisci at earum error est explicabo incidunt iste modi, neque optio, provident sint tenetur!", 106 | "color": "gray", 107 | "italics": true, 108 | "alignment": "justify", 109 | "margin": [0, 10, 0, 10] 110 | }, 111 | { 112 | "columns": [ 113 | { 114 | "chart": { 115 | "data": "chart2.json", 116 | "dataType": "json" 117 | }, 118 | "fit": [250, 300] 119 | }, 120 | { 121 | "chart": { 122 | "data": "chart2.json", 123 | "dataType": "json" 124 | }, 125 | "fit": [250, 300] 126 | } 127 | ], 128 | "columnGap": 10 129 | } 130 | ], 131 | "footer": { 132 | "style": "footer", 133 | "columns": [ 134 | { 135 | "text": "Created by anychart-report-server (https://github.com/AnyChart/node-export-server)", 136 | "alignment": "left", 137 | "width": "auto" 138 | }, 139 | {"text": "© 2017 AnyChart All rights reserved.", "alignment": "right", "width": "*"} 140 | ] 141 | }, 142 | "styles": { 143 | "footer": { 144 | "margin": [10, 0, 10, 10], 145 | "color": "gray", 146 | "fontSize": 9 147 | }, 148 | "tables": { 149 | "fontSize": 7, 150 | "alignment": "right" 151 | }, 152 | "tableHeader": { 153 | "alignment": "left", 154 | "bold": true, 155 | "fontSize": 7.5 156 | } 157 | } 158 | } 159 | })(); -------------------------------------------------------------------------------- /playground/configs/textByPath.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | We go up, then we go down, then up again 17 | 18 | 19 | 20 | 21 | 23 | -------------------------------------------------------------------------------- /playground/configs/xml.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <padding left="20" top="10" bottom="5" right="40"/> 6 | <tooltip format="${%Value}" offset_x="5" offset_y="0" position_mode="point" enabled="true"/> 7 | <credits text="AnyChart" url="https://www.anychart.com/?utm_source=registered" 8 | alt="AnyChart - JavaScript Charts designed to be embedded and integrated" 9 | img_alt="AnyChart - JavaScript Charts" logo_src="https://static.anychart.com/logo.png" 10 | enabled="false"/> 11 | <select_marquee_fill color="#d3d3d3" opacity="0.4"/> 12 | <legend enabled="true" font_size="13"> 13 | <padding left="0" top="0" bottom="20" right="0"/> 14 | </legend> 15 | <series_list> 16 | <series enabled="true" series_type="bar" name="Florida" x_scale="0" y_scale="1"> 17 | <meta/> 18 | <data> 19 | <point x="Nail polish" value="6229"/> 20 | <point x="Eyebrow pencil" value="9332"/> 21 | <point x="Lipstick" value="9256"/> 22 | </data> 23 | </series> 24 | <series enabled="true" series_type="bar" name="Texas" x_scale="0" y_scale="1"> 25 | <meta/> 26 | <data> 27 | <point x="Nail polish" value="4376"/> 28 | <point x="Eyebrow pencil" value="8987"/> 29 | <point x="Lipstick" value="7376"/> 30 | </data> 31 | </series> 32 | <series enabled="true" series_type="bar" name="Arizona" x_scale="0" y_scale="1"> 33 | <meta/> 34 | <data> 35 | <point x="Nail polish" value="4054"/> 36 | <point x="Eyebrow pencil" value="5067"/> 37 | <point x="Lipstick" value="5054"/> 38 | </data> 39 | </series> 40 | <series enabled="true" series_type="bar" name="Nevada" x_scale="0" y_scale="1"> 41 | <meta/> 42 | <data> 43 | <point x="Nail polish" value="2381"/> 44 | <point x="Eyebrow pencil" value="1401"/> 45 | <point x="Lipstick" value="981"/> 46 | </data> 47 | </series> 48 | </series_list> 49 | <x_axes> 50 | <axis enabled="true"> 51 | <labels enabled="true" rotation="-90"> 52 | <padding left="0" top="0" bottom="20" right="0"/> 53 | </labels> 54 | </axis> 55 | </x_axes> 56 | <y_axes> 57 | <axis enabled="true"> 58 | <title enabled="true" text="Revenue in Dollars"/> 59 | <labels enabled="true" format="${%Value}{groupsSeparator: }"/> 60 | </axis> 61 | </y_axes> 62 | <scales> 63 | <scale/> 64 | <scale minimum="0"/> 65 | </scales> 66 | </chart> 67 | </anychart> -------------------------------------------------------------------------------- /playground/css/bootstrap-theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.7 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} 6 | /*# sourceMappingURL=bootstrap-theme.min.css.map */ -------------------------------------------------------------------------------- /playground/css/index.css: -------------------------------------------------------------------------------- 1 | /* Sticky footer styles -------------------------- */ 2 | html { 3 | position: relative; 4 | min-height: 100%; 5 | } 6 | body { 7 | /*background: red;*/ 8 | /* Margin bottom by footer height */ 9 | margin-bottom: 60px; 10 | } 11 | .footer { 12 | position: absolute; 13 | bottom: 0; 14 | width: 100%; 15 | /* Set the fixed height of the footer here */ 16 | height: 25px; 17 | /*background-color: #f5f5f5;*/ 18 | } 19 | .footer-text { 20 | font-size: 11px; 21 | margin-top: 5px; 22 | display: table; 23 | padding-left: 20px; 24 | /*margin-left: auto;*/ 25 | /*margin-right: auto;*/ 26 | } 27 | .anychart-link, .anychart-link:hover, .anychart-link:focus { 28 | color: #333; 29 | 30 | } 31 | /*End Sticky footer styles ------------------------ */ 32 | 33 | 34 | html, body, #content, #viewpdf { 35 | margin: 0; 36 | padding: 0; 37 | } 38 | 39 | 40 | header { 41 | margin: 20px; 42 | } 43 | 44 | .logo { 45 | display: inline-block; 46 | padding: 0px 5px 0px 5px; 47 | } 48 | 49 | .logo img { 50 | width: 55px; 51 | height: 55px; 52 | vertical-align: middle; 53 | } 54 | 55 | .logo-label { 56 | /*float: right;*/ 57 | display: inline-block; 58 | vertical-align: middle; 59 | } 60 | 61 | h1 { 62 | /*padding-left: 15px;*/ 63 | color: #333 64 | } 65 | 66 | 67 | 68 | /*Disable ace code line highlight------------------------------------------------------------------------------------------------------------------------------------*/ 69 | .noselection .ace_marker-layer .ace_selection { 70 | background: transparent; 71 | } 72 | 73 | .noselection .ace_cursor { 74 | color: transparent; 75 | } 76 | /*End Disable ace code line highlight------------------------------------------------------------------------------------------------------------------------------------*/ 77 | 78 | 79 | .img-responsive { 80 | margin: 0 auto; 81 | } 82 | 83 | .playground-panel { 84 | padding: 0; 85 | margin: 0; 86 | } 87 | 88 | #source { 89 | border-bottom: 1px solid #ddd; 90 | } 91 | 92 | #output { 93 | border: 1px solid #ddd; 94 | border-right: 0; 95 | margin-top: 41px; 96 | overflow: auto; 97 | 98 | display: flex; 99 | flex-direction: column; 100 | justify-content: center; 101 | } 102 | 103 | #output embed { 104 | display: none; 105 | width: 100%; 106 | height: 100%; 107 | margin: 0 auto; 108 | } 109 | 110 | #output img { 111 | display: none; 112 | margin: 0 auto; 113 | } 114 | 115 | .full-height { 116 | height: 100%; 117 | } 118 | 119 | 120 | /*Loader------------------------------------------------------------------------------------------------------------------------------------*/ 121 | .anychart-loader { 122 | background-color: rgba(255,255,255,.5); 123 | position: absolute; 124 | top: 0; 125 | left: 0; 126 | width: 100%; 127 | height: 100%; 128 | z-index: 1000; 129 | } 130 | 131 | .anychart-loader .rotating-cover { 132 | width: 70px; 133 | height: 70px; 134 | position: absolute; 135 | top: 50%; 136 | margin-top: -35px; 137 | left: 50%; 138 | margin-left: -35px; 139 | } 140 | 141 | .anychart-loader .rotating-plane { 142 | display: block; 143 | width: 100%; 144 | height: 100%; 145 | border-radius: 20%; 146 | border: 5px solid #1c75ba; 147 | margin: 0 auto; 148 | position: relative; 149 | -webkit-animation: rotateplane 3s infinite; 150 | animation: rotateplane 3s infinite; 151 | } 152 | 153 | .anychart-loader .chart-row { 154 | position: absolute; 155 | top: 10px; 156 | bottom: 0; 157 | left: 10px; 158 | right: 10px; 159 | letter-spacing: -3px; 160 | line-height: 0; 161 | font-size: 0; 162 | white-space: nowrap; 163 | } 164 | 165 | .anychart-loader .chart-row .chart-col { 166 | display: inline-block; 167 | width: 25%; 168 | height: 90%; 169 | background: #000; 170 | margin: 0 12.5% 0 0; 171 | vertical-align: bottom; 172 | } 173 | 174 | .anychart-loader .chart-row .chart-col.green { 175 | background: #26a957; 176 | height: 50%; 177 | -webkit-animation: blinkplane 1.5s infinite; 178 | animation: blinkplane 1.5s infinite; 179 | } 180 | 181 | .anychart-loader .chart-row .chart-col.orange { 182 | background: #ff8207; 183 | height: 70%; 184 | -webkit-animation: blinkplane 1.5s infinite 0.15s; 185 | animation: blinkplane 1.5s infinite 0.25s; 186 | 187 | } 188 | 189 | .anychart-loader .chart-row .chart-col.red { 190 | background: #f0402e; 191 | height: 90%; 192 | -webkit-animation: blinkplane 1.5s infinite 0.3s; 193 | animation: blinkplane 1.5s infinite 0.5s; 194 | } 195 | 196 | @keyframes rotateplane { 197 | 0% { 198 | -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg); 199 | transform: perspective(120px) rotateX(0deg) rotateY(0deg); 200 | opacity: 1; 201 | } 202 | 25% { 203 | -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); 204 | transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); 205 | opacity: 0.3; 206 | } 207 | 50% { 208 | -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); 209 | transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); 210 | opacity: 1; 211 | } 212 | 75% { 213 | -webkit-transform: perspective(120px) rotateX(0deg) rotateY(-180.1deg); 214 | transform: perspective(120px) rotateX(0deg) rotateY(-180.1deg); 215 | opacity: 0.3; 216 | } 217 | 100% { 218 | -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg); 219 | transform: perspective(120px) rotateX(0deg) rotateY(0deg); 220 | opacity: 1; 221 | } 222 | } 223 | 224 | @keyframes blinkplane { 225 | 0% { 226 | opacity: 1; 227 | } 228 | 50% { 229 | opacity: 0.01; 230 | } 231 | 100% { 232 | opacity: 1; 233 | } 234 | } 235 | /*Loader End------------------------------------------------------------------------------------------------------------------------------------*/ -------------------------------------------------------------------------------- /playground/img/500.img: -------------------------------------------------------------------------------- 1 | data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAp0AAAGKCAYAAABO7vqAAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAGCHSURBVHhe7Z0F2BZV2sePrWt3uwgqKraurauuBQb22tiydgcGtghrF3Z3i4K1YiMGtmJhI4iBmGDMd/7H71F4mXmeqTPzxO++rvfy+5Y59ZvzzPznPve5zySBNYNBAAIQgAAEIAABCEDAI4FJPdZN1RCAAAQgAAEIQAACEHAEEJ1MBAhAAAIQgAAEIAAB7wQQnd4R0wAEIAABCEAAAhCAAKKTOQABCEAAAhCAAAQg4J0AotM7YhqAAAQgAAEIQAACEEB0MgcgAAEIQAACEIAABLwTQHR6R0wDEIAABCAAAQhAAAKITuYABCAAAQhAAAIQgIB3AohO74hpAAIQgAAEIAABCEAA0ckcgAAEIAABCEAAAhDwTgDR6R0xDUAAAhCAAAQgAAEIIDqZAxCAAAQgAAEIQAAC3gkgOr0jpgEIQAACEIAABCAAAUQncwACEIAABCAAAQhAwDsBRKd3xDQAAQhAAAIQgAAEIIDoZA5AAAIQgAAEIAABCHgngOj0jpgGIAABCEAAAhCAAAQQncwBCEAAAhCAAAQgAAHvBBCd3hHTAAQgAAEIQAACEIAAopM5AAEIQAACEIAABCDgnQCi0ztiGoAABCAAAQhAAAIQQHQyByAAAQhAAAIQgAAEvBNAdHpHTAMQgAAEIAABCEAAAohO5gAEIAABCEAAAhCAgHcCiE7viGkAAhCAAAQgAAEIQADRyRyAAAQgAAEIQAACEPBOANHpHTENQAACEIAABCAAAQggOpkDEIAABCAAAQhAAALeCSA6vSOmAQhAAAIQgAAEIAABRCdzAAIQgAAEIAABCEDAOwFEp3fENAABCEAAAhCAAAQggOhkDkAAAhCAAAQgAAEIeCeA6PSOmAYgAAEIQAACEIAABBCdzAEIQAACEIAABCAAAe8EEJ3eEdMABCAAAQhAAAIQgACikzkAAQhAAAIQgAAEIOCdAKLTO2IagAAEIAABCEAAAhBAdDIHIAABCEAAAhCAAAS8E0B0ekdMAxCAAAQgAAEIQAACkwTWwAABCEAAAvEIjB071kwyySTu76effjK//PKLmW666dz/r8fp5JNPbiabbLJ4lXHVRATE8Ndff3UsZeL7ww8/OMZTTDGF+f333x1fccYgAIHGIoDobKz7RW9bgMDXX3/d8KOUMJh22mnNNNNM09Bj+fTTT82wYcPM22+/bfR/f/755+bVV191gkd/L7zwghNEyy67rBuvxj3bbLOZjh07mrnmmsv8/e9/N0sttZSZc845zQwzzNDQLHx1/quvvjJvvvmm4/zll1+a1157zQwfPtxxlbj84IMPHPv27dub+eabz4nQmWaaybRr18796X9faKGF3L+JPQYBCNQvAURn/d4betaCBMaNG2dWWmklM+OMMzb06L/77jtzwgknmE022aThxjF06FDTv39/M3jwYPPee+85kSnPW1pbZJFFnPicZ555TLdu3cwqq6xipp566rTVNUW5zz77zDz//PPm7rvvdmJTrDX305pE/cILL2w6dOhgunbtalZffXUz++yzp62OchCAgCcCiE5PYKkWAmkI6AWsF2cz2CWXXGL22muvhhmKvJa77LKLGTVqlPniiy+89Hv66ac3CyywgNluu+3MQQcd5LyjrWTvvPOO6dmzp3n00UfNmDFjzM8//5z78CXo5Qnt0qWL6dGjR9P8nnIHRYUQKIEAG4lKgE6TEIgiIK9as1gjxDXKu9a7d28jMfiPf/zDvPHGG94Ep+6rPMBq49hjj3Uxittvv71bum9m03L4vffea2addVYXdnDzzTc7xj4Epziq3hEjRpgrr7zSLbuvscYa5vHHHze//fZbM2NmbBBoCAKIzoa4TXSyVQjIE9QsVs9LyD/++KO58cYbzfLLL2+OPPJI8/3335eC/aabbjKLLrqo+c9//mNefvnlUvrgs9GBAwea9ddf3y15lxWr/NRTT5m11lrLdO7c2QwaNMjncKkbAhCoQQDRyRSBQB0RePDBB+uoN+m7ok02SyyxRPoKPJZ8+OGHnQDZYYcdzOuvv+6xpfhV9+3b12y44YbmtNNOawqP3Pvvv+9CKzSmxx57LD4Ij1fqvksAq1/aqIRBAALFEyCms3jmtAiBSAJKu9MMdu6555oDDjig7oZy0UUXmf3339/tMk9iWgpfZ511zJJLLmm0Mehvf/ubmX/++d2GIKX2qeyy1o7rb775xu1qV6jEiy++mKQZd+2//vUvc91115m55547cdl6KKB4TTHWjvSktt566znvszZeabe//qvQB92vSSed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d4uKNVS/qy0t1/u48uqfvJBRG1369u0bqxl9lHz99deh12oOtbppM1WUt1diPSr8o9W5MX4ItCWA6GROQKBgAlFeu44dO5qbbrrJiUudNKOcnfPOO69Za621zIEHHmj69OkT6fFLMgQtV1944YVmp512MksttZQTottvv7254oorzHvvvRe5zJqkjTyvrZaSplUTlo/PVx8Ts88+eybkSt8Vtby+2GKLZaq7WQpHpebSCsLIkSObZZiMAwJeCSA6veKlcghMSEBLcVHxnDrLWeJP4vLuu+8uFJ3Erk5CWm+99cy2225rlCS8XvIPRr3QJZY5MvSPlD7VYi6jTr4af4LpYyPssAJd0+qbiCqcFlxwwdDfpOJh6+W3UuhDg8YgkIIAojMFNIpAIC0BvZySpLFJ207acjo+8c477zS7776784JGnXeetv405eSZDbPVV189TXVNWSYq3lCD/fbbb2uOOSrkQwXnmWeemuVb4QKFpYSZRGdUPGwrcGGMEEhCANGZhBbXQiAjAW38aQTTUusHH3xgunXr5o4/vO2220wQBKV0PeokoimnnLKU/tRjo9U8ndUEZWUs1URTq55E1PY+6zjMySeffKLbL0+yVikwCECgNgFEZ21GXAGB3AhUO1knSSMSGRKDimnUX4cOHYzO4damj8qfNhVpN7z+XUuDivubbrrpkjTjrlWux2222casueaa5tVXX01cPmuBKNFJTtO/yGZdXh8zZkzkbYo6ZjPrfW208kodFWVR8bCNNkb6CwHfBCax3oty3Be+R0b9EKhDAto1rk08cU0vOqUFqiSnnmuuuVy+QJ1CIwGpjUb6CWunu87H1i7byk9a57h/8cUXZuzYse5PaXGUaF274bUrXmJOaZWiYvnC+iih26NHD3PAAQe4DUhFmHboh3mIDzroIHP22WcX0YW6b0NHXuo4zLB7edVVV5lddtklcgyKM1Y4xTXXXBN6Da+IP7DIG6wE8fottTVtyquHUJS6n6h0sOUJIDpbfgoAoEgCDz/8sDn00EMjUxUtssgiZtVVV3XxlO3bt3ceSgk9xZPl6XGqxKFJfA4cOND93X777bFRSDyff/75sa9Pe6H6GbW8e8YZZ7id/pgxTz75pMt4ECY6L730UrPnnntGYpKY0ga2e++9d6Jr5N3WRwpmXC5O5UQNy8kpfjfccAOYIACBGgRY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88+HEojK+5gFV9euXSOLX3rppVmqboiy8r4NHDgwsq9p8nO2rWzbbbc1ig0NsxNOOKEhOGXp5MiRI43ihMNMWQGI58xCl7KtTADR2cp3n7FDIAcCDz30UGQtG264YQ4tTFiFPJ0rrLBCaL3HHnts5BnZuXekpAovueSSyEwB119/fS69UsaBqFjct99+O/LozVwar4NKbrvtNvPWW2+F9kRcllhiiTroJV2AQOMRQHQ23j2jxxCoGwJKCH/ZZZeF9kd5DKvlfUw7CHmaonJ2qs5rr702bdV1X07hA1dccUVoP7W7Pyr0IM3A9t1339BiWmJv5vRJOu7z1ltvjUTWq1evNDgpAwEIWAKITqYBBCCQmkC/fv0ik8LvvvvuRnkffdhWW21l5pprrtCq+/btG9knH30pss4zzjgj8sjPXXfd1Uw//fS5dUcCVru0w0yiTKcUNaPJcx+VCUGbhzhvvRnvOmMqigCisyjStAOBJiSw9dZbR46qWuxlVhR68c8333yh1SiX5Omnn561iborLy/nmWeeGdqvGWaYweyxxx6597lHjx6hdX7++edNyViD7dmzZyTH3r17586YCiHQSgQQna10txkrBHIkUE3YKYfh6quvnmNrE1d11VVXRdavM8mVy7KZLEoAaowS+Ep1lLftueeekVUqjOGll17Ku8lS61PoglIlhVn79u0dZwwCEEhPANGZnh0lIdCyBD777DMTdSKOoGhp1vcRgdrMoZyUYfb++++b888/v2nuz1133WWicmTOPPPMRvGXiqHN2yabbDJzwQUXRFabNT1T3v3NUp88yccdd1xkFfKAkiYpC2HKQoCYTuYABCCQgoBOaolKCK8cjz5SJYV1s5q3U3kWX3755RSjq68iP/zwg1EspzZthZkSuWc5gajWaLfZZpvIDWHPPfdc1Y+PWnXX078fcsghRmEDYbbiiiuaqONB62kM9AUC9U4AT2e93yH6B4E6I/Dqq69W3SF+6KGHmllmmaWQXmtjR7Ul4FVXXbWQfvhsRGEMgwcPjmzCd5yhkvvvtttuke2feuqpDb/Mfsstt5ioIz7l7ZUgLWpO+5xL1A2BsglMElgruxO0DwEINAYBpctRYmx5uMJs7rnnNsOHDy90MPK4Kn5US+phtv/++zesN+6JJ54w//znPyN59unTxxx22GHeees10blzZ/Pggw+G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3YwaNcqMHTs2Vk1PPPGEOfTQQ82aa65ppppqKjPJJJOYaaed1qy++urm4IMPNs8995xRnUXaL7/8Yl544QVzxhlnmPXXX9/MOeecrl/669Spk9l9993NXXfdZcaMGVNkt/5s67vvvjP33nuv6datm1lwwQX/7Ntiiy1m9t57b3PfffeZ0aNH59q3zz77zNxwww1mp512MksuuaSZbLLJXLszzTST2XjjjU2fPn3MO++8k2ubVJaOwMiRI83NN99sdtllF7P00kv/OT9mnXVWs9FGG5mLL77YfPzxx+kqT1Dqm2++MVdeeaXZcsstzTzzzDPBPN1xxx1N3759zYgRIxLUWM6lr776qunVq5fp2rWrEcPKs2ChhRZyv8GHHnrIfP/996V07rfffjMDBw40Bx10kFl++eX/7Nvss89u1ltvPXPqqaead999t5S+pW30008/Nddee63ZddddzQorrPDnmGaeeWb3PD7nnHPcmIIgSNtEpnKaD8ccc4z55z//aSaffHLXP82Lzp07u+egL976rVx66aXmX//6l5ltttn+5LLOOuuYo48+2jz99NNm3LhxmcbWtvCbb77p5v7mm29u5p9//gmeJeuuu6457rjjzLPPPpt7u0kG8euvv5pnnnnG/QZWXnnlP/s433zzud/s1VdfbT755JMkVRZ7rZ3ITWNnnnlmcMcddxQ6njfeeCOwYjH4+eefQ9v98ccfg6eeeir473//G1ihGdgXYGAfMqHX2h9vcOyxxwZrrLFGcMoppwSq25fZiRs8//zzwQknnBCsvfbaQY8ePQL7Ywptzr5MgzvvvDPYYIMN3Fg1nh9++CFz16wQCOwPPLKet99+Ozj77LMD+xIPbrnllsCK3omuHT58eHDJJZcE9oUT7Lfffpn6ZX+owXXXXRfYB06w2Wabubn01VdfTdSmffEFL730UnDIIYcEVoAGVpwGH374YWYecSt47LHHAvvACazQjlsk8XX2w8fd78svvzxx2SQF7EM+2GGHHQIrYpIUC6zQDG677bZg6623DuyDN7jsssuCzz//fKI67MdgcPvtt7v5se2227q5m6fp920/eoJ99tnH1T9gwIDAfsRN1MTXX3/t5vByyy0XbLjhhoEVGaFzK8++JalL81nPT7Hceeedg0cffTT46aefJqpCzy49M/SM0n8/+uijJM2EXitm+osy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 -------------------------------------------------------------------------------- /playground/img/any_logo.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnyChart/Node.js-Report-Server/109fc24d62a3ba6dd0dd2771bb69cea98dd9e79c/playground/img/any_logo.img -------------------------------------------------------------------------------- /playground/js/html5shiv.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); -------------------------------------------------------------------------------- /playground/js/index.js: -------------------------------------------------------------------------------- 1 | var loadedFiles = {}; 2 | var pathToConfigs = 'configs/'; 3 | var showPreload = false; 4 | var lastSelectedType = 'png'; 5 | 6 | var img500, jsonSchema, xmlSchema; 7 | $.get('img/500.img', function(data) { 8 | img500 = data; 9 | }); 10 | 11 | $.get('https://cdn.anychart.com/releases/8.0.0/json-schema.json', function(data) { 12 | jsonSchema = data; 13 | }); 14 | 15 | $.get({url: 'https://cdn.anychart.com/releases/8.0.0/xml-schema.xsd'}, function(data) { 16 | xmlSchema = data; 17 | }); 18 | 19 | function showPreloader() { 20 | if (showPreload) { 21 | $('#output').append('<div id="loader-wrapper" class="anychart-loader"><div class="rotating-cover"><div class="rotating-plane"><div class="chart-row"><span class="chart-col green"></span><span class="chart-col orange"></span><span class="chart-col red"></span></div></div></div></div>'); 22 | $('#refresh, #outputType, #save').attr('disabled', 'disabled'); 23 | 24 | $('#tabs li').addClass('disabled'); 25 | $('#tabs li a').removeAttr('data-toggle'); 26 | } 27 | } 28 | 29 | function hidePreloader() { 30 | $('#loader-wrapper').remove(); 31 | showPreload = false; 32 | $('#refresh, #outputType, #save').attr('disabled', false); 33 | 34 | $('#tabs li').removeClass('disabled'); 35 | $('#tabs li a').attr('data-toggle', 'tab'); 36 | } 37 | 38 | function parseReport(data) { 39 | var regex = /chart"*:\s*{\s*\n*\s*"*data"*:\s*"*(.*[^",])"*[,\n]\s*\n*\s*"*dataType"*:\s*"*(.*[^",])"*[,\n]/g; 40 | var res; 41 | while(res = regex.exec(data)) { 42 | var chartData = res[1]; 43 | var dataType = res[2]; 44 | 45 | $.ajax({ 46 | url: pathToConfigs + chartData, 47 | async: false, 48 | dataType: 'text', 49 | success: function(new_data) { 50 | var newStr = dataType === 'json' ? new_data : new_data.replace(/\n/g, ''); 51 | var oldStr = dataType === 'json' ? new RegExp('"*' + chartData + '"*') : chartData; 52 | data = data.replace(oldStr, newStr); 53 | } 54 | }); 55 | } 56 | 57 | return data; 58 | } 59 | 60 | function getParams() { 61 | var controlID = $('#tabs').find('li.active a').attr('aria-controls'); 62 | var tab = $('#' + controlID); 63 | var container = $('#' + controlID + ' div:first'); 64 | var id = tab.attr('id'); 65 | var fileName, mode, data_type; 66 | var url, contentType; 67 | var file_type = $('#outputType').val(); 68 | 69 | switch (id) { 70 | case 'report': 71 | fileName = 'report.js'; 72 | mode = 'ace/mode/javascript'; 73 | file_type = 'pdf'; 74 | data_type = 'report'; 75 | break; 76 | case 'json': 77 | fileName = 'json.json'; 78 | mode = 'ace/mode/json'; 79 | data_type = 'json'; 80 | break; 81 | case 'xml': 82 | fileName = 'xml.xml'; 83 | mode = 'ace/mode/xml'; 84 | data_type = 'xml'; 85 | break; 86 | case 'js': 87 | fileName = 'js.js'; 88 | mode = 'ace/mode/javascript'; 89 | data_type = 'javascript'; 90 | break; 91 | case 'svg': 92 | fileName = 'svg.svg'; 93 | mode = 'ace/mode/svg'; 94 | data_type = 'svg'; 95 | break; 96 | } 97 | 98 | switch (file_type) { 99 | case 'png': 100 | url = '/raster-image'; 101 | contentType = 'image/png'; 102 | break; 103 | case 'jpg': 104 | url = '/raster-image'; 105 | contentType = 'image/jpg'; 106 | break; 107 | case 'tiff': 108 | url = '/raster-image'; 109 | contentType = 'image/tiff'; 110 | break; 111 | case 'pdf': 112 | url = '/vector-image'; 113 | contentType = 'application/pdf'; 114 | break; 115 | case 'svg': 116 | url = '/vector-image'; 117 | contentType = 'image/svf+xm'; 118 | break; 119 | case 'ps': 120 | url = '/vector-image'; 121 | contentType = 'application/postscript'; 122 | break; 123 | } 124 | 125 | if (data_type === 'report') { 126 | url = '/pdf-report'; 127 | } 128 | 129 | return { 130 | mode: mode, 131 | container: container, 132 | fileName: pathToConfigs + fileName, 133 | data_type: data_type, 134 | file_type: file_type, 135 | contentType: contentType, 136 | url: url 137 | } 138 | } 139 | 140 | function generate() { 141 | var params = getParams(); 142 | var mode = params.mode; 143 | var container = params.container; 144 | var fileName = params.fileName; 145 | var data_type = params.data_type; 146 | var file_type = params.file_type; 147 | var contentType = params.contentType; 148 | var url = params.url; 149 | var responseType = 'base64'; 150 | 151 | if (!loadedFiles[fileName]) { 152 | $.ajax({ 153 | url: '/' + fileName, 154 | dataType: 'text', 155 | async: false, 156 | success: function(data) { 157 | var editor = ace.edit(container.attr('id')); 158 | editor.setShowPrintMargin(false); 159 | var session = editor.getSession(); 160 | session.setMode(mode); 161 | session.setValue(data); 162 | 163 | loadedFiles[fileName] = { 164 | editor: editor 165 | }; 166 | convert(data, data_type, file_type, contentType, responseType, url); 167 | } 168 | }); 169 | } else { 170 | var editorSession = loadedFiles[fileName].editor.getSession(); 171 | convert(editorSession.getValue(), data_type, file_type, contentType, responseType, url); 172 | } 173 | } 174 | 175 | function generateAvailableOutputTypes() { 176 | var params = getParams(); 177 | var data_type = params.data_type; 178 | 179 | var types; 180 | switch (data_type) { 181 | case 'report': 182 | types = ['pdf']; 183 | break; 184 | case 'json': 185 | case 'xml': 186 | case 'javascript': 187 | case 'svg': 188 | types = ['png', 'jpg', 'pdf', 'svg', 'ps']; 189 | break; 190 | } 191 | var outputTypeControl = $('#outputType'); 192 | var value = lastSelectedType || outputTypeControl.val(); 193 | outputTypeControl.html(''); 194 | $(types).each(function(index, elem) { 195 | var option = $('<option>' + elem + '</option>'); 196 | option.attr('value', elem); 197 | outputTypeControl.append(option); 198 | }); 199 | if (outputTypeControl.find('option[value=' + value + ']').length !== 0) 200 | outputTypeControl.val(value) 201 | } 202 | 203 | function saveFile() { 204 | var params = getParams(); 205 | var data_type = params.data_type; 206 | var file_type = params.file_type; 207 | var fileName = params.fileName; 208 | var responseType = params.responseType; 209 | var url = params.url; 210 | var editorSession = loadedFiles[fileName].editor.getSession(); 211 | 212 | var data = editorSession.getValue(); 213 | if (data_type === 'report') { 214 | data = parseReport(data); 215 | } 216 | 217 | var form = $('<form></form>'); 218 | form.attr({ 219 | method: 'post', 220 | action: url 221 | }); 222 | var dataTypeInput = $('<input/>'); 223 | dataTypeInput.appendTo(form); 224 | dataTypeInput.attr({ 225 | type: 'hidden', 226 | name: 'data_type', 227 | value: data_type 228 | }); 229 | var fileTypeInput = $('<input/>'); 230 | fileTypeInput.appendTo(form); 231 | fileTypeInput.attr({ 232 | type: 'hidden', 233 | name: 'file_type', 234 | value: file_type 235 | }); 236 | var responseTypeInput = $('<input/>'); 237 | responseTypeInput.appendTo(form); 238 | responseTypeInput.attr({ 239 | type: 'hidden', 240 | name: 'response_type', 241 | value: responseType 242 | }); 243 | var dataInput = $('<input/>'); 244 | dataInput.appendTo(form); 245 | dataInput.attr({ 246 | type: 'hidden', 247 | name: 'data', 248 | value: data 249 | }); 250 | form.appendTo('body'); 251 | form.submit(); 252 | form.remove(); 253 | } 254 | 255 | function showContent(contentType, resData) { 256 | if (contentType === 'application/pdf' || contentType === 'image/tiff') { 257 | $('#viewpdf').attr("src", 'data:' + contentType + ';base64,' + resData.data); 258 | $('#viewpdf').attr("type", contentType); 259 | 260 | $('#viewimage').css('display', 'none'); 261 | $('#viewsvg').css('display', 'none'); 262 | $('#viewpdf').css('display', 'inline-block'); 263 | } else if (contentType === 'image/svf+xm') { 264 | $('#viewimage').attr("src", 'data:image/svg+xml;base64,' + resData.data); 265 | 266 | $('#viewimage').css('display', 'inline-block'); 267 | $('#viewpdf').css('display', 'none'); 268 | $('#viewsvg').css('display', 'none'); 269 | } else { 270 | $('#viewimage').attr("src", 'data:' + contentType + ';base64,' + resData.data); 271 | 272 | $('#viewimage').css('display', 'inline-block'); 273 | $('#viewpdf').css('display', 'none'); 274 | $('#viewsvg').css('display', 'none'); 275 | } 276 | } 277 | 278 | function convert(data, data_type, file_type, contentType, responseType, url) { 279 | if (showPreload) 280 | return; 281 | 282 | if (data_type === 'report') { 283 | data = parseReport(data); 284 | } 285 | 286 | if (file_type === 'ps') { 287 | file_type = 'png'; 288 | } 289 | 290 | var isValid = true, valid = ''; 291 | if (data_type == 'json') { 292 | try { 293 | var json = JSON.parse(data); 294 | valid = tv4.validateResult(json, jsonSchema); 295 | isValid = valid.valid; 296 | } catch (e) { 297 | valid = e; 298 | isValid = false; 299 | } 300 | } else if (data_type == 'xml') { 301 | var Module = { 302 | xml: data, 303 | schema: xmlSchema, 304 | arguments: ["--noout", "--schema", 'schema', 'xml'] 305 | }; 306 | 307 | valid = validateXML(Module); 308 | isValid = valid === 'xml validates\n'; 309 | } 310 | 311 | if (isValid) { 312 | $.ajax({ 313 | method: 'POST', 314 | dataType: 'json', 315 | url: url, 316 | data: { 317 | data_type: data_type, 318 | file_type: file_type, 319 | response_type: responseType, 320 | data: data, 321 | resources: [ 322 | // 'https://code.jquery.com/jquery-latest.min.js', 323 | // 'https://cdn.anychart.com/geodata/1.2.0/countries/canada/canada.js', 324 | // 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', 325 | // 'https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15/proj4.js' 326 | // "https://cdn.anychart.com/fonts/interdex/interdex.css" 327 | ] 328 | }, 329 | beforeSend: function() { 330 | showPreload = true; 331 | setTimeout(showPreloader, 20); 332 | } 333 | }).done(function(resData) { 334 | showContent(contentType, resData); 335 | 336 | hidePreloader(); 337 | }).fail(function(e) { 338 | $('#viewimage').attr("src", img500); 339 | $('#viewimage').css('display', 'inline-block'); 340 | $('#viewpdf').css('display', 'none'); 341 | $('#viewsvg').css('display', 'none'); 342 | console.log(e.responseJSON.error); 343 | hidePreloader(); 344 | }); 345 | } else { 346 | $('#viewimage').css('display', 'none'); 347 | $('#viewpdf').css('display', 'none'); 348 | $('#viewsvg').css('display', 'inline-block'); 349 | $('#viewsvg').html('<div class="panel panel-warning" style="margin: 15px"><div class="panel-heading">Invalid ' + data_type + ' config</div><div class="panel-body"><samp>' + valid + '</samp></div></div>'); 350 | } 351 | } 352 | 353 | $(document).ready(function() { 354 | generateAvailableOutputTypes(); 355 | generate(); 356 | 357 | $('#tabs').find('a').click(function (e) { 358 | if (!showPreload) { 359 | e.preventDefault(); 360 | $(this).tab('show'); 361 | 362 | generateAvailableOutputTypes(); 363 | generate(); 364 | } 365 | }); 366 | 367 | $('#save').click(function() { 368 | saveFile(); 369 | }); 370 | 371 | $('#refresh').click(function() { 372 | generate(); 373 | }); 374 | 375 | $('#outputType').on('change', function() { 376 | lastSelectedType = $(this).val(); 377 | generate(); 378 | }); 379 | 380 | $(window).resize(function() { 381 | resize(); 382 | }); 383 | 384 | $('#viewimage').on('load', function(e) { 385 | resize(); 386 | }); 387 | 388 | resize(); 389 | }); 390 | 391 | function resize() { 392 | var offsetContent = $('#tab-panes').offset(); 393 | var docHeight = $(window).height(); 394 | var offset = 130; 395 | 396 | var output = $('#output'); 397 | var viewImage = $('#viewimage'); 398 | 399 | $('#content, #json_data, #xml_data, #js_data, #svg_data').height(docHeight - offsetContent.top - offset); 400 | $('#tab-panes').height(docHeight - offsetContent.top - offset); 401 | $('#source').height(docHeight - offsetContent.top - offset + 42); 402 | output.height(docHeight - offsetContent.top - offset); 403 | 404 | if (viewImage.height() && viewImage.width()) { 405 | if (viewImage.height() / output.height() > viewImage.width() / output.width()) { 406 | viewImage.css({width: 'auto', height: '100%'}); 407 | } else { 408 | viewImage.css({width: '100%', height: 'auto'}); 409 | } 410 | } 411 | } 412 | -------------------------------------------------------------------------------- /playground/js/respond.min.js: -------------------------------------------------------------------------------- 1 | /*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl 2 | * Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT 3 | * */ 4 | 5 | !function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='­<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b<s.length;b++){var c=s[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!o[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(v(c.styleSheet.rawCssText,e,f),o[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!r||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}w()};x(),c.update=x,c.getEmValue=t,a.addEventListener?a.addEventListener("resize",b,!1):a.attachEvent&&a.attachEvent("onresize",b)}}(this); -------------------------------------------------------------------------------- /playground/js/tv4.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define([],r):"undefined"!=typeof module&&module.exports?module.exports=r():e.tv4=r()}(this,function(){function e(e){return encodeURI(e).replace(/%25[0-9][0-9]/g,function(e){return"%"+e.substring(3)})}function r(r){var t="";p[r.charAt(0)]&&(t=r.charAt(0),r=r.substring(1));var i="",n="",a=!0,o=!1,s=!1;"+"===t?a=!1:"."===t?(n=".",i="."):"/"===t?(n="/",i="/"):"#"===t?(n="#",a=!1):";"===t?(n=";",i=";",o=!0,s=!0):"?"===t?(n="?",i="&",o=!0):"&"===t&&(n="&",i="&",o=!0);for(var l=[],h=r.split(","),u=[],f={},d=0;d<h.length;d++){var m=h[d],v=null;if(m.indexOf(":")!==-1){var y=m.split(":");m=y[0],v=parseInt(y[1],10)}for(var g={};c[m.charAt(m.length-1)];)g[m.charAt(m.length-1)]=!0,m=m.substring(0,m.length-1);var E={truncate:v,name:m,suffices:g};u.push(E),f[m]=E,l.push(m)}var O=function(r){for(var t="",l=0,h=0;h<u.length;h++){var f=u[h],p=r(f.name);if(null===p||void 0===p||Array.isArray(p)&&0===p.length||"object"==typeof p&&0===Object.keys(p).length)l++;else if(t+=h===l?n:i||",",Array.isArray(p)){o&&(t+=f.name+"=");for(var c=0;c<p.length;c++)c>0&&(t+=f.suffices["*"]?i||",":",",f.suffices["*"]&&o&&(t+=f.name+"=")),t+=a?encodeURIComponent(p[c]).replace(/!/g,"%21"):e(p[c])}else if("object"==typeof p){o&&!f.suffices["*"]&&(t+=f.name+"=");var d=!0;for(var m in p)d||(t+=f.suffices["*"]?i||",":","),d=!1,t+=a?encodeURIComponent(m).replace(/!/g,"%21"):e(m),t+=f.suffices["*"]?"=":",",t+=a?encodeURIComponent(p[m]).replace(/!/g,"%21"):e(p[m])}else o&&(t+=f.name,s&&""===p||(t+="=")),null!=f.truncate&&(p=p.substring(0,f.truncate)),t+=a?encodeURIComponent(p).replace(/!/g,"%21"):e(p)}return t};return O.varNames=l,{prefix:n,substitution:O}}function t(e){if(!(this instanceof t))return new t(e);for(var i=e.split("{"),n=[i.shift()],a=[],o=[],s=[];i.length>0;){var l=i.shift(),h=l.split("}")[0],u=l.substring(h.length+1),f=r(h);o.push(f.substitution),a.push(f.prefix),n.push(u),s=s.concat(f.substitution.varNames)}this.fill=function(e){for(var r=n[0],t=0;t<o.length;t++){var i=o[t];r+=i(e),r+=n[t+1]}return r},this.varNames=s,this.template=e}function i(e,r){if(e===r)return!0;if(e&&r&&"object"==typeof e&&"object"==typeof r){if(Array.isArray(e)!==Array.isArray(r))return!1;if(Array.isArray(e)){if(e.length!==r.length)return!1;for(var t=0;t<e.length;t++)if(!i(e[t],r[t]))return!1}else{var n;for(n in e)if(void 0===r[n]&&void 0!==e[n])return!1;for(n in r)if(void 0===e[n]&&void 0!==r[n])return!1;for(n in e)if(!i(e[n],r[n]))return!1}return!0}return!1}function n(e){var r=String(e).replace(/^\s+|\s+$/g,"").match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);return r?{href:r[0]||"",protocol:r[1]||"",authority:r[2]||"",host:r[3]||"",hostname:r[4]||"",port:r[5]||"",pathname:r[6]||"",search:r[7]||"",hash:r[8]||""}:null}function a(e,r){function t(e){var r=[];return e.replace(/^(\.\.?(\/|$))+/,"").replace(/\/(\.(\/|$))+/g,"/").replace(/\/\.\.$/,"/../").replace(/\/?[^\/]*/g,function(e){"/.."===e?r.pop():r.push(e)}),r.join("").replace(/^\//,"/"===e.charAt(0)?"/":"")}return r=n(r||""),e=n(e||""),r&&e?(r.protocol||e.protocol)+(r.protocol||r.authority?r.authority:e.authority)+t(r.protocol||r.authority||"/"===r.pathname.charAt(0)?r.pathname:r.pathname?(e.authority&&!e.pathname?"/":"")+e.pathname.slice(0,e.pathname.lastIndexOf("/")+1)+r.pathname:e.pathname)+(r.protocol||r.authority||r.pathname?r.search:r.search||e.search)+r.hash:null}function o(e){return e.split("#")[0]}function s(e,r){if(e&&"object"==typeof e)if(void 0===r?r=e.id:"string"==typeof e.id&&(r=a(r,e.id),e.id=r),Array.isArray(e))for(var t=0;t<e.length;t++)s(e[t],r);else{"string"==typeof e.$ref&&(e.$ref=a(r,e.$ref));for(var i in e)"enum"!==i&&s(e[i],r)}}function l(e){e=e||"en";var r=P[e];return function(e){var t=r[e.code]||O[e.code];if("string"!=typeof t)return"Unknown error code "+e.code+": "+JSON.stringify(e.messageParams);var i=e.params;return t.replace(/\{([^{}]*)\}/g,function(e,r){var t=i[r];return"string"==typeof t||"number"==typeof t?t:e})}}function h(e,r,t,i,n){if(Error.call(this),void 0===e)throw new Error("No error code supplied: "+i);this.message="",this.params=r,this.code=e,this.dataPath=t||"",this.schemaPath=i||"",this.subErrors=n||null;var a=new Error(this.message);if(this.stack=a.stack||a.stacktrace,!this.stack)try{throw a}catch(e){this.stack=e.stack||e.stacktrace}}function u(e,r){if(r.substring(0,e.length)===e){var t=r.substring(e.length);if(r.length>0&&"/"===r.charAt(e.length-1)||"#"===t.charAt(0)||"?"===t.charAt(0))return!0}return!1}function f(e){var r,t,i=new d,n={setErrorReporter:function(e){return"string"==typeof e?this.language(e):(t=e,!0)},addFormat:function(){i.addFormat.apply(i,arguments)},language:function(e){return e?(P[e]||(e=e.split("-")[0]),!!P[e]&&(r=e,e)):r},addLanguage:function(e,r){var t;for(t in y)r[t]&&!r[y[t]]&&(r[y[t]]=r[t]);var i=e.split("-")[0];if(P[i]){P[e]=Object.create(P[i]);for(t in r)"undefined"==typeof P[i][t]&&(P[i][t]=r[t]),P[e][t]=r[t]}else P[e]=r,P[i]=r;return this},freshApi:function(e){var r=f();return e&&r.language(e),r},validate:function(e,n,a,o){var s=l(r),h=t?function(e,r,i){return t(e,r,i)||s(e,r,i)}:s,u=new d(i,!1,h,a,o);"string"==typeof n&&(n={$ref:n}),u.addSchema("",n);var f=u.validateAll(e,n,null,null,"");return!f&&o&&(f=u.banUnknownProperties(e,n)),this.error=f,this.missing=u.missing,this.valid=null===f,this.valid},validateResult:function(){var e={toString:function(){return this.valid?"valid":this.error.message}};return this.validate.apply(e,arguments),e},validateMultiple:function(e,n,a,o){var s=l(r),h=t?function(e,r,i){return t(e,r,i)||s(e,r,i)}:s,u=new d(i,!0,h,a,o);"string"==typeof n&&(n={$ref:n}),u.addSchema("",n),u.validateAll(e,n,null,null,""),o&&u.banUnknownProperties(e,n);var f={toString:function(){return this.valid?"valid":this.error.message}};return f.errors=u.errors,f.missing=u.missing,f.valid=0===f.errors.length,f},addSchema:function(){return i.addSchema.apply(i,arguments)},getSchema:function(){return i.getSchema.apply(i,arguments)},getSchemaMap:function(){return i.getSchemaMap.apply(i,arguments)},getSchemaUris:function(){return i.getSchemaUris.apply(i,arguments)},getMissingUris:function(){return i.getMissingUris.apply(i,arguments)},dropSchemas:function(){i.dropSchemas.apply(i,arguments)},defineKeyword:function(){i.defineKeyword.apply(i,arguments)},defineError:function(e,r,t){if("string"!=typeof e||!/^[A-Z]+(_[A-Z]+)*$/.test(e))throw new Error("Code name must be a string in UPPER_CASE_WITH_UNDERSCORES");if("number"!=typeof r||r%1!==0||r<1e4)throw new Error("Code number must be an integer > 10000");if("undefined"!=typeof y[e])throw new Error("Error already defined: "+e+" as "+y[e]);if("undefined"!=typeof g[r])throw new Error("Error code already used: "+g[r]+" as "+r);y[e]=r,g[r]=e,O[e]=O[r]=t;for(var i in P){var n=P[i];n[e]&&(n[r]=n[r]||n[e])}},reset:function(){i.reset(),this.error=null,this.missing=[],this.valid=!0},missing:[],error:null,valid:!0,normSchema:s,resolveUrl:a,getDocumentUri:o,errorCodes:y};return n.language(e||"en"),n}Object.keys||(Object.keys=function(){var e=Object.prototype.hasOwnProperty,r=!{toString:null}.propertyIsEnumerable("toString"),t=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],i=t.length;return function(n){if("object"!=typeof n&&"function"!=typeof n||null===n)throw new TypeError("Object.keys called on non-object");var a=[];for(var o in n)e.call(n,o)&&a.push(o);if(r)for(var s=0;s<i;s++)e.call(n,t[s])&&a.push(t[s]);return a}}()),Object.create||(Object.create=function(){function e(){}return function(r){if(1!==arguments.length)throw new Error("Object.create implementation only accepts one parameter.");return e.prototype=r,new e}}()),Array.isArray||(Array.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),Array.prototype.indexOf||(Array.prototype.indexOf=function(e){if(null===this)throw new TypeError;var r=Object(this),t=r.length>>>0;if(0===t)return-1;var i=0;if(arguments.length>1&&(i=Number(arguments[1]),i!==i?i=0:0!==i&&i!==1/0&&i!==-(1/0)&&(i=(i>0||-1)*Math.floor(Math.abs(i)))),i>=t)return-1;for(var n=i>=0?i:Math.max(t-Math.abs(i),0);n<t;n++)if(n in r&&r[n]===e)return n;return-1}),Object.isFrozen||(Object.isFrozen=function(e){for(var r="tv4_test_frozen_key";e.hasOwnProperty(r);)r+=Math.random();try{return e[r]=!0,delete e[r],!1}catch(e){return!0}});var p={"+":!0,"#":!0,".":!0,"/":!0,";":!0,"?":!0,"&":!0},c={"*":!0};t.prototype={toString:function(){return this.template},fillFromObject:function(e){return this.fill(function(r){return e[r]})}};var d=function(e,r,t,i,n){if(this.missing=[],this.missingMap={},this.formatValidators=e?Object.create(e.formatValidators):{},this.schemas=e?Object.create(e.schemas):{},this.collectMultiple=r,this.errors=[],this.handleError=r?this.collectError:this.returnError,i&&(this.checkRecursive=!0,this.scanned=[],this.scannedFrozen=[],this.scannedFrozenSchemas=[],this.scannedFrozenValidationErrors=[],this.validatedSchemasKey="tv4_validation_id",this.validationErrorsKey="tv4_validation_errors_id"),n&&(this.trackUnknownProperties=!0,this.knownPropertyPaths={},this.unknownPropertyPaths={}),this.errorReporter=t||l("en"),"string"==typeof this.errorReporter)throw new Error("debug");if(this.definedKeywords={},e)for(var a in e.definedKeywords)this.definedKeywords[a]=e.definedKeywords[a].slice(0)};d.prototype.defineKeyword=function(e,r){this.definedKeywords[e]=this.definedKeywords[e]||[],this.definedKeywords[e].push(r)},d.prototype.createError=function(e,r,t,i,n,a,o){var s=new h(e,r,t,i,n);return s.message=this.errorReporter(s,a,o),s},d.prototype.returnError=function(e){return e},d.prototype.collectError=function(e){return e&&this.errors.push(e),null},d.prototype.prefixErrors=function(e,r,t){for(var i=e;i<this.errors.length;i++)this.errors[i]=this.errors[i].prefixWith(r,t);return this},d.prototype.banUnknownProperties=function(e,r){for(var t in this.unknownPropertyPaths){var i=this.createError(y.UNKNOWN_PROPERTY,{path:t},t,"",null,e,r),n=this.handleError(i);if(n)return n}return null},d.prototype.addFormat=function(e,r){if("object"==typeof e){for(var t in e)this.addFormat(t,e[t]);return this}this.formatValidators[e]=r},d.prototype.resolveRefs=function(e,r){if(void 0!==e.$ref){if(r=r||{},r[e.$ref])return this.createError(y.CIRCULAR_REFERENCE,{urls:Object.keys(r).join(", ")},"","",null,void 0,e);r[e.$ref]=!0,e=this.getSchema(e.$ref,r)}return e},d.prototype.getSchema=function(e,r){var t;if(void 0!==this.schemas[e])return t=this.schemas[e],this.resolveRefs(t,r);var i=e,n="";if(e.indexOf("#")!==-1&&(n=e.substring(e.indexOf("#")+1),i=e.substring(0,e.indexOf("#"))),"object"==typeof this.schemas[i]){t=this.schemas[i];var a=decodeURIComponent(n);if(""===a)return this.resolveRefs(t,r);if("/"!==a.charAt(0))return;for(var o=a.split("/").slice(1),s=0;s<o.length;s++){var l=o[s].replace(/~1/g,"/").replace(/~0/g,"~");if(void 0===t[l]){t=void 0;break}t=t[l]}if(void 0!==t)return this.resolveRefs(t,r)}void 0===this.missing[i]&&(this.missing.push(i),this.missing[i]=i,this.missingMap[i]=i)},d.prototype.searchSchemas=function(e,r){if(Array.isArray(e))for(var t=0;t<e.length;t++)this.searchSchemas(e[t],r);else if(e&&"object"==typeof e){"string"==typeof e.id&&u(r,e.id)&&void 0===this.schemas[e.id]&&(this.schemas[e.id]=e);for(var i in e)if("enum"!==i)if("object"==typeof e[i])this.searchSchemas(e[i],r);else if("$ref"===i){var n=o(e[i]);n&&void 0===this.schemas[n]&&void 0===this.missingMap[n]&&(this.missingMap[n]=n)}}},d.prototype.addSchema=function(e,r){if("string"!=typeof e||"undefined"==typeof r){if("object"!=typeof e||"string"!=typeof e.id)return;r=e,e=r.id}e===o(e)+"#"&&(e=o(e)),this.schemas[e]=r,delete this.missingMap[e],s(r,e),this.searchSchemas(r,e)},d.prototype.getSchemaMap=function(){var e={};for(var r in this.schemas)e[r]=this.schemas[r];return e},d.prototype.getSchemaUris=function(e){var r=[];for(var t in this.schemas)e&&!e.test(t)||r.push(t);return r},d.prototype.getMissingUris=function(e){var r=[];for(var t in this.missingMap)e&&!e.test(t)||r.push(t);return r},d.prototype.dropSchemas=function(){this.schemas={},this.reset()},d.prototype.reset=function(){this.missing=[],this.missingMap={},this.errors=[]},d.prototype.validateAll=function(e,r,t,i,n){var a;if(r=this.resolveRefs(r),!r)return null;if(r instanceof h)return this.errors.push(r),r;var o,s=this.errors.length,l=null,u=null;if(this.checkRecursive&&e&&"object"==typeof e){if(a=!this.scanned.length,e[this.validatedSchemasKey]){var f=e[this.validatedSchemasKey].indexOf(r);if(f!==-1)return this.errors=this.errors.concat(e[this.validationErrorsKey][f]),null}if(Object.isFrozen(e)&&(o=this.scannedFrozen.indexOf(e),o!==-1)){var p=this.scannedFrozenSchemas[o].indexOf(r);if(p!==-1)return this.errors=this.errors.concat(this.scannedFrozenValidationErrors[o][p]),null}if(this.scanned.push(e),Object.isFrozen(e))o===-1&&(o=this.scannedFrozen.length,this.scannedFrozen.push(e),this.scannedFrozenSchemas.push([])),l=this.scannedFrozenSchemas[o].length,this.scannedFrozenSchemas[o][l]=r,this.scannedFrozenValidationErrors[o][l]=[];else{if(!e[this.validatedSchemasKey])try{Object.defineProperty(e,this.validatedSchemasKey,{value:[],configurable:!0}),Object.defineProperty(e,this.validationErrorsKey,{value:[],configurable:!0})}catch(r){e[this.validatedSchemasKey]=[],e[this.validationErrorsKey]=[]}u=e[this.validatedSchemasKey].length,e[this.validatedSchemasKey][u]=r,e[this.validationErrorsKey][u]=[]}}var c=this.errors.length,d=this.validateBasic(e,r,n)||this.validateNumeric(e,r,n)||this.validateString(e,r,n)||this.validateArray(e,r,n)||this.validateObject(e,r,n)||this.validateCombinations(e,r,n)||this.validateHypermedia(e,r,n)||this.validateFormat(e,r,n)||this.validateDefinedKeywords(e,r,n)||null;if(a){for(;this.scanned.length;){var m=this.scanned.pop();delete m[this.validatedSchemasKey]}this.scannedFrozen=[],this.scannedFrozenSchemas=[]}if(d||c!==this.errors.length)for(;t&&t.length||i&&i.length;){var v=t&&t.length?""+t.pop():null,y=i&&i.length?""+i.pop():null;d&&(d=d.prefixWith(v,y)),this.prefixErrors(c,v,y)}return null!==l?this.scannedFrozenValidationErrors[o][l]=this.errors.slice(s):null!==u&&(e[this.validationErrorsKey][u]=this.errors.slice(s)),this.handleError(d)},d.prototype.validateFormat=function(e,r){if("string"!=typeof r.format||!this.formatValidators[r.format])return null;var t=this.formatValidators[r.format].call(null,e,r);return"string"==typeof t||"number"==typeof t?this.createError(y.FORMAT_CUSTOM,{message:t},"","/format",null,e,r):t&&"object"==typeof t?this.createError(y.FORMAT_CUSTOM,{message:t.message||"?"},t.dataPath||"",t.schemaPath||"/format",null,e,r):null},d.prototype.validateDefinedKeywords=function(e,r,t){for(var i in this.definedKeywords)if("undefined"!=typeof r[i])for(var n=this.definedKeywords[i],a=0;a<n.length;a++){var o=n[a],s=o(e,r[i],r,t);if("string"==typeof s||"number"==typeof s)return this.createError(y.KEYWORD_CUSTOM,{key:i,message:s},"","",null,e,r).prefixWith(null,i);if(s&&"object"==typeof s){var l=s.code;if("string"==typeof l){if(!y[l])throw new Error("Undefined error code (use defineError): "+l);l=y[l]}else"number"!=typeof l&&(l=y.KEYWORD_CUSTOM);var h="object"==typeof s.message?s.message:{key:i,message:s.message||"?"},u=s.schemaPath||"/"+i.replace(/~/g,"~0").replace(/\//g,"~1");return this.createError(l,h,s.dataPath||null,u,null,e,r)}}return null},d.prototype.validateBasic=function(e,r,t){var i;return(i=this.validateType(e,r,t))?i.prefixWith(null,"type"):(i=this.validateEnum(e,r,t))?i.prefixWith(null,"type"):null},d.prototype.validateType=function(e,r){if(void 0===r.type)return null;var t=typeof e;null===e?t="null":Array.isArray(e)&&(t="array");var i=r.type;Array.isArray(i)||(i=[i]);for(var n=0;n<i.length;n++){var a=i[n];if(a===t||"integer"===a&&"number"===t&&e%1===0)return null}return this.createError(y.INVALID_TYPE,{type:t,expected:i.join("/")},"","",null,e,r)},d.prototype.validateEnum=function(e,r){if(void 0===r.enum)return null;for(var t=0;t<r.enum.length;t++){var n=r.enum[t];if(i(e,n))return null}return this.createError(y.ENUM_MISMATCH,{value:"undefined"!=typeof JSON?JSON.stringify(e):e},"","",null,e,r)},d.prototype.validateNumeric=function(e,r,t){return this.validateMultipleOf(e,r,t)||this.validateMinMax(e,r,t)||this.validateNaN(e,r,t)||null};var m=Math.pow(2,-51),v=1-m;d.prototype.validateMultipleOf=function(e,r){var t=r.multipleOf||r.divisibleBy;if(void 0===t)return null;if("number"==typeof e){var i=e/t%1;if(i>=m&&i<v)return this.createError(y.NUMBER_MULTIPLE_OF,{value:e,multipleOf:t},"","",null,e,r)}return null},d.prototype.validateMinMax=function(e,r){if("number"!=typeof e)return null;if(void 0!==r.minimum){if(e<r.minimum)return this.createError(y.NUMBER_MINIMUM,{value:e,minimum:r.minimum},"","/minimum",null,e,r);if(r.exclusiveMinimum&&e===r.minimum)return this.createError(y.NUMBER_MINIMUM_EXCLUSIVE,{value:e,minimum:r.minimum},"","/exclusiveMinimum",null,e,r)}if(void 0!==r.maximum){if(e>r.maximum)return this.createError(y.NUMBER_MAXIMUM,{value:e,maximum:r.maximum},"","/maximum",null,e,r);if(r.exclusiveMaximum&&e===r.maximum)return this.createError(y.NUMBER_MAXIMUM_EXCLUSIVE,{value:e,maximum:r.maximum},"","/exclusiveMaximum",null,e,r)}return null},d.prototype.validateNaN=function(e,r){return"number"!=typeof e?null:isNaN(e)===!0||e===1/0||e===-(1/0)?this.createError(y.NUMBER_NOT_A_NUMBER,{value:e},"","/type",null,e,r):null},d.prototype.validateString=function(e,r,t){return this.validateStringLength(e,r,t)||this.validateStringPattern(e,r,t)||null},d.prototype.validateStringLength=function(e,r){return"string"!=typeof e?null:void 0!==r.minLength&&e.length<r.minLength?this.createError(y.STRING_LENGTH_SHORT,{length:e.length,minimum:r.minLength},"","/minLength",null,e,r):void 0!==r.maxLength&&e.length>r.maxLength?this.createError(y.STRING_LENGTH_LONG,{length:e.length,maximum:r.maxLength},"","/maxLength",null,e,r):null},d.prototype.validateStringPattern=function(e,r){if("string"!=typeof e||"string"!=typeof r.pattern&&!(r.pattern instanceof RegExp))return null;var t;if(r.pattern instanceof RegExp)t=r.pattern;else{var i,n="",a=r.pattern.match(/^\/(.+)\/([img]*)$/);a?(i=a[1],n=a[2]):i=r.pattern,t=new RegExp(i,n)}return t.test(e)?null:this.createError(y.STRING_PATTERN,{pattern:r.pattern},"","/pattern",null,e,r)},d.prototype.validateArray=function(e,r,t){return Array.isArray(e)?this.validateArrayLength(e,r,t)||this.validateArrayUniqueItems(e,r,t)||this.validateArrayItems(e,r,t)||null:null},d.prototype.validateArrayLength=function(e,r){var t;return void 0!==r.minItems&&e.length<r.minItems&&(t=this.createError(y.ARRAY_LENGTH_SHORT,{length:e.length,minimum:r.minItems},"","/minItems",null,e,r),this.handleError(t))?t:void 0!==r.maxItems&&e.length>r.maxItems&&(t=this.createError(y.ARRAY_LENGTH_LONG,{length:e.length,maximum:r.maxItems},"","/maxItems",null,e,r),this.handleError(t))?t:null},d.prototype.validateArrayUniqueItems=function(e,r){if(r.uniqueItems)for(var t=0;t<e.length;t++)for(var n=t+1;n<e.length;n++)if(i(e[t],e[n])){var a=this.createError(y.ARRAY_UNIQUE,{match1:t,match2:n},"","/uniqueItems",null,e,r);if(this.handleError(a))return a}return null},d.prototype.validateArrayItems=function(e,r,t){if(void 0===r.items)return null;var i,n;if(Array.isArray(r.items)){for(n=0;n<e.length;n++)if(n<r.items.length){if(i=this.validateAll(e[n],r.items[n],[n],["items",n],t+"/"+n))return i}else if(void 0!==r.additionalItems)if("boolean"==typeof r.additionalItems){if(!r.additionalItems&&(i=this.createError(y.ARRAY_ADDITIONAL_ITEMS,{},"/"+n,"/additionalItems",null,e,r),this.handleError(i)))return i}else if(i=this.validateAll(e[n],r.additionalItems,[n],["additionalItems"],t+"/"+n))return i}else for(n=0;n<e.length;n++)if(i=this.validateAll(e[n],r.items,[n],["items"],t+"/"+n))return i;return null},d.prototype.validateObject=function(e,r,t){return"object"!=typeof e||null===e||Array.isArray(e)?null:this.validateObjectMinMaxProperties(e,r,t)||this.validateObjectRequiredProperties(e,r,t)||this.validateObjectProperties(e,r,t)||this.validateObjectDependencies(e,r,t)||null},d.prototype.validateObjectMinMaxProperties=function(e,r){var t,i=Object.keys(e);return void 0!==r.minProperties&&i.length<r.minProperties&&(t=this.createError(y.OBJECT_PROPERTIES_MINIMUM,{propertyCount:i.length,minimum:r.minProperties},"","/minProperties",null,e,r),this.handleError(t))?t:void 0!==r.maxProperties&&i.length>r.maxProperties&&(t=this.createError(y.OBJECT_PROPERTIES_MAXIMUM,{propertyCount:i.length,maximum:r.maxProperties},"","/maxProperties",null,e,r),this.handleError(t))?t:null},d.prototype.validateObjectRequiredProperties=function(e,r){if(void 0!==r.required)for(var t=0;t<r.required.length;t++){var i=r.required[t];if(void 0===e[i]){var n=this.createError(y.OBJECT_REQUIRED,{key:i},"","/required/"+t,null,e,r);if(this.handleError(n))return n}}return null},d.prototype.validateObjectProperties=function(e,r,t){var i;for(var n in e){var a=t+"/"+n.replace(/~/g,"~0").replace(/\//g,"~1"),o=!1;if(void 0!==r.properties&&void 0!==r.properties[n]&&(o=!0,i=this.validateAll(e[n],r.properties[n],[n],["properties",n],a)))return i;if(void 0!==r.patternProperties)for(var s in r.patternProperties){var l=new RegExp(s);if(l.test(n)&&(o=!0,i=this.validateAll(e[n],r.patternProperties[s],[n],["patternProperties",s],a)))return i}if(o)this.trackUnknownProperties&&(this.knownPropertyPaths[a]=!0,delete this.unknownPropertyPaths[a]);else if(void 0!==r.additionalProperties){if(this.trackUnknownProperties&&(this.knownPropertyPaths[a]=!0,delete this.unknownPropertyPaths[a]),"boolean"==typeof r.additionalProperties){if(!r.additionalProperties&&(i=this.createError(y.OBJECT_ADDITIONAL_PROPERTIES,{key:n},"","/additionalProperties",null,e,r).prefixWith(n,null),this.handleError(i)))return i}else if(i=this.validateAll(e[n],r.additionalProperties,[n],["additionalProperties"],a))return i}else this.trackUnknownProperties&&!this.knownPropertyPaths[a]&&(this.unknownPropertyPaths[a]=!0)}return null},d.prototype.validateObjectDependencies=function(e,r,t){var i;if(void 0!==r.dependencies)for(var n in r.dependencies)if(void 0!==e[n]){var a=r.dependencies[n];if("string"==typeof a){if(void 0===e[a]&&(i=this.createError(y.OBJECT_DEPENDENCY_KEY,{key:n,missing:a},"","",null,e,r).prefixWith(null,n).prefixWith(null,"dependencies"),this.handleError(i)))return i}else if(Array.isArray(a))for(var o=0;o<a.length;o++){var s=a[o];if(void 0===e[s]&&(i=this.createError(y.OBJECT_DEPENDENCY_KEY,{key:n,missing:s},"","/"+o,null,e,r).prefixWith(null,n).prefixWith(null,"dependencies"),this.handleError(i)))return i}else if(i=this.validateAll(e,a,[],["dependencies",n],t))return i}return null},d.prototype.validateCombinations=function(e,r,t){return this.validateAllOf(e,r,t)||this.validateAnyOf(e,r,t)||this.validateOneOf(e,r,t)||this.validateNot(e,r,t)||null},d.prototype.validateAllOf=function(e,r,t){if(void 0===r.allOf)return null;for(var i,n=0;n<r.allOf.length;n++){var a=r.allOf[n];if(i=this.validateAll(e,a,[],["allOf",n],t))return i}return null},d.prototype.validateAnyOf=function(e,r,t){if(void 0===r.anyOf)return null;var i,n,a=[],o=this.errors.length;this.trackUnknownProperties&&(i=this.unknownPropertyPaths,n=this.knownPropertyPaths);for(var s=!0,l=0;l<r.anyOf.length;l++){this.trackUnknownProperties&&(this.unknownPropertyPaths={},this.knownPropertyPaths={});var h=r.anyOf[l],u=this.errors.length,f=this.validateAll(e,h,[],["anyOf",l],t);if(null===f&&u===this.errors.length){if(this.errors=this.errors.slice(0,o),this.trackUnknownProperties){for(var p in this.knownPropertyPaths)n[p]=!0,delete i[p];for(var c in this.unknownPropertyPaths)n[c]||(i[c]=!0);s=!1;continue}return null}f&&a.push(f.prefixWith(null,""+l).prefixWith(null,"anyOf"))}return this.trackUnknownProperties&&(this.unknownPropertyPaths=i,this.knownPropertyPaths=n),s?(a=a.concat(this.errors.slice(o)),this.errors=this.errors.slice(0,o),this.createError(y.ANY_OF_MISSING,{},"","/anyOf",a,e,r)):void 0},d.prototype.validateOneOf=function(e,r,t){if(void 0===r.oneOf)return null;var i,n,a=null,o=[],s=this.errors.length;this.trackUnknownProperties&&(i=this.unknownPropertyPaths,n=this.knownPropertyPaths);for(var l=0;l<r.oneOf.length;l++){this.trackUnknownProperties&&(this.unknownPropertyPaths={},this.knownPropertyPaths={});var h=r.oneOf[l],u=this.errors.length,f=this.validateAll(e,h,[],["oneOf",l],t);if(null===f&&u===this.errors.length){if(null!==a)return this.errors=this.errors.slice(0,s),this.createError(y.ONE_OF_MULTIPLE,{index1:a,index2:l},"","/oneOf",null,e,r);if(a=l,this.trackUnknownProperties){for(var p in this.knownPropertyPaths)n[p]=!0,delete i[p];for(var c in this.unknownPropertyPaths)n[c]||(i[c]=!0)}}else f&&o.push(f)}return this.trackUnknownProperties&&(this.unknownPropertyPaths=i,this.knownPropertyPaths=n),null===a?(o=o.concat(this.errors.slice(s)),this.errors=this.errors.slice(0,s),this.createError(y.ONE_OF_MISSING,{},"","/oneOf",o,e,r)):(this.errors=this.errors.slice(0,s),null)},d.prototype.validateNot=function(e,r,t){if(void 0===r.not)return null;var i,n,a=this.errors.length;this.trackUnknownProperties&&(i=this.unknownPropertyPaths,n=this.knownPropertyPaths,this.unknownPropertyPaths={},this.knownPropertyPaths={});var o=this.validateAll(e,r.not,null,null,t),s=this.errors.slice(a);return this.errors=this.errors.slice(0,a),this.trackUnknownProperties&&(this.unknownPropertyPaths=i,this.knownPropertyPaths=n),null===o&&0===s.length?this.createError(y.NOT_PASSED,{},"","/not",null,e,r):null},d.prototype.validateHypermedia=function(e,r,i){if(!r.links)return null;for(var n,a=0;a<r.links.length;a++){var o=r.links[a];if("describedby"===o.rel){for(var s=new t(o.href),l=!0,h=0;h<s.varNames.length;h++)if(!(s.varNames[h]in e)){l=!1;break}if(l){var u=s.fillFromObject(e),f={$ref:u};if(n=this.validateAll(e,f,[],["links",a],i))return n}}}};var y={INVALID_TYPE:0,ENUM_MISMATCH:1,ANY_OF_MISSING:10,ONE_OF_MISSING:11,ONE_OF_MULTIPLE:12,NOT_PASSED:13,NUMBER_MULTIPLE_OF:100,NUMBER_MINIMUM:101,NUMBER_MINIMUM_EXCLUSIVE:102,NUMBER_MAXIMUM:103,NUMBER_MAXIMUM_EXCLUSIVE:104,NUMBER_NOT_A_NUMBER:105,STRING_LENGTH_SHORT:200,STRING_LENGTH_LONG:201,STRING_PATTERN:202,OBJECT_PROPERTIES_MINIMUM:300,OBJECT_PROPERTIES_MAXIMUM:301,OBJECT_REQUIRED:302,OBJECT_ADDITIONAL_PROPERTIES:303,OBJECT_DEPENDENCY_KEY:304,ARRAY_LENGTH_SHORT:400,ARRAY_LENGTH_LONG:401,ARRAY_UNIQUE:402,ARRAY_ADDITIONAL_ITEMS:403,FORMAT_CUSTOM:500,KEYWORD_CUSTOM:501,CIRCULAR_REFERENCE:600,UNKNOWN_PROPERTY:1e3},g={};for(var E in y)g[y[E]]=E;var O={INVALID_TYPE:"Invalid type: {type} (expected {expected})",ENUM_MISMATCH:"No enum match for: {value}",ANY_OF_MISSING:'Data does not match any schemas from "anyOf"',ONE_OF_MISSING:'Data does not match any schemas from "oneOf"',ONE_OF_MULTIPLE:'Data is valid against more than one schema from "oneOf": indices {index1} and {index2}',NOT_PASSED:'Data matches schema from "not"',NUMBER_MULTIPLE_OF:"Value {value} is not a multiple of {multipleOf}",NUMBER_MINIMUM:"Value {value} is less than minimum {minimum}",NUMBER_MINIMUM_EXCLUSIVE:"Value {value} is equal to exclusive minimum {minimum}",NUMBER_MAXIMUM:"Value {value} is greater than maximum {maximum}",NUMBER_MAXIMUM_EXCLUSIVE:"Value {value} is equal to exclusive maximum {maximum}",NUMBER_NOT_A_NUMBER:"Value {value} is not a valid number",STRING_LENGTH_SHORT:"String is too short ({length} chars), minimum {minimum}",STRING_LENGTH_LONG:"String is too long ({length} chars), maximum {maximum}",STRING_PATTERN:"String does not match pattern: {pattern}",OBJECT_PROPERTIES_MINIMUM:"Too few properties defined ({propertyCount}), minimum {minimum}",OBJECT_PROPERTIES_MAXIMUM:"Too many properties defined ({propertyCount}), maximum {maximum}",OBJECT_REQUIRED:"Missing required property: {key}",OBJECT_ADDITIONAL_PROPERTIES:"Additional properties not allowed",OBJECT_DEPENDENCY_KEY:"Dependency failed - key must exist: {missing} (due to key: {key})",ARRAY_LENGTH_SHORT:"Array is too short ({length}), minimum {minimum}",ARRAY_LENGTH_LONG:"Array is too long ({length}), maximum {maximum}",ARRAY_UNIQUE:"Array items are not unique (indices {match1} and {match2})",ARRAY_ADDITIONAL_ITEMS:"Additional items not allowed",FORMAT_CUSTOM:"Format validation failed ({message})",KEYWORD_CUSTOM:"Keyword failed: {key} ({message})",CIRCULAR_REFERENCE:"Circular $refs: {urls}",UNKNOWN_PROPERTY:"Unknown property (not in schema)"};h.prototype=Object.create(Error.prototype),h.prototype.constructor=h,h.prototype.name="ValidationError",h.prototype.prefixWith=function(e,r){if(null!==e&&(e=e.replace(/~/g,"~0").replace(/\//g,"~1"),this.dataPath="/"+e+this.dataPath),null!==r&&(r=r.replace(/~/g,"~0").replace(/\//g,"~1"),this.schemaPath="/"+r+this.schemaPath),null!==this.subErrors)for(var t=0;t<this.subErrors.length;t++)this.subErrors[t].prefixWith(e,r);return this};var P={},_=f();return _.addLanguage("en-gb",O),_.tv4=_,_}); 2 | //# sourceMappingURL=tv4.min.js.map -------------------------------------------------------------------------------- /playground/template.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="utf-8"> 5 | <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 | <meta name="viewport" content="width=device-width, initial-scale=1"> 7 | <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags --> 8 | <title>AnyChart Report Server 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
39 |
40 | 43 |
44 |

AnyChart Report Server

45 |
46 |
47 |
48 | 55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | 75 | 76 |
77 |
78 |
79 | 82 |
83 |
84 | 91 |
92 |
93 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | describe('Server', function() { 2 | require('./tests/status'); 3 | 4 | require('./tests/pdf-report'); 5 | 6 | require('./tests/vector-image'); 7 | 8 | require('./tests/raster-image'); 9 | 10 | require('./tests/data-file'); 11 | }); -------------------------------------------------------------------------------- /test/tests/data-file.js: -------------------------------------------------------------------------------- 1 | var chai = require('chai'); 2 | var chaiHttp = require('chai-http'); 3 | var app = require('../../index'); 4 | const should = chai.should(); 5 | 6 | chai.use(chaiHttp); 7 | 8 | describe('/data-file', function() { 9 | it('csv data to xlsx file', function(done) { 10 | chai.request(app) 11 | .post('/data-file') 12 | .send({ 13 | "file_name": "anychart.xlsx", 14 | "data": "x,value\n0,10\n1,20\n2,8\n3,5\n4,12\n5,9", 15 | "response_type": "file" 16 | }) 17 | .end(function(err, res) { 18 | res.should.to.have.status(200); 19 | res.should.to.have.header('content-type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); 20 | res.should.to.have.header('content-disposition', 'attachment; filename=anychart.xlsx'); 21 | done(); 22 | }); 23 | }); 24 | 25 | it('csv data to csv file', function(done) { 26 | chai.request(app) 27 | .post('/data-file') 28 | .send({ 29 | "file_name": "anychart.csv", 30 | "file_type": "csv", 31 | "data": "x,value\n0,10\n1,20\n2,8\n3,5\n4,12\n5,9", 32 | "response_type": "file" 33 | }) 34 | .end(function(err, res) { 35 | res.should.to.have.status(200); 36 | res.should.to.have.header('content-type', 'text/csv'); 37 | res.should.to.have.header('content-disposition', 'attachment; filename=anychart.csv'); 38 | done(); 39 | }); 40 | }); 41 | }); -------------------------------------------------------------------------------- /test/tests/pdf-report.js: -------------------------------------------------------------------------------- 1 | var chai = require('chai'); 2 | var chaiHttp = require('chai-http'); 3 | var app = require('../../index'); 4 | const should = chai.should(); 5 | 6 | chai.use(chaiHttp); 7 | 8 | describe('/pdf-report', function() { 9 | it('base64 report with one chart with custom container id', function(done) { 10 | this.timeout(3000); 11 | 12 | chai.request(app) 13 | .post('/pdf-report') 14 | .send({ 15 | "response_type": "base64", 16 | "data": "(function() {return {content: [{\"chart\": {\"data\": \"chart = anychart.line([1,2,3]); chart.container('custom_container_id').draw();\",\"dataType\": \"javascript\",\"containerId\": \"custom_container_id\"},\"fit\": [500, 500]}]}})();" 17 | }) 18 | .end(function(err, res) { 19 | res.should.to.have.status(200); 20 | res.should.be.json; 21 | res.body.should.be.a('object'); 22 | res.body.should.have.property('data'); 23 | done(); 24 | }); 25 | }); 26 | }); -------------------------------------------------------------------------------- /test/tests/raster-image.js: -------------------------------------------------------------------------------- 1 | var chai = require('chai'); 2 | var chaiHttp = require('chai-http'); 3 | var app = require('../../index'); 4 | const should = chai.should(); 5 | 6 | chai.use(chaiHttp); 7 | 8 | describe('/raster-image', function() { 9 | it('javascript data to png image as base64 string', function(done) { 10 | this.timeout(3000); 11 | 12 | chai.request(app) 13 | .post('/raster-image') 14 | .send({ 15 | "data_type": "javascript", 16 | "file_type": "png", 17 | "response_type": "base64", 18 | "data": "var chart = anychart.pie(); chart.data([10, 20, 8, 5, 12, 9]); chart.container('container'); chart.draw();" 19 | }) 20 | .end(function(err, res) { 21 | res.should.to.have.status(200); 22 | res.should.be.json; 23 | res.body.should.be.a('object'); 24 | res.body.should.have.property('data'); 25 | done(); 26 | }); 27 | }); 28 | 29 | it('json data to jpg image as file', function(done) { 30 | this.timeout(3000); 31 | 32 | chai.request(app) 33 | .post('/raster-image') 34 | .send({ 35 | "file_name": "chart.jpg", 36 | "data_type": "json", 37 | "file_type": "jpg", 38 | "response_type": "file", 39 | "data": '{"chart":{"enabled":true,"padding":{"left":35,"top":35,"bottom":35,"right":35},"credits":{"text":"AnyChart","url":"https://www.anychart.com/?utm_source=registered","alt":"AnyChart - JavaScript Charts designed to be embedded and integrated","imgAlt":"AnyChart - JavaScript Charts","logoSrc":"https://static.anychart.com/logo.png","enabled":false},"selectMarqueeFill":{"color":"#d3d3d3","opacity":0.4},"xScale":0,"yScale":1,"series":[{"enabled":true,"seriesType":"marker","tooltip":{"enabled":false},"labels":{"enabled":true,"fontFamily":"Arial","fontColor":"#546e7a","format":"{%Name}","position":"right","anchor":"leftCenter","offsetX":5,"offsetY":0},"data":[{"x":65,"y":60,"name":"Tableau","logo":"tableau.png","description_short":"Data visualization company","website":"tableau.com","description":"Tableau Software is an American computer software company headquartered in Seattle, Washington. It produces a family of interactive data visualization products focused on business intelligence.","stock_price_today":55.71,"stock_price_change":-0.31,"stock_price_change_percent":-0.55,"founded":"January 2003","founders":"Pat Hanrahan, Christian Chabot, Chris Stolte","CEO":"Adam Selipsky","CFO":"Tom Walker","headquarters":"Seattle, Washington, United States","stock_price_key_data":"DATA.US"},{"x":68,"y":57,"name":"Qlik","logo":"qlik.png","description_short":"Software company","website":"qlik.com","description":"Qlik is a software company based in Radnor, Pennsylvania, United States. Qlik is the provider of QlikView and Qlik Sense, business intelligence & visualization software.","stock_price_today":null,"stock_price_change":null,"founded":"1993","founders":"Björn Berg, Staffan Gestrelius","CEO":"Lars Björk","CFO":"Tim MacCarrick","headquarters":"Radnor, Pennsylvania, United States","stock_price_key_data":"QLIK.US"},{"x":78,"y":55,"name":"Microsoft","logo":"microsoft.png","description_short":"Technology company","website":"microsoft.com","description":"Microsoft Corporation (commonly referred to as Microsoft or MS) is an American multinational technology company headquartered in Redmond, Washington, that develops, manufactures, licenses, supports and sells computer software, consumer electronics and personal computers and services.","stock_price_today":57.24,"stock_price_change":-0.18,"stock_price_change_percent":-0.31,"founded":"April 4, 1975","founders":"Bill Gates, Paul Allen","CEO":"Satya Nadella","CFO":"Amy Hood","headquarters":"Redmond, Washington, United States","stock_price_key_data":"MSFT.US"},{"x":65.5,"y":48,"name":"Alteryx","logo":"alteryx.png","description_short":"Computer software company","website":"alteryx.com","description":"Alteryx is an American computer software company based out of Irvine, California, with a development center in Broomfield, Colorado. The company\'s products are used for data blending and advanced data analytics.","stock_price_today":null,"stock_price_change":null,"founded":"2010","founders":"Dean Stoecker, Olivia Duane Adams, Ned Harding","CEO":"Dean Stoecker ","CFO":"Kevin Rubin","headquarters":"\tIrvine, California, U.S.","stock_price_data":null},{"x":63,"y":47,"name":"SAS","label":{"anchor":"right"},"logo":"sas.jpeg","description_short":"Software company","website":"www.sas.com","description":"SAS Institute is an American multinational developer of analytics software based in Cary, North Carolina. SAS develops and markets a suite of analytics software, which helps access, manage, analyze and report on data to aid in decision-making.","stock_price_today":null,"stock_price_change":null,"founded":"July 1, 1976","founders":"James Goodnight, Anthony James Barr, John Sall","CEO":"James Goodnight","CFO":null,"CTO":"Oliver Schabenberger","headquarters":"Cary, North Carolina, United States","stock_price_key_data":"SAS.ST"},{"x":64,"y":43,"name":"SAP","logo":"sap.jpeg","description_short":"Software company","website":"go.sap.com","description":"SAP SE is a German multinational software corporation that makes enterprise software to manage business operations and customer relations. SAP is headquartered in Walldorf, Baden-Württemberg, Germany, with regional offices in 130 countries.","stock_price_today":81.28,"stock_price_change":-0.19,"stock_price_change_percent":-0.23,"founded":"April 1, 1972","founders":"Dietmar Hopp, Hans-Werner Hector, Hasso Plattner, Klaus Tschira, Claus Wellenreuther","CEO":"Bill McDermott","CFO":"Luka Mucic","headquarters":"Walldorf, Germany","stock_price_key_data":"SAP.US"},{"y":28,"name":"IBM","label":{"anchor":"bottom","offsetX":0},"logo":"ibm.png","description_short":"Computer hardware company","website":"ibm.com","description":"International Business Machines Corporation is an American multinational technology company headquartered in Armonk, New York, United States, with operations in over 170 countries.","stock_price_today":157.08,"stock_price_change":0.62,"stock_price_change_percent":0.4,"founded":"June 16, 1911","founders":"Charles Ranlett Flint","CEO":"Ginni Rometty","CFO":null,"headquarters":"Armonk, North Castle, New York, United States","stock_price_key_data":"IBM.US"},{"x":51,"y":21,"name":"TIBCO Software","logo":"tibco.png","description_short":"Software company","website":"tibco.com","description":"TIBCO Software Inc. is an American company that provides integration, analytics and events processing software for companies to use on-premises or as part of cloud computing environments.","stock_price_today":null,"stock_price_change":null,"founded":"1997","founders":"Dale Skeen, Vivek Ranadivé","CEO":"Murray D. Rode","CFO":"Tom Berquist","headquarters":"Palo Alto, California, United States","stock_price_data":null},{"x":53.2,"y":25.8,"name":"Pentaho","label":{"anchor":"right"},"logo":"pentaho.png","description_short":null,"website":"pentaho.com","description":"Pentaho is a company that offers Pentaho Business Analytics, a suite of open source Business Intelligence products which provide data integration, OLAP services, reporting, dashboarding, data mining and ETL capabilities.","stock_price_today":null,"stock_price_change":null,"founded":"2004","founders":"Richard Daley","CEO":"Quentin Gallivan ","CTO":"James Dixon","CFO":null,"headquarters":"Orlando, Florida, United States","stock_price_data":null},{"x":47,"y":48,"name":"Birst","label":{"anchor":"right"},"logo":"birst.jpeg","description_short":"Cloud BI and analytics","website":"www.birst.com","description":"Birst is a global leader in cloud BI and analytics. The company helps organizations make thousands of decisions better, every day, for every person. Birst’s patented two-tier data architecture and comprehensive BI platform sits on top of all of your data, to unify, refine and embed data consistently into every individual decision—up and down the org chart. ","stock_price_today":null,"stock_price_change":null,"founded":"2004","founders":"Brad Peters, Paul Staelin","CEO":"Jay Larson","CFO":"Sam Wolff","headquarters":"San Francisco, CA","stock_price_data":null},{"x":37,"y":43,"name":"Domo","label":{"anchor":"right"},"logo":"domo.png","description_short":"Business Intelligence: Dashboards, Reporting and Analytics","website":"www.domo.com","description":"Domo, Inc. is an American computer software company based in American Fork, Utah, USA. It specializes in business intelligence tools and data visualization.","stock_price_today":null,"stock_price_change":null,"founded":"2010","founders":"Josh James","CEO":"Josh James","CFO":null,"headquarters":"American Fork, Utah, US","stock_price_data":null},{"y":27.5,"name":"Board International","label":{"anchor":"leftTop","offsetX":-10,"offsetY":3},"logo":"boardInternational.png","description_short":"Business intelligence company","website":"board.com","description":"BOARD International S.A. is a Business Intelligence and Corporate Performance Management software vendor known for its BOARD toolkit. The company is headquartered in Lugano, Switzerland, where it was founded in 1994.","stock_price_today":null,"stock_price_change":null,"founded":"1994","founders":null,"CEO":null,"CFO":null,"headquarters":"Lugano, Switzerland","stock_price_data":null},{"x":35,"y":26.5,"name":"Sisense","label":{"anchor":"rightBottom"},"logo":"sisense.png","description_short":"Software company","website":"sisense.com","description":"Sisense is a business analytics software company with offices in New York City and Tel Aviv. Its business intelligence product includes both a back-end powered by in-chip technology that enables non-technical users to join and analyze large data sets from multiple sources, and a front-end for creating visualizations, like dashboards and reports, on any device, including mobile.","stock_price_today":null,"stock_price_change":null,"founded":"2004","founders":"Elad Israeli, Eldad Farkash, Aviad Harell, Guy Boyangu, Adi Azaria","CEO":"Amir Orad","CFO":null,"headquarters":null,"stock_price_data":null},{"x":30,"y":16,"name":"Yellowfin","label":{"anchor":"right"},"logo":"yellowfin.png","description_short":"Business intelligence company","website":"yellowfinbi.com","description":"Yellowfin is a business intelligence, dashboard, reporting and data analysis software vendor. Yellowfin’s software allows reporting from data stored in relational databases, multi-dimensional cubes or in-memory analytical databases.","stock_price_today":null,"stock_price_change":null,"founded":"2003","founders":"Glen Rabie and Justin Hewitt","CEO":null,"CFO":null,"headquarters":"Melbourne, Victoria, Australia, Tokyo, Idaho, Boston, London, New Hampshire","stock_price_data":null}],"xScale":0,"yScale":1}],"isVertical":false,"quarters":{"rightTop":{"enabled":true,"title":{"enabled":true,"fontColor":"#ff8f00","text":"LEADERS","padding":{"left":10,"top":10,"bottom":10,"right":10}}},"leftTop":{"enabled":true,"title":{"enabled":true,"fontColor":"#ff8f00","text":"CHALLENGERS","padding":{"left":10,"top":10,"bottom":10,"right":10}}},"leftBottom":{"enabled":true,"title":{"enabled":true,"fontColor":"#ff8f00","text":"NICHE PLAYERS","padding":{"left":10,"top":10,"bottom":10,"right":10}},"labels":[{"enabled":true,"zIndex":20,"useHtml":true,"background":{"zIndex":0,"enabled":false,"disablePointerEvents":false},"padding":{},"anchor":"leftCenter","offsetX":-20,"text":"Power to Perform →","rotation":-90,"position":"leftBottom"},{"enabled":true,"zIndex":20,"useHtml":true,"background":{"zIndex":0,"enabled":false,"disablePointerEvents":false},"padding":{},"anchor":"leftCenter","offsetY":20,"text":"Entirety of Representation →","position":"leftBottom"}]},"rightBottom":{"enabled":true,"title":{"enabled":true,"fontColor":"#ff8f00","text":"VISIONARIES","padding":{"left":10,"top":10,"bottom":10,"right":10}}}},"type":"quadrant"}}' 40 | }) 41 | .end(function(err, res) { 42 | res.should.to.have.status(200); 43 | res.should.to.have.header('content-type', 'image/jpg'); 44 | res.should.to.have.header('content-disposition', 'attachment; filename=chart.jpg'); 45 | done(); 46 | }); 47 | }); 48 | }); -------------------------------------------------------------------------------- /test/tests/status.js: -------------------------------------------------------------------------------- 1 | var chai = require('chai'); 2 | var chaiHttp = require('chai-http'); 3 | var app = require('../../index'); 4 | const should = chai.should(); 5 | 6 | chai.use(chaiHttp); 7 | 8 | describe('/status', function() { 9 | it('should return \'ok\'', function(done) { 10 | chai.request(app) 11 | .get('/status') 12 | .end(function(err, res) { 13 | res.text.should.equal('ok'); 14 | done(); 15 | }); 16 | }); 17 | }); -------------------------------------------------------------------------------- /test/tests/vector-image.js: -------------------------------------------------------------------------------- 1 | var chai = require('chai'); 2 | var chaiHttp = require('chai-http'); 3 | var app = require('../../index'); 4 | var crypto = require('crypto'); 5 | const should = chai.should(); 6 | 7 | chai.use(chaiHttp); 8 | 9 | describe('/vector-image', function() { 10 | it('javascript -> pdf(base64)', function(done) { 11 | this.timeout(3000); 12 | 13 | chai.request(app) 14 | .post('/vector-image') 15 | .send({ 16 | "background": "#f00", 17 | "aspect-ratio": true, 18 | "width": 200, 19 | "height": 1000, 20 | "data_type": "javascript", 21 | "file_type": "pdf", 22 | "response_type": "base64", 23 | "data": "var chart = anychart.pie(); chart.data([10, 20, 8, 5, 12, 9]); chart.container('container'); chart.draw();" 24 | }) 25 | .end(function(err, res) { 26 | res.should.to.have.status(200); 27 | res.should.be.json; 28 | res.body.should.be.a('object'); 29 | res.body.should.have.property('data'); 30 | done(); 31 | }); 32 | }); 33 | 34 | it('xml -> ps image(file)', function(done) { 35 | this.timeout(3000); 36 | 37 | chai.request(app) 38 | .post('/raster-image') 39 | .send({ 40 | "file_name": "chart.ps", 41 | "data_type": "xml", 42 | "file_type": "ps", 43 | "response_type": "file", 44 | "data": '<padding left="0" top="0" bottom="35" right="0"/>' 45 | }) 46 | .end(function(err, res) { 47 | res.should.to.have.status(200); 48 | res.should.to.have.header('content-type', 'application/postscript'); 49 | res.should.to.have.header('content-disposition', 'attachment; filename=chart.ps'); 50 | done(); 51 | }); 52 | }); 53 | 54 | it('javascript -> pdf(base64) [+external]', function(done) { 55 | this.timeout(10000); 56 | 57 | chai.request(app) 58 | .post('/vector-image') 59 | .send({ 60 | "resources": [ 61 | "https://cdn.anychart.com/geodata/1.2.0/countries/canada/canada.js", 62 | "https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15/proj4.js" 63 | ], 64 | "data_type": "javascript", 65 | "file_type": "pdf", 66 | "response_type": "base64", 67 | "data": "var data = [];anychart.maps['canada'].features.filter(function (item) {data.push({id: item.properties.id, name: item.properties.name});});map = anychart.map().crs('august').geoData('anychart.maps.canada');map.scale().xTicks({interval: 15}).yTicks({interval: 5}).precision(1).minimumX(-145).maximumX(-45).minimumY(40).maximumY(84);map.axes().enabled(true).drawFirstLabel(false).drawLastLabel(false);map.choropleth(data);map.container('container').draw();" 68 | }) 69 | .end(function(err, res) { 70 | res.should.to.have.status(200); 71 | res.should.be.json; 72 | res.body.should.be.a('object'); 73 | res.body.should.have.property('data'); 74 | 75 | var trueHash = "d94f86c6d48d58d01db8441feeccdf7d"; 76 | var md5sum = crypto.createHash('md5'); 77 | md5sum.update(res.body.data); 78 | var hashOfOutputImage = md5sum.digest('hex'); 79 | 80 | hashOfOutputImage.should.be.equal(trueHash); 81 | done(); 82 | }); 83 | }); 84 | }); --------------------------------------------------------------------------------