├── LICENSE ├── README.md ├── _attachments ├── images │ ├── csv2Couchdb.png │ ├── favicon.png │ ├── html5-badge-h-performance.png │ ├── localCSVs.png │ ├── recline-logo.png │ ├── spinner.gif │ └── square-logo - 23 x 23.png ├── index.html ├── license.html ├── scripts │ ├── app.js │ ├── bulkLoad.js │ ├── jquery-1.6.1.min.js │ ├── jquery.couch.app.js │ ├── jquery.couch.app.util.js │ ├── jquery.couch.js │ └── jquery.csvIn.min.js └── style │ └── main.css ├── _id ├── couchapp.json └── language /LICENSE: -------------------------------------------------------------------------------- 1 | csv2couchdb is released under the MIT License: 2 | 3 | ---------------------------------------------------------- 4 | Copyright (c) 2011 Mango Information Systems SPRL, http://www.mango-is.com 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | ---------------------------------------------------------- 12 | 13 | Source code is available on github: https://github.com/Mango-information-systems/csv2couchdb 14 | 15 | csv2couchdb uses the following components: 16 | 17 | couchdb - Apache License version 2: http://www.apache.org/licenses/LICENSE-2.0 18 | jQuery javascript library - MIT License: http://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt 19 | csvIn jQuery plugin - MIT License: https://github.com/Mango-information-systems/jquery.csvIn/blob/master/LICENSE 20 | 21 | Some of the visuals of this application have been derived from the following sources: 22 | 23 | couchdb logo (c) Damien Katz - Creative Commons Attribution Unported 3: http://creativecommons.org/licenses/by/3.0/deed.en 24 | HTML5 logo (c) W3C - Creative Commons Attribution Unported 3: http://creativecommons.org/licenses/by/3.0/deed.en 25 | public domain cliparts from http://www.openclipart.org/ 26 | public domain spinner from http://mentalized.net/activity-indicators/ 27 | logo of Google refine - new BSD License: http://code.google.com/p/google-refine/source/browse/trunk/LICENSE.txt 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##csv2couchdb - populate couchdb from delimited files 2 | 3 | csv2couchdb is a couchapp allowing to populate couchdb using data from CSV files. It takes advantage of the HTML5 file API to process files at client side before the upload to couchdb. 4 | 5 | ### Features: 6 | 7 | * Read local files 8 | * Select multiple files at a time 9 | * Automatic detection of CSV format 10 | * Preview loaded files to adjust settings 11 | * Customize document to generate 12 | * Filter rows and columns 13 | * Customize header labels 14 | * Generate either one doc per file or one doc per row 15 | * Generate ids based on file name or use couchdb random ids 16 | * Bulk load to couchdb 17 | * Select target database 18 | * Overwrite existing documents in case of conflict (optional) 19 | 20 | ### Usage examples: 21 | 22 | Consider the following CSV file that would be stored in your computer: 23 | 24 | color;popularity 25 | blue;5 26 | green;4.5 27 | red;3 28 | orange;4 29 | 30 | 1. Generate one document per file 31 | 32 | You would insert the following document to couchdb: 33 | 34 | ````javascript 35 | { 36 | "headers": ["color", "popularity"], 37 | "rows":[ 38 | ["blue","5"], 39 | ["green","4.5"], 40 | ["red","3"], 41 | ["orange","4"] 42 | ] 43 | } 44 | ```` 45 | 46 | 2. Generate one document per row 47 | 48 | You would insert the following documents to couchdb: 49 | 50 | ````javascript 51 | { 52 | "color" : "blue", 53 | "popularity" : "5" 54 | }, 55 | { 56 | "color" : "green", 57 | "popularity": "4.5" 58 | }, 59 | { 60 | "color" : "red", 61 | "popularity" : "3" 62 | }, 63 | { 64 | "color" : "orange", 65 | "popularity" : "4" 66 | } 67 | ```` 68 | 69 | 3. Filter rows 70 | 71 | Setting option `Get lines from 1 to 2` would generate a document containing only the first two lines (`blue` and `green` data) 72 | 73 | 4. Filter columns 74 | 75 | Untick the column header `popularity` to insert only colors. 76 | 77 | 5. Customize properties names: 78 | 79 | Click on `popularity` in the preview and replace it by another label you want, eg `rating` 80 | 81 | ### Demo 82 | 83 | ~~A demo is available at this location: http://mango-reports.cloudant.com/mango-apps/_design/csv2couchdb/index.html 84 | **Warning**: the demo couch is read-only, so you will not have access to the whole application. We recommend replicating to your own couch to get all features (see next section).~~ 85 | 86 | ###Installation 87 | 88 | ~~Simply replicate the sample couchapp to your couchdb instance: 89 | 90 | curl -X POST http://user:pass@YOURCOUCH/_replicate -d '{"source":"http://mango-reports.cloudant.com/mango-apps/","target":"YOURDB", "doc_ids":["_design/csv2couchdb"]}' -H "Content-type: application/json"~~ 91 | 92 | Clone this repository into the right folder, and you should be good to go. 93 | 94 | After you install it, the app is available from this url: 95 | 96 | http://yourcouch/yourdb/_design/csv2couchdb/index.html 97 | 98 | 99 | ### Status 100 | 101 | csv2couchdb is a new software and certainly contains bugs. It has been tested in Firefox 5 and Google chrome 12. Large files could be inserted using Firefox, whereas their parsing caused Google Chrome tab to crash. 102 | 103 | Consider this app as an alpha software. 104 | 105 | Thanks for reporting any issue that you would find. 106 | 107 | ### Roadmap 108 | 109 | This app is not maintained anymore. Compatibility with newer versions of couchdb has not been checked. 110 | 111 | contact: either via github message, twitter ([@mango_info](http://twitter.com/mango_info)) or via contact form in http://www.mango-is.com 112 | 113 | ### License and credits 114 | 115 | Please refer to the LICENSE file located in the same folder as the current file 116 | -------------------------------------------------------------------------------- /_attachments/images/csv2Couchdb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mango-information-systems/csv2couchdb/b78bb525df8242bb8998c2d6aeb45260147bc8bf/_attachments/images/csv2Couchdb.png -------------------------------------------------------------------------------- /_attachments/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mango-information-systems/csv2couchdb/b78bb525df8242bb8998c2d6aeb45260147bc8bf/_attachments/images/favicon.png -------------------------------------------------------------------------------- /_attachments/images/html5-badge-h-performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mango-information-systems/csv2couchdb/b78bb525df8242bb8998c2d6aeb45260147bc8bf/_attachments/images/html5-badge-h-performance.png -------------------------------------------------------------------------------- /_attachments/images/localCSVs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mango-information-systems/csv2couchdb/b78bb525df8242bb8998c2d6aeb45260147bc8bf/_attachments/images/localCSVs.png -------------------------------------------------------------------------------- /_attachments/images/recline-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mango-information-systems/csv2couchdb/b78bb525df8242bb8998c2d6aeb45260147bc8bf/_attachments/images/recline-logo.png -------------------------------------------------------------------------------- /_attachments/images/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mango-information-systems/csv2couchdb/b78bb525df8242bb8998c2d6aeb45260147bc8bf/_attachments/images/spinner.gif -------------------------------------------------------------------------------- /_attachments/images/square-logo - 23 x 23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mango-information-systems/csv2couchdb/b78bb525df8242bb8998c2d6aeb45260147bc8bf/_attachments/images/square-logo - 23 x 23.png -------------------------------------------------------------------------------- /_attachments/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CSV to Couchdb 5 | 6 | 7 | 8 | 9 | 15 |
16 |
17 | 24 |
25 |
26 |
27 |

28 | Bulk loading to the couch, time to relax... 29 | loading spinner 30 |

31 |
32 |
33 |
Errors
34 |
35 | document could not be inserted. Error message: 36 | 37 |
38 |
39 |
40 |
Insertions
41 |

42 |
43 |
44 |
Updates
45 |
46 | document already exists in the database 47 | 48 |
49 |
50 |
51 |
52 |
53 | local CSV files 54 |
55 |
56 |

Upload more files

57 |

Click to select one or more CSV files

58 |
59 |
60 |
61 |
62 |
63 |

64 | couchapp to populate couchdb from CSV files. Client side processing using HTML5 file API. Uses bulk insert, with document update option. 65 |

66 |
67 | 68 | 69 |
70 |
71 |
72 | local CSV files 73 |
74 |
75 |

Local upload

76 |

Click to select one or more CSV files

77 |
78 |
79 |
80 |

How it works

81 |
    82 |
  1. Login to couchdb (optional)
  2. 83 |
  3. Select CSV files located in your computer
  4. 84 |
  5. Adjust settings (customize labels, filter lines and columns)
  6. 85 |
  7. Load into couchdb
  8. 86 |
87 |
88 |
89 |
90 | html5 logo 91 |
92 |
93 |

HTML5 file API

94 |

This application works only on browsers supporting HTML5 file API. You're good :)

95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | Column delimitor(s) 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 122 |
123 |
124 | Quote marker 125 | 126 | 127 | 128 | 129 | 130 | 131 |
132 |
133 | Other settings 134 | 135 |
136 | 137 | 138 | 139 |
140 | 141 |
142 |
143 |
144 |
Reading file...
145 |
146 |
0%
147 |
148 |
149 |
150 |
151 |

152 | Review each file settings here: 153 |

154 |
155 | 156 | 157 |
158 |
159 |
160 |
Output settings
161 |
162 | Documents settings 163 | 164 | 165 | 166 |
167 | 168 | 172 |
173 |
174 | Couchdb connection 175 | 176 | 178 |
179 | 180 | 181 |
182 |
183 |
184 | 185 | 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /_attachments/license.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CSV to Couchdb 5 | 6 | 7 | 8 | 9 |
10 |

csv2couchdb is released under the MIT License:

11 |

Copyright (c) 2011 Mango Information Systems SPRL, http://www.mango-is.com

12 |

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

13 |

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

14 |

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

15 |
16 |
17 | Source code is available on github 18 |
19 |
20 |

csv2couchdb uses the following components:

21 | 26 |
27 |
28 |

Some of the visuals of this application have been derived from the following sources:

