├── .github └── workflows │ └── node.js.yml ├── .gitignore ├── .npmignore ├── .travis.yml ├── .vscode └── settings.json ├── CNAME ├── README.md ├── beautifier.js ├── css ├── bootstrap-grid.min.css ├── bootstrap-reboot.min.css ├── bootstrap-theme.min.css ├── bootstrap.min.css └── screen.css ├── dist ├── excel-formula.js └── excel-formula.min.js ├── docs ├── ExcelFormulaUtilities.html ├── core.html ├── docco.css ├── main.html └── public │ ├── fonts │ ├── aller-bold.eot │ ├── aller-bold.ttf │ ├── aller-bold.woff │ ├── aller-light.eot │ ├── aller-light.ttf │ ├── aller-light.woff │ ├── novecento-bold.eot │ ├── novecento-bold.ttf │ └── novecento-bold.woff │ └── stylesheets │ └── normalize.css ├── examples ├── basic_example1 │ ├── basicExample.js │ └── index.html └── node_app │ ├── index.js │ └── package.json ├── fonts ├── glyphicons-halflings-regular.eot ├── glyphicons-halflings-regular.svg ├── glyphicons-halflings-regular.ttf ├── glyphicons-halflings-regular.woff └── glyphicons-halflings-regular.woff2 ├── gulpfile.js ├── img ├── glyphicons-halflings-white.png ├── glyphicons-halflings.png └── logo.png ├── index.coffee ├── index.html ├── index.js ├── js ├── beautifier.js ├── beautifier.min.js ├── bootstrap.min.js ├── clipboard.min.js ├── jquery.min.js ├── jquery.min.map ├── npm.js └── page.js ├── license.include ├── package.json ├── robots.txt ├── src ├── ExcelFormulaUtilities.js └── core.js ├── test ├── ExcelFormulaUtilities.test.js └── browser │ ├── ExcelFormulaUtilities.test.js │ ├── build.min.test.html │ ├── build.test.html │ ├── core.test.js │ ├── dev.parse.debug.html │ ├── dev.test.html │ ├── jquery │ └── jQuery.js │ └── qunit │ ├── qunit.css │ └── qunit.js └── testapp.js /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ main ] 9 | pull_request: 10 | branches: [ main ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [12.x, 14.x, 16.x] 20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v2 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | - run: npm ci 29 | - run: npm run build --if-present 30 | - run: npm test 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # npm packages 2 | /*.tgz 3 | 4 | .c9 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | 15 | # Directory for instrumented libs generated by jscoverage/JSCover 16 | lib-cov 17 | 18 | # Coverage directory used by tools like istanbul 19 | coverage 20 | 21 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 22 | .grunt 23 | 24 | # node-waf configuration 25 | .lock-wscript 26 | 27 | # Compiled binary addons (http://nodejs.org/api/addons.html) 28 | build/Release 29 | 30 | # Dependency directory 31 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 32 | node_modules 33 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test 2 | docs 3 | js 4 | img 5 | examples 6 | css 7 | beautifier.js 8 | Cakefile 9 | CNAME 10 | index.html 11 | robots.txt 12 | testapp.js 13 | index.coffee 14 | .npmignore 15 | gulpfile.js 16 | license.include 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "stable" 4 | - "iojs" 5 | sudo: false 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "arrayrow", 4 | "arrayrowstop", 5 | "arraystop", 6 | "autoindent", 7 | "autolinebreak", 8 | "cellspacing", 9 | "delim", 10 | "ewbi", 11 | "ewbi's", 12 | "fabs", 13 | "math", 14 | "nbsp", 15 | "resig", 16 | "subexpr", 17 | "subexpression", 18 | "tmpl", 19 | "tok", 20 | "type" 21 | ] 22 | } -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | excelformulabeautifier.com -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Excel Formula Utilities for JavaScript 2 | 3 | Excel Formula Utilities for JavaScript is a library that can be used to 4 | pretty print excel formulas or convert excel formulas into JavaScript. 5 | The JavaScript generated by this library will not execute on it's own. 6 | You'll need to include something like 7 | [formula.js](https://github.com/sutoiku/formula.js/) to cover all the functions 8 | from Excel. 9 | 10 | ##Install using npm 11 | npm install excel-formula 12 | 13 | ## Installation for web 14 | Grab the latest js files in the dist folder. 15 | 16 | ## Basic usage for web 17 | ```html 18 | 23 | ``` 24 | ## Basic Usage for Node 25 | ```javascript 26 | var formula = require('excel-formula'); 27 | var formattedFormula = formula.formatFormula('IF(1+1=2,"true","false")'); 28 | console.log(formatFormula); 29 | ``` 30 | ## Node methods 31 | See basic usage above. 32 | ```javascript 33 | formula.getTokens (formula); 34 | formula.formatFormula (formula, [opts]) 35 | formula.toJavaScript(formula) 36 | formula.toCSharp(formula) 37 | ``` 38 | ## Web methods 39 | excelFormulaUtilities is a global variable. 40 | ```javascript 41 | excelFormulaUtilities.getTokens (formula); 42 | excelFormulaUtilities.formatFormula (formula, [opts]) // This will work fine in a pre tag 43 | excelFormulaUtilities.formatFormulaHTML(formula) // Use this if you want the output as html. 44 | excelFormulaUtilities.formula2JavaScript(formula) 45 | excelFormulaUtilities.formula2CSharp(formula) 46 | ``` 47 | -------------------------------------------------------------------------------- /beautifier.js: -------------------------------------------------------------------------------- 1 | //Beautifier.js 2 | // 3 | //Copywrite 2011 Josh Benentt 4 | //License - https://raw.github.com/joshatjben/excelFormulaUtilitiesJS/master/LICENSE.txt 5 | //[on github](https://github.com/joshatjben/excelFormulaUtilitiesJS/tree/master/examples/basic_example1 "github") 6 | // 7 | (function (window, undefiend) { 8 | "use strict"; 9 | 10 | //Check and setup name spaces. 11 | window.excelFormulaBeautifier = window.excelFormulaBeautifier || {}; 12 | window.excelFormulaBeautifier.examples = window.excelFormulaBeautifier.examples || {}; 13 | 14 | //Configuration 15 | //------------------------------- 16 | var config = { 17 | //The ID for the formula Input input/textarea 18 | INPUT_ID: 'formula_input', 19 | 20 | //The ID for the formula title area. in this example it spits out the function call; 21 | FORMULA_TITLE_ID: 'fomatFormula_2', 22 | 23 | //THE ID for the area to contain the beautified excel formula. 24 | FORMULA_BODY_ID:'fomatFormula_2_out', 25 | 26 | //Use this to set the inital textare/input text area. 27 | DEFAULT_FORMULA: '' 28 | }, 29 | 30 | 31 | //Beautifier Page functionality 32 | //------------------------------- 33 | beautifier = window.excelFormulaBeautifier.examples.beautifier = 34 | (function () { 35 | var oldFormula; 36 | 37 | return { 38 | formula: '=IF(SUM( If(FOO = BAR, 10, 0), 10 ) = 20 , "FOO", "BAR")', 39 | input: null, 40 | formulaTitle: null, 41 | formulaBody: null, 42 | mode: "beautify", 43 | changeMode: function(mode){ 44 | window.excelFormulaBeautifier.examples.beautifier.mode = mode; 45 | window.excelFormulaBeautifier.examples.beautifier.update.call(window.excelFormulaBeautifier.examples.beautifier); 46 | }, 47 | update: function () { 48 | this.formula = this.input.value; 49 | 50 | //Test to see if the formula has changed, if it hasn't don't do anything 51 | if (oldFormula === this.formula) { 52 | return; 53 | } 54 | 55 | // Check to see which mode we're in, render appropriately 56 | try{ 57 | 58 | switch( this.mode ) { 59 | case "beautify": 60 | this.formulaBody.innerHTML = window.excelFormulaUtilities.formatFormulaHTML(this.formula); 61 | break; 62 | case "js": 63 | this.formulaBody.innerHTML = window.excelFormulaUtilities.formula2JavaScript(this.formula); 64 | break; 65 | } 66 | }catch(exception){ 67 | //Do nothing, This should throw an error when the formula is improperly formed, which shouldn't blow things up. 68 | } 69 | } 70 | }; 71 | }()); 72 | 73 | //On Page Load 74 | //------------------- 75 | window.onload = function () { 76 | beautifier.input = document.getElementById(config.INPUT_ID); 77 | //beautifier.formulaTitle = document.getElementById(config.FORMULA_TITLE_ID); 78 | beautifier.formulaBody = document.getElementById(config.FORMULA_BODY_ID); 79 | 80 | beautifier.input.value = beautifier.formula; 81 | beautifier.update(); 82 | //add beautifier.update(); here if if you have set an inital DEFAULT_FORMULA and would like it to render on page load. 83 | }; 84 | 85 | }(window)); 86 | -------------------------------------------------------------------------------- /css/bootstrap-grid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Grid v4.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2018 The Bootstrap Authors 4 | * Copyright 2011-2018 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | */@-ms-viewport{width:device-width}html{box-sizing:border-box;-ms-overflow-style:scrollbar}*,::after,::before{box-sizing:inherit}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}} 7 | /*# sourceMappingURL=bootstrap-grid.min.css.map */ -------------------------------------------------------------------------------- /css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v4.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2018 The Bootstrap Authors 4 | * Copyright 2011-2018 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important} 8 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /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 */ -------------------------------------------------------------------------------- /css/screen.css: -------------------------------------------------------------------------------- 1 | html, body{ font-family: 'Open Sans', sans-serif; margin-top:0.61em;} 2 | h1, h2, h3, h4, h5, h6 {font-family: 'Open Sans', sans-serif;} 3 | footer{margin-top:1.61em;text-align: right} 4 | 5 | textarea{border:solid 1px #e4e4e4} 6 | h1{font-weight:normal; } 7 | 8 | /*-----------HEADER STYLES-------------*/ 9 | header{margin-bottom:.61em; color:#696969} 10 | header p{display:block; margin:0; padding: 0} 11 | header h1{display:block; vertical-align: middle; margin:0; padding:0} 12 | header img{vertical-align: middle; float:left;} 13 | 14 | header .title{float:left;} 15 | 16 | /*Non Phone*/ 17 | @media(min-width:767px){ 18 | header .title{margin:1.55em 0 0 0;} 19 | } 20 | /*Phone*/ 21 | @media(max-width:767px){ 22 | header .title{margin:0.55em 0 0 0;} 23 | header img{width:50px; height: 52px;} 24 | header h1{font-size:1.31em; line-height:0.91em; } 25 | header p{font-size:0.61em; line-height:1.61em; } 26 | } 27 | 28 | /*-----------FORMULA INPUT-------------*/ 29 | /* 30 | #inputArea textarea{height:3.2em; } 31 | #inputArea select{vertical-align:middle; }*/ 32 | 33 | 34 | /*-----------FORMULA STYLES------------*/ 35 | .formula{ 36 | font-family: "Courier New", Courier, "Lucida Sans Typewriter", "Lucida Typewriter", monospace; 37 | background-color:#f5fffa; 38 | border:solid 1px #e4e4e4; 39 | padding: 1.428em; 40 | overflow:auto; 41 | } 42 | #fomatFormula_2_out{display:inline;white-space: nowrap} 43 | .function{ 44 | color:#069; 45 | } 46 | .function_start, .function_stop{ 47 | color:#ff0000; 48 | } 49 | .tabbed{border-left:dotted 1px #a0a0a0} 50 | .quote_mark, .text{color:#0000ff} 51 | /*-----------FORMULA STYLES------------*/ 52 | 53 | label{margin: 0.5em 0;} 54 | 55 | input[type="file"], input[type="image"], input[type="submit"], input[type="reset"], input[type="button"], input[type="radio"], input[type="checkbox"] { 56 | vertical-align: text-top; 57 | } 58 | 59 | #copyFormulaBtn{ 60 | float:right; 61 | position: relative; 62 | clear: none; 63 | } 64 | -------------------------------------------------------------------------------- /dist/excel-formula.min.js: -------------------------------------------------------------------------------- 1 | !function(){"undefined"==typeof window&&(window=root);var t=(window.excelFormulaUtilities=window.excelFormulaUtilities||{},window.excelFormulaUtilities.core={});window.excelFormulaUtilities.string=window.excelFormulaUtilities.string||{};var e=(window.excelFormulaUtilities.string.formatStr=function(t){for(var e=t,n=1;n)*|(?:\s| |<\s*br\s*\/*\s*>)*$/,"")},t.isFunction=function(t){return"function"==typeof t}),n=t.isArray=function(t){return"object"==typeof t&&t.length},r=t.isWindow=function(){return obj&&"object"==typeof obj&&"setInterval"in obj},o=t.isPlainObject=function(t){if(!t||"object"!=typeof t||t.nodeType||r(t))return!1;if(t.constructor&&!hasOwnProperty.call(t,"constructor")&&!hasOwnProperty.call(t.constructor.prototype,"isPrototypeOf"))return!1;var e;for(key in t)e=key;return void 0===e||hasOwnProperty.call(t,e)};t.extend=function(){var r,i,a,s,p,u,l=arguments[0]||{},c=1,d=arguments.length,m=!1;for("boolean"==typeof l&&(m=l,l=arguments[1]||{},c=2),"object"==typeof l||e(l)||(l={}),d===c&&(l=this,--c);c=this.items.length-1},this.moveNext=function(){return!this.EOF()&&(this.index+=1,!0)},this.current=function(){return this.index===-1?null:this.items[this.index]},this.next=function(){return this.EOF()?null:this.items[this.index+1]},this.previous=function(){return this.index<1?null:this.items[this.index-1]}}function r(){this.items=[],this.push=function(t){this.items.push(t)},this.pop=function(t){var n=this.items.pop();return new e(t||"",n.type,O)},this.token=function(){return this.items.length>0?this.items[this.items.length-1]:null},this.value=function(){return this.token()?this.token().value.toString():""},this.type=function(){return this.token()?this.token().type.toString():""},this.subtype=function(){return this.token()?this.token().subtype.toString():""}}function o(e){for(var o=new n,i=new r,a=0,s=function(){return e.substr(a,1)},p=function(){return e.substr(a,2)},u=function(){return e.substr(a+1,1)},l=function(){return a>=e.length},c="",P=!1,N=!1,Y=!1,K=!1,I=/^[1-9]{1}(\.[0-9]+)?E{1}$/;e.length>0;){if(" "!==e.substr(0,1)){"="===e.substr(0,1)&&(e=e.substr(1));break}e=e.substr(1)}for(;!l();)if(P)'"'===s()?'"'===u()?(c+='"',a+=1):(P=!1,o.add(c,m,w),c=""):c+=s(),a+=1;else if(N)"'"===s()?"'"===u()?(c+="'",a+=1):(N=!1,c+="'"):c+=s(),a+=1;else if(Y)"]"===s()&&(Y=!1),c+=s(),a+=1;else if(K)c+=s(),a+=1,",#NULL!,#DIV/0!,#VALUE!,#REF!,#NAME?,#NUM!,#N/A,".indexOf(","+c+",")!==-1&&(K=!1,o.add(c,m,E),c="");else if("+-".indexOf(s())!==-1&&c.length>1&&c.match(I))c+=s(),a+=1;else if('"'!==s())if("'"!==s())if("["!==s())if("#"!==s())if("{"!==s())if(";"!==s())if("}"!==s())if(" "!==s())",>=,<=,<>,".indexOf(","+p()+",")===-1?"+-*/^&=><".indexOf(s())===-1?"%".indexOf(s())===-1?"("!==s()?","!==s()||t.excelFormulaUtilities.isEu?")"!==s()?(c+=s(),a+=1):(c.length>0&&(o.add(c,m),c=""),o.addRef(i.pop()),a+=1):(c.length>0&&(o.add(c,m),c=""),i.type()!==g?o.add(s(),h,C):o.add(s(),S),a+=1):(c.length>0?(i.push(o.add(c,g,x)),c=""):i.push(o.add("",f,x)),a+=1):(c.length>0&&(o.add(c,m),c=""),o.add(s(),y),a+=1):(c.length>0&&(o.add(c,m),c=""),o.add(s(),h),a+=1):(c.length>0&&(o.add(c,m),c=""),o.add(p(),h,R),a+=2);else for(c.length>0&&(o.add(c,m),c=""),o.add("",T),a+=1;" "===s()&&!l();)a+=1;else c.length>0&&(o.add(c,m),c=""),o.addRef(i.pop("ARRAYROWSTOP")),o.addRef(i.pop("ARRAYSTOP")),a+=1;else{if(t.excelFormulaUtilities.isEu){c.length>0&&(o.add(c,m),c=""),i.type()!==g?o.add(s(),h,C):o.add(s(),S),a+=1;continue}c.length>0&&(o.add(c,m),c=""),o.addRef(i.pop()),o.add(",",S),i.push(o.add("ARRAYROW",g,x)),a+=1}else c.length>0&&(o.add(c,k),c=""),i.push(o.add("ARRAY",g,x)),i.push(o.add("ARRAYROW",g,x)),a+=1;else c.length>0&&(o.add(c,k),c=""),K=!0,c+=s(),a+=1;else Y=!0,c+=s(),a+=1;else c.length>0&&(o.add(c,k),c=""),c="'",N=!0,a+=1;else c.length>0&&(o.add(c,k),c=""),P=!0,a+=1;(c.length>0||P||N||Y||K)&&(P||N||Y||K?(P?c='"'+c:N?c="'"+c:Y?c="["+c:K&&(c="#"+c),o.add(c,k)):o.add(c,m));for(var L=new n;o.moveNext();)if(c=o.current(),c.type.toString()!==T)L.addRef(c);else{var B=o.BOF()||o.EOF();B=B&&(o.previous().type.toString()===g&&o.previous().subtype.toString()===O||o.previous().type.toString()===f&&o.previous().subtype.toString()===O||o.previous().type.toString()===m),B=B&&(o.next().type.toString()===g&&o.next().subtype.toString()===x||o.next().type.toString()===f&&o.next().subtype.toString()===x||o.next().type.toString()===m),B&&L.add(c.value.toString(),h,F)}for(;L.moveNext();)c=L.current(),c.type.toString()!==h||"-"!==c.value.toString()?c.type.toString()!==h||"+"!==c.value.toString()?c.type.toString()!==h||0!==c.subtype.length?c.type.toString()!==m||0!==c.subtype.length?c.type.toString()!==g||"@"===c.value.substr(0,1)&&(c.value=c.value.substr(1).toString()):isNaN(parseFloat(c.value))?"TRUE"===c.value.toString()||"FALSE"===c.value.toString()?c.subtype=R.toString():c.subtype=_.toString():c.subtype=v.toString():"<>=".indexOf(c.value.substr(0,1))!==-1?c.subtype=R.toString():"&"===c.value.toString()?c.subtype=A.toString():c.subtype=U.toString():L.BOF()?c.type=d.toString():L.previous().type.toString()===g&&L.previous().subtype.toString()===O||L.previous().type.toString()===f&&L.previous().subtype.toString()===O||L.previous().type.toString()===y||L.previous().type.toString()===m?c.subtype=U.toString():c.type=d.toString():L.BOF()?c.type=b.toString():L.previous().type.toString()===g&&L.previous().subtype.toString()===O||L.previous().type.toString()===f&&L.previous().subtype.toString()===O||L.previous().type.toString()===y||L.previous().type.toString()===m?c.subtype=U.toString():c.type=b.toString();for(L.reset(),o=new n;L.moveNext();)L.current().type.toString()!==d&&o.addRef(L.current());return o.reset(),o}function i(t,e){if(!RegExp("[a-z]+[0-9]+:[a-z]+[0-9]+","gi").test(t))throw"This is not a valid range: "+t;var n=t.split(":"),r=parseInt(n[0].match(/[0-9]+/gi)[0]),o=n[0].match(/[A-Z]+/gi)[0],i=N(o);for(endRow=parseInt(n[1].match(/[0-9]+/gi)[0]),endCol=n[1].match(/[A-Z]+/gi)[0],endColDec=N(endCol),totalRows=endRow-r+1,totalCols=N(endCol)-N(o)+1,curCol=0,curRow=1,curCell="",retStr="";curRow<=totalRows;curRow+=1){for(;curCol",p+="",p+="index",p+="type",p+="subtype",p+="token",p+="token tree";s.moveNext();){var u=s.current();u.subtype===O&&(n-=n>0?1:0),p+="",p+=""+(s.index+1)+"",p+=""+u.type+"",p+=""+(0===u.subtype.length?" ":u.subtype.toString())+"",p+=""+(0===u.value.length?" ":u.value).split(" ").join(" ")+"",p+=""+r()+(0===u.value.length?" ":u.value).split(" ").join(" ")+"",p+="",u.subtype===x&&(n+=1)}p+="",document.getElementById(e).innerHTML=p,i.select(),i.focus()},s.toBase26=function(t){t=Math.abs(t);var e,n="",r=!1;do e=t%26,r&&t<25&&e--,n=String.fromCharCode(e+"A".charCodeAt(0))+n,t=Math.floor((t-e)/26),r=!0;while(t>0);return n}),N=s.fromBase26=function(t){t=t.toUpperCase();var e=0,n=0,r=0;if(null!==t&&"undefined"!=typeof t&&t.length>0)for(;n0?1:0);var y=(new RegExp("^"+e.newLine,""),new RegExp(e.newLine+"$","")),T=f(h),k=g,w=k?s():e.tmplIndentSpace,v=T?e.newLine:"";d+=a(b,e,w,v,e.customTokenRender,S),b.subtype.toString()===x&&(i+=1),g=T||y.test(d),n=!1,S=b}return d=e.prefix+l(d)+e.postfix},K=(s.formatFormulaHTML=function(t,e){var n=function(t,e,n,r){var o=t;switch(e.type.toString()){case m:e.subtype===w&&(o=t.replace(//gi,">"))}return{tokenString:o,useTemplate:!0}},r={tmplFunctionStart:'{{autoindent}}{{token}}(
',tmplFunctionStop:'
{{autoindent}}{{token}})',tmplOperandText:'{{autoindent}}"{{token}}"',tmplArgument:"{{token}}
",tmplSubexpressionStart:"{{autoindent}}(",tmplSubexpressionStop:" )",tmplIndentTab:'    ',tmplIndentSpace:" ",newLine:"
",autoLineBreak:"TOK_TYPE_FUNCTION | TOK_TYPE_ARGUMENT | TOK_SUBTYPE_LOGICAL | TOK_TYPE_OP_IN ",trim:!0,prefix:"=",customTokenRender:n};return e=e?p.extend(!0,r,e):r,Y(t,e)},s.formula2CSharp=function(t,e){var n=[],r=function(t,e,r,o){var a="",s=t,p={"=":"==","<>":"!=",MIN:"Math.min",MAX:"Math.max",ABS:"Math.abs",SUM:"",IF:"","&":"+",AND:"",OR:""},u=n[n.length-1],l=!1;switch(e.type.toString()){case g:switch(e.subtype){case x:n.push({name:s,argumentNumber:0}),a="string"==typeof p[s.toUpperCase()]?p[s.toUpperCase()]:s,l=!0;break;case O:switch(l=!0,u.name.toLowerCase()){case"if":a=1===u.argumentNumber?":0)":")",l=!1;break;default:a="string"==typeof p[s.toUpperCase()]?p[s.toUpperCase()]:s}n.pop()}break;case S:switch(u.name.toLowerCase()){case"if":switch(u.argumentNumber){case 0:a="?";break;case 1:a=":"}break;case"sum":a="+";break;case"and":a="&&";break;case"or":a="||";break;default:a="string"==typeof p[s.toUpperCase()]?p[s.toUpperCase()]:s,l=!0}u.argumentNumber+=1;break;case m:switch(e.subtype){case _:if(!u)break;switch(u.name.toLowerCase()){case"sum":RegExp(":","gi").test(s)?a=i(s,"+"):outStr=s;break;case"and":RegExp(":","gi").test(s)?a=i(s,"&&"):outStr=s;break;case"or":RegExp(":","gi").test(s)?a=i(s,"||"):outStr=s;break;default:a=RegExp(":","gi").test(s)?"["+i(s,",")+"]":s}}default:""===a&&(a="string"==typeof p[s.toUpperCase()]?p[s.toUpperCase()]:s),l=!0}return{tokenString:a,useTemplate:l}},o={tmplFunctionStart:"{{token}}(",tmplFunctionStop:"{{token}})",tmplOperandError:"{{token}}",tmplOperandRange:"{{token}}",tmplOperandLogical:"{{token}}",tmplOperandNumber:"{{token}}",tmplOperandText:'"{{token}}"',tmplArgument:"{{token}}",tmplOperandOperatorInfix:"{{token}}",tmplFunctionStartArray:"",tmplFunctionStartArrayRow:"{",tmplFunctionStopArrayRow:"}",tmplFunctionStopArray:"",tmplSubexpressionStart:"(",tmplSubexpressionStop:")",tmplIndentTab:"\t",tmplIndentSpace:" ",autoLineBreak:"TOK_SUBTYPE_STOP | TOK_SUBTYPE_START | TOK_TYPE_ARGUMENT",trim:!0,customTokenRender:r};e=e?p.extend(!0,o,e):o;var a=Y(t,e);return a});s.formula2JavaScript=function(t,e){return K(t,e).replace("==","===")},s.formula2Python=function(t,e){var n=[],r=function(t,e,r,o){var a="",s=t,p={"=":"==","<>":"!=",MIN:"min",MAX:"max",ABS:"math.fabs",SUM:"",IF:"","&":"+",AND:"",OR:"",NOT:"!",TRUE:"True",FALSE:"False"},u=n[n.length-1],l=!1;switch(e.type.toString()){case g:switch(e.subtype){case x:n.push({name:s,argumentNumber:0}),a="string"==typeof p[s.toUpperCase()]?p[s.toUpperCase()]:s,l=!0;break;case O:switch(l=!0,u.name.toLowerCase()){case"if":a=",))[0]",1===u.argumentNumber&&(a=" or (0"+a),l=!1;break;default:a="string"==typeof p[s.toUpperCase()]?p[s.toUpperCase()]:s}n.pop()}break;case S:switch(u.name.toLowerCase()){case"if":switch(u.argumentNumber){case 0:a=" and (";break;case 1:a=",) or ("}break;case"sum":a="+";break;case"and":a=" and ";break;case"or":a=" or ";break;default:a="string"==typeof p[s.toUpperCase()]?p[s.toUpperCase()]:s,l=!0}u.argumentNumber+=1;break;case m:switch(e.subtype){case _:if(!u)break;if(RegExp("true|false","gi").test(s)){a="string"==typeof p[s.toUpperCase()]?p[s.toUpperCase()]:s;break}switch(u.name.toLowerCase()){case"sum":RegExp(":","gi").test(s)?a=i(s,"+"):outStr=s;break;case"and":RegExp(":","gi").test(s)?a=i(s," and "):outStr=s;break;case"or":RegExp(":","gi").test(s)?a=i(s," or "):outStr=s;break;default:a=RegExp(":","gi").test(s)?"["+i(s,",")+"]":s}}default:""===a&&(a="string"==typeof p[s.toUpperCase()]?p[s.toUpperCase()]:s),l=!0}return{tokenString:a,useTemplate:l}},o={tmplFunctionStart:"{{token}}(",tmplFunctionStop:"{{token}})",tmplOperandError:"{{token}}",tmplOperandRange:"{{token}}",tmplOperandLogical:"{{token}}",tmplOperandNumber:"{{token}}",tmplOperandText:'"{{token}}"',tmplArgument:"{{token}}",tmplOperandOperatorInfix:"{{token}}",tmplFunctionStartArray:"",tmplFunctionStartArrayRow:"{",tmplFunctionStopArrayRow:"}",tmplFunctionStopArray:"",tmplSubexpressionStart:"(",tmplSubexpressionStop:")",tmplIndentTab:"\t",tmplIndentSpace:" ",autoLineBreak:"TOK_SUBTYPE_STOP | TOK_SUBTYPE_START | TOK_TYPE_ARGUMENT",trim:!0,customTokenRender:r};e=e?p.extend(!0,o,e):o;var a=Y(t,e);return a};s.getTokens=o}(window||module.exports||{}); -------------------------------------------------------------------------------- /docs/core.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | core.js 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 | 39 | 40 |
    41 | 42 |
  • 43 |
    44 |

    core.js

    45 |
    46 |
  • 47 | 48 | 49 | 50 |
  • 51 |
    52 | 53 |
    54 | 55 |
    56 | 57 |
    58 | 59 |
    /*
     60 |  * excelFormulaUtilitiesJS
     61 |  * https://github.com/joshatjben/excelFormulaUtilitiesJS/
     62 |  *
     63 |  * Copyright 2011, Josh Bennett
     64 |  * licensed under the MIT license.
     65 |  * https://github.com/joshatjben/excelFormulaUtilitiesJS/blob/master/LICENSE.txt
     66 |  *
     67 |  * Some functionality based off of the jquery core lib
     68 |  * Copyright 2011, John Resig
     69 |  * Dual licensed under the MIT or GPL Version 2 licenses.
     70 |  * http://jquery.org/license
     71 |  *
     72 |  * Based on Ewbi's Go Calc Prototype Excel Formula Parser. [http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html]
     73 |  */
     74 |  
     75 | (function () {
     76 | 
     77 |     if (typeof window === 'undefined') {
     78 |       window = root;
     79 |     }
     80 |     var excelFormulaUtilities = window.excelFormulaUtilities = window.excelFormulaUtilities || {};
     81 |     var core = window.excelFormulaUtilities.core = {};
     82 | 	window.excelFormulaUtilities.string = window.excelFormulaUtilities.string || {};
     83 | 	
     84 | 	/**
     85 | 	* Simple/quick string formater. This will take an input string and apply n number of arguments to it.
     86 | 	*
     87 | 	* <b>example:</b><br />
     88 | 	* <code>
     89 | 	* <pre>
     90 | 	*	var foo = excelFormulaUtilities.core.formatStr("{0}", "foo"); // foo will be set to "foo"
     91 | 	*	var fooBar = excelFormulaUtilities.core.formatStr("{0} {1}", "foo", "bar"); // fooBar will be set to "fooBar"
     92 | 	*	var error = excelFormulaUtilities.core.formatStr("{1}", "error"); // will throw an index out of range error since only 1 extra argument was passed, which would be index 0.
     93 | 	* </pre>
     94 | 	* </code>
     95 | 	*
     96 |     * @memberOf window.excelFormulaUtilities.core
     97 | 	* @function
     98 |     * @param {String} inStr 
     99 |     **/
    100 | 	var formatStr = window.excelFormulaUtilities.string.formatStr = function(inStr) {
    101 | 			var formattedStr = inStr;
    102 | 			var argIndex = 1;
    103 | 			for (; argIndex < arguments.length; argIndex++) {
    104 | 				var replaceIndex = (argIndex - 1);
    105 | 				var replaceRegex = new RegExp("\\{{1}" + replaceIndex.toString() + "{1}\\}{1}", "g");
    106 | 				formattedStr = formattedStr.replace(replaceRegex, arguments[argIndex]);
    107 | 			}
    108 | 			return formattedStr;
    109 | 		};
    110 |     
    111 |     var trim = window.excelFormulaUtilities.string.trim = function(inStr){
    112 | 			return inStr.replace(/^\s|\s$/, "");
    113 | 		};
    114 | 	
    115 | 	var trimHTML = window.excelFormulaUtilities.string.trim = function(inStr){
    116 | 			return inStr.replace(/^(?:\s|&nbsp;|<\s*br\s*\/*\s*>)*|(?:\s|&nbsp;|<\s*br\s*\/*\s*>)*$/, "");
    117 | 		};
    118 | 119 |
  • 120 | 121 | 122 |
  • 123 |
    124 | 125 |
    126 | 127 |
    128 |

    Quick and dirty type checks

    129 | 130 |
    131 | 132 |
    	/**
    133 | 	* @param {object} obj
    134 | 	* @returns {boolean}
    135 | 	* @memberOf window.excelFormulaUtilities.core
    136 | 	*/
    137 | 	var isFunction = core.isFunction = function (obj) {
    138 | 		return (typeof obj) === "function";
    139 | 	};
    140 | 
    141 | 	/**
    142 | 	* @param {object} obj
    143 | 	* @returns {boolean}
    144 | 	* @memberOf window.excelFormulaUtilities.core
    145 | 	*/
    146 | 	var isArray = core.isArray = function (obj) {
    147 | 		return (typeof obj) === "object" && obj.length;
    148 | 	};
    149 | 
    150 | 	/**
    151 | 	* @param {object} obj
    152 | 	* @returns {boolean}
    153 | 	* @memberOf window.excelFormulaUtilities.core
    154 | 	*/
    155 | 	var isWindow = core.isWindow = function () {
    156 | 		return obj && typeof obj === "object" && "setInterval" in obj;
    157 | 	}; /*----The functionality below has based off of the jQuery core library----*/
    158 | 
    159 | 	/**
    160 | 	* Check if the object is a plain object or not. This has been pulled from the jQuery core and modified slightly.
    161 | 	* @param {object} obj
    162 | 	* @returns {boolean} returns weather the object is a plain object or not.
    163 | 	* @memberOf window.excelFormulaUtilities.core
    164 | 	*/
    165 | 	var isPlainObject = core.isPlainObject = function (obj) {
    166 | 167 |
  • 168 | 169 | 170 |
  • 171 |
    172 | 173 |
    174 | 175 |
    176 |

    Must be an Object. 177 | Because of IE, we also have to check the presence of the constructor property. 178 | Make sure that DOM nodes and window objects don’t pass through, as well

    179 | 180 |
    181 | 182 |
    		if (!obj || typeof obj !== "object" || obj.nodeType || isWindow(obj)) {
    183 | 			return false;
    184 | 		}
    185 | 186 |
  • 187 | 188 | 189 |
  • 190 |
    191 | 192 |
    193 | 194 |
    195 |

    Not own constructor property must be Object

    196 | 197 |
    198 | 199 |
    		if (obj.constructor && !hasOwnProperty.call(obj, "constructor") && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf")) {
    200 | 			return false;
    201 | 		}
    202 | 203 |
  • 204 | 205 | 206 |
  • 207 |
    208 | 209 |
    210 | 211 |
    212 |

    Own properties are enumerated firstly, so to speed up, 213 | if last one is own, then all properties are own.

    214 | 215 |
    216 | 217 |
    		var key;
    218 | 		for (key in obj) { }
    219 | 		return key === undefined || hasOwnProperty.call(obj, key);
    220 | 	};
    221 | 
    222 | 	/**
    223 | 	* This has been pulled from the jQuery core and modified slightly. see http://api.jquery.com/jQuery.extend/
    224 | 	* @param {object} target
    225 | 	* @param {object} object add one or more object to extend the target.
    226 | 	* @returns {object} returns the extended object.
    227 | 	* @memberOf window.excelFormulaUtilities.core
    228 | 	*/
    229 | 	var extend = core.extend = function () {
    230 | 		var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {},
    231 | 		i = 1,
    232 | 		length = arguments.length,
    233 | 		deep = false;
    234 | 235 |
  • 236 | 237 | 238 |
  • 239 |
    240 | 241 |
    242 | 243 |
    244 |

    Handle a deep copy situation

    245 | 246 |
    247 | 248 |
    		if (typeof target === "boolean") {
    249 | 			deep = target;
    250 | 			target = arguments[1] || {};
    251 | 252 |
  • 253 | 254 | 255 |
  • 256 |
    257 | 258 |
    259 | 260 |
    261 |

    skip the boolean and the target

    262 | 263 |
    264 | 265 |
    			i = 2;
    266 | 		}
    267 | 268 |
  • 269 | 270 | 271 |
  • 272 |
    273 | 274 |
    275 | 276 |
    277 |

    Handle case when target is a string or something (possible in deep copy)

    278 | 279 |
    280 | 281 |
    		if (typeof target !== "object" && !isFunction(target)) {
    282 | 			target = {};
    283 | 		}
    284 | 285 |
  • 286 | 287 | 288 |
  • 289 |
    290 | 291 |
    292 | 293 |
    294 |

    extend jQuery itself if only one argument is passed

    295 | 296 |
    297 | 298 |
    		if (length === i) {
    299 | 			target = this;
    300 | 			--i;
    301 | 		}
    302 | 		for (; i < length; i++) {
    303 | 304 |
  • 305 | 306 | 307 |
  • 308 |
    309 | 310 |
    311 | 312 |
    313 |

    Only deal with non-null/undefined values

    314 | 315 |
    316 | 317 |
    			if ((options = arguments[i]) != null) {
    318 | 319 |
  • 320 | 321 | 322 |
  • 323 |
    324 | 325 |
    326 | 327 |
    328 |

    Extend the base object

    329 | 330 |
    331 | 332 |
    				for (name in options) {
    333 | 					src = target[name];
    334 | 					copy = options[name];
    335 | 336 |
  • 337 | 338 | 339 |
  • 340 |
    341 | 342 |
    343 | 344 |
    345 |

    Prevent never-ending loop

    346 | 347 |
    348 | 349 |
    					if (target === copy) {
    350 | 						continue;
    351 | 					}
    352 | 353 |
  • 354 | 355 | 356 |
  • 357 |
    358 | 359 |
    360 | 361 |
    362 |

    Recurse if we’re merging plain objects or arrays

    363 | 364 |
    365 | 366 |
    					if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
    367 | 						if (copyIsArray) {
    368 | 							copyIsArray = false;
    369 | 							clone = src && isArray(src) ? src : [];
    370 | 						} else {
    371 | 							clone = src && isPlainObject(src) ? src : {};
    372 | 						}
    373 | 374 |
  • 375 | 376 | 377 |
  • 378 |
    379 | 380 |
    381 | 382 |
    383 |

    Never move original objects, clone them

    384 | 385 |
    386 | 387 |
    						target[name] = core.extend(deep, clone, copy);
    388 | 389 |
  • 390 | 391 | 392 |
  • 393 |
    394 | 395 |
    396 | 397 |
    398 |

    Don’t bring in undefined values

    399 | 400 |
    401 | 402 |
    					} else if (copy !== undefined) {
    403 | 						target[name] = copy;
    404 | 					}
    405 | 				}
    406 | 			}
    407 | 		}
    408 | 409 |
  • 410 | 411 | 412 |
  • 413 |
    414 | 415 |
    416 | 417 |
    418 |

    Return the modified object

    419 | 420 |
    421 | 422 |
    		return target;
    423 | 	}; /*----end of jquery functionality----*/
    424 | 
    425 | 	
    426 | }());
    427 | 428 |
  • 429 | 430 |
431 |
432 | 433 | 434 | -------------------------------------------------------------------------------- /docs/docco.css: -------------------------------------------------------------------------------- 1 | /*--------------------- Typography ----------------------------*/ 2 | 3 | @font-face { 4 | font-family: 'aller-light'; 5 | src: url('public/fonts/aller-light.eot'); 6 | src: url('public/fonts/aller-light.eot?#iefix') format('embedded-opentype'), 7 | url('public/fonts/aller-light.woff') format('woff'), 8 | url('public/fonts/aller-light.ttf') format('truetype'); 9 | font-weight: normal; 10 | font-style: normal; 11 | } 12 | 13 | @font-face { 14 | font-family: 'aller-bold'; 15 | src: url('public/fonts/aller-bold.eot'); 16 | src: url('public/fonts/aller-bold.eot?#iefix') format('embedded-opentype'), 17 | url('public/fonts/aller-bold.woff') format('woff'), 18 | url('public/fonts/aller-bold.ttf') format('truetype'); 19 | font-weight: normal; 20 | font-style: normal; 21 | } 22 | 23 | @font-face { 24 | font-family: 'novecento-bold'; 25 | src: url('public/fonts/novecento-bold.eot'); 26 | src: url('public/fonts/novecento-bold.eot?#iefix') format('embedded-opentype'), 27 | url('public/fonts/novecento-bold.woff') format('woff'), 28 | url('public/fonts/novecento-bold.ttf') format('truetype'); 29 | font-weight: normal; 30 | font-style: normal; 31 | } 32 | 33 | /*--------------------- Layout ----------------------------*/ 34 | html { height: 100%; } 35 | body { 36 | font-family: "aller-light"; 37 | font-size: 14px; 38 | line-height: 18px; 39 | color: #30404f; 40 | margin: 0; padding: 0; 41 | height:100%; 42 | } 43 | #container { min-height: 100%; } 44 | 45 | a { 46 | color: #000; 47 | } 48 | 49 | b, strong { 50 | font-weight: normal; 51 | font-family: "aller-bold"; 52 | } 53 | 54 | p { 55 | margin: 15px 0 0px; 56 | } 57 | .annotation ul, .annotation ol { 58 | margin: 25px 0; 59 | } 60 | .annotation ul li, .annotation ol li { 61 | font-size: 14px; 62 | line-height: 18px; 63 | margin: 10px 0; 64 | } 65 | 66 | h1, h2, h3, h4, h5, h6 { 67 | color: #112233; 68 | line-height: 1em; 69 | font-weight: normal; 70 | font-family: "novecento-bold"; 71 | text-transform: uppercase; 72 | margin: 30px 0 15px 0; 73 | } 74 | 75 | h1 { 76 | margin-top: 40px; 77 | } 78 | 79 | hr { 80 | border: 0; 81 | background: 1px #ddd; 82 | height: 1px; 83 | margin: 20px 0; 84 | } 85 | 86 | pre, tt, code { 87 | font-size: 12px; line-height: 16px; 88 | font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; 89 | margin: 0; padding: 0; 90 | } 91 | .annotation pre { 92 | display: block; 93 | margin: 0; 94 | padding: 7px 10px; 95 | background: #fcfcfc; 96 | -moz-box-shadow: inset 0 0 10px rgba(0,0,0,0.1); 97 | -webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.1); 98 | box-shadow: inset 0 0 10px rgba(0,0,0,0.1); 99 | overflow-x: auto; 100 | } 101 | .annotation pre code { 102 | border: 0; 103 | padding: 0; 104 | background: transparent; 105 | } 106 | 107 | 108 | blockquote { 109 | border-left: 5px solid #ccc; 110 | margin: 0; 111 | padding: 1px 0 1px 1em; 112 | } 113 | .sections blockquote p { 114 | font-family: Menlo, Consolas, Monaco, monospace; 115 | font-size: 12px; line-height: 16px; 116 | color: #999; 117 | margin: 10px 0 0; 118 | white-space: pre-wrap; 119 | } 120 | 121 | ul.sections { 122 | list-style: none; 123 | padding:0 0 5px 0;; 124 | margin:0; 125 | } 126 | 127 | /* 128 | Force border-box so that % widths fit the parent 129 | container without overlap because of margin/padding. 130 | 131 | More Info : http://www.quirksmode.org/css/box.html 132 | */ 133 | ul.sections > li > div { 134 | -moz-box-sizing: border-box; /* firefox */ 135 | -ms-box-sizing: border-box; /* ie */ 136 | -webkit-box-sizing: border-box; /* webkit */ 137 | -khtml-box-sizing: border-box; /* konqueror */ 138 | box-sizing: border-box; /* css3 */ 139 | } 140 | 141 | 142 | /*---------------------- Jump Page -----------------------------*/ 143 | #jump_to, #jump_page { 144 | margin: 0; 145 | background: white; 146 | -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; 147 | -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; 148 | font: 16px Arial; 149 | cursor: pointer; 150 | text-align: right; 151 | list-style: none; 152 | } 153 | 154 | #jump_to a { 155 | text-decoration: none; 156 | } 157 | 158 | #jump_to a.large { 159 | display: none; 160 | } 161 | #jump_to a.small { 162 | font-size: 22px; 163 | font-weight: bold; 164 | color: #676767; 165 | } 166 | 167 | #jump_to, #jump_wrapper { 168 | position: fixed; 169 | right: 0; top: 0; 170 | padding: 10px 15px; 171 | margin:0; 172 | } 173 | 174 | #jump_wrapper { 175 | display: none; 176 | padding:0; 177 | } 178 | 179 | #jump_to:hover #jump_wrapper { 180 | display: block; 181 | } 182 | 183 | #jump_page { 184 | padding: 5px 0 3px; 185 | margin: 0 0 25px 25px; 186 | } 187 | 188 | #jump_page .source { 189 | display: block; 190 | padding: 15px; 191 | text-decoration: none; 192 | border-top: 1px solid #eee; 193 | } 194 | 195 | #jump_page .source:hover { 196 | background: #f5f5ff; 197 | } 198 | 199 | #jump_page .source:first-child { 200 | } 201 | 202 | /*---------------------- Low resolutions (> 320px) ---------------------*/ 203 | @media only screen and (min-width: 320px) { 204 | .pilwrap { display: none; } 205 | 206 | ul.sections > li > div { 207 | display: block; 208 | padding:5px 10px 0 10px; 209 | } 210 | 211 | ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol { 212 | padding-left: 30px; 213 | } 214 | 215 | ul.sections > li > div.content { 216 | overflow-x:auto; 217 | -webkit-box-shadow: inset 0 0 5px #e5e5ee; 218 | box-shadow: inset 0 0 5px #e5e5ee; 219 | border: 1px solid #dedede; 220 | margin:5px 10px 5px 10px; 221 | padding-bottom: 5px; 222 | } 223 | 224 | ul.sections > li > div.annotation pre { 225 | margin: 7px 0 7px; 226 | padding-left: 15px; 227 | } 228 | 229 | ul.sections > li > div.annotation p tt, .annotation code { 230 | background: #f8f8ff; 231 | border: 1px solid #dedede; 232 | font-size: 12px; 233 | padding: 0 0.2em; 234 | } 235 | } 236 | 237 | /*---------------------- (> 481px) ---------------------*/ 238 | @media only screen and (min-width: 481px) { 239 | #container { 240 | position: relative; 241 | } 242 | body { 243 | background-color: #F5F5FF; 244 | font-size: 15px; 245 | line-height: 21px; 246 | } 247 | pre, tt, code { 248 | line-height: 18px; 249 | } 250 | p, ul, ol { 251 | margin: 0 0 15px; 252 | } 253 | 254 | 255 | #jump_to { 256 | padding: 5px 10px; 257 | } 258 | #jump_wrapper { 259 | padding: 0; 260 | } 261 | #jump_to, #jump_page { 262 | font: 10px Arial; 263 | text-transform: uppercase; 264 | } 265 | #jump_page .source { 266 | padding: 5px 10px; 267 | } 268 | #jump_to a.large { 269 | display: inline-block; 270 | } 271 | #jump_to a.small { 272 | display: none; 273 | } 274 | 275 | 276 | 277 | #background { 278 | position: absolute; 279 | top: 0; bottom: 0; 280 | width: 350px; 281 | background: #fff; 282 | border-right: 1px solid #e5e5ee; 283 | z-index: -1; 284 | } 285 | 286 | ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol { 287 | padding-left: 40px; 288 | } 289 | 290 | ul.sections > li { 291 | white-space: nowrap; 292 | } 293 | 294 | ul.sections > li > div { 295 | display: inline-block; 296 | } 297 | 298 | ul.sections > li > div.annotation { 299 | max-width: 350px; 300 | min-width: 350px; 301 | min-height: 5px; 302 | padding: 13px; 303 | overflow-x: hidden; 304 | white-space: normal; 305 | vertical-align: top; 306 | text-align: left; 307 | } 308 | ul.sections > li > div.annotation pre { 309 | margin: 15px 0 15px; 310 | padding-left: 15px; 311 | } 312 | 313 | ul.sections > li > div.content { 314 | padding: 13px; 315 | vertical-align: top; 316 | border: none; 317 | -webkit-box-shadow: none; 318 | box-shadow: none; 319 | } 320 | 321 | .pilwrap { 322 | position: relative; 323 | display: inline; 324 | } 325 | 326 | .pilcrow { 327 | font: 12px Arial; 328 | text-decoration: none; 329 | color: #454545; 330 | position: absolute; 331 | top: 3px; left: -20px; 332 | padding: 1px 2px; 333 | opacity: 0; 334 | -webkit-transition: opacity 0.2s linear; 335 | } 336 | .for-h1 .pilcrow { 337 | top: 47px; 338 | } 339 | .for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow { 340 | top: 35px; 341 | } 342 | 343 | ul.sections > li > div.annotation:hover .pilcrow { 344 | opacity: 1; 345 | } 346 | } 347 | 348 | /*---------------------- (> 1025px) ---------------------*/ 349 | @media only screen and (min-width: 1025px) { 350 | 351 | body { 352 | font-size: 16px; 353 | line-height: 24px; 354 | } 355 | 356 | #background { 357 | width: 525px; 358 | } 359 | ul.sections > li > div.annotation { 360 | max-width: 525px; 361 | min-width: 525px; 362 | padding: 10px 25px 1px 50px; 363 | } 364 | ul.sections > li > div.content { 365 | padding: 9px 15px 16px 25px; 366 | } 367 | } 368 | 369 | /*---------------------- Syntax Highlighting -----------------------------*/ 370 | 371 | td.linenos { background-color: #f0f0f0; padding-right: 10px; } 372 | span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } 373 | /* 374 | 375 | github.com style (c) Vasily Polovnyov 376 | 377 | */ 378 | 379 | pre code { 380 | display: block; padding: 0.5em; 381 | color: #000; 382 | background: #f8f8ff 383 | } 384 | 385 | pre .hljs-comment, 386 | pre .hljs-template_comment, 387 | pre .hljs-diff .hljs-header, 388 | pre .hljs-javadoc { 389 | color: #408080; 390 | font-style: italic 391 | } 392 | 393 | pre .hljs-keyword, 394 | pre .hljs-assignment, 395 | pre .hljs-literal, 396 | pre .hljs-css .hljs-rule .hljs-keyword, 397 | pre .hljs-winutils, 398 | pre .hljs-javascript .hljs-title, 399 | pre .hljs-lisp .hljs-title, 400 | pre .hljs-subst { 401 | color: #954121; 402 | /*font-weight: bold*/ 403 | } 404 | 405 | pre .hljs-number, 406 | pre .hljs-hexcolor { 407 | color: #40a070 408 | } 409 | 410 | pre .hljs-string, 411 | pre .hljs-tag .hljs-value, 412 | pre .hljs-phpdoc, 413 | pre .hljs-tex .hljs-formula { 414 | color: #219161; 415 | } 416 | 417 | pre .hljs-title, 418 | pre .hljs-id { 419 | color: #19469D; 420 | } 421 | pre .hljs-params { 422 | color: #00F; 423 | } 424 | 425 | pre .hljs-javascript .hljs-title, 426 | pre .hljs-lisp .hljs-title, 427 | pre .hljs-subst { 428 | font-weight: normal 429 | } 430 | 431 | pre .hljs-class .hljs-title, 432 | pre .hljs-haskell .hljs-label, 433 | pre .hljs-tex .hljs-command { 434 | color: #458; 435 | font-weight: bold 436 | } 437 | 438 | pre .hljs-tag, 439 | pre .hljs-tag .hljs-title, 440 | pre .hljs-rules .hljs-property, 441 | pre .hljs-django .hljs-tag .hljs-keyword { 442 | color: #000080; 443 | font-weight: normal 444 | } 445 | 446 | pre .hljs-attribute, 447 | pre .hljs-variable, 448 | pre .hljs-instancevar, 449 | pre .hljs-lisp .hljs-body { 450 | color: #008080 451 | } 452 | 453 | pre .hljs-regexp { 454 | color: #B68 455 | } 456 | 457 | pre .hljs-class { 458 | color: #458; 459 | font-weight: bold 460 | } 461 | 462 | pre .hljs-symbol, 463 | pre .hljs-ruby .hljs-symbol .hljs-string, 464 | pre .hljs-ruby .hljs-symbol .hljs-keyword, 465 | pre .hljs-ruby .hljs-symbol .hljs-keymethods, 466 | pre .hljs-lisp .hljs-keyword, 467 | pre .hljs-tex .hljs-special, 468 | pre .hljs-input_number { 469 | color: #990073 470 | } 471 | 472 | pre .hljs-builtin, 473 | pre .hljs-constructor, 474 | pre .hljs-built_in, 475 | pre .hljs-lisp .hljs-title { 476 | color: #0086b3 477 | } 478 | 479 | pre .hljs-preprocessor, 480 | pre .hljs-pi, 481 | pre .hljs-doctype, 482 | pre .hljs-shebang, 483 | pre .hljs-cdata { 484 | color: #999; 485 | font-weight: bold 486 | } 487 | 488 | pre .hljs-deletion { 489 | background: #fdd 490 | } 491 | 492 | pre .hljs-addition { 493 | background: #dfd 494 | } 495 | 496 | pre .hljs-diff .hljs-change { 497 | background: #0086b3 498 | } 499 | 500 | pre .hljs-chunk { 501 | color: #aaa 502 | } 503 | 504 | pre .hljs-tex .hljs-formula { 505 | opacity: 0.5; 506 | } 507 | -------------------------------------------------------------------------------- /docs/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | main.js 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 | 39 | 40 |
    41 | 42 |
  • 43 |
    44 |

    main.js

    45 |
    46 |
  • 47 | 48 | 49 | 50 |
  • 51 |
    52 | 53 |
    54 | 55 |
    56 |

    Generated by CoffeeScript 1.3.3

    57 | 58 |
    59 | 60 |
    (function() {
    61 |   var xl;
    62 | 
    63 |   require('./core');
    64 | 
    65 |   require('./ExcelFormulaUtilities');
    66 | 
    67 |   xl = excelFormulaUtilities;
    68 | 
    69 |   module.exports = {
    70 |     getTokens: function(f) {
    71 |       return xl.getTokens(f).items;
    72 |     },
    73 |     formatFormula: function(f, opts) {
    74 |       return xl.formatFormula(f, opts);
    75 |     },
    76 |     toJavaScript: xl.formula2JavaScript,
    77 |     toCSharp: xl.formula2CSharp
    78 |   };
    79 | 
    80 | }).call(this);
    81 | 82 |
  • 83 | 84 |
85 |
86 | 87 | 88 | -------------------------------------------------------------------------------- /docs/public/fonts/aller-bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/docs/public/fonts/aller-bold.eot -------------------------------------------------------------------------------- /docs/public/fonts/aller-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/docs/public/fonts/aller-bold.ttf -------------------------------------------------------------------------------- /docs/public/fonts/aller-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/docs/public/fonts/aller-bold.woff -------------------------------------------------------------------------------- /docs/public/fonts/aller-light.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/docs/public/fonts/aller-light.eot -------------------------------------------------------------------------------- /docs/public/fonts/aller-light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/docs/public/fonts/aller-light.ttf -------------------------------------------------------------------------------- /docs/public/fonts/aller-light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/docs/public/fonts/aller-light.woff -------------------------------------------------------------------------------- /docs/public/fonts/novecento-bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/docs/public/fonts/novecento-bold.eot -------------------------------------------------------------------------------- /docs/public/fonts/novecento-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/docs/public/fonts/novecento-bold.ttf -------------------------------------------------------------------------------- /docs/public/fonts/novecento-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/docs/public/fonts/novecento-bold.woff -------------------------------------------------------------------------------- /docs/public/stylesheets/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v2.0.1 | MIT License | git.io/normalize */ 2 | 3 | /* ========================================================================== 4 | HTML5 display definitions 5 | ========================================================================== */ 6 | 7 | /* 8 | * Corrects `block` display not defined in IE 8/9. 9 | */ 10 | 11 | article, 12 | aside, 13 | details, 14 | figcaption, 15 | figure, 16 | footer, 17 | header, 18 | hgroup, 19 | nav, 20 | section, 21 | summary { 22 | display: block; 23 | } 24 | 25 | /* 26 | * Corrects `inline-block` display not defined in IE 8/9. 27 | */ 28 | 29 | audio, 30 | canvas, 31 | video { 32 | display: inline-block; 33 | } 34 | 35 | /* 36 | * Prevents modern browsers from displaying `audio` without controls. 37 | * Remove excess height in iOS 5 devices. 38 | */ 39 | 40 | audio:not([controls]) { 41 | display: none; 42 | height: 0; 43 | } 44 | 45 | /* 46 | * Addresses styling for `hidden` attribute not present in IE 8/9. 47 | */ 48 | 49 | [hidden] { 50 | display: none; 51 | } 52 | 53 | /* ========================================================================== 54 | Base 55 | ========================================================================== */ 56 | 57 | /* 58 | * 1. Sets default font family to sans-serif. 59 | * 2. Prevents iOS text size adjust after orientation change, without disabling 60 | * user zoom. 61 | */ 62 | 63 | html { 64 | font-family: sans-serif; /* 1 */ 65 | -webkit-text-size-adjust: 100%; /* 2 */ 66 | -ms-text-size-adjust: 100%; /* 2 */ 67 | } 68 | 69 | /* 70 | * Removes default margin. 71 | */ 72 | 73 | body { 74 | margin: 0; 75 | } 76 | 77 | /* ========================================================================== 78 | Links 79 | ========================================================================== */ 80 | 81 | /* 82 | * Addresses `outline` inconsistency between Chrome and other browsers. 83 | */ 84 | 85 | a:focus { 86 | outline: thin dotted; 87 | } 88 | 89 | /* 90 | * Improves readability when focused and also mouse hovered in all browsers. 91 | */ 92 | 93 | a:active, 94 | a:hover { 95 | outline: 0; 96 | } 97 | 98 | /* ========================================================================== 99 | Typography 100 | ========================================================================== */ 101 | 102 | /* 103 | * Addresses `h1` font sizes within `section` and `article` in Firefox 4+, 104 | * Safari 5, and Chrome. 105 | */ 106 | 107 | h1 { 108 | font-size: 2em; 109 | } 110 | 111 | /* 112 | * Addresses styling not present in IE 8/9, Safari 5, and Chrome. 113 | */ 114 | 115 | abbr[title] { 116 | border-bottom: 1px dotted; 117 | } 118 | 119 | /* 120 | * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome. 121 | */ 122 | 123 | b, 124 | strong { 125 | font-weight: bold; 126 | } 127 | 128 | /* 129 | * Addresses styling not present in Safari 5 and Chrome. 130 | */ 131 | 132 | dfn { 133 | font-style: italic; 134 | } 135 | 136 | /* 137 | * Addresses styling not present in IE 8/9. 138 | */ 139 | 140 | mark { 141 | background: #ff0; 142 | color: #000; 143 | } 144 | 145 | 146 | /* 147 | * Corrects font family set oddly in Safari 5 and Chrome. 148 | */ 149 | 150 | code, 151 | kbd, 152 | pre, 153 | samp { 154 | font-family: monospace, serif; 155 | font-size: 1em; 156 | } 157 | 158 | /* 159 | * Improves readability of pre-formatted text in all browsers. 160 | */ 161 | 162 | pre { 163 | white-space: pre; 164 | white-space: pre-wrap; 165 | word-wrap: break-word; 166 | } 167 | 168 | /* 169 | * Sets consistent quote types. 170 | */ 171 | 172 | q { 173 | quotes: "\201C" "\201D" "\2018" "\2019"; 174 | } 175 | 176 | /* 177 | * Addresses inconsistent and variable font size in all browsers. 178 | */ 179 | 180 | small { 181 | font-size: 80%; 182 | } 183 | 184 | /* 185 | * Prevents `sub` and `sup` affecting `line-height` in all browsers. 186 | */ 187 | 188 | sub, 189 | sup { 190 | font-size: 75%; 191 | line-height: 0; 192 | position: relative; 193 | vertical-align: baseline; 194 | } 195 | 196 | sup { 197 | top: -0.5em; 198 | } 199 | 200 | sub { 201 | bottom: -0.25em; 202 | } 203 | 204 | /* ========================================================================== 205 | Embedded content 206 | ========================================================================== */ 207 | 208 | /* 209 | * Removes border when inside `a` element in IE 8/9. 210 | */ 211 | 212 | img { 213 | border: 0; 214 | } 215 | 216 | /* 217 | * Corrects overflow displayed oddly in IE 9. 218 | */ 219 | 220 | svg:not(:root) { 221 | overflow: hidden; 222 | } 223 | 224 | /* ========================================================================== 225 | Figures 226 | ========================================================================== */ 227 | 228 | /* 229 | * Addresses margin not present in IE 8/9 and Safari 5. 230 | */ 231 | 232 | figure { 233 | margin: 0; 234 | } 235 | 236 | /* ========================================================================== 237 | Forms 238 | ========================================================================== */ 239 | 240 | /* 241 | * Define consistent border, margin, and padding. 242 | */ 243 | 244 | fieldset { 245 | border: 1px solid #c0c0c0; 246 | margin: 0 2px; 247 | padding: 0.35em 0.625em 0.75em; 248 | } 249 | 250 | /* 251 | * 1. Corrects color not being inherited in IE 8/9. 252 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 253 | */ 254 | 255 | legend { 256 | border: 0; /* 1 */ 257 | padding: 0; /* 2 */ 258 | } 259 | 260 | /* 261 | * 1. Corrects font family not being inherited in all browsers. 262 | * 2. Corrects font size not being inherited in all browsers. 263 | * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome 264 | */ 265 | 266 | button, 267 | input, 268 | select, 269 | textarea { 270 | font-family: inherit; /* 1 */ 271 | font-size: 100%; /* 2 */ 272 | margin: 0; /* 3 */ 273 | } 274 | 275 | /* 276 | * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in 277 | * the UA stylesheet. 278 | */ 279 | 280 | button, 281 | input { 282 | line-height: normal; 283 | } 284 | 285 | /* 286 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 287 | * and `video` controls. 288 | * 2. Corrects inability to style clickable `input` types in iOS. 289 | * 3. Improves usability and consistency of cursor style between image-type 290 | * `input` and others. 291 | */ 292 | 293 | button, 294 | html input[type="button"], /* 1 */ 295 | input[type="reset"], 296 | input[type="submit"] { 297 | -webkit-appearance: button; /* 2 */ 298 | cursor: pointer; /* 3 */ 299 | } 300 | 301 | /* 302 | * Re-set default cursor for disabled elements. 303 | */ 304 | 305 | button[disabled], 306 | input[disabled] { 307 | cursor: default; 308 | } 309 | 310 | /* 311 | * 1. Addresses box sizing set to `content-box` in IE 8/9. 312 | * 2. Removes excess padding in IE 8/9. 313 | */ 314 | 315 | input[type="checkbox"], 316 | input[type="radio"] { 317 | box-sizing: border-box; /* 1 */ 318 | padding: 0; /* 2 */ 319 | } 320 | 321 | /* 322 | * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome. 323 | * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome 324 | * (include `-moz` to future-proof). 325 | */ 326 | 327 | input[type="search"] { 328 | -webkit-appearance: textfield; /* 1 */ 329 | -moz-box-sizing: content-box; 330 | -webkit-box-sizing: content-box; /* 2 */ 331 | box-sizing: content-box; 332 | } 333 | 334 | /* 335 | * Removes inner padding and search cancel button in Safari 5 and Chrome 336 | * on OS X. 337 | */ 338 | 339 | input[type="search"]::-webkit-search-cancel-button, 340 | input[type="search"]::-webkit-search-decoration { 341 | -webkit-appearance: none; 342 | } 343 | 344 | /* 345 | * Removes inner padding and border in Firefox 4+. 346 | */ 347 | 348 | button::-moz-focus-inner, 349 | input::-moz-focus-inner { 350 | border: 0; 351 | padding: 0; 352 | } 353 | 354 | /* 355 | * 1. Removes default vertical scrollbar in IE 8/9. 356 | * 2. Improves readability and alignment in all browsers. 357 | */ 358 | 359 | textarea { 360 | overflow: auto; /* 1 */ 361 | vertical-align: top; /* 2 */ 362 | } 363 | 364 | /* ========================================================================== 365 | Tables 366 | ========================================================================== */ 367 | 368 | /* 369 | * Remove most spacing between table cells. 370 | */ 371 | 372 | table { 373 | border-collapse: collapse; 374 | border-spacing: 0; 375 | } -------------------------------------------------------------------------------- /examples/basic_example1/basicExample.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | window.onload = function(){ 4 | 5 | //Beautify an Excel formula, output as text 6 | var formula_1 = 'SUM((A1:A10>=5)*(A1:A10<=10)*A1:A10)'; 7 | document.getElementById('fomatFormula_1').innerHTML = formula_1; 8 | document.getElementById('fomatFormula_1_out').innerHTML = excelFormulaUtilities.formatFormula(formula_1); 9 | 10 | //Beautify an Excel formula, output as html. 11 | var formula_2 = '=RIGHT(A2,LEN(A2)-FIND("*",SUBSTITUTE(A2," ","*",LEN(A2)-LEN(SUBSTITUTE(A2," ","")))))'; 12 | document.getElementById('fomatFormula_2').innerHTML = formula_2; 13 | document.getElementById('fomatFormula_2_out').innerHTML = excelFormulaUtilities.formatFormulaHTML(formula_2); 14 | 15 | //Convert an Excel formula to C# 16 | var formula_3 = '=IF(A2:A3="YES","A2 equals yes", "A2 does not equal yes")'; 17 | document.getElementById('fomatFormula_3').innerHTML = formula_3; 18 | document.getElementById('fomatFormula_3_out').innerHTML = excelFormulaUtilities.formula2CSharp(formula_3); 19 | 20 | //Convert an Excel formula to Javascript 21 | var formula_4 = 'ADDRESS(ROW(DataRange2),COLUMN(DataRange2),4)&":"&ADDRESS(MAX((DataRange2<>"")*ROW(DataRange2)),COLUMN(DataRange2)+COLUMNS(DataRange2)-1,4)'; 22 | document.getElementById('fomatFormula_4').innerHTML = formula_4; 23 | document.getElementById('fomatFormula_4_out').innerHTML = excelFormulaUtilities.formula2JavaScript(formula_4); 24 | 25 | } 26 | 27 | }()) -------------------------------------------------------------------------------- /examples/basic_example1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ExcelFormulaUtilities.js - Basic Example 5 | 6 | 7 | 8 | 9 | 61 | 62 | 63 | 64 | 65 | 66 |
67 |
68 |

Test

69 |
70 | 71 |
72 | 73 |
74 |

excelFormulaUtilities.formatFormula( "" );

75 |

 76 | 			
77 | 78 |
79 |

excelFormulaUtilities.formatFormulaHTML( "" );

80 | 81 |
82 | 83 |
84 |

excelFormulaUtilities.formula2CSharp( "" );

85 | 86 |
87 | 88 |
89 |

excelFormulaUtilities.formula2Javascript( "" );

90 | 91 |
92 | 93 |
94 | 95 |
96 | © copyright 2011 Josh Bennett 97 |
98 |
99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /examples/node_app/index.js: -------------------------------------------------------------------------------- 1 | var formula = require('excel-formula'); 2 | 3 | var unFormattedFormula = '=IF(SUM(A1:A5)>1,"YES","NO")'; 4 | 5 | console.log("Original formula: " + unFormattedFormula); 6 | console.log("Formatted Formula: "); 7 | console.log(formula.formatFormula(unFormattedFormula)); 8 | -------------------------------------------------------------------------------- /examples/node_app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Josh Bennett (http://joshbennett.me/)", 3 | "name": "excel-formula-example-app", 4 | "description": "Simple node example for excel-formula", 5 | "version": "1.0.0", 6 | "main": "index.js", 7 | "engines": { 8 | "node": "*" 9 | }, 10 | "license": "MIT", 11 | "dependenciess": { 12 | "excel-formula": "^1.2.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'), 2 | uglify = require('gulp-uglify'), 3 | rename = require('gulp-rename'), 4 | notify = require('gulp-notify'), 5 | concat = require('gulp-concat'), 6 | del = require('del'), 7 | fs = require('fs.extra'), 8 | paths = { 9 | scripts: ['src/core.js', 'src/ExcelFormulaUtilities.js'], 10 | siteScripts: ['js/page.js', 'js/beautifier.js'], 11 | css: ['bootstrap.min.css', 'css/*.css'] 12 | }; 13 | 14 | gulp.task('update_jquery', function(){ 15 | return gulp.src('node_modules/jquery/dist/jquery.min.*') 16 | .pipe(gulp.dest('js')); 17 | }) 18 | 19 | gulp.task('update_bs_css', function(){ 20 | return gulp.src('node_modules/bootstrap/dist/css/*.min.css') 21 | .pipe(gulp.dest('css')); 22 | }); 23 | 24 | gulp.task('update_bs_js', function(){ 25 | return gulp.src('node_modules/bootstrap/dist/js/*.min.js') 26 | .pipe(gulp.dest('js')); 27 | }); 28 | 29 | gulp.task('update_bs_fonts', function(){ 30 | return gulp.src('node_modules/bootstrap/dist/fonts/*') 31 | .pipe(gulp.dest('fonts')); 32 | }); 33 | 34 | gulp.task('libs', ['update_jquery', 'update_bs_js', 'update_bs_css', 'update_bs_fonts']); 35 | 36 | gulp.task('scripts', function() { 37 | return gulp.src(paths.scripts) 38 | .pipe(concat('core.js')) 39 | .pipe(concat('excel-formula.js')) 40 | .pipe(gulp.dest('dist')) 41 | .pipe(rename({suffix: '.min'})) 42 | .pipe(uglify()) 43 | .pipe(gulp.dest('dist')) 44 | }); 45 | 46 | gulp.task('site', function() { 47 | return gulp.src(paths.siteScripts) 48 | .pipe(concat('page.js')) 49 | .pipe(concat('beautifier.js')) 50 | .pipe(gulp.dest('js/tmp')) 51 | .pipe(rename({suffix: '.min'})) 52 | .pipe(uglify()) 53 | .pipe(gulp.dest('js')) 54 | .on('end', function(){ 55 | fs.rmrfSync('js/tmp/') 56 | }) 57 | }); 58 | 59 | gulp.task('watch', function() { 60 | gulp.watch(paths.scripts, ['scripts']); 61 | gulp.watch(paths.scripts, ['site']); 62 | }); 63 | 64 | gulp.task('default', ['scripts']) 65 | -------------------------------------------------------------------------------- /img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/img/logo.png -------------------------------------------------------------------------------- /index.coffee: -------------------------------------------------------------------------------- 1 | 2 | require './core' 3 | require './ExcelFormulaUtilities' 4 | xl = excelFormulaUtilities 5 | 6 | module.exports = 7 | getTokens: (f) -> xl.getTokens(f).items 8 | formatFormula: (f, opts) -> xl.formatFormula(f, opts) 9 | toJavaScript: xl.formula2JavaScript 10 | toCSharp: xl.formula2CSharp 11 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Online Excel Formula Beautifier 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 41 | 42 | 43 | 44 | 45 | 46 |
47 | 48 |
49 |
50 | Logo 51 |
52 |

Beautify or Convert Excel Formulas to JavaScript.

53 |

Excel Formula Beautifier

54 |
55 |
56 |
57 | 58 |
59 | 60 |
61 |
62 |
63 |

This is a JavaScript and html5 based excel formula beautifier. It can also convert excel formulas to JavaScript. It has been built using Excel Formula Utilities JS

64 |
65 |
66 | 67 | 68 | 69 | 70 |
71 |
72 | 73 | 80 |
81 |
82 | 83 | 84 |
85 | 86 |
87 | 88 |
89 |
90 |
91 | 92 |
93 |
94 |
95 |
96 | 97 | 98 |
99 |
100 |
101 |
102 |

Formatting Options:

103 |
104 |
105 |
106 |
107 | 108 |
109 | 110 |
111 | 112 | 113 |
114 | 115 |
116 | 117 | 118 |
119 | 120 |
121 | 122 |
123 | 124 |
125 | 126 |
127 | 128 | 129 |
130 |
131 |
132 |

Have some feedback or feature requests?

133 |

134 | Post Feedback 135 | Fork Me on GitHub 136 | 137 |

138 |
139 |
140 | 141 |
142 |
143 |
© Copyright 2017 Josh Bennett
144 |
ExcelFormulaUtilities.js Version:
145 |
146 |
147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.3.3 2 | (function() { 3 | var xl; 4 | 5 | require('./src/core'); 6 | 7 | require('./src/ExcelFormulaUtilities'); 8 | 9 | xl = excelFormulaUtilities; 10 | 11 | module.exports = { 12 | getTokens: function(f) { 13 | return xl.getTokens(f).items; 14 | }, 15 | formatFormula: function(f, opts) { 16 | return xl.formatFormula(f, opts); 17 | }, 18 | formatFormulaHTML: xl.formatFormulaHTML, 19 | toJavaScript: xl.formula2JavaScript, 20 | toCSharp: xl.formula2CSharp, 21 | toPython: xl.formula2Python 22 | }; 23 | 24 | }).call(this); 25 | -------------------------------------------------------------------------------- /js/beautifier.js: -------------------------------------------------------------------------------- 1 | //Beautifier.js 2 | // 3 | //Copywrite 2011 Josh Benentt 4 | //License - https://raw.github.com/joshatjben/excelFormulaUtilitiesJS/master/LICENSE.txt 5 | //[on github](https://github.com/joshatjben/excelFormulaUtilitiesJS/tree/master/examples/basic_example1 "github") 6 | // 7 | (function(window, undefiend) { 8 | "use strict"; 9 | //Check and setup name spaces. 10 | window.excelFormulaBeautifier = window.excelFormulaBeautifier || {}; 11 | window.excelFormulaBeautifier.examples = window.excelFormulaBeautifier.examples || {}; 12 | 13 | function htmlReplace(text){ 14 | return text.replace(//gi,">") 15 | } 16 | 17 | //Configuration 18 | //------------------------------- 19 | var config = { 20 | //The ID for the formula Input input/textarea 21 | INPUT_ID: 'formula_input', 22 | //The ID for the formula title area. in this example it spits out the function call; 23 | FORMULA_TITLE_ID: 'fomatFormula_2', 24 | //THE ID for the area to contain the beautified excel formula. 25 | FORMULA_BODY_ID: 'fomatFormula_2_out', 26 | //Use this to set the inital textare/input text area. 27 | DEFAULT_FORMULA: '' 28 | }, 29 | timer = null, 30 | lastMode = "beautify", 31 | //Beautifier Page functionality 32 | //------------------------------- 33 | beautifier = window.excelFormulaBeautifier.examples.beautifier = 34 | (function() { 35 | var oldFormula; 36 | return { 37 | formula: '=IF(SUM( IF(FOO = BAR, 10, 0), 10 ) = 20 , "FOO", "BAR")', 38 | input: null, 39 | formulaTitle: null, 40 | formulaBody: null, 41 | mode: "beautify", 42 | changeMode: function(mode) { 43 | lastMode = mode; 44 | window.excelFormulaBeautifier.examples.beautifier.mode = mode; 45 | window.excelFormulaBeautifier.examples.beautifier.update.call(window.excelFormulaBeautifier.examples.beautifier); 46 | if (typeof _gaq !== 'undefined' && _gaq !== null) 47 | _gaq.push(['_trackEvent', 'Change Mode', 'Select', mode]); 48 | }, 49 | formulaAreaClicked: function() { 50 | if (typeof _gaq !== 'undefined' && _gaq !== null) 51 | _gaq.push(['_trackEvent', 'Formula Input', 'Clicked', lastMode]); 52 | }, 53 | update: function() { 54 | 55 | this.formula = this.input.value; 56 | //Test to see if the formula has changed, if it hasn't don't do anything 57 | if (oldFormula === this.formula) { 58 | return; 59 | } 60 | var numberOfSpaces = document.getElementById("numberOfSpaces").value || 4; 61 | numberOfSpaces = Number.isNaN(parseInt(numberOfSpaces)) ? 4 : Math.min(numberOfSpaces, 10) 62 | document.getElementById("numberOfSpaces").value = numberOfSpaces 63 | // Check to see which mode we're in, render appropriately 64 | try { 65 | switch (this.mode) { 66 | case "beautify": 67 | var spaces = ""; 68 | for (var i = 0; i < numberOfSpaces; i += 1) { 69 | spaces += " " 70 | } 71 | var options = { 72 | tmplIndentTab: '' + spaces + '' 73 | } 74 | this.formulaBody.innerHTML = window.excelFormulaUtilities.formatFormulaHTML(this.formula, options); 75 | break; 76 | case "minify": 77 | this.formulaBody.innerHTML = htmlReplace(this.formula.replace(/\s+/gi, ' ')); 78 | break; 79 | case "js": 80 | this.formulaBody.innerHTML = htmlReplace(window.excelFormulaUtilities.formula2JavaScript(this.formula)); 81 | break; 82 | case "csharp": 83 | this.formulaBody.innerHTML = htmlReplace(window.excelFormulaUtilities.formula2CSharp(this.formula)); 84 | break; 85 | case "python": 86 | this.formulaBody.innerHTML = htmlReplace(window.excelFormulaUtilities.formula2Python(this.formula)); 87 | break; 88 | } 89 | } catch (exception) { 90 | //Do nothing, This should throw an error when the formula is improperly formed, which shouldn't blow things up. 91 | } 92 | clearTimeout(timer) 93 | timer = setTimeout(function() { 94 | if (typeof _gaq !== 'undefined' && _gaq !== null) 95 | _gaq.push(['_trackEvent', 'Formula Input', 'Updated', lastMode]); 96 | }, 97 | 1000); 98 | } 99 | }; 100 | }()); 101 | //On Page Load 102 | //------------------- 103 | window.onload = function() { 104 | beautifier.input = document.getElementById(config.INPUT_ID); 105 | //beautifier.formulaTitle = document.getElementById(config.FORMULA_TITLE_ID); 106 | beautifier.formulaBody = document.getElementById(config.FORMULA_BODY_ID); 107 | beautifier.input.value = beautifier.formula; 108 | beautifier.update(); 109 | //add beautifier.update(); here if if you have set an inital DEFAULT_FORMULA and would like it to render on page load. 110 | var xhttp = new XMLHttpRequest(); 111 | xhttp.onreadystatechange = function() { 112 | if (this.readyState == 4 && this.status == 200) { 113 | var versionText = document.getElementById("version"); 114 | versionText.innerHTML = JSON.parse(xhttp.responseText).version 115 | } 116 | }; 117 | xhttp.open("GET", "package.json", true); 118 | xhttp.send(); 119 | }; 120 | }(window)); 121 | -------------------------------------------------------------------------------- /js/beautifier.min.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";window.addEventListener("load",function(){var e=window.document.getElementById("isEu");e.addEventListener("click",function(){window.excelFormulaUtilities.isEu=e.checked})});var e=new Clipboard("#copyFormulaBtn",{text:function(e){return document.getElementById("fomatFormula_2_out").innerHtml}});e.on("success",function(e){e.clearSelection()}),e.on("error",function(e){})}(),function(e,t){"use strict";function a(e){return e.replace(//gi,">")}e.excelFormulaBeautifier=e.excelFormulaBeautifier||{},e.excelFormulaBeautifier.examples=e.excelFormulaBeautifier.examples||{};var u={INPUT_ID:"formula_input",FORMULA_TITLE_ID:"fomatFormula_2",FORMULA_BODY_ID:"fomatFormula_2_out",DEFAULT_FORMULA:""},n=null,i="beautify",r=e.excelFormulaBeautifier.examples.beautifier=function(){var t;return{formula:'=IF(SUM( IF(FOO = BAR, 10, 0), 10 ) = 20 , "FOO", "BAR")',input:null,formulaTitle:null,formulaBody:null,mode:"beautify",changeMode:function(t){i=t,e.excelFormulaBeautifier.examples.beautifier.mode=t,e.excelFormulaBeautifier.examples.beautifier.update.call(e.excelFormulaBeautifier.examples.beautifier),"undefined"!=typeof _gaq&&null!==_gaq&&_gaq.push(["_trackEvent","Change Mode","Select",t])},formulaAreaClicked:function(){"undefined"!=typeof _gaq&&null!==_gaq&&_gaq.push(["_trackEvent","Formula Input","Clicked",i])},update:function(){if(this.formula=this.input.value,t!==this.formula){var u=document.getElementById("numberOfSpaces").value||4;u=Number.isNaN(parseInt(u))?4:Math.min(u,10),document.getElementById("numberOfSpaces").value=u;try{switch(this.mode){case"beautify":for(var r="",l=0;l'+r+""};this.formulaBody.innerHTML=e.excelFormulaUtilities.formatFormulaHTML(this.formula,o);break;case"minify":this.formulaBody.innerHTML=a(this.formula.replace(/\s+/gi," "));break;case"js":this.formulaBody.innerHTML=a(e.excelFormulaUtilities.formula2JavaScript(this.formula));break;case"csharp":this.formulaBody.innerHTML=a(e.excelFormulaUtilities.formula2CSharp(this.formula));break;case"python":this.formulaBody.innerHTML=a(e.excelFormulaUtilities.formula2Python(this.formula))}}catch(m){}clearTimeout(n),n=setTimeout(function(){"undefined"!=typeof _gaq&&null!==_gaq&&_gaq.push(["_trackEvent","Formula Input","Updated",i])},1e3)}}}}();e.onload=function(){r.input=document.getElementById(u.INPUT_ID),r.formulaBody=document.getElementById(u.FORMULA_BODY_ID),r.input.value=r.formula,r.update();var e=new XMLHttpRequest;e.onreadystatechange=function(){if(4==this.readyState&&200==this.status){var t=document.getElementById("version");t.innerHTML=JSON.parse(e.responseText).version}},e.open("GET","package.json",!0),e.send()}}(window); -------------------------------------------------------------------------------- /js/clipboard.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clipboard.js v1.6.1 3 | * https://zenorocha.github.io/clipboard.js 4 | * 5 | * Licensed MIT © Zeno Rocha 6 | */ 7 | !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.Clipboard=e()}}(function(){var e,t,n;return function e(t,n,o){function i(a,c){if(!n[a]){if(!t[a]){var l="function"==typeof require&&require;if(!c&&l)return l(a,!0);if(r)return r(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var s=n[a]={exports:{}};t[a][0].call(s.exports,function(e){var n=t[a][1][e];return i(n?n:e)},s,s.exports,e,t,n,o)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;a0&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function e(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function e(){var t=this,n="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=document.body.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[n?"right":"left"]="-9999px";var o=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=o+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,document.body.appendChild(this.fakeElem),this.selectedText=(0,i.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function e(){this.fakeHandler&&(document.body.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(document.body.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function e(){this.selectedText=(0,i.default)(this.target),this.copyText()}},{key:"copyText",value:function e(){var t=void 0;try{t=document.execCommand(this.action)}catch(e){t=!1}this.handleResult(t)}},{key:"handleResult",value:function e(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function e(){this.target&&this.target.blur(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function e(){this.removeFake()}},{key:"action",set:function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function e(){return this._action}},{key:"target",set:function e(t){if(void 0!==t){if(!t||"object"!==("undefined"==typeof t?"undefined":r(t))||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function e(){return this._target}}]),e}();e.exports=c})},{select:5}],8:[function(t,n,o){!function(i,r){if("function"==typeof e&&e.amd)e(["module","./clipboard-action","tiny-emitter","good-listener"],r);else if("undefined"!=typeof o)r(n,t("./clipboard-action"),t("tiny-emitter"),t("good-listener"));else{var a={exports:{}};r(a,i.clipboardAction,i.tinyEmitter,i.goodListener),i.clipboard=a.exports}}(this,function(e,t,n,o){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function c(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function l(e,t){var n="data-clipboard-"+e;if(t.hasAttribute(n))return t.getAttribute(n)}var u=i(t),s=i(n),f=i(o),d=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText}},{key:"listenClick",value:function e(t){var n=this;this.listener=(0,f.default)(t,"click",function(e){return n.onClick(e)})}},{key:"onClick",value:function e(t){var n=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new u.default({action:this.action(n),target:this.target(n),text:this.text(n),trigger:n,emitter:this})}},{key:"defaultAction",value:function e(t){return l("action",t)}},{key:"defaultTarget",value:function e(t){var n=l("target",t);if(n)return document.querySelector(n)}},{key:"defaultText",value:function e(t){return l("text",t)}},{key:"destroy",value:function e(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],n="string"==typeof t?[t]:t,o=!!document.queryCommandSupported;return n.forEach(function(e){o=o&&!!document.queryCommandSupported(e)}),o}}]),t}(s.default);e.exports=h})},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8)}); 8 | -------------------------------------------------------------------------------- /js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /js/page.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | "use strict"; 3 | window.addEventListener('load', function() { 4 | var isEu = window.document.getElementById("isEu"); 5 | isEu.addEventListener('click', function() { 6 | window.excelFormulaUtilities.isEu = isEu.checked; 7 | }); 8 | }); 9 | 10 | function selectText(container) { 11 | if (document.selection) { 12 | var range = document.body.createTextRange(); 13 | range.moveToElementText(container); 14 | range.select(); 15 | } else if (window.getSelection) { 16 | window.getSelection().empty() 17 | var range = document.createRange(); 18 | range.selectNode(container); 19 | window.getSelection().addRange(range); 20 | } 21 | } 22 | 23 | var clipboard = new Clipboard('#copyFormulaBtn', { 24 | text: function(trigger) { 25 | return document.getElementById('fomatFormula_2_out').innerHtml; 26 | } 27 | }); 28 | 29 | clipboard.on('success', function(e) { 30 | e.clearSelection(); 31 | }); 32 | 33 | clipboard.on('error', function(e) { 34 | }); 35 | 36 | 37 | }()); 38 | -------------------------------------------------------------------------------- /license.include: -------------------------------------------------------------------------------- 1 | /* 2 | * excelFormulaUtilitiesJS #{VERSION} 3 | * https://github.com/joshatjben/excelFormulaUtilitiesJS/ 4 | * 5 | * Copyright #{YEAR}, Josh Bennett 6 | * licensed under the MIT license. 7 | * https://github.com/joshatjben/excelFormulaUtilitiesJS/blob/master/LICENSE.txt 8 | * 9 | * Some functionality based off of the jQuery(1.6.2) core lib 10 | * Copyright 2011, John Resig 11 | * Dual licensed under the MIT or GPL Version 2 licenses. 12 | * http://jquery.org/license 13 | * 14 | * Based on Ewbi's Go Calc Prototype Excel Formula Parser. [http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html] 15 | */ -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Josh Bennett (http://joshbennett.me/)", 3 | "name": "excel-formula", 4 | "description": "Methods to beautify an excel formula and convert it to JavaScript or C#", 5 | "version": "1.5.0", 6 | "homepage": "http://excelformulabeautifier.com/", 7 | "contributors": [ 8 | { 9 | "name": "Josh Bennett", 10 | "url": "https://github.com/joshbtn" 11 | }, 12 | { 13 | "name": "Adam Schmideg", 14 | "url": "http://adam.schmideg.net" 15 | } 16 | ], 17 | "repository": { 18 | "url": "git://github.com/joshatjben/excelFormulaUtilitiesJS.git" 19 | }, 20 | "keyword": [ 21 | "excel", 22 | "formula", 23 | "convert" 24 | ], 25 | "scripts": { 26 | "test": "./node_modules/mocha/bin/mocha & ./node_modules/qunit/bin/cli.js -t ./test/browser/ExcelFormulaUtilities.test.js -d ./src/core.js -c ./src/ExcelFormulaUtilities.js & ./node_modules/qunit/bin/cli.js -c ./dist/excel-formula.min.js -t ./test/browser/ExcelFormulaUtilities.test.js & ./node_modules/qunit/bin/cli.js -c ./dist/excel-formula.js -t ./test/browser/ExcelFormulaUtilities.test.js" 27 | }, 28 | "main": "index.js", 29 | "engines": { 30 | "node": "*" 31 | }, 32 | "license": "MIT", 33 | "devDependencies": { 34 | "del": "^2.0.2", 35 | "docco": "~0.6.3", 36 | "gulp": "^3.9.0", 37 | "gulp-concat": "^2.6.0", 38 | "gulp-notify": "^2.2.0", 39 | "gulp-rename": "^1.2.2", 40 | "gulp-uglify": "^1.4.1", 41 | "qunit": "~0.7.7", 42 | "fs.extra": "^1.3.2" 43 | }, 44 | "dependencies": { 45 | "bootstrap": "^4.1.3", 46 | "jquery": "^3.2.1" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * -------------------------------------------------------------------------------- /src/core.js: -------------------------------------------------------------------------------- 1 | /* 2 | * excelFormulaUtilitiesJS 3 | * https://github.com/joshatjben/excelFormulaUtilitiesJS/ 4 | * 5 | * Copyright 2011, Josh Bennett 6 | * licensed under the MIT license. 7 | * https://github.com/joshatjben/excelFormulaUtilitiesJS/blob/master/LICENSE.txt 8 | * 9 | * Some functionality based off of the jquery core lib 10 | * Copyright 2011, John Resig 11 | * Dual licensed under the MIT or GPL Version 2 licenses. 12 | * http://jquery.org/license 13 | * 14 | * Based on Ewbi's Go Calc Prototype Excel Formula Parser. [http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html] 15 | */ 16 | 17 | (function () { 18 | 19 | if (typeof window === 'undefined') { 20 | window = global; 21 | } 22 | var excelFormulaUtilities = window.excelFormulaUtilities = window.excelFormulaUtilities || {}; 23 | var core = window.excelFormulaUtilities.core = {}; 24 | window.excelFormulaUtilities.string = window.excelFormulaUtilities.string || {}; 25 | 26 | /** 27 | * Simple/quick string formater. This will take an input string and apply n number of arguments to it. 28 | * 29 | * example:
30 | * 31 | *
 32 | 	*	var foo = excelFormulaUtilities.core.formatStr("{0}", "foo"); // foo will be set to "foo"
 33 | 	*	var fooBar = excelFormulaUtilities.core.formatStr("{0} {1}", "foo", "bar"); // fooBar will be set to "fooBar"
 34 | 	*	var error = excelFormulaUtilities.core.formatStr("{1}", "error"); // will throw an index out of range error since only 1 extra argument was passed, which would be index 0.
 35 | 	* 
36 | *
37 | * 38 | * @memberOf window.excelFormulaUtilities.core 39 | * @function 40 | * @param {String} inStr 41 | **/ 42 | var formatStr = window.excelFormulaUtilities.string.formatStr = function(inStr) { 43 | var formattedStr = inStr; 44 | var argIndex = 1; 45 | for (; argIndex < arguments.length; argIndex++) { 46 | var replaceIndex = (argIndex - 1); 47 | var replaceRegex = new RegExp("\\{{1}" + replaceIndex.toString() + "{1}\\}{1}", "g"); 48 | formattedStr = formattedStr.replace(replaceRegex, arguments[argIndex]); 49 | } 50 | return formattedStr; 51 | }; 52 | 53 | var trim = window.excelFormulaUtilities.string.trim = function(inStr){ 54 | return inStr.replace(/^\s|\s$/, ""); 55 | }; 56 | 57 | var trimHTML = window.excelFormulaUtilities.string.trim = function(inStr){ 58 | return inStr.replace(/^(?:\s| |<\s*br\s*\/*\s*>)*|(?:\s| |<\s*br\s*\/*\s*>)*$/, ""); 59 | }; 60 | 61 | //Quick and dirty type checks 62 | /** 63 | * @param {object} obj 64 | * @returns {boolean} 65 | * @memberOf window.excelFormulaUtilities.core 66 | */ 67 | var isFunction = core.isFunction = function (obj) { 68 | return (typeof obj) === "function"; 69 | }; 70 | 71 | /** 72 | * @param {object} obj 73 | * @returns {boolean} 74 | * @memberOf window.excelFormulaUtilities.core 75 | */ 76 | var isArray = core.isArray = function (obj) { 77 | return (typeof obj) === "object" && obj.length; 78 | }; 79 | 80 | /** 81 | * @param {object} obj 82 | * @returns {boolean} 83 | * @memberOf window.excelFormulaUtilities.core 84 | */ 85 | var isWindow = core.isWindow = function () { 86 | return obj && typeof obj === "object" && "setInterval" in obj; 87 | }; /*----The functionality below has based off of the jQuery core library----*/ 88 | 89 | /** 90 | * Check if the object is a plain object or not. This has been pulled from the jQuery core and modified slightly. 91 | * @param {object} obj 92 | * @returns {boolean} returns weather the object is a plain object or not. 93 | * @memberOf window.excelFormulaUtilities.core 94 | */ 95 | var isPlainObject = core.isPlainObject = function (obj) { 96 | // Must be an Object. 97 | // Because of IE, we also have to check the presence of the constructor property. 98 | // Make sure that DOM nodes and window objects don't pass through, as well 99 | if (!obj || typeof obj !== "object" || obj.nodeType || isWindow(obj)) { 100 | return false; 101 | } 102 | // Not own constructor property must be Object 103 | if (obj.constructor && !hasOwnProperty.call(obj, "constructor") && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf")) { 104 | return false; 105 | } 106 | // Own properties are enumerated firstly, so to speed up, 107 | // if last one is own, then all properties are own. 108 | var lastKey; 109 | for (key in obj) { lastKey = key; } 110 | return lastKey === undefined || hasOwnProperty.call(obj, lastKey); 111 | }; 112 | 113 | /** 114 | * This has been pulled from the jQuery core and modified slightly. see http://api.jquery.com/jQuery.extend/ 115 | * @param {object} target 116 | * @param {object} object add one or more object to extend the target. 117 | * @returns {object} returns the extended object. 118 | * @memberOf window.excelFormulaUtilities.core 119 | */ 120 | var extend = core.extend = function () { 121 | var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, 122 | i = 1, 123 | length = arguments.length, 124 | deep = false; 125 | // Handle a deep copy situation 126 | if (typeof target === "boolean") { 127 | deep = target; 128 | target = arguments[1] || {}; 129 | // skip the boolean and the target 130 | i = 2; 131 | } 132 | // Handle case when target is a string or something (possible in deep copy) 133 | if (typeof target !== "object" && !isFunction(target)) { 134 | target = {}; 135 | } 136 | // extend jQuery itself if only one argument is passed 137 | if (length === i) { 138 | target = this; 139 | --i; 140 | } 141 | for (; i < length; i++) { 142 | // Only deal with non-null/undefined values 143 | if ((options = arguments[i]) != null) { 144 | // Extend the base object 145 | for (name in options) { 146 | src = target[name]; 147 | copy = options[name]; 148 | // Prevent never-ending loop 149 | if (target === copy) { 150 | continue; 151 | } 152 | // Recurse if we're merging plain objects or arrays 153 | if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { 154 | if (copyIsArray) { 155 | copyIsArray = false; 156 | clone = src && isArray(src) ? src : []; 157 | } else { 158 | clone = src && isPlainObject(src) ? src : {}; 159 | } 160 | // Never move original objects, clone them 161 | target[name] = core.extend(deep, clone, copy); 162 | // Don't bring in undefined values 163 | } else if (copy !== undefined) { 164 | target[name] = copy; 165 | } 166 | } 167 | } 168 | } 169 | // Return the modified object 170 | return target; 171 | }; /*----end of jquery functionality----*/ 172 | 173 | 174 | }()); 175 | -------------------------------------------------------------------------------- /test/ExcelFormulaUtilities.test.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const assert = require('assert'); 4 | const formula = require('../index.js'); 5 | 6 | describe("ExcelFormulaUtilities", () => { 7 | 8 | describe("#formatFormula", () => { 9 | 10 | it("should parse a formula that doesn't start with a function. Tests fix for Issue #46.", () => { 11 | let inputFormula='=A1+B1'; 12 | let expected = 'A1 + B1'; 13 | let actual = formula.formatFormula(inputFormula); 14 | assert.equal(actual, expected); 15 | }); 16 | 17 | }); 18 | 19 | describe("#formatFormulaHTML", () => { 20 | 21 | it("should replace < or > signs in a formula with < and >. Tests fix for Issue #58.", () => { 22 | let inputFormula = '"

foo

"'; 23 | let expected = '="<h1>foo</h1>"'; 24 | let actual = formula.formatFormulaHTML(inputFormula); 25 | assert.equal(actual, expected); 26 | }); 27 | }); 28 | 29 | describe("#toCSharp", () => { 30 | it("should parse a formula that doesn't start with a function. Tests fix for Issue #46.", () => { 31 | let inputFormula='=A5'; 32 | let expected = 'A5'; 33 | let actual = formula.toCSharp(inputFormula); 34 | assert.equal(actual, expected); 35 | }); 36 | }); 37 | 38 | describe("#toJavaScript", () => { 39 | it("should parse a formula that doesn't start with a function. Tests fix for Issue #46.", () => { 40 | let inputFormula='=A1+B1'; 41 | let expected = 'A1+B1'; 42 | let actual = formula.toJavaScript(inputFormula); 43 | assert.equal(actual, expected); 44 | }) 45 | }) 46 | 47 | describe("#toPython", () => { 48 | it("Test parsing a formula that does not start with a function. From Issue #46", () => { 49 | let inputFormula='=A1+B1'; 50 | let expected = 'A1+B1'; 51 | let actual = formula.toPython(inputFormula); 52 | assert.equal(actual, expected); 53 | }) 54 | }) 55 | 56 | describe("#arrayliterals", () => { 57 | it("Test parsing a formula that contains array literals. From Issue #89", () => { 58 | let inputFormula='={A1:C2,B2:C3}'; 59 | let expected = '={ A1:C2,
        B2:C3}'; 60 | let actual = formula.formatFormulaHTML(inputFormula); 61 | assert.equal(actual, expected); 62 | }) 63 | }) 64 | 65 | }) 66 | -------------------------------------------------------------------------------- /test/browser/ExcelFormulaUtilities.test.js: -------------------------------------------------------------------------------- 1 | QUnit.module("base26"); 2 | 3 | window.excelFormulaUtilities.isEu = false; 4 | 5 | test("fromBase26", function(){ 6 | var input = 'AAA'; 7 | var expected = '702'; 8 | 9 | equal(excelFormulaUtilities.fromBase26(input), expected, input + " = " + expected); 10 | 11 | input = 'BAA'; 12 | expected = '1378'; 13 | equal(excelFormulaUtilities.fromBase26(input), expected, input + " = " + expected); 14 | 15 | input = 'ZZ'; 16 | expected = '701'; 17 | equal(excelFormulaUtilities.fromBase26(input), expected, input + " = " + expected); 18 | 19 | input = 'A'; 20 | expected = '0'; 21 | equal(excelFormulaUtilities.fromBase26(input), expected, input + " = " + expected); 22 | 23 | input = 'Z'; 24 | expected = '25'; 25 | equal(excelFormulaUtilities.fromBase26(input), expected, input + " = " + expected); 26 | 27 | input = 'AA'; 28 | expected = '26'; 29 | equal(excelFormulaUtilities.fromBase26(input), expected, input + " = " + expected); 30 | 31 | input = 'AC'; 32 | expected = '28'; 33 | equal(excelFormulaUtilities.fromBase26(input), expected, input + " = " + expected); 34 | 35 | input = 'BA'; 36 | expected = '52'; 37 | equal(excelFormulaUtilities.fromBase26(input), expected, input + " = " + expected); 38 | }); 39 | 40 | 41 | QUnit.module("ExcelFormulaUtilities") 42 | /* 43 | test("Test formatFormula ()", function() { 44 | var inputFormula = "IF('foo' = 'foo', 'foo', 'bar')"; 45 | var formattedFormula = 'IF(\n\t"foo" = "foo",\n\t"foo",\n\t"bar"\n)'; 46 | console.log(formattedFormula); 47 | console.log(excelFormulaUtilities.formatFormula(inputFormula)) 48 | //equal(excelFormulaUtilities.formatFormula(inputFormula), "Simple formating example."); 49 | equal(typeof {}, "object", "foo exsits"); 50 | });*/ 51 | 52 | test("formatFormula", function() { 53 | var inputFormula = 'IF("foo" = "foo", "foo", "bar")'; 54 | var expected = 'IF(\n\t"foo" = "foo",\n\t"foo",\n\t"bar"\n)'; 55 | 56 | equal(window.excelFormulaUtilities.formatFormula(inputFormula), expected, "Simple formating example."); 57 | 58 | inputFormula = 'IF(A1="yes", "yes", "no")'; 59 | expected = 'IF(\n\tA1 = "yes",\n\t"yes",\n\t"no"\n)'; 60 | equal(excelFormulaUtilities.formatFormula(inputFormula), expected, "advanced example."); 61 | 62 | inputFormula = '(AC6+AD6+IF(H6="Yes",1,IF(J6="Yes",1,0)))+IF(X6="Yes",1,0)' 63 | expected = '(\n\tAC6 + AD6 +\n\tIF(\n\t\tH6 = \"Yes\",\n\t\t1,\n\t\tIF(\n\t\t\tJ6 = \"Yes\",\n\t\t\t1,\n\t\t\t0\n\t\t)\n\t)\n) +\nIF(\n\tX6 = \"Yes\",\n\t1,\n\t0\n)'; 64 | equal(excelFormulaUtilities.formatFormula(inputFormula), expected, "Encapsulation spacing."); 65 | 66 | inputFormula = 'TEST(1,,,1)'; 67 | expected = 'TEST(\n\t1,\n\t,\n\t,\n\t1\n)'; 68 | equal(excelFormulaUtilities.formatFormula(inputFormula), expected, "multiple commas."); 69 | 70 | window.excelFormulaUtilities.isEu = true; 71 | inputFormula = 'IF(A1="yes"; "yes"; "no")'; 72 | expected = 'IF(\n\tA1 = "yes";\n\t"yes";\n\t"no"\n)'; 73 | equal(excelFormulaUtilities.formatFormula(inputFormula), expected, "Test with ; instead of ,"); 74 | window.excelFormulaUtilities.isEu = false; 75 | 76 | }); 77 | 78 | test("Issue #28", function() { 79 | inputFormula = "'Data Sheet'!$D3"; 80 | expected = "'Data Sheet'!$D3"; 81 | equal(excelFormulaUtilities.formatFormula(inputFormula), expected, "Data sheet ref to stay intact."); 82 | 83 | }) 84 | 85 | /*test("formatFormulaHTML", function() { 86 | 87 | });*/ 88 | 89 | test("formula2CSharp", function() { 90 | var inputFormula = 'IF("foo" = "foo", "foo", "bar")', 91 | expected = '("foo"=="foo"?"foo":"bar")'; 92 | equal(excelFormulaUtilities.formula2CSharp(inputFormula), expected, "Simple if example."); 93 | 94 | inputFormula = 'IF(IF(true, "foo", "bar") = "foo", "foo", "bar")'; 95 | expected = '((true?"foo":"bar")=="foo"?"foo":"bar")'; 96 | equal(excelFormulaUtilities.formula2CSharp(inputFormula), expected, "Nested If Test."); 97 | 98 | inputFormula = 'IF(IF(MAX(1, -10)>0, "foo", "bar") = "foo", "foo", "bar")'; 99 | expected = '((Math.max(1,-10)>0?"foo":"bar")=="foo"?"foo":"bar")'; 100 | equal(excelFormulaUtilities.formula2CSharp(inputFormula), expected, "Nested If Test with a nested function."); 101 | 102 | inputFormula = 'SUM(1,1)'; 103 | expected = '(1+1)'; 104 | equal(excelFormulaUtilities.formula2CSharp(inputFormula), expected, "SUM(1,1)"); 105 | 106 | inputFormula = 'SUM(1,1,1,1)'; 107 | expected = '(1+1+1+1)'; 108 | equal(excelFormulaUtilities.formula2CSharp(inputFormula), expected, "SUM(1,1,1,1)"); 109 | 110 | inputFormula = 'IF(FOO_BAR = "foo bar", "THIS WORKED", "THIS ISN\'T WORKING")'; 111 | expected = '(FOO_BAR=="foo bar"?"THIS WORKED":"THIS ISN\'T WORKING")'; 112 | equal(excelFormulaUtilities.formula2CSharp(inputFormula), expected, "Test that strings keep correct spaces. See issue #2. https://github.com/joshatjben/excelFormulaUtilitiesJS/issues/2"); 113 | }); 114 | 115 | test("Make sure lines don't wrap after 44 indents. Issue #29", function(){ 116 | var inputFormula = '=IF(SUM( IF(FOO = BAR, IF(SUM( IF(FOO = BAR, IF(SUM( IF(FOO = BAR, IF(SUM( IF(FOO = BAR, IF(SUM( IF(FOO = BAR, IF(SUM( IF(FOO = BAR, IF(SUM( IF(FOO = BAR, IF(SUM( IF(FOO = BAR, IF(SUM( IF(FOO = BAR, IF(SUM( IF(FOO = BAR, IF(SUM( IF(FOO = BAR, 10, 0), 10 ) = 20 , "FOO", "BAR"), 0), 10 ) = 20 , "FOO", "BAR"), 0), 10 ) = 20 , "FOO", "BAR"), 0), 10 ) = 20 , "FOO", "BAR"), 0), 10 ) = 20 , "FOO", "BAR"), 0), 10 ) = 20 , "FOO", "BAR"), 0), 10 ) = 20 , "FOO", "BAR"), 0), 10 ) = 20 , "FOO", "BAR"), 0), 10 ) = 20 , "FOO", "BAR"), 0), 10 ) = 20 , "FOO", "BAR"), 0), 10 ) = 20 , "FOO", "BAR")', 117 | expected = 'IF(\n SUM(\n IF(\n FOO = BAR,\n IF(\n SUM(\n IF(\n FOO = BAR,\n IF(\n SUM(\n IF(\n FOO = BAR,\n IF(\n SUM(\n IF(\n FOO = BAR,\n IF(\n SUM(\n IF(\n FOO = BAR,\n IF(\n SUM(\n IF(\n FOO = BAR,\n IF(\n SUM(\n IF(\n FOO = BAR,\n IF(\n SUM(\n IF(\n FOO = BAR,\n IF(\n SUM(\n IF(\n FOO = BAR,\n IF(\n SUM(\n IF(\n FOO = BAR,\n IF(\n SUM(\n IF(\n FOO = BAR,\n 10,\n 0\n ),\n 10\n ) = 20,\n \"FOO\",\n \"BAR\"\n ),\n 0\n ),\n 10\n ) = 20,\n \"FOO\",\n \"BAR\"\n ),\n 0\n ),\n 10\n ) = 20,\n \"FOO\",\n \"BAR\"\n ),\n 0\n ),\n 10\n ) = 20,\n \"FOO\",\n \"BAR\"\n ),\n 0\n ),\n 10\n ) = 20,\n \"FOO\",\n \"BAR\"\n ),\n 0\n ),\n 10\n ) = 20,\n \"FOO\",\n \"BAR\"\n ),\n 0\n ),\n 10\n ) = 20,\n \"FOO\",\n \"BAR\"\n ),\n 0\n ),\n 10\n ) = 20,\n \"FOO\",\n \"BAR\"\n ),\n 0\n ),\n 10\n ) = 20,\n \"FOO\",\n \"BAR\"\n ),\n 0\n ),\n 10\n ) = 20,\n \"FOO\",\n \"BAR\"\n ),\n 0\n ),\n 10\n ) = 20,\n \"FOO\",\n \"BAR\"\n)', 118 | actual = excelFormulaUtilities.formatFormula(inputFormula); 119 | 120 | equal(actual, expected); 121 | }) 122 | 123 | test("formula2JavaScript", function() { 124 | var inputFormula = 'IF("foo" = "foo", "foo", "bar")', 125 | expected = '("foo"==="foo"?"foo":"bar")'; 126 | equal(excelFormulaUtilities.formula2JavaScript(inputFormula), expected, inputFormula + " -- Simple if example."); 127 | 128 | inputFormula = 'IF("foo" = "foo", "foo")', 129 | expected = '("foo"==="foo"?"foo":0)'; 130 | equal(excelFormulaUtilities.formula2JavaScript(inputFormula), expected, inputFormula + " -- If with no else example."); 131 | 132 | inputFormula = 'IF(IF(true, "foo", "bar") = "foo", "foo", "bar")'; 133 | expected = '((true?"foo":"bar")==="foo"?"foo":"bar")'; 134 | equal(excelFormulaUtilities.formula2JavaScript(inputFormula), expected, inputFormula + " -- Nested If Test."); 135 | 136 | inputFormula = 'IF(IF(MAX(1, -10)>0, "foo", "bar") = "foo", "foo", "bar")'; 137 | expected = '((Math.max(1,-10)>0?"foo":"bar")==="foo"?"foo":"bar")'; 138 | equal(excelFormulaUtilities.formula2JavaScript(inputFormula), expected, inputFormula + " -- Nested If Test with a nested function."); 139 | 140 | inputFormula = 'IF(FOO_BAR = "foo bar", "THIS WORKED", "THIS ISN\'T WORKING")'; 141 | expected = '(FOO_BAR==="foo bar"?"THIS WORKED":"THIS ISN\'T WORKING")'; 142 | equal(excelFormulaUtilities.formula2JavaScript(inputFormula), expected, inputFormula + " -- Test that strings keep correct spaces. See issue #2. https://github.com/joshatjben/excelFormulaUtilitiesJS/issues/2"); 143 | 144 | inputFormula = 'SUM(A1:C3)'; 145 | expected = '(A1+B1+C1+A2+B2+C2+A3+B3+C3)'; 146 | equal(excelFormulaUtilities.formula2JavaScript(inputFormula), expected, inputFormula + " -- Make sure the sum of ranges break out, See issue #6 https://github.com/joshatjben/excelFormulaUtilitiesJS/issues/6"); 147 | 148 | inputFormula = 'SUM(AA1:BA3)'; 149 | expected = '(AA1+AB1+AC1+AD1+AE1+AF1+AG1+AH1+AI1+AJ1+AK1+AL1+AM1+AN1+AO1+AP1+AQ1+AR1+AS1+AT1+AU1+AV1+AW1+AX1+AY1+AZ1+BA1+AA2+AB2+AC2+AD2+AE2+AF2+AG2+AH2+AI2+AJ2+AK2+AL2+AM2+AN2+AO2+AP2+AQ2+AR2+AS2+AT2+AU2+AV2+AW2+AX2+AY2+AZ2+BA2+AA3+AB3+AC3+AD3+AE3+AF3+AG3+AH3+AI3+AJ3+AK3+AL3+AM3+AN3+AO3+AP3+AQ3+AR3+AS3+AT3+AU3+AV3+AW3+AX3+AY3+AZ3+BA3)'; 150 | equal(excelFormulaUtilities.formula2JavaScript(inputFormula), expected, inputFormula + " -- Make sure the sum of ranges break out, See issue #6 https://github.com/joshatjben/excelFormulaUtilitiesJS/issues/6"); 151 | 152 | inputFormula = 'SUM(AG39:AG49)'; 153 | expected = '(AG39+AG40+AG41+AG42+AG43+AG44+AG45+AG46+AG47+AG48+AG49)'; 154 | equal(excelFormulaUtilities.formula2JavaScript(inputFormula), expected, inputFormula + " -- Test for @sblommers comment on issue #6 https://github.com/joshatjben/excelFormulaUtilitiesJS/issues/6"); 155 | 156 | inputFormula = 'SUM(AA1:BB2)'; 157 | expected = '(AA1+AB1+AC1+AD1+AE1+AF1+AG1+AH1+AI1+AJ1+AK1+AL1+AM1+AN1+AO1+AP1+AQ1+AR1+AS1+AT1+AU1+AV1+AW1+AX1+AY1+AZ1+BA1+BB1+AA2+AB2+AC2+AD2+AE2+AF2+AG2+AH2+AI2+AJ2+AK2+AL2+AM2+AN2+AO2+AP2+AQ2+AR2+AS2+AT2+AU2+AV2+AW2+AX2+AY2+AZ2+BA2+BB2)'; 158 | equal(excelFormulaUtilities.formula2JavaScript(inputFormula), expected, inputFormula + " -- Test for issue #6 https://github.com/joshatjben/excelFormulaUtilitiesJS/issues/6"); 159 | 160 | 161 | inputFormula = '=FOO(A1:B3)'; 162 | expected = 'FOO([A1,B1,A2,B2,A3,B3])'; 163 | equal(excelFormulaUtilities.formula2JavaScript(inputFormula), expected, "FOO(A1:B3) = Make sure the sum of ranges break out, for non sum function"); 164 | 165 | inputFormula = 'IF(AND(D1="x",C1>B1),"PASS","FAIL")', 166 | expected = '((D1==="x"&&C1>B1)?"PASS":"FAIL")'; 167 | equal(excelFormulaUtilities.formula2JavaScript(inputFormula), expected, inputFormula + " -- AND nested in IF example."); 168 | 169 | inputFormula = 'IF(OR(D1="x",C1>B1),"PASS","FAIL")', 170 | expected = '((D1==="x"||C1>B1)?"PASS":"FAIL")'; 171 | equal(excelFormulaUtilities.formula2JavaScript(inputFormula), expected, inputFormula + " -- OR nested in IF example."); 172 | 173 | inputFormula = 'IF(AND(OR(D1="x",C1>B1),E1="foo"),"PASS","FAIL")', 174 | expected = '(((D1==="x"||C1>B1)&&E1=="foo")?"PASS":"FAIL")'; 175 | equal(excelFormulaUtilities.formula2JavaScript(inputFormula), expected, inputFormula + " -- OR nested in AND nested in IF example."); 176 | }); 177 | 178 | test("space after =", function() { 179 | inputFormula = '= A1 + B2'; 180 | expected = 'A1 + B2'; 181 | equal(excelFormulaUtilities.formatFormula(inputFormula), expected, "space after ="); 182 | }); 183 | 184 | test("Logical operands TRUE and FALSE should not break formatting - found in issue 26", function(){ 185 | 186 | /* 187 | ISSUE: 188 | subtype: "logical" 189 | type: "operand" 190 | value: "TRUE" 191 | */ 192 | 193 | var inputFormula='=IF(True,TRUE,FALSE)', 194 | expected = 'IF(\n\tTrue,\n\tTRUE,\n\tFALSE\n)', 195 | actual = excelFormulaUtilities.formatFormula(inputFormula); 196 | 197 | equal(actual, expected, 'formatFormula'); 198 | 199 | inputFormula='=IF(True,TRUE,FALSE)', 200 | expected = '=IF(
    True,
    TRUE,
    FALSE
)', 201 | actual = excelFormulaUtilities.formatFormulaHTML(inputFormula); 202 | 203 | equal(actual, expected, "html formatting"); 204 | 205 | }) 206 | 207 | test("Test parsing a formula that does not start with a function. From Issue #46", function(){ 208 | var inputFormula='=A1+B1', 209 | expected = 'A1+B1', 210 | actual = excelFormulaUtilities.formula2JavaScript(inputFormula); 211 | 212 | equal(actual, expected, 'Should Covert to JS'); 213 | 214 | inputFormula='=A5', 215 | expected = 'A5', 216 | actual = excelFormulaUtilities.formula2JavaScript(inputFormula); 217 | 218 | equal(actual, expected, "Should convert to JS"); 219 | }) 220 | 221 | 222 | 223 | test("formula2Python", function() { 224 | var inputFormula = 'IF("foo" = "foo", "foo", "bar")', 225 | expected = '("foo"=="foo" and ("foo",) or ("bar",))[0]'; 226 | equal(excelFormulaUtilities.formula2Python(inputFormula), expected, "Simple if example."); 227 | 228 | inputFormula = 'IF(IF(true, "foo", "bar") = "foo", "foo", "bar")'; 229 | expected = '((True and ("foo",) or ("bar",))[0]=="foo" and ("foo",) or ("bar",))[0]'; 230 | equal(excelFormulaUtilities.formula2Python(inputFormula), expected, "Nested If Test."); 231 | 232 | inputFormula = 'IF(IF(MAX(1, -10)>0, "foo", "bar") = "foo", "foo", "bar")'; 233 | expected = '((max(1,-10)>0 and ("foo",) or ("bar",))[0]=="foo" and ("foo",) or ("bar",))[0]'; 234 | equal(excelFormulaUtilities.formula2Python(inputFormula), expected, "Nested If Test with a nested function."); 235 | 236 | inputFormula = 'SUM(1,1)'; 237 | expected = '(1+1)'; 238 | equal(excelFormulaUtilities.formula2Python(inputFormula), expected, "SUM(1,1)"); 239 | 240 | inputFormula = 'SUM(1,1,1,1)'; 241 | expected = '(1+1+1+1)'; 242 | equal(excelFormulaUtilities.formula2Python(inputFormula), expected, "SUM(1,1,1,1)"); 243 | 244 | inputFormula = 'IF(FOO_BAR = "foo bar", "THIS WORKED", "THIS ISN\'T WORKING")'; 245 | expected = '(FOO_BAR=="foo bar" and ("THIS WORKED",) or ("THIS ISN\'T WORKING",))[0]'; 246 | equal(excelFormulaUtilities.formula2Python(inputFormula), expected, "Test that strings keep correct spaces. See issue #2. https://github.com/joshatjben/excelFormulaUtilitiesJS/issues/2"); 247 | }); 248 | -------------------------------------------------------------------------------- /test/browser/build.min.test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 |

Tests for Build

22 |
23 |
24 |

QUnit example

25 |

26 |
27 |

28 |
    29 |
    test markup, will be hidden
    30 |
    31 |
    32 | © copyright 2011 Josh Bennett 33 |
    34 |
    35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /test/browser/build.test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 |
    20 |
    21 |

    Tests for Build

    22 |
    23 |
    24 |

    QUnit example

    25 |

    26 |
    27 |

    28 |
      29 |
      test markup, will be hidden
      30 |
      31 |
      32 | © copyright 2011 Josh Bennett 33 |
      34 |
      35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /test/browser/core.test.js: -------------------------------------------------------------------------------- 1 | //REMOVE ME 2 | module("core"); 3 | 4 | test("Test extend with simple objects", function() { 5 | var target = {foo: "foo"}; 6 | var object = {bar: "bar"}; 7 | var merged = window.excelFormulaUtilities.core.extend(target, object); 8 | equal(typeof merged.foo, "string", "foo exsits"); 9 | equal(typeof merged.bar, "string", "bar exsits"); 10 | }); 11 | 12 | test("Test extend with a simple object extending a function", function() { 13 | var target = function(){return true;} 14 | target.foo = "foo"; 15 | var object = {bar: "bar"}; 16 | var merged = window.excelFormulaUtilities.core.extend(target, object); 17 | 18 | ok(merged(), "merged() is working"); 19 | equal(typeof merged.foo, "string", "foo exsits"); 20 | equal(typeof merged.bar, "string", "bar exsits"); 21 | }); 22 | 23 | module("string"); 24 | 25 | test("formatStr()", function() { 26 | var target = "{0}"; 27 | var target2 = "{0} {1}"; 28 | var append = "hi"; 29 | var append2 = "there"; 30 | var expected1 = "hi"; 31 | var expected2 = "hi there"; 32 | 33 | equal(window.excelFormulaUtilities.string.formatStr(target, append), expected1, "test one") 34 | equal(window.excelFormulaUtilities.string.formatStr(target2, append, append2), expected2, "test two") 35 | 36 | }); -------------------------------------------------------------------------------- /test/browser/dev.parse.debug.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Parse Debug 9 | 10 | 11 | 12 | 13 |
      14 | 15 |
      16 | 17 | 18 | 19 | 20 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /test/browser/dev.test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 |
      20 |
      21 |

      Tests for Build

      22 |
      23 |
      24 |

      QUnit example

      25 |

      26 |
      27 |

      28 |
        29 |
        test markup, will be hidden
        30 |
        31 |
        32 | © copyright 2011 Josh Bennett 33 |
        34 |
        35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /test/browser/qunit/qunit.css: -------------------------------------------------------------------------------- 1 | /** 2 | * QUnit v1.10.0 - A JavaScript Unit Testing Framework 3 | * 4 | * http://qunitjs.com 5 | * 6 | * Copyright 2012 jQuery Foundation and other contributors 7 | * Released under the MIT license. 8 | * http://jquery.org/license 9 | */ 10 | 11 | /** Font Family and Sizes */ 12 | 13 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { 14 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; 15 | } 16 | 17 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } 18 | #qunit-tests { font-size: smaller; } 19 | 20 | 21 | /** Resets */ 22 | 23 | #qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { 24 | margin: 0; 25 | padding: 0; 26 | } 27 | 28 | 29 | /** Header */ 30 | 31 | #qunit-header { 32 | padding: 0.5em 0 0.5em 1em; 33 | 34 | color: #8699a4; 35 | background-color: #0d3349; 36 | 37 | font-size: 1.5em; 38 | line-height: 1em; 39 | font-weight: normal; 40 | 41 | border-radius: 5px 5px 0 0; 42 | -moz-border-radius: 5px 5px 0 0; 43 | -webkit-border-top-right-radius: 5px; 44 | -webkit-border-top-left-radius: 5px; 45 | } 46 | 47 | #qunit-header a { 48 | text-decoration: none; 49 | color: #c2ccd1; 50 | } 51 | 52 | #qunit-header a:hover, 53 | #qunit-header a:focus { 54 | color: #fff; 55 | } 56 | 57 | #qunit-testrunner-toolbar label { 58 | display: inline-block; 59 | padding: 0 .5em 0 .1em; 60 | } 61 | 62 | #qunit-banner { 63 | height: 5px; 64 | } 65 | 66 | #qunit-testrunner-toolbar { 67 | padding: 0.5em 0 0.5em 2em; 68 | color: #5E740B; 69 | background-color: #eee; 70 | overflow: hidden; 71 | } 72 | 73 | #qunit-userAgent { 74 | padding: 0.5em 0 0.5em 2.5em; 75 | background-color: #2b81af; 76 | color: #fff; 77 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; 78 | } 79 | 80 | #qunit-modulefilter-container { 81 | float: right; 82 | } 83 | 84 | /** Tests: Pass/Fail */ 85 | 86 | #qunit-tests { 87 | list-style-position: inside; 88 | } 89 | 90 | #qunit-tests li { 91 | padding: 0.4em 0.5em 0.4em 2.5em; 92 | border-bottom: 1px solid #fff; 93 | list-style-position: inside; 94 | } 95 | 96 | #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { 97 | display: none; 98 | } 99 | 100 | #qunit-tests li strong { 101 | cursor: pointer; 102 | } 103 | 104 | #qunit-tests li a { 105 | padding: 0.5em; 106 | color: #c2ccd1; 107 | text-decoration: none; 108 | } 109 | #qunit-tests li a:hover, 110 | #qunit-tests li a:focus { 111 | color: #000; 112 | } 113 | 114 | #qunit-tests ol { 115 | margin-top: 0.5em; 116 | padding: 0.5em; 117 | 118 | background-color: #fff; 119 | 120 | border-radius: 5px; 121 | -moz-border-radius: 5px; 122 | -webkit-border-radius: 5px; 123 | } 124 | 125 | #qunit-tests table { 126 | border-collapse: collapse; 127 | margin-top: .2em; 128 | } 129 | 130 | #qunit-tests th { 131 | text-align: right; 132 | vertical-align: top; 133 | padding: 0 .5em 0 0; 134 | } 135 | 136 | #qunit-tests td { 137 | vertical-align: top; 138 | } 139 | 140 | #qunit-tests pre { 141 | margin: 0; 142 | white-space: pre-wrap; 143 | word-wrap: break-word; 144 | } 145 | 146 | #qunit-tests del { 147 | background-color: #e0f2be; 148 | color: #374e0c; 149 | text-decoration: none; 150 | } 151 | 152 | #qunit-tests ins { 153 | background-color: #ffcaca; 154 | color: #500; 155 | text-decoration: none; 156 | } 157 | 158 | /*** Test Counts */ 159 | 160 | #qunit-tests b.counts { color: black; } 161 | #qunit-tests b.passed { color: #5E740B; } 162 | #qunit-tests b.failed { color: #710909; } 163 | 164 | #qunit-tests li li { 165 | padding: 5px; 166 | background-color: #fff; 167 | border-bottom: none; 168 | list-style-position: inside; 169 | } 170 | 171 | /*** Passing Styles */ 172 | 173 | #qunit-tests li li.pass { 174 | color: #3c510c; 175 | background-color: #fff; 176 | border-left: 10px solid #C6E746; 177 | } 178 | 179 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } 180 | #qunit-tests .pass .test-name { color: #366097; } 181 | 182 | #qunit-tests .pass .test-actual, 183 | #qunit-tests .pass .test-expected { color: #999999; } 184 | 185 | #qunit-banner.qunit-pass { background-color: #C6E746; } 186 | 187 | /*** Failing Styles */ 188 | 189 | #qunit-tests li li.fail { 190 | color: #710909; 191 | background-color: #fff; 192 | border-left: 10px solid #EE5757; 193 | white-space: pre; 194 | } 195 | 196 | #qunit-tests > li:last-child { 197 | border-radius: 0 0 5px 5px; 198 | -moz-border-radius: 0 0 5px 5px; 199 | -webkit-border-bottom-right-radius: 5px; 200 | -webkit-border-bottom-left-radius: 5px; 201 | } 202 | 203 | #qunit-tests .fail { color: #000000; background-color: #EE5757; } 204 | #qunit-tests .fail .test-name, 205 | #qunit-tests .fail .module-name { color: #000000; } 206 | 207 | #qunit-tests .fail .test-actual { color: #EE5757; } 208 | #qunit-tests .fail .test-expected { color: green; } 209 | 210 | #qunit-banner.qunit-fail { background-color: #EE5757; } 211 | 212 | 213 | /** Result */ 214 | 215 | #qunit-testresult { 216 | padding: 0.5em 0.5em 0.5em 2.5em; 217 | 218 | color: #2b81af; 219 | background-color: #D2E0E6; 220 | 221 | border-bottom: 1px solid white; 222 | } 223 | #qunit-testresult .module-name { 224 | font-weight: bold; 225 | } 226 | 227 | /** Fixture */ 228 | 229 | #qunit-fixture { 230 | position: absolute; 231 | top: -10000px; 232 | left: -10000px; 233 | width: 1000px; 234 | height: 1000px; 235 | } 236 | -------------------------------------------------------------------------------- /testapp.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshbtn/excelFormulaUtilitiesJS/9f00e9081b64aca00065a399e18d126ecebab4b3/testapp.js --------------------------------------------------------------------------------