├── LICENSE ├── README.md ├── dev └── simpleD3.html ├── docs ├── example.js ├── images │ ├── logo.png │ └── logo.svg ├── reference.html └── release-notes.html ├── index.html ├── peek.css ├── peek.js └── require ├── d3.min.js ├── fonts ├── DroidSansMono.woff ├── OpenSans.woff ├── OpenSansBold.woff ├── OpenSansBoldItalic.woff └── OpenSansItalic.woff ├── framework.icons.js ├── framework.min.css ├── framework.min.js ├── highlight.min.css ├── highlight.min.js └── textures.min.js /LICENSE: -------------------------------------------------------------------------------- 1 | Peek is licensed under the MIT license 2 | -------------------------------------- 3 | 4 | Copyright (c) 2015 Mark Macdonald 5 | 6 | Peek includes third-party libraries (see below). 7 | 8 | MIT licensed: 9 | ------------- 10 | 11 | Webknife: Copyright (c) 2015 The Webknife Project, (http://mtmacdonald.github.io/webknife) 12 | 13 | Webknife includes third-party libraries attributed here: https://github.com/mtmacdonald/webknife/blob/master/LICENSE 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | 33 | BSD licensed: 34 | ------------- 35 | 36 | d3.js: Copyright (c) 2010-2015, Michael Bostock (http://d3js.org) 37 | 38 | Redistribution and use in source and binary forms, with or without 39 | modification, are permitted provided that the following conditions are met: 40 | 41 | * Redistributions of source code must retain the above copyright notice, this 42 | list of conditions and the following disclaimer. 43 | 44 | * Redistributions in binary form must reproduce the above copyright notice, 45 | this list of conditions and the following disclaimer in the documentation 46 | and/or other materials provided with the distribution. 47 | 48 | * The name Michael Bostock may not be used to endorse or promote products 49 | derived from this software without specific prior written permission. 50 | 51 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 52 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 54 | DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, 55 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 56 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 57 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 58 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 59 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 60 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | peek 2 | ==== 3 | 4 | Charts based on D3 5 | -------------------------------------------------------------------------------- /dev/simpleD3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 71 | 72 | 73 |
74 | 75 | -------------------------------------------------------------------------------- /docs/example.js: -------------------------------------------------------------------------------- 1 | /*! Peek.js (c) 2015 Mark Macdonald | http://mtmacdonald.github.io/peek/LICENSE */ 2 | 3 | /* 4 | Example input data for Peek.js 5 | */ 6 | 7 | var timeData = [ 8 | { 9 | "label": "Foo", 10 | "units": "kg", 11 | "group" : "A", 12 | "color": "#69A9CA", 13 | "values": [ 14 | { 15 | x : "2014-03-01 00:00:00", 16 | y : 3 17 | }, 18 | { 19 | x : "2014-03-02 00:00:00", 20 | y : 1.43 21 | }, 22 | { 23 | x : "2014-03-03 00:00:00", 24 | y : 0.38 25 | }, 26 | { 27 | x : "2014-03-04 00:00:00", 28 | y : 3.5 29 | }, 30 | { 31 | x : "2014-03-05 00:00:00", 32 | y : 2.0 33 | } 34 | ] 35 | }, 36 | { 37 | "label": "Foo", 38 | "units": "kg", 39 | "group" : "B", 40 | "color": "#8583C2", 41 | "values": [ 42 | { 43 | x : "2014-03-01 00:00:00", 44 | y : 2 45 | }, 46 | { 47 | x : "2014-03-02 00:00:00", 48 | y : 4.5 49 | }, 50 | { 51 | x : "2014-03-03 00:00:00", 52 | y : 6 53 | }, 54 | { 55 | x : "2014-03-04 00:00:00", 56 | y : 1.1 57 | }, 58 | { 59 | x : "2014-03-05 00:00:00", 60 | y : 0.8 61 | } 62 | ] 63 | }, 64 | { 65 | "label": "Foo", 66 | "units": "kg", 67 | "group" : "C", 68 | "color": "#67D1B8", 69 | "values": [ 70 | { 71 | x : "2014-03-01 00:00:00", 72 | y : 2 73 | }, 74 | { 75 | x : "2014-03-02 00:00:00", 76 | y : 4.5 77 | }, 78 | { 79 | x : "2014-03-03 00:00:00", 80 | y : 6 81 | }, 82 | { 83 | x : "2014-03-04 00:00:00", 84 | y : 1.1 85 | }, 86 | { 87 | x : "2014-03-05 00:00:00", 88 | y : 0.8 89 | } 90 | ] 91 | }, 92 | { 93 | "label": "Bar", 94 | "units": "m/s", 95 | "group" : "A", 96 | "color": "#C76842", 97 | "values": [ 98 | { 99 | x : "2014-03-01 00:00:00", 100 | y : 2 101 | }, 102 | { 103 | x : "2014-03-02 00:00:00", 104 | y : 4.4 105 | }, 106 | { 107 | x : "2014-03-03 00:00:00", 108 | y : 0.8 109 | }, 110 | { 111 | x : "2014-03-04 00:00:00", 112 | y : 2.24 113 | }, 114 | { 115 | x : "2014-03-05 00:00:00", 116 | y : 2.0 117 | } 118 | ] 119 | }, 120 | { 121 | "label": "Bar", 122 | "units": "m/s", 123 | "group" : "B", 124 | "color": "#C06472", 125 | "values": [ 126 | { 127 | x : "2014-03-01 00:00:00", 128 | y : 4.2 129 | }, 130 | { 131 | x : "2014-03-02 00:00:00", 132 | y : 2.4 133 | }, 134 | { 135 | x : "2014-03-03 00:00:00", 136 | y : 0.6 137 | }, 138 | { 139 | x : "2014-03-04 00:00:00", 140 | y : 5.1 141 | }, 142 | { 143 | x : "2014-03-05 00:00:00", 144 | y : 9.0 145 | } 146 | ] 147 | }, 148 | { 149 | "label": "Bar", 150 | "units": "m/s", 151 | "group" : "C", 152 | "color": "#C99336", 153 | "values": [ 154 | { 155 | x : "2014-03-01 00:00:00", 156 | y : 5 157 | }, 158 | { 159 | x : "2014-03-02 00:00:00", 160 | y : 1.5 161 | }, 162 | { 163 | x : "2014-03-03 00:00:00", 164 | y : 7 165 | }, 166 | { 167 | x : "2014-03-04 00:00:00", 168 | y : 2.1 169 | }, 170 | { 171 | x : "2014-03-05 00:00:00", 172 | y : 5.8 173 | } 174 | ] 175 | }, 176 | { 177 | "label": "Baz", 178 | "units": "l", 179 | "group" : "A", 180 | "color": "#68843C", 181 | "values": [ 182 | { 183 | x : "2014-03-01 00:00:00", 184 | y : 1 185 | }, 186 | { 187 | x : "2014-03-02 00:00:00", 188 | y : 3.2 189 | }, 190 | { 191 | x : "2014-03-03 00:00:00", 192 | y : 3.6 193 | }, 194 | { 195 | x : "2014-03-04 00:00:00", 196 | y : 1.9 197 | }, 198 | { 199 | x : "2014-03-05 00:00:00", 200 | y : 3.1 201 | } 202 | ] 203 | }, 204 | { 205 | "label": "Baz", 206 | "units": "l", 207 | "group" : "B", 208 | "color": "#84D747", 209 | "values": [ 210 | { 211 | x : "2014-03-01 00:00:00", 212 | y : 3.2 213 | }, 214 | { 215 | x : "2014-03-02 00:00:00", 216 | y : 2.2 217 | }, 218 | { 219 | x : "2014-03-03 00:00:00", 220 | y : 4.6 221 | }, 222 | { 223 | x : "2014-03-04 00:00:00", 224 | y : 5.1 225 | }, 226 | { 227 | x : "2014-03-05 00:00:00", 228 | y : 0.1 229 | } 230 | ] 231 | }, 232 | { 233 | "label": "Baz", 234 | "units": "l", 235 | "group" : "C", 236 | "color": "#6C7970", 237 | "values": [ 238 | { 239 | x : "2014-03-01 00:00:00", 240 | y : 1 241 | }, 242 | { 243 | x : "2014-03-02 00:00:00", 244 | y : 2.5 245 | }, 246 | { 247 | x : "2014-03-03 00:00:00", 248 | y : 5 249 | }, 250 | { 251 | x : "2014-03-04 00:00:00", 252 | y : 3.1 253 | }, 254 | { 255 | x : "2014-03-05 00:00:00", 256 | y : 1.8 257 | } 258 | ] 259 | }, 260 | ]; 261 | 262 | var horizontalBarData = [ 263 | { 264 | "label": "Foo", 265 | "units" : "", 266 | "color": "#69A9CA", 267 | "value": 80, 268 | }, 269 | { 270 | "label": "Bar", 271 | "units" : "", 272 | "color": "#C76842", 273 | "value": 50, 274 | }, 275 | { 276 | "label": "Baz", 277 | "units" : "", 278 | "color": "#68843C", 279 | "value": 30, 280 | }, 281 | { 282 | "label": "Qux", 283 | "units" : "", 284 | "color": "#8583C2", 285 | "value": 2, 286 | }, 287 | ]; 288 | 289 | var radialData = [ 290 | { 291 | "label": "Foo", 292 | "units" : "", 293 | "color": "#69A9CA", 294 | "value": 50, 295 | }, 296 | { 297 | "label": "Bar", 298 | "units" : "", 299 | "color": "#C76842", 300 | "value": 25, 301 | }, 302 | { 303 | "label": "Baz", 304 | "units" : "", 305 | "color": "#68843C", 306 | "value": 25, 307 | }, 308 | ]; 309 | 310 | function getFirstGroupData() { 311 | var data = JSON.parse(JSON.stringify(timeData)); //clone 312 | var firstGroupName = data[0].group; 313 | var i = data.length; 314 | while (i--) { //iterate data in reverse to allow safe deletion 315 | if (data[i].group !== firstGroupName) { 316 | data.splice(i, 1); 317 | } 318 | } 319 | return data; 320 | } 321 | 322 | function getFirstGroupDataWithScale() { 323 | var data = getFirstGroupData(); 324 | data.forEach(function (series, i) { 325 | if (i === 0) { 326 | series.dualScale = true; 327 | } 328 | }); 329 | return data; 330 | } 331 | 332 | function getFirstGroupDataWithTexture() { 333 | var data = getFirstGroupData(); 334 | data.forEach(function (series) { 335 | series.texture = 'diagonal'; 336 | }); 337 | return data; 338 | } 339 | 340 | function getFirstGroupFirstSeriesData() { 341 | var data = JSON.parse(JSON.stringify(timeData)); //clone 342 | data.splice(1, data.length); 343 | return data; 344 | } 345 | 346 | function getAllGroupsLastSeriesData() { 347 | var data = JSON.parse(JSON.stringify(timeData)); //clone 348 | var alreadyIncluded = []; 349 | var i = data.length; 350 | while (i--) { //iterate data in reverse to allow safe deletion 351 | if (!(alreadyIncluded.indexOf(data[i].group) > -1)) { 352 | alreadyIncluded.push(data[i].group); 353 | } else { 354 | data.splice(i, 1); 355 | } 356 | } 357 | return data; 358 | } 359 | 360 | function getLinearData() { 361 | var data = getFirstGroupData(); 362 | //instead of a time scale, return a linear x-scale with values 1-5 363 | data.forEach(function (series, i) { 364 | var xVal = 1; 365 | for (var point in series.values) { 366 | if (series.values.hasOwnProperty(point)) { 367 | series.values[point].x = xVal; 368 | ++xVal; 369 | } 370 | } 371 | }); 372 | return data; 373 | } 374 | 375 | function getOrdinalData() { 376 | var data = getFirstGroupData(); 377 | //instead of a time scale, return an ordinal x-scale with values A-E 378 | data.forEach(function (series, i) { 379 | var xVal = 1; 380 | for (var point in series.values) { 381 | if (series.values.hasOwnProperty(point)) { 382 | if (xVal === 1) { 383 | series.values[point].x = 'A'; 384 | } else if (xVal === 2) { 385 | series.values[point].x = 'B'; 386 | } else if (xVal === 3) { 387 | series.values[point].x = 'C'; 388 | } else if (xVal === 4) { 389 | series.values[point].x = 'D'; 390 | } else if (xVal === 5) { 391 | series.values[point].x = 'E'; 392 | } 393 | ++xVal; 394 | } 395 | } 396 | }); 397 | return data; 398 | } -------------------------------------------------------------------------------- /docs/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtmacdonald/peek/d4e1bb4ae3c803991b945eb640daefb65a097a2a/docs/images/logo.png -------------------------------------------------------------------------------- /docs/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 20 | 38 | 40 | 41 | 43 | image/svg+xml 44 | 46 | 47 | 48 | 49 | 50 | 55 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /docs/reference.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Peek - a chart library based on D3.js 8 | 9 | 10 | 11 | 12 | 13 | 14 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 77 | 94 | 95 | 96 | 97 | 98 |
99 |
100 | 101 |
102 | Peek - a chart library based on D3.js (version 1.4.1) 103 |
104 |
105 |
106 |
107 |
108 |
109 | 110 |
111 |
112 | 113 |

Chart Types

114 | 115 |

Peek supports the following chart types:

116 | 117 | 139 | 140 |

See the example data for the input JSON format. The time-series charts are interchangeable 141 | (a common data format can be used with all chart types). 142 |

143 | 144 |

Limitations

145 | 146 | 151 | 152 | 153 | 154 |

Line chart

155 |
156 | 167 | 168 |
169 |
170 |
171 | 172 | 173 | 174 |

Line chart (with dual y-axis and dual scales)

175 |

176 | Dual y-axes with series belonging to one of two scales. Note: only line and scatter charts support dual y-axes. 177 |

178 |
179 | 194 | 195 |
196 |
197 |
198 | 199 | 200 | 201 |

Line chart (with interpolation, data points and grid)

202 |

203 | See the D3.js documentation 204 | and this example for a list of interpolation types. 205 |

206 |
207 | 218 | 219 |
220 |
221 |
222 | 223 | 224 | 225 |

Line chart (with linear x-axis scale)

226 |
227 | 239 | 240 |
241 |
242 |
243 | 244 | 245 | 246 |

Scatter chart

247 |
248 | 263 | 264 |
265 |
266 |
267 | 268 | 269 | 270 |

Area chart

271 |
272 | 285 | 286 |
287 |
288 |
289 | 290 | 291 | 292 |

Stacked area chart

293 |
294 | 307 | 308 |
309 |
310 |
311 | 312 | 313 | 314 |

Stacked area chart (with opacity and data points)

315 |
316 | 332 | 333 |
334 |
335 |
336 | 337 | 338 | 339 |

Expanded stacked area chart

340 |
341 | 357 | 358 |
359 |
360 |
361 | 362 | 363 | 364 |

Stacked area chart (wiggle offset)

365 |
366 | 382 | 383 |
384 |
385 |
386 | 387 | 388 | 389 |

Stacked area chart (silhouette offset)

390 |
391 | 407 | 408 |
409 |
410 |
411 | 412 | 413 | 414 |

Bar chart

415 |
416 | 428 | 429 |
430 |
431 |
432 | 433 | 434 | 435 |

Bar chart (with opacity)

436 |
437 | 451 | 452 |
453 |
454 |
455 | 456 | 457 | 458 |

Grouped bar chart

459 |
460 | 475 | 476 |
477 |
478 |
479 | 480 | 481 | 482 |

Stacked bar chart

483 |
484 | 498 | 499 |
500 |
501 |
502 | 503 | 504 | 505 |

Stacked bar chart (with texture)

506 |
507 | 521 | 522 |
523 |
524 |
525 | 526 | 527 | 528 |

Stacked grouped bar chart

529 |
530 | 545 | 546 |
547 |
548 |
549 | 550 | 551 | 552 |

Bar chart (with linear x-axis scale)

553 |
554 | 569 | 570 |
571 |
572 |
573 | 574 | 575 | 576 |

Bar chart (with ordinal x-axis scale)

577 |
578 | 593 | 594 |
595 |
596 |
597 | 598 | 599 | 600 |

Horizontal bar chart

601 | 602 |

The horizontal bar chart features a flexible height, which expands automatically as more rows are added to the data input.

603 | 604 |
605 | 611 | 612 |
613 |
614 | 615 | 616 | 617 |

Pie chart

618 |
619 | 628 | 629 |
630 |
631 |
632 | 633 | 634 | 635 |

Donut chart

636 |
637 | 645 | 646 |
647 |
648 |
649 | 650 | 651 | 652 |

Donut chart (with outline and transparency)

653 |
654 | 665 | 666 |
667 |
668 |
669 | 670 |
671 |
672 | 673 | 680 | 681 | 682 | 683 | -------------------------------------------------------------------------------- /docs/release-notes.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | Peek - a chart library based on D3.js 8 | 9 | 10 | 11 | 12 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
32 | 33 |
34 | Peek - a chart library based on D3.js (version 1.4.1) 35 |
36 |
37 |
38 |
39 | 40 |
41 |
42 | 43 |

Release Notes

44 | 45 |

1.4.1 released 12/02/2016

46 | 47 | 50 | 51 |

1.4.0 released 01/12/2015

52 | 53 | 57 | 58 |

1.3.1 released 19/11/2015

59 | 60 | 63 | 64 |

1.3.0 released 19/11/2015

65 | 66 | 69 | 70 |

1.2.0 released 11/11/2015

71 | 72 | 83 | 84 |

1.1.0 released 17/03/2015

85 | 86 | 115 | 116 |

1.0.0 released 22/09/2014

117 | 118 | 126 | 127 |
128 |
129 | 130 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Peek - a chart library based on D3.js 7 | 8 | 9 | 10 | 11 | 12 | 13 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 210 | 211 | 212 | 213 | 214 | 215 |
216 |
217 | 218 |
219 | Peek - a chart library based on D3.js (version 1.4.1) 220 |
221 |
222 |
223 | Reference Guide 224 | Release Notes 225 |
226 |
227 |
228 | 229 | 246 | 247 | 253 |
254 | 255 |
256 | 257 |

258 | Peek is a an object-oriented chart library for web applications, based on D3.js. 259 |

260 | 261 |
    262 |
  • 263 |

    Object-oriented

    264 |

    The benefits of D3.js, but with easier, configurable, reusable chart objects.

    265 |
  • 266 |
  • 267 |

    Many chart types

    268 |

    Supports scatter, line, area, bar, pie, and donut charts in multiple orientations and configurations.

    269 |
  • 270 |
  • 271 |

    Multiple series

    272 |

    Display and compare multiple data series with stacked and grouped charts.

    273 |
  • 274 |
  • 275 |

    Automatic scaling

    276 |

    Scales and axis tick labels are handled automatically, with input data maxima detection.

    277 |
  • 278 |
  • 279 |

    Interpolation

    280 |

    Optional best-fit curves and line smoothing with 281 | D3 line interpolation.

    282 |
  • 283 |
  • 284 |

    JSON data format

    285 |

    Standardised data inputs allow the same dataset to easily be displayed in multiple chart types. 286 |

    287 |
  • 288 |
  • 289 |

    Labelling

    290 |

    Support for configurable chart titles, axis labels, and legends.

    291 |
  • 292 |
  • 293 |

    Interactive

    294 |

    Optionally show data points, with interactive tooltips for displaying values.

    295 |
  • 296 |
297 | 298 |

Peek provides an HTML5, CSS3 and JavaScript chart library for any modern web application.

299 | 300 |
301 | 302 |
303 |

Getting started

304 |

Peek is server-side agnostic and will work with any backend framework.

305 | 306 |
    307 |
  • 308 |

    Download the library

    309 |

    310 | Download or clone a copy of the library. 311 |

    312 |
  • 313 |
  • 314 |

    Copy from examples

    315 |

    316 | Copy and paste from the examples. 317 |

    318 |
  • 319 |
  • 320 |

    Customize and publish

    321 |

    322 | Attach to any webpage, and publish. 323 |

    324 |
  • 325 |
326 | 327 |

The key point is to attach the library CSS and JavaScript files:

328 | 329 |
<link rel="stylesheet" href="peek.css" type="text/css" />
330 | 331 |
<script src="require/d3.min.js"></script>
332 | <script src="peek.js"></script>
333 | 
334 | 335 |
336 | 337 |
338 |

Overview

339 | 340 |

The best way to get an overview is to look at the examples. 341 | 342 |

Class list

343 | 344 |

User classes are accessed directy. Internal classes are only accessed indirectly, as a child members of a user class.

345 | 346 |
    347 |
  • User classes:
  • 348 |
      349 |
    • Cartesian - creates a Cartesian (xy), time-series chart of any type
    • 350 |
    • Radial - creates a radial chart, e.g. pie chart
    • 351 |
    • HorizontalBar - creates a horizontal bar chart
    • 352 |
    • Legend - draws a chart legend with color/label key
    • 353 |
    354 |
  • Internal classes:
  • 355 |
      356 |
    • Plot - plot handler, including title, legends, and SVG for all charts
    • 357 |
    • Axes
    • 358 |
        359 |
      • Axis - axis handler for all charts
      • 360 |
      361 |
    • Data - a common data input handler for Cartesian charts
    • 362 |
    • Lines - line handler for Cartesian charts
    • 363 |
    • Areas - shaded area handler for Cartesian charts
    • 364 |
    • Points - point handler, including tooltips for Cartesian charts
    • 365 |
    • Bars - bar handler for Cartesian charts
    • 366 |
    367 |
368 | 369 |

Chart topology

370 | 371 |

Legends, titles, and labels (except axis tick labels) are rendered as HTML elements, not SVG elements. This is 372 | primarily because HTML elements handle text overflow better. The chart topology, with CSS class names, is shown below: 373 |

374 | 375 |
.pk-chart 376 |
.pk-plot 377 |
.pk-yLabelContainer 378 |
.pk-yLabel 379 |
380 |
381 |
.pk-mainContainer 382 |
.pk-title 383 |


384 |
.pk-svgContainer 385 |
svg 386 |
387 |


388 |
.pk-xLabel 389 |
390 |
391 |
392 |
393 |
.pk-legendContainer 394 |
.pk-legend 395 |
396 |
397 | 398 |
399 | 400 |
401 | 402 | 409 | 410 | 411 | 412 | -------------------------------------------------------------------------------- /peek.css: -------------------------------------------------------------------------------- 1 | /*! Peek.js (c) 2015 Mark Macdonald | http://mtmacdonald.github.io/peek/LICENSE */ 2 | 3 | .pk-plot div, .pk-legend div { 4 | margin: 0!important; 5 | } 6 | 7 | /* 8 | make it easy to clear floats 9 | */ 10 | 11 | .pk-clear-after::after { 12 | clear: both; 13 | height: 0; 14 | visibility: hidden; 15 | display: block; 16 | content:" "; 17 | } 18 | 19 | /* 20 | chart 21 | */ 22 | 23 | .pk-chart { 24 | margin: 0; 25 | overflow: hidden; 26 | display: inline-block; 27 | } 28 | 29 | .pk-plot { 30 | margin: 0; 31 | float: left; 32 | display: table; /*make left-container stretch to height of chart*/ 33 | } 34 | 35 | .pk-yLabelContainer { 36 | display: table-cell; /*make left-container stretch to height of chart*/ 37 | vertical-align: middle; 38 | position: relative; /*make container the closest positioned ancestor for yLabel: http://stackoverflow.com/questions/28741562*/ 39 | } 40 | 41 | .pk-yLabel { 42 | text-align: center; 43 | overflow: hidden; 44 | position: absolute; 45 | bottom: 0; 46 | transform: rotate(-90deg); 47 | transform-origin: top left; 48 | } 49 | 50 | .pk-mainContainer { 51 | /*display: table-cell;*/ 52 | } 53 | 54 | .pk-title { 55 | text-align: center; 56 | overflow: hidden; 57 | font-weight: bold; 58 | } 59 | 60 | .pk-xLabel { 61 | text-align: center; 62 | overflow: hidden; 63 | } 64 | 65 | .pk-svgContainer { 66 | line-height: 0; 67 | } 68 | 69 | .pk-svgContainer svg { 70 | line-height: 14px; 71 | } 72 | 73 | /**********************************************************************************************************************/ 74 | 75 | /* 76 | axes 77 | */ 78 | 79 | .pk-axis path, .pk-axis line, .pk-fakeAxis { 80 | fill: none; 81 | stroke: black; 82 | stroke-width: 1; 83 | shape-rendering: crispEdges; 84 | } 85 | 86 | .pk-axis text { 87 | font-size: 11px; 88 | fill: #444; /*match the body color*/ 89 | } 90 | 91 | .pk-grid { 92 | stroke: lightgrey; 93 | shape-rendering: crispEdges; 94 | } 95 | 96 | .pk-grid path { 97 | stroke-width: 0; 98 | } 99 | 100 | /**********************************************************************************************************************/ 101 | 102 | /* 103 | legends 104 | */ 105 | 106 | .pk-legendContainer { 107 | margin: 0; 108 | overflow: hidden; 109 | display: inline-block; 110 | vertical-align: top; 111 | } 112 | 113 | .pk-legend { 114 | margin: 0; 115 | float: left; 116 | padding-left: 10px; 117 | } 118 | 119 | .pk-legend div { 120 | /*inherited line height*/ 121 | } 122 | 123 | .pk-keyContainer { 124 | display: inline-block; 125 | vertical-align: middle; 126 | height: 16px; 127 | } 128 | 129 | .pk-keyText { 130 | margin 0; 131 | padding-left: 4px; 132 | vertical-align: middle; 133 | } 134 | 135 | /**********************************************************************************************************************/ 136 | 137 | /* 138 | lines 139 | */ 140 | 141 | .pk-line { 142 | fill: none; 143 | } 144 | 145 | .pk-area { 146 | stroke-width: 0; 147 | } 148 | 149 | circle { 150 | stroke-width: 2px; 151 | } 152 | 153 | .pk-tooltip { 154 | position: absolute; 155 | min-width: 100px; 156 | padding: 4px; 157 | border-radius: 4px; 158 | background-color: rgba(235, 235, 235, .75); 159 | display: none; 160 | } 161 | 162 | .pk-tooltip p { 163 | margin: 0; 164 | } -------------------------------------------------------------------------------- /peek.js: -------------------------------------------------------------------------------- 1 | /*! Peek.js (c) 2015 Mark Macdonald | http://mtmacdonald.github.io/peek/LICENSE */ 2 | 3 | function pkEscapeHtml(string) { 4 | var entityMap = { 5 | "&": "&", 6 | "<": "<", 7 | ">": ">", 8 | '"': '"', 9 | "'": ''', 10 | "/": '/' 11 | }; 12 | return String(string).replace(/[&<>"'\/]/g, function (s) { 13 | return entityMap[s]; 14 | }); 15 | } 16 | 17 | function Legend(container) { 18 | 19 | this.showGroups = false; 20 | this.hasOutline = true; 21 | this.hasOpacity = false; 22 | this.opacity = 0.6; 23 | this.width = 300; 24 | 25 | var outlineWidth = 2; 26 | var keyWidth = 22; 27 | var keyHeight = 16; 28 | 29 | this.draw = function (data) { 30 | var legendContainer = d3.select(container).attr('class', 'pk-legendContainer'); 31 | 32 | var legend = legendContainer.append("div").attr("class", "pk-legend"); 33 | legend.style('width', this.width+'px'); 34 | 35 | data.forEach(function(series, i) { 36 | var row = legend.append("div"); 37 | 38 | var keyContainer = row.append("div").attr("class", "pk-keyContainer") 39 | .insert("svg").attr('width', keyWidth).attr('height', keyHeight); 40 | 41 | var key = keyContainer.append("rect") 42 | .attr("x", 0+outlineWidth/2) 43 | .attr("y", 0+outlineWidth/2).attr("rx", 3).attr("ry", 3) 44 | .attr("width", (keyWidth - outlineWidth)) 45 | .attr("height", (keyHeight - outlineWidth)); 46 | 47 | //------------------------------------------------------------------ 48 | //apply patterns if optionally selected - see http://riccardoscalco.github.io/textures/ 49 | if (series.texture === 'diagonal') { 50 | key.style("fill", function(d) { 51 | var t = textures.lines().size(8).strokeWidth(3).stroke(series.color); 52 | keyContainer.call(t); 53 | return t.url(); 54 | }) 55 | } else if (series.texture === 'horizontal') { 56 | key.style("fill", function(d) { 57 | var t = textures.lines().orientation('horizontal').size(6).strokeWidth(3).stroke(series.color); 58 | keyContainer.call(t); 59 | return t.url(); 60 | }) 61 | } else if (series.texture === 'woven') { 62 | key.style("fill", function(d) { 63 | var t = textures.paths().d('woven').thicker().stroke(series.color); 64 | keyContainer.call(t); 65 | return t.url(); 66 | }) 67 | //------------------------------------------------------------------ 68 | } else { 69 | key.style("fill", series.color); 70 | } 71 | 72 | if (this.hasOutline === true) { 73 | key.attr("stroke", series.color ); 74 | key.style("stroke-width", outlineWidth) 75 | } 76 | if (this.hasOpacity === true) { 77 | key.style('fill-opacity', this.opacity); 78 | } 79 | 80 | var text = [], i = -1; 81 | text[++i] = pkEscapeHtml(series.label); 82 | if (this.showGroups === true) { 83 | text[++i] = ' - '+pkEscapeHtml(series.group); 84 | } 85 | if (series.units) { 86 | text[++i] = ' ('+pkEscapeHtml(series.units)+')'; 87 | }; 88 | 89 | row.append("span").html(text.join('')).attr('class', 'pk-keyText'); 90 | }, this); 91 | } 92 | } 93 | 94 | function Plot(container) { 95 | 96 | var labelHeight = 20; 97 | 98 | this.isRadial = false; 99 | this.showTitle = true; 100 | this.showXLabel = true; 101 | this.showYLabel = true; 102 | this.showY2Label = false; 103 | 104 | this.container = container; 105 | this.margin = {top: 14, right: 25, bottom: 35, left: 45}; 106 | if (this.showYLabel === true) { 107 | this.margin.right = this.margin.left; //increase the right margin when second yLabel is shown 108 | } 109 | this.width = 600; 110 | this.height = 400; 111 | this.radius = 150; //only applies to radial charts 112 | 113 | this.title = 'Chart Title'; 114 | this.xLabel = 'X Label'; 115 | this.yLabel = 'Y Label'; 116 | this.y2Label = 'Y Label 2'; 117 | 118 | this.axes = new Axes(this); 119 | 120 | this.getLabelHeight = function () { 121 | return labelHeight; 122 | } 123 | 124 | this.getSvgWidth = function() { 125 | var yLabelWidth = this.showYLabel === true ? labelHeight : 0; 126 | var plotWidth = this.width - yLabelWidth - this.margin.left - this.margin.right; 127 | return plotWidth; 128 | } 129 | 130 | this.getSvgHeight = function() { 131 | var titleHeight = this.showTitle === true ? labelHeight : 0; 132 | var xLabelHeight = this.showXLabel === true ? labelHeight : 0; 133 | var plotHeight = this.height - titleHeight - xLabelHeight - this.margin.top - this.margin.bottom; 134 | return plotHeight; 135 | } 136 | 137 | this.draw = function() { 138 | 139 | var chartContainer = d3.select(container).attr('class', 'pk-chart'); 140 | 141 | var chart = chartContainer.insert("div").attr("class", "pk-plot pk-clear-after"); 142 | /**************************************************************************************************************/ 143 | //left container with yLabel 144 | if (this.showYLabel === true) { 145 | var leftContainer = chart.insert("div").attr("class", "pk-yLabelContainer"); 146 | leftContainer.style('width', labelHeight+'px'); 147 | leftContainer.insert("div").html(pkEscapeHtml(this.yLabel)).attr("class", "pk-yLabel") 148 | .style('height', labelHeight+'px').style('line-height', labelHeight+'px') 149 | .style('width', (this.getSvgHeight()+this.margin.top+this.margin.bottom)+'px'); /*must be same as height of svg area+margins*/ 150 | } 151 | /**************************************************************************************************************/ 152 | //main container with xLabel and plot area 153 | var mainContainer = chart.insert("div").attr("class", "pk-mainContainer"); 154 | if (this.showTitle === true) { 155 | mainContainer.insert("div").html(pkEscapeHtml(this.title)).attr("class", "pk-title") 156 | .style('height', labelHeight+'px').style('line-height', labelHeight+'px'); 157 | } 158 | var svgContainer = mainContainer.insert("div").attr("class", "pk-svgContainer"); 159 | if (this.showXLabel === true) { 160 | mainContainer.insert("div").html(pkEscapeHtml(this.xLabel)).attr("class", "pk-xLabel") 161 | .style('height', labelHeight+'px').style('line-height', labelHeight+'px'); 162 | } 163 | 164 | this.svg = svgContainer.insert("svg") 165 | .attr('width', this.getSvgWidth() + this.margin.left + this.margin.right) 166 | .attr('height', this.getSvgHeight() + this.margin.top + this.margin.bottom); 167 | /**************************************************************************************************************/ 168 | //right container with second (optional) yLabel 169 | if (this.showY2Label === true) { 170 | var rightContainer = chart.insert("div").attr("class", "pk-yLabelContainer"); 171 | rightContainer.style('width', labelHeight+'px'); 172 | rightContainer.insert("div").html(pkEscapeHtml(this.y2Label)).attr("class", "pk-yLabel") 173 | .style('height', labelHeight+'px').style('line-height', labelHeight+'px') 174 | .style('width', (this.getSvgHeight()+this.margin.top+this.margin.bottom)+'px'); /*must be same as height of svg area+margins*/ 175 | } 176 | /**************************************************************************************************************/ 177 | 178 | svgContainer.on("mousemove", function() { 179 | var tooltip = d3.select(".pk-tooltip"); 180 | var coord = d3.mouse(this); 181 | tooltip.style("left", (d3.event.pageX) + "px" ); 182 | tooltip.style("top", (d3.event.pageY) + "px"); 183 | }); 184 | 185 | if (this.isRadial === false) { 186 | this.svg = this.svg.append("g") 187 | .attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")"); 188 | } else { 189 | this.svg = this.svg.append("g") 190 | .attr("transform", "translate(" + this.radius + "," + this.radius + ")"); 191 | } 192 | }; 193 | } 194 | 195 | function Axis (plot) { 196 | 197 | var plot = plot; 198 | this.show = true; 199 | this.showTicks = true; 200 | this.tickCount = 5; 201 | this.offset = 0; 202 | 203 | this.draw = function (scale, orient, ticks) { 204 | 205 | //fake x-axis: (line at bottom of chart hides the 'gaps' from the bar chart x-axis being shorter) 206 | if (orient === 'bottom') { 207 | plot.svg.append('line') 208 | .attr('x1', 0) 209 | .attr('y1', plot.getSvgHeight()) 210 | .attr('x2', plot.getSvgWidth()) 211 | .attr('y2', plot.getSvgHeight()) 212 | .attr('class', 'pk-fakeAxis'); 213 | } 214 | 215 | //real axes: 216 | var axis = d3.svg.axis() 217 | .scale(scale) 218 | .orient(orient).ticks(ticks); 219 | 220 | var rendered = plot.svg.append("g") 221 | .attr("class", "pk-axis"); 222 | 223 | if (orient === 'bottom') { 224 | var translate = this.offset+','+plot.getSvgHeight(); 225 | rendered.attr('transform', 'translate('+translate+')'); 226 | } 227 | 228 | if (orient === 'right') { 229 | var translate = plot.getSvgWidth()+',0'; 230 | rendered.attr('transform', 'translate('+translate+')'); 231 | } 232 | 233 | rendered.call(axis); 234 | } 235 | 236 | this.drawGrid = function (scale, orient) { 237 | var axis = d3.svg.axis() 238 | .scale(scale) 239 | .orient(orient).ticks(this.tickCount); 240 | 241 | if (orient === 'bottom') { 242 | plot.svg.append('g') 243 | .attr('class', 'pk-grid pk-xGrid') 244 | .attr('transform', "translate("+this.offset+"," + plot.getSvgHeight() + ")") 245 | .call(axis 246 | .tickSize(-plot.getSvgHeight(), 0, 0) 247 | .tickFormat("") 248 | ); 249 | } else { 250 | plot.svg.append('g') 251 | .attr('class', 'pk-grid pk-yGrid') 252 | .call(axis 253 | .tickSize(-plot.getSvgWidth(), 0, 0) 254 | .tickFormat('') 255 | ); 256 | } 257 | } 258 | } 259 | 260 | function Axes (plot) { 261 | 262 | var plot = plot; 263 | this.x = new Axis(plot); 264 | this.y = new Axis(plot); 265 | this.y2 = new Axis(plot); 266 | this.y2.show = false; 267 | this.y2.showTicks = false; 268 | 269 | this.draw = function(xScale, yScale, y2Scale) { 270 | if (this.x.show === true) { 271 | this.x.draw(xScale, 'bottom', 5); 272 | } 273 | if (this.y.show === true) { 274 | this.y.draw(yScale, 'left', 5); 275 | } 276 | if (this.y2.show === true) { 277 | this.y2.draw(y2Scale, 'right', 5); 278 | } 279 | }; 280 | 281 | this.drawGrid = function(xScale, yScale, y2Scale) { 282 | if (this.x.showTicks === true) { 283 | this.x.drawGrid(xScale, 'bottom'); 284 | } 285 | if (this.y.showTicks === true) { 286 | this.y.drawGrid(yScale, 'left'); 287 | } 288 | if (this.y2.show === true && this.y2.showTicks === true) { 289 | this.y.drawGrid(y2Scale, 'left'); 290 | } 291 | }; 292 | } 293 | 294 | function Lines (plot) { 295 | var data; 296 | var plot = plot; 297 | var self = this; 298 | 299 | this.visible = true; 300 | this.interpolation = 'linear'; 301 | this.lineWidth = 2; 302 | this.dualScale = false; 303 | 304 | this.init = function (dataObject) { 305 | if (this.visible === true) { 306 | data = dataObject; 307 | } 308 | } 309 | 310 | this.draw = function(xScale, yScale, y2Scale) { 311 | if (this.visible === true) { 312 | 313 | var line = d3.svg.line().interpolate(this.interpolation).x(function(d) { return xScale(d.x); }); 314 | var dualScaleLine = d3.svg.line().interpolate(this.interpolation).x(function(d) { return xScale(d.x); }); 315 | if (data.isStacked === true) { 316 | line.y(function(d) { return yScale(d.y0 + d.y); }); 317 | } else { 318 | line.y(function(d) { return yScale(d.y); }); 319 | } 320 | if (this.dualScale === true) { 321 | dualScaleLine.y(function(d) { return y2Scale(d.y); }); 322 | } 323 | 324 | data.getData().forEach(function (series) { 325 | var element = plot.svg.append("path") 326 | .attr("class", "pk-line") 327 | .style("stroke", series.color) 328 | .style("stroke-width", this.lineWidth) 329 | .attr("d", (series.dualScale === true ? dualScaleLine(series.values) : line(series.values) )); 330 | }, this); 331 | } 332 | } 333 | } 334 | 335 | function Areas (plot) { 336 | var data; 337 | var plot = plot; 338 | var self = this; 339 | 340 | this.visible = false; 341 | this.interpolation = 'linear'; 342 | this.hasOpacity = false; 343 | this.opacity = 0.6; 344 | 345 | this.init = function (dataObject) { 346 | if (this.visible === true) { 347 | data = dataObject; 348 | } 349 | } 350 | 351 | this.draw = function(xScale, yScale) { 352 | if (this.visible === true) { 353 | 354 | var area = d3.svg.area().interpolate(this.interpolation).x(function(d) { return xScale(d.x); }); 355 | if (data.isStacked === true) { 356 | area.y0(function(d) { return yScale(d.y0); }) 357 | area.y1(function(d) { return yScale(d.y0 + d.y); }); 358 | } else { 359 | area.y0(plot.getSvgHeight()) 360 | area.y1(function(d) { return yScale(d.y); }); 361 | } 362 | 363 | data.getData().forEach(function (series) { 364 | var element = plot.svg.append("path") 365 | .attr("class", "pk-area") 366 | .style("fill", series.color) 367 | .attr("d", area(series.values)); 368 | if (this.hasOpacity === true) { 369 | element.style('fill-opacity', this.opacity); 370 | } 371 | }, this); 372 | } 373 | } 374 | } 375 | 376 | function Points (plot) { 377 | var data; 378 | var self = this; 379 | var plot = plot; 380 | 381 | this.visible = false; 382 | this.size = 4; 383 | this.fill = false; 384 | this.dualScale = false; 385 | 386 | this.init = function (dataObject) { 387 | if (this.visible === true) { 388 | data = dataObject; 389 | } 390 | } 391 | 392 | this.draw = function(xScale, yScale, y2Scale) { 393 | var self = this; 394 | if (this.visible === true) { 395 | data.getData().forEach(function (series) { 396 | //------------------------------------------------------------------------------------------------------ 397 | d3.select(plot.container) 398 | .append("div") 399 | .attr("class", "pk-tooltip").html("

Tooltip

"); 400 | var color = series.color; 401 | series.values.forEach(function(value, i) { 402 | var xV = xScale(value.x); 403 | if (data.isStacked === true) { 404 | var yV = yScale(value.y0+value.y); 405 | } else if (self.dualScale && series.dualScale === true) { 406 | var yV = y2Scale(value.y); 407 | } else { 408 | var yV = yScale(value.y); 409 | } 410 | var point = plot.svg.append("circle") 411 | .datum(value) 412 | .attr("transform", "translate(" + xV + ", " + yV + ")") 413 | .attr("r", self.size) 414 | .style("stroke", series.color) 415 | .on("mouseover", self.mouseover_circle) 416 | .on("mouseout", self.mouseout_circle); 417 | if (self.fill) { 418 | point.attr("fill", series.color); 419 | } else { 420 | point.attr("fill", "white"); 421 | } 422 | }); 423 | //------------------------------------------------------------------------------------------------------ 424 | }); 425 | } 426 | } 427 | 428 | this.mouseover_circle = function(data, i) { 429 | var formatDate = d3.time.format("%A %d. %B %Y"); 430 | var circle = d3.select(this); 431 | circle.transition().duration(500).attr("r", 10); 432 | 433 | d3.select(".pk-tooltip") 434 | .style("display", "block") 435 | .style('opacity', 0) 436 | .transition().delay(200).duration(500).style('opacity', 1); 437 | 438 | d3.select(".pk-tooltip p") 439 | .html("Date: " 440 | + formatDate(new Date(data.x)) 441 | + "
" 442 | + "Value: " 443 | + data.y 444 | ); 445 | 446 | } 447 | 448 | this.mouseout_circle = function() { 449 | var circle = d3.select(this); 450 | circle.transition().duration(500).attr("r", self.size); 451 | d3.select(".pk-tooltip").style("display", "none"); 452 | } 453 | 454 | } 455 | 456 | function Bars(plot) { 457 | 458 | var plot = plot; 459 | var data; 460 | 461 | this.visible = false; 462 | this.hasOutline = true; 463 | this.outlineWidth = 2; 464 | this.hasOpacity = false; 465 | this.opacity = 0.6; 466 | 467 | var sampleCount; 468 | var groupCount; 469 | this.outerGap = 20; 470 | this.innerGap = 5; 471 | 472 | var sampleBoxWidth; 473 | var groupBoxWidth; 474 | var barWidth; 475 | 476 | this.getSampleBoxWidth = function () { 477 | return sampleBoxWidth; 478 | } 479 | 480 | this.init = function (dataObject) { 481 | if (this.visible === true) { 482 | data = dataObject; 483 | sampleCount =data.countSamples(); 484 | groupCount = data.countGroups(); 485 | 486 | sampleBoxWidth = plot.getSvgWidth() / sampleCount; 487 | groupBoxWidth = (sampleBoxWidth - (2 * this.outerGap)); 488 | barWidth = (groupBoxWidth / groupCount) - this.innerGap + (this.innerGap / groupCount); //the final bar in each groupBox should not be proceeded by a gap 489 | 490 | plot.axes.x.offset = sampleBoxWidth/2; //translate the tick to the center of sampleBox 491 | } 492 | } 493 | 494 | this.draw = function(xScale, yScale) { 495 | var self = this; 496 | if (this.visible === true) { 497 | var groups = data.getGroups(); 498 | var max = data.yExtent()[1]; //refactor 499 | 500 | data.getData().forEach(function(series, i) { 501 | series.values.forEach(function(value) { 502 | var bar = plot.svg.append("rect") 503 | .attr("class", "pk-rect-line pk-rect-area") 504 | .attr("x", function(d) { 505 | var x = xScale(value.x)+self.outerGap; 506 | //------------------------------------------------------------------------------------------ 507 | //add offset for group 508 | var offset = groups.indexOf(series.group); 509 | x += (barWidth+self.innerGap)*offset; 510 | return x; 511 | }) 512 | .attr("width", barWidth) 513 | //for y-axis, d3 has a top-left coordinate system 514 | //todo - account for line size / line overlap? 515 | .attr("y", function(d) { return plot.getSvgHeight()-yScale(max-value.y-value.y0); }) 516 | .attr("height", function(d) { return yScale(max-value.y); }); 517 | //-------------------------------------------------------------------------------------------------- 518 | //apply a patterns if optionally selected - see http://riccardoscalco.github.io/textures/ 519 | if (series.texture === 'diagonal') { 520 | bar.style("fill", function(d) { 521 | var t = textures.lines().size(8).strokeWidth(3).stroke(series.color); 522 | plot.svg.call(t); 523 | return t.url(); 524 | }) 525 | } else if (series.texture === 'horizontal') { 526 | bar.style("fill", function(d) { 527 | var t = textures.lines().orientation('horizontal').size(6).strokeWidth(3).stroke(series.color); 528 | plot.svg.call(t); 529 | return t.url(); 530 | }) 531 | } else if (series.texture === 'woven') { 532 | bar.style("fill", function(d) { 533 | var t = textures.paths().d('woven').thicker().stroke(series.color); 534 | plot.svg.call(t); 535 | return t.url(); 536 | }) 537 | //-------------------------------------------------------------------------------------------------- 538 | } else { 539 | bar.style("fill", series.color); 540 | } 541 | 542 | if (this.hasOutline === true) { 543 | bar.style("stroke", series.color); 544 | bar.style("stroke-width", this.outlineWidth); 545 | } 546 | if (this.hasOpacity === true) { 547 | bar.style('fill-opacity', this.opacity); 548 | } 549 | }, this); 550 | }, this); 551 | } 552 | } 553 | } 554 | 555 | //---------------------------------------------------------------------------------------------------------------------- 556 | 557 | function Data() { 558 | 559 | var self = this; 560 | var data; 561 | 562 | this.isStacked = false; 563 | this.isStackedByGroup = false; 564 | this.stackOffset = 'zero'; 565 | this.dualScale = false; 566 | this.xAxisType = 'time'; 567 | 568 | this.init = function(dataArray) { 569 | data = dataArray; 570 | if (this.xAxisType === 'time') { 571 | parseDates(); 572 | } else if (this.xAxisType === 'ordinal') { 573 | parseOrdinalValues(); 574 | } 575 | fetchGroups(); 576 | if (this.isStacked) { 577 | stack(); 578 | } 579 | fetchXExtent(); 580 | fetchYExtents(); 581 | } 582 | 583 | //todo - interpolate missing data points ... e.g. http://stackoverflow.com/questions/14713503 584 | 585 | this.getData = function() { 586 | return data; 587 | } 588 | 589 | //------------------------------------------------------------------------------------------------------------------ 590 | 591 | this.countSamples = function () { 592 | return data[0].values.length; //todo: don't assume each series is the same length 593 | } 594 | 595 | //------------------------------------------------------------------------------------------------------------------ 596 | 597 | var ordinalDomain = []; 598 | 599 | var parseOrdinalValues = function () { 600 | data.forEach(function (series, i) { 601 | for (var point in series.values) { 602 | if (series.values.hasOwnProperty(point)) { 603 | if (!(ordinalDomain.indexOf(series.values[point].x) > -1)) { 604 | ordinalDomain.push(series.values[point].x); 605 | } 606 | } 607 | } 608 | }); 609 | } 610 | 611 | this.getOrdinalDomain = function () { 612 | return ordinalDomain; 613 | } 614 | 615 | this.getOrdinalRange = function (barWidth) { 616 | var ordinalRange = []; 617 | for (var x = 0; x < ordinalDomain.length; x++) { 618 | ordinalRange.push(x*barWidth); 619 | } 620 | return ordinalRange; 621 | } 622 | 623 | //------------------------------------------------------------------------------------------------------------------ 624 | 625 | var parseDates = function () { 626 | var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse; 627 | data.forEach(function (series) { 628 | series.values.forEach(function (value) { 629 | value.x = parseDate(value.x); 630 | }); 631 | }); 632 | } 633 | 634 | var stack = function () { 635 | 636 | //layering code (only for stacked charts) 637 | //D3.layout.stack can't handle the metadata in the data array, so create a stripped-down data array 638 | //Note - because objects are copied by reference, modifying the objects in the stripped-down array also 639 | //modifies the original data array 640 | 641 | var stack = d3.layout.stack().offset(self.stackOffset); 642 | 643 | if (self.isStackedByGroup === true) { 644 | var groups = getGroupsWithSeries(); 645 | for (key in groups) { 646 | if (groups.hasOwnProperty(key)) { 647 | stack(groups[key]); 648 | } 649 | } 650 | } else { 651 | var stripped_data = []; 652 | data.forEach(function (series) { 653 | stripped_data.push(series.values); 654 | }); 655 | stack(stripped_data); 656 | } 657 | } 658 | 659 | //------------------------------------------------------------------------------------------------------------------ 660 | 661 | var groups = []; 662 | 663 | this.getGroups = function () { 664 | return groups; 665 | } 666 | 667 | this.countGroups = function () { 668 | return groups.length; 669 | } 670 | 671 | var fetchGroups = function () { 672 | data.forEach(function (series) { 673 | if (!(groups.indexOf(series.group) > -1)) { 674 | groups.push(series.group); 675 | } 676 | }); 677 | } 678 | 679 | var getGroupsWithSeries = function () { 680 | var groupsWithSeries = {}; 681 | groups.forEach(function (name) { 682 | groupsWithSeries[name] = []; 683 | }); 684 | data.forEach(function (series) { 685 | groupsWithSeries[series.group].push(series.values); 686 | }); 687 | return groupsWithSeries; 688 | } 689 | 690 | //------------------------------------------------------------------------------------------------------------------ 691 | 692 | var xExtent = 0; 693 | var yExtent = [0, 0]; 694 | var y2Extent = [0, 0]; 695 | 696 | this.xExtent = function () { 697 | return xExtent; 698 | } 699 | 700 | this.yExtent = function () { 701 | return yExtent; 702 | } 703 | 704 | this.y2Extent = function () { 705 | return y2Extent; 706 | } 707 | 708 | var fetchXExtent = function () { 709 | //get the min value from all series 710 | var min = d3.min(data.map(function (series) { 711 | return d3.min(series.values.map(function (point) { 712 | return point.x; 713 | })); 714 | })); 715 | //get the max value from all series 716 | var max = d3.max(data.map(function (series) { 717 | return d3.max(series.values.map(function (point) { 718 | return point.x; 719 | })); 720 | })); 721 | xExtent = [min, max]; 722 | } 723 | 724 | var fetchYExtents = function () { 725 | var min = 0; 726 | var max = 0; 727 | var dualMin = 0; 728 | var dualMax = 0; 729 | 730 | //Min------------------------------------------------------------------------------------------------------------------- 731 | 732 | //min is either the min value from all series, or 0, whichever is lower 733 | var min = d3.min(data.map(function (series) { 734 | if (self.dualScale === true && series.dualScale !== true) { 735 | return d3.min(series.values.map(function (point) { 736 | return point.y; 737 | })); 738 | } else { 739 | return d3.min(series.values.map(function (point) { 740 | return point.y; 741 | })); 742 | } 743 | })); 744 | var dualMin = d3.min(data.map(function (series) { 745 | if (series.dualScale === true) { 746 | return d3.min(series.values.map(function (point) { 747 | return point.y; 748 | })); 749 | } 750 | })); 751 | if (min > 0) { 752 | min = 0; 753 | } 754 | if (dualMin > 0) { 755 | dualMin = 0; 756 | } 757 | 758 | //Max------------------------------------------------------------------------------------------------------------------- 759 | 760 | //max depends on whether series are not stacked, stacked, or grouped and stacked 761 | //we do not handle dual y-axes for stacked charts 762 | if (self.isStacked) { //if stacked, get max of y0+y in the final data series 763 | var max = 0; 764 | var groups = getGroupsWithSeries(); 765 | for (key in groups) { 766 | if (groups.hasOwnProperty(key)) { 767 | var lastSeriesInGroup = groups[key][groups[key].length-1]; 768 | var localMax = d3.max(lastSeriesInGroup.map(function (point) { 769 | return point.y0+point.y; 770 | })); 771 | if (localMax > max) { 772 | max = localMax; 773 | } 774 | } 775 | } 776 | 777 | //if not stacked but dual scale, get the max value by series 778 | } else if (self.dualScale) { 779 | var max = d3.max(data.map(function (series) { 780 | if (series.dualScale !== true) { 781 | return d3.max(series.values.map(function (point) { 782 | return point.y; 783 | })); 784 | } else { 785 | return 0; 786 | } 787 | })); 788 | var dualMax = d3.max(data.map(function (series) { 789 | if (series.dualScale === true) { 790 | return d3.max(series.values.map(function (point) { 791 | return point.y; 792 | })); 793 | } else { 794 | return 0; 795 | } 796 | })); 797 | //if not stacked and not dual scale, get the max value from all series 798 | } else { 799 | var max = d3.max(data.map(function (series) { 800 | return d3.max(series.values.map(function (point) { 801 | return point.y; 802 | })); 803 | })); 804 | } 805 | 806 | //---------------------------------------------------------------------------------------------------------------------- 807 | 808 | yExtent = [min, max]; 809 | if (self.dualScale === true) { 810 | y2Extent = [dualMin, dualMax]; 811 | } 812 | } 813 | 814 | } 815 | 816 | function Cartesian(container) { 817 | 818 | var self = this; 819 | 820 | this.data = new Data(); 821 | this.plot = new Plot(container); 822 | this.lines = new Lines(this.plot); 823 | this.points = new Points(this.plot); 824 | this.areas = new Areas(this.plot); 825 | this.bars = new Bars(this.plot); 826 | this.dualScale = false; 827 | 828 | //x-axis scale type 829 | this.xAxisType = 'time'; 830 | 831 | this.draw = function (dataArray) { 832 | 833 | //is this a dual scale chart? 834 | if (this.dualScale === true) { 835 | this.plot.showY2Label = true; 836 | this.plot.axes.y2.show = true; 837 | this.data.dualScale = true; 838 | this.lines.dualScale = true; 839 | this.points.dualScale = true; 840 | } 841 | 842 | if (this.bars.visible === true) { 843 | this.data.isStackedByGroup = true; //bar charts are always stacked by group 844 | } 845 | 846 | this.data.xAxisType = this.xAxisType; 847 | this.data.init(dataArray); 848 | 849 | this.plot.draw(); 850 | 851 | if (this.bars.visible === true) { 852 | this.bars.init(this.data); 853 | } 854 | if (this.lines.visible === true) { 855 | this.lines.init(this.data); 856 | } 857 | if (this.points.visible === true) { 858 | this.points.init(this.data); 859 | } 860 | if (this.areas.visible === true) { 861 | this.areas.init(this.data); 862 | } 863 | 864 | if (this.xAxisType === 'linear') { 865 | if (this.bars.visible === true) { 866 | var xScale = d3.scale.linear().range([0, this.plot.getSvgWidth()-this.bars.getSampleBoxWidth()]); 867 | } else { 868 | var xScale = d3.scale.linear().range([0, this.plot.getSvgWidth()]); 869 | } 870 | xScale.domain(this.data.xExtent()); 871 | } else if (this.xAxisType === 'ordinal') { 872 | var barWidth = this.bars.getSampleBoxWidth(); 873 | var xScale = d3.scale.ordinal().range(this.data.getOrdinalRange(barWidth)); 874 | xScale.domain(this.data.getOrdinalDomain()); 875 | } else if (this.xAxisType === 'time') { 876 | if (this.bars.visible === true) { 877 | var xScale = d3.time.scale().range([0, this.plot.getSvgWidth()-this.bars.getSampleBoxWidth()]); 878 | } else { 879 | var xScale = d3.time.scale().range([0, this.plot.getSvgWidth()]); 880 | } 881 | xScale.domain(this.data.xExtent()); 882 | } 883 | 884 | var yScale = d3.scale.linear().range([this.plot.getSvgHeight(), 0]); 885 | yScale.domain(this.data.yExtent()); 886 | if (this.dualScale === true) { 887 | var y2Scale = d3.scale.linear().range([this.plot.getSvgHeight(), 0]); 888 | y2Scale.domain(this.data.y2Extent()); 889 | } 890 | 891 | this.plot.axes.drawGrid(xScale, yScale, y2Scale); 892 | if (this.bars.visible === true) { 893 | this.bars.draw(xScale, yScale); 894 | } 895 | if (this.lines.visible === true) { 896 | this.lines.draw(xScale, yScale, y2Scale); 897 | } 898 | if (this.areas.visible === true) { 899 | this.areas.draw(xScale, yScale); 900 | } 901 | this.plot.axes.draw(xScale, yScale, y2Scale); 902 | if (this.points.visible === true) { 903 | this.points.draw(xScale, yScale, y2Scale); 904 | } 905 | } 906 | } 907 | 908 | function HorizontalBar(container) { 909 | 910 | var self = this; 911 | 912 | this.barHeight = 60; 913 | this.barSpacing = 10; 914 | this.hasOutline = true; 915 | this.outlineWidth = 2; 916 | this.hasOpacity = false; 917 | this.opacity = 0.6; 918 | 919 | this.plot = new Plot(container); 920 | this.plot.showTitle = false; 921 | this.plot.showXLabel = false; 922 | this.plot.showYLabel = false; 923 | this.plot.margin.top = 0; 924 | this.plot.margin.right = 0; 925 | this.plot.margin.bottom = 0; 926 | this.plot.margin.left = 0; 927 | 928 | var getMaxLabelWidth = function (data) { 929 | var longestLabel = 0; 930 | var longestRowIndex = 0; 931 | data.forEach(function(row, index) { 932 | if (longestLabel < row.label.length) { 933 | longestLabel = row.label.length; 934 | longestRowIndex = index; 935 | } 936 | }); 937 | var fakeLabel = self.plot.svg.append("text") 938 | .attr("x", 0) 939 | .attr("y", 0) 940 | .style("visibility", "hidden") 941 | .text(data[longestRowIndex].label); 942 | var result = fakeLabel.node().getComputedTextLength(); 943 | fakeLabel.remove(); 944 | return result; 945 | } 946 | 947 | this.draw = function (data) { 948 | var self = this; 949 | 950 | //dynamically set the plot height based on the length of the input data 951 | this.plot.height = data.length*(this.barHeight+this.barSpacing); 952 | this.plot.draw(); 953 | 954 | //dynamically find the space needed for labels, from the maximum label width 955 | var maxLabelWidth = getMaxLabelWidth(data); 956 | var rightPadding = maxLabelWidth+10; 957 | 958 | var max = d3.max(data, function(d) { return d.value;} ); 959 | 960 | var dx = (this.plot.width - rightPadding) / max; 961 | var dy = (this.plot.height / data.length) - (this.barSpacing); 962 | 963 | //bars 964 | var bars = this.plot.svg.selectAll(".bar") 965 | .data(data) 966 | .enter() 967 | .append("rect") 968 | .attr("x", function(d, i) {return self.outlineWidth-1;}) 969 | .attr("y", function(d, i) {return dy*i + self.barSpacing*i +(self.outlineWidth-1);}) 970 | .attr("width", function(d, i) {return dx*d.value}) 971 | .attr("height", dy) 972 | .attr("fill", function(d, i) {return d.color} ); 973 | if (this.hasOutline === true) { 974 | bars.style("stroke", function(d, i) {return d.color}); 975 | bars.style("stroke-width", this.outlineWidth); 976 | } 977 | if (this.hasOpacity === true) { 978 | bars.style('fill-opacity', this.opacity); 979 | } 980 | //labels 981 | var text = this.plot.svg.selectAll("text") 982 | .data(data) 983 | .enter() 984 | .append("text") 985 | .attr('class', 'pk-label') 986 | .attr("x", function(d, i) {return (dx*d.value)+5}) 987 | .attr("y", function(d, i) {return dy*i + self.barSpacing*i + (dy/2) + 4 + self.outlineWidth;}) //4 accounts for text height 988 | .text( function(d) {return pkEscapeHtml(d.label);}); 989 | 990 | //text values 991 | var text = this.plot.svg.selectAll(".compare-chart-values") 992 | .data(data) 993 | .enter() 994 | .append("text") 995 | .attr('class', 'compare-chart-values') 996 | .text( function(d) { return d.value.toFixed(2); }) 997 | .attr("x", function(d, i) { 998 | //position the values just left of the end of the bars 999 | var width = this.getComputedTextLength() + 10; 1000 | return (dx*d.value)-(width); 1001 | }) 1002 | .attr("y", function(d, i) {return dy*i + self.barSpacing*i + (dy/2) + 4 + self.outlineWidth;}) //4 accounts for text height 1003 | .style("display", function(d, i){ 1004 | //only display the values when there is space inside the bar 1005 | var width = this.getComputedTextLength() + 10; 1006 | if (dx*d.value < width) { 1007 | return "none"; 1008 | } else { 1009 | return "initial"; 1010 | } 1011 | }) 1012 | .style("font-weight", "bold") 1013 | .attr("fill", "white"); 1014 | 1015 | }; 1016 | } 1017 | 1018 | function Radial(container) { 1019 | 1020 | this.radius = 150; 1021 | this.innerRadius = 60; 1022 | this.hasOutline = false; 1023 | this.outlineWidth = 2; 1024 | this.hasOpacity = false; 1025 | this.opacity = 0.6; 1026 | 1027 | this.plot = new Plot(container); 1028 | this.plot.isRadial = true; 1029 | this.plot.showTitle = false; 1030 | this.plot.showXLabel = false; 1031 | this.plot.showYLabel = false; 1032 | 1033 | this.draw = function (data) { 1034 | 1035 | //---------------------------------------------------------------- 1036 | //decrease the radius if the title or labels are enabled 1037 | if (this.plot.showXLabel === true || this.plot.showYLabel === true) { 1038 | this.radius = this.radius - this.plot.getLabelHeight(); 1039 | } 1040 | if (this.showTitle === true) { 1041 | this.radius = this.radius - this.plot.getLabelHeight(); 1042 | } 1043 | this.plot.radius = this.radius; 1044 | 1045 | //---------------------------------------------------------------- 1046 | //adjust the plot dimensions if the title or labels are enabled 1047 | var xOffset = 0; 1048 | var yOffset = 0; 1049 | if (this.plot.showTitle === true) { 1050 | yOffset += this.plot.getLabelHeight(); 1051 | } 1052 | if (this.plot.showXLabel === true) { 1053 | yOffset += this.plot.getLabelHeight(); 1054 | } 1055 | if (this.plot.showYLabel === true) { 1056 | xOffset += this.plot.getLabelHeight(); 1057 | } 1058 | this.plot.width = this.radius*2 + xOffset; 1059 | this.plot.height = this.radius*2 + yOffset; 1060 | 1061 | //---------------------------------------------------------------- 1062 | //draw plot area 1063 | var outerRadius = this.radius; 1064 | if (this.hasOutline === true) { 1065 | outerRadius = this.radius - this.outlineWidth; 1066 | } 1067 | this.arc = d3.svg.arc().outerRadius(outerRadius).innerRadius(this.innerRadius); 1068 | this.pie = d3.layout.pie().sort(null).value(function(d) { return d.value }); 1069 | 1070 | this.plot.draw(); 1071 | 1072 | this.plot.svg.data([data]); 1073 | 1074 | //---------------------------------------------------------------- 1075 | //explicitly check that not all data values are 0, else D3 throws an invalid value error: http://stackoverflow.com/questions/19933581 1076 | var total = 0; 1077 | data.forEach( function (segment) { 1078 | total += segment.value; 1079 | }); 1080 | if (total !== 0 && total !== null && !isNaN(total)) { 1081 | this.render(data); 1082 | } 1083 | } 1084 | 1085 | this.render = function (data) { 1086 | var self = this; 1087 | var arcs = this.plot.svg.selectAll("g.slice") 1088 | .data(self.pie) 1089 | .enter() 1090 | .append("svg:g") 1091 | .attr("class", "slice"); 1092 | 1093 | var segments = arcs.append("svg:path"); 1094 | if (this.hasOutline === true) { 1095 | segments.attr("stroke", function(d, i) { return data[i].color; } ); 1096 | segments.style("stroke-width", this.outlineWidth); 1097 | } 1098 | segments.attr("fill", function(d, i) { return data[i].color; } ); 1099 | if (this.hasOpacity === true) { 1100 | segments.style('fill-opacity', this.opacity); 1101 | } 1102 | segments.attr("d", self.arc); 1103 | 1104 | arcs.append("svg:text") 1105 | .attr("transform", function(d) { 1106 | d.innerRadius = 0; 1107 | d.outerRadius = self.radius; 1108 | return "translate(" + self.arc.centroid(d) + ")"; 1109 | }) 1110 | .attr("text-anchor", "middle") 1111 | .text(function(d, i) { 1112 | var value = data[i].value; 1113 | if (value > 3.0) { 1114 | return Math.round(data[i].value)+'%'; 1115 | } 1116 | }); 1117 | }; 1118 | } -------------------------------------------------------------------------------- /require/fonts/DroidSansMono.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtmacdonald/peek/d4e1bb4ae3c803991b945eb640daefb65a097a2a/require/fonts/DroidSansMono.woff -------------------------------------------------------------------------------- /require/fonts/OpenSans.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtmacdonald/peek/d4e1bb4ae3c803991b945eb640daefb65a097a2a/require/fonts/OpenSans.woff -------------------------------------------------------------------------------- /require/fonts/OpenSansBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtmacdonald/peek/d4e1bb4ae3c803991b945eb640daefb65a097a2a/require/fonts/OpenSansBold.woff -------------------------------------------------------------------------------- /require/fonts/OpenSansBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtmacdonald/peek/d4e1bb4ae3c803991b945eb640daefb65a097a2a/require/fonts/OpenSansBoldItalic.woff -------------------------------------------------------------------------------- /require/fonts/OpenSansItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtmacdonald/peek/d4e1bb4ae3c803991b945eb640daefb65a097a2a/require/fonts/OpenSansItalic.woff -------------------------------------------------------------------------------- /require/framework.min.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";/*! 2 | Webknife (c) 2014 The Webknife Project | http://mtmacdonald.github.io/webknife/LICENSE 3 | */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}a:focus,button:focus,input[type=button]:focus,input[type=submit]:focus{color:#4b91ff!important;outline:0}.w-clear,.w-clear-after::after,header::after{clear:both;height:0;visibility:hidden;display:block;content:" "}.w-left{text-align:left;display:block;margin-left:0;margin-right:auto}.w-right{text-align:right;display:block;margin-left:auto;margin-right:0}.w-center{text-align:center;display:block;margin-left:auto;margin-right:auto}.w-inline{display:inline}#w-browser-warning{text-align:center}.w-invisible{display:none}html{background-color:#385691;color:#444}html body{min-width:1020px}html body .w-fixed-width{width:980px;margin:0 auto}header{color:#385691;padding:30px 0;background-color:#fff;border-top:2px solid #385691;border-bottom:2px solid #385691}header .w-false-link,header .w-false-link:hover,header a,header a:active,header a:hover,header a:visited{color:#385691}header>div>a{float:left;text-decoration:none;font-weight:700;font-size:16px}header>div>a div{background-repeat:no-repeat;height:42px;line-height:42px;padding-left:115px}header>div>div{float:right;height:42px;line-height:42px}footer div{padding:15px 0}footer>div:first-child{background-color:#ddd;border-top:2px solid #bbb;border-bottom:2px solid #bbb}footer>div:nth-child(2){color:#fff;text-align:center;line-height:35px}footer>div:nth-child(2) .w-false-link,footer>div:nth-child(2) .w-false-link:hover,footer>div:nth-child(2) a,footer>div:nth-child(2) a:active,footer>div:nth-child(2) a:hover,footer>div:nth-child(2) a:visited{color:#fff}footer>div:nth-child(2)>p:nth-child(2){font-size:10px;line-height:12px}section{background-color:#fff;padding:25px 0}section>div blockquote,section>div div,section>div ol,section>div p,section>div pre,section>div table,section>div ul{margin:20px 0}@font-face{font-family:open-sans;src:url(fonts/OpenSans.woff) format('woff');font-weight:400;font-style:normal}@font-face{font-family:open-sans;src:url(fonts/OpenSansBold.woff) format('woff');font-weight:700;font-style:normal}@font-face{font-family:open-sans;src:url(fonts/OpenSansItalic.woff) format('woff');font-weight:400;font-style:italic}@font-face{font-family:open-sans;src:url(fonts/OpenSansBoldItalic.woff) format('woff');font-weight:700;font-style:italic}@font-face{font-family:droid-sans-mono;src:url(fonts/DroidSansMono.woff) format('woff');font-weight:400;font-style:normal}body{font-family:open-sans,Arial,sans-serif;font-size:14px;line-height:20px}.w-small{font-size:12px}.w-large{font-size:18px}.w-massive{font-size:34px}.w-bold{font-weight:700}.w-information-text{color:#001f8a}.w-success-text{color:#218900}.w-warning-text{color:#8a6b00}.w-error-text{color:#b30000}.w-de-emphasised-text{color:#bbb}.w-false-link,.w-link-button,a{color:#385691}.w-false-link:hover,.w-link-button:hover,a:hover{color:#809ace;text-decoration:none}a:active{background:0 0}a:visited{color:#809ace}.w-false-link,.w-link-button{text-decoration:underline;cursor:pointer}.w-message{border-radius:5px}.w-success{background-color:#ccffbc;border:1px solid #218900;padding:10px;color:#218900}.w-success .w-false-link,.w-success .w-false-link:hover,.w-success a,.w-success a:active,.w-success a:hover,.w-success a:visited{color:#218900}.w-warning{background-color:#fff0bd;border:1px solid #8a6b00;padding:10px;color:#8a6b00}.w-warning .w-false-link,.w-warning .w-false-link:hover,.w-warning a,.w-warning a:active,.w-warning a:hover,.w-warning a:visited{color:#8a6b00}.w-error{background-color:#ffe6e6;border:1px solid #b30000;padding:10px;color:#b30000}.w-error .w-false-link,.w-error .w-false-link:hover,.w-error a,.w-error a:active,.w-error a:hover,.w-error a:visited{color:#b30000}.w-information{background-color:#bdccff;border:1px solid #001f8a;padding:10px;color:#001f8a}.w-information .w-false-link,.w-information .w-false-link:hover,.w-information a,.w-information a:active,.w-information a:hover,.w-information a:visited{color:#001f8a}h1,h2,h3,h4,h5,h6{text-decoration:none;font-weight:700;color:#385691;border-bottom:1px solid #999;margin:20px 0}h1{font-size:20px;padding-bottom:6px}h2{font-size:18px;padding-bottom:4px}h3{font-size:16px;padding-bottom:4px}h4{font-size:14px;padding-bottom:3px}h5{font-size:13px;padding-bottom:2px}h6{font-size:12px;padding-bottom:2px}.w-no-underline{border-bottom:none}ol,ul{padding-left:15px}ul{list-style-type:disc}ol{list-style-type:decimal}li.list-heading{position:relative;left:-15px;list-style-type:none;font-weight:700}section>div ol ol,section>div ul ul{margin:0}blockquote{padding:10px 10px 10px 6px;border-left:5px solid #bbb;background-color:#ddd}code{font-family:droid-sans-mono,Courier,monospace}pre{padding:12px;background-color:#222;border:1px solid #999;line-height:14px;border-radius:6px}.w-inline-code{background-color:#222;vertical-align:middle;display:inline-block!important;padding:2px!important;border-radius:2px}.w-table{width:700px}.w-table td,.w-table th{border:1px solid #999;padding:2px 15px;height:25px;vertical-align:middle}.w-table tfoot td,.w-table th{background-color:#ddd;font-weight:700}.w-table caption{caption-side:bottom;font-weight:700;padding:15px}.w-table.w-fixed{table-layout:fixed;word-wrap:break-word}.w-table.w-stripe tbody tr:nth-of-type(2n){background-color:#eee}.w-table td.w-center,.w-table th.w-center{display:table-cell}a.w-button-link,button,input[type=button],input[type=submit]{box-sizing:border-box;vertical-align:middle;height:36px;cursor:pointer;padding:0 9px;font-family:open-sans,Arial,sans-serif;font-size:12px;font-weight:700;border-radius:4px;border:1px solid #d4d4d4;color:#444;background-color:#eee;box-shadow:inset 0 1px 4px #fff}a.w-button-link:not([disabled]):hover,button:not([disabled]):hover,input[type=button]:not([disabled]):hover,input[type=submit]:not([disabled]):hover{background-color:#eee;border-color:#bbb;box-shadow:0 1px 1px #bbb}a.w-button-link:not([disabled]):active,button:not([disabled]):active,input[type=button]:not([disabled]):active,input[type=submit]:not([disabled]):active{border-color:#888}a.w-button-link.w-dark,button.w-dark,input[type=button].w-dark,input[type=submit].w-dark{border:1px solid #a2a2a2;color:#444;background-color:#bbb;box-shadow:inset 0 1px 4px #d4d4d4}a.w-button-link.w-dark:not([disabled]):hover,button.w-dark:not([disabled]):hover,input[type=button].w-dark:not([disabled]):hover,input[type=submit].w-dark:not([disabled]):hover{background-color:#bcbaba;border-color:#888;box-shadow:0 1px 1px #bbb}a.w-button-link.w-dark:not([disabled]):active,button.w-dark:not([disabled]):active,input[type=button].w-dark:not([disabled]):active,input[type=submit].w-dark:not([disabled]):active{border-color:#555}a.w-button-link.w-colored,button.w-colored,input[type=button].w-colored,input[type=submit].w-colored{border:1px solid #2a406c;color:#fff;background-color:#385691;box-shadow:inset 0 1px 4px #466cb6}a.w-button-link.w-colored:not([disabled]):hover,button.w-colored:not([disabled]):hover,input[type=button].w-colored:not([disabled]):hover,input[type=submit].w-colored:not([disabled]):hover{background-color:#375692;border-color:#1c2a47;box-shadow:0 1px 1px #bbb}a.w-button-link.w-colored:not([disabled]):active,button.w-colored:not([disabled]):active,input[type=button].w-colored:not([disabled]):active,input[type=submit].w-colored:not([disabled]):active{border-color:#000}a.w-button-link.w-small,button.w-small,input[type=button].w-small,input[type=submit].w-small{height:22px;padding:0 6px}a.w-button-link.w-large,button.w-large,input[type=button].w-large,input[type=submit].w-large{height:52px;font-size:16px;padding:0 20px;border-width:2px;border-radius:8px}a.w-button-link.w-flat,button.w-flat,input[type=button].w-flat,input[type=submit].w-flat{border-bottom-left-radius:0;border-bottom-right-radius:0}a.w-button-link:disabled,button:disabled,input[type=button]:disabled,input[type=submit]:disabled{cursor:default;border:1px solid #d4d4d4;color:#bbb;background-color:#eee;box-shadow:inset 0 1px 4px #fff}a.w-button-link:disabled:not([disabled]):hover,button:disabled:not([disabled]):hover,input[type=button]:disabled:not([disabled]):hover,input[type=submit]:disabled:not([disabled]):hover{background-color:#eee;border-color:#bbb;box-shadow:0 1px 1px #bbb}a.w-button-link:disabled:not([disabled]):active,button:disabled:not([disabled]):active,input[type=button]:disabled:not([disabled]):active,input[type=submit]:disabled:not([disabled]):active{border-color:#888}a.w-button-link{display:inline-block;text-decoration:none;line-height:34px}a.w-button-link.w-small{line-height:20px}a.w-button-link.w-large{line-height:45px}.w-button-link:active,.w-button-link:hover{color:#444}.w-button-link:active.w-colored,.w-button-link:hover.w-colored{color:#fff}button.w-link-button{display:inline;border:none;border-radius:0;margin:0;padding:0;font:inherit;height:auto;line-height:20px;-moz-user-select:text;background:0 0}button.w-link-button:active,button.w-link-button:hover{background:0 0;box-shadow:none}.w-tab{list-style:none;padding:0;margin:0}.w-tab li{float:left;margin-right:5px;font-size:20px;display:block;background-color:#eee;margin-bottom:-1px;border:1px solid #999;border-width:1px;position:relative;color:#a2a2a2;border-top-left-radius:8px;border-top-right-radius:8px}.w-tab li.w-active{background-color:#fff;top:1px;border-bottom:0}.w-tab li.w-active a,.w-tab li.w-active span{color:#444;font-weight:700}.w-tab li.w-active .w-icon>svg{fill:#444}.w-tab li:hover{cursor:pointer;background-color:#ddd}.w-tab li.w-active:hover{cursor:text;background-color:#fff}.w-tab li.w-disabled:hover{cursor:text;background-color:#eee}.w-tab li span{display:inline-block;padding:10px 8px}.w-tab li a{color:#a2a2a2;text-decoration:none}.w-tab-content{border:1px solid #999;padding:15px;margin:0}.w-tab::after{clear:both;height:0;visibility:hidden;display:block;content:""}.w-tab .w-disabled .w-icon,.w-tab li a .w-icon{display:inline-block;float:left;width:28px;height:28px;padding:6px 4px 0 6px;margin:0}.w-tab .w-disabled .w-icon>svg,.w-tab li a .w-icon>svg{fill:#a2a2a2}.w-tab .w-disabled .w-icon+a,.w-tab .w-disabled .w-icon+span,.w-tab li a .w-icon+a,.w-tab li a .w-icon+span{padding-left:0}.w-tab .w-disabled .w-icon>svg{cursor:text}.w-breadcrumb-container{border:1px solid #999;background-color:#ddd;height:40px;box-sizing:border-box}.w-breadcrumb,.w-breadcrumb-right{background:#ddd;overflow:hidden;list-style-type:none;padding:0;margin:0!important;height:38px}.w-breadcrumb,.w-breadcrumb li{float:left}.w-breadcrumb-right,.w-breadcrumb-right li{float:right}.w-breadcrumb a,.w-breadcrumb-right a{float:left;text-decoration:none;color:#444;position:relative;box-sizing:border-box;height:38px;line-height:38px}.w-breadcrumb a{background-color:#bbb;padding:0 0 0 32px}.w-breadcrumb-right a{padding:0 12px}.w-breadcrumb li:first-child a{padding-left:12px}.w-breadcrumb li a:hover,.w-breadcrumb-right li a:hover{background:#eee}.w-breadcrumb li a::after,.w-breadcrumb li a::before{content:"";position:absolute;top:50%;margin-top:-30px;border-top:30px solid transparent;border-bottom:30px solid transparent;left:100%}.w-breadcrumb li a:after{z-index:2;border-left:20px solid #bbb}.w-breadcrumb li a:before{border-left:20px solid #999;margin-left:1px;z-index:1}.w-breadcrumb li a:hover::after{border-left-color:#eee}.w-breadcrumb li:last-child a{background:0 0;font-weight:700;cursor:default}.w-breadcrumb li:last-child a::after,.w-breadcrumb li:last-child a::before{content:normal}.w-paginator{padding-left:0}.w-paginator>li{display:inline}.pika-single{z-index:9999;display:block;position:relative;color:#333;background:#fff;border:1px solid #ccc;border-bottom-color:#bbb}.pika-single:after,.pika-single:before{content:" ";display:table}.pika-single:after{clear:both}.pika-single.is-hidden{display:none}.pika-single.is-bound{position:absolute;box-shadow:0 5px 15px -5px rgba(0,0,0,.5)}.pika-lendar{float:left;width:240px;margin:8px}.pika-title{position:relative;text-align:center}.pika-label{display:inline-block;position:relative;z-index:9999;overflow:hidden;margin:0;padding:5px 3px;font-size:14px;line-height:20px;font-weight:700;background-color:#fff}.pika-title select{cursor:pointer;position:absolute;z-index:9998;margin:0;left:0;top:5px;filter:alpha(opacity=0);opacity:0}.pika-next,.pika-prev{display:block;cursor:pointer;position:relative;outline:0;border:0;padding:0;width:20px;height:30px;text-indent:20px;white-space:nowrap;overflow:hidden;background-color:transparent;background-position:center center;background-repeat:no-repeat;background-size:75% 75%;opacity:.5}.pika-next:hover,.pika-prev:hover{opacity:1}.is-rtl .pika-next,.pika-prev{float:left;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==)}.is-rtl .pika-prev,.pika-next{float:right;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=)}.pika-next.is-disabled,.pika-prev.is-disabled{cursor:default;opacity:.2}.pika-select{display:inline-block}.pika-table{width:100%;border-collapse:collapse;border-spacing:0;border:0}.pika-table td,.pika-table th{width:14.28571%;padding:0}.pika-table th{color:#999;font-size:12px;line-height:25px;font-weight:700;text-align:center}.pika-button{cursor:pointer;display:block;box-sizing:border-box;-moz-box-sizing:border-box;outline:0;border:0;margin:0;width:100%;padding:5px;color:#666;font-size:12px;line-height:15px;text-align:right;background:#f5f5f5}.pika-week{font-size:11px;color:#999}.is-today .pika-button{color:#3af;font-weight:700}.is-selected .pika-button{color:#fff;font-weight:700;background:#3af;box-shadow:inset 0 1px 3px #178fe5;border-radius:3px}.is-disabled .pika-button{pointer-events:none;cursor:default;color:#999;opacity:.3}.pika-button:hover{color:#fff!important;background:#ff8000!important;box-shadow:none!important;border-radius:3px!important}.pika-table abbr{border-bottom:none}.chosen-container{position:relative;display:inline-block;vertical-align:middle;font-size:13px;zoom:1;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.chosen-container *{box-sizing:border-box}.chosen-container .chosen-drop{position:absolute;top:100%;left:-9999px;z-index:1010;width:100%;border:1px solid #aaa;border-top:0;background:#fff;box-shadow:0 4px 5px rgba(0,0,0,.15)}.chosen-container.chosen-with-drop .chosen-drop{left:0}.chosen-container a{cursor:pointer}.chosen-container-single .chosen-single{position:relative;display:block;overflow:hidden;border-radius:5px;background:linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background-clip:padding-box;color:#444;text-decoration:none;white-space:nowrap}.chosen-container-single .chosen-default{color:#999}.chosen-container-single .chosen-single span{display:block;overflow:hidden;margin-right:26px;text-overflow:ellipsis;white-space:nowrap}.chosen-container-single .chosen-single-with-deselect span{margin-right:38px}.chosen-container-single .chosen-single abbr{position:absolute;top:6px;right:26px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-single .chosen-single abbr:hover,.chosen-container-single.chosen-disabled .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single .chosen-single div{position:absolute;right:0;display:block;width:18px;height:100%}.chosen-container-single .chosen-single div b{display:block;width:100%;height:100%;background:url(chosen-sprite.png) 0 2px no-repeat}.chosen-container-single .chosen-search{position:relative;z-index:1010;margin:0;padding:3px 4px;white-space:nowrap}.chosen-container-single .chosen-search input[type=text]{margin:1px 0;padding:4px 20px 4px 5px;width:100%;height:auto;outline:0;border:1px solid #aaa;background:url(chosen-sprite.png) 100% -20px no-repeat;font-size:1em;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-single .chosen-drop{margin-top:-1px;border-radius:0 0 4px 4px;background-clip:padding-box}.chosen-container-single.chosen-container-single-nosearch .chosen-search{position:absolute;left:-9999px}.chosen-container .chosen-results{color:#444;position:relative;overflow-x:hidden;overflow-y:auto;max-height:240px;-webkit-overflow-scrolling:touch}.chosen-container .chosen-results li{display:none;margin:0;padding:5px 6px;list-style:none;line-height:15px;word-wrap:break-word;-webkit-touch-callout:none}.chosen-container .chosen-results li.active-result{display:list-item;cursor:pointer}.chosen-container .chosen-results li.disabled-result{display:list-item;color:#ccc;cursor:default}.chosen-container .chosen-results li.highlighted{background-color:#3875d7;background-image:linear-gradient(#3875d7 20%,#2a62bc 90%);color:#fff}.chosen-container .chosen-results li.no-results{color:#777;display:list-item;background:#f4f4f4}.chosen-container .chosen-results li.group-result{display:list-item;font-weight:700;cursor:default}.chosen-container .chosen-results li.group-option{padding-left:15px}.chosen-container .chosen-results li em{font-style:normal;text-decoration:underline}.chosen-container-multi .chosen-choices{position:relative;overflow:hidden;margin:0;width:100%;height:auto!important;height:1%;background-color:#fff;cursor:text}.chosen-container-multi .chosen-choices li{float:left;list-style:none}.chosen-container-multi .chosen-choices li.search-field{margin:0;padding:0;white-space:nowrap}.chosen-container-multi .chosen-choices li.search-field input[type=text]{margin:1px 0;padding:0;height:25px;outline:0;border:0!important;background:0 0!important;box-shadow:none;color:#999;font-size:100%;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-multi .chosen-choices li.search-choice{position:relative;margin:3px 5px 3px 0;padding:3px 20px 3px 5px;border:1px solid #aaa;max-width:100%;border-radius:3px;background-color:#eee;background-image:linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-size:100% 19px;background-repeat:repeat-x;background-clip:padding-box;box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,.05);color:#333;line-height:13px;cursor:default}.chosen-container-multi .chosen-choices li.search-choice span{word-wrap:break-word}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close{position:absolute;top:4px;right:3px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover{background-position:-42px -10px}.chosen-container-multi .chosen-choices li.search-choice-disabled{padding-right:5px;border:1px solid #ccc;background-color:#e4e4e4;background-image:linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);color:#666}.chosen-container-multi .chosen-choices li.search-choice-focus{background:#d4d4d4}.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close{background-position:-42px -10px}.chosen-container-multi .chosen-results{margin:0;padding:0}.chosen-container-multi .chosen-drop .result-selected{display:list-item;color:#ccc;cursor:default}.chosen-container-active .chosen-single{border:1px solid #5897fb}.chosen-container-active.chosen-with-drop .chosen-single{border:1px solid #aaa}.chosen-container-active.chosen-with-drop .chosen-single div{border-left:none;background:0 0}.chosen-container-active.chosen-with-drop .chosen-single div b{background-position:-18px 2px}.chosen-container-active .chosen-choices{border:1px solid #5897fb}.chosen-container-active .chosen-choices li.search-field input[type=text]{color:#222!important}.chosen-disabled{opacity:.5!important;cursor:default}.chosen-disabled .chosen-choices .search-choice .search-choice-close,.chosen-disabled .chosen-single{cursor:default}.chosen-rtl{text-align:right}.chosen-rtl .chosen-single{overflow:visible;padding:0 8px 0 0}.chosen-rtl .chosen-single span{margin-right:0;margin-left:26px;direction:rtl}.chosen-rtl .chosen-single-with-deselect span{margin-left:38px}.chosen-rtl .chosen-single div{right:auto;left:3px}.chosen-rtl .chosen-single abbr{right:auto;left:26px}.chosen-rtl .chosen-choices li{float:right}.chosen-rtl .chosen-choices li.search-field input[type=text]{direction:rtl}.chosen-rtl .chosen-choices li.search-choice{margin:3px 5px 3px 0;padding:3px 5px 3px 19px}.chosen-rtl .chosen-choices li.search-choice .search-choice-close{right:auto;left:4px}.chosen-rtl .chosen-drop,.chosen-rtl.chosen-container-single-nosearch .chosen-search{left:9999px}.chosen-rtl.chosen-container-single .chosen-results{margin:0 0 4px 4px;padding:0 4px 0 0}.chosen-rtl .chosen-results li.group-option{padding-right:15px;padding-left:0}.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div{border-right:none}.chosen-rtl .chosen-search input[type=text]{padding:4px 5px 4px 20px;background:url(chosen-sprite.png) -30px -20px no-repeat;direction:rtl}.chosen-rtl.chosen-container-single .chosen-single div b{background-position:6px 2px}.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b{background-position:-12px 2px}@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-resolution:144dpi){.chosen-container .chosen-results-scroll-down span,.chosen-container .chosen-results-scroll-up span,.chosen-container-multi .chosen-choices .search-choice .search-choice-close,.chosen-container-single .chosen-search input[type=text],.chosen-container-single .chosen-single abbr,.chosen-container-single .chosen-single div b,.chosen-rtl .chosen-search input[type=text]{background-image:url(chosen-sprite@2x.png)!important;background-size:52px 37px!important;background-repeat:no-repeat!important}}.w-switchbutton{position:relative;width:80px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.w-switchbutton-checkbox{display:none}.w-switchbutton-label{display:block;overflow:hidden;cursor:pointer;border:1px solid #999;border-radius:5px}.w-switchbutton-inner{display:block;width:200%;margin-left:-100%;transition:margin .3s ease-in 0s}.w-switchbutton-inner:after,.w-switchbutton-inner:before{display:block;float:left;width:50%;height:28px;padding:0;line-height:28px;font-size:14px;font-weight:700;box-sizing:border-box}.w-switchbutton-inner:before{content:"ON";padding-left:10px;background-color:#385691;color:#FFF}.w-switchbutton-inner:after{content:"OFF";padding-right:10px;background-color:#F8F8F8;color:#666;text-align:right}.w-switchbutton-switch{display:block;width:30px;margin:0;background:#FFF;border:2px solid #999;border-radius:5px;position:absolute;top:0;bottom:0;right:46px;transition:all .3s ease-in 0s;background:linear-gradient(center top,rgba(0,0,0,.1) 0,transparent 100%) #FFF}.w-switchbutton-checkbox:checked+.w-switchbutton-label .w-switchbutton-inner{margin-left:0}.w-switchbutton-checkbox:checked+.w-switchbutton-label .w-switchbutton-switch{right:0}.w-switchbutton{vertical-align:middle;display:inline-block}.w-switchbutton-inner:after,.w-switchbutton-inner:before{font-family:open-sans,Arial,sans-serif}label{font-size:15px;vertical-align:middle}input[type=text],input[type=password],select,textarea{display:inline-block;box-sizing:border-box;vertical-align:middle;padding:8px;border:1px solid #999;border-radius:4px;box-shadow:inset 0 1px 3px #ccc;font-size:15px}input[type=text]:focus,input[type=password]:focus,select:focus,textarea:focus{outline:0;border-color:#4b91ff;box-shadow:inset 0 0 8px #4b91ff}input[type=text].w-form-error,input[type=password].w-form-error,select.w-form-error,textarea.w-form-error{background-color:#ffe6e6;border:1px solid #b30000}input[type=text],input[type=password],select{height:36px}select[multiple]{height:auto}select{background-color:#fff;padding-top:6px}textarea{resize:vertical}input[type=checkbox],input[type=radio]{width:17px;height:17px;vertical-align:middle;margin-top:1px}input[type=checkbox]:focus,input[type=radio]:focus{outline:#4b91ff solid 1px}#recaptcha_image{border-radius:4px}.w-file-input{width:400px}.w-file-input input[type=file]{position:absolute;top:-9999px;left:-9999px}.w-file-input span{margin-left:5px}.w-form{width:700px;box-sizing:border-box;border-radius:5px;border:1px solid #bbb}.w-form>p{text-align:left;margin:0;padding:20px 30px;border-radius:5px 5px 0 0;background-color:#bbb;font-weight:700;font-size:18px}.w-form>div{margin:0;padding:0 30px 30px}.w-form form{text-align:left}.w-form form p{margin:0}.w-form .w-form-group{margin:30px 0 0}.w-form fieldset{border:0;margin:0;padding:0}.w-form legend{width:100%;font-size:16px;font-weight:700;box-sizing:border-box;border-top:2px solid #999;border-bottom:2px solid #999;padding:6px 0}.w-form .w-form-label,.w-form label{display:block;width:100%;font-weight:700}.w-form .w-form-label{font-size:15px}.w-form .w-file-input,.w-form input[type=text],.w-form input[type=password],.w-form select,.w-form textarea{margin-top:3px;display:block;width:100%}.w-form input[type=checkbox]+label,.w-form input[type=radio]+label{display:inline;font-weight:400;margin-left:4px}.w-form .w-file-input{margin:0}.w-form .w-input-description,.w-form .w-input-error{font-size:11px;font-style:italic;margin:0;padding:0;text-align:right}.w-form .w-input-error{color:#b30000}.w-background-form{background-color:#eee}#recaptcha_widget{margin:0}#recaptcha_image{background-color:#fff;border:1px solid #999;float:left;margin-top:5px!important;padding:5px;margin:0}#recaptcha_links{float:left;margin:5px 0 0;padding-left:10px}#recaptcha_links a{font-style:italic;font-size:11px;line-height:9px;color:#666}#recaptcha_links div{margin:0}iframe{display:none!important}div iframe,footer iframe,header iframe,section iframe{display:inline}#recaptcha_image{width:300px;height:57px}.pika-single{font-family:open-sans,Arial,sans-serif}.pika-title select{height:19px;line-height:normal}.pika-button,.pika-select{font-weight:400}.pika-day{height:28px}.pika-table abbr{cursor:default}.chosen-choices .default,.chosen-single span{font-family:open-sans,Arial,sans-serif!important;font-size:15px!important}.chosen-container-multi .chosen-choices{box-shadow:inset 0 1px 3px #ccc;border-radius:4px}.chosen-container-single .chosen-single{background-color:#fff;box-shadow:inset 0 1px 3px #ccc;height:36px;line-height:26px}.chosen-container-multi .chosen-choices,.chosen-container-single .chosen-single{background-image:none;border:1px solid #999;padding:4px 8px 3px;vertical-align:middle!important}.chosen-container-active .chosen-choices,.chosen-container-active .chosen-single,.chosen-container-active.chosen-with-drop .chosen-single{box-shadow:inset 0 0 8px #4b91ff;outline:0;border-color:#4b91ff}.chosen-container-active.chosen-with-drop .chosen-single{background-image:none;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.chosen-container-single .chosen-single div{top:-14px}.chosen-container,.chosen-drop{margin:0}.chosen-container-single .search-choice-close{margin-top:6px}.chosen-container .chosen-results{padding:0;margin:0}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close,.chosen-container-single .chosen-search input[type=text],.chosen-container-single .chosen-single abbr,.chosen-container-single .chosen-single div b,.chosen-rtl .chosen-search input[type=text]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAAlCAQAAACn+wJeAAAB4UlEQVRIx+2XsWtTURTGrwouLQQDwYLFzT3yJBDoYoVvySQoKFShSHe7qAgqiMn9rcUibnVwEARBl0AgUIh/QXBxFIpKJHAhUBz0HQcf4U0xtZwu+r3l8t4758fHPe/jvhBcRIUuWbFuMKAWnEB9jEQWAk0SRt8LtMo+RmKdhDGiHrzEChOMHGPsiAkhBDbIMXKu+2KaJUfZwcsXD4RJrJFKKHaw6fVmRnmNT5ydC9TDSDRCIGOMMfh9u8pegRmzNKP8NUZvzu+oR6NY19mddqVVgG7MKL5SvHPrcJu3g/F2xvMqowKUOHMYUJXhrAa8Ku1j90/dVFFXxaypoYFqfzFR80h9mZKyENRUkskrgrSqfZmS1pVkGskvG7SiiUy5TGP5RpA2lMuUyzeC1Cw5yrwxSWtKrij1ZEpqhKBMY5kGXqCKeioiSHXtain817+k9gLLLD887ozhLl8xjGG86onZxuIe99jCsHjTCRMvYvF9+1QIIcTz8RuTzmkfP0+jdaYJHW9jXPYBvYj5/ZNlf06HxvgEYzoC8Tk5l1xAnXP8IHVam8faC3GTn3x5cMJr6q5h0fjI5+L4suU24PFCfMkHhvExHQyL20eQEfERhsVncdEfdYfvGK2jcPUOK/+A/QJb5yp50uoC6QAAAABJRU5ErkJggg==)}@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-resolution:144dpi){.chosen-container .chosen-results-scroll-down span,.chosen-container .chosen-results-scroll-up span,.chosen-container-multi .chosen-choices .search-choice .search-choice-close,.chosen-container-single .chosen-search input[type=text],.chosen-container-single .chosen-single abbr,.chosen-container-single .chosen-single div b,.chosen-rtl .chosen-search input[type=text]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGgAAABKCAQAAAD9cdkXAAACqUlEQVRo3u2av2/TQBTHI8FQCYYguoLCyOY/IQNk6NSF3RNzBmZ04oe/JwFSp0owtSNb/oT8B8mIBIioAyuWrA7pD4fns+vkzvZQ1+3lne57UoZXJfan79333ovT6zGTDGUsg0o0oGjY4yfCWdEykBROFg954hhIJQ4/pI0bL5E0HIryAgpMpGqEW9HpAAktzjg1SNxxGpH44hRIiYaTsMZxDsixknPMFKzaNgSEQwcrBtklMLDW+mBRV5lYtAaaqvdPrTWnGNYCDdtdOtq/+oRo39r4gEkFZ9LusqK/zjcWom9pwKOq1w0xbrsDILR/i7Bmit3cSG4H2icN7CEturIDDWhqD2jYnR1srm6t4XpIk5vYQff2b2oUjuJRxRRGAUXDph0Qt7eD2xbhrGgZSAoni4d31LJ0jGMglTjNSNuqjRsvkTQcivICCkykaoTZ+GAAJLQ449QgccdpROKLUyAlGk7CGsc5IMdKzjFTcMy2nTtY3Wt9XGtOW44PW490vQHPy8vLy8vLy2ubJfrRGHP6RjxVaxaNu31kdseipxdXj93SYq3kP4tPL24mhAqAMHApL+QFvRZQCHlmJ8/MGX7jtXz64Yl8K39hmUOyy5Loq2JLcYoDsVNCPpbfcKqyFDPbS9FYldpSftHjr+7JQ5xnWYrGrIDkLNs5+PnmQSV3OzhR+2jOC0jtn/os4F1uD+yAcPn+Wd3fPr4kz2MK9NwpoMaSkwxLrmh3foiHFVPYxYkCmnGz7fxQ/SruGx53zNK21cGaqoP1WOyWeXskv6uDdYUluyaVWh/V5OAcf+QnvIj28Bl/8+woyzji2JwWranWnK5/YsMPqRgf0o3hgYqNNVI24GVtUL4wzwY8HLFGqi1Gj8QNae4ckiPfCa2Req5I9XyNv1n+D6RKWo1cTsbTAAAAAElFTkSuQmCC)!important}}.wi-modal-background{position:fixed;height:100%;width:100%;top:0;left:0;background:#000;z-index:3;opacity:.2}.wi-modal{position:fixed;background:#fff;border:2px solid #999;z-index:4;padding:2px 25px}.wi-modal-close{cursor:pointer;right:8px;top:2px;position:absolute;color:#999;font-weight:700;display:block}.w-image-shadow{box-shadow:0 0 8px #000}.w-image-border{border:1px solid #333}.w-image-rounded{border-radius:5px}.w-image-circle{border-radius:100%}.w-caption-image img{float:right}.w-caption{float:left}.w-caption-image{position:relative;display:inline-block;margin:0}.w-caption{position:absolute;background-color:rgba(0,0,0,.6);bottom:0;margin:0;width:100%;color:#fff;overflow:hidden}.w-caption span{display:block;padding:5px}.w-icon{width:25px;height:25px;display:inline-block;margin:0;overflow:hidden}.w-icon svg{margin:0;fill:#385691}.w-table td>.w-icon{vertical-align:middle}.w-icon-button{padding-left:2px}.w-icon-button .w-icon{display:inline-block;float:left;width:28px;height:28px;padding:0;margin:0}.w-icon-button .w-icon>svg{fill:#444}.w-icon-button span:nth-child(2){display:inline-block;padding:4px 0 0 2px}.w-icon-button.w-large{padding-left:8px}.w-message>.w-icon{width:21px;height:21px;float:left;margin-right:5px}.w-success>.w-icon svg{fill:#218900}.w-warning>.w-icon svg{fill:#8a6b00}.w-error>.w-icon svg{fill:#b30000}.w-information>.w-icon svg{fill:#001f8a}td.center{display:table-cell} -------------------------------------------------------------------------------- /require/highlight.min.css: -------------------------------------------------------------------------------- 1 | .hljs{display:block;overflow-x:auto;padding:.5em;background:#232323;color:#e6e1dc;-webkit-text-size-adjust:none}.hljs-comment,.hljs-javadoc,.hljs-shebang{color:#bc9458;font-style:italic}.hljs-keyword,.hljs-list .hljs-title,.hljs-request,.hljs-status,.method,.nginx .hljs-title,.ruby .hljs-function .hljs-keyword{color:#c26230}.apache .hljs-cbracket,.asciidoc .hljs-link_label,.hljs-attr_selector,.hljs-cdata,.hljs-date,.hljs-filter .hljs-argument,.hljs-number,.hljs-regexp,.hljs-string,.hljs-tag .hljs-value,.markdown .hljs-link_label,.tex .hljs-command{color:#a5c261}.hljs-subst{color:#519f50}.hljs-doctype,.hljs-pi,.hljs-sub .hljs-identifier,.hljs-tag,.hljs-tag .hljs-keyword,.hljs-tag .hljs-title,.input_number{color:#e8bf6a}.hljs-identifier{color:#d0d0ff}.hljs-class .hljs-title,.hljs-dartdoc,.hljs-javadoctag,.hljs-phpdoc,.hljs-type,.hljs-yardoctag,.smalltalk .hljs-class{text-decoration:none}.hljs-constant{color:#da4939}.asciidoc .hljs-link_url,.hljs-attribute,.hljs-built_in,.hljs-symbol,.markdown .hljs-link_url,.ruby .hljs-symbol .hljs-identifier,.ruby .hljs-symbol .hljs-string{color:#6d9cbe}.asciidoc .hljs-link_url,.markdown .hljs-link_url{text-decoration:underline}.clojure .hljs-attribute,.hljs-params,.hljs-variable{color:#d0d0ff}.css .hljs-tag,.hljs-pseudo,.hljs-rules .hljs-property,.tex .hljs-special{color:#cda869}.css .hljs-class{color:#9b703f}.hljs-rules .hljs-keyword{color:#c5af75}.hljs-rules .hljs-value{color:#cf6a4c}.css .hljs-id{color:#8b98ab}.apache .hljs-sqbracket,.hljs-annotation,.nginx .hljs-built_in{color:#9b859d}.hljs-pragma,.hljs-preprocessor,.hljs-preprocessor *{color:#8996a8!important}.css .hljs-value .hljs-number,.hljs-hexcolor{color:#a5c261}.css .hljs-function,.hljs-decorator,.hljs-title{color:#ffc66d}.diff .hljs-header,.hljs-chunk{background-color:#2f33ab;color:#e6e1dc;display:inline-block;width:100%}.diff .hljs-change{background-color:#4a410d;color:#f8f8f8;display:inline-block;width:100%}.hljs-addition{background-color:#144212;color:#e6e1dc;display:inline-block;width:100%}.hljs-deletion{background-color:#600;color:#e6e1dc;display:inline-block;width:100%}.coffeescript .javascript,.javascript .xml,.tex .hljs-formula,.xml .css,.xml .hljs-cdata,.xml .javascript,.xml .vbscript{opacity:.7} -------------------------------------------------------------------------------- /require/highlight.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | highlight.js 3 | Copyright (c) 2006, Ivan Sagalaev https://highlightjs.org/ 4 | */ 5 | !function(e){"undefined"!=typeof exports?e(exports):(window.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return window.hljs}))}(function(e){function t(e){return e.replace(/&/gm,"&").replace(//gm,">")}function r(e){return e.nodeName.toLowerCase()}function n(e,t){var r=e&&e.exec(t);return r&&0==r.index}function a(e){var t=(e.className+" "+(e.parentNode?e.parentNode.className:"")).split(/\s+/);return t=t.map(function(e){return e.replace(/^lang(uage)?-/,"")}),t.filter(function(e){return N(e)||/no(-?)highlight/.test(e)})[0]}function i(e,t){var r={};for(var n in e)r[n]=e[n];if(t)for(var n in t)r[n]=t[n];return r}function s(e){var t=[];return function n(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(t.push({event:"start",offset:a,node:i}),a=n(i,a),r(i).match(/br|hr|img|input/)||t.push({event:"stop",offset:a,node:i}));return a}(e,0),t}function c(e,n,a){function i(){return e.length&&n.length?e[0].offset!=n[0].offset?e[0].offset"}function c(e){u+=""}function o(e){("start"==e.event?s:c)(e.node)}for(var l=0,u="",d=[];e.length||n.length;){var b=i();if(u+=t(a.substr(l,b[0].offset-l)),l=b[0].offset,b==e){d.reverse().forEach(c);do o(b.splice(0,1)[0]),b=i();while(b==e&&b.length&&b[0].offset==l);d.reverse().forEach(s)}else"start"==b[0].event?d.push(b[0].node):d.pop(),o(b.splice(0,1)[0])}return u+t(a.substr(l))}function o(e){function t(e){return e&&e.source||e}function r(r,n){return RegExp(t(r),"m"+(e.cI?"i":"")+(n?"g":""))}function n(a,s){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var c={},o=function(t,r){e.cI&&(r=r.toLowerCase()),r.split(" ").forEach(function(e){var r=e.split("|");c[r[0]]=[t,r[1]?Number(r[1]):1]})};"string"==typeof a.k?o("keyword",a.k):Object.keys(a.k).forEach(function(e){o(e,a.k[e])}),a.k=c}a.lR=r(a.l||/\b[A-Za-z0-9_]+\b/,!0),s&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=r(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=r(a.e)),a.tE=t(a.e)||"",a.eW&&s.tE&&(a.tE+=(a.e?"|":"")+s.tE)),a.i&&(a.iR=r(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var l=[];a.c.forEach(function(e){e.v?e.v.forEach(function(t){l.push(i(e,t))}):l.push("self"==e?a:e)}),a.c=l,a.c.forEach(function(e){n(e,a)}),a.starts&&n(a.starts,s);var u=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(t).filter(Boolean);a.t=u.length?r(u.join("|"),!0):{exec:function(){return null}}}}n(e)}function l(e,r,a,i){function s(e,t){for(var r=0;r";return i+=e+'">',i+t+s}function f(){if(!k.k)return t(S);var e="",r=0;k.lR.lastIndex=0;for(var n=k.lR.exec(S);n;){e+=t(S.substr(r,n.index-r));var a=b(k,n);a?(E+=a[1],e+=p(a[0],t(n[0]))):e+=t(n[0]),r=k.lR.lastIndex,n=k.lR.exec(S)}return e+t(S.substr(r))}function m(){if(k.sL&&!w[k.sL])return t(S);var e=k.sL?l(k.sL,S,!0,x[k.sL]):u(S);return k.r>0&&(E+=e.r),"continuous"==k.subLanguageMode&&(x[k.sL]=e.top),p(e.language,e.value,!1,!0)}function g(){return void 0!==k.sL?m():f()}function _(e,r){var n=e.cN?p(e.cN,"",!0):"";e.rB?(M+=n,S=""):e.eB?(M+=t(r)+n,S=""):(M+=n,S=r),k=Object.create(e,{parent:{value:k}})}function h(e,r){if(S+=e,void 0===r)return M+=g(),0;var n=s(r,k);if(n)return M+=g(),_(n,r),n.rB?0:r.length;var a=c(k,r);if(a){var i=k;i.rE||i.eE||(S+=r),M+=g();do k.cN&&(M+=""),E+=k.r,k=k.parent;while(k!=a.parent);return i.eE&&(M+=t(r)),S="",a.starts&&_(a.starts,""),i.rE?0:r.length}if(d(r,k))throw new Error('Illegal lexeme "'+r+'" for mode "'+(k.cN||"")+'"');return S+=r,r.length||1}var y=N(e);if(!y)throw new Error('Unknown language: "'+e+'"');o(y);for(var k=i||y,x={},M="",C=k;C!=y;C=C.parent)C.cN&&(M=p(C.cN,"",!0)+M);var S="",E=0;try{for(var B,I,L=0;k.t.lastIndex=L,B=k.t.exec(r),B;)I=h(r.substr(L,B.index-L),B[0]),L=B.index+I;h(r.substr(L));for(var C=k;C.parent;C=C.parent)C.cN&&(M+="");return{r:E,value:M,language:e,top:k}}catch(R){if(-1!=R.message.indexOf("Illegal"))return{r:0,value:t(r)};throw R}}function u(e,r){r=r||v.languages||Object.keys(w);var n={r:0,value:t(e)},a=n;return r.forEach(function(t){if(N(t)){var r=l(t,e,!1);r.language=t,r.r>a.r&&(a=r),r.r>n.r&&(a=n,n=r)}}),a.language&&(n.second_best=a),n}function d(e){return v.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,t){return t.replace(/\t/g,v.tabReplace)})),v.useBR&&(e=e.replace(/\n/g,"
")),e}function b(e,t,r){var n=t?y[t]:r,a=[e.trim()];return e.match(/(\s|^)hljs(\s|$)/)||a.push("hljs"),n&&a.push(n),a.join(" ").trim()}function p(e){var t=a(e);if(!/no(-?)highlight/.test(t)){var r;v.useBR?(r=document.createElementNS("http://www.w3.org/1999/xhtml","div"),r.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):r=e;var n=r.textContent,i=t?l(t,n,!0):u(n),o=s(r);if(o.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=i.value,i.value=c(o,s(p),n)}i.value=d(i.value),e.innerHTML=i.value,e.className=b(e.className,t,i.language),e.result={language:i.language,re:i.r},i.second_best&&(e.second_best={language:i.second_best.language,re:i.second_best.r})}}function f(e){v=i(v,e)}function m(){if(!m.called){m.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function g(){addEventListener("DOMContentLoaded",m,!1),addEventListener("load",m,!1)}function _(t,r){var n=w[t]=r(e);n.aliases&&n.aliases.forEach(function(e){y[e]=t})}function h(){return Object.keys(w)}function N(e){return w[e]||w[y[e]]}var v={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},w={},y={};return e.highlight=l,e.highlightAuto=u,e.fixMarkup=d,e.highlightBlock=p,e.configure=f,e.initHighlighting=m,e.initHighlightingOnLoad=g,e.registerLanguage=_,e.listLanguages=h,e.getLanguage=N,e.inherit=i,e.IR="[a-zA-Z][a-zA-Z0-9_]*",e.UIR="[a-zA-Z_][a-zA-Z0-9_]*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/},e.CLCM={cN:"comment",b:"//",e:"$",c:[e.PWM]},e.CBCM={cN:"comment",b:"/\\*",e:"\\*/",c:[e.PWM]},e.HCM={cN:"comment",b:"#",e:"$",c:[e.PWM]},e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e}),hljs.registerLanguage("xml",function(){var e="[A-Za-z0-9\\._:-]+",t={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php",subLanguageMode:"continuous"},r={eW:!0,i:/]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"doctype",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"|$)",e:">",k:{title:"style"},c:[r],starts:{e:"",rE:!0,sL:"css"}},{cN:"tag",b:"|$)",e:">",k:{title:"script"},c:[r],starts:{e:"",rE:!0,sL:"javascript"}},t,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"",c:[{cN:"title",b:/[^ \/><\n\t]+/,r:0},r]}]}}),hljs.registerLanguage("cpp",function(e){var t={keyword:"false int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using true class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue wchar_t inline delete alignof char16_t char32_t constexpr decltype noexcept nullptr static_assert thread_local restrict _Bool complex _Complex _Imaginaryintmax_t uintmax_t int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_tint_least8_t uint_least8_t int_least16_t uint_least16_t int_least32_t uint_least32_tint_least64_t uint_least64_t int_fast8_t uint_fast8_t int_fast16_t uint_fast16_t int_fast32_tuint_fast32_t int_fast64_t uint_fast64_t intptr_t uintptr_t atomic_bool atomic_char atomic_scharatomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llongatomic_ullong atomic_wchar_t atomic_char16_t atomic_char32_t atomic_intmax_t atomic_uintmax_tatomic_intptr_t atomic_uintptr_t atomic_size_t atomic_ptrdiff_t atomic_int_least8_t atomic_int_least16_tatomic_int_least32_t atomic_int_least64_t atomic_uint_least8_t atomic_uint_least16_t atomic_uint_least32_tatomic_uint_least64_t atomic_int_fast8_t atomic_int_fast16_t atomic_int_fast32_t atomic_int_fast64_tatomic_uint_fast8_t atomic_uint_fast16_t atomic_uint_fast32_t atomic_uint_fast64_t",built_in:"std string cin cout cerr clog stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf"};return{aliases:["c","h","c++","h++"],k:t,i:""]',k:"include",i:"\\n"},e.CLCM]},{cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:t,c:["self"]},{b:e.IR+"::"},{bK:"new throw return",r:0},{cN:"function",b:"("+e.IR+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.CBCM]},e.CLCM,e.CBCM]}]}}),hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)\}/}]},r={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},n={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,e.NM,r,n,t]}}),hljs.registerLanguage("java",function(e){var t=e.UIR+"(<"+e.UIR+">)?",r="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",n="(\\b(0b[01_]+)|\\b0[xX][a-fA-F0-9_]+|(\\b[\\d_]+(\\.[\\d_]*)?|\\.[\\d_]+)([eE][-+]?\\d+)?)[lLfF]?",a={cN:"number",b:n,r:0};return{aliases:["jsp"],k:r,i:/<\//,c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",r:0,c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}]},e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},a,{cN:"annotation",b:"@[A-Za-z]+"}]}}),hljs.registerLanguage("ini",function(e){return{cI:!0,i:/\S/,c:[{cN:"comment",b:";",e:"$"},{cN:"title",b:"^\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9\\[\\]_-]+[ \\t]*=[ \\t]*",e:"$",c:[{cN:"value",eW:!0,k:"on off true false yes no",c:[e.QSM,e.NM],r:0}]}]}}),hljs.registerLanguage("objectivec",function(e){var t={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"NSString NSData NSDictionary CGRect CGPoint UIButton UILabel UITextView UIWebView MKMapView NSView NSViewController NSWindow NSWindowController NSSet NSUUID NSIndexSet UISegmentedControl NSObject UITableViewDelegate UITableViewDataSource NSThread UIActivityIndicator UITabbar UIToolBar UIBarButtonItem UIImageView NSAutoreleasePool UITableView BOOL NSInteger CGFloat NSException NSLog NSMutableString NSMutableArray NSMutableDictionary NSURL NSIndexPath CGSize UITableViewCell UIView UIViewController UINavigationBar UINavigationController UITabBarController UIPopoverController UIPopoverControllerDelegate UIImage NSNumber UISearchBar NSFetchedResultsController NSFetchedResultsChangeType UIScrollView UIScrollViewDelegate UIEdgeInsets UIColor UIFont UIApplication NSNotFound NSNotificationCenter NSNotification UILocalNotification NSBundle NSFileManager NSTimeInterval NSDate NSCalendar NSUserDefaults UIWindow NSRange NSArray NSError NSURLRequest NSURLConnection NSURLSession NSURLSessionDataTask NSURLSessionDownloadTask NSURLSessionUploadTask NSURLResponseUIInterfaceOrientation MPMoviePlayerController dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},r=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["m","mm","objc","obj-c"],k:t,l:r,i:""}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:r,c:[e.UTM]},{cN:"variable",b:"\\."+e.UIR,r:0}]}}),hljs.registerLanguage("php",function(e){var t={cN:"variable",b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},r={cN:"preprocessor",b:/<\?(php)?|\?>/},n={cN:"string",c:[e.BE,r],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},a={v:[e.BNM,e.CNM]};return{aliases:["php3","php4","php5","php6"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.CLCM,e.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+"},r]},{cN:"comment",b:"__halt_compiler.+?;",eW:!0,k:"__halt_compiler",l:e.UIR},{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[e.BE]},r,t,{b:/->+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",t,e.CBCM,n,a]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},n,a]}}),hljs.registerLanguage("coffeescript",function(e){var t={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",reserved:"case default function var void with const let enum export import native __hasProp __extends __slice __bind __indexOf",built_in:"npm require console print module global window document"},r="[A-Za-z$_][0-9A-Za-z$_]*",n={cN:"subst",b:/#\{/,e:/}/,k:t},a=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,n]},{b:/"/,e:/"/,c:[e.BE,n]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[n,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{cN:"property",b:"@"+r},{b:"`",e:"`",eB:!0,eE:!0,sL:"javascript"}];n.c=a;var i=e.inherit(e.TM,{b:r}),s="(\\(.*\\))?\\s*\\B[-=]>",c={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:t,c:["self"].concat(a)}]};return{aliases:["coffee","cson","iced"],k:t,i:/\/\*/,c:a.concat([{cN:"comment",b:"###",e:"###",c:[e.PWM]},e.HCM,{cN:"function",b:"^\\s*"+r+"\\s*=\\s*"+s,e:"[-=]>",rB:!0,c:[i,c]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:s,e:"[-=]>",rB:!0,c:[c]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[i]},i]},{cN:"attribute",b:r+":",e:":",rB:!0,rE:!0,r:0}])}}),hljs.registerLanguage("sql",function(e){var t={cN:"comment",b:"--",e:"$"};return{cI:!0,i:/[<>]/,c:[{cN:"operator",bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate savepoint release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup",e:/;/,eW:!0,k:{keyword:"abs absolute acos action add adddate addtime aes_decrypt aes_encrypt after aggregate all allocate alter analyze and any are as asc ascii asin assertion at atan atan2 atn2 authorization authors avg backup before begin benchmark between bin binlog bit_and bit_count bit_length bit_or bit_xor both by cache call cascade cascaded case cast catalog ceil ceiling chain change changed char_length character_length charindex charset check checksum checksum_agg choose close coalesce coercibility collate collation collationproperty column columns columns_updated commit compress concat concat_ws concurrent connect connection connection_id consistent constraint constraints continue contributors conv convert convert_tz corresponding cos cot count count_big crc32 create cross cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime data database databases datalength date_add date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts datetimeoffsetfromparts day dayname dayofmonth dayofweek dayofyear deallocate declare decode default deferrable deferred degrees delayed delete des_decrypt des_encrypt des_key_file desc describe descriptor diagnostics difference disconnect distinct distinctrow div do domain double drop dumpfile each else elt enclosed encode encrypt end end-exec engine engines eomonth errors escape escaped event eventdata events except exception exec execute exists exp explain export_set extended external extract fast fetch field fields find_in_set first first_value floor flush for force foreign format found found_rows from from_base64 from_days from_unixtime full function get get_format get_lock getdate getutcdate global go goto grant grants greatest group group_concat grouping grouping_id gtid_subset gtid_subtract handler having help hex high_priority hosts hour ident_current ident_incr ident_seed identified identity if ifnull ignore iif ilike immediate in index indicator inet6_aton inet6_ntoa inet_aton inet_ntoa infile initially inner innodb input insert install instr intersect into is is_free_lock is_ipv4 is_ipv4_compat is_ipv4_mapped is_not is_not_null is_used_lock isdate isnull isolation join key kill language last last_day last_insert_id last_value lcase lead leading least leaves left len lenght level like limit lines ln load load_file local localtime localtimestamp locate lock log log10 log2 logfile logs low_priority lower lpad ltrim make_set makedate maketime master master_pos_wait match matched max md5 medium merge microsecond mid min minute mod mode module month monthname mutex name_const names national natural nchar next no no_write_to_binlog not now nullif nvarchar oct octet_length of old_password on only open optimize option optionally or ord order outer outfile output pad parse partial partition password patindex percent_rank percentile_cont percentile_disc period_add period_diff pi plugin position pow power pragma precision prepare preserve primary prior privileges procedure procedure_analyze processlist profile profiles public publishingservername purge quarter query quick quote quotename radians rand read references regexp relative relaylog release release_lock rename repair repeat replace replicate reset restore restrict return returns reverse revoke right rlike rollback rollup round row row_count rows rpad rtrim savepoint schema scroll sec_to_time second section select serializable server session session_user set sha sha1 sha2 share show sign sin size slave sleep smalldatetimefromparts snapshot some soname soundex sounds_like space sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sql_variant_property sqlstate sqrt square start starting status std stddev stddev_pop stddev_samp stdev stdevp stop str str_to_date straight_join strcmp string stuff subdate substr substring subtime subtring_index sum switchoffset sysdate sysdatetime sysdatetimeoffset system_user sysutcdatetime table tables tablespace tan temporary terminated tertiary_weights then time time_format time_to_sec timediff timefromparts timestamp timestampadd timestampdiff timezone_hour timezone_minute to to_base64 to_days to_seconds todatetimeoffset trailing transaction translation trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse ucase uncompress uncompressed_length unhex unicode uninstall union unique unix_timestamp unknown unlock update upgrade upped upper usage use user user_resources using utc_date utc_time utc_timestamp uuid uuid_short validate_password_strength value values var var_pop var_samp variables variance varp version view warnings week weekday weekofyear weight_string when whenever where with work write xml xor year yearweek zon",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int integer interval number numeric real serial smallint varchar varying int8 serial8 text"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}}),hljs.registerLanguage("http",function(){return{i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:!0}}]}}),hljs.registerLanguage("makefile",function(e){var t={cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]};return{aliases:["mk","mak"],c:[e.HCM,{b:/^\w+\s*\W*=/,rB:!0,r:0,starts:{cN:"constant",e:/\s*\W*=/,eE:!0,starts:{e:/$/,r:0,c:[t]}}},{cN:"title",b:/^[\w]+:\s*$/},{cN:"phony",b:/^\.PHONY:/,e:/$/,k:".PHONY",l:/[\.\w]+/},{b:/^\t+/,e:/$/,r:0,c:[e.QSM,t]}]}}),hljs.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",r={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},n={b:"->{",e:"}"},a={cN:"variable",v:[{b:/\$\d/},{b:/[\$\%\@](\^\w\b|#\w+(\:\:\w+)*|{\w+}|\w+(\:\:\w*)*)/},{b:/[\$\%\@][^\s\w{]/,r:0}]},i={cN:"comment",b:"^(__END__|__DATA__)",e:"\\n$",r:5},s=[e.BE,r,a],c=[a,e.HCM,i,{cN:"comment",b:"^\\=\\w",e:"\\=cut",eW:!0},n,{cN:"string",c:s,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,i,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"sub",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",r:5},{cN:"operator",b:"-\\w\\b",r:0}];return r.c=c,n.c=c,{aliases:["pl"],k:t,c:c}}),hljs.registerLanguage("ruby",function(e){var t="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r="and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",n={cN:"yardoctag",b:"@[A-Za-z]+"},a={cN:"value",b:"#<",e:">"},i={cN:"comment",v:[{b:"#",e:"$",c:[n]},{b:"^\\=begin",e:"^\\=end",c:[n],r:10},{b:"^__END__",e:"\\n$"}]},s={cN:"subst",b:"#\\{",e:"}",k:r},c={cN:"string",c:[e.BE,s],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/}]},o={cN:"params",b:"\\(",e:"\\)",k:r},l=[c,a,i,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]},i]},{cN:"function",bK:"def",e:" |$|;",r:0,c:[e.inherit(e.TM,{b:t}),o,i]},{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":",c:[c,{b:t}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:[a,i,{cN:"regexp",c:[e.BE,s],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}],r:0}];s.c=l,o.c=l;var u="[>?]>",d="[\\w#]+\\(\\w+\\):\\d+:\\d+>",b="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",p=[{b:/^\s*=>/,cN:"status",starts:{e:"$",c:l}},{cN:"prompt",b:"^("+u+"|"+d+"|"+b+")",starts:{e:"$",c:l}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,c:[i].concat(p).concat(l)}}),hljs.registerLanguage("apache",function(e){var t={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"tag",b:""},{cN:"keyword",b:/\w+/,r:0,k:{common:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"sqbracket",b:"\\s\\[",e:"\\]$"},{cN:"cbracket",b:"[\\$%]\\{",e:"\\}",c:["self",t]},t,e.QSM]}}],i:/\S/}}),hljs.registerLanguage("json",function(e){var t={literal:"true false null"},r=[e.QSM,e.CNM],n={cN:"value",e:",",eW:!0,eE:!0,c:r,k:t},a={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:n}],i:"\\S"},i={b:"\\[",e:"\\]",c:[e.inherit(n,{cN:null})],i:"\\S"};return r.splice(r.length,0,a,i),{c:r,k:t,i:"\\S"}}),hljs.registerLanguage("css",function(e){var t="[a-zA-Z-][a-zA-Z0-9_-]*",r={cN:"function",b:t+"\\(",rB:!0,eE:!0,e:"\\("};return{cI:!0,i:"[=/|']",c:[e.CBCM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[r,e.ASM,e.QSM,e.CSSNM]}]},{cN:"tag",b:t,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[e.CBCM,{cN:"rule",b:"[^\\s]",rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:!0,i:"[^\\s]",starts:{cN:"value",eW:!0,eE:!0,c:[r,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}}),hljs.registerLanguage("nginx",function(e){var t={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},r={eW:!0,l:"[a-z/_]+",k:{built_in:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,t],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{cN:"url",b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[t]},{cN:"regexp",c:[e.BE,t],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},t]}; 6 | return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"title",b:e.UIR,starts:r}],r:0}],i:"[^\\s\\}]"}}),hljs.registerLanguage("cs",function(e){var t="abstract as base bool break byte case catch char checked const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long null object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async protected public private internal ascending descending from get group into join let orderby partial select set value var where yield",r=e.IR+"(<"+e.IR+">)?";return{aliases:["csharp"],k:t,i:/::/,c:[{cN:"comment",b:"///",e:"$",rB:!0,c:[{cN:"xmlDocTag",v:[{b:"///",r:0},{b:""},{b:""}]}]},e.CLCM,e.CBCM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line region endregion pragma checksum"},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},e.ASM,e.QSM,e.CNM,{bK:"class namespace interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"new return throw await",r:0},{cN:"function",b:"("+r+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}}),hljs.registerLanguage("markdown",function(){return{aliases:["md","mkdown","mkd"],c:[{cN:"header",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{cN:"horizontal_rule",b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"link_label",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link_url",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"link_reference",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:"^\\[.+\\]:",rB:!0,c:[{cN:"link_reference",b:"\\[",e:"\\]:",eB:!0,eE:!0,starts:{cN:"link_url",e:"$"}}]}]}}),hljs.registerLanguage("diff",function(){return{aliases:["patch"],c:[{cN:"chunk",r:10,v:[{b:/^\@\@ +\-\d+,\d+ +\+\d+,\d+ +\@\@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"header",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\-\-\-/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+\+\+/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}}),hljs.registerLanguage("javascript",function(e){return{aliases:["js"],k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document"},c:[{cN:"pi",r:10,v:[{b:/^\s*('|")use strict('|")/},{b:/^\s*('|")use asm('|")/}]},e.ASM,e.QSM,e.CLCM,e.CBCM,e.CNM,{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+e.IR,r:0}]}}),hljs.registerLanguage("python",function(e){var t={cN:"prompt",b:/^(>>>|\.\.\.) /},r={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[t],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[t],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},e.ASM,e.QSM]},n={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},a={cN:"params",b:/\(/,e:/\)/,c:["self",t,n,r]};return{aliases:["py","gyp"],k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:[t,n,r,e.HCM,{v:[{cN:"function",bK:"def",r:10},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n]/,c:[e.UTM,a]},{cN:"decorator",b:/@/,e:/$/},{b:/\b(print|exec)\(/}]}}); -------------------------------------------------------------------------------- /require/textures.min.js: -------------------------------------------------------------------------------- 1 | (function(){var rand,umd,slice=[].slice;rand=function(){return(Math.random().toString(36)+"00000000000000000").replace(/[^a-z]+/g,"").slice(0,5)};umd=function(factory){if(typeof exports==="object"){return module.exports=factory()}else if(typeof define==="function"&&define.amd){return define([],factory)}else{return this.textures=factory()}};umd(function(){return{circles:function(){var background,circles,complement,fill,id,radius,size,stroke,strokeWidth;size=20;background="";radius=2;complement=false;fill="#343434";stroke="#343434";strokeWidth=0;id=rand();circles=function(){var corner,g,i,len,ref,results;g=this.append("defs").append("pattern").attr({id:id,patternUnits:"userSpaceOnUse",width:size,height:size});if(background){g.append("rect").attr({width:size,height:size,fill:background})}g.append("circle").attr({cx:size/2,cy:size/2,r:radius,fill:fill,stroke:stroke,"stroke-width":strokeWidth});if(complement){ref=[[0,0],[0,size],[size,0],[size,size]];results=[];for(i=0,len=ref.length;i