[
  {
    "path": "LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Andreas Petersson\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "watable\n=======\n\nA jQuery table plugin with sorting, paging, filtering.\nVisit https://oweitman.github.io/watable/doc/index.html for demo and docs.\n"
  },
  {
    "path": "bower.json",
    "content": "{\n    \"name\": \"WATable\",\n    \"version\": \"1.10.3\",\n    \"homepage\": \"http://wootapa-watable.appspot.com\",\n    \"authors\": [\"Andreas Petersson <apesv03@gmail.com>\"],\n    \"description\": \"A swiss army jQuery table plugin. Filter, format, paginate and sort your data with ease and lightning speed.\",\n    \"main\": [\n        \"jquery.watable.js\",\n        \"watable.css\"\n    ],\n    \"keywords\": [\n        \"table\",\n        \"jquery\",\n        \"paginate\",\n        \"sort\",\n        \"filter\"\n    ],\n    \"ignore\": [\n        \"index.html\"\n    ],\n    \"dependencies\": {\n        \"jquery\": \">= 1.7.1\",\n        \"bootstrap\": \">= 3.2.0\"\n    }\n}"
  },
  {
    "path": "index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <title>WATable</title>\n    <script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.js\" type=\"text/javascript\"></script>\n    <script src=\"http://netdna.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js\" type=\"text/javascript\"></script>\n    <script src=\"jquery.watable.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n    <link rel='stylesheet' href=\"http://netdna.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css\" />\n    <link rel='stylesheet' href='watable.css'/>\n    <style type=\"text/css\">\n        body { padding: 30px; font-size: 12px }\n    </style>\n</head>\n<body>\n    <h2>WATable</h2>\n    <p><a href=\"http://wootapa-watable.appspot.com/\">http://wootapa-watable.appspot.com/</a></p>\n    \n    <h4>Example 1. No options supplied</h4>\n    <div id=\"example1\" style=\"width:auto\"></div>\n    \n    <h4>Example 2. Lots of options supplied</h4>\n    <div id=\"example2\" style=\"width:auto\"></div>\n\n    <script type=\"text/javascript\">\n        $(document).ready( function() {\n                //First example. No options supplied.\n                $('#example1').WATable({\n                    data: generateSampleData(2, true)\n                });\n                \n                //Second example that shows all options.\n                var waTable = $('#example2').WATable({\n                //data: generateSampleData(100), //Initiate with data if you already have it\n                debug:false,                //Prints some debug info to console\n                dataBind: true,             //Auto-updates table when changing data row values. See example below. (Note. You need a column with the 'unique' property)\n                pageSize: 8,                //Initial pagesize\n                pageSizePadding: true,      //Pads with empty rows when pagesize is not met\n                //transition: 'slide',       //Type of transition when paging (bounce, fade, flip, rotate, scroll, slide).Requires https://github.com/daneden/animate.css.\n                //transitionDuration: 0.2,    //Duration of transition in seconds.\n                filter: true,               //Show filter fields\n                sorting: true,              //Enable sorting\n                sortEmptyLast:true,         //Empty values will be shown last\n                columnPicker: true,         //Show the columnPicker button\n                pageSizes: [1,5,8,12,200],  //Set custom pageSizes. Leave empty array to hide button.\n                hidePagerOnEmpty: true,     //Removes the pager if data is empty.\n                checkboxes: true,           //Make rows checkable. (Note. You need a column with the 'unique' property)\n                checkAllToggle:true,        //Show the check-all toggle\n                preFill: true,              //Initially fills the table with empty rows (as many as the pagesize).\n                //url: '/someWebservice'    //Url to a webservice if not setting data manually as we do in this example\n                //urlData: { report:1 }     //Any data you need to pass to the webservice\n                //urlPost: true             //Use POST httpmethod to webservice. Default is GET.\n                types: {                    //If you want, you can supply some properties that will be applied for specific data types.\n                    string: {\n                        //filterTooltip: \"Giggedi...\"    //What to say in tooltip when hoovering filter fields. Set false to remove.\n                        //placeHolder: \"Type here...\"    //What to say in placeholder filter fields. Set false for empty.\n                    },\n                    number: {\n                        decimals: 1   //Sets decimal precision for float types\n                    },\n                    bool: {\n                        //filterTooltip: false\n                    },\n                    date: {\n                      utc: true,            //Show time as universal time, ie without timezones.\n                      //format: 'yy/dd/MM',   //The format. See all possible formats here http://arshaw.com/xdate/#Formatting.\n                      datePicker: true      //Requires \"Datepicker for Bootstrap\" plugin (http://www.eyecon.ro/bootstrap-datepicker).\n                    }\n                },\n                actions: {                //This generates a button where you can add elements.\n                    filter: true,         //If true, the filter fields can be toggled visible and hidden.\n                    columnPicker: true,   //if true, the columnPicker can be toggled visible and hidden.\n                    custom: [             //Add any other elements here. Here is a refresh and export example.\n                      $('<a href=\"#\" class=\"refresh\"><span class=\"glyphicon glyphicon-refresh\"></span>&nbsp;Refresh</a>'),\n                      $('<a href=\"#\" class=\"export all\"><span class=\"glyphicon glyphicon-share\"></span>&nbsp;Export all rows</a>'),\n                      $('<a href=\"#\" class=\"export checked\"><span class=\"glyphicon glyphicon-share\"></span>&nbsp;Export checked rows</a>'),\n                      $('<a href=\"#\" class=\"export filtered\"><span class=\"glyphicon glyphicon-share\"></span>&nbsp;Export filtered rows</a>'),\n                      $('<a href=\"#\" class=\"export rendered\"><span class=\"glyphicon glyphicon-share\"></span>&nbsp;Export rendered rows</a>')\n                    ]\n                },\n                tableCreated: function(data) {    //Fires when the table is created / recreated. Use it if you want to manipulate the table in any way.\n                    console.log('table created'); //data.table holds the html table element.\n                    console.log(data);            //'this' keyword also holds the html table element.\n                },\n                rowClicked: function(data) {      //Fires when a row or anything within is clicked (Note. You need a column with the 'unique' property).\n                    console.log('row clicked');   //data.event holds the original jQuery event.\n                                                  //data.row holds the underlying row you supplied.\n                                                  //data.index holds the index of row in rows array (Useful when you want to remove the row)\n                                                  //data.column holds the underlying column you supplied.\n                                                  //data.checked is true if row is checked. (Set to false/true to have it unchecked/checked)\n                                                  //'this' keyword holds the clicked element.\n\n                    //Removes the row if user clicked on the column called 'remove'.\n                    if (data.column.column == \"remove\") {\n                        data.event.preventDefault();\n                        //Remove fast with dataBind option\n                        waTable.getData().rows.splice(data.index, 1);\n                        Platform.performMicrotaskCheckpoint();\n\n                        //This would have worked fine as well, but is slower\n                        //var d = waTable.getData();\n                        //d.rows.splice(data.index, 1);\n                        //waTable.setData(d);\n                    }\n                    //We can look at classes on the clicked element as well\n                    if (this.classList.contains('someClass')) {\n                        //Do something...\n                    }\n                    //Example toggle checked state\n                    if (data.column.column == \"check\") {\n                        data.checked = !data.checked;\n                    }\n                    console.log(data);\n                },\n                columnClicked: function(data) {    //Fires when a column is clicked\n                  console.log('column clicked');  //data.event holds the original jQuery event\n                  console.log(data);              //data.column holds the underlying column you supplied\n                                                  //data.descending is true when sorted descending (duh)\n                },\n                pageChanged: function(data) {      //Fires when manually changing page\n                  console.log('page changed');    //data.event holds the original jQuery event\n                  console.log(data);              //data.page holds the new page index\n                },\n                pageSizeChanged: function(data) {  //Fires when manually changing pagesize\n                  console.log('pagesize changed');//data.event holds teh original event\n                  console.log(data);              //data.pageSize holds the new pagesize\n                }\n            }).data('WATable');  //This step reaches into the html data property to get the actual WATable object. Important if you want a reference to it as we want here.\n\n            //Generate some data\n            var data = generateSampleData(500);\n            waTable.setData(data);  //Sets the data.\n            //waTable.setData(data, true); //Sets the data but prevents any previously set columns from being overwritten\n            //waTable.setData(data, false, false); //Sets the data and prevents any previously checked rows from being reset\n\n            //Get the data\n            var allRows = waTable.getData(false); //Returns the data you previously set.\n            var checkedRows = waTable.getData(true); //Returns only the checked rows.\n            var filteredRows = waTable.getData(false, true); //Returns only the filtered rows.\n            var renderedRows = waTable.getData(false, false, true) //Returns only the rendered rows.\n\n            //Set options on the fly\n            var pageSize = waTable.option(\"pageSize\"); //Get option\n            //waTable.option(\"pageSize\", pageSize); //Set option\n\n            //Databinding example\n            var row = waTable.getRow(5).row; //Get row with unique value of 5.\n            row.name = \"Data-Binding Works\"; //This would update the table...but only in ultra modern browsers. (See here http://caniuse.com/#search=observe)\n            Platform.performMicrotaskCheckpoint(); //This make sure it also works in browsers not yet compatible with Object.observe. This is the polyfill that's used.(https://github.com/polymer/observe-js).\n\n            //More databinding\n            data.rows.shift(); //Removes the first row.\n            var newRow = generateSampleData(1).rows[0];\n            data.rows.push(newRow); //Add new row\n            Platform.performMicrotaskCheckpoint();\n\n            //Example event handler triggered by the custom refresh link above.\n            $('#example2').on('click', '.refresh', function(e) {\n                e.preventDefault();\n                //Get and set some new data\n                var data = generateSampleData(100);\n                waTable.setData(data, true);\n            });\n            //Example event handler triggered by the custom export links above.\n            $('#example2').on('click', '.export', function(e) {\n                e.preventDefault();\n                var elem = $(e.target);\n                var data;\n                if (elem.hasClass('all')) data = waTable.getData(false);\n                else if (elem.hasClass('checked')) data = waTable.getData(true);\n                else if (elem.hasClass('filtered')) data = waTable.getData(false, true);\n                else if (elem.hasClass('rendered')) data = waTable.getData(false, false, true);\n                console.log(data.rows.length + ' rows returned', data);\n                alert(data.rows.length + ' rows returned.\\nSee data in console.');\n            });\n\n        });\n\n        //Generates some data.\n        function generateSampleData(limit, simpleMode) {\n\n            //First define the columns\n            var cols = {\n                userId: {\n                    index: 1, //The order this column should appear in the table\n                    type: \"number\", //The type. Possible are string, number, bool, date(in milliseconds).\n                    friendly: \"<span class='glyphicon glyphicon-user'></span>\",  //Name that will be used in header. Can also be any html as shown here.\n                    format: \"<a href='#' target='_blank'>{0}</a>\",  //Used to format the data anything you want. Use {0} as placeholder for the actual data.\n                    unique: true,  //This is required if you want checkable rows, databinding or to use the rowClicked callback. Be certain the values are really unique or weird things will happen.\n                    sortOrder: \"asc\", //Data will initially be sorted by this column. Possible are \"asc\" or \"desc\"\n                    tooltip: \"This column has an initial filter\", //Show some additional info about column\n                    filter: \"1..400\" //Set initial filter.\n                },\n                name: {\n                    index: 2,\n                    type: \"string\",\n                    friendly: \"Name\",\n                    cls: \"blue, anotherClass\", //apply some css classes\n                    tooltip: \"This column has a custom placeholder and css classes\", //Show some additional info about column\n                    placeHolder: \"abc123\" //Overrides default placeholder and placeholder specified in data types(row 34).\n                },\n                age: {\n                    index: 3,\n                    type: \"number\",\n                    friendly: \"Age\",\n                    sorting: true, //dont allow sorting\n                    tooltip: \"This column has filtering and sorting turned off\", //Show some additional info about column\n                    filter: false //Removes filter field for this column\n                },\n                weight: {\n                    index: 4,\n                    type: \"number\",\n                    decimals: 2, //Force decimal precision\n                    friendly: \"Weight\",\n                    placeHolder: \"50..90\",\n                    format: \"{0}kg\",\n                    tooltip: \"This column has no tooltip for the filter\", //Show some additional info about column\n                    filterTooltip: false //Turn off tooltip for this column\n                },\n                height: {\n                    index: 5,\n                    type: \"number\",\n                    friendly: \"Height\",\n                    hidden: true //Hides the column. Useful if you want this value later on but not visible to user. It can be made visible if columnPicker is enabled.\n                },\n                important: {\n                    index: 6,\n                    type: \"bool\",\n                    friendly: \"Important\"\n                },\n                someDate: {\n                    index: 7,\n                    type: \"date\", //Don't forget dates are expressed in milliseconds.\n                    friendly: \"SomeDate\"\n                },\n                someDateDay: {\n                    index: 8,\n                    type: \"date\", //Don't forget dates are expressed in milliseconds\n                    dateFormat: \"dddd\", //Special date format. See all possible formats here http://arshaw.com/xdate/#Formatting.\n                    friendly: \"Day\"\n                },\n                remove: {\n                    index: 9,\n                    type: \"string\",\n                    friendly: \"<span class='glyphicon glyphicon-remove'></span>\",\n                    format: \"<a href='#' title='Remove me'><span class='glyphicon glyphicon-remove'></span></a>\",\n                    filter: false,\n                    sorting: false,\n                    hidden: simpleMode //For the sake of this demo, this column gets hidden for example1\n                },\n                check: {\n                    index: 10,\n                    type: \"string\",\n                    friendly: \"<span class='glyphicon glyphicon-check'></span>\",\n                    format: \"<a href='#' title='Toggle checked'><span class='glyphicon glyphicon-check'></span></a>\",\n                    filter: false,\n                    sorting: false,\n                    hidden: simpleMode //For the sake of this demo, this column gets hidden for example1\n                }\n            };\n\n            /*\n              Create the rows (This step is of course normally done by your web server). \n              What's worth mentioning is the special row properties. See some examples below.\n              <column>Format allows you to override column format and have it formatted the way you want.\n              <column>Cls allows you to add css classes on the cell(td) element.\n              row-checkable allows you to prevent rows from being checkable.\n              row-checked allows you to pre-check a row.\n              row-cls allows you to add css classes to the row(tr) element.\n            */\n            var rows = [];\n            var i = 1;\n            while(i <= limit)\n            {\n                //We leave some fields intentionally undefined, so you can see how sorting/filtering works with these.\n                var row = {};\n                row.userId           = i;\n                row.name             = i % 100 == 0 ? undefined : elfName(); //Random name\n                row.age              = Math.floor(Math.random() * 50) + 20; //Random age\n                row.ageFormat        = row.age + (row.age > 50 ? \" (senior)\" : \" (junior)\"); //Special formatting\n                row.weight           = (Math.floor(Math.random() * 40) + 50) + (Math.floor(Math.random() * 100) / 100); //Random weight\n                row.weightCls        = row.weight < 70 ? 'green' : row.weight < 80 && row.weight >= 70 ? 'yellow' : 'red'; //Add css class to cell\n                row.height           = Math.floor(Math.random() * 50) + 150; //Random height\n                row.important        = i % 5 == 0 ? 1 : 0; //Random important\n                row.someDate         = i % 4 == 0 ? undefined : Date.now() + (i*Math.floor(Math.random()*(60 * 60 * 24 * 100))); //Random date\n                row.someDateDay      = i % 4 == 0 ? \"\" : row.someDate; //Use same date as above, but its column has different formatting\n                row[\"row-checkable\"] = i % 4 != 0; //disable checking for every 4th row\n                row[\"row-checked\"]   = i % 3 == 0; //pre check every 3rd row\n                row[\"row-cls\"]       = i % 3 == 0 ? \"gray, anotherClass\" : \"\"; //apply some row css classes for every 3rd row\n                \n                row.secret           = { \"secret\" : \"foobar\" }; //Add something else that you want later(ex in rowClicked event)\n\n                rows.push(row);\n                i++;\n            }\n\n            //Create the returning object. Besides cols and rows, you can also pass any other object you would need later on.\n            var data = {\n                cols: cols,\n                rows: rows,\n                otherStuff: {\n                    thatIMight: 1,\n                    needLater: true\n                }\n            };\n            return data;\n        }\n\n        //Helper function to generate names. Ignore this.\n        function elfName() {\n            var elf_male = new Array(\"Abardon\", \"Acaman\", \"Achard\", \"Ackmard\", \"Agon\", \"Agnar\", \"Abdun\", \"Aidan\", \"Airis\", \"Aldaren\", \"Alderman\", \"Alkirk\", \"Amerdan\", \"Anfarc\", \"Aslan\", \"Actar\", \"Atgur\", \"Atlin\", \"Aldan\", \"Badek\", \"Baduk\", \"Bedic\", \"Beeron\", \"Bein\", \"Bithon\", \"Bohl\", \"Boldel\", \"Bolrock\", \"Bredin\", \"Bredock\", \"Breen\", \"tristan\", \"Bydern\", \"Cainon\", \"Calden\", \"Camon\", \"Cardon\", \"Casdon\", \"Celthric\", \"Cevelt\", \"Chamon\", \"Chidak\", \"Cibrock\", \"Cipyar\", \"Colthan\", \"Connell\", \"Cordale\", \"Cos\", \"Cyton\", \"Daburn\", \"Dawood\", \"Dak\", \"Dakamon\", \"Darkboon\", \"Dark\", \"Darg\", \"Darmor\", \"Darpick\", \"Dask\", \"Deathmar\", \"Derik\", \"Dismer\", \"Dokohan\", \"Doran\", \"Dorn\", \"Dosman\", \"Draghone\", \"Drit\", \"Driz\", \"Drophar\", \"Durmark\", \"Dusaro\", \"Eckard\", \"Efar\", \"Egmardern\", \"Elvar\", \"Elmut\", \"Eli\", \"Elik\", \"Elson\", \"Elthin\", \"Elbane\", \"Eldor\", \"Elidin\", \"Eloon\", \"Enro\", \"Erik\", \"Erim\", \"Eritai\", \"Escariet\", \"Espardo\", \"Etar\", \"Eldar\", \"Elthen\", \"Elfdorn\", \"Etran\", \"Eythil\", \"Fearlock\", \"Fenrirr\", \"Fildon\", \"Firdorn\", \"Florian\", \"Folmer\", \"Fronar\", \"Fydar\", \"Gai\", \"Galin\", \"Galiron\", \"Gametris\", \"Gauthus\", \"Gehardt\", \"Gemedes\", \"Gefirr\", \"Gibolt\", \"Geth\", \"Gom\", \"Gosform\", \"Gothar\", \"Gothor\", \"Greste\", \"Grim\", \"Gryni\", \"Gundir\", \"Gustov\", \"Halmar\", \"Haston\", \"Hectar\", \"Hecton\", \"Helmon\", \"Hermedes\", \"Hezaq\", \"Hildar\", \"Idon\", \"Ieli\", \"Ipdorn\", \"Ibfist\", \"Iroldak\", \"Ixen\", \"Ixil\", \"Izic\", \"Jamik\", \"Jethol\", \"Jihb\", \"Jibar\", \"Jhin\", \"Julthor\", \"Justahl\", \"Kafar\", \"Kaldar\", \"Kelar\", \"Keran\", \"Kib\", \"Kilden\", \"Kilbas\", \"Kildar\", \"Kimdar\", \"Kilder\", \"Koldof\", \"Kylrad\", \"Lackus\", \"Lacspor\", \"Lahorn\", \"Laracal\", \"Ledal\", \"Leith\", \"Lalfar\", \"Lerin\", \"Letor\", \"Lidorn\", \"Lich\", \"Loban\", \"Lox\", \"Ludok\", \"Ladok\", \"Lupin\", \"Lurd\", \"Mardin\", \"Markard\", \"Merklin\", \"Mathar\", \"Meldin\", \"Merdon\", \"Meridan\", \"Mezo\", \"Migorn\", \"Milen\", \"Mitar\", \"Modric\", \"Modum\", \"Madon\", \"Mafur\", \"Mujardin\", \"Mylo\", \"Mythik\", \"Nalfar\", \"Nadorn\", \"Naphazw\", \"Neowald\", \"Nildale\", \"Nizel\", \"Nilex\", \"Niktohal\", \"Niro\", \"Nothar\", \"Nathon\", \"Nadale\", \"Nythil\", \"Ozhar\", \"Oceloth\", \"Odeir\", \"Ohmar\", \"Orin\", \"Oxpar\", \"Othelen\", \"Padan\", \"Palid\", \"Palpur\", \"Peitar\", \"Pendus\", \"Penduhl\", \"Pildoor\", \"Puthor\", \"Phar\", \"Phalloz\", \"Qidan\", \"Quid\", \"Qupar\", \"Randar\", \"Raydan\", \"Reaper\", \"Relboron\", \"Riandur\", \"Rikar\", \"Rismak\", \"Riss\", \"Ritic\", \"Ryodan\", \"Rysdan\", \"Rythen\", \"Rythorn\", \"Sabalz\", \"Sadaron\", \"Safize\", \"Samon\", \"Samot\", \"Secor\", \"Sedar\", \"Senic\", \"Santhil\", \"Sermak\", \"Seryth\", \"Seth\", \"Shane\", \"Shard\", \"Shardo\", \"Shillen\", \"Silco\", \"Sildo\", \"Silpal\", \"Sithik\", \"Soderman\", \"Sothale\", \"Staph\", \"Suktar\", \"zuth\", \"Sutlin\", \"Syr\", \"Syth\", \"Sythril\", \"Talberon\", \"Telpur\", \"Temil\", \"Tamilfist\", \"Tempist\", \"Teslanar\", \"Tespan\", \"Tesio\", \"Thiltran\", \"Tholan\", \"Tibers\", \"Tibolt\", \"Thol\", \"Tildor\", \"Tilthan\", \"Tobaz\", \"Todal\", \"Tothale\", \"Touck\", \"Tok\", \"Tuscan\", \"Tusdar\", \"Tyden\", \"Uerthe\", \"Uhmar\", \"Uhrd\", \"Updar\", \"Uther\", \"Vacon\", \"Valker\", \"Valyn\", \"Vectomon\", \"Veldar\", \"Velpar\", \"Vethelot\", \"Vildher\", \"Vigoth\", \"Vilan\", \"Vildar\", \"Vi\", \"Vinkol\", \"Virdo\", \"Voltain\", \"Wanar\", \"Wekmar\", \"Weshin\", \"Witfar\", \"Wrathran\", \"Waytel\", \"Wathmon\", \"Wider\", \"Wyeth\", \"Xandar\", \"Xavor\", \"Xenil\", \"Xelx\", \"Xithyl\", \"Yerpal\", \"Yesirn\", \"Ylzik\", \"Zak\", \"Zek\", \"Zerin\", \"Zestor\", \"Zidar\", \"Zigmal\", \"Zilex\", \"Zilz\", \"Zio\", \"Zotar\", \"Zutar\", \"Zytan\");\n            var elf_female = new Array(\"Acele Acholate\", \"Ada\", \"Adiannon\", \"Adorra\", \"Ahanna\", \"Akara\", \"Akassa\", \"Akia\", \"Amara\", \"Amarisa\", \"Amarizi\", \"Ana\", \"Andonna\", \"Ariannona\", \"Arina\", \"Arryn\", \"Asada\", \"Awnia\", \"Ayne\", \"Basete\", \"Bathelie\", \"Bethel\", \"Brana\", \"Brynhilde\", \"Calene\", \"Calina\", \"Celestine\", \"Corda\", \"Enaldie\", \"Enoka\", \"Enoona\", \"Errinaya\", \"Fayne\", \"Frederika\", \"Frida\", \"Gvene\", \"Gwethana\", \"Helenia\", \"Hildandi\", \"Helvetica\", \"Idona\", \"Irina\", \"Irene\", \"Illia\", \"Irona\", \"Justalyne\", \"Kassina\", \"Kilia\", \"Kressara\", \"Laela\", \"Laenaya\", \"Lelani\", \"Luna\", \"Linyah\", \"Lyna\", \"Lynessa\", \"Mehande\", \"Melisande\", \"Midiga\", \"Mirayam\", \"Mylene\", \"Naria\", \"Narisa\", \"Nelena\", \"Nimaya\", \"Nymia\", \"Ochala\", \"Olivia\", \"Onathe\", \"Parthinia\", \"Philadona\", \"Prisane\", \"Rhyna\", \"Rivatha\", \"Ryiah\", \"Sanata\", \"Sathe\", \"Senira\", \"Sennetta\", \"Serane\", \"Sevestra\", \"Sidara\", \"Sidathe\", \"Sina\", \"Sunete\", \"Synestra\", \"Sythini\", \"zena\", \"Tabithi\", \"Tomara\", \"Teressa\", \"Tonica\", \"Thea\", \"Teressa\", \"Urda\", \"Usara\", \"Useli\", \"Unessa\", \"ursula\", \"Venessa\", \"Wanera\", \"Wellisa\", \"yeta\", \"Ysane\", \"Yve\", \"Yviene\", \"Zana\", \"Zathe\", \"Zecele\", \"Zenobe\", \"Zema\", \"Zestia\", \"Zilka\", \"Zoucka\", \"Zona\", \"Zyneste\", \"Zynoa\");\n            var elf_surname = new Array(\"Abardon\", \"Acaman\", \"Achard\", \"Ackmard\", \"Agon\", \"Agnar\", \"Aldan\", \"Abdun\", \"Aidan\", \"Airis\", \"Aldaren\", \"Alderman\", \"Alkirk\", \"Amerdan\", \"Anfarc\", \"Aslan\", \"Actar\", \"Atgur\", \"Atlin\", \"Badek\", \"Baduk\", \"Bedic\", \"Beeron\", \"Bein\", \"Bithon\", \"Bohl\", \"Boldel\", \"Bolrock\", \"Bredin\", \"Bredock\", \"Breen\", \"tristan\", \"Bydern\", \"Cainon\", \"Calden\", \"Camon\", \"Cardon\", \"Casdon\", \"Celthric\", \"Cevelt\", \"Chamon\", \"Chidak\", \"Cibrock\", \"Cipyar\", \"Colthan\", \"Connell\", \"Cordale\", \"Cos\", \"Cyton\", \"Daburn\", \"Dawood\", \"Dak\", \"Dakamon\", \"Darkboon\", \"Dark\", \"Dark\", \"Darmor\", \"Darpick\", \"Dask\", \"Deathmar\", \"Derik\", \"Dismer\", \"Dokohan\", \"Doran\", \"Dorn\", \"Dosman\", \"Draghone\", \"Drit\", \"Driz\", \"Drophar\", \"Durmark\", \"Dusaro\", \"Eckard\", \"Efar\", \"Egmardern\", \"Elvar\", \"Elmut\", \"Eli\", \"Elik\", \"Elson\", \"Elthin\", \"Elbane\", \"Eldor\", \"Elidin\", \"Eloon\", \"Enro\", \"Erik\", \"Erim\", \"Eritai\", \"Escariet\", \"Espardo\", \"Etar\", \"Eldar\", \"Elthen\", \"Etran\", \"Eythil\", \"Fearlock\", \"Fenrirr\", \"Fildon\", \"Firdorn\", \"Florian\", \"Folmer\", \"Fronar\", \"Fydar\", \"Gai\", \"Galin\", \"Galiron\", \"Gametris\", \"Gauthus\", \"Gehardt\", \"Gemedes\", \"Gefirr\", \"Gibolt\", \"Geth\", \"Gom\", \"Gosform\", \"Gothar\", \"Gothor\", \"Greste\", \"Grim\", \"Gryni\", \"Gundir\", \"Gustov\", \"Halmar\", \"Haston\", \"Hectar\", \"Hecton\", \"Helmon\", \"Hermedes\", \"Hezaq\", \"Hildar\", \"Idon\", \"Ieli\", \"Ipdorn\", \"Ibfist\", \"Iroldak\", \"Ixen\", \"Ixil\", \"Izic\", \"Jamik\", \"Jethol\", \"Jihb\", \"Jibar\", \"Jhin\", \"Julthor\", \"Justahl\", \"Kafar\", \"Kaldar\", \"Kelar\", \"Keran\", \"Kib\", \"Kilden\", \"Kilbas\", \"Kildar\", \"Kimdar\", \"Kilder\", \"Koldof\", \"Kylrad\", \"Lackus\", \"Lacspor\", \"Lahorn\", \"Laracal\", \"Ledal\", \"Leith\", \"Lalfar\", \"Lerin\", \"Letor\", \"Lidorn\", \"Lich\", \"Loban\", \"Lox\", \"Ludok\", \"Ladok\", \"Lupin\", \"Lurd\", \"Mardin\", \"Markard\", \"Merklin\", \"Mathar\", \"Meldin\", \"Merdon\", \"Meridan\", \"Mezo\", \"Migorn\", \"Milen\", \"Mitar\", \"Modric\", \"Modum\", \"Madon\", \"Mafur\", \"Mujardin\", \"Mylo\", \"Mythik\", \"Nalfar\", \"Nadorn\", \"Naphazw\", \"Neowald\", \"Nildale\", \"Nizel\", \"Nilex\", \"Niktohal\", \"Niro\", \"Nothar\", \"Nathon\", \"Nadale\", \"Nythil\", \"Ozhar\", \"Oceloth\", \"Odeir\", \"Ohmar\", \"Orin\", \"Oxpar\", \"Othelen\", \"Padan\", \"Palid\", \"Palpur\", \"Peitar\", \"Pendus\", \"Penduhl\", \"Pildoor\", \"Puthor\", \"Phar\", \"Phalloz\", \"Qidan\", \"Quid\", \"Qupar\", \"Randar\", \"Raydan\", \"Reaper\", \"Relboron\", \"Riandur\", \"Rikar\", \"Rismak\", \"Riss\", \"Ritic\", \"Ryodan\", \"Rysdan\", \"Rythen\", \"Rythorn\", \"Sabalz\", \"Sadaron\", \"Safize\", \"Samon\", \"Samot\", \"Secor\", \"Sedar\", \"Senic\", \"Santhil\", \"Sermak\", \"Seryth\", \"Seth\", \"Shane\", \"Shard\", \"Shardo\", \"Shillen\", \"Silco\", \"Sildo\", \"Silpal\", \"Sithik\", \"Soderman\", \"Sothale\", \"Staph\", \"Suktar\", \"zuth\", \"Sutlin\", \"Syr\", \"Syth\", \"Sythril\", \"Talberon\", \"Telpur\", \"Temil\", \"Tamilfist\", \"Tempist\", \"Teslanar\", \"Tespan\", \"Tesio\", \"Thiltran\", \"Tholan\", \"Tibers\", \"Tibolt\", \"Thol\", \"Tildor\", \"Tilthan\", \"Tobaz\", \"Todal\", \"Tothale\", \"Touck\", \"Tok\", \"Tuscan\", \"Tusdar\", \"Tyden\", \"Uerthe\", \"Uhmar\", \"Uhrd\", \"Updar\", \"Uther\", \"Vacon\", \"Valker\", \"Valyn\", \"Vectomon\", \"Veldar\", \"Velpar\", \"Vethelot\", \"Vildher\", \"Vigoth\", \"Vilan\", \"Vildar\", \"Vi\", \"Vinkol\", \"Virdo\", \"Voltain\", \"Wanar\", \"Wekmar\", \"Weshin\", \"Witfar\", \"Wrathran\", \"Waytel\", \"Wathmon\", \"Wider\", \"Wyeth\", \"Xandar\", \"Xavor\", \"Xenil\", \"Xelx\", \"Xithyl\", \"Yerpal\", \"Yesirn\", \"Ylzik\", \"Zak\", \"Zek\", \"Zerin\", \"Zestor\", \"Zidar\", \"Zigmal\", \"Zilex\", \"Zilz\", \"Zio\", \"Zotar\", \"Zutar\", \"Zytan\");\n            var prefix_male = elf_male;\n            var prefix_female = elf_female;\n            var suffix = elf_surname;\n            var n1m = parseInt(Math.random() * prefix_male.length);\n            var n1f = parseInt(Math.random() * prefix_female.length);\n            var n2 = parseInt(Math.random() * suffix.length);\n            var n2ekstra = parseInt(Math.random() * suffix.length);\n            var extraname = \"extranahme\";\n            var prename_male = prefix_male[n1m].slice(0, 1).toUpperCase() + prefix_male[n1m].slice(1);\n            var prename_female = prefix_female[n1f].slice(0, 1).toUpperCase() + prefix_female[n1f].slice(1);\n            var sufname = suffix[n2].slice(0, 1).toUpperCase() + suffix[n2].slice(1);\n            var extraname = suffix[n2ekstra].slice(0, 1).toUpperCase() + suffix[n2ekstra].slice(1);\n            var n3 = parseInt(Math.random() * 100);\n            if (n3 <= 40) {\n                name = prename_male + \" \" + sufname\n            } else if (n3 > 40 && n3 <= 70) {\n                name = prename_female + \" \" + sufname\n            }\n            return name;\n        }\n</script>\n</body>\n</html>"
  },
  {
    "path": "jquery.watable.js",
    "content": "/*\n WATable 1.10.3\n Copyright (c) 2012 Andreas Petersson(apesv03@gmail.com)\n http://wootapa-watable.appspot.com/\n\n Permission is hereby granted, free of charge, to any person obtaining\n a copy of this software and associated documentation files (the\n \"Software\"), to deal in the Software without restriction, including\n without limitation the rights to use, copy, modify, merge, publish,\n distribute, sublicense, and/or sell copies of the Software, and to\n permit persons to whom the Software is furnished to do so, subject to\n the following conditions:\n\n The above copyright notice and this permission notice shall be\n included in all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n(function ($, undefined) {\n\n    var WATable = function () {\n\n        var priv = {}; //private api\n        var publ = {}; //public api\n\n        priv.options = {};\n        var defaults = {\n            url: '',  //webservice url\n            urlData: '', //webservice params\n            urlPost: false, //use POST instead of GET\n            debug: false, //prints debug info to console\n            filter: false, //show filter row\n            columnPicker: false, //show columnpicker\n            checkboxes: false, //show body checkboxes\n            checkAllToggle: true, //show check all toggle\n            actions: '', //holds action links\n            pageSize: 10, //current pagesize\n            pageSizePadding: false, //pad with empty rows\n            pageSizes: [10, 20, 30, 40, 50, 'All'], //available pagesizes\n            hidePagerOnEmpty: false, //removes pager if no rows\n            preFill: false, //prefill table with empty rows\n            sorting: true, // enable column sorting\n            sortEmptyLast: true, //empty values will be shown last\n            dataBind: false, //updates table when detecting row data changes\n            types: { //type specific options\n                string: {},\n                number: {},\n                bool: {},\n                date: {}\n            },\n            transition: undefined, //transition type when paging\n            transitionDuration: 0.3 //duration of transition in seconds\n        };\n\n        /* bundled scripts */\n        priv.ext = {};\n        priv.ext.XDate = /* xdate 0.7 */ function(a,b,c,d){function e(){var b=this instanceof e?this:new e,c=arguments,d=c.length,h;typeof c[d-1]==\"boolean\"&&(h=c[--d],c=y(c,0,d));if(d)if(d==1)if(d=c[0],d instanceof a||typeof d==\"number\")b[0]=new a(+d);else if(d instanceof e){var c=b,i=new a(+d[0]);if(f(d))i.toString=G;c[0]=i}else{if(typeof d==\"string\"){b[0]=new a(0);a:{for(var c=d,d=h||!1,i=e.parsers,j=0,k;j<i.length;j++)if(k=i[j](c,d,b)){b=k;break a}b[0]=new a(c)}}}else b[0]=new a(F.apply(a,c)),h||(b[0]=u(b[0]));else b[0]=new a;typeof h==\"boolean\"&&g(b,h);return b}function f(a){return a[0].toString===G}function g(b,c,d){if(c){if(!f(b))d&&(b[0]=new a(F(b[0].getFullYear(),b[0].getMonth(),b[0].getDate(),b[0].getHours(),b[0].getMinutes(),b[0].getSeconds(),b[0].getMilliseconds()))),b[0].toString=G}else f(b)&&(b[0]=d?u(b[0]):new a(+b[0]));return b}function h(a,b,c,d,e){var f=x(s,a[0],e),a=x(t,a[0],e),e=b==1?c%12:f(1),g=!1;d.length==2&&typeof d[1]==\"boolean\"&&(g=d[1],d=[c]);a(b,d);g&&f(1)!=e&&(a(1,[f(1)-1]),a(2,[v(f(0),f(1))]))}function i(a,c,d,e){var d=Number(d),f=b.floor(d);a[\"set\"+B[c]](a[\"get\"+B[c]]()+f,e||!1);f!=d&&c<6&&i(a,c+1,(d-f)*D[c],e)}function j(a,c,d){var a=a.clone().setUTCMode(!0,!0),c=e(c).setUTCMode(!0,!0),f=0;if(d==0||d==1){for(var g=6;g>=d;g--)f/=D[g],f+=s(c,!1,g)-s(a,!1,g);d==1&&(f+=(c.getFullYear()-a.getFullYear())*12)}else d==2?(d=a.toDate().setUTCHours(0,0,0,0),f=c.toDate().setUTCHours(0,0,0,0),f=b.round((f-d)/864e5)+(c-f-(a-d))/864e5):f=(c-a)/[36e5,6e4,1e3,1][d-3];return f}function k(c){var d=c(0),e=c(1),c=c(2),e=new a(F(d,e,c)),f=l(d),c=f;e<f?c=l(d-1):(d=l(d+1),e>=d&&(c=d));return b.floor(b.round((e-c)/864e5)/7)+1}function l(b){b=new a(F(b,0,4));b.setUTCDate(b.getUTCDate()-(b.getUTCDay()+6)%7);return b}function m(a,b,c,e){var f=x(s,a,e),g=x(t,a,e),c=l(c===d?f(0):c);e||(c=u(c));a.setTime(+c);g(2,[f(2)+(b-1)*7])}function n(a,b,c,d,f){var g=e.locales,h=g[e.defaultLocale]||{},i=x(s,a,f),c=(typeof c==\"string\"?g[c]:c)||{};return o(a,b,function(a){if(d)for(var b=(a==7?2:a)-1;b>=0;b--)d.push(i(b));return i(a)},function(a){return c[a]||h[a]},f)}function o(a,b,c,e,f){for(var g,h,i=\"\";g=b.match(E);){i+=b.substr(0,g.index);if(g[1]){h=i;for(var i=a,j=g[1],k=c,l=e,m=f,n=j.length,q=void 0,r=\"\";n>0;)q=p(i,j.substr(0,n),k,l,m),q!==d?(r+=q,j=j.substr(n),n=j.length):n--;i=h+(r+j)}else g[3]?(h=o(a,g[4],c,e,f),parseInt(h.replace(/\\D/g,\"\"),10)&&(i+=h)):i+=g[7]||\"'\";b=b.substr(g.index+g[0].length)}return i+b}function p(a,c,d,f,g){var h=e.formatters[c];if(typeof h==\"string\")return o(a,h,d,f,g);else if(typeof h==\"function\")return h(a,g||!1,f);switch(c){case\"fff\":return A(d(6),3);case\"s\":return d(5);case\"ss\":return A(d(5));case\"m\":return d(4);case\"mm\":return A(d(4));case\"h\":return d(3)%12||12;case\"hh\":return A(d(3)%12||12);case\"H\":return d(3);case\"HH\":return A(d(3));case\"d\":return d(2);case\"dd\":return A(d(2));case\"ddd\":return f(\"dayNamesShort\")[d(7)]||\"\";case\"dddd\":return f(\"dayNames\")[d(7)]||\"\";case\"M\":return d(1)+1;case\"MM\":return A(d(1)+1);case\"MMM\":return f(\"monthNamesShort\")[d(1)]||\"\";case\"MMMM\":return f(\"monthNames\")[d(1)]||\"\";case\"yy\":return(d(0)+\"\").substring(2);case\"yyyy\":return d(0);case\"t\":return q(d,f).substr(0,1).toLowerCase();case\"tt\":return q(d,f).toLowerCase();case\"T\":return q(d,f).substr(0,1);case\"TT\":return q(d,f);case\"z\":case\"zz\":case\"zzz\":return g?c=\"Z\":(f=a.getTimezoneOffset(),a=f<0?\"+\":\"-\",d=b.floor(b.abs(f)/60),f=b.abs(f)%60,g=d,c==\"zz\"?g=A(d):c==\"zzz\"&&(g=A(d)+\":\"+A(f)),c=a+g),c;case\"w\":return k(d);case\"ww\":return A(k(d));case\"S\":return c=d(2),c>10&&c<20?\"th\":[\"st\",\"nd\",\"rd\"][c%10-1]||\"th\"}}function q(a,b){return a(3)<12?b(\"amDesignator\"):b(\"pmDesignator\")}function r(a){return!isNaN(+a[0])}function s(a,b,c){return a[\"get\"+(b?\"UTC\":\"\")+B[c]]()}function t(a,b,c,d){a[\"set\"+(b?\"UTC\":\"\")+B[c]].apply(a,d)}function u(b){return new a(b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate(),b.getUTCHours(),b.getUTCMinutes(),b.getUTCSeconds(),b.getUTCMilliseconds())}function v(b,c){return 32-(new a(F(b,c,32))).getUTCDate()}function w(a){return function(){return a.apply(d,[this].concat(y(arguments)))}}function x(a){var b=y(arguments,1);return function(){return a.apply(d,b.concat(y(arguments)))}}function y(a,b,e){return c.prototype.slice.call(a,b||0,e===d?a.length:e)}function z(a,b){for(var c=0;c<a.length;c++)b(a[c],c)}function A(a,b){b=b||2;for(a+=\"\";a.length<b;)a=\"0\"+a;return a}var B=\"FullYear,Month,Date,Hours,Minutes,Seconds,Milliseconds,Day,Year\".split(\",\"),C=[\"Years\",\"Months\",\"Days\"],D=[12,31,24,60,60,1e3,1],E=/(([a-zA-Z])\\2*)|(\\((('.*?'|\\(.*?\\)|.)*?)\\))|('(.*?)')/,F=a.UTC,G=a.prototype.toUTCString,H=e.prototype;H.length=1;H.splice=c.prototype.splice;H.getUTCMode=w(f);H.setUTCMode=w(g);H.getTimezoneOffset=function(){return f(this)?0:this[0].getTimezoneOffset()};z(B,function(a,b){H[\"get\"+a]=function(){return s(this[0],f(this),b)};b!=8&&(H[\"getUTC\"+a]=function(){return s(this[0],!0,b)});b!=7&&(H[\"set\"+a]=function(a){h(this,b,a,arguments,f(this));return this},b!=8&&(H[\"setUTC\"+a]=function(a){h(this,b,a,arguments,!0);return this},H[\"add\"+(C[b]||a)]=function(a,c){i(this,b,a,c);return this},H[\"diff\"+(C[b]||a)]=function(a){return j(this,a,b)}))});H.getWeek=function(){return k(x(s,this,!1))};H.getUTCWeek=function(){return k(x(s,this,!0))};H.setWeek=function(a,b){m(this,a,b,!1);return this};H.setUTCWeek=function(a,b){m(this,a,b,!0);return this};H.addWeeks=function(a){return this.addDays(Number(a)*7)};H.diffWeeks=function(a){return j(this,a,2)/7};e.parsers=[function(b,c,d){if(b=b.match(/^(\\d{4})(-(\\d{2})(-(\\d{2})([T ](\\d{2}):(\\d{2})(:(\\d{2})(\\.(\\d+))?)?(Z|(([-+])(\\d{2})(:?(\\d{2}))?))?)?)?)?$/)){var e=new a(F(b[1],b[3]?b[3]-1:0,b[5]||1,b[7]||0,b[8]||0,b[10]||0,b[12]?Number(\"0.\"+b[12])*1e3:0));b[13]?b[14]&&e.setUTCMinutes(e.getUTCMinutes()+(b[15]==\"-\"?1:-1)*(Number(b[16])*60+(b[18]?Number(b[18]):0))):c||(e=u(e));return d.setTime(+e)}}];e.parse=function(a){return+e(\"\"+a)};H.toString=function(a,b,c){return a===d||!r(this)?this[0].toString():n(this,a,b,c,f(this))};H.toUTCString=H.toGMTString=function(a,b,c){return a===d||!r(this)?this[0].toUTCString():n(this,a,b,c,!0)};H.toISOString=function(){return this.toUTCString(\"yyyy-MM-dd'T'HH:mm:ss(.fff)zzz\")};e.defaultLocale=\"\";e.locales={\"\":{monthNames:\"January,February,March,April,May,June,July,August,September,October,November,December\".split(\",\"),monthNamesShort:\"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec\".split(\",\"),dayNames:\"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday\".split(\",\"),dayNamesShort:\"Sun,Mon,Tue,Wed,Thu,Fri,Sat\".split(\",\"),amDesignator:\"AM\",pmDesignator:\"PM\"}};e.formatters={i:\"yyyy-MM-dd'T'HH:mm:ss(.fff)\",u:\"yyyy-MM-dd'T'HH:mm:ss(.fff)zzz\"};z(\"getTime,valueOf,toDateString,toTimeString,toLocaleString,toLocaleDateString,toLocaleTimeString,toJSON\".split(\",\"),function(a){H[a]=function(){return this[0][a]()}});H.setTime=function(a){this[0].setTime(a);return this};H.valid=w(r);H.clone=function(){return new e(this)};H.clearTime=function(){return this.setHours(0,0,0,0)};H.toDate=function(){return new a(+this[0])};e.now=function(){return+(new a)};e.today=function(){return(new e).clearTime()};e.UTC=F;e.getDaysInMonth=v;if(typeof module!==\"undefined\"&&module.exports)module.exports=e;return e}(Date,Math,Array);\n\n        //these holds the actual dom table objects, and is used to identify what parts of the table that needs to be created.\n        var _cont; //container holding table\n        var _table; //the table\n        var _head; //table header\n        var _headSort; //table header sorting row\n        var _headFilter; //table header filter row\n        var _body; //table body\n        var _foot; //table footer\n\n        var _data = {};  //columns and rows\n        var _currPage = 1; //current page\n        var _pageSize; //current pagesize\n        var _totalPages = 1; //total pages\n        var _currSortCol; //current sorting column\n        var _currSortFlip = false; //current sorting direction\n        var _currDpOp; //clicked datepicker operator\n        var _filterCols = {}; //array with current filters\n        var _filterTimeout; //timer for delayed filtering\n        var _uniqueCol; //reference to column with the unique property\n        var _checkToggleChecked = false; //check-all toggle state\n        var _dataBind; //true if dataBind\n        var _reservedRowProps = ['AutoFormat']; //internally used row properties\n\n        var _vendors = [\"webkit\", \"moz\", \"Moz\", \"ms\", \"o\", \"O\"]; //vendors prefixes. used for not yet officially supported features.\n        var _transition = {\n            supported: undefined, //true if browser supports transitions\n            doTransition: false,  //true if allowed to transition\n            direction: undefined, //direction of transition.\n            available: {\n                'bounce': {\n                    next: {\n                        tin: 'bounceIn',\n                        tout: 'bounceOut'\n                    },\n                    prev: {\n                        tin: 'bounceIn',\n                        tout: 'bounceOut'\n                    }\n                },\n                'fade': {\n                    next: {\n                        tin: 'fadeIn',\n                        tout: 'fadeOut'\n                    },\n                    prev: {\n                        tin: 'fadeIn',\n                        tout: 'fadeOut'\n                    }\n                },\n                'flip': {\n                    next: {\n                        tin: 'flipInX',\n                        tout: 'flipOutX'\n                    },\n                    prev: {\n                        tin: 'flipInX',\n                        tout: 'flipOutX'\n                    }\n                },\n                'rotate': {\n                    next: {\n                        tin: 'rotateInDownLeft',\n                        tout: 'rotateOutDownLeft'\n                    },\n                    prev: {\n                        tin: 'rotateInUpLeft',\n                        tout: 'rotateOutUpLeft'\n                    }\n                },\n                'scroll': {\n                    next: {\n                        tin: 'fadeInUp',\n                        tout: 'fadeOutUp'\n                    },\n                    prev: {\n                        tin: 'fadeInDown',\n                        tout: 'fadeOutDown'\n                    }\n                },\n                'slide': {\n                    next: {\n                        tin: 'fadeInRight',\n                        tout: 'fadeOutLeft'\n                    },\n                    prev: {\n                        tin: 'fadeInLeft',\n                        tout: 'fadeOutRight'\n                    }\n                }\n            }\n\n        }\n\n        /*\n         initialize the plugin.\n         */\n        priv.init = function () {\n            _cont = priv.options.id;\n            priv.options.types.string = ((priv.options.types || {}).string || {});\n            priv.options.types.number = ((priv.options.types || {}).number || {});\n            priv.options.types.bool = ((priv.options.types || {}).bool || {});\n            priv.options.types.date = ((priv.options.types || {}).date || {});\n            priv.options.transition = priv.options.transition === true ? 'scroll' : priv.options.transition;\n\n            //check support transitions\n            _transition.supported = priv.supportsTransition();\n\n            //check supports dataBinding\n            _dataBind = (priv.options.dataBind && !!document.addEventListener);\n            \n            if (priv.options.data) {\n                priv.setData(priv.options.data);\n            }\n            else {\n                //fill the table with empty cells\n                if (priv.options.preFill) {\n                    var data = {\n                        cols: {\n                            dummy: {\n                                index: 1,\n                                friendly: \"&nbsp;\",\n                                type: \"string\"\n                            }\n                        },\n                        rows: []\n                    };\n                    for (var i = 0; i < priv.options.pageSize; i++)\n                        data.rows.push({dummy: \"&nbsp;\"});\n                    priv.setData(data);\n                }\n            }\n            \n            //try call webservice for data\n            priv.update();\n        };\n\n        /*\n         creates the table with all its parts and handlers.\n         note that only the parts we need is created.\n         (yeah, the function is huge)\n         */\n        priv.createTable = function () {\n            var start = new priv.ext.XDate();\n\n            //create table itself\n            if (!_table) {\n                _head = _body = _foot = undefined;\n                _table = $('<table class=\"watable table table-striped table-hover table-bordered table-condensed\"></table>').appendTo(_cont);\n            }\n\n            //create the header which will later hold both sorting and filtering\n            if (!_head) {\n                _table.find('thead').remove();\n                _headSort = _headFilter = undefined;\n                _head = $('<thead></thead>').prependTo(_table);\n            }\n\n            //sort the columns in index order\n            var colsSorted = Object.keys(_data.cols).sort(function (a, b) {\n                return _data.cols[a].index - _data.cols[b].index;\n            });\n\n            //create the header sorting row\n            if (!_headSort) {\n                _head.find('.sort i').tooltip('hide');\n                _head.find(\".sort\").remove();\n                _headSort = $('<tr class=\"sort\"></tr>').prependTo(_head);\n\n                //create the checkall toggle\n                if (_uniqueCol && priv.options.checkboxes) {\n                    var checked = _checkToggleChecked ? 'checked' : '';\n                    var headCell = $('<th></th>').appendTo(_headSort);\n                    if (priv.options.checkAllToggle) {\n                        var elem = $('<input {0} class=\"checkToggle\" type=\"checkbox\" />'.f(checked)).appendTo(headCell);\n                        elem.on('change', priv.checkToggleChanged);\n                    }\n                }\n\n                //create the sortable headers\n                for (var i = 0; i < colsSorted.length; i++) {\n                    var column = colsSorted[i];\n                    var props = _data.cols[column];\n\n                    if (!props.hidden) {\n                        var headCell = $('<th></th>').appendTo(_headSort);\n                        var link;\n                        if(priv.options.sorting && props.sorting !== false) {\n                            link = $('<a class=\"pull-left\" href=\"#\">{0}</a>'.f(props.friendly || column));\n                            link.on('click', {column: column}, priv.columnClicked);\n                        }\n                        else {\n                            link = $('<span class=\"pull-left\">{0}</span>'.f(props.friendly || column));\n                        }\n                        link.appendTo(headCell);\n\n                        if (props.tooltip) {\n                            $('<span class=\"glyphicon glyphicon-info-sign\"></span>').tooltip({\n                                title: props.tooltip.trim(),\n                                html: true,\n                                container: 'body',\n                                placement: 'top',\n                                delay: {\n                                    show: 500,\n                                    hide: 100\n                                }\n                            }).appendTo(link);\n                        }\n\n                        //Add sort arrow\n                        if (column == _currSortCol) {\n                            if (_currSortFlip) $('<span class=\"glyphicon glyphicon-chevron-down pull-right\"></span>').appendTo(headCell);\n                            else $('<span class=\"glyphicon glyphicon-chevron-up pull-right\"></span>').appendTo(headCell);\n                        }\n                    }\n                }\n            }\n\n            //create the header filtering row\n            if (!_headFilter && priv.options.filter) {\n                _head.find(\".filter\").remove();\n                _headFilter = $('<tr class=\"filter\"></tr>').appendTo(_head);\n                var headCell;\n                var elem;\n                var placeHolder = '';\n                var tooltip = '';\n\n                //create the filter checkbox\n                if (_uniqueCol && priv.options.checkboxes) {\n                    tooltip = priv.options.types.bool.filterTooltip || 'Toggle between:<br/>indeterminate,<br/>checked,<br/>unchecked';\n                    headCell = $('<th></th>').appendTo(_headFilter);\n                    elem = $('<input class=\"filter indeterminate\" checked type=\"checkbox\" />').appendTo(headCell);\n                    $.map(_filterCols, function (colProps, col) {\n                        if (col == \"unique\") {\n                            if (colProps.filter == 1)\n                                elem.prop('checked', true).removeClass('indeterminate');\n                            else if (colProps.filter == 0)\n                                elem.prop('checked', false).removeClass('indeterminate');\n                            else\n                                elem.prop('checked', true).addClass('indeterminate');\n                        }\n                    });\n\n                    if (tooltip) {\n                        elem.tooltip({\n                            title: tooltip.trim(),\n                            html: true,\n                            container: 'body',\n                            trigger: 'hover',\n                            placement: 'top',\n                            delay: {\n                                show: 500,\n                                hide: 100\n                            }\n                        });\n                    }\n                    elem.on('click', {column: \"unique\"}, priv.filterChanged);\n                }\n\n                //create the column filters\n                for (var i = 0; i < colsSorted.length; i++) {\n                    var column = colsSorted[i];\n                    var props = _data.cols[column];\n                    tooltip = props.filterTooltip === true ? undefined : props.filterTooltip === false ? '' : props.filterTooltip;\n                    placeHolder = props.placeHolder === true ? undefined : props.placeHolder === false ? '' : props.placeHolder;\n\n                    if (!props.hidden) {\n                        headCell = $('<th></th>').appendTo(_headFilter);\n\n                        switch (props.type || 'string') {\n                            case \"number\":\n                                if (placeHolder == undefined) placeHolder = priv.options.types.number.placeHolder;\n                                placeHolder = (placeHolder === true || placeHolder == undefined) ? '10..20 =50' : placeHolder === false ? '' : placeHolder;\n                                if (tooltip == undefined) tooltip = priv.options.types.number.filterTooltip;\n                                tooltip = (tooltip === true || tooltip == undefined) ? 'Values 10 to 20:<br/>10..20<br/>Values except 10 to 20:<br/>!10..20<br/>Values exactly 50:<br/>=50' : tooltip === false ? '' : tooltip;\n                                elem = $('<input placeholder=\"{0}\" class=\"filter\" type=\"text\" />'.f(placeHolder));\n                                elem.on('keyup', {column: column}, priv.filterChanged);\n                                break;\n                            case \"date\":\n                                if (placeHolder == undefined) placeHolder = priv.options.types.date.placeHolder;\n                                placeHolder = (placeHolder === true || placeHolder == undefined) ? '-7..0' : placeHolder === false ? '' : placeHolder;\n                                if (tooltip == undefined) tooltip = priv.options.types.date.filterTooltip;\n                                tooltip = (tooltip === true || tooltip == undefined) ? 'Today:<br/>0..1<br/>All except today:<br/>!0..1<br/>A week today excluded:<br/>-7..0' : tooltip === false ? '' : tooltip;\n                                elem = $('<div><input placeholder=\"{0}\" class=\"filter\" type=\"text\" /></div>'.f(placeHolder));\n\n                                if (priv.options.types.date.datePicker === true || priv.options.types.date.datePicker == undefined)\n                                {\n                                    if ($().datepicker)\n                                    {\n                                        elem.addClass('date-wrap');\n                                        var today = new priv.ext.XDate(false).setHours(0, 0, 0, 0).toString('yyyy-MM-dd');\n                                        var dp = $('<div style=\"float:right\" class=\"date\" data-date=\"{0}\" data-date-format=\"{1}\" />'.f(today, 'yyyy-mm-dd')).appendTo(elem);\n                                        $('<input style=\"display:none\" type=\"text\"  />').appendTo(dp);\n                                        $('<span class=\"add-on glyphicon glyphicon-chevron-right\"></span>').on('click', {op: \"l\"}, priv.dpOpChanged).appendTo(dp);\n                                        $('<span class=\"add-on glyphicon glyphicon-chevron-left\"></span>').on('click', {op: \"r\"}, priv.dpOpChanged).appendTo(dp);\n                                        dp.datepicker({weekStart:1});\n                                        dp.on('changeDate', {column: column, input: $('input.filter', elem)}, priv.dpClicked);\n                                    }\n                                    else\n                                    priv.log('datepicker plugin not found');\n                                }\n                                elem.on('keyup', 'input.filter', {column: column}, priv.filterChanged);\n                                break;\n                            case \"bool\":\n                                if (tooltip == undefined) tooltip = priv.options.types.bool.filterTooltip;\n                                tooltip = (tooltip === true || tooltip == undefined) ? 'Toggle between:<br/>indeterminate,<br/>checked,<br/>unchecked' : tooltip === false ? '' : tooltip;\n                                elem = $('<input class=\"filter indeterminate\" checked type=\"checkbox\" />');\n                                elem.on('click', {column: column}, priv.filterChanged);\n                                break;\n                            case \"string\":\n                                if (placeHolder == undefined) placeHolder = priv.options.types.string.placeHolder;\n                                placeHolder = (placeHolder === true || placeHolder == undefined) ? 'John Doe' : placeHolder === false ? '' : placeHolder;\n                                if (tooltip == undefined) tooltip = priv.options.types.string.filterTooltip;\n                                tooltip = (tooltip === true || tooltip == undefined) ? 'Find John Doe:<br/>John Doe<br/>Find John and Jane Doe(Regex):<br/>?John Doe|Jane Doe<br/>Find all except John Doe:<br/>!John Doe' : tooltip === false ? '' : tooltip;\n                                elem = $('<input placeholder=\"{0}\" class=\"filter\" type=\"text\" />'.f(placeHolder));\n                                elem.on('keyup', {column: column}, priv.filterChanged);\n                                break;\n                            case \"none\":\n                                elem = $('<div>&nbsp;</div>');\n                                break;\n                        }\n\n                        if (tooltip) {\n                            elem.tooltip({\n                                title: tooltip.trim(),\n                                html: true,\n                                container: 'body',\n                                trigger: 'hover',\n                                placement: 'top',\n                                delay: {\n                                    show: 500,\n                                    hide: 100\n                                }\n                            });\n                        }\n\n                        if (elem && props.filter !== false) {\n                            $.map(_filterCols, function (colProps, col) {\n                                if (col == column) {\n                                    if (colProps.col.type == 'bool') {\n                                        if (colProps.filter == 1)\n                                            elem.prop('checked', true).removeClass('indeterminate');\n                                        else if (colProps.filter == 0)\n                                            elem.prop('checked', false).removeClass('indeterminate');\n                                        else\n                                            elem.prop('checked', true).addClass('indeterminate');\n                                    }\n                                    else if (colProps.col.type == 'date') {\n                                        //dates have the input nested\n                                        $('input:first', elem).val(colProps.filter);\n                                    }\n                                    else{\n                                        elem.val(colProps.filter);\n                                    }\n                                }\n                            });\n                            elem.appendTo(headCell);\n                        }\n                    }\n                }\n            }\n\n            //create the body\n            if (!_body) {\n                var prevBody = _table.find('tbody');\n                if (!_transition.doTransition && prevBody.length)\n                    prevBody.remove();\n                _body = $('<tbody style=\"display:none\"></tbody>').insertAfter(_head);\n                _body.on('change', '.unique', priv.rowChecked);\n                _body.on('click', 'td:not(.watable-col-cbunique)', priv.rowClicked);\n\n                //find out what rows to show next...\n                _pageSize = priv.options.pageSize == -1 ? _data.rows.length : Math.min(priv.options.pageSize, _data.rows.length);\n                _totalPages = Math.ceil(_data.rows.length / _pageSize) || 1;\n                _currPage = Math.min(_totalPages, _currPage);\n                _data.meta.rowsRendered = {};\n\n                if (_currPage > 1) {\n                    _data.meta.fromRow = Math.max((_pageSize * _currPage) - _pageSize, 0);\n                    _data.meta.toRow = Math.min(_data.meta.fromRow + _pageSize, _data.rows.length);\n                }\n                else {\n                    _data.meta.fromRow = 0;\n                    _data.meta.toRow = _pageSize;\n                }\n\n                //slice out the chunk of data we need and create rows\n                $.each(_data.rows.slice(_data.meta.fromRow, _data.meta.toRow), function (index, row) {\n\n                    var rowRendered = $('<tr class=\"{0}\"></tr>'.f(index%2 == 0 ? 'odd' : 'even')).appendTo(_body);\n                    \n                    if (_uniqueCol) {\n                        _data.meta.rowsRendered[row[_uniqueCol]] = rowRendered;\n                        \n                        //create checkbox\n                        if (priv.options.checkboxes) {\n                            var check = _data.meta.rowsChecked[row[_uniqueCol]] != undefined ? 'checked' : '';\n                            var checkable = row['row-checkable'] === false ? 'disabled' : '';\n                            var cell = $('<td class=\"watable-col-cbunique\"></td>').appendTo(rowRendered);\n                            $('<input class=\"unique\" {0} {1} type=\"checkbox\" />'.f(check, checkable)).appendTo(cell);\n                        }\n                    }\n\n                    //create cells\n                    for (var i = 0; i < colsSorted.length; i++) {\n                        var col = colsSorted[i];\n\n                        if (!_data.cols[col]) {\n                            return;\n                        }\n                        if (_data.cols[col].unique) {\n                            rowRendered.data('unique', row[col]);\n                        }\n                        if (!_data.cols[col].hidden) {\n                            var cell = $('<td></td>');\n                            priv.renderCell(cell, col, row, rowRendered);\n                            cell.appendTo(rowRendered);\n                        }\n                    }\n                });\n\n                //pad with empty rows?\n                if (priv.options.pageSize != -1 && (_currPage == _totalPages && _currPage > 1) || priv.options.pageSizePadding) {\n                    var loops = priv.options.pageSize - (_data.meta.toRow - _data.meta.fromRow);\n                    while (loops-- >0) {\n                        var row = $('<tr></tr>').appendTo(_body);\n\n                        if (_uniqueCol && priv.options.checkboxes) {\n                            var cell = $('<td></td>').appendTo(row);\n                            $('<input disabled type=\"checkbox\" />').appendTo(cell);\n                        }\n\n                        $.each(_data.cols, function (column, props) {\n                            if (!props.hidden) $('<td>&nbsp;</td>').appendTo(row);\n                        });\n                    }\n                }\n\n                //transition between bodys?\n                if (prevBody.length && _transition.doTransition) {\n                    var transition = _transition.direction == 1 ? _transition.available[priv.options.transition].next : _transition.available[priv.options.transition].prev;\n\n                    //animation duration\n                    var vendorCSSProps = {};\n                    $.each(_vendors, function (index, vendor) {\n                        var key = '-{0}-animation-duration'.f(vendor);\n                        vendorCSSProps[key] = '{0}s'.f(priv.options.transitionDuration);\n                    });\n                    prevBody.css(vendorCSSProps);\n\n                    var fallbackTimer;\n                    var vendorAnimationEnd = $.map(_vendors, function (vendor) { return '{0}AnimationEnd {0}animationend'.f(vendor); }).join(\" \");\n                    prevBody.one('{0} animationend'.f(vendorAnimationEnd), function (e) {\n                        clearTimeout(fallbackTimer);\n                        prevBody.remove();\n                        _body.css(vendorCSSProps);\n                        //animate in the current body\n                        _body.one('{0} animationend'.f(vendorAnimationEnd), function (e) {\n                            _body.removeClass('animated {0}'.f(transition.tin));\n                        });\n                        _body.show(0).addClass('animated {0}'.f(transition.tin));\n                    });\n\n                    //fallback timer to prevent paging from breaking when animationend wont fire\n                    fallbackTimer = setTimeout(function(e) {\n                        priv.log('animate.css seems to be missing!', true);\n                        prevBody.remove();\n                        _body.show(0);\n                        _transition.supported = false;\n                    }, (priv.options.transitionDuration * 1000) /* wait a little longer */ + 500);\n\n                    //animate out the previous body\n                    prevBody.addClass('animated {0}'.f(transition.tout));\n                    _transition.doTransition = false;\n                }\n                else {\n                    _body.show(0);\n                }\n\n                //recreate footer?\n                _data.meta.rowsFilteredCount = _data.meta.rowsFilteredCount || 0;\n                if (_data.meta.rowsFilteredCount != _data.rows.length) {\n                    _foot = undefined;\n                    _data.meta.rowsFilteredCount = _data.rows.length;\n                }\n            }\n\n            //create the footer\n            if (!_foot) {\n                _table.find('tfoot').remove();\n                _foot = $('<tfoot></tfoot>').insertAfter(_body);\n\n                var footRow = $('<tr></tr>').appendTo(_foot);\n                var footCell = $('<td colspan=\"999\"></td>').appendTo(footRow);\n\n                //create summary\n                if (_data.rows.length > 0)\n                    $('<p>Rows {0}-{1} of {2}</p>'.f(_data.meta.fromRow + 1, Math.min(_data.meta.toRow, _data.rows.length), _data.rows.length)).appendTo(footCell);\n                else {\n                    $('<p>No results</p>').appendTo(footCell);\n                }\n\n                //create the pager.\n                var lowerPage = _currPage - 2;\n                var upperPage = _currPage + 2;\n                if (upperPage > _totalPages) {\n                    var diff = upperPage - _totalPages;\n                    upperPage = _totalPages;\n                    lowerPage -= diff;\n                }\n                if (lowerPage < 1) lowerPage = 1;\n                if (upperPage < 5) upperPage = 5;\n\n                var footToolbar = $('<div class=\"btn-toolbar\"></div>').appendTo(footCell);\n                var footDiv = $('<div class=\"btn-group\"></div>').appendTo(footToolbar);\n                var footPagerUl = $('<ul class=\"pagination\"></ul>').appendTo(footDiv);\n\n                $('<li class=\"{0}\"><a href=\"#\">«</a></li>'.f(_currPage == 1 ? 'disabled' : ''))\n                    .on('click', {pageIndex: _currPage - 1}, priv.pageChanged).appendTo(footPagerUl);\n\n                for (var i = lowerPage; i <= upperPage; i++) {\n                    var link;\n                    if (i == _currPage) {\n                        link = $('<li class=\"active\"><a href=\"#\">{0}</a></li>'.f(i));\n                        link.on('click', function(e) { e.preventDefault();} )\n                    }\n                    else {\n                        link = $('<li class=\"{1}\"><a href=\"#\">{0}</a></li>'.f(i, i > _totalPages ? 'disabled' : ''));\n                        link.on('click', {pageIndex: i}, priv.pageChanged);\n                    }\n                    link.appendTo(footPagerUl);\n                }\n                $('<li class=\"{0}\"><a href=\"#\">»</a></li>'.f(_currPage == _totalPages ? 'disabled' : ''))\n                    .on('click', {pageIndex: _currPage + 1}, priv.pageChanged).appendTo(footPagerUl);\n\n                //create pagesize dropdown\n                if (priv.options.pageSizes.length) {\n                    var div = $('<div class=\"btn-group dropup pagesize\"></div>').appendTo(footToolbar);\n                    var btn = $('<button class=\"btn btn-default dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">Rows&nbsp;</button>').appendTo(div);\n                    var span = $('<span class=\"caret\"></span>').appendTo(btn);\n                    var ul = $('<ul class=\"dropdown-menu\">').appendTo(div);\n\n                    $.each(priv.options.pageSizes, function (index, val) {\n                        var li = $('<li></li>').appendTo(ul);\n                        $('<a href=\"#\">{0}</a>'.f(val)).appendTo(li);\n                    });\n                    div.on('click', 'a', priv.pageSizeChanged);\n                }\n\n                //create columnpicker dropdown\n                if (priv.options.columnPicker) {\n                    var div = $('<div class=\"btn-group dropup columnpicker\"></div>').appendTo(footToolbar);\n                    var btn = $('<button class=\"btn btn-default dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">Columns&nbsp;</button>').appendTo(div);\n                    var span = $('<span class=\"caret\"></span>').appendTo(btn);\n                    var ul = $('<ul class=\"dropdown-menu\">').appendTo(div);\n\n                    for (var i = 0; i < colsSorted.length; i++) {\n                        var col = colsSorted[i];\n                        var props = _data.cols[col];\n\n                        if (props.type != \"unique\") {\n                            var li = $('<li></li>').appendTo(ul);\n                            $('<input {0} type=\"checkbox\" title=\"{1}\" value=\"{1}\" >&nbsp;{2}</input>'.f(props.hidden ? '' : 'checked', col, props.friendly || col)).appendTo(li);\n                        }\n                    }\n                    div.on('click', 'input', priv.columnPickerClicked);\n                }\n\n                //create actions dropdown\n                if (priv.options.actions) {\n                    var div = $('<div class=\"btn-group dropup actions\"></div>').appendTo(footToolbar);\n                    var btn = $('<button class=\"btn btn-default dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\"><span class=\"glyphicon glyphicon-list\"></span>&nbsp;</button>').appendTo(div);\n                    var span = $('<span class=\"caret\"></span>').appendTo(btn);\n                    var ul = $('<ul class=\"dropdown-menu\">').appendTo(div);\n\n                    if (priv.options.actions.filter) {\n                        var li = $('<li></li>').appendTo(ul);\n                        $('<input {0} type=\"checkbox\" >&nbsp;Filter</input>'.f(priv.options.filter ? 'checked' : '')).appendTo(li);\n                        li.on('click', 'input', function (e) {\n                            priv.options.filter = !priv.options.filter;\n                            _head = undefined;\n                            priv.createTable();\n                        });\n                    }\n                    if (priv.options.actions.columnPicker) {\n                        var li = $('<li></li>').appendTo(ul);\n                        $('<input {0} type=\"checkbox\" >&nbsp;ColumnPicker</input>'.f(priv.options.columnPicker ? 'checked' : '')).appendTo(li);\n                        li.on('click', 'input', function (e) {\n                            priv.options.columnPicker = !priv.options.columnPicker;\n                            _foot = undefined;\n                            priv.createTable();\n                        });\n                    }\n                    if (priv.options.actions.custom) {\n                        $.each(priv.options.actions.custom, function (index, val) {\n                            var li = $('<li></li>').appendTo(ul);\n                            $(val).appendTo(li);\n                        });\n                    }\n                }\n            }\n\n            if (_data.rows.length == 0 && priv.options.hidePagerOnEmpty)\n                $('.btn-toolbar', _foot).remove();\n            priv.log('table created in {0}ms.'.f(new priv.ext.XDate() - start));\n            if (typeof priv.options.tableCreated == 'function')\n                priv.options.tableCreated.call(_table.get(0), {table: _table.get(0)});\n\n        };\n\n        /*\n         renders a cell\n         */\n        priv.renderCell= function(cell, col, row, renderedRow) {\n            cell.data('column', col);\n\n            //add any cell/column level classes\n            cell.removeClass();\n            var cellClasses = $.grep([].concat((row[col + 'Cls'] || '').split(','), (_data.cols[col].cls || '').split(',')),function(n){ return(n)});\n            $.each(cellClasses, function(i, cellClass) {\n                cellClass = cellClass.trim();\n                if (!cell.hasClass(cellClass))\n                    cell.addClass(cellClass);\n            });\n\n            //add any row level classes here as well\n            var rowClasses = row['row-cls'] || \"\";\n            var newClasses = $.grep(rowClasses.split(','),function(n){ return(n)});\n            var oldClasses = renderedRow.attr('class').split(' ');\n\n            var addClasses = $.unique($(newClasses)).not($(oldClasses)).get();\n            $.each(addClasses, function(i, cls) {\n                renderedRow.addClass(cls);\n            });\n            var removeClasses = $.unique($(oldClasses)).not($(newClasses.concat(['odd','even']))).get();\n            $.each(removeClasses, function(i, cls) {\n                renderedRow.removeClass(cls);\n            });\n\n            if (_uniqueCol) {\n                var cellClass = 'watable-col-{0}'.f(col);\n                if (!cell.hasClass(cellClass))\n                    cell.addClass(cellClass);\n            }\n            \n            var val = row[col];\n            var format = row[col + 'Format'] ||\n                        _data.cols[col].format ||\n                        row[col + 'AutoFormat'] ||\n                        '{0}';\n\n            function isNumber(n) {\n                return !isNaN(parseFloat(n)) && isFinite(n);\n            }\n\n            switch (_data.cols[col].type) {\n                case \"string\":\n                    val = val || '';\n                    cell.html(format.f(val));\n                    break;\n                case \"number\":\n                    val = val || '';\n                    if (isNumber(val)) {\n                        val = (+val);\n                        var forceDecimals = !isNaN(_data.cols[col].decimals);\n                        if (forceDecimals) {\n                            val = val.toFixed(_data.cols[col].decimals);\n                        }\n                        else {\n                            val = val % 1 === 0\n                                ? val\n                                : val.toFixed(priv.options.types.number.decimals || 2);\n                        }\n                    }\n                    cell.html(format.f(val));\n                    break;\n                case \"date\":\n                    val = val || '';\n                    if (isNumber(val)) {\n                        val = (+val);\n                        val = new priv.ext.XDate(val, _data.cols[col].dateUTC === true || priv.options.types.date.utc === true).toString(_data.cols[col].dateFormat || priv.options.types.date.format || 'yyyy-MM-dd HH:mm:ss');\n                    }\n                    cell.html(format.f(val));\n                    break;\n                case \"bool\":\n                    var checkbox = cell.children(\"input:checkbox\");\n                    if(checkbox.length) {\n                        checkbox.prop(\"checked\", val == 1);\n                    } else {\n                        $('<input type=\"checkbox\" {0} disabled />'.f(val == 1 ? \"checked\" : \"\")).appendTo(cell);\n                    }\n                    break;\n            }\n        };\n\n        /*\n         calls the webservice(if defined).\n         */\n        priv.update = function (callback, skipCols, resetChecked) {\n            if (!priv.options.url) {\n                priv.log('no url found');\n                return;\n            }\n\n            priv.log('requesting data from url:{0} data:{1}'.f(priv.options.url, JSON.stringify(priv.options.urlData) || ''));\n            var start = new priv.ext.XDate();\n\n            $.ajax({\n                url: priv.options.url,\n                type: priv.options.urlPost ? 'POST' : 'GET',\n                dataType: 'json',\n                contentType: \"application/json; charset=utf-8\",\n                data: priv.options.urlData,\n                async: true,\n                success: function (data) {\n                    priv.log('request finished in {0}ms.'.f(new priv.ext.XDate() - start));\n\n                    //assign the new data\n                    if (data.d && data.d.cols)\n                        priv.setData(data.d, skipCols, resetChecked);\n                    else\n                        priv.setData(data, skipCols, resetChecked);\n                    if (typeof callback == \"function\")\n                        callback.call(this);\n                },\n                error: function (err) {\n                    priv.log('request error: '.f(err));\n                }\n            });\n        };\n\n\n        /*\n         assigns the new data.\n         */\n        priv.setData = function (pData, skipCols, resetChecked) {\n            var data = $.extend(true, {}, pData);\n            data.meta = {};\n            data.meta.rowsRendered = {};\n            data.meta.fromRow = _data.meta && _data.meta.fromRow || 0;\n            data.meta.toRow = _data.meta && _data.meta.toRow || 0;\n\n            //use previous column definitions?\n            skipCols = skipCols || false;\n            if (skipCols) data.cols = _data.cols;\n            else _filterCols = {};\n\n            _data = data;\n            _data.meta.rowsAll = pData.rows;\n\n            //wash the new data a bit\n            _uniqueCol = \"\";\n            $.each(_data.cols, function (col, props) {\n                //set sorting\n                if (!_currSortCol && props.sortOrder && priv.options.sorting && props.sorting !== false) {\n                    _currSortCol = col;\n                    _currSortFlip = props.sortOrder != \"asc\";\n                }\n\n                //default to string type if missing\n                if (!props.type) _data.cols[col].type = \"string\";\n\n                //if several unique columns is defined, use the first.\n                if (props.unique) {\n                    if (!_uniqueCol) _uniqueCol = col;\n                    else props.unique = false;\n                }\n\n                //if index property is missing, create one\n                if (!props.index) _data.cols[col].index = new priv.ext.XDate();\n                props.column = col;\n\n                //set any initial filter\n                if (!skipCols) {\n                    props.filter = props.filter == undefined ? '' : props.filter;\n\n                    if (props.filter !== false) {\n                        _filterCols[col] = _filterCols[col] || {\n                            filter: props.filter,\n                            col: props\n                        };\n                    }\n                }\n            });\n\n            _data.meta.rowsLookup = {};\n            //keep any previously checked rows around?\n            if (resetChecked === true || resetChecked === undefined)\n                _data.meta.rowsChecked = {};\n            else {\n                for (var key in _data.meta.rowsChecked)\n                    _data.meta.rowsChecked[key] = _data.meta.rowsLookup[key];\n            }\n\n            if (_uniqueCol) {\n                //create a unique column definition\n                _data.cols[\"unique\"] = {\n                    column: \"unique\",\n                    type: \"unique\",\n                    index: -1,\n                    hidden: true\n                };\n\n               _data.meta.rowObservers = {};\n                $.each(_data.meta.rowsAll, function (index, row) {\n                    //add rows that needs to be pre-checked\n                    if (row[\"row-checked\"] === true) {\n                        _data.meta.rowsChecked[row[_uniqueCol]] = row;\n                    }\n                    //add the row to lookup object, so we can find it fast later on.\n                    _data.meta.rowsLookup[row[_uniqueCol]] = {\n                        index: index,\n                        row: row\n                    };\n                    //add row observer\n                    priv.addRowObserver(row);\n                });\n                 if (_dataBind) {\n                    _data.meta.rowsObserver = new ArrayObserver(_data.meta.rowsAll).open(priv.rowsChanged);\n                 }\n            }\n\n            _head = undefined;\n            _body = undefined;\n            priv.filter();\n            priv.sort();\n            priv.createTable();\n        };\n\n        /*\n         returns data with all,checked,filtered or rendered rows\n         */\n        priv.getData = function (checked, filtered, rendered) {\n            checked = checked || false;\n            filtered = filtered || false;\n            rendered = rendered || false;\n\n            //copy complete _data object\n            var data = $.extend(true, {}, _data);\n            //remove internal stuff\n            delete data.cols[\"unique\"];\n            delete data.meta;\n\n            //set the current filters\n            $.each(data.cols, function(col) {\n                if (_filterCols[col]) {\n                    data.cols[col].filter = _filterCols[col].filter;\n                }\n            });\n\n            //set rows\n            data.rows = filtered ? _data.rows : _data.meta.rowsAll;\n            if (checked) {\n                data.rows = $.map(data.rows, function (row, index) {\n                    if (_data.meta.rowsChecked[row[_uniqueCol]]) {\n                        return row;\n                    }\n                });\n            }\n            if (rendered) {\n                data.rows = $.map(data.rows, function (row, index) {\n                    if (_data.meta.rowsRendered[row[_uniqueCol]]) {\n                        return row;\n                    }\n                });\n            }\n            return data;\n        };\n\n        /*\n         filters all rows.\n         */\n        priv.filter = function () {\n            //get a fresh copy of the data\n            _data.rows = _data.meta.rowsAll.slice();\n\n            if (!priv.options.filter) return;\n            if (Object.keys(_filterCols).length == 0) return;\n\n            var start = new priv.ext.XDate();\n\n            //for every column with a filter, run through the rows and return the matching rows\n            $.each(_filterCols, function (col, colProps) {\n                priv.log('filtering on text:{0} col:{1} type:{2} '.f(colProps.filter, colProps.col.column, colProps.col.type));\n\n                switch (colProps.col.type) {\n                    case \"string\":\n                        var filter = colProps.filter;\n                        var ne = false, regex = false, validRegex = true;\n\n                        //Escaping first character means cannot be negate or regex\n                        if (filter.charAt(0) == '\\\\')\n                            filter = filter.substr(1);\n                        else {\n                            var ne = filter.charAt(0) == '!';\n                            if (ne) filter = filter.substring(1);\n                            regex = filter.length > 0 && filter.charAt(0) == \"?\";\n                        }\n\n                        if (regex) {\n                            filter = filter.substr(1);\n                            try {filter = new RegExp(filter, \"gi\");}\n                            catch(err) {\n                                priv.log('invalid regex:{0}'.f(filter), true);\n                                validRegex = false;\n                            }\n                        }\n                        else filter = filter.toLowerCase();\n\n                        _data.rows = $.map(_data.rows, function (row) {\n\n                            var val = String(row[col]);\n                            row[col + 'AutoFormat'] = '';\n\n                            if (regex && validRegex) {\n                                var matches = val.match(filter);\n                                if (!matches && ne) return row;\n\n                                if (matches && !ne) {\n                                    var pos = 0;\n                                    $.each(matches, function(index, match) {\n                                        var matchMask = '<span class=\"filter\">{0}</span>'.f(match);\n                                        pos = val.indexOf(match, pos);\n                                        var pre = val.substring(0, pos);\n                                        var post = val.substring(pos + match.length);\n                                        val = '{0}{1}{2}'.f(pre, matchMask, post);\n                                        pos += matchMask.length;\n                                    });\n                                    row[col + 'AutoFormat'] = val;\n                                    return row;\n                                }\n                            }\n                            else {\n                                var pos = val.toLowerCase().indexOf(filter);\n\n                                if ((pos == -1 && ne) || filter === '') return row;\n                                else if (row[col] != undefined && pos >= 0 && !ne) {\n                                    var pre = val.substring(0, pos);\n                                    var match = val.substring(pos, pos + filter.length);\n                                    var post = val.substring(pos + filter.length, row[col].length);\n                                    val = '{0}<span class=\"filter\">{1}</span>{2}'.f(pre, match, post);\n                                    row[col + 'AutoFormat'] = val;\n                                    return row;\n                                }\n                            }\n                        });\n                        break;\n                    case \"number\":\n                    case \"date\":\n                        var expr = colProps.filter.replace(/\\s+/gi, ' ');\n                        var pos = -1, lval, rval, op;\n                        var ne = expr.charAt(0) == '!';\n                        if (ne) expr = expr.substring(1);\n\n                        //find operator,l/r value\n                        $.each([\"..\", \"=\"], function(index, operator) {\n                            pos = expr.indexOf(operator);\n                            if (pos >= 0) {\n                                op = operator;\n                                lval = expr.substring(0, pos);\n                                rval = expr.substring(pos + op.length);\n\n                                lval = parseFloat(lval);\n                                rval = parseFloat(rval);\n                                if (isNaN(lval)) lval = Number.NEGATIVE_INFINITY;\n                                if (isNaN(rval)) rval = Number.MAX_VALUE;\n\n                                if (colProps.col.type == \"date\") {\n                                    var today = new priv.ext.XDate(priv.options.types.date.utc === true).setHours(0, 0, 0, 0);\n                                    lval = today - (lval * -1) * (60 * 60 * 24 * 1000);\n                                    rval = today - (rval * -1) * (60 * 60 * 24 * 1000);\n                                }\n                                return false;\n                            }\n                        });\n\n                        _data.rows = $.map(_data.rows, function (row) {\n                            var match = false;\n\n                            switch (op) {\n                                case \"=\":\n                                    if (row[col] == rval) match = true;\n                                    break;\n                                case \"..\":\n                                    if (colProps.col.type == \"date\") {\n                                        if (row[col] >= lval && row[col] < rval) match = true;\n                                    }\n                                    else {\n                                        if (row[col] >= lval && row[col] <= rval) match = true;\n                                    }\n                                    break;\n                                default:\n                                    break;\n                            }\n                            if (match && !ne ||\n                                !match && ne ||\n                                expr.length == 0 ||\n                                pos < 0)\n                                return row;\n                        });\n                        break;\n                    case \"bool\":\n                        _data.rows = $.map(_data.rows, function (row) {\n                            if (colProps.filter === '') return row;\n                            if (row[col] === colProps.filter) return row;\n                        });\n                        break;\n                    case \"unique\":\n                        _data.rows = $.map(_data.rows, function (row) {\n                            if (colProps.filter === '') return row;\n                            var a = row[_uniqueCol];\n                            var b = _data.meta.rowsChecked[a] ? _data.meta.rowsChecked[a][_uniqueCol] : '';\n                            if ((colProps.filter && a === b) || (!colProps.filter && b === '')) return row;\n                        });\n                        break;  \n                }\n                if (colProps.filter === '') delete _filterCols[colProps.col.column];\n            });\n            priv.log('filtering finished in {0}ms.'.f(new priv.ext.XDate() - start));\n\n            _body = undefined;\n        };\n\n        /*\n         sorts all rows on the current sorting column\n         */\n        priv.sort = function () {\n            if (!_data.cols[_currSortCol]) _currSortCol = \"\";\n            if (!_currSortCol) return;\n\n            var start = new priv.ext.XDate();\n            priv.log('sorting on col:{0} order:{1}'.f(_currSortCol, _currSortFlip ? \"desc\" : \"asc\"));\n\n            var isString = (_data.cols[_currSortCol].type == \"string\");\n            _data.rows = _data.rows.sort(function (a, b) {\n\n                var valA = a[_currSortCol];\n                var valB = b[_currSortCol];\n\n                if (isString) {\n                    valA = valA || '';\n                    valB = valB || '';\n                    if (!valA) {\n                        valA = priv.options.sortEmptyLast ? _currSortFlip ? \"!!!\" : \"|||\" : \"!!!\";\n                    }\n                    if (!valB) {\n                        valB = priv.options.sortEmptyLast ? _currSortFlip ? \"!!!\" : \"|||\" : \"!!!\";\n                    }\n                    if (String(valA).toLowerCase() == String(valB).toLowerCase()) return 0;\n                    if (String(valA).toLowerCase() > String(valB).toLowerCase()) return _currSortFlip ? -1 : 1;\n                    else return _currSortFlip ? 1 : -1;\n                } else {\n                    if (valA == '' || undefined || isNaN(valA)) {\n                        valA = priv.options.sortEmptyLast ? _currSortFlip ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n                    }\n                    if (valB == '' || undefined || isNaN(valB)) {\n                        valB = priv.options.sortEmptyLast ? _currSortFlip ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n                    }\n                    if (valA == valB) return 0;\n                    if (valA > valB) return _currSortFlip ? -1 : 1;\n                    else return _currSortFlip ? 1 : -1;\n                }\n            });\n            priv.log('sorting finished in {0}ms.'.f(new priv.ext.XDate() - start));\n        };\n\n        /*\n         helper for console logging\n         */\n        priv.log = function (message, isWarning) {\n            if (isWarning)\n                console.warn(message);\n            else if (priv.options.debug)\n                console.log(message);\n        };\n\n        /*\n        helper to detect transition support\n         */\n        priv.supportsTransition = function() {\n            var style = document.createElement('p').style;\n            //check vendorfree support\n            if( style['transition'] == '' )\n                return true;\n\n            //check vendor support\n            var vendorSupport = false;\n             $.each(_vendors, function (index, vendor) {\n                 if ('{0}Transition'.f(vendor) in style) {\n                     vendorSupport = true;\n                     return false;\n                 }\n             });\n            return vendorSupport;\n        };\n\n        /*\n         adds an observer to a row\n         */\n        priv.addRowObserver = function(row) {\n            if (_dataBind) {\n                _data.meta.rowObservers[row[_uniqueCol]] = new ObjectObserver(row).open(function(added, removed, changed, getOldValueFn) {\n                    priv.rowChanged(row, added, removed, changed, getOldValueFn);\n                });\n            }\n        };\n\n\n        /* Event Handlers\n         *************************************************************************/\n\n        /*\n         when: typing a filter\n         what: data is filtered on the value\n         */\n        priv.filterChanged = function (e) {\n            //clear old timer if we're typing fast enough\n            if (_filterTimeout) {\n                clearTimeout(_filterTimeout);\n                priv.log('filtering cancelled');\n            }\n\n            var filter = this.value;\n            var col = _data.cols[e.data.column];\n            var timeout = 200;\n\n            //boolean filters needs some special care\n            if (col.type == \"bool\" || col.type == \"unique\") {\n                timeout = 0;\n                var elem = $(this);\n                var cssClass = 'indeterminate';\n                if (elem.hasClass(cssClass)) {\n                    e.preventDefault();\n                    elem.removeClass(cssClass);\n                    filter = 1;\n                } else {\n                    if (!elem.is(':checked')) {\n                        filter =0;\n                    } else {\n                        elem.addClass(cssClass);\n                        filter = '';\n                    }\n                }\n            }\n\n            //add the filter to the filter array\n            _filterCols[col.column] = {\n                filter: filter,\n                col: col\n            };\n\n            //wait a few deciseconds before filtering\n            _filterTimeout = setTimeout(function () {\n                _filterTimeout = undefined;\n                priv.filter();\n                priv.sort();\n                priv.createTable();\n            }, timeout);\n        };\n\n        /*\n         when: changing page in pager\n         what: table is created with new page\n         */\n        priv.pageChanged = function (e) {\n            e.preventDefault();\n            if (e.data.pageIndex < 1 || e.data.pageIndex > _totalPages) return;\n\n            //if we have a valid transition, enable it.\n            _transition.doTransition = (_transition.supported && priv.options.transitionDuration > 0 && _transition.available[priv.options.transition]) || false; //\n            _transition.direction = e.data.pageIndex < _currPage ? 0 : 1;\n            //set the new page\n            _currPage = e.data.pageIndex;\n            priv.log('paging to index:{0}'.f(_currPage));\n\n            //trigger callback\n            if (typeof priv.options.pageChanged == 'function') {\n                priv.options.pageChanged.call(e.target, {\n                    event: e,\n                    page: _currPage\n                });\n            }\n\n            _body = undefined;\n            _foot = undefined;\n            priv.createTable();\n        };\n\n        /*\n         when: changing pagesize in pagesize dropdown\n         what: table is created with new pagesize\n         */\n        priv.pageSizeChanged = function (e) {\n            e.preventDefault();\n            var val = $(this).text().toLowerCase();\n            priv.log('pagesize changed to:{0}'.f(val));\n\n            //set the new pagesize\n            if (val == \"all\") priv.options.pageSize = _data.rows.length;\n            else priv.options.pageSize = parseInt(val);\n\n            //revert to first page, as its gets messy otherwise.\n            _currPage = 1;\n            _data.meta.fromRow = 0;\n            _data.meta.toRow = _data.meta.fromRow + priv.options.pageSize;\n            if (_data.meta.toRow > _data.rows.length) _data.meta.toRow = _data.rows.length;\n\n            //trigger callback\n            if (typeof priv.options.pageSizeChanged == 'function') {\n                priv.options.pageSizeChanged.call(e.target, {\n                    event: e,\n                    pageSize: priv.options.pageSize\n                });\n            }\n\n            _body = undefined;\n            _foot = undefined;\n            priv.createTable();\n        };\n\n        /*\n         when: clicking a column\n         what: data is sorted on the column\n         */\n        priv.columnClicked = function (e) {\n            e.preventDefault();\n            priv.log('col:{0} clicked'.f(e.data.column));\n\n            //set the new sorting column\n            if (_currSortCol == e.data.column) _currSortFlip = !_currSortFlip;\n            _currSortCol = e.data.column;\n\n            //trigger callback\n            if (typeof priv.options.columnClicked == 'function') {\n                priv.options.columnClicked.call(e.target, {\n                    event: e,\n                    column: _data.cols[_currSortCol],\n                    descending: _currSortFlip\n                });\n            }\n\n            _headSort = undefined;\n            _body = undefined;\n            priv.sort();\n            priv.createTable();\n        };\n\n        /*\n         when: clicking a column in columnpicker\n         what: show/hides the column\n         */\n        priv.columnPickerClicked = function (e) {\n            e.stopPropagation();\n\n            var elem = $(this);\n            var col = elem.val();\n            priv.log('col:{0} {1}'.f(col, elem.is(':checked') ? 'checked' : 'unchecked'));\n\n            //toggle column visibility\n            _data.cols[col].hidden = !_data.cols[col].hidden;\n\n            _data.cols[col].index = _data.cols[col].index || new priv.ext.XDate();\n            _head = undefined;\n            _body = undefined;\n            priv.createTable();\n        };\n\n        /*\n         when: clicking the check-all checkbox\n         what: toggles checked state on all rows, and adds/removes them from checked array\n         */\n        priv.checkToggleChanged = function (e) {\n            var elem = $(this);\n\n            if (elem.is(':checked')) {\n                var start = new priv.ext.XDate();\n                //for every row(except non checkables), add it to the checked array\n                var count = 0;\n                $.each(_data.rows, function (index, row) {\n                    if (row['row-checkable'] === false) return;\n                    if (!_data.meta.rowsChecked[row[_uniqueCol]]) {\n                        _data.meta.rowsChecked[row[_uniqueCol]] = row;\n                        count++;\n                    }\n                });\n                priv.log('{0} rows checked in {1}ms.'.f(count, new priv.ext.XDate() - start));\n                _checkToggleChecked = true;\n            }\n            else {\n                var start = new priv.ext.XDate();\n                //for every checked row(except non checkables), remove it from checked array\n                var count = 0;\n                $.each(_data.meta.rowsChecked, function(index, row) {\n                    if (row['row-checkable'] === false) return;\n                    delete _data.meta.rowsChecked[row[_uniqueCol]];\n                    count++;\n                });\n                priv.log('{0} rows unchecked in {1}ms.'.f(count, new priv.ext.XDate() - start));\n                _checkToggleChecked = false;\n            }\n            _body = undefined;\n            priv.createTable();\n        };\n\n        /*\n         when: clicking a row checkbox\n         what: toggles checked state on row, and add/removes it from checked array\n         */\n        priv.rowChecked = function (e) {\n            var elem = $(this);\n\n            //get the row's unique value\n            var unique = elem.closest('tr').data('unique');\n            priv.log('row({0}) {1}'.f(unique, elem.is(':checked') ? 'checked' : 'unchecked'));\n\n            //store the row in checked array\n            if (elem.is(':checked')) {\n                _data.meta.rowsChecked[unique] = _data.meta.rowsLookup[unique].row;\n            }\n            else {\n                delete _data.meta.rowsChecked[unique];\n            }\n            priv.rowClicked.call(elem, e);\n        };\n\n        /*\n         when: clicking anywhere on a row\n         what: row data and other info is returned to caller\n         */\n        priv.rowClicked = function (e) {\n            if (!_uniqueCol) {\n                priv.log('no unique column specified');\n                return;\n            }\n            var elem = $(this);\n            var unique = elem.closest('tr').data('unique');\n            if (!unique) return;\n\n            //gather callback data\n            var column = _data.cols[elem.data('column')];\n            var row =  _data.meta.rowsLookup[unique].row;\n            var index = _data.meta.rowsLookup[unique].index;\n\n            var isChecked = _data.meta.rowsChecked[unique] != undefined;\n\n            //trigger callback\n            if (typeof priv.options.rowClicked == 'function') {\n                var callBackData = {\n                    event: e,\n                    row: row,\n                    index: index,\n                    column: column || {}, //no column available when when using the checkboxes\n                    checked: isChecked\n                };\n                priv.options.rowClicked.call(e.target, callBackData);\n\n                //check for new checked state\n                if (row['row-checkable'] !== false) {\n                    var target = $(e.target);\n                    var checkbox;\n\n                    if (target.hasClass('unique') && target.prop('checked') != callBackData.checked) {\n                        checkbox = $(target);\n                        e.preventDefault();\n                    }\n                    if (callBackData.checked != isChecked) {\n                        checkbox = checkbox || $('.unique', elem.closest('tr'));\n                        checkbox.prop('checked', callBackData.checked);\n                        //priv.rowChecked.call(checkbox, e);\n                        //store the row in checked array\n                        if (callBackData.checked) {\n                            _data.meta.rowsChecked[unique] = _data.meta.rowsLookup[unique].row;\n                        }\n                        else {\n                            delete _data.meta.rowsChecked[unique];\n                        }\n                    }\n                }\n            }\n\n        };\n\n        /*\n         when: clicking a datepicker operator\n         what: sets the datepicker operator before a datepicker date is chosen.\n         */\n        priv.dpOpChanged = function(e) {\n            priv.log('dp oper:{0} clicked'.f(e.data.op));\n            e.preventDefault();\n            _currDpOp = e.data.op;\n        };\n\n        /*\n         when: clicking a datepicker date\n         what: filters on the date\n         */\n        priv.dpClicked = function (e) {\n            priv.log('dp date:{0} clicked'.f(new priv.ext.XDate(e.date, priv.options.types.date.utc === true).toString('yyyy-MM-dd')));\n\n            e.preventDefault();\n            var input = $(this).prev('input.filter').get(0);\n            Placeholders.disable(input); //Remove date placeholders for IE\n\n            var today = new priv.ext.XDate(false).setHours(0, 0, 0, 0);\n            var daysDiff = Math.floor(e.date / (60 * 60 * 24 * 1000)) - Math.floor(today / (60 * 60 * 24 * 1000));\n\n            var filter = $(e.data.input);\n            var op = \"..\";\n            var pos = filter.val().indexOf(op);\n            var lval = filter.val().substring(0, pos);\n            var rval = filter.val().substring(pos + op.length);\n\n            if (_currDpOp == \"l\") lval = daysDiff;\n            if (_currDpOp == \"r\") rval = daysDiff;\n\n            filter.val(\"{0}{1}{2}\".f(lval, op, rval));\n            Placeholders.enable(input);\n            $(this).datepicker('hide');\n            filter.trigger('keyup');\n        };\n\n        /*\n         when: rows array are modified\n         what: table gets recreated\n         */\n        priv.rowsChanged = function(splices) {\n\n            $.each(splices, function(index, splice) {\n\n                var start = new priv.ext.XDate();\n                var from = splice.index;\n                var to = splice.index + splice.addedCount;\n\n                //update indexes\n                $.each(_data.meta.rowsAll.slice(to), function(index, row) {\n                    _data.meta.rowsLookup[row[_uniqueCol]].index = to + index;\n                });\n                //remove old references\n                $.each(splice.removed, function(index, row) {\n                    delete _data.meta.rowObservers[row[_uniqueCol]];\n                    delete _data.meta.rowsLookup[row[_uniqueCol]];\n                    delete _data.meta.rowsChecked[row[_uniqueCol]];\n                });                \n\n                //get the new rows, add them to lookup and make them observable\n                $.each(_data.meta.rowsAll.slice(from, to), function (index, row) {\n                    _data.meta.rowsLookup[row[_uniqueCol]] = {\n                        index: from + index,\n                        row: row\n                    };\n                    if (row[\"row-checked\"] === true)\n                        _data.meta.rowsChecked[row[_uniqueCol]] = row;\n                    else\n                        delete _data.meta.rowsChecked[row[_uniqueCol]];\n                    priv.addRowObserver(row);\n                });\n\n                priv.log('splicing finished in {0}ms.'.f(new priv.ext.XDate() - start));\n            });\n\n            _body = undefined;\n            _foot = undefined;\n            priv.filter();\n            priv.sort();\n            priv.createTable();\n        };\n\n        /*\n         when: row object is modified\n         what: recreates cell(if rendered) or table(if column is sorted/filtered on)\n         */\n        priv.rowChanged = function(row, added, removed, changed, getOldValueFn) {\n            var rowRendered = _data.meta.rowsRendered[row[_uniqueCol]];\n            var createTable = false;\n\n            var render = function(property) {\n                var col = _data.cols[property];\n                if (!col) col = _data.cols[property.substring(0, property.indexOf('Format'))];\n                if (!col) col = _data.cols[property.substring(0, property.indexOf('Cls'))];\n\n                if (property == 'row-checked') {\n                    if (row[\"row-checked\"] === true)\n                        _data.meta.rowsChecked[row[_uniqueCol]] = row;\n                    else\n                        delete _data.meta.rowsChecked[row[_uniqueCol]];\n                    //re-render table if sorting/filtering on checked state\n                    if (col && _filterCols[col.column] || _data.cols[_currSortCol] == col)\n                        createTable = true;\n                    //otherwise, re-render the checkbox\n                    else if (rowRendered)\n                        $('input.unique', rowRendered.closest('tr')).prop('checked', row[\"row-checked\"] === true);\n                    return;\n                }\n                // re-render checkbox if checkable state changed\n                if (property == 'row-checkable' && rowRendered) {\n                    $('input.unique', rowRendered.closest('tr')).prop('disabled', row[\"row-checkable\"] === false);\n                    return;\n                }\n                // when row-class, find cell not unique/sorted/filtered on, and fall though to trigger a cell update\n                if (property == 'row-cls' && rowRendered) {\n                    $.each(_data.cols, function (column, props) {\n                        if (props.column == _uniqueCol || props.hidden || _filterCols[props.column] || _data.cols[_currSortCol] == props)\n                            return;\n                        col = props;\n                        return false;\n                    });\n                    if (!col) {\n                        createTable = true;\n                        return;\n                    }\n                }\n\n                if (col && !col.hidden === true) {\n                    //re-render table if filtering/sorting on this column\n                    if (_filterCols[col.column] || _data.cols[_currSortCol] == col) {\n                        createTable = true;\n                        return;\n                    }\n                    //re-render cell if cell is rendered.\n                    if (rowRendered) {\n                        var start = new priv.ext.XDate();\n                        var cell = $('.watable-col-{0}'.f(col.column), rowRendered);\n                        priv.renderCell(cell, col.column, row, rowRendered);\n                        priv.log('row({0}).{1} changed value from:{2} to:{3} in {4}ms'.f(row[_uniqueCol], col.column, getOldValueFn(col.column), changed[col.column], new priv.ext.XDate() - start));\n                    }\n                }\n            };\n\n            var isReserved = function(property) {\n                var reserved = false;\n                $.each(_reservedRowProps, function(index, prop) {\n                    if (property.indexOf(prop) >= 0) {\n                        reserved = true;\n                        return false;\n                    }\n                });\n                return reserved;\n            };\n\n            $.each(Object.keys(changed), function(index, property) {\n                if (isReserved(property) || createTable) return false;\n                render(property);\n            });\n            $.each(Object.keys(added), function(index, property) {\n                if (isReserved(property) || createTable) return false;\n                render(property);\n            });\n            $.each(Object.keys(removed), function(index, property) {\n                if (isReserved(property) || createTable) return false;\n                render(property);\n            });\n\n            if (createTable) {\n                _body = undefined;\n                priv.filter();\n                priv.sort();\n                priv.createTable();\n            }\n        };\n\n\n        /* Public API\n         *************************************************************************/\n\n        publ.init = function (options) {\n            priv.log('watable initialization...');\n            //merge supplied options with defaults\n            $.extend(priv.options, defaults, options);\n            priv.init();\n            return publ;\n        };\n\n        publ.update = function (callback, skipCols, resetChecked) {\n            priv.log('publ.update called');\n            priv.update(callback, skipCols, resetChecked);\n            return publ;\n        };\n\n        publ.getRow = function(unique) {\n            priv.log('publ.getRow called');\n            if (!_uniqueCol) {\n                priv.log('No unique column defined', true);\n                return;\n            }\n            return _data.meta.rowsLookup[unique];\n        }\n\n        publ.getData = function (checked, filtered, rendered) {\n            priv.log('publ.getData called');\n            return priv.getData(checked, filtered, rendered);\n        };\n\n        publ.setData = function (data, skipCols, resetChecked) {\n            priv.log('publ.setData called');\n            priv.setData(data, skipCols, resetChecked);\n            return publ;\n        };\n\n        publ.option = function (option, val) {\n            priv.log('publ.option called');\n            if (val == undefined) return priv.options[option];\n            priv.options[option] = val;\n            _head = undefined;\n            _body = undefined;\n            _foot = undefined;\n            priv.createTable();\n            return publ;\n        };\n\n        return publ;\n    };\n\n    $.fn.WATable = function (options) {\n        options = options || {};\n        return this.each(function () {\n            options.id = this;\n            $(this).data('WATable', new WATable().init(options));\n        });\n    };\n\n    String.prototype.format = String.prototype.f = function () {\n        var s = this;\n        var i = arguments.length;\n        while (i--) s = s.replace(new RegExp('\\\\{' + i + '\\\\}', 'gm'), arguments[i]);\n        return s;\n    };\n\n    //Polyfills\n    /* placeholders.js */ (function(t){\"use strict\";function e(t,e,r){return t.addEventListener?t.addEventListener(e,r,!1):t.attachEvent?t.attachEvent(\"on\"+e,r):void 0}function r(t,e){var r,n;for(r=0,n=t.length;n>r;r++)if(t[r]===e)return!0;return!1}function n(t,e){var r;t.createTextRange?(r=t.createTextRange(),r.move(\"character\",e),r.select()):t.selectionStart&&(t.focus(),t.setSelectionRange(e,e))}function a(t,e){try{return t.type=e,!0}catch(r){return!1}}t.Placeholders={Utils:{addEventListener:e,inArray:r,moveCaret:n,changeType:a}}})(this),function(t){\"use strict\";function e(t){var e;return t.value===t.getAttribute(S)&&\"true\"===t.getAttribute(I)?(t.setAttribute(I,\"false\"),t.value=\"\",t.className=t.className.replace(R,\"\"),e=t.getAttribute(P),e&&(t.type=e),!0):!1}function r(t){var e,r=t.getAttribute(S);return\"\"===t.value&&r?(t.setAttribute(I,\"true\"),t.value=r,t.className+=\" \"+k,e=t.getAttribute(P),e?t.type=\"text\":\"password\"===t.type&&H.changeType(t,\"text\")&&t.setAttribute(P,\"password\"),!0):!1}function n(t,e){var r,n,a,u,i;if(t&&t.getAttribute(S))e(t);else for(r=t?t.getElementsByTagName(\"input\"):v,n=t?t.getElementsByTagName(\"textarea\"):b,i=0,u=r.length+n.length;u>i;i++)a=r.length>i?r[i]:n[i-r.length],e(a)}function a(t){n(t,e)}function u(t){n(t,r)}function i(t){return function(){f&&t.value===t.getAttribute(S)&&\"true\"===t.getAttribute(I)?H.moveCaret(t,0):e(t)}}function l(t){return function(){r(t)}}function c(t){return function(e){return p=t.value,\"true\"===t.getAttribute(I)?!(p===t.getAttribute(S)&&H.inArray(C,e.keyCode)):void 0}}function o(t){return function(){var e;\"true\"===t.getAttribute(I)&&t.value!==p&&(t.className=t.className.replace(R,\"\"),t.value=t.value.replace(t.getAttribute(S),\"\"),t.setAttribute(I,!1),e=t.getAttribute(P),e&&(t.type=e)),\"\"===t.value&&(t.blur(),H.moveCaret(t,0))}}function s(t){return function(){t===document.activeElement&&t.value===t.getAttribute(S)&&\"true\"===t.getAttribute(I)&&H.moveCaret(t,0)}}function d(t){return function(){a(t)}}function g(t){t.form&&(x=t.form,x.getAttribute(U)||(H.addEventListener(x,\"submit\",d(x)),x.setAttribute(U,\"true\"))),H.addEventListener(t,\"focus\",i(t)),H.addEventListener(t,\"blur\",l(t)),f&&(H.addEventListener(t,\"keydown\",c(t)),H.addEventListener(t,\"keyup\",o(t)),H.addEventListener(t,\"click\",s(t))),t.setAttribute(j,\"true\"),t.setAttribute(S,y),r(t)}var v,b,f,h,p,m,A,y,E,x,T,N,L,w=[\"text\",\"search\",\"url\",\"tel\",\"email\",\"password\",\"number\",\"textarea\"],C=[27,33,34,35,36,37,38,39,40,8,46],B=\"#ccc\",k=\"placeholdersjs\",R=RegExp(\"\\\\b\"+k+\"\\\\b\"),S=\"data-placeholder-value\",I=\"data-placeholder-active\",P=\"data-placeholder-type\",U=\"data-placeholder-submit\",j=\"data-placeholder-bound\",V=\"data-placeholder-focus\",q=\"data-placeholder-live\",z=document.createElement(\"input\"),D=document.getElementsByTagName(\"head\")[0],F=document.documentElement,G=t.Placeholders,H=G.Utils;if(void 0===z.placeholder){for(v=document.getElementsByTagName(\"input\"),b=document.getElementsByTagName(\"textarea\"),f=\"false\"===F.getAttribute(V),h=\"false\"!==F.getAttribute(q),m=document.createElement(\"style\"),m.type=\"text/css\",A=document.createTextNode(\".\"+k+\" { color:\"+B+\"; }\"),m.styleSheet?m.styleSheet.cssText=A.nodeValue:m.appendChild(A),D.insertBefore(m,D.firstChild),L=0,N=v.length+b.length;N>L;L++)T=v.length>L?v[L]:b[L-v.length],y=T.getAttribute(\"placeholder\"),y&&H.inArray(w,T.type)&&g(T);E=setInterval(function(){for(L=0,N=v.length+b.length;N>L;L++)T=v.length>L?v[L]:b[L-v.length],y=T.getAttribute(\"placeholder\"),y&&H.inArray(w,T.type)&&(T.getAttribute(j)||g(T),(y!==T.getAttribute(S)||\"password\"===T.type&&!T.getAttribute(P))&&(\"password\"===T.type&&!T.getAttribute(P)&&H.changeType(T,\"text\")&&T.setAttribute(P,\"password\"),T.value===T.getAttribute(S)&&(T.value=y),T.setAttribute(S,y)));h||clearInterval(E)},100)}G.disable=a,G.enable=u}(this);\n    /* json3 */ (function(){var e=null;(function(t){function r(t){if(r[t]!==u)return r[t];var s;if(\"bug-string-char-index\"==t)s=\"a\"!=\"a\"[0];else if(\"json\"==t)s=r(\"json-stringify\")&&r(\"json-parse\");else{var o;if(\"json-stringify\"==t){s=l.stringify;var a=\"function\"==typeof s&&c;if(a){(o=function(){return 1}).toJSON=o;try{a=\"0\"===s(0)&&\"0\"===s(new Number)&&'\"\"'==s(new String)&&s(i)===u&&s(u)===u&&s()===u&&\"1\"===s(o)&&\"[1]\"==s([o])&&\"[null]\"==s([u])&&\"null\"==s(e)&&\"[null,null,null]\"==s([u,i,e])&&'{\"a\":[1,true,false,null,\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\"]}'==s({a:[o,!0,!1,e,\"\\0\\b\\n\\f\\r   \"]})&&\"1\"===s(e,o)&&\"[\\n 1,\\n 2\\n]\"==s([1,2],e,1)&&'\"-271821-04-20T00:00:00.000Z\"'==s(new Date(-864e13))&&'\"+275760-09-13T00:00:00.000Z\"'==s(new Date(864e13))&&'\"-000001-01-01T00:00:00.000Z\"'==s(new Date(-621987552e5))&&'\"1969-12-31T23:59:59.999Z\"'==s(new Date(-1))}catch(f){a=!1}}s=a}if(\"json-parse\"==t){s=l.parse;if(\"function\"==typeof s)try{if(0===s(\"0\")&&!s(!1)){o=s('{\"a\":[1,true,false,null,\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\"]}');var h=5==o.a.length&&1===o.a[0];if(h){try{h=!s('\"   \"')}catch(p){}if(h)try{h=1!==s(\"01\")}catch(d){}if(h)try{h=1!==s(\"1.\")}catch(v){}}}}catch(m){h=!1}s=h}}return r[t]=!!s}var i={}.toString,s,o,u,a=typeof define===\"function\"&&define.amd,f=\"object\"==typeof JSON&&JSON,l=\"object\"==typeof exports&&exports&&!exports.nodeType&&exports;l&&f?(l.stringify=f.stringify,l.parse=f.parse):l=t.JSON=f||{};var c=new Date(-0xc782b5b800cec);try{c=-109252==c.getUTCFullYear()&&0===c.getUTCMonth()&&1===c.getUTCDate()&&10==c.getUTCHours()&&37==c.getUTCMinutes()&&6==c.getUTCSeconds()&&708==c.getUTCMilliseconds()}catch(h){}if(!r(\"json\")){var p=r(\"bug-string-char-index\");if(!c)var d=Math.floor,v=[0,31,59,90,120,151,181,212,243,273,304,334],m=function(e,t){return v[t]+365*(e-1970)+d((e-1969+(t=+(t>1)))/4)-d((e-1901+t)/100)+d((e-1601+t)/400)};if(!(s={}.hasOwnProperty))s=function(t){var r={},o;if((r.__proto__=e,r.__proto__={toString:1},r).toString!=i)s=function(t){var r=this.__proto__,t=t in(this.__proto__=e,this);this.__proto__=r;return t};else{o=r.constructor;s=function(e){var t=(this.constructor||o).prototype;return e in this&&!(e in t&&this[e]===t[e])}}r=e;return s.call(this,t)};var g={\"boolean\":1,number:1,string:1,\"undefined\":1};o=function(t,r){var u=0,a,f,l;(a=function(){this.valueOf=0}).prototype.valueOf=0;f=new a;for(l in f)s.call(f,l)&&u++;a=f=e;if(u)o=u==2?function(e,t){var n={},r=i.call(e)==\"[object Function]\",o;for(o in e)!(r&&o==\"prototype\")&&!s.call(n,o)&&(n[o]=1)&&s.call(e,o)&&t(o)}:function(e,t){var n=i.call(e)==\"[object Function]\",r,o;for(r in e)!(n&&r==\"prototype\")&&s.call(e,r)&&!(o=r===\"constructor\")&&t(r);(o||s.call(e,r=\"constructor\"))&&t(r)};else{f=[\"valueOf\",\"toString\",\"toLocaleString\",\"propertyIsEnumerable\",\"isPrototypeOf\",\"hasOwnProperty\",\"constructor\"];o=function(e,t){var n=i.call(e)==\"[object Function]\",r,o;if(o=!n)if(o=typeof e.constructor!=\"function\"){o=typeof e.hasOwnProperty;o=o==\"object\"?!!e.hasOwnProperty:!g[o]}o=o?e.hasOwnProperty:s;for(r in e)!(n&&r==\"prototype\")&&o.call(e,r)&&t(r);for(n=f.length;r=f[--n];o.call(e,r)&&t(r));}}return o(t,r)};if(!r(\"json-stringify\")){var y={92:\"\\\\\\\\\",34:'\\\\\"',8:\"\\\\b\",12:\"\\\\f\",10:\"\\\\n\",13:\"\\\\r\",9:\"\\\\t\"},b=function(e,t){return(\"000000\"+(t||0)).slice(-e)},w=function(e){var t='\"',n=0,r=e.length,i=r>10&&p,s;for(i&&(s=e.split(\"\"));n<r;n++){var o=e.charCodeAt(n);switch(o){case 8:case 9:case 10:case 12:case 13:case 34:case 92:t=t+y[o];break;default:if(o<32){t=t+(\"\\\\u00\"+b(2,o.toString(16)));break}t=t+(i?s[n]:p?e.charAt(n):e[n])}}return t+'\"'},E=function(t,r,a,f,l,c,h){var p,v,g,y,S,x,T,N,C;try{p=r[t]}catch(k){}if(typeof p==\"object\"&&p){v=i.call(p);if(v==\"[object Date]\"&&!s.call(p,\"toJSON\"))if(p>-1/0&&p<1/0){if(m){y=d(p/864e5);for(v=d(y/365.2425)+1970-1;m(v+1,0)<=y;v++);for(g=d((y-m(v,0))/30.42);m(v,g+1)<=y;g++);y=1+y-m(v,g);S=(p%864e5+864e5)%864e5;x=d(S/36e5)%24;T=d(S/6e4)%60;N=d(S/1e3)%60;S=S%1e3}else{v=p.getUTCFullYear();g=p.getUTCMonth();y=p.getUTCDate();x=p.getUTCHours();T=p.getUTCMinutes();N=p.getUTCSeconds();S=p.getUTCMilliseconds()}p=(v<=0||v>=1e4?(v<0?\"-\":\"+\")+b(6,v<0?-v:v):b(4,v))+\"-\"+b(2,g+1)+\"-\"+b(2,y)+\"T\"+b(2,x)+\":\"+b(2,T)+\":\"+b(2,N)+\".\"+b(3,S)+\"Z\"}else p=e;else if(typeof p.toJSON==\"function\"&&(v!=\"[object Number]\"&&v!=\"[object String]\"&&v!=\"[object Array]\"||s.call(p,\"toJSON\")))p=p.toJSON(t)}a&&(p=a.call(r,t,p));if(p===e)return\"null\";v=i.call(p);if(v==\"[object Boolean]\")return\"\"+p;if(v==\"[object Number]\")return p>-1/0&&p<1/0?\"\"+p:\"null\";if(v==\"[object String]\")return w(\"\"+p);if(typeof p==\"object\"){for(t=h.length;t--;)if(h[t]===p)throw TypeError();h.push(p);C=[];r=c;c=c+l;if(v==\"[object Array]\"){g=0;for(t=p.length;g<t;g++){v=E(g,p,a,f,l,c,h);C.push(v===u?\"null\":v)}t=C.length?l?\"[\\n\"+c+C.join(\",\\n\"+c)+\"\\n\"+r+\"]\":\"[\"+C.join(\",\")+\"]\":\"[]\"}else{o(f||p,function(e){var t=E(e,p,a,f,l,c,h);t!==u&&C.push(w(e)+\":\"+(l?\" \":\"\")+t)});t=C.length?l?\"{\\n\"+c+C.join(\",\\n\"+c)+\"\\n\"+r+\"}\":\"{\"+C.join(\",\")+\"}\":\"{}\"}h.pop();return t}};l.stringify=function(e,t,n){var r,s,o,u;if(typeof t==\"function\"||typeof t==\"object\"&&t)if((u=i.call(t))==\"[object Function]\")s=t;else if(u==\"[object Array]\"){o={};for(var a=0,f=t.length,l;a<f;l=t[a++],(u=i.call(l),u==\"[object String]\"||u==\"[object Number]\")&&(o[l]=1));}if(n)if((u=i.call(n))==\"[object Number]\"){if((n=n-n%1)>0){r=\"\";for(n>10&&(n=10);r.length<n;r=r+\" \");}}else u==\"[object String]\"&&(r=n.length<=10?n:n.slice(0,10));return E(\"\",(l={},l[\"\"]=e,l),s,o,r,\"\",[])}}if(!r(\"json-parse\")){var S=String.fromCharCode,x={92:\"\\\\\",34:'\"',47:\"/\",98:\"\\b\",116:\"    \",110:\"\\n\",102:\"\\f\",114:\"\\r\"},T,N,C=function(){T=N=e;throw SyntaxError()},k=function(){for(var t=N,r=t.length,i,s,o,u,a;T<r;){a=t.charCodeAt(T);switch(a){case 9:case 10:case 13:case 32:T++;break;case 123:case 125:case 91:case 93:case 58:case 44:i=p?t.charAt(T):t[T];T++;return i;case 34:i=\"@\";for(T++;T<r;){a=t.charCodeAt(T);if(a<32)C();else if(a==92){a=t.charCodeAt(++T);switch(a){case 92:case 34:case 47:case 98:case 116:case 110:case 102:case 114:i=i+x[a];T++;break;case 117:s=++T;for(o=T+4;T<o;T++){a=t.charCodeAt(T);a>=48&&a<=57||a>=97&&a<=102||a>=65&&a<=70||C()}i=i+S(\"0x\"+t.slice(s,T));break;default:C()}}else{if(a==34)break;a=t.charCodeAt(T);for(s=T;a>=32&&a!=92&&a!=34;)a=t.charCodeAt(++T);i=i+t.slice(s,T)}}if(t.charCodeAt(T)==34){T++;return i}C();default:s=T;if(a==45){u=true;a=t.charCodeAt(++T)}if(a>=48&&a<=57){for(a==48&&(a=t.charCodeAt(T+1),a>=48&&a<=57)&&C();T<r&&(a=t.charCodeAt(T),a>=48&&a<=57);T++);if(t.charCodeAt(T)==46){for(o=++T;o<r&&(a=t.charCodeAt(o),a>=48&&a<=57);o++);o==T&&C();T=o}a=t.charCodeAt(T);if(a==101||a==69){a=t.charCodeAt(++T);(a==43||a==45)&&T++;for(o=T;o<r&&(a=t.charCodeAt(o),a>=48&&a<=57);o++);o==T&&C();T=o}return+t.slice(s,T)}u&&C();if(t.slice(T,T+4)==\"true\"){T=T+4;return true}if(t.slice(T,T+5)==\"false\"){T=T+5;return false}if(t.slice(T,T+4)==\"null\"){T=T+4;return e}C()}}return\"$\"},L=function(e){var t,n;e==\"$\"&&C();if(typeof e==\"string\"){if((p?e.charAt(0):e[0])==\"@\")return e.slice(1);if(e==\"[\"){for(t=[];;n||(n=true)){e=k();if(e==\"]\")break;if(n)if(e==\",\"){e=k();e==\"]\"&&C()}else C();e==\",\"&&C();t.push(L(e))}return t}if(e==\"{\"){for(t={};;n||(n=true)){e=k();if(e==\"}\")break;if(n)if(e==\",\"){e=k();e==\"}\"&&C()}else C();(e==\",\"||typeof e!=\"string\"||(p?e.charAt(0):e[0])!=\"@\"||k()!=\":\")&&C();t[e.slice(1)]=L(k())}return t}C()}return e},A=function(e,t,n){n=O(e,t,n);n===u?delete e[t]:e[t]=n},O=function(e,t,n){var r=e[t],s;if(typeof r==\"object\"&&r)if(i.call(r)==\"[object Array]\")for(s=r.length;s--;)A(r,s,n);else o(r,function(e){A(r,e,n)});return n.call(e,t,r)};l.parse=function(t,r){var s,o;T=0;N=\"\"+t;s=L(k());k()!=\"$\"&&C();T=N=e;return r&&i.call(r)==\"[object Function]\"?O((o={},o[\"\"]=s,o),\"\",r):s}}}a&&define(function(){return l})})(this)})();\n    Object.keys = Object.keys || function(o) { var result = []; for(var name in o) {  if (o.hasOwnProperty(name)) result.push(name); } return result; };\n    String.prototype.trim = String.prototype.trim || function () { return this.replace(/^\\s+|\\s+$/g,''); };\n    Date.now = Date.now || function() { return +new Date; };\n    console = window.console || { log:function(){}, warn:function(){} };\n    /* polymer observe-js, Copyright (c) 2014 The Polymer Authors. All rights reserved. */ (function(e){\"use strict\";function n(){function t(t){e=t}if(typeof Object.observe!==\"function\"||typeof Array.observe!==\"function\"){return false}var e=[];var n={};var r=[];Object.observe(n,t);Array.observe(r,t);n.id=1;n.id=2;delete n.id;r.push(1,2);r.length=0;Object.deliverChangeRecords(t);if(e.length!==5)return false;if(e[0].type!=\"add\"||e[1].type!=\"update\"||e[2].type!=\"delete\"||e[3].type!=\"splice\"||e[4].type!=\"splice\"){return false}Object.unobserve(n,t);Array.unobserve(r,t);return true}function i(){if(typeof chrome!==\"undefined\"&&chrome.app&&chrome.app.runtime){return false}if(typeof navigator!=\"undefined\"&&navigator.getDeviceStorage){return false}try{var e=new Function(\"\",\"return true;\");return e()}catch(t){return false}}function o(e){return+e===e>>>0&&e!==\"\"}function u(e){return+e}function a(e){return e===Object(e)}function l(e,t){if(e===t)return e!==0||1/e===1/t;if(f(e)&&f(t))return true;return e!==e&&t!==t}function v(e){if(e===undefined)return\"eof\";var t=e.charCodeAt(0);switch(t){case 91:case 93:case 46:case 34:case 39:case 48:return e;case 95:case 36:return\"ident\";case 32:case 9:case 10:case 13:case 160:case 65279:case 8232:case 8233:return\"ws\"}if(97<=t&&t<=122||65<=t&&t<=90)return\"ident\";if(49<=t&&t<=57)return\"number\";return\"else\"}function g(){}function y(e){function h(){if(n>=e.length)return;var t=e[n+1];if(l==\"inSingleQuote\"&&t==\"'\"||l==\"inDoubleQuote\"&&t=='\"'){n++;i=t;c.append();return true}}var t=[];var n=-1;var r,i,s,o,u,a,f,l=\"beforePath\";var c={push:function(){if(s===undefined)return;t.push(s);s=undefined},append:function(){if(s===undefined)s=i;else s+=i}};while(l){n++;r=e[n];if(r==\"\\\\\"&&h(l))continue;o=v(r);f=m[l];u=f[o]||f[\"else\"]||\"error\";if(u==\"error\")return;l=u[0];a=c[u[1]]||g;i=u[2]===undefined?r:u[2];a();if(l===\"afterPath\"){return t}}return}function b(e){return d.test(e)}function E(e,t){if(t!==w)throw Error(\"Use Path.get to retrieve path objects\");for(var n=0;n<e.length;n++){this.push(String(e[n]))}if(s&&this.length){this.getValueFrom=this.compiledGetValueFromFn()}}function x(e){if(e instanceof E)return e;if(e==null||e.length==0)e=\"\";if(typeof e!=\"string\"){if(o(e.length)){return new E(e,w)}e=String(e)}var t=S[e];if(t)return t;var n=y(e);if(!n)return N;var t=new E(n,w);S[e]=t;return t}function T(e){if(o(e)){return\"[\"+e+\"]\"}else{return'[\"'+e.replace(/\"/g,'\\\\\"')+'\"]'}}function k(n){var r=0;while(r<C&&n.check_()){r++}if(t)e.dirtyCheckCycleCount=r;return r>0}function L(e){for(var t in e)return false;return true}function A(e){return L(e.added)&&L(e.removed)&&L(e.changed)}function O(e,t){var n={};var r={};var i={};for(var s in t){var o=e[s];if(o!==undefined&&o===t[s])continue;if(!(s in e)){r[s]=undefined;continue}if(o!==t[s])i[s]=o}for(var s in e){if(s in t)continue;n[s]=e[s]}if(Array.isArray(e)&&e.length!==t.length)i.length=e.length;return{added:n,removed:r,changed:i}}function _(){if(!M.length)return false;for(var e=0;e<M.length;e++){M[e]()}M.length=0;return true}function H(){function i(t){if(e&&e.state_===U&&!n)e.check_(t)}var e;var t;var n=false;var r=true;return{open:function(t){if(e)throw Error(\"ObservedObject in use\");if(!r)Object.deliverChangeRecords(i);e=t;r=false},observe:function(e,n){t=e;if(n)Array.observe(t,i);else Object.observe(t,i)},deliver:function(e){n=e;Object.deliverChangeRecords(i);n=false},close:function(){e=undefined;Object.unobserve(t,i);P.push(this)}}}function B(e,t,n){var r=P.pop()||H();r.open(e);r.observe(t,n);return r}function F(){function s(e,t){if(!e)return;if(e===r)i[t]=true;if(n.indexOf(e)<0){n.push(e);Object.observe(e,u)}s(Object.getPrototypeOf(e),t)}function o(e){for(var t=0;t<e.length;t++){var n=e[t];if(n.object!==r||i[n.name]||n.type===\"setPrototype\"){return false}}return true}function u(e){if(o(e))return;var n;for(var r=0;r<t.length;r++){n=t[r];if(n.state_==U){n.iterateObjects_(s)}}for(var r=0;r<t.length;r++){n=t[r];if(n.state_==U){n.check_()}}}var e=0;var t=[];var n=[];var r;var i;var a={objects:n,get rootObject(){return r},set rootObject(e){r=e;i={}},open:function(n,r){t.push(n);e++;n.iterateObjects_(s)},close:function(s){e--;if(e>0){return}for(var o=0;o<n.length;o++){Object.unobserve(n[o],u);V.unobservedCount++}t.length=0;n.length=0;r=undefined;i=undefined;j.push(this);if(I===this)I=null}};return a}function q(e,t){if(!I||I.rootObject!==t){I=j.pop()||F();I.rootObject=t}I.open(e,t);return I}function V(){this.state_=R;this.callback_=undefined;this.target_=undefined;this.directObserver_=undefined;this.value_=undefined;this.id_=X++}function K(e){V._allObserversCount++;if(!$)return;J.push(e)}function Q(e){V._allObserversCount--}function Y(e){V.call(this);this.value_=e;this.oldObject_=undefined}function Z(e){if(!Array.isArray(e))throw Error(\"Provided object is not an Array\");Y.call(this,e)}function et(e,t){V.call(this);this.object_=e;this.path_=x(t);this.directObserver_=undefined}function tt(e){V.call(this);this.reportChangesOnOpen_=e;this.value_=[];this.directObserver_=undefined;this.observed_=[]}function rt(e){return e}function it(e,t,n,r){this.callback_=undefined;this.target_=undefined;this.value_=undefined;this.observable_=e;this.getValueFn_=t||rt;this.setValueFn_=n||rt;this.dontPassThroughSet_=r}function ot(e,t,n){var r={};var i={};for(var s=0;s<t.length;s++){var o=t[s];if(!st[o.type]){console.error(\"Unknown changeRecord type: \"+o.type);console.error(o);continue}if(!(o.name in n))n[o.name]=o.oldValue;if(o.type==\"update\")continue;if(o.type==\"add\"){if(o.name in i)delete i[o.name];else r[o.name]=true;continue}if(o.name in r){delete r[o.name];delete n[o.name]}else{i[o.name]=true}}for(var u in r)r[u]=e[u];for(var u in i)i[u]=undefined;var a={};for(var u in n){if(u in r||u in i)continue;var f=e[u];if(n[u]!==f)a[u]=f}return{added:r,removed:i,changed:a}}function ut(e,t,n){return{index:e,removed:t,addedCount:n}}function ht(){}function dt(e,t,n,r,i,s){return pt.calcSplices(e,t,n,r,i,s)}function vt(e,t,n,r){if(t<n||r<e)return-1;if(t==n||r==e)return 0;if(e<n){if(t<r)return t-n;else return r-n}else{if(r<t)return r-e;else return t-e}}function mt(e,t,n,r){var i=ut(t,n,r);var s=false;var o=0;for(var u=0;u<e.length;u++){var a=e[u];a.index+=o;if(s)continue;var f=vt(i.index,i.index+i.removed.length,a.index,a.index+a.addedCount);if(f>=0){e.splice(u,1);u--;o-=a.addedCount-a.removed.length;i.addedCount+=a.addedCount-f;var l=i.removed.length+a.removed.length-f;if(!i.addedCount&&!l){s=true}else{var n=a.removed;if(i.index<a.index){var c=i.removed.slice(0,a.index-i.index);Array.prototype.push.apply(c,n);n=c}if(i.index+i.removed.length>a.index+a.addedCount){var h=i.removed.slice(a.index+a.addedCount-i.index);Array.prototype.push.apply(n,h)}i.removed=n;if(a.index<i.index){i.index=a.index}}}else if(i.index<a.index){s=true;e.splice(u,0,i);u++;var p=i.addedCount-i.removed.length;a.index+=p;o+=p}}if(!s)e.push(i)}function gt(e,t){var n=[];for(var r=0;r<t.length;r++){var i=t[r];switch(i.type){case\"splice\":mt(n,i.index,i.removed.slice(),i.addedCount);break;case\"add\":case\"update\":case\"delete\":if(!o(i.name))continue;var s=u(i.name);if(s<0)continue;mt(n,s,[i.oldValue],1);break;default:console.error(\"Unexpected record type: \"+JSON.stringify(i));break}}return n}function yt(e,t){var n=[];gt(e,t).forEach(function(t){if(t.addedCount==1&&t.removed.length==1){if(t.removed[0]!==e[t.index])n.push(t);return}n=n.concat(dt(e,t.index,t.index+t.addedCount,t.removed,0,t.removed.length))});return n}var t=e.testingExposeCycleCount;var r=n();var s=i();var f=e.Number.isNaN||function(t){return typeof t===\"number\"&&e.isNaN(t)};var c=\"__proto__\"in{}?function(e){return e}:function(e){var t=e.__proto__;if(!t)return e;var n=Object.create(t);Object.getOwnPropertyNames(e).forEach(function(t){Object.defineProperty(n,t,Object.getOwnPropertyDescriptor(e,t))});return n};var h=\"[$_a-zA-Z]\";var p=\"[$_a-zA-Z0-9]\";var d=new RegExp(\"^\"+h+\"+\"+p+\"*\"+\"$\");var m={beforePath:{ws:[\"beforePath\"],ident:[\"inIdent\",\"append\"],\"[\":[\"beforeElement\"],eof:[\"afterPath\"]},inPath:{ws:[\"inPath\"],\".\":[\"beforeIdent\"],\"[\":[\"beforeElement\"],eof:[\"afterPath\"]},beforeIdent:{ws:[\"beforeIdent\"],ident:[\"inIdent\",\"append\"]},inIdent:{ident:[\"inIdent\",\"append\"],0:[\"inIdent\",\"append\"],number:[\"inIdent\",\"append\"],ws:[\"inPath\",\"push\"],\".\":[\"beforeIdent\",\"push\"],\"[\":[\"beforeElement\",\"push\"],eof:[\"afterPath\",\"push\"]},beforeElement:{ws:[\"beforeElement\"],0:[\"afterZero\",\"append\"],number:[\"inIndex\",\"append\"],\"'\":[\"inSingleQuote\",\"append\",\"\"],'\"':[\"inDoubleQuote\",\"append\",\"\"]},afterZero:{ws:[\"afterElement\",\"push\"],\"]\":[\"inPath\",\"push\"]},inIndex:{0:[\"inIndex\",\"append\"],number:[\"inIndex\",\"append\"],ws:[\"afterElement\"],\"]\":[\"inPath\",\"push\"]},inSingleQuote:{\"'\":[\"afterElement\"],eof:[\"error\"],\"else\":[\"inSingleQuote\",\"append\"]},inDoubleQuote:{'\"':[\"afterElement\"],eof:[\"error\"],\"else\":[\"inDoubleQuote\",\"append\"]},afterElement:{ws:[\"afterElement\"],\"]\":[\"inPath\",\"push\"]}};var w={};var S={};E.get=x;E.prototype=c({__proto__:[],valid:true,toString:function(){var e=\"\";for(var t=0;t<this.length;t++){var n=this[t];if(b(n)){e+=t?\".\"+n:n}else{e+=T(n)}}return e},getValueFrom:function(e,t){for(var n=0;n<this.length;n++){if(e==null)return;e=e[this[n]]}return e},iterateObjects:function(e,t){for(var n=0;n<this.length;n++){if(n)e=e[this[n-1]];if(!a(e))return;t(e,this[n])}},compiledGetValueFromFn:function(){var e=\"\";var t=\"obj\";e+=\"if (obj != null\";var n=0;var r;for(;n<this.length-1;n++){r=this[n];t+=b(r)?\".\"+r:T(r);e+=\" &&\\n     \"+t+\" != null\"}e+=\")\\n\";var r=this[n];t+=b(r)?\".\"+r:T(r);e+=\"  return \"+t+\";\\nelse\\n  return undefined;\";return new Function(\"obj\",e)},setValueFrom:function(e,t){if(!this.length)return false;for(var n=0;n<this.length-1;n++){if(!a(e))return false;e=e[this[n]]}if(!a(e))return false;e[this[n]]=t;return true}});var N=new E(\"\",w);N.valid=false;N.getValueFrom=N.setValueFrom=function(){};var C=1e3;var M=[];var D=r?function(){return function(e){return Promise.resolve().then(e)}}():function(){return function(e){M.push(e)}}();var P=[];var j=[];var I;var R=0;var U=1;var z=2;var W=3;var X=1;V.prototype={open:function(e,t){if(this.state_!=R)throw Error(\"Observer has already been opened.\");K(this);this.callback_=e;this.target_=t;this.connect_();this.state_=U;return this.value_},close:function(){if(this.state_!=U)return;Q(this);this.disconnect_();this.value_=undefined;this.callback_=undefined;this.target_=undefined;this.state_=z},deliver:function(){if(this.state_!=U)return;k(this)},report_:function(e){try{this.callback_.apply(this.target_,e)}catch(t){V._errorThrownDuringCallback=true;console.error(\"Exception caught during observer callback: \"+(t.stack||t))}},discardChanges:function(){this.check_(undefined,true);return this.value_}};var $=!r;var J;V._allObserversCount=0;if($){J=[]}var G=false;e.Platform=e.Platform||{};e.Platform.performMicrotaskCheckpoint=function(){if(G)return;if(!$)return;G=true;var n=0;var r,i;do{n++;i=J;J=[];r=false;for(var s=0;s<i.length;s++){var o=i[s];if(o.state_!=U)continue;if(o.check_())r=true;J.push(o)}if(_())r=true}while(n<C&&r);if(t)e.dirtyCheckCycleCount=n;G=false};if($){e.Platform.clearObservers=function(){J=[]}}Y.prototype=c({__proto__:V.prototype,arrayObserve:false,connect_:function(e,t){if(r){this.directObserver_=B(this,this.value_,this.arrayObserve)}else{this.oldObject_=this.copyObject(this.value_)}},copyObject:function(e){var t=Array.isArray(e)?[]:{};for(var n in e){t[n]=e[n]}if(Array.isArray(e))t.length=e.length;return t},check_:function(e,t){var n;var i;if(r){if(!e)return false;i={};n=ot(this.value_,e,i)}else{i=this.oldObject_;n=O(this.value_,this.oldObject_)}if(A(n))return false;if(!r)this.oldObject_=this.copyObject(this.value_);this.report_([n.added||{},n.removed||{},n.changed||{},function(e){return i[e]}]);return true},disconnect_:function(){if(r){this.directObserver_.close();this.directObserver_=undefined}else{this.oldObject_=undefined}},deliver:function(){if(this.state_!=U)return;if(r)this.directObserver_.deliver(false);else k(this)},discardChanges:function(){if(this.directObserver_)this.directObserver_.deliver(true);else this.oldObject_=this.copyObject(this.value_);return this.value_}});Z.prototype=c({__proto__:Y.prototype,arrayObserve:true,copyObject:function(e){return e.slice()},check_:function(e){var t;if(r){if(!e)return false;t=yt(this.value_,e)}else{t=dt(this.value_,0,this.value_.length,this.oldObject_,0,this.oldObject_.length)}if(!t||!t.length)return false;if(!r)this.oldObject_=this.copyObject(this.value_);this.report_([t]);return true}});Z.applySplices=function(e,t,n){n.forEach(function(n){var r=[n.index,n.removed.length];var i=n.index;while(i<n.index+n.addedCount){r.push(t[i]);i++}Array.prototype.splice.apply(e,r)})};et.prototype=c({__proto__:V.prototype,get path(){return this.path_},connect_:function(){if(r)this.directObserver_=q(this,this.object_);this.check_(undefined,true)},disconnect_:function(){this.value_=undefined;if(this.directObserver_){this.directObserver_.close(this);this.directObserver_=undefined}},iterateObjects_:function(e){this.path_.iterateObjects(this.object_,e)},check_:function(e,t){var n=this.value_;this.value_=this.path_.getValueFrom(this.object_);if(t||l(this.value_,n))return false;this.report_([this.value_,n,this]);return true},setValue:function(e){if(this.path_)this.path_.setValueFrom(this.object_,e)}});var nt={};tt.prototype=c({__proto__:V.prototype,connect_:function(){if(r){var e;var t=false;for(var n=0;n<this.observed_.length;n+=2){e=this.observed_[n];if(e!==nt){t=true;break}}if(t)this.directObserver_=q(this,e)}this.check_(undefined,!this.reportChangesOnOpen_)},disconnect_:function(){for(var e=0;e<this.observed_.length;e+=2){if(this.observed_[e]===nt)this.observed_[e+1].close()}this.observed_.length=0;this.value_.length=0;if(this.directObserver_){this.directObserver_.close(this);this.directObserver_=undefined}},addPath:function(e,t){if(this.state_!=R&&this.state_!=W)throw Error(\"Cannot add paths once started.\");var t=x(t);this.observed_.push(e,t);if(!this.reportChangesOnOpen_)return;var n=this.observed_.length/2-1;this.value_[n]=t.getValueFrom(e)},addObserver:function(e){if(this.state_!=R&&this.state_!=W)throw Error(\"Cannot add observers once started.\");this.observed_.push(nt,e);if(!this.reportChangesOnOpen_)return;var t=this.observed_.length/2-1;this.value_[t]=e.open(this.deliver,this)},startReset:function(){if(this.state_!=U)throw Error(\"Can only reset while open\");this.state_=W;this.disconnect_()},finishReset:function(){if(this.state_!=W)throw Error(\"Can only finishReset after startReset\");this.state_=U;this.connect_();return this.value_},iterateObjects_:function(e){var t;for(var n=0;n<this.observed_.length;n+=2){t=this.observed_[n];if(t!==nt)this.observed_[n+1].iterateObjects(t,e)}},check_:function(e,t){var n;for(var r=0;r<this.observed_.length;r+=2){var i=this.observed_[r];var s=this.observed_[r+1];var o;if(i===nt){var u=s;o=this.state_===R?u.open(this.deliver,this):u.discardChanges()}else{o=s.getValueFrom(i)}if(t){this.value_[r/2]=o;continue}if(l(o,this.value_[r/2]))continue;n=n||[];n[r/2]=this.value_[r/2];this.value_[r/2]=o}if(!n)return false;this.report_([this.value_,n,this.observed_]);return true}});it.prototype={open:function(e,t){this.callback_=e;this.target_=t;this.value_=this.getValueFn_(this.observable_.open(this.observedCallback_,this));return this.value_},observedCallback_:function(e){e=this.getValueFn_(e);if(l(e,this.value_))return;var t=this.value_;this.value_=e;this.callback_.call(this.target_,this.value_,t)},discardChanges:function(){this.value_=this.getValueFn_(this.observable_.discardChanges());return this.value_},deliver:function(){return this.observable_.deliver()},setValue:function(e){e=this.setValueFn_(e);if(!this.dontPassThroughSet_&&this.observable_.setValue)return this.observable_.setValue(e)},close:function(){if(this.observable_)this.observable_.close();this.callback_=undefined;this.target_=undefined;this.observable_=undefined;this.value_=undefined;this.getValueFn_=undefined;this.setValueFn_=undefined}};var st={add:true,update:true,\"delete\":true};var at=0;var ft=1;var lt=2;var ct=3;ht.prototype={calcEditDistances:function(e,t,n,r,i,s){var o=s-i+1;var u=n-t+1;var a=new Array(o);for(var f=0;f<o;f++){a[f]=new Array(u);a[f][0]=f}for(var l=0;l<u;l++)a[0][l]=l;for(var f=1;f<o;f++){for(var l=1;l<u;l++){if(this.equals(e[t+l-1],r[i+f-1]))a[f][l]=a[f-1][l-1];else{var c=a[f-1][l]+1;var h=a[f][l-1]+1;a[f][l]=c<h?c:h}}}return a},spliceOperationsFromEditDistances:function(e){var t=e.length-1;var n=e[0].length-1;var r=e[t][n];var i=[];while(t>0||n>0){if(t==0){i.push(lt);n--;continue}if(n==0){i.push(ct);t--;continue}var s=e[t-1][n-1];var o=e[t-1][n];var u=e[t][n-1];var a;if(o<u)a=o<s?o:s;else a=u<s?u:s;if(a==s){if(s==r){i.push(at)}else{i.push(ft);r=s}t--;n--}else if(a==o){i.push(ct);t--;r=o}else{i.push(lt);n--;r=u}}i.reverse();return i},calcSplices:function(e,t,n,r,i,s){var o=0;var u=0;var a=Math.min(n-t,s-i);if(t==0&&i==0)o=this.sharedPrefix(e,r,a);if(n==e.length&&s==r.length)u=this.sharedSuffix(e,r,a-o);t+=o;i+=o;n-=u;s-=u;if(n-t==0&&s-i==0)return[];if(t==n){var f=ut(t,[],0);while(i<s)f.removed.push(r[i++]);return[f]}else if(i==s)return[ut(t,[],n-t)];var l=this.spliceOperationsFromEditDistances(this.calcEditDistances(e,t,n,r,i,s));var f=undefined;var c=[];var h=t;var p=i;for(var d=0;d<l.length;d++){switch(l[d]){case at:if(f){c.push(f);f=undefined}h++;p++;break;case ft:if(!f)f=ut(h,[],0);f.addedCount++;h++;f.removed.push(r[p]);p++;break;case lt:if(!f)f=ut(h,[],0);f.addedCount++;h++;break;case ct:if(!f)f=ut(h,[],0);f.removed.push(r[p]);p++;break}}if(f){c.push(f)}return c},sharedPrefix:function(e,t,n){for(var r=0;r<n;r++)if(!this.equals(e[r],t[r]))return r;return n},sharedSuffix:function(e,t,n){var r=e.length;var i=t.length;var s=0;while(s<n&&this.equals(e[--r],t[--i]))s++;return s},calculateSplices:function(e,t){return this.calcSplices(e,0,e.length,t,0,t.length)},equals:function(e,t){return e===t}};var pt=new ht;var bt=e;if(typeof exports!==\"undefined\"){if(typeof module!==\"undefined\"&&module.exports){bt=exports=module.exports}bt=exports}bt.Observer=V;bt.Observer.runEOM_=D;bt.Observer.observerSentinel_=nt;bt.Observer.hasObjectObserve=r;bt.ArrayObserver=Z;bt.ArrayObserver.calculateSplices=function(e,t){return pt.calculateSplices(e,t)};bt.ArraySplice=ht;bt.ObjectObserver=Y;bt.PathObserver=et;bt.CompoundObserver=tt;bt.Path=E;bt.ObserverTransform=it})(typeof global!==\"undefined\"&&global&&typeof module!==\"undefined\"&&module?global:this||window);\n\n})(jQuery);"
  },
  {
    "path": "watable.css",
    "content": ".watable * {\n  white-space: nowrap;\n  font-size: 12px !important;\n}\n\n.watable.table {\n  width: auto;\n}\n\n.watable p {\n  margin: 0;\n}\n\n.watable th,\n.watable td {\n  border-width: 1px !important;\n}\n\n.watable .glyphicon {\n  margin: 0 0 0 2px;\n  opacity: 0.5;\n}\n\n.watable span.filter {\n  background-color: #999;\n}\n\n.watable .indeterminate {\n  opacity: 0.4;\n  -ms-filter: \"progid:DXImageTransform.Microsoft.Alpha(Opacity=40)\";\n  filter: alpha(opacity=40);\n}\n\n.watable .columnpicker li,\n.watable .actions li {\n  padding-left: 5px;\n}\n\n.watable .btn-toolbar {\n  margin-bottom: -5px;\n}\n\n.watable .pagination {\n  margin: 0;\n}\n\n.watable input[type=checkbox] {\n  margin: 0;\n  padding: 0;\n}\n\n.watable input[type=text].filter {\n  margin: 0;\n  padding: 0;\n  box-shadow: none;\n  border: none;\n  width: 80px;\n  float: left;\n  background-color: transparent;\n}\n\n.watable .date-wrap {\n  width: 100%;\n  min-width: 115px;\n}\n\n.watable .dateWrap .add-on {\n  margin: 0;\n  padding: 0;\n  background: none;\n  border: none;\n  float: right;\n  cursor: pointer;\n}\n\n.watable .dropdown-menu {\n  max-height: 250px;\n  overflow: auto;\n}\n\n.watable .actions a {\n  padding: 0;\n  margin: 0;\n}\n\n/* Only for demo purposes */\n.watable .green {\n  background: -moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(0,140,37,0.38) 38%, rgba(0,140,37,1) 100%); /* FF3.6+ */\n  background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,255,255,0)), color-stop(38%,rgba(0,140,37,0.38)), color-stop(100%,rgba(0,140,37,1))); /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(0,140,37,0.38) 38%,rgba(0,140,37,1) 100%); /* Chrome10+,Safari5.1+ */\n  background: -o-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(0,140,37,0.38) 38%,rgba(0,140,37,1) 100%); /* Opera 11.10+ */\n  background: -ms-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(0,140,37,0.38) 38%,rgba(0,140,37,1) 100%); /* IE10+ */\n  background: linear-gradient(to right, rgba(255,255,255,0) 0%,rgba(0,140,37,0.38) 38%,rgba(0,140,37,1) 100%); /* W3C */\n  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#008c25',GradientType=1 ); /* IE6-9 */\n}\n\n.watable .yellow {\n  background: -moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(188,179,0,0.38) 38%, rgba(188,179,0,1) 100%); /* FF3.6+ */\n  background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,255,255,0)), color-stop(38%,rgba(188,179,0,0.38)), color-stop(100%,rgba(188,179,0,1))); /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(188,179,0,0.38) 38%,rgba(188,179,0,1) 100%); /* Chrome10+,Safari5.1+ */\n  background: -o-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(188,179,0,0.38) 38%,rgba(188,179,0,1) 100%); /* Opera 11.10+ */\n  background: -ms-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(188,179,0,0.38) 38%,rgba(188,179,0,1) 100%); /* IE10+ */\n  background: linear-gradient(to right, rgba(255,255,255,0) 0%,rgba(188,179,0,0.38) 38%,rgba(188,179,0,1) 100%); /* W3C */\n  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#bcb300',GradientType=1 ); /* IE6-9 */\n}\n\n.watable .red {\n  background: -moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(147,22,0,0.38) 38%, rgba(147,22,0,1) 100%); /* FF3.6+ */\n  background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,255,255,0)), color-stop(38%,rgba(147,22,0,0.38)), color-stop(100%,rgba(147,22,0,1))); /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(147,22,0,0.38) 38%,rgba(147,22,0,1) 100%); /* Chrome10+,Safari5.1+ */\n  background: -o-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(147,22,0,0.38) 38%,rgba(147,22,0,1) 100%); /* Opera 11.10+ */\n  background: -ms-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(147,22,0,0.38) 38%,rgba(147,22,0,1) 100%); /* IE10+ */\n  background: linear-gradient(to right, rgba(255,255,255,0) 0%,rgba(147,22,0,0.38) 38%,rgba(147,22,0,1) 100%); /* W3C */\n  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#931600',GradientType=1 ); /* IE6-9 */\n}\n\n.watable .blue {\n  background: -moz-linear-gradient(left,  rgba(255,255,255,0) 0%, rgba(0,127,206,0.38) 38%, rgba(0,127,206,1) 100%) !important; /* FF3.6+ */\n  background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,255,255,0)), color-stop(38%,rgba(0,127,206,0.38)), color-stop(100%,rgba(0,127,206,1))) !important; /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(left,  rgba(255,255,255,0) 0%,rgba(0,127,206,0.38) 38%,rgba(0,127,206,1) 100%) !important; /* Chrome10+,Safari5.1+ */\n  background: -o-linear-gradient(left,  rgba(255,255,255,0) 0%,rgba(0,127,206,0.38) 38%,rgba(0,127,206,1) 100%) !important; /* Opera 11.10+ */\n  background: -ms-linear-gradient(left,  rgba(255,255,255,0) 0%,rgba(0,127,206,0.38) 38%,rgba(0,127,206,1) 100%) !important;/* IE10+ */\n  background: linear-gradient(to right,  rgba(255,255,255,0) 0%,rgba(0,127,206,0.38) 38%,rgba(0,127,206,1) 100%) !important; /* W3C */\n  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#007fce',GradientType=1 ) !important; /* IE6-9 */\n}\n\n.watable .gray {\n  background-color: #d3d3d3 !important;\n}"
  }
]