29 | 36 |
37 | 38 | -------------------------------------------------------------------------------- /_attachments/scripts/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | csv2couchdb couchapp released under MIT License 3 | (c) Mango Information Systems SPRL - 2011-2012 4 | version 0.3 - February, 27th 2012 5 | 6 | todo: 7 | handle file not conform error (when file is not a csv) 8 | handle file load error: the given file should be excluded (ideally retry option) so that other files still can be loaded 9 | */ 10 | 11 | /* Extract data from csv files at client side then push them into couchdb 12 | Consists in 5 steps: 13 | 1) select files (HTML5 file API) 14 | 2) define settings for each file 15 | 3) set documents and couchdb settings 16 | 4) get feedback about bulk insert and select files to overwrite in case of conflict and retry in case of error 17 | 5) (if applicable) get feedback about overwrites / retries 18 | */ 19 | 20 | // fileData contains data from read files 21 | var filesData = []; 22 | 23 | // currentStepkeeps track of steps 24 | var currentStep = 1; 25 | 26 | var $db = ''; 27 | 28 | function errorHandler(evt) { 29 | // handle errors occuring when reading file 30 | switch(evt.target.error.code) { 31 | case evt.target.error.NOT_FOUND_ERR: 32 | alert('File Not Found!'); 33 | break; 34 | case evt.target.error.NOT_READABLE_ERR: 35 | console.log(evt.target.error); 36 | alert('File is not readable'); 37 | break; 38 | case evt.target.error.ABORT_ERR: 39 | break; // noop 40 | default: 41 | alert('An error occurred reading this file.'); 42 | console.log(evt.target.error); 43 | }; 44 | } 45 | 46 | function updateProgress(evt, fileIndex) { 47 | // update the file reading progress status display 48 | // evt is an ProgressEvent. 49 | progress = $('#bar'+fileIndex); 50 | 51 | if (evt.lengthComputable) { 52 | var percentLoaded = Math.round((evt.loaded / evt.total) * 100); 53 | // increase the progress bar length. 54 | if (percentLoaded < 100) { 55 | progress.find('.percent').width(percentLoaded+'%'); 56 | progress.find('.percent').text( percentLoaded+'%'); 57 | } 58 | } 59 | } 60 | 61 | function handleFileSelect(evt) { 62 | var files = evt.target.files; // FileList object 63 | 64 | // files is a FileList of File objects. List some properties. 65 | var output = []; 66 | 67 | var counter=0; 68 | 69 | for (var i = 0, f; f = files[i]; i++) { 70 | // 1. show input and processing options for each file 71 | 72 | var $fileDiv = $('#step2 .template') 73 | .clone() 74 | .removeClass('template') 75 | .attr('id','file'+i) 76 | 77 | // set ids for the elements of the div (necessary to have labels clickable) 78 | $fileDiv.find('input').each(function() { 79 | $(this).attr('id', $(this).attr('id')+i); 80 | $(this).prop('checked', false); 81 | }); 82 | $fileDiv.find('label').each(function() { 83 | $(this).attr('for', $(this).attr('for')+i); 84 | }); 85 | 86 | $fileDiv.find('.progress_bar').attr('id','bar'+i); 87 | 88 | $fileDiv 89 | .appendTo('#filesContainer') 90 | .fadeIn(); 91 | 92 | var reader = new FileReader(); 93 | // Closure to capture the file information. 94 | 95 | progress = $('#bar'+counter); 96 | 97 | // Initialize progress indicator on new file selection. 98 | progress.find('.percent').width('0%'); 99 | progress.find('.percent').text('0%'); 100 | 101 | reader.onerror = errorHandler; 102 | 103 | reader.onprogress = function(e) { 104 | // handle progress of the file read 105 | updateProgress(e,counter); 106 | } 107 | 108 | // onload event necessary so that processing starts only once the file is read 109 | reader.onload = (function(theFile) { 110 | return function(e) { 111 | // Send file data to csv processor. 112 | 113 | var $input = $('#file'+counter); 114 | 115 | // display a spinner during the file update 116 | $input.find('div.filePreview > div:nth-child(2)').html('loading... Parsing CSV data...'); 117 | 118 | // update file preview div title 119 | $input.find('div.filePreview > div:nth-child(1)').text('Preview of 5 first rows'); 120 | 121 | // add data to the global variable storing all files 122 | filesData.push({"name": theFile.name, "index":counter, "data": e.target.result}); 123 | 124 | // process the current file 125 | processCsv($input, {}); 126 | 127 | counter++; 128 | }; 129 | })(f); 130 | 131 | // Read in the image file as a data URL. 132 | reader.readAsText(f); 133 | 134 | } 135 | 136 | currentStep++; 137 | 138 | // 2. show output options 139 | //displayOutputSettings(); 140 | 141 | // 3. hide step 1 142 | $('#step1').hide(); 143 | 144 | // 4. show step 2 145 | $('#step2') 146 | .show(); 147 | 148 | } 149 | 150 | function getFileOptions ($fileDiv) { 151 | // return values of the csv file settings chosen by the user 152 | // based on the page's form 153 | // return an object with following hashes: delimitors, delim, headerCheck, quote, quoteMark, startLine, endLine, excludedColumns 154 | // delim and quote are symbols whereas delimitors and quoteMark are text values 155 | var result = {}; 156 | 157 | result.delimitors = []; 158 | $fileDiv.find('input[name="delimitor"]').each(function() { 159 | // get selected delimitors (preset delimitors) 160 | // .each used instead of for loop to save three selections of same item (item, then prop, then id) 161 | if($(this).prop('checked') && this.value !="custom") { 162 | result.delimitors.push(this.value); 163 | } 164 | }); 165 | if ($fileDiv.find('.customdelimitors').val() != "") { 166 | // get custom delimitor if exists 167 | result.delimitors.push($fileDiv.find('.customdelimitors').val()); 168 | } 169 | 170 | delim = encodeDelimitors(result.delimitors); 171 | result.delim = delim.regular.join('') + delim.custom; 172 | 173 | // get headerCheck value 174 | result.headerCheck = $fileDiv.find('input[name="header"]').prop('checked'); 175 | 176 | result.quoteMark= ""; 177 | // get quote marker 178 | $fileDiv.find('input[name="quoteMark"]').each(function() { 179 | // get selected quoteMark 180 | // .each used instead of for loop to save three selections of same item (item, then prop, then id) 181 | if($(this).prop('checked')) { 182 | result.quoteMark = this.value; 183 | } 184 | }); 185 | 186 | result.startLine = $fileDiv.find('[type="text"][name="startLine"]').val(); 187 | 188 | result.endLine = $fileDiv.find('[type="text"][name="endLine"]').val(); 189 | 190 | result.excludedColumns = []; 191 | 192 | $('span.excluded', $fileDiv).each(function() { 193 | // addding each excluded column to the list 194 | result.excludedColumns.push($(this).parent()[0].cellIndex); 195 | }); 196 | 197 | return result; 198 | } 199 | 200 | function processCsv($fileDiv, fileOpts) { 201 | // step 2: show options and preview for csv file 202 | 203 | if (!fileOpts) 204 | fileOpts = {}; 205 | // retrieving index of the file 206 | var fileIndex = $fileDiv.attr('id').substr(4,1); 207 | var file = filesData[fileIndex]; 208 | 209 | // detect column delimitor from a standard list at first run 210 | if (!fileOpts.delimitors) { 211 | fileOpts.delimitors = []; 212 | 213 | // detect delimitor 214 | fileOpts.delim = $.csvIn.detectDelimitor(file.data); 215 | // store string form of the delimitor 216 | fileOpts.delimitors.push(decodeDelimitor(fileOpts.delim)); 217 | } 218 | 219 | // initialize quote marker at first run 220 | if(!fileOpts.quoteMark) { 221 | fileOpts.quoteMark = 'doubleQuote'; 222 | fileOpts.quote= encodeQuoteMarkers(fileOpts.quoteMark); 223 | } 224 | 225 | // ignore excluded columns for the preview generation 226 | fileOpts.excludedColumns = []; 227 | 228 | // override startLine for the preview generation (header must appear) 229 | fileOpts.startLine = 0; 230 | 231 | // endLine not overriden for the preview generation because full parsing is needed to display total length 232 | // fileOpts.endLine = 6; 233 | // convert the file content into a javascript array 234 | 235 | var currentCsvArray = $.csvIn.toArray(file.data, fileOpts); 236 | 237 | // console.log($.csvIn.toJSON(file.data, fileOpts)); 238 | 239 | if(typeof fileOpts.headerCheck == 'undefined') 240 | // detect presence of header in case of first run 241 | fileOpts.headerCheck = $.csvIn.isHeader(currentCsvArray[0]); 242 | 243 | // setting file name 244 | $fileDiv.find('.divTitle').eq(0).text(file.name); 245 | 246 | for (i in fileOpts.delimitors) { 247 | // check checkbox for selected delimitors 248 | if ($.inArray(fileOpts.delimitors[i], ["space", "colon", "comma", "semicolon", "hyphen", "tab"]) !=-1) { 249 | // regular delimitor, check appropriate checkbox 250 | $fileDiv.find('#'+fileOpts.delimitors[i]+file.index).prop('checked', true); 251 | } 252 | else { 253 | // delimitor is custom one, check custom checkbox and fill value inside text input 254 | if (typeof fileOpts.delimitors[i]!='undefined' && fileOpts.delimitors[i] !="") { 255 | // check custom only if there is a defined delimitor 256 | $fileDiv.find('#custom'+file.index).prop('checked', true); 257 | $fileDiv.find('#customdelimitors'+file.index).append(fileOpts.delimitors[i]); 258 | } 259 | } 260 | } 261 | 262 | // check radio button for the selected quote marker 263 | $fileDiv.find('#'+fileOpts.quoteMark+file.index).prop('checked', true); 264 | 265 | if (fileOpts.headerCheck) 266 | // check header checkbox in case a header has been detected 267 | $fileDiv.find('[type="checkbox"][name="header"]').prop('checked',true); 268 | 269 | // initialize row filters at first run 270 | if(!fileOpts.startLine) { 271 | fileOpts.startLine = 1; 272 | if (fileOpts.headerCheck) 273 | // increment start line to skip header if applicable 274 | fileOpts.startLine++; 275 | } 276 | 277 | // initialize row filters at first run 278 | if(!fileOpts.endLine) { 279 | fileOpts.endLine = currentCsvArray.length; 280 | } 281 | 282 | $fileDiv.find('[type="text"][name="startLine"]').val(fileOpts.startLine); 283 | 284 | $fileDiv.find('[type="text"][name="endLine"]').val(fileOpts.endLine); 285 | 286 | $fileDiv.find('span.totalRows').text('Total file length: '+currentCsvArray.length+' lines'); 287 | 288 | // show file preview 289 | var result = previewCsv(currentCsvArray, fileOpts.headerCheck); 290 | $fileDiv.find('div.filePreview > div:nth-child(2)').html(result); 291 | 292 | } 293 | 294 | function previewCsv(data, headerCheck) { 295 | // show a preview of the csv file 296 | 297 | var result = ""; 298 | if(headerCheck) { 299 | result += ""; 300 | 301 | for (i in data[0]) { 302 | result += ""; 303 | } 304 | result += ""; 305 | } 306 | else { 307 | result += ""; 308 | 309 | for (i in data[0]) { 310 | result += ""; 311 | } 312 | result += ""; 313 | } 314 | 315 | // set length of the preview according to headerCheck and length of the file 316 | if (headerCheck) { 317 | var startLine = 1; 318 | var endLine = data.length>6?5:data.length-1; 319 | } 320 | else { 321 | var startLine = 0; 322 | var endLine = data.length>5?4:data.length-1; 323 | } 324 | 325 | result += ""; 326 | 327 | for (i =startLine;i<=endLine;i++) { 328 | result += ""; 329 | for (j in data[i]) { 330 | result += ""; 331 | } 332 | result += ""; 333 | } 334 | result +="
"+data[0][i]+"
Column "+ (parseInt(i)+1) +"
"+data[i][j]+"
"; 335 | 336 | return result; 337 | } 338 | 339 | function columnSelection($targetTable, columnIds) { 340 | // add or remove excluded class to the given columns 341 | 342 | for (i in columnIds) { 343 | // toggle class for all cells belonging to the column 344 | $targetTable.find('tr >td:nth-child('+columnIds[i]+')').toggleClass('excluded'); 345 | $targetTable.find('tr >th:nth-child('+columnIds[i]+') >span').toggleClass('excluded'); 346 | } 347 | 348 | } 349 | 350 | function decodeDelimitor(delim) { 351 | // return name corresponding to delimitor code 352 | // necessary because signs cannot be used in DOM element ids 353 | switch(delim) { 354 | case " ": 355 | return "space"; 356 | break; 357 | case ",": 358 | return "comma"; 359 | break; 360 | case ":": 361 | return "colon"; 362 | break; 363 | case ";": 364 | return "semicolon"; 365 | break; 366 | case "-": 367 | return "hyphen"; 368 | break; 369 | case "\t": 370 | return "tab"; 371 | break; 372 | } 373 | } 374 | 375 | function encodeDelimitors(delimitors) { 376 | // encode delimitors 377 | 378 | var result = {}; 379 | result.regular = []; 380 | result.custom = ""; 381 | 382 | for (i in delimitors) { 383 | // encode delimitors 384 | switch (delimitors[i]) { 385 | case "space": 386 | result.regular.push(" "); 387 | break; 388 | case "tab": 389 | result.regular.push("\t"); 390 | break; 391 | case "colon": 392 | result.regular.push(":"); 393 | break; 394 | case "semicolon": 395 | result.regular.push(";"); 396 | break; 397 | case "comma": 398 | result.regular.push(","); 399 | break; 400 | case "hyphen": 401 | result.regular.push("-"); 402 | break; 403 | default: 404 | if (typeof delimitors[i] != 'undefined' && delimitors[i] !="") { 405 | result.regular.push(delimitors[i]); 406 | result.custom = delimitors[i]; 407 | } 408 | break; 409 | } 410 | } 411 | return result; 412 | } 413 | 414 | function encodeQuoteMarkers(mark) { 415 | // encode quote markers 416 | switch(mark) { 417 | // encode quote marker 418 | case "doubleQuote": 419 | result = "\""; 420 | break; 421 | case "simpleQuote": 422 | result = "'"; 423 | break; 424 | case "none": 425 | result = 0; 426 | break; 427 | } 428 | return result; 429 | } 430 | 431 | function generateDocuments () { 432 | // generate JSON couchdb document 433 | // fileDiv is a jquery selector containing the files information, whereas opts are the options applicable to all files 434 | var result = []; 435 | 436 | // get output format value 437 | var outputFormat = $('input[name="outputFormat"]:checked').val(); 438 | 439 | // get ids option value 440 | var ids = $('#ids').val(); 441 | 442 | var $filesDiv = $('div.container', '#filesContainer'); 443 | 444 | $filesDiv.each(function() { 445 | //$('#step'+currentStep+' >div').each(function() { 446 | // process individual file 447 | 448 | $input = $(this); 449 | 450 | var fileIndex = $input.attr('id').substr(4,1); 451 | 452 | // retrieving file options 453 | var fileOptions = getFileOptions ($input); 454 | 455 | // update start and end lines (0-indexed) 456 | fileOptions.startLine--; 457 | fileOptions.endLine--; 458 | 459 | fileOptions.customHeaders = []; 460 | 461 | $(this).find('th > span').each(function() { 462 | // retrieve custom headers labels 463 | fileOptions.customHeaders.push($(this).text().trim()); 464 | }); 465 | 466 | // generate JSON document 467 | if (outputFormat == "byRow") { 468 | // generate one document per data row 469 | 470 | // convert the file content into a javascript array of JSON objects 471 | JSONdoc = $.csvIn.toJSON(filesData[fileIndex].data, fileOptions); 472 | 473 | if (ids == 'custom') { 474 | // process with generation of custom _id : file name and row number 475 | for (i in JSONdoc) { 476 | // go through each row, generate id and add document 477 | JSONdoc[i]._id = filesData[fileIndex].name+ (parseInt(i)+1); 478 | result.push(JSONdoc[i]); 479 | } 480 | } 481 | else { 482 | // add document without generating id 483 | for (i in JSONdoc) { 484 | // go through each row to add document 485 | result.push(JSONdoc[i]); 486 | } 487 | } 488 | 489 | } 490 | else { 491 | // generate one document per file 492 | 493 | JSONdoc = {}; 494 | 495 | // convert the file content into a javascript array 496 | JSONdoc.rows = $.csvIn.toArray(filesData[fileIndex].data, fileOptions); 497 | 498 | if (ids == 'custom') 499 | // generate custom _id : file name 500 | JSONdoc._id = filesData[fileIndex].name; 501 | 502 | JSONdoc.headers = fileOptions.customHeaders; 503 | 504 | // add array as a document 505 | result.push(JSONdoc); 506 | } 507 | }); 508 | return result; 509 | 510 | } 511 | 512 | function pushToDB(docs) { 513 | // insert documents into couchdb 514 | 515 | // get output settings 516 | var dbName = $('#dbName').val(); 517 | 518 | var bulkLoader = new Worker('scripts/bulkLoad.js'); 519 | 520 | // bulk upload using workers - logic inspired by maxodgen's recline 521 | // https://github.com/maxogden/recline/blob/master/attachments/script/costco.js#L111 522 | 523 | var url = window.location.protocol + "//" + window.location.host + "/" + dbName + "/_bulk_docs"; 524 | 525 | bulkLoader.postMessage({"docs":docs, "url":url }); 526 | 527 | bulkLoader.onmessage = function (event) { 528 | // react according to result of processing 529 | var result = event.data; 530 | 531 | result = $.parseJSON(event.data); 532 | 533 | if(result.success) { 534 | // confirm that insertion was succcessfully done 535 | 536 | $('#bulkLoadSpinner').hide(); 537 | 538 | $('#successDocs, #postProcessing').fadeIn(); 539 | 540 | $db = $.couch.db(dbName); 541 | 542 | // check presence of recline design document in the database 543 | $db.allDocs({ 544 | keys: ['_design/recline'], 545 | success: function(data) { 546 | if(!data.rows[0].error) { 547 | // insert link to recline in case recline design document exists in the target DB 548 | $('
go to recline

Continue to recline

Process the documents in recline

').insertAfter('#moreFiles'); 549 | // bind click event listener 550 | $('#recline').live('click',function() { 551 | // go to recline 552 | reclineUrl = '../../../' + $('#dbName').val() + '/_design/recline/_rewrite'; 553 | window.location.href = reclineUrl; 554 | }); 555 | 556 | 557 | } 558 | } 559 | }); 560 | 561 | var successCount = 0; 562 | for (i in result.response) { 563 | if (!result.response[i].error) { 564 | // show confirmation for successful document insert 565 | // show list of inserted files by Id 566 | successCount++; 567 | } 568 | else if (result.response[i].error == 'conflict') { 569 | // show conflict documents and provide overwrite option 570 | 571 | // display the failed documents div in case it is not already visible 572 | $('#conflictDocs').not(':visible').fadeIn(); 573 | 574 | var $conflictDoc = $('.template', '#conflictDocs') 575 | .clone() 576 | .removeClass('template') 577 | .attr('id','doc'+i) 578 | 579 | $conflictDoc.find('span') 580 | .text(result.response[i].id); 581 | 582 | $conflictDoc.find('input') 583 | .attr('fileName', docs[i]._id) 584 | .data('doc',docs[i]) 585 | .data('formId','doc'+i); 586 | 587 | $conflictDoc 588 | .appendTo('#conflictDocs') 589 | .fadeIn(); 590 | 591 | // get revision id of existing document 592 | $db.allDocs({ 593 | keys: [result.response[i].id], 594 | context: $conflictDoc.find('input'), 595 | success: function(data) { 596 | this.context 597 | .data('rev',data.rows[0].value.rev); 598 | }, 599 | error: function(jqXHR, textStatus, errorThrown) { 600 | // throw appropriate error message 601 | console.log(jqXHR); 602 | console.log(textStatus); 603 | console.log(errorThrown); 604 | } 605 | }); 606 | } 607 | else { 608 | // show failed document inserts and provide retry option 609 | 610 | // display the failed documents div in case it is not already visible 611 | $('#failDocs').not(':visible').fadeIn(); 612 | 613 | var $failDoc = $('.template', '#failDocs') 614 | .clone() 615 | .removeClass('template') 616 | .attr('id','doc'+i) 617 | 618 | $failDoc.find('span').eq(1) 619 | .text(result.response[i].id); 620 | 621 | $failDoc.find('span').eq(2) 622 | .text(result.response[i].error + ': ' + result.response[i].reason); 623 | 624 | $failDoc.find('input') 625 | .attr('fileName', docs[i]._id) 626 | .data('doc',docs[i]) 627 | .data('formId','doc'+i); 628 | 629 | $failDoc 630 | .appendTo('#failDocs') 631 | .fadeIn(); 632 | 633 | // get revision id of existing document 634 | $db.allDocs({ 635 | keys: [result.response[i].id], 636 | context: $failDoc.find('input'), 637 | success: function(data) { 638 | this.context 639 | .data('rev',data.rows[0].value.rev); 640 | }, 641 | error: function(jqXHR, textStatus, errorThrown) { 642 | // throw appropriate error message 643 | console.log(jqXHR); 644 | console.log(textStatus); 645 | console.log(errorThrown); 646 | } 647 | }); 648 | } 649 | } 650 | if (successCount > 1) 651 | $('#successDocs').find('p').html(successCount + ' new documents were successfully inserted
'); 652 | else if (successCount == 1) 653 | $('#successDocs').find('p').html('1 new document was successfully inserted'); 654 | else 655 | // successCount == 0 656 | $('#successDocs').find('p').html('No new document was inserted'); 657 | 658 | } 659 | else { 660 | // throw appropriate error message 661 | $('#step4').html(result.response.textStatus + ' ' + result.response.errorThrown); 662 | console.log(result.response.jqXHR); 663 | console.log(result.response.textStatus); 664 | console.log(result.response.errorThrown); 665 | } 666 | } 667 | } 668 | 669 | $(document).ready(function() { 670 | 671 | // Check whether user is already connected 672 | $.couch.session({ 673 | success: function(data) { 674 | if (data.userCtx.name != null) 675 | // show logged in user name and logout button 676 | $('#session').html('logged in as '+data.userCtx.name+ ' '); 677 | else 678 | // show logon form 679 | $('#session').html('
'); 680 | 681 | }, 682 | error: function(data) { 683 | // show logon form 684 | $('#session').html('
'); 685 | } 686 | }); 687 | 688 | // Check for the various File API support. 689 | if (window.File && window.FileReader && window.FileList && window.Blob) { 690 | // Great success! All the File APIs are supported. 691 | } 692 | else { 693 | $('#techDisclaimer').css('border','3px solid red'); 694 | $('#html5Status').html('The HTML5 File APIs are not fully supported in this browser. Please try another browser (Firefox, Google Chrome, Opera)'); 695 | } 696 | 697 | // todo: check whether this UI is suitable (jqueryUI buttons) 698 | // $( ".fileSettings > fieldset" ).eq(0).buttonset(); 699 | 700 | 701 | // trigger proper function at file selection 702 | // document.getElementById('files').addEventListener('change', handleFileSelect, false); 703 | $('#files').live('change', function(evt) { 704 | handleFileSelect(evt); 705 | }); 706 | 707 | $('[type="submit"][name="next"]').live('click', function(e) { 708 | // go to next step 709 | // console.log($('#step'+currentStep+' >div')) 710 | e.preventDefault(); 711 | 712 | // 1. hide current step 713 | $('#step'+currentStep) 714 | .hide() 715 | 716 | // 2. increment step 717 | currentStep++; 718 | 719 | // 3. show next step 720 | $('#step'+currentStep) 721 | .fadeIn() 722 | 723 | // 4. perform specific processing if applicable 724 | if (currentStep == 3) { 725 | // step 3, load databases list inside select 726 | $.couch.allDbs({ 727 | success: function(data) { 728 | $dbsSelect = $('#dbName'); 729 | $dbsSelect.empty(); 730 | data.sort(); 731 | for (i in data) { 732 | if (data[i][0] !='_') { 733 | $dbsSelect 734 | .append($("") 735 | .attr("value",data[i]) 736 | .text(data[i])); 737 | } 738 | } 739 | }, 740 | error: function(jqXHR, textStatus, errorThrown) { 741 | // replace dbs list with text input in case the database list is not accessible to the loged-in user 742 | $('#dbName').replaceWith(''); 743 | } 744 | }); 745 | } 746 | else if (currentStep == 4) { 747 | // step 4, load documents into couchdb 748 | // 4.2 generate couchdb documents 749 | var docs = generateDocuments (); 750 | // temporary preview of the documents: 751 | /* var myText = '
'+JSON.stringify(docs, null, '\t')+'
'; 752 | $('#step'+currentStep) 753 | .html(myText) 754 | */ 755 | // 4.3 push documents to couchdb 756 | pushToDB(docs); 757 | } 758 | 759 | }); 760 | 761 | $('[type="submit"][name="back"]').live('click', function(e) { 762 | // go to previous step 763 | 764 | e.preventDefault(); 765 | 766 | // 1. hide current step 767 | $('#step'+currentStep) 768 | .hide() 769 | 770 | // 2. reset appropriate elements 771 | if (currentStep == 2) { 772 | $('#step'+currentStep).find('div.container').not('div.template').remove(); 773 | filesData = []; 774 | $('#files').replaceWith(''); 775 | } 776 | 777 | // 3. decrement step 778 | currentStep--; 779 | 780 | // 4. show previous step 781 | $('#step'+currentStep) 782 | .show(); 783 | }); 784 | 785 | $('[type="checkbox"][name="columnSelector"]').live('click', function() { 786 | // toggle selected column display 787 | var $input = $(this); 788 | var fileIndex = $input.parents().filter('div')[2].id.substr(4,1); 789 | var columnIndex = $input.parent()[0].cellIndex+1; 790 | 791 | columnSelection($input.parents('table'), [columnIndex]); 792 | 793 | }); 794 | 795 | $('[type="checkbox"][name="delimitor"], [type="checkbox"][name="header"], [type="radio"][name="quoteMark"]').live('click', function() { 796 | // re-process the file when user clicks on a delimitor checkbox 797 | 798 | // cache file div selector 799 | var $input = $(this).parents().filter('div').eq(1); 800 | 801 | // store file index 802 | var fileIndex = $input.attr('id').substr(4,1); 803 | 804 | if (this.value=="custom" && $(this).prop("checked") == false) { 805 | // empty custom delimitor text input in case user unticks custom checkbox 806 | $input.find('.customdelimitors').val(""); 807 | } 808 | 809 | if (this.name=="header") { 810 | if ($(this).prop("checked") == false && $input.find('[name="startLine"]').val() == 2) 811 | // set start row to 1 in case user unticks header box and first row is 2 812 | $input.find('[name="startLine"]').val(1); 813 | else if ($(this).prop("checked") == true && $input.find('[name="startLine"]').val() == 1) 814 | // set start row to 2 in case user ticks header box and first row is 1 815 | $input.find('[name="startLine"]').val(2); 816 | } 817 | 818 | //retrieve selected options for the file 819 | var opts = getFileOptions($input); 820 | 821 | // refresh file display 822 | processCsv($input, opts); 823 | 824 | }); 825 | 826 | $('.customdelimitors').live('blur',function() { 827 | // check/uncheck custom box and trigger preview refresh when custom delimitor has been typed 828 | 829 | // cache file div selector 830 | var $input = $(this).parents().filter('div').eq(1); 831 | 832 | var opts = getFileOptions($input); 833 | 834 | // store file index 835 | // var fileIndex = $input.attr('id').substr(4,1); 836 | 837 | processCsv($input, opts); 838 | 839 | $(this).parent().find('input[value="custom"]') 840 | .prop("checked",this.value==""?false:true); 841 | }); 842 | 843 | $('[type="radio"][name="outputFormat"]').live('change', function() { 844 | // update custom id generation value when user changes the output format option 845 | if (this.value == "byRow") { 846 | // custom id for one document by row 847 | $(this).parent().find('#ids option[value="custom"]').html('file name and row number'); 848 | } 849 | else { 850 | // custom id for one document by file 851 | $(this).parent().find('#ids option[value="custom"]').html('file name'); 852 | } 853 | }); 854 | 855 | $('[type="submit"][name="logIn"]').live('click', function(e) { 856 | // sign user in 857 | e.preventDefault(); 858 | 859 | var username = $('input[name="username"]', '#session').val(); 860 | var password = $('input[name="password"]', '#session').val(); 861 | 862 | // login the user 863 | $.couch.login({ 864 | 'name': username, 865 | 'password': password, 866 | success: function(data) { 867 | /* 868 | // replace login form by user name 869 | $('#session').html('logged in as '+data.name+ ' '); 870 | */ 871 | // workaround to avoid some bug in couchdb1.0.2: username is not always returned in the callback function. 872 | $.couch.session({ 873 | success: function(data) { 874 | if (data.userCtx.name != null) 875 | // replace login form by user name 876 | $('#session').html('logged in as '+data.userCtx.name+ ' '); 877 | } 878 | }); 879 | } 880 | }); 881 | 882 | }); 883 | 884 | $('[type="submit"][name="logOut"]').live('click', function(e) { 885 | // sign user in 886 | e.preventDefault(); 887 | 888 | // log the user out 889 | $.couch.logout(); 890 | 891 | // restore login form 892 | $('#session').html('
'); 893 | }); 894 | 895 | $('[type="submit"][name="overwrite"]').live('click', function(e) { 896 | // overwrite selected document 897 | e.preventDefault(); 898 | 899 | // cache the overwrite button selector 900 | $input = $(this); 901 | 902 | // disable overwrite button 903 | $input.prop('disabled',true); 904 | 905 | // display a spinner during the file update 906 | $('loading...').insertAfter($input); 907 | 908 | doc = $input.data('doc'); 909 | doc._rev = $input.data('rev'); 910 | formId = $input.data('formId'); 911 | 912 | $db.saveDoc( 913 | doc,{ 914 | success: function(data) { 915 | // confirm that insertion was succcessfully done 916 | $('#'+formId).replaceWith('

document ' + doc._id +' was successfully updated

'); 917 | }, 918 | error: function(jqXHR, textStatus, errorThrown) { 919 | // throw appropriate error message 920 | // console.log(jqXHR, textStatus, errorThrown) 921 | $('#'+formId).replaceWith('

Error updating document ' + doc._id +': '+jqXHR + ' ' + textStatus + ' - '+ errorThrown +'

'); 922 | } 923 | }); 924 | 925 | }); 926 | 927 | $('[type="submit"][name="retry"]').live('click', function(e) { 928 | // retry document insertion 929 | e.preventDefault(); 930 | 931 | doc = $(this).data('doc'); 932 | doc._rev = $(this).data('rev'); 933 | formId = $(this).data('formId'); 934 | 935 | $db.saveDoc( 936 | doc,{ 937 | success: function(data) { 938 | // confirm that insertion was succcessfully done 939 | $('#'+formId).replaceWith('

document ' + doc._id +' was successfully inserted

'); 940 | }, 941 | error: function(jqXHR, textStatus, errorThrown) { 942 | // throw appropriate error message 943 | console.log(jqXHR, textStatus, errorThrown) 944 | $('#'+formId).replaceWith('

Error inserting document ' + doc._id +': '+jqXHR + ' ' + textStatus + ' - '+ errorThrown +'

'); 945 | } 946 | }); 947 | 948 | }); 949 | 950 | $('#localFiles').click(function() { 951 | // trigger local files selection 952 | $('#files')[0].click(); 953 | }); 954 | 955 | $('#moreFiles').click(function() { 956 | // reset data and trigger local files selection 957 | // reset currentStep variable 958 | currentStep = 1; 959 | 960 | // reset data related to previous processing 961 | $('#step4').hide(); 962 | $('#step1').show(); 963 | $('#step2').find('div.container').not('.template').remove(); 964 | $('#conflictDocs, #failDocs').find('form').not('.template').remove(); 965 | $('#conflictDocs, #failDocs').find('p').remove(); 966 | filesData = []; 967 | $('#files').replaceWith(''); 968 | $('#bulkLoadSpinner').show(); 969 | $('#successDocs, #conflictDocs, #postProcessing').hide(); 970 | 971 | // trigger file selection 972 | $('#files')[0].click(); 973 | }); 974 | 975 | $('.editable') 976 | .live('click', function() { 977 | // start inline editing 978 | var $editable = $(this); 979 | if ($editable.hasClass('active-inline')) { 980 | return; 981 | } 982 | var contents = $.trim($editable.html()); 983 | $editable 984 | .addClass("active-inline") 985 | .empty(); 986 | 987 | $('') 988 | .val(contents) 989 | .appendTo($editable) 990 | .focus() 991 | .blur(function(e) { 992 | $editable.trigger('blur'); 993 | }); 994 | }) 995 | .live('blur', function() { 996 | // end inline editing 997 | var $editable = $(this); 998 | var contents = $editable.find(':first-child:input').val(); 999 | $editable 1000 | .removeClass('active-inline') 1001 | .contents() 1002 | .replaceWith(contents); 1003 | }); 1004 | }); 1005 | -------------------------------------------------------------------------------- /_attachments/scripts/bulkLoad.js: -------------------------------------------------------------------------------- 1 | onmessage = function(event) { 2 | 3 | var url = event.data.url; 4 | var docs = event.data.docs; 5 | 6 | var req = new XMLHttpRequest(); 7 | req.onreadystatechange = function() { 8 | if (req.readyState == 4) { 9 | result = {}; 10 | result.response=JSON.parse(req.responseText); 11 | if(req.status == 201) { 12 | result.success = true; 13 | postMessage(JSON.stringify(result)); 14 | } 15 | else { 16 | postMessage(JSON.stringify(result)); 17 | } 18 | close(); 19 | } 20 | }; 21 | req.open('POST', url); 22 | req.setRequestHeader('Content-Type', 'application/json'); 23 | req.send(JSON.stringify({docs: docs})); 24 | 25 | 26 | } -------------------------------------------------------------------------------- /_attachments/scripts/jquery-1.6.1.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery JavaScript Library v1.6.1 3 | * http://jquery.com/ 4 | * 5 | * Copyright 2011, John Resig 6 | * Dual licensed under the MIT or GPL Version 2 licenses. 7 | * http://jquery.org/license 8 | * 9 | * Includes Sizzle.js 10 | * http://sizzlejs.com/ 11 | * Copyright 2011, The Dojo Foundation 12 | * Released under the MIT, BSD, and GPL Licenses. 13 | * 14 | * Date: Thu May 12 15:04:36 2011 -0400 15 | */ 16 | (function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!cj[a]){var b=f("<"+a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),c.body.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write("");b=cl.createElement(a),cl.body.appendChild(b),d=f.css(b,"display"),c.body.removeChild(ck)}cj[a]=d}return cj[a]}function cu(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function ct(){cq=b}function cs(){setTimeout(ct,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g=0===c})}function W(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function O(a,b){return(a&&a!=="*"?a+".":"")+b.replace(A,"`").replace(B,"&")}function N(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function L(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function F(){return!0}function E(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function H(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(H,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=d.userAgent,x,y,z,A=Object.prototype.toString,B=Object.prototype.hasOwnProperty,C=Array.prototype.push,D=Array.prototype.slice,E=String.prototype.trim,F=Array.prototype.indexOf,G={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.1",length:0,size:function(){return this.length},toArray:function(){return D.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?C.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),y.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(D.apply(this,arguments),"slice",D.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:C,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;y.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!y){y=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",z,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",z),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&H()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):G[A.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!B.call(a,"constructor")&&!B.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||B.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};f=c.createElement("select"),g=f.appendChild(c.createElement("option")),h=a.getElementsByTagName("input")[0],j={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},h.checked=!0,j.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,j.optDisabled=!g.disabled;try{delete a.test}catch(s){j.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function b(){j.noCloneEvent=!1,a.detachEvent("onclick",b)}),a.cloneNode(!0).fireEvent("onclick")),h=c.createElement("input"),h.value="t",h.setAttribute("type","radio"),j.radioValue=h.value==="t",h.setAttribute("checked","checked"),a.appendChild(h),k=c.createDocumentFragment(),k.appendChild(a.firstChild),j.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",l=c.createElement("body"),m={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"};for(q in m)l.style[q]=m[q];l.appendChild(a),b.insertBefore(l,b.firstChild),j.appendChecked=h.checked,j.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,j.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",j.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
",n=a.getElementsByTagName("td"),r=n[0].offsetHeight===0,n[0].style.display="",n[1].style.display="none",j.reliableHiddenOffsets=r&&n[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(i=c.createElement("div"),i.style.width="0",i.style.marginRight="0",a.appendChild(i),j.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(i,null)||{marginRight:0}).marginRight,10)||0)===0),l.innerHTML="",b.removeChild(l);if(a.attachEvent)for(q in{submit:1,change:1,focusin:1})p="on"+q,r=p in a,r||(a.setAttribute(p,"return;"),r=typeof a[p]=="function"),j[q+"Bubbles"]=r;return j}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[f.camelCase(c)]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[f.camelCase(c)]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;return(e.value||"").replace(p,"")}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);c=j&&f.attrFix[c]||c,i=f.attrHooks[c],i||(!t.test(c)||typeof d!="boolean"&&d!==b&&d.toLowerCase()!==c.toLowerCase()?v&&(f.nodeName(a,"form")||u.test(c))&&(i=v):i=w);if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j)return i.get(a,c);h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);c=i&&f.propFix[c]||c,h=f.propHooks[c];return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),w={get:function(a,c){return a[f.propFix[c]||c]?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=b),a.setAttribute(c,c.toLowerCase()));return c}},f.attrHooks.value={get:function(a,b){if(v&&f.nodeName(a,"button"))return v.get(a,b);return a.value},set:function(a,b,c){if(v&&f.nodeName(a,"button"))return v.set(a,b,c);a.value=b}},f.support.getSetAttribute||(f.attrFix=f.propFix,v=f.attrHooks.name=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var x=Object.prototype.hasOwnProperty,y=/\.(.*)$/,z=/^(?:textarea|input|select)$/i,A=/\./g,B=/ /g,C=/[^\w\s.|`]/g,D=function(a){return a.replace(C,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=E;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=E);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),D).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem 17 | )});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},K=function(c){var d=c.target,e,g;if(!!z.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=J(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:K,beforedeactivate:K,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&K.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&K.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",J(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in I)f.event.add(this,c+".specialChange",I[c]);return z.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return z.test(this.nodeName)}},I=f.event.special.change.filters,I.focus=I.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(h=g;h0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=U.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(W(c[0])||W(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=T.call(arguments);P.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!V[a]?f.unique(e):e,(this.length>1||R.test(d))&&Q.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var Y=/ jQuery\d+="(?:\d+|null)"/g,Z=/^\s+/,$=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,_=/<([\w:]+)/,ba=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Y,""):null;if(typeof a=="string"&&!bc.test(a)&&(f.support.leadingWhitespace||!Z.test(a))&&!bg[(_.exec(a)||["",""])[1].toLowerCase()]){a=a.replace($,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bj(a,d),e=bk(a),g=bk(d);for(h=0;e[h];++h)bj(e[h],g[h])}if(b){bi(a,d);if(c){e=bk(a),g=bk(d);for(h=0;e[h];++h)bi(e[h],g[h])}}return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument|| 18 | b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!bb.test(k))k=b.createTextNode(k);else{k=k.replace($,"<$1>");var l=(_.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=ba.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&Z.test(k)&&o.insertBefore(b.createTextNode(Z.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bp.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bo.test(g)?g.replace(bo,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,c){var d,e,g;c=c.replace(br,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bs.test(d)&&bt.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bE=/%20/g,bF=/\[\]$/,bG=/\r?\n/g,bH=/#.*$/,bI=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bJ=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bK=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bL=/^(?:GET|HEAD)$/,bM=/^\/\//,bN=/\?/,bO=/)<[^<]*)*<\/script>/gi,bP=/^(?:select|textarea)/i,bQ=/\s+/,bR=/([?&])_=[^&]*/,bS=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bT=f.fn.load,bU={},bV={},bW,bX;try{bW=e.href}catch(bY){bW=c.createElement("a"),bW.href="",bW=bW.href}bX=bS.exec(bW.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bT)return bT.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bO,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bP.test(this.nodeName)||bJ.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bG,"\r\n")}}):{name:b.name,value:c.replace(bG,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bW,isLocal:bK.test(bX[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bZ(bU),ajaxTransport:bZ(bV),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?ca(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=cb(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bI.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bH,"").replace(bM,bX[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bQ),d.crossDomain==null&&(r=bS.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bX[1]&&r[2]==bX[2]&&(r[3]||(r[1]==="http:"?80:443))==(bX[3]||(bX[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bU,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bL.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bN.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bR,"$1_="+x);d.url=y+(y===d.url?(bN.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bV,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bE,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq,cr=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b
";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){return this[0]?parseFloat(f.css(this[0],d,"padding")):null},f.fn["outer"+c]=function(a){return this[0]?parseFloat(f.css(this[0],d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); -------------------------------------------------------------------------------- /_attachments/scripts/jquery.couch.app.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | // use this file except in compliance with the License. You may obtain a copy 3 | // of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | // Usage: The passed in function is called when the page is ready. 14 | // CouchApp passes in the app object, which takes care of linking to 15 | // the proper database, and provides access to the CouchApp helpers. 16 | // $.couch.app(function(app) { 17 | // app.db.view(...) 18 | // ... 19 | // }); 20 | 21 | (function($) { 22 | 23 | function Design(db, name, code) { 24 | this.doc_id = "_design/"+name; 25 | if (code) { 26 | this.code_path = this.doc_id + "/" + code; 27 | } else { 28 | this.code_path = this.doc_id; 29 | } 30 | this.view = function(view, opts) { 31 | db.view(name+'/'+view, opts); 32 | }; 33 | this.list = function(list, view, opts) { 34 | db.list(name+'/'+list, view, opts); 35 | }; 36 | } 37 | 38 | function docForm() { alert("docForm has been moved to vendor/couchapp/lib/docForm.js, use app.require to load") }; 39 | 40 | function resolveModule(path, names, parents, current) { 41 | parents = parents || []; 42 | if (names.length === 0) { 43 | if (typeof current != "string") { 44 | throw ["error","invalid_require_path", 45 | 'Must require a JavaScript string, not: '+(typeof current)]; 46 | } 47 | return [current, parents]; 48 | } 49 | var n = names.shift(); 50 | if (n == '..') { 51 | parents.pop(); 52 | var pp = parents.pop(); 53 | if (!pp) { 54 | throw ["error", "invalid_require_path", path]; 55 | } 56 | return resolveModule(path, names, parents, pp); 57 | } else if (n == '.') { 58 | var p = parents.pop(); 59 | if (!p) { 60 | throw ["error", "invalid_require_path", path]; 61 | } 62 | return resolveModule(path, names, parents, p); 63 | } else { 64 | parents = []; 65 | } 66 | if (!current[n]) { 67 | throw ["error", "invalid_require_path", path]; 68 | } 69 | parents.push(current); 70 | return resolveModule(path, names, parents, current[n]); 71 | } 72 | 73 | function makeRequire(ddoc) { 74 | var moduleCache = []; 75 | function getCachedModule(name, parents) { 76 | var key, i, len = moduleCache.length; 77 | for (i=0;i>> 0; 202 | if (typeof fun != "function") 203 | throw new TypeError(); 204 | 205 | var thisp = arguments[1]; 206 | for (var i = 0; i < len; i++) 207 | { 208 | if (i in this) 209 | fun.call(thisp, this[i], i, this); 210 | } 211 | }; 212 | } 213 | 214 | if (!Array.prototype.indexOf) 215 | { 216 | Array.prototype.indexOf = function(elt) 217 | { 218 | var len = this.length >>> 0; 219 | 220 | var from = Number(arguments[1]) || 0; 221 | from = (from < 0) 222 | ? Math.ceil(from) 223 | : Math.floor(from); 224 | if (from < 0) 225 | from += len; 226 | 227 | for (; from < len; from++) 228 | { 229 | if (from in this && 230 | this[from] === elt) 231 | return from; 232 | } 233 | return -1; 234 | }; 235 | } 236 | -------------------------------------------------------------------------------- /_attachments/scripts/jquery.couch.app.util.js: -------------------------------------------------------------------------------- 1 | $.log = function(m) { 2 | if (window && window.console && window.console.log) { 3 | window.console.log(arguments.length == 1 ? m : arguments); 4 | } 5 | }; 6 | 7 | // http://stackoverflow.com/questions/1184624/serialize-form-to-json-with-jquery/1186309#1186309 8 | $.fn.serializeObject = function() { 9 | var o = {}; 10 | var a = this.serializeArray(); 11 | $.each(a, function() { 12 | if (o[this.name]) { 13 | if (!o[this.name].push) { 14 | o[this.name] = [o[this.name]]; 15 | } 16 | o[this.name].push(this.value || ''); 17 | } else { 18 | o[this.name] = this.value || ''; 19 | } 20 | }); 21 | return o; 22 | }; 23 | 24 | // todo remove this crap 25 | function escapeHTML(st) { 26 | return( 27 | st && st.replace(/&/g,'&'). 28 | replace(/>/g,'>'). 29 | replace(/'+a+''; 42 | }).replace(/\@([\w\-]+)/g,function(user,name) { 43 | return ''+user+''; 44 | }).replace(/\#([\w\-\.]+)/g,function(word,tag) { 45 | return ''+word+''; 46 | }); 47 | }; 48 | 49 | $.fn.prettyDate = function() { 50 | $(this).each(function() { 51 | var string, title = $(this).attr("title"); 52 | if (title) { 53 | string = $.prettyDate(title); 54 | } else { 55 | string = $.prettyDate($(this).text()); 56 | } 57 | $(this).text(string); 58 | }); 59 | }; 60 | 61 | $.prettyDate = function(time){ 62 | 63 | var date = new Date(time.replace(/-/g,"/").replace("T", " ").replace("Z", " +0000").replace(/(\d*\:\d*:\d*)\.\d*/g,"$1")), 64 | diff = (((new Date()).getTime() - date.getTime()) / 1000), 65 | day_diff = Math.floor(diff / 86400); 66 | 67 | if (isNaN(day_diff)) return time; 68 | 69 | return day_diff < 1 && ( 70 | diff < 60 && "just now" || 71 | diff < 120 && "1 minute ago" || 72 | diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" || 73 | diff < 7200 && "1 hour ago" || 74 | diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") || 75 | day_diff == 1 && "yesterday" || 76 | day_diff < 21 && day_diff + " days ago" || 77 | day_diff < 45 && Math.ceil( day_diff / 7 ) + " weeks ago" || 78 | time; 79 | // day_diff < 730 && Math.ceil( day_diff / 31 ) + " months ago" || 80 | // Math.ceil( day_diff / 365 ) + " years ago"; 81 | }; 82 | 83 | $.argsToArray = function(args) { 84 | if (!args.callee) return args; 85 | var array = []; 86 | for (var i=0; i < args.length; i++) { 87 | array.push(args[i]); 88 | }; 89 | return array; 90 | } 91 | -------------------------------------------------------------------------------- /_attachments/scripts/jquery.couch.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | // use this file except in compliance with the License. You may obtain a copy of 3 | // the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | (function($) { 14 | $.couch = $.couch || {}; 15 | 16 | function encodeDocId(docID) { 17 | var parts = docID.split("/"); 18 | if (parts[0] == "_design") { 19 | parts.shift(); 20 | return "_design/" + encodeURIComponent(parts.join('/')); 21 | } 22 | return encodeURIComponent(docID); 23 | }; 24 | 25 | function prepareUserDoc(user_doc, new_password) { 26 | if (typeof hex_sha1 == "undefined") { 27 | alert("creating a user doc requires sha1.js to be loaded in the page"); 28 | return; 29 | } 30 | var user_prefix = "org.couchdb.user:"; 31 | user_doc._id = user_doc._id || user_prefix + user_doc.name; 32 | if (new_password) { 33 | // handle the password crypto 34 | user_doc.salt = $.couch.newUUID(); 35 | user_doc.password_sha = hex_sha1(new_password + user_doc.salt); 36 | } 37 | user_doc.type = "user"; 38 | if (!user_doc.roles) { 39 | user_doc.roles = []; 40 | } 41 | return user_doc; 42 | }; 43 | 44 | var uuidCache = []; 45 | 46 | $.extend($.couch, { 47 | urlPrefix: '', 48 | activeTasks: function(options) { 49 | ajax( 50 | {url: this.urlPrefix + "/_active_tasks"}, 51 | options, 52 | "Active task status could not be retrieved" 53 | ); 54 | }, 55 | 56 | allDbs: function(options) { 57 | ajax( 58 | {url: this.urlPrefix + "/_all_dbs"}, 59 | options, 60 | "An error occurred retrieving the list of all databases" 61 | ); 62 | }, 63 | 64 | config: function(options, section, option, value) { 65 | var req = {url: this.urlPrefix + "/_config/"}; 66 | if (section) { 67 | req.url += encodeURIComponent(section) + "/"; 68 | if (option) { 69 | req.url += encodeURIComponent(option); 70 | } 71 | } 72 | if (value === null) { 73 | req.type = "DELETE"; 74 | } else if (value !== undefined) { 75 | req.type = "PUT"; 76 | req.data = toJSON(value); 77 | req.contentType = "application/json"; 78 | req.processData = false; 79 | } 80 | 81 | ajax(req, options, 82 | "An error occurred retrieving/updating the server configuration" 83 | ); 84 | }, 85 | 86 | session: function(options) { 87 | options = options || {}; 88 | $.ajax({ 89 | type: "GET", url: this.urlPrefix + "/_session", 90 | complete: function(req) { 91 | var resp = httpData(req, "json"); 92 | if (req.status == 200) { 93 | if (options.success) options.success(resp); 94 | } else if (options.error) { 95 | options.error(req.status, resp.error, resp.reason); 96 | } else { 97 | alert("An error occurred getting session info: " + resp.reason); 98 | } 99 | } 100 | }); 101 | }, 102 | 103 | userDb : function(callback) { 104 | $.couch.session({ 105 | success : function(resp) { 106 | var userDb = $.couch.db(resp.info.authentication_db); 107 | callback(userDb); 108 | } 109 | }); 110 | }, 111 | 112 | signup: function(user_doc, password, options) { 113 | options = options || {}; 114 | // prepare user doc based on name and password 115 | user_doc = prepareUserDoc(user_doc, password); 116 | $.couch.userDb(function(db) { 117 | db.saveDoc(user_doc, options); 118 | }); 119 | }, 120 | 121 | login: function(options) { 122 | options = options || {}; 123 | $.ajax({ 124 | type: "POST", url: this.urlPrefix + "/_session", dataType: "json", 125 | data: {name: options.name, password: options.password}, 126 | complete: function(req) { 127 | var resp = httpData(req, "json"); 128 | if (req.status == 200) { 129 | if (options.success) options.success(resp); 130 | } else if (options.error) { 131 | options.error(req.status, resp.error, resp.reason); 132 | } else { 133 | alert("An error occurred logging in: " + resp.reason); 134 | } 135 | } 136 | }); 137 | }, 138 | logout: function(options) { 139 | options = options || {}; 140 | $.ajax({ 141 | type: "DELETE", url: this.urlPrefix + "/_session", dataType: "json", 142 | username : "_", password : "_", 143 | complete: function(req) { 144 | var resp = httpData(req, "json"); 145 | if (req.status == 200) { 146 | if (options.success) options.success(resp); 147 | } else if (options.error) { 148 | options.error(req.status, resp.error, resp.reason); 149 | } else { 150 | alert("An error occurred logging out: " + resp.reason); 151 | } 152 | } 153 | }); 154 | }, 155 | 156 | db: function(name, db_opts) { 157 | db_opts = db_opts || {}; 158 | var rawDocs = {}; 159 | function maybeApplyVersion(doc) { 160 | if (doc._id && doc._rev && rawDocs[doc._id] && rawDocs[doc._id].rev == doc._rev) { 161 | // todo: can we use commonjs require here? 162 | if (typeof Base64 == "undefined") { 163 | alert("please include /_utils/script/base64.js in the page for base64 support"); 164 | return false; 165 | } else { 166 | doc._attachments = doc._attachments || {}; 167 | doc._attachments["rev-"+doc._rev.split("-")[0]] = { 168 | content_type :"application/json", 169 | data : Base64.encode(rawDocs[doc._id].raw) 170 | }; 171 | return true; 172 | } 173 | } 174 | }; 175 | return { 176 | name: name, 177 | uri: this.urlPrefix + "/" + encodeURIComponent(name) + "/", 178 | 179 | compact: function(options) { 180 | $.extend(options, {successStatus: 202}); 181 | ajax({ 182 | type: "POST", url: this.uri + "_compact", 183 | data: "", processData: false 184 | }, 185 | options, 186 | "The database could not be compacted" 187 | ); 188 | }, 189 | viewCleanup: function(options) { 190 | $.extend(options, {successStatus: 202}); 191 | ajax({ 192 | type: "POST", url: this.uri + "_view_cleanup", 193 | data: "", processData: false 194 | }, 195 | options, 196 | "The views could not be cleaned up" 197 | ); 198 | }, 199 | compactView: function(groupname, options) { 200 | $.extend(options, {successStatus: 202}); 201 | ajax({ 202 | type: "POST", url: this.uri + "_compact/" + groupname, 203 | data: "", processData: false 204 | }, 205 | options, 206 | "The view could not be compacted" 207 | ); 208 | }, 209 | create: function(options) { 210 | $.extend(options, {successStatus: 201}); 211 | ajax({ 212 | type: "PUT", url: this.uri, contentType: "application/json", 213 | data: "", processData: false 214 | }, 215 | options, 216 | "The database could not be created" 217 | ); 218 | }, 219 | drop: function(options) { 220 | ajax( 221 | {type: "DELETE", url: this.uri}, 222 | options, 223 | "The database could not be deleted" 224 | ); 225 | }, 226 | info: function(options) { 227 | ajax( 228 | {url: this.uri}, 229 | options, 230 | "Database information could not be retrieved" 231 | ); 232 | }, 233 | changes: function(since, options) { 234 | options = options || {}; 235 | // set up the promise object within a closure for this handler 236 | var timeout = 100, db = this, active = true, 237 | listeners = [], 238 | promise = { 239 | onChange : function(fun) { 240 | listeners.push(fun); 241 | }, 242 | stop : function() { 243 | active = false; 244 | } 245 | }; 246 | // call each listener when there is a change 247 | function triggerListeners(resp) { 248 | $.each(listeners, function() { 249 | this(resp); 250 | }); 251 | }; 252 | // when there is a change, call any listeners, then check for another change 253 | options.success = function(resp) { 254 | timeout = 100; 255 | if (active) { 256 | since = resp.last_seq; 257 | triggerListeners(resp); 258 | getChangesSince(); 259 | }; 260 | }; 261 | options.error = function() { 262 | if (active) { 263 | setTimeout(getChangesSince, timeout); 264 | timeout = timeout * 2; 265 | } 266 | }; 267 | // actually make the changes request 268 | function getChangesSince() { 269 | var opts = $.extend({heartbeat : 10 * 1000}, options, { 270 | feed : "longpoll", 271 | since : since 272 | }); 273 | ajax( 274 | {url: db.uri + "_changes"+encodeOptions(opts)}, 275 | options, 276 | "Error connecting to "+db.uri+"/_changes." 277 | ); 278 | } 279 | // start the first request 280 | if (since) { 281 | getChangesSince(); 282 | } else { 283 | db.info({ 284 | success : function(info) { 285 | since = info.update_seq; 286 | getChangesSince(); 287 | } 288 | }); 289 | } 290 | return promise; 291 | }, 292 | allDocs: function(options) { 293 | var type = "GET"; 294 | var data = null; 295 | if (options["keys"]) { 296 | type = "POST"; 297 | var keys = options["keys"]; 298 | delete options["keys"]; 299 | data = toJSON({ "keys": keys }); 300 | } 301 | ajax({ 302 | type: type, 303 | data: data, 304 | url: this.uri + "_all_docs" + encodeOptions(options) 305 | }, 306 | options, 307 | "An error occurred retrieving a list of all documents" 308 | ); 309 | }, 310 | allDesignDocs: function(options) { 311 | this.allDocs($.extend({startkey:"_design", endkey:"_design0"}, options)); 312 | }, 313 | allApps: function(options) { 314 | options = options || {}; 315 | var self = this; 316 | if (options.eachApp) { 317 | this.allDesignDocs({ 318 | success: function(resp) { 319 | $.each(resp.rows, function() { 320 | self.openDoc(this.id, { 321 | success: function(ddoc) { 322 | var index, appPath, appName = ddoc._id.split('/'); 323 | appName.shift(); 324 | appName = appName.join('/'); 325 | index = ddoc.couchapp && ddoc.couchapp.index; 326 | if (index) { 327 | appPath = ['', name, ddoc._id, index].join('/'); 328 | } else if (ddoc._attachments && ddoc._attachments["index.html"]) { 329 | appPath = ['', name, ddoc._id, "index.html"].join('/'); 330 | } 331 | if (appPath) options.eachApp(appName, appPath, ddoc); 332 | } 333 | }); 334 | }); 335 | } 336 | }); 337 | } else { 338 | alert("Please provide an eachApp function for allApps()"); 339 | } 340 | }, 341 | openDoc: function(docId, options, ajaxOptions) { 342 | options = options || {}; 343 | if (db_opts.attachPrevRev || options.attachPrevRev) { 344 | $.extend(options, { 345 | beforeSuccess : function(req, doc) { 346 | rawDocs[doc._id] = { 347 | rev : doc._rev, 348 | raw : req.responseText 349 | }; 350 | } 351 | }); 352 | } else { 353 | $.extend(options, { 354 | beforeSuccess : function(req, doc) { 355 | if (doc["jquery.couch.attachPrevRev"]) { 356 | rawDocs[doc._id] = { 357 | rev : doc._rev, 358 | raw : req.responseText 359 | }; 360 | } 361 | } 362 | }); 363 | } 364 | ajax({url: this.uri + encodeDocId(docId) + encodeOptions(options)}, 365 | options, 366 | "The document could not be retrieved", 367 | ajaxOptions 368 | ); 369 | }, 370 | saveDoc: function(doc, options) { 371 | options = options || {}; 372 | var db = this; 373 | var beforeSend = fullCommit(options); 374 | if (doc._id === undefined) { 375 | var method = "POST"; 376 | var uri = this.uri; 377 | } else { 378 | var method = "PUT"; 379 | var uri = this.uri + encodeDocId(doc._id); 380 | } 381 | var versioned = maybeApplyVersion(doc); 382 | $.ajax({ 383 | type: method, url: uri + encodeOptions(options), 384 | contentType: "application/json", 385 | dataType: "json", data: toJSON(doc), 386 | beforeSend : beforeSend, 387 | complete: function(req) { 388 | var resp = httpData(req, "json"); 389 | if (req.status == 200 || req.status == 201 || req.status == 202) { 390 | doc._id = resp.id; 391 | doc._rev = resp.rev; 392 | if (versioned) { 393 | db.openDoc(doc._id, { 394 | attachPrevRev : true, 395 | success : function(d) { 396 | doc._attachments = d._attachments; 397 | if (options.success) options.success(resp); 398 | } 399 | }); 400 | } else { 401 | if (options.success) options.success(resp); 402 | } 403 | } else if (options.error) { 404 | options.error(req.status, resp.error, resp.reason); 405 | } else { 406 | alert("The document could not be saved: " + resp.reason); 407 | } 408 | } 409 | }); 410 | }, 411 | bulkSave: function(docs, options) { 412 | var beforeSend = fullCommit(options); 413 | $.extend(options, {successStatus: 201, beforeSend : beforeSend}); 414 | ajax({ 415 | type: "POST", 416 | url: this.uri + "_bulk_docs" + encodeOptions(options), 417 | contentType: "application/json", data: toJSON(docs) 418 | }, 419 | options, 420 | "The documents could not be saved" 421 | ); 422 | }, 423 | removeDoc: function(doc, options) { 424 | ajax({ 425 | type: "DELETE", 426 | url: this.uri + 427 | encodeDocId(doc._id) + 428 | encodeOptions({rev: doc._rev}) 429 | }, 430 | options, 431 | "The document could not be deleted" 432 | ); 433 | }, 434 | bulkRemove: function(docs, options){ 435 | docs.docs = $.each( 436 | docs.docs, function(i, doc){ 437 | doc._deleted = true; 438 | } 439 | ); 440 | $.extend(options, {successStatus: 201}); 441 | ajax({ 442 | type: "POST", 443 | url: this.uri + "_bulk_docs" + encodeOptions(options), 444 | data: toJSON(docs) 445 | }, 446 | options, 447 | "The documents could not be deleted" 448 | ); 449 | }, 450 | copyDoc: function(docId, options, ajaxOptions) { 451 | ajaxOptions = $.extend(ajaxOptions, { 452 | complete: function(req) { 453 | var resp = httpData(req, "json"); 454 | if (req.status == 201) { 455 | if (options.success) options.success(resp); 456 | } else if (options.error) { 457 | options.error(req.status, resp.error, resp.reason); 458 | } else { 459 | alert("The document could not be copied: " + resp.reason); 460 | } 461 | } 462 | }); 463 | ajax({ 464 | type: "COPY", 465 | url: this.uri + encodeDocId(docId) 466 | }, 467 | options, 468 | "The document could not be copied", 469 | ajaxOptions 470 | ); 471 | }, 472 | query: function(mapFun, reduceFun, language, options) { 473 | language = language || "javascript"; 474 | if (typeof(mapFun) !== "string") { 475 | mapFun = mapFun.toSource ? mapFun.toSource() : "(" + mapFun.toString() + ")"; 476 | } 477 | var body = {language: language, map: mapFun}; 478 | if (reduceFun != null) { 479 | if (typeof(reduceFun) !== "string") 480 | reduceFun = reduceFun.toSource ? reduceFun.toSource() : "(" + reduceFun.toString() + ")"; 481 | body.reduce = reduceFun; 482 | } 483 | ajax({ 484 | type: "POST", 485 | url: this.uri + "_temp_view" + encodeOptions(options), 486 | contentType: "application/json", data: toJSON(body) 487 | }, 488 | options, 489 | "An error occurred querying the database" 490 | ); 491 | }, 492 | list: function(list, view, options) { 493 | var list = list.split('/'); 494 | var options = options || {}; 495 | var type = 'GET'; 496 | var data = null; 497 | if (options['keys']) { 498 | type = 'POST'; 499 | var keys = options['keys']; 500 | delete options['keys']; 501 | data = toJSON({'keys': keys }); 502 | } 503 | ajax({ 504 | type: type, 505 | data: data, 506 | url: this.uri + '_design/' + list[0] + 507 | '/_list/' + list[1] + '/' + view + encodeOptions(options) 508 | }, 509 | options, 'An error occured accessing the list' 510 | ); 511 | }, 512 | view: function(name, options) { 513 | var name = name.split('/'); 514 | var options = options || {}; 515 | var type = "GET"; 516 | var data= null; 517 | if (options["keys"]) { 518 | type = "POST"; 519 | var keys = options["keys"]; 520 | delete options["keys"]; 521 | data = toJSON({ "keys": keys }); 522 | } 523 | ajax({ 524 | type: type, 525 | data: data, 526 | url: this.uri + "_design/" + name[0] + 527 | "/_view/" + name[1] + encodeOptions(options) 528 | }, 529 | options, "An error occurred accessing the view" 530 | ); 531 | }, 532 | getDbProperty: function(propName, options, ajaxOptions) { 533 | ajax({url: this.uri + propName + encodeOptions(options)}, 534 | options, 535 | "The property could not be retrieved", 536 | ajaxOptions 537 | ); 538 | }, 539 | 540 | setDbProperty: function(propName, propValue, options, ajaxOptions) { 541 | ajax({ 542 | type: "PUT", 543 | url: this.uri + propName + encodeOptions(options), 544 | data : JSON.stringify(propValue) 545 | }, 546 | options, 547 | "The property could not be updated", 548 | ajaxOptions 549 | ); 550 | } 551 | }; 552 | }, 553 | 554 | encodeDocId: encodeDocId, 555 | 556 | info: function(options) { 557 | ajax( 558 | {url: this.urlPrefix + "/"}, 559 | options, 560 | "Server information could not be retrieved" 561 | ); 562 | }, 563 | 564 | replicate: function(source, target, ajaxOptions, repOpts) { 565 | repOpts = $.extend({source: source, target: target}, repOpts); 566 | if (repOpts.continuous && !repOpts.cancel) { 567 | ajaxOptions.successStatus = 202; 568 | } 569 | ajax({ 570 | type: "POST", url: this.urlPrefix + "/_replicate", 571 | data: JSON.stringify(repOpts), 572 | contentType: "application/json" 573 | }, 574 | ajaxOptions, 575 | "Replication failed" 576 | ); 577 | }, 578 | 579 | newUUID: function(cacheNum) { 580 | if (cacheNum === undefined) { 581 | cacheNum = 1; 582 | } 583 | if (!uuidCache.length) { 584 | ajax({url: this.urlPrefix + "/_uuids", data: {count: cacheNum}, async: false}, { 585 | success: function(resp) { 586 | uuidCache = resp.uuids; 587 | } 588 | }, 589 | "Failed to retrieve UUID batch." 590 | ); 591 | } 592 | return uuidCache.shift(); 593 | } 594 | }); 595 | 596 | var httpData = $.httpData || function( xhr, type, s ) { // lifted from jq1.4.4 597 | var ct = xhr.getResponseHeader("content-type") || "", 598 | xml = type === "xml" || !type && ct.indexOf("xml") >= 0, 599 | data = xml ? xhr.responseXML : xhr.responseText; 600 | 601 | if ( xml && data.documentElement.nodeName === "parsererror" ) { 602 | $.error( "parsererror" ); 603 | } 604 | if ( s && s.dataFilter ) { 605 | data = s.dataFilter( data, type ); 606 | } 607 | if ( typeof data === "string" ) { 608 | if ( type === "json" || !type && ct.indexOf("json") >= 0 ) { 609 | data = $.parseJSON( data ); 610 | } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) { 611 | $.globalEval( data ); 612 | } 613 | } 614 | return data; 615 | }; 616 | 617 | function ajax(obj, options, errorMessage, ajaxOptions) { 618 | 619 | var defaultAjaxOptions = { 620 | contentType: "application/json", 621 | headers: {"Accept": "application/json"} 622 | }; 623 | 624 | options = $.extend({successStatus: 200}, options); 625 | ajaxOptions = $.extend(defaultAjaxOptions, ajaxOptions); 626 | errorMessage = errorMessage || "Unknown error"; 627 | $.ajax($.extend($.extend({ 628 | type: "GET", dataType: "json", cache : !$.browser.msie, 629 | beforeSend: function(xhr){ 630 | if(ajaxOptions && ajaxOptions.headers){ 631 | for (var header in ajaxOptions.headers){ 632 | xhr.setRequestHeader(header, ajaxOptions.headers[header]); 633 | } 634 | } 635 | }, 636 | complete: function(req) { 637 | try { 638 | var resp = httpData(req, "json"); 639 | } catch(e) { 640 | if (options.error) { 641 | options.error(req.status, req, e); 642 | } else { 643 | alert(errorMessage + ": " + e); 644 | } 645 | return; 646 | } 647 | if (options.ajaxStart) { 648 | options.ajaxStart(resp); 649 | } 650 | if (req.status == options.successStatus) { 651 | if (options.beforeSuccess) options.beforeSuccess(req, resp); 652 | if (options.success) options.success(resp); 653 | } else if (options.error) { 654 | options.error(req.status, resp && resp.error || errorMessage, resp && resp.reason || "no response"); 655 | } else { 656 | alert(errorMessage + ": " + resp.reason); 657 | } 658 | } 659 | }, obj), ajaxOptions)); 660 | } 661 | 662 | function fullCommit(options) { 663 | var options = options || {}; 664 | if (typeof options.ensure_full_commit !== "undefined") { 665 | var commit = options.ensure_full_commit; 666 | delete options.ensure_full_commit; 667 | return function(xhr) { 668 | xhr.setRequestHeader("X-Couch-Full-Commit", commit.toString()); 669 | }; 670 | } 671 | }; 672 | 673 | // Convert a options object to an url query string. 674 | // ex: {key:'value',key2:'value2'} becomes '?key="value"&key2="value2"' 675 | function encodeOptions(options) { 676 | var buf = []; 677 | if (typeof(options) === "object" && options !== null) { 678 | for (var name in options) { 679 | if ($.inArray(name, ["error", "success", "beforeSuccess", "ajaxStart"]) >= 0) 680 | continue; 681 | var value = options[name]; 682 | if ($.inArray(name, ["key", "startkey", "endkey"]) >= 0) { 683 | value = toJSON(value); 684 | } 685 | buf.push(encodeURIComponent(name) + "=" + encodeURIComponent(value)); 686 | } 687 | } 688 | return buf.length ? "?" + buf.join("&") : ""; 689 | } 690 | 691 | function toJSON(obj) { 692 | return obj !== null ? JSON.stringify(obj) : null; 693 | } 694 | 695 | })(jQuery); -------------------------------------------------------------------------------- /_attachments/scripts/jquery.csvIn.min.js: -------------------------------------------------------------------------------- 1 | /* jQuery.csvIn - Set of functions to process csv data in jquery 2 | https://github.com/Mango-information-systems/jquery.csvIn/blob/master/README.md 3 | version 0.2 - 31st July 2011 4 | Copyright (c) 2011 Mango Information Systems SPRL, http://www.mango-is.com 5 | This plugin will either be released under dual license (MIT + LGPL) or under Apache license version 2.0. Precision will be added soon right here. 6 | csvIn code is based on [jquery.csv] plugin, licensed under Apache license version 2.0 7 | [jquery.csv]: http://code.google.com/p/js-tables/ 8 | */ 9 | (function(b){if("a,,b".split(",").length<3){var e=e||String.prototype.split;String.prototype.split=function(p,k){if(!(p instanceof RegExp)){return e.apply(this,arguments)}if(k===undefined||+k<0){k=false}else{k=Math.floor(+k);if(!k){return[]}}var h=(p.global?"g":"")+(p.ignoreCase?"i":"")+(p.multiline?"m":""),n=new RegExp("^"+p.source+"$",h),g=[],f=0,l=0,m;if(!p.global){p=new RegExp(p.source,"g"+h)}while((!k||l++<=k)&&(m=p.exec(this))){var o=!m[0].length;if(o&&p.lastIndex>m.index){p.lastIndex=m.index}if(p.lastIndex>f){if(m.length>1){m[0].replace(n,function(){for(var q=1;qn.endLine?n.endLine:o.length-1}if(n.excludedColumns.length==0){for(var g=n.startLine;g<=n.endLine;g++){p.push(h(o[g]))}}else{for(var g=n.startLine;g<=n.endLine;g++){split=h(o[g]);for(j in n.excludedColumns){split.splice(n.excludedColumns[j],1)}p.push(split)}}return p};b.csvIn.toJSON=function(l,r){r=b.extend({},b.csvIn.defaults,r);var f=a(r.delim,r.quote,r.lined),n=f[0],o=f[1],k=f[2];var s=l.replace(n,"").split(o);if(r.endLine==-1){r.endLine=s.length-1}else{r.endLine=s.length>r.endLine?r.endLine:s.length-1}var m=r.customHeaders.length==0?k(s[0]):r.customHeaders;if(r.startLine==0&&r.customHeaders.length==0){r.startLine=1}nfields=m.length;out=[];if(r.excludedColumns.length==0){for(var h=r.startLine;h<=r.endLine;h++){var q=k(s[h]);for(var g=0,p={};g .divTitle { 33 | color:red; 34 | } 35 | 36 | div#session { 37 | position:absolute; 38 | top:0; 39 | right:0; 40 | float:right; 41 | padding:7px; 42 | } 43 | 44 | div#session > form > input[type="text"], div#session > form > input[type="password"] { 45 | width:100px; 46 | margin:7px; 47 | } 48 | 49 | .fileName { 50 | width: 375px; 51 | margin-top:-5px; 52 | } 53 | 54 | div.fileSettings { 55 | position:absolute; 56 | width:375px; 57 | overflow:auto; 58 | padding-left:5px; 59 | } 60 | div.filePreview { 61 | position: absolute; 62 | top: 5px; 63 | left: 395px; 64 | height: 305px; 65 | overflow: auto; 66 | } 67 | 68 | #successDocs, #conflictDocs, #failDocs { 69 | width: 700px; 70 | display:none; 71 | } 72 | 73 | div.container { 74 | position: relative; 75 | height: 313px; 76 | overflow:auto; 77 | margin:10px; 78 | padding: 7px; 79 | border: 2px solid #b4b4b4; 80 | background-color: #E6E6E6; 81 | background-image: -webkit-gradient(linear, left top, left bottom, from(#E6E6E6), to(#b4b4b4)); 82 | background-image: -webkit-linear-gradient(top, #E6E6E6, #b4b4b4); 83 | background-image: -moz-linear-gradient(top, #E6E6E6, #b4b4b4); 84 | background-image: -ms-linear-gradient(top, #E6E6E6, #b4b4b4); 85 | background-image: -o-linear-gradient(top, #E6E6E6, #b4b4b4); 86 | background-image: linear-gradient(top, #E6E6E6, #b4b4b4); 87 | filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#E6E6E6', EndColorStr='#b4b4b4'); 88 | border-radius: 12px; 89 | -webkit-border-radius: 12px; 90 | -moz-border-radius: 12px; 91 | } 92 | 93 | #bulkLoadSpinner, #localFiles, #moreFiles, #recline, #step3, #successDocs, #conflictDocs, #failDocs { 94 | margin-top: 5px; 95 | padding: 7px; 96 | border: 2px solid #E6E6E6; 97 | background-color: #E6E6E6; 98 | background-image: -webkit-gradient(linear, left top, left bottom, from(#E6E6E6), to(#b4b4b4)); 99 | background-image: -webkit-linear-gradient(top, #E6E6E6, #b4b4b4); 100 | background-image: -moz-linear-gradient(top, #E6E6E6, #b4b4b4); 101 | background-image: -ms-linear-gradient(top, #E6E6E6, #b4b4b4); 102 | background-image: -o-linear-gradient(top, #E6E6E6, #b4b4b4); 103 | background-image: linear-gradient(top, #E6E6E6, #b4b4b4); 104 | filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#E6E6E6', EndColorStr='#b4b4b4'); 105 | border-radius: 12px; 106 | -webkit-border-radius: 12px; 107 | -moz-border-radius: 12px; 108 | } 109 | 110 | .template { 111 | display: none 112 | } 113 | 114 | #commonSettings { 115 | clear: both; 116 | } 117 | 118 | .editable { 119 | padding-left: 4px; 120 | padding-right: 4px; 121 | background: #e6e6e6; 122 | color: #565656; 123 | border: 1px solid #565656; 124 | } 125 | .editable:hover { 126 | background: white; 127 | cursor:pointer; 128 | } 129 | 130 | 131 | .smallText, .customdelimitors { 132 | width: 45px; 133 | } 134 | 135 | .excluded { 136 | color: gray; 137 | text-decoration: line-through; 138 | } 139 | 140 | #step1, #step2 { 141 | margin-top:-15px; 142 | } 143 | 144 | #step3, #bulkLoadSpinner { 145 | width: 500px; 146 | } 147 | 148 | #step2, #step3, #step4 { 149 | display: none; 150 | color: black; 151 | } 152 | 153 | #localFilesForm { 154 | visibility:hidden; 155 | } 156 | 157 | .progress_bar { 158 | width: 400px; 159 | margin: 10px 0; 160 | padding: 3px; 161 | border: 1px solid #565656; 162 | font-size: 14px; 163 | clear: both; 164 | -moz-transition: opacity 1s linear; 165 | -o-transition: opacity 1s linear; 166 | -webkit-transition: opacity 1s linear; 167 | } 168 | .progress_bar .percent { 169 | height: auto; 170 | width: 0; 171 | background-color: #565656; 172 | color: #e6e6e6; 173 | padding-left: 5px; 174 | } 175 | 176 | #filesContainer { 177 | height: 402px; 178 | overflow: auto; 179 | margin-bottom:7px; 180 | border: 2px solid #E6E6E6; 181 | border-radius: 12px; 182 | -webkit-border-radius: 12px; 183 | -moz-border-radius: 12px; 184 | } 185 | 186 | #step2 > .divTitle { 187 | color:#E6E6E6; 188 | margin-bottom:0px; 189 | } 190 | 191 | #howTo { 192 | position:absolute; 193 | top: 150px; 194 | left: 450px; 195 | width:485px; 196 | margin-top: 5px; 197 | padding: 7px; 198 | border: 2px solid #E6E6E6; 199 | border-radius: 12px; 200 | -webkit-border-radius: 12px; 201 | -moz-border-radius: 12px; 202 | } 203 | 204 | #techDisclaimer { 205 | position:absolute; 206 | top: 290px; 207 | width:400px; 208 | height: 120px; 209 | margin-top: 5px; 210 | padding: 7px; 211 | border: 2px solid #E6E6E6; 212 | border-radius: 12px; 213 | -webkit-border-radius: 12px; 214 | -moz-border-radius: 12px; 215 | } 216 | 217 | #localFiles { 218 | position:absolute; 219 | top: 150px; 220 | height:110px; 221 | width:400px; 222 | color:#565656; 223 | } 224 | 225 | #postProcessing { 226 | display:none; 227 | position:absolute; 228 | top: 98px; 229 | left: 735px; 230 | } 231 | 232 | #moreFiles, #recline { 233 | height:110px; 234 | width:400px; 235 | color:#565656; 236 | } 237 | 238 | 239 | #localFiles:hover, #moreFiles:hover, #recline:hover { 240 | border: 2px solid #333; 241 | background-image: -webkit-gradient(linear, left top, left bottom, from(#E6E6E6), to(#ccc)); 242 | background-image: -webkit-linear-gradient(top, #E6E6E6, #ccc); 243 | background-image: -moz-linear-gradient(top, #E6E6E6, #ccc); 244 | background-image: -ms-linear-gradient(top, #E6E6E6, #ccc); 245 | background-image: -o-linear-gradient(top, #E6E6E6, #ccc); 246 | background-image: linear-gradient(top, #E6E6E6, #ccc); 247 | filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#E6E6E6', EndColorStr='#ccc'); 248 | cursor: pointer; 249 | } 250 | 251 | #banner { 252 | position:relative; 253 | height:90px; 254 | } 255 | 256 | #banner > img { 257 | position:absolute; 258 | } 259 | 260 | #banner > h1 { 261 | position:absolute; 262 | left:140px; 263 | top:30px; 264 | } 265 | 266 | #footer { 267 | position: absolute; 268 | bottom:0; 269 | right:25px; 270 | padding-bottom:5px; 271 | } 272 | 273 | #localFiles > div:nth-child(1), #moreFiles > div:nth-child(1), #recline > div:nth-child(1), #techDisclaimer > div:nth-child(1) { 274 | position:absolute; 275 | width:100px; 276 | } 277 | 278 | #localFiles > div:nth-child(2), #moreFiles > div:nth-child(2), #recline > div:nth-child(2), #techDisclaimer > div:nth-child(2) { 279 | position:absolute; 280 | left:100px; 281 | width:330px; 282 | } 283 | 284 | fieldset { 285 | padding-top: 4px; 286 | padding-bottom: 7px; 287 | } 288 | 289 | legend { 290 | font-weight:bold; 291 | color: #565656; 292 | } 293 | 294 | .fileSettings > fieldset:nth-child(1) > label { 295 | display:inline-block; 296 | width:140px; 297 | } 298 | 299 | .fileSettings > fieldset:nth-child(2) > label { 300 | display:inline-block; 301 | width:140px; 302 | } 303 | 304 | .conflict, .fail { 305 | margin-top:16px; 306 | } -------------------------------------------------------------------------------- /_id: -------------------------------------------------------------------------------- 1 | _design/csv2couchdb -------------------------------------------------------------------------------- /couchapp.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "csv2couchdb", 3 | "description": "CouchApp to integrate data from CSV files inside couchdb" 4 | } -------------------------------------------------------------------------------- /language: -------------------------------------------------------------------------------- 1 | javascript --------------------------------------------------------------------------------