From 5886952eb5a5b773d74fe15bddbee87cd2eec3eb Mon Sep 17 00:00:00 2001 From: ayyoob Date: Fri, 17 Jul 2015 17:34:23 +0530 Subject: [PATCH] removed iot --- .../jaggeryapps/iot/api/device-api.jag | 85 - .../jaggeryapps/iot/api/stats-api.jag | 105 - .../jaggeryapps/iot/api/user-api.jag | 149 - .../jaggeryapps/iot/config/config.json | 16 - .../jaggeryapps/iot/config/dc-props.js | 37 - .../repository/jaggeryapps/iot/config/init.js | 28 - .../repository/jaggeryapps/iot/jaggery.conf | 47 - .../jaggeryapps/iot/layouts/enrollment.hbs | 29 - .../jaggeryapps/iot/layouts/fluid.hbs | 23 - .../jaggeryapps/iot/layouts/nav-fluid.hbs | 50 - .../repository/jaggeryapps/iot/lib/acs.jag | 49 - .../jaggeryapps/iot/lib/fuse-router.js | 242 - .../repository/jaggeryapps/iot/lib/fuse.jag | 29 - .../repository/jaggeryapps/iot/lib/fuse.js | 453 - .../jaggeryapps/iot/lib/handlebars-helpers.js | 194 - .../jaggeryapps/iot/lib/handlebars-v2.0.0.js | 3079 ---- .../jaggeryapps/iot/lib/less-rhino-1.7.5.js | 10209 ------------ .../repository/jaggeryapps/iot/lib/login.jag | 36 - .../repository/jaggeryapps/iot/lib/logout.jag | 37 - .../jaggeryapps/iot/modules/constants.js | 26 - .../jaggeryapps/iot/modules/device.js | 43 - .../jaggeryapps/iot/modules/download.js | 68 - .../jaggeryapps/iot/modules/pinch.min.js | 27 - .../repository/jaggeryapps/iot/modules/sso.js | 161 - .../jaggeryapps/iot/modules/user.js | 299 - .../jaggeryapps/iot/modules/utility.js | 59 - .../jaggeryapps/iot/pages/alldevices.hbs | 9 - .../jaggeryapps/iot/pages/arduino.hbs | 8 - .../jaggeryapps/iot/pages/digitaldisplay.hbs | 8 - .../jaggeryapps/iot/pages/firealarm.hbs | 8 - .../jaggeryapps/iot/pages/index.hbs | 8 - .../jaggeryapps/iot/pages/login.hbs | 8 - .../jaggeryapps/iot/pages/mydevice.hbs | 9 - .../jaggeryapps/iot/pages/sensebot.hbs | 8 - .../jaggeryapps/iot/test/testExecutor.jag | 20 - .../iot/tmp/cached_theme_less_base.css | 6293 -------- .../iot/units/alldevices/alldevices.hbs | 39 - .../iot/units/alldevices/alldevices.js | 4 - .../iot/units/alldevices/alldevices.json | 3 - .../alldevices/public/js/alldevices_util.js | 49 - .../jaggeryapps/iot/units/appbar/appbar.hbs | 164 - .../jaggeryapps/iot/units/appbar/appbar.js | 19 - .../jaggeryapps/iot/units/appbar/appbar.json | 3 - .../iot/units/appbar/public/images/logo.png | Bin 5028 -> 0 bytes .../iot/units/devices/arduino/arduino.hbs | 78 - .../iot/units/devices/arduino/arduino.js | 4 - .../iot/units/devices/arduino/arduino.json | 3 - .../arduino/public/images/arduino-thumb.png | Bin 9862 -> 0 bytes .../devices/arduino/public/images/arduino.png | Bin 1162747 -> 0 bytes .../devices/digitaldisplay/digitaldisplay.hbs | 80 - .../devices/digitaldisplay/digitaldisplay.js | 4 - .../digitaldisplay/digitaldisplay.json | 3 - .../public/images/digitaldisplay-thumb.png | Bin 8161 -> 0 bytes .../public/images/digitaldisplay.png | Bin 121889 -> 0 bytes .../iot/units/devices/firealarm/firealarm.hbs | 89 - .../iot/units/devices/firealarm/firealarm.js | 4 - .../units/devices/firealarm/firealarm.json | 3 - .../public/images/firealarm-thumb.png | Bin 10339 -> 0 bytes .../firealarm/public/images/firealarm.png | Bin 141980 -> 0 bytes .../public/images/schematicsGuide.png | Bin 489842 -> 0 bytes .../sensebot/public/images/sensebot-thumb.png | Bin 15059 -> 0 bytes .../sensebot/public/images/sensebot.png | Bin 92674 -> 0 bytes .../iot/units/devices/sensebot/sensebot.hbs | 98 - .../iot/units/devices/sensebot/sensebot.js | 4 - .../iot/units/devices/sensebot/sensebot.json | 3 - .../public/css/daterangepicker.css | 232 - .../sensebot_nologin/public/css/nv.d3.css | 645 - .../public/images/bulb-off.png | Bin 516 -> 0 bytes .../public/images/bulb-on.png | Bin 451 -> 0 bytes .../sensebot_nologin/public/images/fan.png | Bin 650 -> 0 bytes .../sensebot_nologin/public/images/temp.png | Bin 373 -> 0 bytes .../sensebot_nologin/public/js/bulb.js | 10 - .../public/js/cumulativelinechart.js | 0 .../sensebot_nologin/public/js/d3.min.js | 5 - .../sensebot_nologin/public/js/date-range.js | 0 .../public/js/discretebarchart.js | 0 .../sensebot_nologin/public/js/graph_util.js | 117 - .../public/js/jquery.daterangepicker.js | 1627 -- .../sensebot_nologin/public/js/light_graph.js | 61 - .../public/js/linewithfocuschart.js | 0 .../sensebot_nologin/public/js/moment.min.js | 7 - .../public/js/motion_graph.js | 60 - .../sensebot_nologin/public/js/nv.d3.js | 11357 ------------- .../sensebot_nologin/public/js/sonar_graph.js | 60 - .../public/js/stream_layers.js | 35 - .../public/js/temperature_graph.js | 60 - .../sensebot_nologin/sensebot_nologin.hbs | 80 - .../sensebot_nologin/sensebot_nologin.js | 4 - .../sensebot_nologin/sensebot_nologin.json | 3 - .../jaggeryapps/iot/units/login/login.hbs | 26 - .../jaggeryapps/iot/units/login/login.js | 10 - .../jaggeryapps/iot/units/login/login.json | 3 - .../iot/units/login/public/js/login-box.js | 13 - .../iot/units/mydevice/mydevice.hbs | 105 - .../iot/units/mydevice/mydevice.js | 4 - .../iot/units/mydevice/mydevice.json | 3 - .../mydevice/public/css/daterangepicker.css | 331 - .../iot/units/mydevice/public/css/graph.css | 197 - .../iot/units/mydevice/public/css/lines.css | 21 - .../iot/units/mydevice/public/css/nv.d3.css | 641 - .../units/mydevice/public/images/bulb-off.png | Bin 516 -> 0 bytes .../units/mydevice/public/images/bulb-on.png | Bin 451 -> 0 bytes .../iot/units/mydevice/public/images/fan.png | Bin 650 -> 0 bytes .../iot/units/mydevice/public/images/temp.png | Bin 373 -> 0 bytes .../iot/units/mydevice/public/js/Chart.min.js | 11 - .../iot/units/mydevice/public/js/bulb.js | 10 - .../iot/units/mydevice/public/js/d3.min.js | 9470 ----------- .../iot/units/mydevice/public/js/d3.v3.js | 5 - .../units/mydevice/public/js/graph_util.js | 243 - .../mydevice/public/js/graphs/bulb_graph.js | 85 - .../mydevice/public/js/graphs/fan_graph.js | 84 - .../mydevice/public/js/graphs/light_graph.js | 85 - .../mydevice/public/js/graphs/motion_graph.js | 70 - .../mydevice/public/js/graphs/sonar_graph.js | 69 - .../public/js/graphs/temperature_graph.js | 70 - .../public/js/jquery.daterangepicker.js | 1432 -- .../units/mydevice/public/js/moment.min.js | 7 - .../iot/units/mydevice/public/js/nv.d3.js | 13435 ---------------- .../units/mydevice/public/js/rickshaw.min.js | 3 - .../units/mydevice/public/js/stream_layers.js | 35 - .../showcase/public/images/RaspberryPi.png | Bin 8006 -> 0 bytes .../showcase/public/images/arduino-thumb.png | Bin 9862 -> 0 bytes .../showcase/public/images/banner-img-3.png | Bin 17519 -> 0 bytes .../showcase/public/images/beagleBone.png | Bin 10433 -> 0 bytes .../public/images/digitaldisplay-thumb.png | Bin 8161 -> 0 bytes .../public/images/firealarm-thumb.png | Bin 10339 -> 0 bytes .../units/showcase/public/images/intel.png | Bin 5068 -> 0 bytes .../showcase/public/images/sensebot-thumb.png | Bin 15059 -> 0 bytes .../iot/units/showcase/showcase.hbs | 99 - .../iot/units/showcase/showcase.js | 4 - .../iot/units/showcase/showcase.json | 3 - .../units/theme/public/css/bootstrap.min.css | 6671 -------- .../units/theme/public/css/custom-theme.css | 74 - .../theme/public/css/fontwso2-extend.css | 177 - .../iot/units/theme/public/css/fontwso2.css | 481 - .../iot/units/theme/public/css/main.css | 484 - .../public/fonts/OpenSans-Bold-webfont.eot | Bin 30858 -> 0 bytes .../public/fonts/OpenSans-Bold-webfont.svg | 251 - .../public/fonts/OpenSans-Bold-webfont.ttf | Bin 30680 -> 0 bytes .../public/fonts/OpenSans-Bold-webfont.woff | Bin 19788 -> 0 bytes .../fonts/OpenSans-BoldItalic-webfont.eot | Bin 34166 -> 0 bytes .../fonts/OpenSans-BoldItalic-webfont.svg | 251 - .../fonts/OpenSans-BoldItalic-webfont.ttf | Bin 33960 -> 0 bytes .../fonts/OpenSans-BoldItalic-webfont.woff | Bin 21940 -> 0 bytes .../fonts/OpenSans-ExtraBold-webfont.eot | Bin 30602 -> 0 bytes .../fonts/OpenSans-ExtraBold-webfont.svg | 251 - .../fonts/OpenSans-ExtraBold-webfont.ttf | Bin 30404 -> 0 bytes .../fonts/OpenSans-ExtraBold-webfont.woff | Bin 19972 -> 0 bytes .../OpenSans-ExtraBoldItalic-webfont.eot | Bin 33758 -> 0 bytes .../OpenSans-ExtraBoldItalic-webfont.svg | 251 - .../OpenSans-ExtraBoldItalic-webfont.ttf | Bin 33532 -> 0 bytes .../OpenSans-ExtraBoldItalic-webfont.woff | Bin 21824 -> 0 bytes .../public/fonts/OpenSans-Italic-webfont.eot | Bin 34798 -> 0 bytes .../public/fonts/OpenSans-Italic-webfont.svg | 251 - .../public/fonts/OpenSans-Italic-webfont.ttf | Bin 34612 -> 0 bytes .../public/fonts/OpenSans-Italic-webfont.woff | Bin 22416 -> 0 bytes .../public/fonts/OpenSans-Light-webfont.eot | Bin 29794 -> 0 bytes .../public/fonts/OpenSans-Light-webfont.svg | 252 - .../public/fonts/OpenSans-Light-webfont.ttf | Bin 29612 -> 0 bytes .../public/fonts/OpenSans-Light-webfont.woff | Bin 19396 -> 0 bytes .../fonts/OpenSans-LightItalic-webfont.eot | Bin 34578 -> 0 bytes .../fonts/OpenSans-LightItalic-webfont.svg | 252 - .../fonts/OpenSans-LightItalic-webfont.ttf | Bin 34368 -> 0 bytes .../fonts/OpenSans-LightItalic-webfont.woff | Bin 22444 -> 0 bytes .../public/fonts/OpenSans-Regular-webfont.eot | Bin 29934 -> 0 bytes .../public/fonts/OpenSans-Regular-webfont.svg | 252 - .../public/fonts/OpenSans-Regular-webfont.ttf | Bin 29744 -> 0 bytes .../fonts/OpenSans-Regular-webfont.woff | Bin 19624 -> 0 bytes .../fonts/OpenSans-Semibold-webfont.eot | Bin 30350 -> 0 bytes .../fonts/OpenSans-Semibold-webfont.svg | 251 - .../fonts/OpenSans-Semibold-webfont.ttf | Bin 30156 -> 0 bytes .../fonts/OpenSans-Semibold-webfont.woff | Bin 19736 -> 0 bytes .../fonts/OpenSans-SemiboldItalic-webfont.eot | Bin 34866 -> 0 bytes .../fonts/OpenSans-SemiboldItalic-webfont.svg | 251 - .../fonts/OpenSans-SemiboldItalic-webfont.ttf | Bin 34644 -> 0 bytes .../OpenSans-SemiboldItalic-webfont.woff | Bin 22332 -> 0 bytes .../iot/units/theme/public/fonts/fontwso2.eot | Bin 34828 -> 0 bytes .../iot/units/theme/public/fonts/fontwso2.svg | 124 - .../iot/units/theme/public/fonts/fontwso2.ttf | Bin 34660 -> 0 bytes .../units/theme/public/fonts/fontwso2.woff | Bin 34736 -> 0 bytes .../fonts/glyphicons-halflings-regular.eot | Bin 20335 -> 0 bytes .../fonts/glyphicons-halflings-regular.svg | 229 - .../fonts/glyphicons-halflings-regular.ttf | Bin 41280 -> 0 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 23320 -> 0 bytes .../theme/public/images/content-bg-1.png | Bin 29835 -> 0 bytes .../units/theme/public/images/content-bg.png | Bin 11641 -> 0 bytes .../units/theme/public/js/bootstrap.min.js | 7 - .../units/theme/public/js/html5shiv.min.js | 7 - .../theme/public/js/jquery-1.11.2.min.js | 5 - .../iot/units/theme/public/js/jquery.min.js | 5 - .../iot/units/theme/public/js/respond.min.js | 5 - .../iot/units/theme/public/js/toggle.js | 11 - .../theme/public/scripts/validate-register.js | 140 - .../jaggeryapps/iot/units/theme/theme.hbs | 27 - .../jaggeryapps/iot/units/theme/theme.json | 3 - 195 files changed, 74513 deletions(-) delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/api/device-api.jag delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/api/stats-api.jag delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/api/user-api.jag delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/config/config.json delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/config/dc-props.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/config/init.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/jaggery.conf delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/layouts/enrollment.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/layouts/fluid.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/layouts/nav-fluid.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/lib/acs.jag delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/lib/fuse-router.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/lib/fuse.jag delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/lib/fuse.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/lib/handlebars-helpers.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/lib/handlebars-v2.0.0.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/lib/less-rhino-1.7.5.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/lib/login.jag delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/lib/logout.jag delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/modules/constants.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/modules/device.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/modules/download.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/modules/pinch.min.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/modules/sso.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/modules/user.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/modules/utility.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/pages/alldevices.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/pages/arduino.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/pages/digitaldisplay.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/pages/firealarm.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/pages/index.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/pages/login.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/pages/mydevice.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/pages/sensebot.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/test/testExecutor.jag delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/tmp/cached_theme_less_base.css delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/alldevices.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/alldevices.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/alldevices.json delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/public/js/alldevices_util.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/appbar/appbar.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/appbar/appbar.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/appbar/appbar.json delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/appbar/public/images/logo.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/arduino.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/arduino.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/arduino.json delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/public/images/arduino-thumb.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/public/images/arduino.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/digitaldisplay.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/digitaldisplay.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/digitaldisplay.json delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/public/images/digitaldisplay-thumb.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/public/images/digitaldisplay.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/firealarm.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/firealarm.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/firealarm.json delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/public/images/firealarm-thumb.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/public/images/firealarm.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot/public/images/schematicsGuide.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot/public/images/sensebot-thumb.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot/public/images/sensebot.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot/sensebot.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot/sensebot.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot/sensebot.json delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/css/daterangepicker.css delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/css/nv.d3.css delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/images/bulb-off.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/images/bulb-on.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/images/fan.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/images/temp.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/bulb.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/cumulativelinechart.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/d3.min.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/date-range.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/discretebarchart.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/graph_util.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/jquery.daterangepicker.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/light_graph.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/linewithfocuschart.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/moment.min.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/motion_graph.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/nv.d3.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/sonar_graph.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/stream_layers.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/public/js/temperature_graph.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/sensebot_nologin.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/sensebot_nologin.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/devices/sensebot_nologin/sensebot_nologin.json delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/login/login.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/login/login.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/login/login.json delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/login/public/js/login-box.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/mydevice.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/mydevice.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/mydevice.json delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/css/daterangepicker.css delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/css/graph.css delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/css/lines.css delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/css/nv.d3.css delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/images/bulb-off.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/images/bulb-on.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/images/fan.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/images/temp.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/Chart.min.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/bulb.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/d3.min.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/d3.v3.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graph_util.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/bulb_graph.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/fan_graph.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/light_graph.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/motion_graph.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/sonar_graph.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/temperature_graph.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/jquery.daterangepicker.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/moment.min.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/nv.d3.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/rickshaw.min.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/stream_layers.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/RaspberryPi.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/arduino-thumb.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/banner-img-3.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/beagleBone.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/digitaldisplay-thumb.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/firealarm-thumb.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/intel.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/sensebot-thumb.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/showcase/showcase.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/showcase/showcase.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/showcase/showcase.json delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/css/bootstrap.min.css delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/css/custom-theme.css delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/css/fontwso2-extend.css delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/css/fontwso2.css delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/css/main.css delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Bold-webfont.eot delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Bold-webfont.svg delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Bold-webfont.ttf delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Bold-webfont.woff delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-BoldItalic-webfont.eot delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-BoldItalic-webfont.svg delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-BoldItalic-webfont.ttf delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-BoldItalic-webfont.woff delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-ExtraBold-webfont.eot delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-ExtraBold-webfont.svg delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-ExtraBold-webfont.ttf delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-ExtraBold-webfont.woff delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-ExtraBoldItalic-webfont.eot delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-ExtraBoldItalic-webfont.svg delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-ExtraBoldItalic-webfont.ttf delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-ExtraBoldItalic-webfont.woff delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Italic-webfont.eot delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Italic-webfont.svg delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Italic-webfont.ttf delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Italic-webfont.woff delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Light-webfont.eot delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Light-webfont.svg delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Light-webfont.ttf delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Light-webfont.woff delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-LightItalic-webfont.eot delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-LightItalic-webfont.svg delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-LightItalic-webfont.ttf delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-LightItalic-webfont.woff delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Regular-webfont.eot delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Regular-webfont.svg delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Regular-webfont.ttf delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Regular-webfont.woff delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Semibold-webfont.eot delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Semibold-webfont.svg delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Semibold-webfont.ttf delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-Semibold-webfont.woff delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-SemiboldItalic-webfont.eot delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-SemiboldItalic-webfont.svg delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-SemiboldItalic-webfont.ttf delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/OpenSans-SemiboldItalic-webfont.woff delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/fontwso2.eot delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/fontwso2.svg delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/fontwso2.ttf delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/fontwso2.woff delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/glyphicons-halflings-regular.eot delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/glyphicons-halflings-regular.svg delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/glyphicons-halflings-regular.ttf delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/fonts/glyphicons-halflings-regular.woff delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/images/content-bg-1.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/images/content-bg.png delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/js/bootstrap.min.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/js/html5shiv.min.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/js/jquery-1.11.2.min.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/js/jquery.min.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/js/respond.min.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/js/toggle.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/public/scripts/validate-register.js delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/theme.hbs delete mode 100644 modules/distribution/src/repository/jaggeryapps/iot/units/theme/theme.json diff --git a/modules/distribution/src/repository/jaggeryapps/iot/api/device-api.jag b/modules/distribution/src/repository/jaggeryapps/iot/api/device-api.jag deleted file mode 100644 index aa2275f3..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/api/device-api.jag +++ /dev/null @@ -1,85 +0,0 @@ -<% -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -var uri = request.getRequestURI(); -var uriMatcher = new URIMatcher(String(uri)); - -var log = new Log("api/device-api.jag"); - -var constants = require("/modules/constants.js"); -var dcProps = require('/config/dc-props.js').config(); - -var deviceModule = require("/modules/user.js").deviceModule; - -var carbon = require('carbon'); -var carbonHttpServletTransport = carbon.server.address('http'); -var carbonHttpsServletTransport = carbon.server.address('https'); - -var result; - -if (uriMatcher.match("/{context}/api/device/sketch/download")) { - sketchType = request.getParameter("sketchType"); - deviceType = request.getParameter("deviceType"); - - if (!sketchType) { - log.error("Sketch Type is empty"); - } - - var user = session.get(constants.USER_SESSION_KEY); - if (!user) { - response.sendRedirect(dcProps.appContext + "login?#login-required"); - exit(); - } - - //URL: https://localhost:9443/{deviceType}/download?owner={username} - deviceManagerService = carbonHttpsServletTransport + "/" + deviceType + "/manager"; - sketchDownloadEndPoint = deviceManagerService + "/device/" + sketchType + "/download"; - response.sendRedirect(sketchDownloadEndPoint + "?owner=" + user.username); - exit();//stop execution - -} else if (uriMatcher.match("/{context}/api/devices/all")) { - var user = session.get(constants.USER_SESSION_KEY); - if (!user) { - response.sendRedirect(dcProps.appContext + "login?#login-required"); - exit();//stop execution - } - - //URL: https://localhost:9443/devicecloud/manager/devices/username/{username} - deviceCloudService = carbonHttpsServletTransport + "/devicecloud/manager"; - listAllDevicesEndPoint = deviceCloudService + "/devices/username/" + user.username; - - var data = {}; - //XMLHTTPRequest's GET - result = get(listAllDevicesEndPoint, data, "json"); - -} else if (uriMatcher.match("/{context}/api/devices/types")) { - var user = session.get(constants.USER_SESSION_KEY); - if (!user) { - response.sendRedirect(dcProps.appContext + "login?#login-required"); - exit();//stop execution - } - - result = deviceModule.getAllDevicesTypes(); -} - -// returning the result. -if (result) { - print(result); -} -%> diff --git a/modules/distribution/src/repository/jaggeryapps/iot/api/stats-api.jag b/modules/distribution/src/repository/jaggeryapps/iot/api/stats-api.jag deleted file mode 100644 index 5fec123a..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/api/stats-api.jag +++ /dev/null @@ -1,105 +0,0 @@ -<% -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -var uri = request.getRequestURI(); -var uriMatcher = new URIMatcher(String(uri)); - -var log = new Log("api/stats-api.jag"); - -var constants = require("/modules/constants.js"); -var dcProps = require('/config/dc-props.js').config(); -var utility = require("/modules/utility.js").utility; - -var result; -var statsClient = new Packages.org.wso2.carbon.device.mgt.iot.common.analytics.statistics.IoTUsageStatisticsClient; - -if (uriMatcher.match("/{context}/api/stats")) { - - deviceId = request.getParameter("deviceId"); - deviceType = request.getParameter("deviceType"); - from = request.getParameter("from"); - to = request.getParameter("to"); - - user = session.get(constants.USER_SESSION_KEY); - if (!user) { - response.sendRedirect(dcProps.appContext + "login?#login-required"); - exit(); - } - - log.info("deviceId : " + deviceId + " from : " + from + " to : " + to); - if(deviceType=="firealarm"){ - result = getFireAlarmData(user.username, deviceId, from, to); - }else if(deviceType=="sensebot"){ - result = getSensebotData(user.username, deviceId, from, to); - } -} - -// returning the result. -if (result) { - print(result); -} - -function getSensebotData(user, deviceId, from, to){ - result = new Object(); - result['sonarData'] = getSensorData("SONAR_SENSOR_SUMMARY","sonar",user, deviceId, from, to); - result['motionData'] = getSensorData("PIR_MOTION_SENSOR_SUMMARY","motion",user, deviceId, from, to); - result['lightData'] = getSensorData("LDR_LIGHT_SENSOR_SUMMARY","light",user, deviceId, from, to); - result['temperatureData'] = getSensorData("DEVICE_TEMPERATURE_SUMMARY","TEMPERATURE",user, deviceId, from, to); - return result; -} - - -function getFireAlarmData(user, deviceId, from, to){ - result = new Object(); - - //result['sonarData'] = getSensorData("SONAR_SENSOR_SUMMARY","sonar",user, deviceId, from, to); - //result['motionData'] = getSensorData("PIR_MOTION_SENSOR_SUMMARY","motion",user, deviceId, from, to); - //result['lightData'] = getSensorData("LDR_LIGHT_SENSOR_SUMMARY","light",user, deviceId, from, to); - - result['temperatureData'] = getSensorData("DEVICE_TEMPERATURE_SUMMARY","TEMPERATURE",user, deviceId, from, to); - result['fanData'] = getSensorData("DEVICE_FAN_USAGE_SUMMARY","status",user, deviceId, from, to); - result['bulbData'] = getSensorData("DEVICE_BULB_USAGE_SUMMARY","status",user, deviceId, from, to); - return result; -} - -function getSensorData(table, column, user, deviceId, from, to) { - - var fetchedData = null; - - try { - fetchedData = statsClient.getDeviceStats(table, column, user, deviceId, from, to); - }catch(error){ - log.info(error); - } - - var temperatureData = []; - - if(fetchedData==null) return []; - - for (var i = 0; i < fetchedData.size(); i++) { - temperatureData.push({ - time: fetchedData.get(i).getTime(), - value: fetchedData.get(i).getValue() - }); - } - - return temperatureData; -} - -%> \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/api/user-api.jag b/modules/distribution/src/repository/jaggeryapps/iot/api/user-api.jag deleted file mode 100644 index 6658fda0..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/api/user-api.jag +++ /dev/null @@ -1,149 +0,0 @@ -<% -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -var uri = request.getRequestURI(); -var uriMatcher = new URIMatcher(String(uri)); - -var log = new Log("api/user-api.jag"); - -var constants = require("/modules/constants.js"); -var dcProps = require('/config/dc-props.js').config(); -var userModule = require("/modules/user.js").userModule; -var utility = require("/modules/utility.js").utility; - -var result; - -if (uriMatcher.match("/{context}/api/user/login/")) { - - var username = request.getParameter("username"); - var password = request.getParameter("password"); - var redirect = request.getParameter("redirect"); - - try { - userModule.login(username, password, function (user) { - utility.insertAppPermissions(userModule, "login"); - if (log.isDebugEnabled()) { - log.debug("User Logged In : " + user); - } - if(redirect==null){ - response.sendRedirect(constants.WEB_APP_CONTEXT); - }else{ - - result=200; - } - }, function () { - - if(redirect==null){ - response.sendRedirect(dcProps.appContext + "login?#auth-failed"); - }else{ - - result=401; - } - }); - } catch (e) { - log.error("Exception occurred while a user tried to login to DC", e); - response.sendRedirect(dcProps.appContext + "login?#error"); - - } - -} else if (uriMatcher.match("/{context}/api/user/logout/")) { - - userModule.logout(function () { - response.sendRedirect(dcProps.appContext + "login"); - }); - -} else if (uriMatcher.match("/{context}/api/users/register")) { - - addUserFormData = request.getContent(); - username = addUserFormData.username; - firstname = addUserFormData.firstname; - lastname = addUserFormData.lastname; - emailAddress = addUserFormData.emailAddress; - password = addUserFormData.password; - - if (!addUserFormData.userRoles) { - userRoles = null; - } else { - userRoles = String(addUserFormData.userRoles).split(","); - } - - try { - result = userModule.registerUser(username, firstname, lastname, emailAddress, password, - userRoles); - } catch (e) { - log.error("Exception occurred while trying to registering a new user to DC User Store", e); - // http status code 400 refers to - Bad request. - result = 400; - } - -} else if (uriMatcher.match("/{context}/api/users/add")) { - - if (userModule.isAuthorized("/permission/device-mgt/admin/users/add")) { - - addUserFormData = request.getContent(); - username = addUserFormData.username; - firstname = addUserFormData.firstname; - lastname = addUserFormData.lastname; - emailAddress = addUserFormData.emailAddress; - - if (!addUserFormData.userRoles) { - userRoles = null; - } else { - userRoles = String(addUserFormData.userRoles).split(","); - } - - try { - result = userModule.addUser(username, firstname, lastname, emailAddress, userRoles); - } catch (e) { - log.error("Exception occurred while trying to add a user to DC User Store", e); - // http status code 400 refers to - Bad request. - result = 400; - } - } else { - // http status code 403 refers to - forbidden. - result = 403; - } - -} else if (uriMatcher.match("/{context}/api/users/{username}/remove")) { - - if (userModule.isAuthorized("/permission/device-mgt/admin/users/remove")) { - - elements = uriMatcher.elements(); - username = elements.username; - - try { - result = userModule.removeUser(username); - } catch (e) { - log.error("Exception occurred while trying to remove a user from DC User Store", e); - // http status code 400 refers to - Bad request. - result = 400; - } - - } else { - // http status code 403 refers to - forbidden. - result = 403; - } - -} - -// returning the result. -if (result) { - print(result); -} -%> diff --git a/modules/distribution/src/repository/jaggeryapps/iot/config/config.json b/modules/distribution/src/repository/jaggeryapps/iot/config/config.json deleted file mode 100644 index 95a917df..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/config/config.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "appContext" : "/iot/", - "apiContext" : "api", - "httpsURL": "%https.ip%", - "httpURL": "%http.ip%", - "ssoConfiguration": { - "enabled": false, - "issuer": "iot", - "appName": "iot", - "identityProviderURL": "%https.ip%/sso/samlsso.jag", - "responseSigningEnabled": "true", - "keyStorePassword": "wso2carbon", - "identityAlias": "wso2carbon", - "keyStoreName": "/repository/resources/security/wso2carbon.jks" - } -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/config/dc-props.js b/modules/distribution/src/repository/jaggeryapps/iot/config/dc-props.js deleted file mode 100644 index 7911f514..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/config/dc-props.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -var config = function () { - var conf = application.get("PINCH_CONFIG"); - if (!conf) {//if not in cache - var pinch = require('/modules/pinch.min.js').pinch; - var server = require('carbon').server; - var config = require('/config/config.json'); - pinch(config, /^/, function (path, key, value) { - if ((typeof value === 'string') && value.indexOf('%https.ip%') > -1) { - return value.replace('%https.ip%', server.address("https")); - } else if ((typeof value === 'string') && value.indexOf('%http.ip%') > -1) { - return value.replace('%http.ip%', server.address("http")); - } - return value; - }); - application.put("PINCH_CONFIG", config);//caching - conf = config; - } - return conf; -}; \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/config/init.js b/modules/distribution/src/repository/jaggeryapps/iot/config/init.js deleted file mode 100644 index d492ae79..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/config/init.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -var carbonModule = require("carbon"); -var dcProps = require('/config/dc-props.js').config(); -var carbonServer = new carbonModule.server.Server({ - tenanted: true, - url: dcProps.httpsURL + '/admin' -}); -application.put("carbonServer", carbonServer); -var userModule = require("/modules/user.js").userModule; -var utility = require("/modules/utility.js").utility; -utility.insertAppPermissions(userModule, "init"); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/jaggery.conf b/modules/distribution/src/repository/jaggeryapps/iot/jaggery.conf deleted file mode 100644 index 9d723c35..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/jaggery.conf +++ /dev/null @@ -1,47 +0,0 @@ -{ - "displayName": "Fuse Sample", - "logLevel": "info", - "initScripts": ["/config/init.js"], - "urlMappings": [ - { - "url" : "/test/*", - "path" : "test/testExecutor.jag" - }, - { - "url": "/api/device/*", - "path": "/api/device-api.jag" - }, - { - "url": "/api/devices/*", - "path": "/api/device-api.jag" - }, - { - "url": "/api/user/*", - "path": "/api/user-api.jag" - }, - { - "url": "/api/users/*", - "path": "/api/user-api.jag" - }, - { - "url": "/api/stats/*", - "path": "/api/stats-api.jag" - }, - { - "url": "/sso/login", - "path": "/lib/login.jag" - }, - { - "url": "/sso/logout", - "path": "/lib/logout.jag" - }, - { - "url": "/sso/acs", - "path": "/lib/acs.jag" - }, - { - "url": "/*", - "path": "/lib/fuse.jag" - } - ] -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/layouts/enrollment.hbs b/modules/distribution/src/repository/jaggeryapps/iot/layouts/enrollment.hbs deleted file mode 100644 index 388ca0d4..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/layouts/enrollment.hbs +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - {{ defineZone "title"}} - - {{ defineZone "topLibCss"}} - {{ defineZone "topCss"}} - - -
- -
-
- -
-
- - {{ defineZone "body"}} -
- {{ defineZone "bottomjquery" }} - {{ defineZone "bottomLibJs" }} - {{ defineZone "bottomJs" }} - - diff --git a/modules/distribution/src/repository/jaggeryapps/iot/layouts/fluid.hbs b/modules/distribution/src/repository/jaggeryapps/iot/layouts/fluid.hbs deleted file mode 100644 index 1c9a5847..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/layouts/fluid.hbs +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - {{ defineZone "title"}} - {{ defineZone "topLibCss"}} - {{ defineZone "topCss"}} - {{ defineZone "topJs"}} - - -
- - {{ defineZone "header"}} - - {{ defineZone "body"}} -
- {{ defineZone "bottomLibJs" }} - {{ defineZone "bottomJs" }} - - diff --git a/modules/distribution/src/repository/jaggeryapps/iot/layouts/nav-fluid.hbs b/modules/distribution/src/repository/jaggeryapps/iot/layouts/nav-fluid.hbs deleted file mode 100644 index 00278772..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/layouts/nav-fluid.hbs +++ /dev/null @@ -1,50 +0,0 @@ - - - - - {{ defineZone "title"}} - {{ defineZone "topCss"}} - - - - -
-
- -
-
- {{ defineZone "left"}} -
- -
- {{ defineZone "content"}} -
-
- -
- -
- - - - diff --git a/modules/distribution/src/repository/jaggeryapps/iot/lib/acs.jag b/modules/distribution/src/repository/jaggeryapps/iot/lib/acs.jag deleted file mode 100644 index 147c20a2..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/lib/acs.jag +++ /dev/null @@ -1,49 +0,0 @@ -<% -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -var dataConfig = require('/config/dc-props.js').config(); -var sso = require('/modules/sso.js').sso; -var constants = require('/modules/constants.js'); -var carbonModule = require("carbon"); -var log = new Log(); -var keyStoreParams = { - keyStoreName: dataConfig.ssoConfiguration.keyStoreName, - keyStorePassword: dataConfig.ssoConfiguration.keyStorePassword, - identityAlias: dataConfig.ssoConfiguration.identityAlias -}; -sso.configure(dataConfig.ssoConfiguration.issuer, - dataConfig.ssoConfiguration.appName, - keyStoreParams, dataConfig.ssoConfiguration.identityProviderURL); -sso.acs( - function(loggedInUser) { - var carbonUser = carbonModule.server.tenantUser(loggedInUser); - session.put(constants.USER_SESSION_KEY, carbonUser); - var username = carbonUser.username; - if(log.isDebugEnabled()){ - log.debug("User logged in: "+username); - } - response.sendRedirect(dataConfig.appContext); - }, function() { - if(log.isDebugEnabled()){ - log.debug("User logged out"); - } - response.sendRedirect(dataConfig.appContext); - } -); -%> \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/lib/fuse-router.js b/modules/distribution/src/repository/jaggeryapps/iot/lib/fuse-router.js deleted file mode 100644 index db673316..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/lib/fuse-router.js +++ /dev/null @@ -1,242 +0,0 @@ -//public function declarations -var route; - -(function () { - - //public - /** - * front controller entity point. acts as the main function for every request. - */ - route = function () { - //lets assume URL looks like https://my.domain.com/app/{one}/{two}/{three}/{four} - var uri = request.getRequestURI(); // = app/{one}/{two}/{three}/{four} - var parts = splitFirst(uri); - fuseState.appName = parts.head; - var path = parts.tail; // = /{one}/{two}/{three}/{four} - var handled = false; - - parts = splitFirst(path); - if (parts.head == 'public') { // {one} == 'public' - parts = splitFirst(parts.tail); - if (splitFirst(parts.tail).head == 'less') { // {three} == 'less' - handled = renderLess(parts.head, parts.tail); // renderLess({two},{three}/{four}) - } else { - handled = renderStatic(parts.head, parts.tail); - } - } else { - handled = renderPage(path); - if (!handled) { - handled = renderUnit(path); - } - } - - if (!handled) { - response.sendError(404, 'Requested resource not found'); - } - - }; - - - //private - var log = new Log('fuse.router'); - - var getMime = function (path) { - var index = path.lastIndexOf('.') + 1; - var knowMime = { - 'js': 'application/javascript', - 'html': 'text/html', - 'htm': 'text/html', - 'woff': 'application/x-font-woff', - "png": "image/png", - "css": "text/css", - "hbs": "text/x-handlebars-template", - "apk": "application/vnd.android.package-archive", - "ipa": "application/octet-stream" - }; - var mime; - if (index >= 0) { - mime = knowMime[path.substr(index)]; - } - return mime || 'text/plain'; - }; - - /** - * '/a/b/c/d' -> {'a','b/c/d'} - * @param path URI part, should start with '/' - * @returns {{head: string, tail: string}} - */ - var splitFirst = function (path) { - var firstSlashPos = path.indexOf('/', 1); - var head = path.substring(1, firstSlashPos); - var tail = path.substring(firstSlashPos); - return {head: head, tail: tail}; - }; - - /** - * @param str - * @param prefix - * @returns {boolean} true iif str starts with prefix - */ - var startsWith = function (str, prefix) { - return (str.lastIndexOf(prefix, 0) === 0); - }; - - var renderStatic = function (unit, path) { - var unitModel = null; - var unitName = ""; - var parts = (unit + path).split("/"); - - //'unitName' name can be "unitA" or "categoryA/unitA" or "categoryA/categoryAb/unitB"...etc - //incrementally trying to resolve a unit using url path parts. - for (var i = 0; i < parts.length; i++) { - - if (unitName == "") { - unitName = parts[i]; - } else { - unitName += "/" + parts[i]; - } - - try { - var model = fuse.getUnitDefinition(unitName); - if (model) { - unitModel = { - name: model.name, - path: parts.splice(i + 1).join("/") - }; - break; - } - } catch (err) { - //unit not found, ignore error - } - } - - if (unitModel == null) { - throw '[' + requestId + '] unit "' + unit + path + '" does not exits'; - } - - var staticFile = fuse.getFile(unitModel.name, 'public' + "/" + unitModel.path); - - if (staticFile.isExists() && !staticFile.isDirectory()) { - response.addHeader('Content-type', getMime(path)); - response.addHeader('Cache-Control', 'public,max-age=12960000'); - staticFile.open('r'); - var stream = staticFile.getStream(); - print(stream); - staticFile.close(); - return true; - } - return false; - }; - - var renderPage = function (path) { - var jagFile; - if (path.indexOf('/', path.length - 1) !== -1) { - jagFile = new File('/pages' + path + 'index.jag'); - } else { - jagFile = new File('/pages' + path + '.jag'); - } - if (jagFile.isExists()) { - include(jagFile.getPath()); - return true; - }else{ - return false; - } - }; - - var renderUnit = function (path) { - var mainUnit = null; - var matchedUnits = fuse.getMatchedUnitDefinitions(); - fuse.addDependencies(matchedUnits); - var zones = fuseState.zones; - - // A map of maps. this is used to ensure same zone is not render twice in to same definition. - // zonesAdded = { titleZone : { zoneFromA : true, zoneFromB : true } } - var zonesAdded = {}; - - for (var i = 0; i < matchedUnits.length; i++) { - var definition = matchedUnits[i]; - - for (var j = 0; j < definition.zones.length; j++) { - var zone = definition.zones[j]; - if (!zones[zone.name]) { - zones[zone.name] = []; - zonesAdded[zone.name] = {}; - } - var zoneKey = zone.origin + ':' + zone.name; // temp unique key to identify zone form a given unit. - if (!zonesAdded[zone.name][zoneKey]) { - var zoneInfo = {unitName: definition.name}; - if (zone.origin != definition.name) { - zoneInfo.originUnitName = zone.origin; - } - zones[zone.name].push(zoneInfo); - zonesAdded[zone.name][zoneKey] = true; - } - } - - } - - var layout = fuseState.layout; - if (layout !== null) { - log.debug( - '[' + requestId + '] request for "' + path + '" will be rendered using layout "' + - layout + '" (defined in "' + mainUnit + '") and zones ' + - stringify(zones) - ); - - var output = handlebars.Handlebars.compileFile(fuse.getLayoutPath(layout))({}); - response.addHeader('Content-type', 'text/html'); - print(output); - return true; - } else { - log.debug( - '[' + requestId + '] request for "' + path + '" will can\'t be rendered, since no layout is defined' + - 'in any of the units ' + stringify(zones)); - return false; - } - }; - - function fileToString(path) { - } - - /** - * convert less file to css and print to output. add '?nocache=true' to force regenerate. - * @param unit name of the unit - * @param path the path to the less file relative to unit root (should start with slash) - * @returns {boolean} is successfully rendered. - */ - function renderLess(unit, path) { - //TODO: fix - incorrect less files makes it respond the old less even if it is nocahce. - log.debug('[' + requestId + '] for unit "' + unit + '" a request received for a less file "' + path + '"'); - var cacheKey = '/tmp/cached_' + unit + path.replace(/[^\w\.-]/g, '_'); - fuseState.currentUnit = unit; - var cachedCss = new File(cacheKey); - - //TODO: move this check to caller function ?? - if (fuseDebug || request.getParameter('nocache') == 'true' || !cachedCss.isExists()) { - var parts = splitFirst(path); - var lessPath = '/public/less' + parts.tail.replace(/\.css$/, '') + '.less'; - var lessFile = fuse.getFile(unit, lessPath); - - if (lessFile.isExists()) { - var x = require('less-rhino-1.7.5.js'); - x.compile([lessFile.getPath(), cacheKey]); - log.debug('[' + requestId + '] for unit "' + unit + '" request for "' + path + '" is cached as "' + cacheKey + '"'); - } - } - - - if (cachedCss.isExists()) { - response.addHeader('Content-type', 'text/css'); - response.addHeader('Cache-Control', 'public,max-age=12960000'); - cachedCss.open('r'); - var stream = cachedCss.getStream(); - print(stream); - cachedCss.close(); - return true; - } - return false; - - } - - -})(); diff --git a/modules/distribution/src/repository/jaggeryapps/iot/lib/fuse.jag b/modules/distribution/src/repository/jaggeryapps/iot/lib/fuse.jag deleted file mode 100644 index 597c9970..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/lib/fuse.jag +++ /dev/null @@ -1,29 +0,0 @@ -<% - -//global object to pass request stat among fuse framework files. -var fuseState = { - zones: {}, - appName: '', - zoneStack: [], - currentUnit: null -}; - -var requestId = function makeId() { - var text = ""; - var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - for (var i = 0; i < 5; i++) - text += possible.charAt(Math.floor(Math.random() * possible.length)); - - return text; -}(); -var fuseDebug = false; -//var fuseDebug = true; - -var handlebars = require('handlebars-helpers.js'); -var fuseRouter = require('fuse-router.js'); -var fuse = require('fuse.js'); - - -fuseRouter.route(); - -%> diff --git a/modules/distribution/src/repository/jaggeryapps/iot/lib/fuse.js b/modules/distribution/src/repository/jaggeryapps/iot/lib/fuse.js deleted file mode 100644 index 85672ae4..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/lib/fuse.js +++ /dev/null @@ -1,453 +0,0 @@ -//public function declarations -var getHbsFile, getFile, toRelativePath, cleanupAncestors, - getUnitPath, getMatchedUnitDefinitions, getZoneDefinition, getUnitDefinition, - getUnitDefinitions, getLayoutPath, readUnitDefinitions; - -(function () { - //private - var log = new Log('fuse.core'); - var lookUpTable = null; - var definitions = null; - - var initLookUp = function (definitions) { - if (lookUpTable === null) { - lookUpTable = {}; - for (var i = 0; i < definitions.length; i++) { - var definition = definitions[i]; - lookUpTable[definition.name] = i; - //log.info("initLookUp()"+definition.name+"<-"+i); - } - } - }; - - var isMatched = function (definition, layout) { - var urlMatch = function (pattern) { - var uriMatcher = new URIMatcher(request.getRequestURI()); - return Boolean(uriMatcher.match('/{appName}' + pattern)); - }; - var permission = function (permissionStr) { - var carbonModule = require("carbon"); - var carbonServer = application.get("carbonServer"); - var carbonUser = session.get("USER"); - if (carbonUser) { - var userManager = new carbonModule.user.UserManager(carbonServer, carbonUser.tenantId); - var user = new carbonModule.user.User(userManager, carbonUser.username); - return user.isAuthorized(permissionStr, "ui.execute"); - } - return false; - }; - var config = {'theme': 'default'}; - var predicateStr = definition.definition.predicate; - if (predicateStr) { - var js = 'function(config,urlMatch,permission,layout){ return ' + predicateStr + ';}'; - return Boolean(eval(js)(config, urlMatch,permission, layout ? layout : NaN)); - } - return false; - }; - - var getAncestorModels = function (unit) { - //log.info('[' + requestId + '] getAncestorModels()'+unit); - var unitModel = getUnitDefinition(unit); - var ancestors = [unitModel]; - var parentName; - while ((parentName = unitModel.definition.extends) != null) { - unitModel = getUnitDefinition(parentName); - ancestors.push(unitModel); - } - return ancestors; - }; - - addDependencies = function (unitModels) { - var resolved = {}; - for (var i = 0; i < unitModels.length; i++) { - resolved[unitModels[i].name] = true; - } - - for (i = 0; i < unitModels.length; i++) { - var unitModel = unitModels[i]; - var dependencies = unitModel.definition.dependencies; - if (dependencies) { - for (var j = 0; j < dependencies.length; j++) { - var dependencyName = dependencies[j]; - unitModels.push(getUnitDefinition(dependencyName)); - resolved[dependencyName] = true; - } - } - } - - - }; - - - //public - getMatchedUnitDefinitions = function () { - //TODO: return map not list - var unitDefinitions = getUnitDefinitions(); - var matched = []; - var unMatched = []; - var layout = null; - var mainUnit = null; - - var addToMatched = function (model) { - matched.push(model); - if (model.layout) { - if (layout == null) { - layout = model.layout; - mainUnit = model.name; - } else { - log.warn( - '[' + requestId + '] multiple layouts ' + mainUnit + ':' + - layout + ' vs ' + model.name + ':' + model.layout - ); - } - } - }; - - - // first pass - for (var i = 0; i < unitDefinitions.length; i++) { - var unitDefinition = unitDefinitions[i]; - if (isMatched(unitDefinition)) { - addToMatched(unitDefinition); - } else { - unMatched.push(unitDefinition); - } - } - - fuseState.layout = layout; - - // second pass : we have to do this two passes since we don't know the layout - // first time around - if (layout) { - for (i = 0; i < unMatched.length; i++) { - unitDefinition = unMatched[i]; - if (isMatched(unitDefinition, layout)) { - addToMatched(unitDefinition) - } - } - } - - - var toDelete = []; - - for (i = 0; i < matched.length; i++) { - var ancestors = getAncestorModels(matched[i].name); - for (var j = 1; j < ancestors.length; j++) { - var ancestor = ancestors[j]; - toDelete.push(ancestor.name); - } - } - - - for (i = matched.length - 1; i >= 0; i--) { - //log.info(matched[i].name); - if (toDelete.indexOf(matched[i].name) >= 0) { - matched.splice(i, 1); - } - } - - return matched; - }; - - getUnitDefinition = function (unit) { - //log.info('[' + requestId + '] getUnitDefinition()'+unit); - var definitions = getUnitDefinitions(); - initLookUp(definitions); - //log.info('[' + requestId + '] lookUpTable[unit]:'+unit); - var model = definitions[lookUpTable[unit]]; - if (!model) { - log.warn('[' + requestId + '] unit "' + unit + '" does not exits'); - throw '[' + requestId + '] unit "' + unit + '" does not exits'; - } - return model; - }; - - var flattenAllInheritance = function (unitModels) { - var hasFlattend = {}; - for (var i = 0; i < unitModels.length; i++) { - var model = unitModels[i]; - if (!hasFlattend[model]) { - var ancestors = getAncestorModels(model.name); - for (var j = ancestors.length - 1; j >= 1; j--) { - flattenInheritance(ancestors[j], ancestors[j - 1]); - } - } - } - }; - - var flattenInheritance = function (parent, child) { - var parentZones = parent.zones; - for (var i = 0; i < parentZones.length; i++) { - var parentZone = parentZones[i]; - child.zones.push(parentZone); - } - }; - - getUnitDefinitions = function () { - if (definitions !== null) { - return definitions; - } else { - definitions = []; - } - - var unitDirs = new File('/units').listFiles(); - - definitions = readUnitDefinitions("",unitDirs,definitions); - //log.info(definitions); - - addPageUnitDefinitions(definitions); - - initLookUp(definitions); - flattenAllInheritance(definitions); - - return definitions; - }; - - readUnitDefinitions = function(basePath, unitDirs, definitions){ - for (var i = 0; i < unitDirs.length; i++) { - - var unitDir = unitDirs[i]; - if (unitDir.isDirectory()) { - var unitName = unitDir.getName(); - //log.info("reading: "+unitName + " basePath:'" + basePath + "'"); - var definitionFile = new File(fuse.getUnitPath(basePath+unitName) + '/' + unitName + '.json'); - - if(definitionFile.isExists()) { - var unitModel = { - name: unitName, - path: unitDir.getPath() - }; - if(basePath!=""){ - unitModel.name = basePath + unitName; - } - - var path = definitionFile.getPath(); - log.debug('[' + requestId + '] reading file "' + path + '"'); - unitModel.definition = require(path); - - // add the information derived by parsing hbs file to the same model - var hbsMetadata = getHbsMetadata(unitModel); - unitModel.zones = hbsMetadata.zones; - if (hbsMetadata.layout) { - unitModel.layout = hbsMetadata.layout; - } - - definitions.push(unitModel); - - }else{ - var unitSubDirs = new File(fuse.getUnitPath(basePath+"/"+unitName)).listFiles(); - readUnitDefinitions(basePath+unitName+"/",unitSubDirs,definitions); - } - } - } - return definitions; - }; - - addPageUnitDefinitions = function (unitModels, dir) { - var pageFiles = new File(dir || '/pages').listFiles(); - for (var i = 0; i < pageFiles.length; i++) { - var pageFile = pageFiles[i]; - var fileName = pageFile.getName(); - if (pageFile.isDirectory()) { - addPageUnitDefinitions(unitModels, pageFile.getPath()) - } else if (fileName.indexOf('.hbs', fileName.length - 4) !== -1) { // File name ends with '.hbs' - - var isLeaf = true; - //path relative to app root - var relativePath = pageFile.getPath() - .substring(6 + pageFile.getPath().indexOf('/pages/'), pageFile.getPath().length - 4); - - if (relativePath.match(/\/index$/)) { - relativePath = relativePath.replace(/\/index$/, ''); - var parentFile = new File(pageFile.getPath().substr(0, pageFile.getPath().lastIndexOf('/'))); - var hasSiblings = parentFile.listFiles().length != 1; - if (hasSiblings) { - isLeaf = false; - } - } - - //this will be used as a name for the virtual unit, useful for debugging purposes. - var unitName = (relativePath == '' ? 'index' : relativePath.substr(1).replace(/\//, '-') ) + '-page'; - - var predicate = "urlMatch('" + relativePath + "')"; - // leaf is page that can handle multiple URLs. in this case it should have a wildcard at end. - // but since our current matcher doesn't support {/wildcard*} patten, "OR" ( || ) is used - if (isLeaf) { - predicate += " || urlMatch('" + relativePath + "/{+wildcard}')"; - } - var unitModel = { - name: unitName, - - path: pageFile.getPath(), - definition: {predicate: predicate} - }; - var hbsMetadata = getHbsMetadata(unitModel); - unitModel.zones = hbsMetadata.zones; - if (hbsMetadata.layout) { - unitModel.layout = hbsMetadata.layout; - } - - unitModels.push(unitModel); - } - } - }; - - - getLayoutPath = function (layout) { - return '/layouts/' + layout + '.hbs'; - }; - - getHbsFile = function (unit) { - // we determining if it's page unit or a proper unit - // by checking if path ends with '.hbs' - // TODO: improve getFile to do include this logic - if (unit.path.indexOf('.hbs', unit.path.length - 4) !== -1) { - return new File(unit.path); - } else { - if(unit.name.indexOf('/') !== -1){//a subcategory unit - var rawParts = unit.name.split("/"); - return new File(unit.path + '/' + rawParts[rawParts.length-1] + '.hbs'); - }else { - return new File(unit.path + '/' + unit.name + '.hbs'); - } - } - }; - - var getHbsMetadata = function (unit) { - var zoneDef = {'zones': []}; - var hbsFile = getHbsFile(unit); - if (!hbsFile.isExists()) { - log.error("Couldn't find .hbs file at: `" + unit.path + "`"); - return zoneDef; - } - var output = handlebars.Handlebars.compileFile(hbsFile)({}); - var zonesAndLayouts = output.trim().split(/\s+/gm); - for (var i = 0; i < zonesAndLayouts.length; i++) { - var name = zonesAndLayouts[i]; - if (name.lastIndexOf('zone_', 0) === 0) { - zoneDef.zones.push({name: name.substr(5), origin: unit.name}); - } else if (name.lastIndexOf('layout_', 0) === 0) { - zoneDef.layout = name.substr(7); - } - } - return zoneDef; - }; - - - getUnitPath = function (unit) { - return '/units/' + unit; - }; - - cleanupAncestors = function (units) { - var toDelete = {}; - var len = units.length; - for (var i = 0; i < len; i++) { - var unit = units[i]; - if (!toDelete[unit]) { - var ancestors = getAncestorModels(unit.name); - for (var j = 1; j < ancestors.length; j++) { - toDelete[ancestors[j].name] = unit; - } - } - } - while (len--) { - if (toDelete[units[len]]) { - log.debug( - '[' + requestId + '] unit "' + units[len] + - '" is overridden by "' + toDelete[units[len]] + '"' - ); - units.splice(len, 1); - } - } - }; - - toRelativePath = function (path) { - var start = 0; - if (path.lastIndexOf('/units/', 0) == 0) { - start = 7; // len('/units/') - } - var slashPos = path.indexOf('/', 7); - return { - unit: path.substring(start, slashPos), - path: path.substr(slashPos) - } - }; - - /** - * Get a file inside a unit by relative path. if the file is not available in the given unit, - * the closest ancestor's file will be returned. if an optional suffix is used the relative path is - * calculated as ( path + < unit name > + opt_suffix ). if no such a file exists a returned file object will - * point to provided unit's non-existing file location (not to any ancestors). - * - * @param unitName name of the unit - * @param path path relative to unit root. - * @param opt_suffix - * @returns {File} - */ - getFile = function (unitName, path, opt_suffix) { - //log.info("getFile() unitName:"+unitName+", path:"+path+", opt_suffix:"+opt_suffix); - var slashPath = ((path[0] === '/') ? '' : '/') + path; - var selfFileName = ''; - var fileName = ''; - if (opt_suffix) { - if(unitName.indexOf('/') !== -1) {//a subcategory unit - var rawParts = unitName.split("/"); - selfFileName = rawParts[rawParts.length - 1]; - }else { - selfFileName = unitName; - } - selfFileName = selfFileName + opt_suffix; - slashPath = slashPath + ((slashPath[slashPath.length - 1] === '/') ? '' : '/'); - } - - //TODO: remove this hack that makes in page-unit, any file is same - var unitDef = getUnitDefinition(unitName); - if (unitDef.path.indexOf('.hbs', unitDef.path.length - 4) !== -1) { - if (opt_suffix.indexOf('.hbs', opt_suffix.length - 4) !== -1) { - //log.info("1:"+unitDef.path); - return new File(unitDef.path); - } else { - //log.info("2:"+unitDef.path.replace(/.hbs$/, opt_suffix)); - return new File(unitDef.path.replace(/.hbs$/, opt_suffix)); - } - } - - var selfFile = new File(getUnitPath(unitName) + slashPath + selfFileName); - if (selfFile.isExists()) { - log.debug( - '[' + requestId + '] for unit "' + unitName + '" file resolved : "' - + slashPath + selfFileName + '" -> "' + selfFile.getPath() + '"' - ); - //log.info("3:"+getUnitPath(unitName) + slashPath + selfFileName); - return selfFile; - } - - var ancestors = getAncestorModels(unitName); - for (var i = 1; i < ancestors.length; i++) { - var ancestorName = ancestors[i].name; - if(ancestorName.indexOf('/') !== -1) {//a subcategory unit - var rawParts = ancestorName.split("/"); - ancestorName = rawParts[rawParts.length - 1]; - } - if (opt_suffix) { - fileName = ancestorName + opt_suffix; - } - var file = new File(getUnitPath(ancestorName) + slashPath + fileName); - if (file.isExists()) { - log.debug( - '[' + requestId + '] for unit "' + unitName + '" file resolved : "' - + slashPath + selfFileName + '" -> "' + file.getPath() + '"' - ); - //log.info("4:"+getUnitPath(ancestorName) + slashPath + fileName); - return file; - } - } - log.debug( - '[' + requestId + '] for unit "' + unitName + '" (non-excising) file resolved : "' - + slashPath + selfFileName + '" -> "' + selfFile.getPath() + '"' - ); - //log.info("5:"+getUnitPath(unitName) + slashPath + selfFileName); - return selfFile; - }; - -})(); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/lib/handlebars-helpers.js b/modules/distribution/src/repository/jaggeryapps/iot/lib/handlebars-helpers.js deleted file mode 100644 index 80342019..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/lib/handlebars-helpers.js +++ /dev/null @@ -1,194 +0,0 @@ -var log = new Log('fuse.handlebars'); -//TODO: create a different set of helpers for init parsing - -var Handlebars = require('handlebars-v2.0.0.js').Handlebars; -var USER_SESSION_KEY = "USER"; -var getScope = function (unit,configs) { - var jsFile = fuse.getFile(unit, '', '.js'); - var templateConfigs = configs || {}; - var script; - var onRequestCb = function(){}; //Assume that onRequest function will not be defined by the user - var viewModel = {}; - var cbResult; - if (jsFile.isExists()) { - script = require(jsFile.getPath()); - //Eagerly make the viewModel the template configs - viewModel = templateConfigs; - //Check if the unit author has specified an onRequest - //callback - if(script.hasOwnProperty('onRequest')){ - script.app = { - url: '/' + fuseState.appName, - publicURL: '/' + fuseState.appName + '/public/' + unit, - "class": unit + '-unit' - }; - onRequestCb = script.onRequest; - cbResult = onRequestCb(templateConfigs); - log.debug("passing configs to unit "+unit+" configs: "+stringify(templateConfigs)); - //If the execution does not yield an object we will print - //a warning as the unit author may have forgotten to return a data object - if(cbResult===undefined){ - cbResult = {}; //Give an empty data object - log.warn('[' + requestId + '] unit "' + unit + '" has a onRequest method which does not return a value.This may lead to the ' - +'unit not been rendered correctly.'); - } - viewModel = cbResult; - } - } - else{ - //If there is no script then the view should get the configurations - //passed in the unit call - viewModel = templateConfigs; - } - viewModel.app = { - url: '/' + fuseState.appName - }; - viewModel.self = { - publicURL: '/' + fuseState.appName + '/public/' + unit, - "class": unit + '-unit' - }; - return viewModel; -}; - -Handlebars.innerZones = []; -Handlebars.innerZonesFromUnit = null; - -Handlebars.registerHelper('defineZone', function (zoneName, zoneContent) { - var result = ''; - var zone = Handlebars.Utils.escapeExpression(zoneName); - fuseState.zoneStack.push(zone); - var unitsToRender = fuseState.zones[zone] || []; - - if (Handlebars.innerZones.length > 0) { - unitsToRender = fuseState.zones[Handlebars.innerZones[0]] || []; - } - - // if there is no one overriding, then display inline zone - if (zoneContent['fn'] && unitsToRender.length == 0) { - return zoneContent.fn(this).trim(); - } - - for (var i = 0; i < unitsToRender.length; i++) { - var unit = unitsToRender[i]; - if (Handlebars.innerZonesFromUnit == null || Handlebars.innerZonesFromUnit.unitName == unit.unitName) { - var template = fuse.getFile(unit.originUnitName || unit.unitName, '', '.hbs'); - log.debug('[' + requestId + '] for zone "' + zone + '" including template :"' + template.getPath() + '"'); - result += Handlebars.compileFile(template)(getScope(unit.unitName, zoneContent.data.root)); - } - } - - // we go to inner zones if result is empty, what we should really do it - // if matched zone is fully made of sub-zones. this is a hack to - // make it easy to implement. - if (result.trim().length == 0 && zoneContent['fn']) { - Handlebars.innerZones.push(zoneName); - for (i = 0; i < unitsToRender.length; i++) { - unit = unitsToRender[i]; - Handlebars.innerZonesFromUnit = unit; - result += zoneContent.fn(this).trim(); - Handlebars.innerZonesFromUnit = null; - } - Handlebars.innerZones.pop(); - return result; - } - - fuseState.zoneStack.pop(); - return new Handlebars.SafeString(result); -}); - -Handlebars.registerHelper('zone', function (zoneName, zoneContent) { - var currentZone = fuseState.zoneStack[fuseState.zoneStack.length - 1]; - if (currentZone == null) { - return 'zone_' + zoneName + ' '; - } - - // if it's exact zone match or if any in inner zone matches we render zone. - // this second condition is a hack. what we should really do is to keep another stack, - // and only match with the peek of that stack and always fill it with next in innerZone stack. - if (zoneName == currentZone || Handlebars.innerZones.indexOf(zoneName) >= 0) { - return zoneContent.fn(this).trim(); - } else { - return ''; - } -}); - -Handlebars.registerHelper('layout', function (layoutName) { - var currentZone = fuseState.zoneStack[fuseState.zoneStack.length - 1]; - if (currentZone == null) { - return 'layout_' + layoutName; - } else { - return ''; - } -}); - -Handlebars.registerHelper('authorized', function () { - var currentZone = fuseState.zoneStack[fuseState.zoneStack.length - 1]; - if (currentZone == null) { - return ''; - } else { - var loggedUser = session.get(USER_SESSION_KEY); - if(loggedUser == null){ - response.sendRedirect("/"+ fuseState.appName + "/login"); - exit(); - } - } -}); - -Handlebars.registerHelper('unit', function (unitName,options) { - var unitDef = fuse.getUnitDefinition(unitName); - var baseUnit = null; - var templateConfigs = options.hash || {}; - for (var i = 0; i < unitDef.zones.length; i++) { - var zone = unitDef.zones[i]; - if (zone.name == 'main') { - baseUnit = zone.origin; - } else { - var golbalZone = fuseState.zones[zone.name]; - if (!golbalZone) { - fuseState.zones[zone.name] = [{"unitName": unitName}]; - } else { - fuseState.zones[zone.name].push({"unitName": unitName}); - } - } - } - if (baseUnit == null) { - log.error('unit does not have a main zone'); - } - //TODO warn when unspecified decencies are included. - fuseState.zoneStack.push('main'); - var template = fuse.getFile(baseUnit, '', '.hbs'); - log.debug('[' + requestId + '] including "' + baseUnit + '"'+" with configs "+stringify(templateConfigs)); - var result = new Handlebars.SafeString(Handlebars.compileFile(template)(getScope(baseUnit,templateConfigs))); - fuseState.zoneStack.pop(); - return result; -}); - -Handlebars.compileFile = function (file) { - //TODO: remove this overloaded argument - var f = (typeof file === 'string') ? new File(file) : file; - - if (!Handlebars.cache) { - Handlebars.cache = {}; - } - - if (Handlebars.cache[f.getPath()] != null) { - return Handlebars.cache[f.getPath()]; - } - - f.open('r'); - log.debug('[' + requestId + '] reading file "' + f.getPath() + '"'); - var content = f.readAll().trim(); - f.close(); - var compiled = Handlebars.compile(content); - Handlebars.cache[f.getPath()] = compiled; - return compiled; -}; -Handlebars.registerHelper('equal', function(lvalue, rvalue, options) { - if (arguments.length < 3) - throw new Error("Handlebars Helper equal needs 2 parameters"); - if( lvalue!=rvalue ) { - return options.inverse(this); - } else { - return options.fn(this); - } -}); diff --git a/modules/distribution/src/repository/jaggeryapps/iot/lib/handlebars-v2.0.0.js b/modules/distribution/src/repository/jaggeryapps/iot/lib/handlebars-v2.0.0.js deleted file mode 100644 index f826bbfd..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/lib/handlebars-v2.0.0.js +++ /dev/null @@ -1,3079 +0,0 @@ -/*! - - handlebars v2.0.0 - -Copyright (C) 2011-2014 by Yehuda Katz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -@license -*/ -/* exported Handlebars */ -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define([], factory); - } else if (typeof exports === 'object') { - module.exports = factory(); - } else { - root.Handlebars = root.Handlebars || factory(); - } -}(this, function () { -// handlebars/safe-string.js -var __module4__ = (function() { - "use strict"; - var __exports__; - // Build out our basic SafeString type - function SafeString(string) { - this.string = string; - } - - SafeString.prototype.toString = function() { - return "" + this.string; - }; - - __exports__ = SafeString; - return __exports__; -})(); - -// handlebars/utils.js -var __module3__ = (function(__dependency1__) { - "use strict"; - var __exports__ = {}; - /*jshint -W004 */ - var SafeString = __dependency1__; - - var escape = { - "&": "&", - "<": "<", - ">": ">", - '"': """, - "'": "'", - "`": "`" - }; - - var badChars = /[&<>"'`]/g; - var possible = /[&<>"'`]/; - - function escapeChar(chr) { - return escape[chr]; - } - - function extend(obj /* , ...source */) { - for (var i = 1; i < arguments.length; i++) { - for (var key in arguments[i]) { - if (Object.prototype.hasOwnProperty.call(arguments[i], key)) { - obj[key] = arguments[i][key]; - } - } - } - - return obj; - } - - __exports__.extend = extend;var toString = Object.prototype.toString; - __exports__.toString = toString; - // Sourced from lodash - // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt - var isFunction = function(value) { - return typeof value === 'function'; - }; - // fallback for older versions of Chrome and Safari - /* istanbul ignore next */ - if (isFunction(/x/)) { - isFunction = function(value) { - return typeof value === 'function' && toString.call(value) === '[object Function]'; - }; - } - var isFunction; - __exports__.isFunction = isFunction; - /* istanbul ignore next */ - var isArray = Array.isArray || function(value) { - return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false; - }; - __exports__.isArray = isArray; - - function escapeExpression(string) { - // don't escape SafeStrings, since they're already safe - if (string instanceof SafeString) { - return string.toString(); - } else if (string == null) { - return ""; - } else if (!string) { - return string + ''; - } - - // Force a string conversion as this will be done by the append regardless and - // the regex test will do this transparently behind the scenes, causing issues if - // an object's to string has escaped characters in it. - string = "" + string; - - if(!possible.test(string)) { return string; } - return string.replace(badChars, escapeChar); - } - - __exports__.escapeExpression = escapeExpression;function isEmpty(value) { - if (!value && value !== 0) { - return true; - } else if (isArray(value) && value.length === 0) { - return true; - } else { - return false; - } - } - - __exports__.isEmpty = isEmpty;function appendContextPath(contextPath, id) { - return (contextPath ? contextPath + '.' : '') + id; - } - - __exports__.appendContextPath = appendContextPath; - return __exports__; -})(__module4__); - -// handlebars/exception.js -var __module5__ = (function() { - "use strict"; - var __exports__; - - var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack']; - - function Exception(message, node) { - var line; - if (node && node.firstLine) { - line = node.firstLine; - - message += ' - ' + line + ':' + node.firstColumn; - } - - var tmp = Error.prototype.constructor.call(this, message); - - // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. - for (var idx = 0; idx < errorProps.length; idx++) { - this[errorProps[idx]] = tmp[errorProps[idx]]; - } - - if (line) { - this.lineNumber = line; - this.column = node.firstColumn; - } - } - - Exception.prototype = new Error(); - - __exports__ = Exception; - return __exports__; -})(); - -// handlebars/base.js -var __module2__ = (function(__dependency1__, __dependency2__) { - "use strict"; - var __exports__ = {}; - var Utils = __dependency1__; - var Exception = __dependency2__; - - var VERSION = "2.0.0"; - __exports__.VERSION = VERSION;var COMPILER_REVISION = 6; - __exports__.COMPILER_REVISION = COMPILER_REVISION; - var REVISION_CHANGES = { - 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it - 2: '== 1.0.0-rc.3', - 3: '== 1.0.0-rc.4', - 4: '== 1.x.x', - 5: '== 2.0.0-alpha.x', - 6: '>= 2.0.0-beta.1' - }; - __exports__.REVISION_CHANGES = REVISION_CHANGES; - var isArray = Utils.isArray, - isFunction = Utils.isFunction, - toString = Utils.toString, - objectType = '[object Object]'; - - function HandlebarsEnvironment(helpers, partials) { - this.helpers = helpers || {}; - this.partials = partials || {}; - - registerDefaultHelpers(this); - } - - __exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = { - constructor: HandlebarsEnvironment, - - logger: logger, - log: log, - - registerHelper: function(name, fn) { - if (toString.call(name) === objectType) { - if (fn) { throw new Exception('Arg not supported with multiple helpers'); } - Utils.extend(this.helpers, name); - } else { - this.helpers[name] = fn; - } - }, - unregisterHelper: function(name) { - delete this.helpers[name]; - }, - - registerPartial: function(name, partial) { - if (toString.call(name) === objectType) { - Utils.extend(this.partials, name); - } else { - this.partials[name] = partial; - } - }, - unregisterPartial: function(name) { - delete this.partials[name]; - } - }; - - function registerDefaultHelpers(instance) { - instance.registerHelper('helperMissing', function(/* [args, ]options */) { - if(arguments.length === 1) { - // A missing field in a {{foo}} constuct. - return undefined; - } else { - // Someone is actually trying to call something, blow up. - throw new Exception("Missing helper: '" + arguments[arguments.length-1].name + "'"); - } - }); - - instance.registerHelper('blockHelperMissing', function(context, options) { - var inverse = options.inverse, - fn = options.fn; - - if(context === true) { - return fn(this); - } else if(context === false || context == null) { - return inverse(this); - } else if (isArray(context)) { - if(context.length > 0) { - if (options.ids) { - options.ids = [options.name]; - } - - return instance.helpers.each(context, options); - } else { - return inverse(this); - } - } else { - if (options.data && options.ids) { - var data = createFrame(options.data); - data.contextPath = Utils.appendContextPath(options.data.contextPath, options.name); - options = {data: data}; - } - - return fn(context, options); - } - }); - - instance.registerHelper('each', function(context, options) { - if (!options) { - throw new Exception('Must pass iterator to #each'); - } - - var fn = options.fn, inverse = options.inverse; - var i = 0, ret = "", data; - - var contextPath; - if (options.data && options.ids) { - contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.'; - } - - if (isFunction(context)) { context = context.call(this); } - - if (options.data) { - data = createFrame(options.data); - } - - if(context && typeof context === 'object') { - if (isArray(context)) { - for(var j = context.length; i 0) { - throw new Exception("Invalid path: " + original, this); - } else if (part === "..") { - depth++; - depthString += '../'; - } else { - this.isScoped = true; - } - } else { - dig.push(part); - } - } - - this.original = original; - this.parts = dig; - this.string = dig.join('.'); - this.depth = depth; - this.idName = depthString + this.string; - - // an ID is simple if it only has one part, and that part is not - // `..` or `this`. - this.isSimple = parts.length === 1 && !this.isScoped && depth === 0; - - this.stringModeValue = this.string; - }, - - PartialNameNode: function(name, locInfo) { - LocationInfo.call(this, locInfo); - this.type = "PARTIAL_NAME"; - this.name = name.original; - }, - - DataNode: function(id, locInfo) { - LocationInfo.call(this, locInfo); - this.type = "DATA"; - this.id = id; - this.stringModeValue = id.stringModeValue; - this.idName = '@' + id.stringModeValue; - }, - - StringNode: function(string, locInfo) { - LocationInfo.call(this, locInfo); - this.type = "STRING"; - this.original = - this.string = - this.stringModeValue = string; - }, - - NumberNode: function(number, locInfo) { - LocationInfo.call(this, locInfo); - this.type = "NUMBER"; - this.original = - this.number = number; - this.stringModeValue = Number(number); - }, - - BooleanNode: function(bool, locInfo) { - LocationInfo.call(this, locInfo); - this.type = "BOOLEAN"; - this.bool = bool; - this.stringModeValue = bool === "true"; - }, - - CommentNode: function(comment, locInfo) { - LocationInfo.call(this, locInfo); - this.type = "comment"; - this.comment = comment; - - this.strip = { - inlineStandalone: true - }; - } - }; - - - // Must be exported as an object rather than the root of the module as the jison lexer - // most modify the object to operate properly. - __exports__ = AST; - return __exports__; -})(__module5__); - -// handlebars/compiler/parser.js -var __module9__ = (function() { - "use strict"; - var __exports__; - /* jshint ignore:start */ - /* istanbul ignore next */ - /* Jison generated parser */ - var handlebars = (function(){ - var parser = {trace: function trace() { }, - yy: {}, - symbols_: {"error":2,"root":3,"program":4,"EOF":5,"program_repetition0":6,"statement":7,"mustache":8,"block":9,"rawBlock":10,"partial":11,"CONTENT":12,"COMMENT":13,"openRawBlock":14,"END_RAW_BLOCK":15,"OPEN_RAW_BLOCK":16,"sexpr":17,"CLOSE_RAW_BLOCK":18,"openBlock":19,"block_option0":20,"closeBlock":21,"openInverse":22,"block_option1":23,"OPEN_BLOCK":24,"CLOSE":25,"OPEN_INVERSE":26,"inverseAndProgram":27,"INVERSE":28,"OPEN_ENDBLOCK":29,"path":30,"OPEN":31,"OPEN_UNESCAPED":32,"CLOSE_UNESCAPED":33,"OPEN_PARTIAL":34,"partialName":35,"param":36,"partial_option0":37,"partial_option1":38,"sexpr_repetition0":39,"sexpr_option0":40,"dataName":41,"STRING":42,"NUMBER":43,"BOOLEAN":44,"OPEN_SEXPR":45,"CLOSE_SEXPR":46,"hash":47,"hash_repetition_plus0":48,"hashSegment":49,"ID":50,"EQUALS":51,"DATA":52,"pathSegments":53,"SEP":54,"$accept":0,"$end":1}, - terminals_: {2:"error",5:"EOF",12:"CONTENT",13:"COMMENT",15:"END_RAW_BLOCK",16:"OPEN_RAW_BLOCK",18:"CLOSE_RAW_BLOCK",24:"OPEN_BLOCK",25:"CLOSE",26:"OPEN_INVERSE",28:"INVERSE",29:"OPEN_ENDBLOCK",31:"OPEN",32:"OPEN_UNESCAPED",33:"CLOSE_UNESCAPED",34:"OPEN_PARTIAL",42:"STRING",43:"NUMBER",44:"BOOLEAN",45:"OPEN_SEXPR",46:"CLOSE_SEXPR",50:"ID",51:"EQUALS",52:"DATA",54:"SEP"}, - productions_: [0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[10,3],[14,3],[9,4],[9,4],[19,3],[22,3],[27,2],[21,3],[8,3],[8,3],[11,5],[11,4],[17,3],[17,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,3],[47,1],[49,3],[35,1],[35,1],[35,1],[41,2],[30,1],[53,3],[53,1],[6,0],[6,2],[20,0],[20,1],[23,0],[23,1],[37,0],[37,1],[38,0],[38,1],[39,0],[39,2],[40,0],[40,1],[48,1],[48,2]], - performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) { - - var $0 = $$.length - 1; - switch (yystate) { - case 1: yy.prepareProgram($$[$0-1].statements, true); return $$[$0-1]; - break; - case 2:this.$ = new yy.ProgramNode(yy.prepareProgram($$[$0]), {}, this._$); - break; - case 3:this.$ = $$[$0]; - break; - case 4:this.$ = $$[$0]; - break; - case 5:this.$ = $$[$0]; - break; - case 6:this.$ = $$[$0]; - break; - case 7:this.$ = new yy.ContentNode($$[$0], this._$); - break; - case 8:this.$ = new yy.CommentNode($$[$0], this._$); - break; - case 9:this.$ = new yy.RawBlockNode($$[$0-2], $$[$0-1], $$[$0], this._$); - break; - case 10:this.$ = new yy.MustacheNode($$[$0-1], null, '', '', this._$); - break; - case 11:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], false, this._$); - break; - case 12:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], true, this._$); - break; - case 13:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$); - break; - case 14:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$); - break; - case 15:this.$ = { strip: yy.stripFlags($$[$0-1], $$[$0-1]), program: $$[$0] }; - break; - case 16:this.$ = {path: $$[$0-1], strip: yy.stripFlags($$[$0-2], $$[$0])}; - break; - case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$); - break; - case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$); - break; - case 19:this.$ = new yy.PartialNode($$[$0-3], $$[$0-2], $$[$0-1], yy.stripFlags($$[$0-4], $$[$0]), this._$); - break; - case 20:this.$ = new yy.PartialNode($$[$0-2], undefined, $$[$0-1], yy.stripFlags($$[$0-3], $$[$0]), this._$); - break; - case 21:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$); - break; - case 22:this.$ = new yy.SexprNode([$$[$0]], null, this._$); - break; - case 23:this.$ = $$[$0]; - break; - case 24:this.$ = new yy.StringNode($$[$0], this._$); - break; - case 25:this.$ = new yy.NumberNode($$[$0], this._$); - break; - case 26:this.$ = new yy.BooleanNode($$[$0], this._$); - break; - case 27:this.$ = $$[$0]; - break; - case 28:$$[$0-1].isHelper = true; this.$ = $$[$0-1]; - break; - case 29:this.$ = new yy.HashNode($$[$0], this._$); - break; - case 30:this.$ = [$$[$0-2], $$[$0]]; - break; - case 31:this.$ = new yy.PartialNameNode($$[$0], this._$); - break; - case 32:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$); - break; - case 33:this.$ = new yy.PartialNameNode(new yy.NumberNode($$[$0], this._$)); - break; - case 34:this.$ = new yy.DataNode($$[$0], this._$); - break; - case 35:this.$ = new yy.IdNode($$[$0], this._$); - break; - case 36: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2]; - break; - case 37:this.$ = [{part: $$[$0]}]; - break; - case 38:this.$ = []; - break; - case 39:$$[$0-1].push($$[$0]); - break; - case 48:this.$ = []; - break; - case 49:$$[$0-1].push($$[$0]); - break; - case 52:this.$ = [$$[$0]]; - break; - case 53:$$[$0-1].push($$[$0]); - break; - } - }, - table: [{3:1,4:2,5:[2,38],6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],31:[2,38],32:[2,38],34:[2,38]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:[1,10],13:[1,11],14:16,16:[1,20],19:14,22:15,24:[1,18],26:[1,19],28:[2,2],29:[2,2],31:[1,12],32:[1,13],34:[1,17]},{1:[2,1]},{5:[2,39],12:[2,39],13:[2,39],16:[2,39],24:[2,39],26:[2,39],28:[2,39],29:[2,39],31:[2,39],32:[2,39],34:[2,39]},{5:[2,3],12:[2,3],13:[2,3],16:[2,3],24:[2,3],26:[2,3],28:[2,3],29:[2,3],31:[2,3],32:[2,3],34:[2,3]},{5:[2,4],12:[2,4],13:[2,4],16:[2,4],24:[2,4],26:[2,4],28:[2,4],29:[2,4],31:[2,4],32:[2,4],34:[2,4]},{5:[2,5],12:[2,5],13:[2,5],16:[2,5],24:[2,5],26:[2,5],28:[2,5],29:[2,5],31:[2,5],32:[2,5],34:[2,5]},{5:[2,6],12:[2,6],13:[2,6],16:[2,6],24:[2,6],26:[2,6],28:[2,6],29:[2,6],31:[2,6],32:[2,6],34:[2,6]},{5:[2,7],12:[2,7],13:[2,7],16:[2,7],24:[2,7],26:[2,7],28:[2,7],29:[2,7],31:[2,7],32:[2,7],34:[2,7]},{5:[2,8],12:[2,8],13:[2,8],16:[2,8],24:[2,8],26:[2,8],28:[2,8],29:[2,8],31:[2,8],32:[2,8],34:[2,8]},{17:21,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:27,30:22,41:23,50:[1,26],52:[1,25],53:24},{4:28,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{4:29,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{12:[1,30]},{30:32,35:31,42:[1,33],43:[1,34],50:[1,26],53:24},{17:35,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:36,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:37,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[1,38]},{18:[2,48],25:[2,48],33:[2,48],39:39,42:[2,48],43:[2,48],44:[2,48],45:[2,48],46:[2,48],50:[2,48],52:[2,48]},{18:[2,22],25:[2,22],33:[2,22],46:[2,22]},{18:[2,35],25:[2,35],33:[2,35],42:[2,35],43:[2,35],44:[2,35],45:[2,35],46:[2,35],50:[2,35],52:[2,35],54:[1,40]},{30:41,50:[1,26],53:24},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],52:[2,37],54:[2,37]},{33:[1,42]},{20:43,27:44,28:[1,45],29:[2,40]},{23:46,27:47,28:[1,45],29:[2,42]},{15:[1,48]},{25:[2,46],30:51,36:49,38:50,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],47:57,48:58,49:60,50:[1,59],52:[1,25],53:24},{25:[2,31],42:[2,31],43:[2,31],44:[2,31],45:[2,31],50:[2,31],52:[2,31]},{25:[2,32],42:[2,32],43:[2,32],44:[2,32],45:[2,32],50:[2,32],52:[2,32]},{25:[2,33],42:[2,33],43:[2,33],44:[2,33],45:[2,33],50:[2,33],52:[2,33]},{25:[1,61]},{25:[1,62]},{18:[1,63]},{5:[2,17],12:[2,17],13:[2,17],16:[2,17],24:[2,17],26:[2,17],28:[2,17],29:[2,17],31:[2,17],32:[2,17],34:[2,17]},{18:[2,50],25:[2,50],30:51,33:[2,50],36:65,40:64,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],46:[2,50],47:66,48:58,49:60,50:[1,59],52:[1,25],53:24},{50:[1,67]},{18:[2,34],25:[2,34],33:[2,34],42:[2,34],43:[2,34],44:[2,34],45:[2,34],46:[2,34],50:[2,34],52:[2,34]},{5:[2,18],12:[2,18],13:[2,18],16:[2,18],24:[2,18],26:[2,18],28:[2,18],29:[2,18],31:[2,18],32:[2,18],34:[2,18]},{21:68,29:[1,69]},{29:[2,41]},{4:70,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{21:71,29:[1,69]},{29:[2,43]},{5:[2,9],12:[2,9],13:[2,9],16:[2,9],24:[2,9],26:[2,9],28:[2,9],29:[2,9],31:[2,9],32:[2,9],34:[2,9]},{25:[2,44],37:72,47:73,48:58,49:60,50:[1,74]},{25:[1,75]},{18:[2,23],25:[2,23],33:[2,23],42:[2,23],43:[2,23],44:[2,23],45:[2,23],46:[2,23],50:[2,23],52:[2,23]},{18:[2,24],25:[2,24],33:[2,24],42:[2,24],43:[2,24],44:[2,24],45:[2,24],46:[2,24],50:[2,24],52:[2,24]},{18:[2,25],25:[2,25],33:[2,25],42:[2,25],43:[2,25],44:[2,25],45:[2,25],46:[2,25],50:[2,25],52:[2,25]},{18:[2,26],25:[2,26],33:[2,26],42:[2,26],43:[2,26],44:[2,26],45:[2,26],46:[2,26],50:[2,26],52:[2,26]},{18:[2,27],25:[2,27],33:[2,27],42:[2,27],43:[2,27],44:[2,27],45:[2,27],46:[2,27],50:[2,27],52:[2,27]},{17:76,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[2,47]},{18:[2,29],25:[2,29],33:[2,29],46:[2,29],49:77,50:[1,74]},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],51:[1,78],52:[2,37],54:[2,37]},{18:[2,52],25:[2,52],33:[2,52],46:[2,52],50:[2,52]},{12:[2,13],13:[2,13],16:[2,13],24:[2,13],26:[2,13],28:[2,13],29:[2,13],31:[2,13],32:[2,13],34:[2,13]},{12:[2,14],13:[2,14],16:[2,14],24:[2,14],26:[2,14],28:[2,14],29:[2,14],31:[2,14],32:[2,14],34:[2,14]},{12:[2,10]},{18:[2,21],25:[2,21],33:[2,21],46:[2,21]},{18:[2,49],25:[2,49],33:[2,49],42:[2,49],43:[2,49],44:[2,49],45:[2,49],46:[2,49],50:[2,49],52:[2,49]},{18:[2,51],25:[2,51],33:[2,51],46:[2,51]},{18:[2,36],25:[2,36],33:[2,36],42:[2,36],43:[2,36],44:[2,36],45:[2,36],46:[2,36],50:[2,36],52:[2,36],54:[2,36]},{5:[2,11],12:[2,11],13:[2,11],16:[2,11],24:[2,11],26:[2,11],28:[2,11],29:[2,11],31:[2,11],32:[2,11],34:[2,11]},{30:79,50:[1,26],53:24},{29:[2,15]},{5:[2,12],12:[2,12],13:[2,12],16:[2,12],24:[2,12],26:[2,12],28:[2,12],29:[2,12],31:[2,12],32:[2,12],34:[2,12]},{25:[1,80]},{25:[2,45]},{51:[1,78]},{5:[2,20],12:[2,20],13:[2,20],16:[2,20],24:[2,20],26:[2,20],28:[2,20],29:[2,20],31:[2,20],32:[2,20],34:[2,20]},{46:[1,81]},{18:[2,53],25:[2,53],33:[2,53],46:[2,53],50:[2,53]},{30:51,36:82,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],50:[1,26],52:[1,25],53:24},{25:[1,83]},{5:[2,19],12:[2,19],13:[2,19],16:[2,19],24:[2,19],26:[2,19],28:[2,19],29:[2,19],31:[2,19],32:[2,19],34:[2,19]},{18:[2,28],25:[2,28],33:[2,28],42:[2,28],43:[2,28],44:[2,28],45:[2,28],46:[2,28],50:[2,28],52:[2,28]},{18:[2,30],25:[2,30],33:[2,30],46:[2,30],50:[2,30]},{5:[2,16],12:[2,16],13:[2,16],16:[2,16],24:[2,16],26:[2,16],28:[2,16],29:[2,16],31:[2,16],32:[2,16],34:[2,16]}], - defaultActions: {4:[2,1],44:[2,41],47:[2,43],57:[2,47],63:[2,10],70:[2,15],73:[2,45]}, - parseError: function parseError(str, hash) { - throw new Error(str); - }, - parse: function parse(input) { - var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; - this.lexer.setInput(input); - this.lexer.yy = this.yy; - this.yy.lexer = this.lexer; - this.yy.parser = this; - if (typeof this.lexer.yylloc == "undefined") - this.lexer.yylloc = {}; - var yyloc = this.lexer.yylloc; - lstack.push(yyloc); - var ranges = this.lexer.options && this.lexer.options.ranges; - if (typeof this.yy.parseError === "function") - this.parseError = this.yy.parseError; - function popStack(n) { - stack.length = stack.length - 2 * n; - vstack.length = vstack.length - n; - lstack.length = lstack.length - n; - } - function lex() { - var token; - token = self.lexer.lex() || 1; - if (typeof token !== "number") { - token = self.symbols_[token] || token; - } - return token; - } - var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; - while (true) { - state = stack[stack.length - 1]; - if (this.defaultActions[state]) { - action = this.defaultActions[state]; - } else { - if (symbol === null || typeof symbol == "undefined") { - symbol = lex(); - } - action = table[state] && table[state][symbol]; - } - if (typeof action === "undefined" || !action.length || !action[0]) { - var errStr = ""; - if (!recovering) { - expected = []; - for (p in table[state]) - if (this.terminals_[p] && p > 2) { - expected.push("'" + this.terminals_[p] + "'"); - } - if (this.lexer.showPosition) { - errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; - } else { - errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'"); - } - this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected}); - } - } - if (action[0] instanceof Array && action.length > 1) { - throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); - } - switch (action[0]) { - case 1: - stack.push(symbol); - vstack.push(this.lexer.yytext); - lstack.push(this.lexer.yylloc); - stack.push(action[1]); - symbol = null; - if (!preErrorSymbol) { - yyleng = this.lexer.yyleng; - yytext = this.lexer.yytext; - yylineno = this.lexer.yylineno; - yyloc = this.lexer.yylloc; - if (recovering > 0) - recovering--; - } else { - symbol = preErrorSymbol; - preErrorSymbol = null; - } - break; - case 2: - len = this.productions_[action[1]][1]; - yyval.$ = vstack[vstack.length - len]; - yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column}; - if (ranges) { - yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]]; - } - r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); - if (typeof r !== "undefined") { - return r; - } - if (len) { - stack = stack.slice(0, -1 * len * 2); - vstack = vstack.slice(0, -1 * len); - lstack = lstack.slice(0, -1 * len); - } - stack.push(this.productions_[action[1]][0]); - vstack.push(yyval.$); - lstack.push(yyval._$); - newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; - stack.push(newState); - break; - case 3: - return true; - } - } - return true; - } - }; - /* Jison generated lexer */ - var lexer = (function(){ - var lexer = ({EOF:1, - parseError:function parseError(str, hash) { - if (this.yy.parser) { - this.yy.parser.parseError(str, hash); - } else { - throw new Error(str); - } - }, - setInput:function (input) { - this._input = input; - this._more = this._less = this.done = false; - this.yylineno = this.yyleng = 0; - this.yytext = this.matched = this.match = ''; - this.conditionStack = ['INITIAL']; - this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0}; - if (this.options.ranges) this.yylloc.range = [0,0]; - this.offset = 0; - return this; - }, - input:function () { - var ch = this._input[0]; - this.yytext += ch; - this.yyleng++; - this.offset++; - this.match += ch; - this.matched += ch; - var lines = ch.match(/(?:\r\n?|\n).*/g); - if (lines) { - this.yylineno++; - this.yylloc.last_line++; - } else { - this.yylloc.last_column++; - } - if (this.options.ranges) this.yylloc.range[1]++; - - this._input = this._input.slice(1); - return ch; - }, - unput:function (ch) { - var len = ch.length; - var lines = ch.split(/(?:\r\n?|\n)/g); - - this._input = ch + this._input; - this.yytext = this.yytext.substr(0, this.yytext.length-len-1); - //this.yyleng -= len; - this.offset -= len; - var oldLines = this.match.split(/(?:\r\n?|\n)/g); - this.match = this.match.substr(0, this.match.length-1); - this.matched = this.matched.substr(0, this.matched.length-1); - - if (lines.length-1) this.yylineno -= lines.length-1; - var r = this.yylloc.range; - - this.yylloc = {first_line: this.yylloc.first_line, - last_line: this.yylineno+1, - first_column: this.yylloc.first_column, - last_column: lines ? - (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length: - this.yylloc.first_column - len - }; - - if (this.options.ranges) { - this.yylloc.range = [r[0], r[0] + this.yyleng - len]; - } - return this; - }, - more:function () { - this._more = true; - return this; - }, - less:function (n) { - this.unput(this.match.slice(n)); - }, - pastInput:function () { - var past = this.matched.substr(0, this.matched.length - this.match.length); - return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); - }, - upcomingInput:function () { - var next = this.match; - if (next.length < 20) { - next += this._input.substr(0, 20-next.length); - } - return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, ""); - }, - showPosition:function () { - var pre = this.pastInput(); - var c = new Array(pre.length + 1).join("-"); - return pre + this.upcomingInput() + "\n" + c+"^"; - }, - next:function () { - if (this.done) { - return this.EOF; - } - if (!this._input) this.done = true; - - var token, - match, - tempMatch, - index, - col, - lines; - if (!this._more) { - this.yytext = ''; - this.match = ''; - } - var rules = this._currentRules(); - for (var i=0;i < rules.length; i++) { - tempMatch = this._input.match(this.rules[rules[i]]); - if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { - match = tempMatch; - index = i; - if (!this.options.flex) break; - } - } - if (match) { - lines = match[0].match(/(?:\r\n?|\n).*/g); - if (lines) this.yylineno += lines.length; - this.yylloc = {first_line: this.yylloc.last_line, - last_line: this.yylineno+1, - first_column: this.yylloc.last_column, - last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length}; - this.yytext += match[0]; - this.match += match[0]; - this.matches = match; - this.yyleng = this.yytext.length; - if (this.options.ranges) { - this.yylloc.range = [this.offset, this.offset += this.yyleng]; - } - this._more = false; - this._input = this._input.slice(match[0].length); - this.matched += match[0]; - token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]); - if (this.done && this._input) this.done = false; - if (token) return token; - else return; - } - if (this._input === "") { - return this.EOF; - } else { - return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(), - {text: "", token: null, line: this.yylineno}); - } - }, - lex:function lex() { - var r = this.next(); - if (typeof r !== 'undefined') { - return r; - } else { - return this.lex(); - } - }, - begin:function begin(condition) { - this.conditionStack.push(condition); - }, - popState:function popState() { - return this.conditionStack.pop(); - }, - _currentRules:function _currentRules() { - return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules; - }, - topState:function () { - return this.conditionStack[this.conditionStack.length-2]; - }, - pushState:function begin(condition) { - this.begin(condition); - }}); - lexer.options = {}; - lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { - - - function strip(start, end) { - return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end); - } - - - var YYSTATE=YY_START - switch($avoiding_name_collisions) { - case 0: - if(yy_.yytext.slice(-2) === "\\\\") { - strip(0,1); - this.begin("mu"); - } else if(yy_.yytext.slice(-1) === "\\") { - strip(0,1); - this.begin("emu"); - } else { - this.begin("mu"); - } - if(yy_.yytext) return 12; - - break; - case 1:return 12; - break; - case 2: - this.popState(); - return 12; - - break; - case 3: - yy_.yytext = yy_.yytext.substr(5, yy_.yyleng-9); - this.popState(); - return 15; - - break; - case 4: return 12; - break; - case 5:strip(0,4); this.popState(); return 13; - break; - case 6:return 45; - break; - case 7:return 46; - break; - case 8: return 16; - break; - case 9: - this.popState(); - this.begin('raw'); - return 18; - - break; - case 10:return 34; - break; - case 11:return 24; - break; - case 12:return 29; - break; - case 13:this.popState(); return 28; - break; - case 14:this.popState(); return 28; - break; - case 15:return 26; - break; - case 16:return 26; - break; - case 17:return 32; - break; - case 18:return 31; - break; - case 19:this.popState(); this.begin('com'); - break; - case 20:strip(3,5); this.popState(); return 13; - break; - case 21:return 31; - break; - case 22:return 51; - break; - case 23:return 50; - break; - case 24:return 50; - break; - case 25:return 54; - break; - case 26:// ignore whitespace - break; - case 27:this.popState(); return 33; - break; - case 28:this.popState(); return 25; - break; - case 29:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 42; - break; - case 30:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 42; - break; - case 31:return 52; - break; - case 32:return 44; - break; - case 33:return 44; - break; - case 34:return 43; - break; - case 35:return 50; - break; - case 36:yy_.yytext = strip(1,2); return 50; - break; - case 37:return 'INVALID'; - break; - case 38:return 5; - break; - } - }; - lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]*?(?=(\{\{\{\{\/)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/]; - lexer.conditions = {"mu":{"rules":[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[5],"inclusive":false},"raw":{"rules":[3,4],"inclusive":false},"INITIAL":{"rules":[0,1,38],"inclusive":true}}; - return lexer;})() - parser.lexer = lexer; - function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser; - return new Parser; - })();__exports__ = handlebars; - /* jshint ignore:end */ - return __exports__; -})(); - -// handlebars/compiler/helpers.js -var __module10__ = (function(__dependency1__) { - "use strict"; - var __exports__ = {}; - var Exception = __dependency1__; - - function stripFlags(open, close) { - return { - left: open.charAt(2) === '~', - right: close.charAt(close.length-3) === '~' - }; - } - - __exports__.stripFlags = stripFlags; - function prepareBlock(mustache, program, inverseAndProgram, close, inverted, locInfo) { - /*jshint -W040 */ - if (mustache.sexpr.id.original !== close.path.original) { - throw new Exception(mustache.sexpr.id.original + ' doesn\'t match ' + close.path.original, mustache); - } - - var inverse = inverseAndProgram && inverseAndProgram.program; - - var strip = { - left: mustache.strip.left, - right: close.strip.right, - - // Determine the standalone candiacy. Basically flag our content as being possibly standalone - // so our parent can determine if we actually are standalone - openStandalone: isNextWhitespace(program.statements), - closeStandalone: isPrevWhitespace((inverse || program).statements) - }; - - if (mustache.strip.right) { - omitRight(program.statements, null, true); - } - - if (inverse) { - var inverseStrip = inverseAndProgram.strip; - - if (inverseStrip.left) { - omitLeft(program.statements, null, true); - } - if (inverseStrip.right) { - omitRight(inverse.statements, null, true); - } - if (close.strip.left) { - omitLeft(inverse.statements, null, true); - } - - // Find standalone else statments - if (isPrevWhitespace(program.statements) - && isNextWhitespace(inverse.statements)) { - - omitLeft(program.statements); - omitRight(inverse.statements); - } - } else { - if (close.strip.left) { - omitLeft(program.statements, null, true); - } - } - - if (inverted) { - return new this.BlockNode(mustache, inverse, program, strip, locInfo); - } else { - return new this.BlockNode(mustache, program, inverse, strip, locInfo); - } - } - - __exports__.prepareBlock = prepareBlock; - function prepareProgram(statements, isRoot) { - for (var i = 0, l = statements.length; i < l; i++) { - var current = statements[i], - strip = current.strip; - - if (!strip) { - continue; - } - - var _isPrevWhitespace = isPrevWhitespace(statements, i, isRoot, current.type === 'partial'), - _isNextWhitespace = isNextWhitespace(statements, i, isRoot), - - openStandalone = strip.openStandalone && _isPrevWhitespace, - closeStandalone = strip.closeStandalone && _isNextWhitespace, - inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace; - - if (strip.right) { - omitRight(statements, i, true); - } - if (strip.left) { - omitLeft(statements, i, true); - } - - if (inlineStandalone) { - omitRight(statements, i); - - if (omitLeft(statements, i)) { - // If we are on a standalone node, save the indent info for partials - if (current.type === 'partial') { - current.indent = (/([ \t]+$)/).exec(statements[i-1].original) ? RegExp.$1 : ''; - } - } - } - if (openStandalone) { - omitRight((current.program || current.inverse).statements); - - // Strip out the previous content node if it's whitespace only - omitLeft(statements, i); - } - if (closeStandalone) { - // Always strip the next node - omitRight(statements, i); - - omitLeft((current.inverse || current.program).statements); - } - } - - return statements; - } - - __exports__.prepareProgram = prepareProgram;function isPrevWhitespace(statements, i, isRoot) { - if (i === undefined) { - i = statements.length; - } - - // Nodes that end with newlines are considered whitespace (but are special - // cased for strip operations) - var prev = statements[i-1], - sibling = statements[i-2]; - if (!prev) { - return isRoot; - } - - if (prev.type === 'content') { - return (sibling || !isRoot ? (/\r?\n\s*?$/) : (/(^|\r?\n)\s*?$/)).test(prev.original); - } - } - function isNextWhitespace(statements, i, isRoot) { - if (i === undefined) { - i = -1; - } - - var next = statements[i+1], - sibling = statements[i+2]; - if (!next) { - return isRoot; - } - - if (next.type === 'content') { - return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original); - } - } - - // Marks the node to the right of the position as omitted. - // I.e. {{foo}}' ' will mark the ' ' node as omitted. - // - // If i is undefined, then the first child will be marked as such. - // - // If mulitple is truthy then all whitespace will be stripped out until non-whitespace - // content is met. - function omitRight(statements, i, multiple) { - var current = statements[i == null ? 0 : i + 1]; - if (!current || current.type !== 'content' || (!multiple && current.rightStripped)) { - return; - } - - var original = current.string; - current.string = current.string.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), ''); - current.rightStripped = current.string !== original; - } - - // Marks the node to the left of the position as omitted. - // I.e. ' '{{foo}} will mark the ' ' node as omitted. - // - // If i is undefined then the last child will be marked as such. - // - // If mulitple is truthy then all whitespace will be stripped out until non-whitespace - // content is met. - function omitLeft(statements, i, multiple) { - var current = statements[i == null ? statements.length - 1 : i - 1]; - if (!current || current.type !== 'content' || (!multiple && current.leftStripped)) { - return; - } - - // We omit the last node if it's whitespace only and not preceeded by a non-content node. - var original = current.string; - current.string = current.string.replace(multiple ? (/\s+$/) : (/[ \t]+$/), ''); - current.leftStripped = current.string !== original; - return current.leftStripped; - } - return __exports__; -})(__module5__); - -// handlebars/compiler/base.js -var __module8__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__) { - "use strict"; - var __exports__ = {}; - var parser = __dependency1__; - var AST = __dependency2__; - var Helpers = __dependency3__; - var extend = __dependency4__.extend; - - __exports__.parser = parser; - - var yy = {}; - extend(yy, Helpers, AST); - - function parse(input) { - // Just return if an already-compile AST was passed in. - if (input.constructor === AST.ProgramNode) { return input; } - - parser.yy = yy; - - return parser.parse(input); - } - - __exports__.parse = parse; - return __exports__; -})(__module9__, __module7__, __module10__, __module3__); - -// handlebars/compiler/compiler.js -var __module11__ = (function(__dependency1__, __dependency2__) { - "use strict"; - var __exports__ = {}; - var Exception = __dependency1__; - var isArray = __dependency2__.isArray; - - var slice = [].slice; - - function Compiler() {} - - __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a - // function in a context. This is necessary for mustache compatibility, which - // requires that context functions in blocks are evaluated by blockHelperMissing, - // and then proceed as if the resulting value was provided to blockHelperMissing. - - Compiler.prototype = { - compiler: Compiler, - - equals: function(other) { - var len = this.opcodes.length; - if (other.opcodes.length !== len) { - return false; - } - - for (var i = 0; i < len; i++) { - var opcode = this.opcodes[i], - otherOpcode = other.opcodes[i]; - if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) { - return false; - } - } - - // We know that length is the same between the two arrays because they are directly tied - // to the opcode behavior above. - len = this.children.length; - for (i = 0; i < len; i++) { - if (!this.children[i].equals(other.children[i])) { - return false; - } - } - - return true; - }, - - guid: 0, - - compile: function(program, options) { - this.opcodes = []; - this.children = []; - this.depths = {list: []}; - this.options = options; - this.stringParams = options.stringParams; - this.trackIds = options.trackIds; - - // These changes will propagate to the other compiler components - var knownHelpers = this.options.knownHelpers; - this.options.knownHelpers = { - 'helperMissing': true, - 'blockHelperMissing': true, - 'each': true, - 'if': true, - 'unless': true, - 'with': true, - 'log': true, - 'lookup': true - }; - if (knownHelpers) { - for (var name in knownHelpers) { - this.options.knownHelpers[name] = knownHelpers[name]; - } - } - - return this.accept(program); - }, - - accept: function(node) { - return this[node.type](node); - }, - - program: function(program) { - var statements = program.statements; - - for(var i=0, l=statements.length; i 0) { - varDeclarations += ", " + locals.join(", "); - } - - // Generate minimizer alias mappings - for (var alias in this.aliases) { - if (this.aliases.hasOwnProperty(alias)) { - varDeclarations += ', ' + alias + '=' + this.aliases[alias]; - } - } - - var params = ["depth0", "helpers", "partials", "data"]; - - if (this.useDepths) { - params.push('depths'); - } - - // Perform a second pass over the output to merge content when possible - var source = this.mergeSource(varDeclarations); - - if (asObject) { - params.push(source); - - return Function.apply(this, params); - } else { - return 'function(' + params.join(',') + ') {\n ' + source + '}'; - } - }, - mergeSource: function(varDeclarations) { - var source = '', - buffer, - appendOnly = !this.forceBuffer, - appendFirst; - - for (var i = 0, len = this.source.length; i < len; i++) { - var line = this.source[i]; - if (line.appendToBuffer) { - if (buffer) { - buffer = buffer + '\n + ' + line.content; - } else { - buffer = line.content; - } - } else { - if (buffer) { - if (!source) { - appendFirst = true; - source = buffer + ';\n '; - } else { - source += 'buffer += ' + buffer + ';\n '; - } - buffer = undefined; - } - source += line + '\n '; - - if (!this.environment.isSimple) { - appendOnly = false; - } - } - } - - if (appendOnly) { - if (buffer || !source) { - source += 'return ' + (buffer || '""') + ';\n'; - } - } else { - varDeclarations += ", buffer = " + (appendFirst ? '' : this.initializeBuffer()); - if (buffer) { - source += 'return buffer + ' + buffer + ';\n'; - } else { - source += 'return buffer;\n'; - } - } - - if (varDeclarations) { - source = 'var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n ') + source; - } - - return source; - }, - - // [blockValue] - // - // On stack, before: hash, inverse, program, value - // On stack, after: return value of blockHelperMissing - // - // The purpose of this opcode is to take a block of the form - // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and - // replace it on the stack with the result of properly - // invoking blockHelperMissing. - blockValue: function(name) { - this.aliases.blockHelperMissing = 'helpers.blockHelperMissing'; - - var params = [this.contextName(0)]; - this.setupParams(name, 0, params); - - var blockName = this.popStack(); - params.splice(1, 0, blockName); - - this.push('blockHelperMissing.call(' + params.join(', ') + ')'); - }, - - // [ambiguousBlockValue] - // - // On stack, before: hash, inverse, program, value - // Compiler value, before: lastHelper=value of last found helper, if any - // On stack, after, if no lastHelper: same as [blockValue] - // On stack, after, if lastHelper: value - ambiguousBlockValue: function() { - this.aliases.blockHelperMissing = 'helpers.blockHelperMissing'; - - // We're being a bit cheeky and reusing the options value from the prior exec - var params = [this.contextName(0)]; - this.setupParams('', 0, params, true); - - this.flushInline(); - - var current = this.topStack(); - params.splice(1, 0, current); - - this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }"); - }, - - // [appendContent] - // - // On stack, before: ... - // On stack, after: ... - // - // Appends the string value of `content` to the current buffer - appendContent: function(content) { - if (this.pendingContent) { - content = this.pendingContent + content; - } - - this.pendingContent = content; - }, - - // [append] - // - // On stack, before: value, ... - // On stack, after: ... - // - // Coerces `value` to a String and appends it to the current buffer. - // - // If `value` is truthy, or 0, it is coerced into a string and appended - // Otherwise, the empty string is appended - append: function() { - // Force anything that is inlined onto the stack so we don't have duplication - // when we examine local - this.flushInline(); - var local = this.popStack(); - this.pushSource('if (' + local + ' != null) { ' + this.appendToBuffer(local) + ' }'); - if (this.environment.isSimple) { - this.pushSource("else { " + this.appendToBuffer("''") + " }"); - } - }, - - // [appendEscaped] - // - // On stack, before: value, ... - // On stack, after: ... - // - // Escape `value` and append it to the buffer - appendEscaped: function() { - this.aliases.escapeExpression = 'this.escapeExpression'; - - this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")")); - }, - - // [getContext] - // - // On stack, before: ... - // On stack, after: ... - // Compiler value, after: lastContext=depth - // - // Set the value of the `lastContext` compiler value to the depth - getContext: function(depth) { - this.lastContext = depth; - }, - - // [pushContext] - // - // On stack, before: ... - // On stack, after: currentContext, ... - // - // Pushes the value of the current context onto the stack. - pushContext: function() { - this.pushStackLiteral(this.contextName(this.lastContext)); - }, - - // [lookupOnContext] - // - // On stack, before: ... - // On stack, after: currentContext[name], ... - // - // Looks up the value of `name` on the current context and pushes - // it onto the stack. - lookupOnContext: function(parts, falsy, scoped) { - /*jshint -W083 */ - var i = 0, - len = parts.length; - - if (!scoped && this.options.compat && !this.lastContext) { - // The depthed query is expected to handle the undefined logic for the root level that - // is implemented below, so we evaluate that directly in compat mode - this.push(this.depthedLookup(parts[i++])); - } else { - this.pushContext(); - } - - for (; i < len; i++) { - this.replaceStack(function(current) { - var lookup = this.nameLookup(current, parts[i], 'context'); - // We want to ensure that zero and false are handled properly if the context (falsy flag) - // needs to have the special handling for these values. - if (!falsy) { - return ' != null ? ' + lookup + ' : ' + current; - } else { - // Otherwise we can use generic falsy handling - return ' && ' + lookup; - } - }); - } - }, - - // [lookupData] - // - // On stack, before: ... - // On stack, after: data, ... - // - // Push the data lookup operator - lookupData: function(depth, parts) { - /*jshint -W083 */ - if (!depth) { - this.pushStackLiteral('data'); - } else { - this.pushStackLiteral('this.data(data, ' + depth + ')'); - } - - var len = parts.length; - for (var i = 0; i < len; i++) { - this.replaceStack(function(current) { - return ' && ' + this.nameLookup(current, parts[i], 'data'); - }); - } - }, - - // [resolvePossibleLambda] - // - // On stack, before: value, ... - // On stack, after: resolved value, ... - // - // If the `value` is a lambda, replace it on the stack by - // the return value of the lambda - resolvePossibleLambda: function() { - this.aliases.lambda = 'this.lambda'; - - this.push('lambda(' + this.popStack() + ', ' + this.contextName(0) + ')'); - }, - - // [pushStringParam] - // - // On stack, before: ... - // On stack, after: string, currentContext, ... - // - // This opcode is designed for use in string mode, which - // provides the string value of a parameter along with its - // depth rather than resolving it immediately. - pushStringParam: function(string, type) { - this.pushContext(); - this.pushString(type); - - // If it's a subexpression, the string result - // will be pushed after this opcode. - if (type !== 'sexpr') { - if (typeof string === 'string') { - this.pushString(string); - } else { - this.pushStackLiteral(string); - } - } - }, - - emptyHash: function() { - this.pushStackLiteral('{}'); - - if (this.trackIds) { - this.push('{}'); // hashIds - } - if (this.stringParams) { - this.push('{}'); // hashContexts - this.push('{}'); // hashTypes - } - }, - pushHash: function() { - if (this.hash) { - this.hashes.push(this.hash); - } - this.hash = {values: [], types: [], contexts: [], ids: []}; - }, - popHash: function() { - var hash = this.hash; - this.hash = this.hashes.pop(); - - if (this.trackIds) { - this.push('{' + hash.ids.join(',') + '}'); - } - if (this.stringParams) { - this.push('{' + hash.contexts.join(',') + '}'); - this.push('{' + hash.types.join(',') + '}'); - } - - this.push('{\n ' + hash.values.join(',\n ') + '\n }'); - }, - - // [pushString] - // - // On stack, before: ... - // On stack, after: quotedString(string), ... - // - // Push a quoted version of `string` onto the stack - pushString: function(string) { - this.pushStackLiteral(this.quotedString(string)); - }, - - // [push] - // - // On stack, before: ... - // On stack, after: expr, ... - // - // Push an expression onto the stack - push: function(expr) { - this.inlineStack.push(expr); - return expr; - }, - - // [pushLiteral] - // - // On stack, before: ... - // On stack, after: value, ... - // - // Pushes a value onto the stack. This operation prevents - // the compiler from creating a temporary variable to hold - // it. - pushLiteral: function(value) { - this.pushStackLiteral(value); - }, - - // [pushProgram] - // - // On stack, before: ... - // On stack, after: program(guid), ... - // - // Push a program expression onto the stack. This takes - // a compile-time guid and converts it into a runtime-accessible - // expression. - pushProgram: function(guid) { - if (guid != null) { - this.pushStackLiteral(this.programExpression(guid)); - } else { - this.pushStackLiteral(null); - } - }, - - // [invokeHelper] - // - // On stack, before: hash, inverse, program, params..., ... - // On stack, after: result of helper invocation - // - // Pops off the helper's parameters, invokes the helper, - // and pushes the helper's return value onto the stack. - // - // If the helper is not found, `helperMissing` is called. - invokeHelper: function(paramSize, name, isSimple) { - this.aliases.helperMissing = 'helpers.helperMissing'; - - var nonHelper = this.popStack(); - var helper = this.setupHelper(paramSize, name); - - var lookup = (isSimple ? helper.name + ' || ' : '') + nonHelper + ' || helperMissing'; - this.push('((' + lookup + ').call(' + helper.callParams + '))'); - }, - - // [invokeKnownHelper] - // - // On stack, before: hash, inverse, program, params..., ... - // On stack, after: result of helper invocation - // - // This operation is used when the helper is known to exist, - // so a `helperMissing` fallback is not required. - invokeKnownHelper: function(paramSize, name) { - var helper = this.setupHelper(paramSize, name); - this.push(helper.name + ".call(" + helper.callParams + ")"); - }, - - // [invokeAmbiguous] - // - // On stack, before: hash, inverse, program, params..., ... - // On stack, after: result of disambiguation - // - // This operation is used when an expression like `{{foo}}` - // is provided, but we don't know at compile-time whether it - // is a helper or a path. - // - // This operation emits more code than the other options, - // and can be avoided by passing the `knownHelpers` and - // `knownHelpersOnly` flags at compile-time. - invokeAmbiguous: function(name, helperCall) { - this.aliases.functionType = '"function"'; - this.aliases.helperMissing = 'helpers.helperMissing'; - this.useRegister('helper'); - - var nonHelper = this.popStack(); - - this.emptyHash(); - var helper = this.setupHelper(0, name, helperCall); - - var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper'); - - this.push( - '((helper = (helper = ' + helperName + ' || ' + nonHelper + ') != null ? helper : helperMissing' - + (helper.paramsInit ? '),(' + helper.paramsInit : '') + '),' - + '(typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper))'); - }, - - // [invokePartial] - // - // On stack, before: context, ... - // On stack after: result of partial invocation - // - // This operation pops off a context, invokes a partial with that context, - // and pushes the result of the invocation back. - invokePartial: function(name, indent) { - var params = [this.nameLookup('partials', name, 'partial'), "'" + indent + "'", "'" + name + "'", this.popStack(), this.popStack(), "helpers", "partials"]; - - if (this.options.data) { - params.push("data"); - } else if (this.options.compat) { - params.push('undefined'); - } - if (this.options.compat) { - params.push('depths'); - } - - this.push("this.invokePartial(" + params.join(", ") + ")"); - }, - - // [assignToHash] - // - // On stack, before: value, ..., hash, ... - // On stack, after: ..., hash, ... - // - // Pops a value off the stack and assigns it to the current hash - assignToHash: function(key) { - var value = this.popStack(), - context, - type, - id; - - if (this.trackIds) { - id = this.popStack(); - } - if (this.stringParams) { - type = this.popStack(); - context = this.popStack(); - } - - var hash = this.hash; - if (context) { - hash.contexts.push("'" + key + "': " + context); - } - if (type) { - hash.types.push("'" + key + "': " + type); - } - if (id) { - hash.ids.push("'" + key + "': " + id); - } - hash.values.push("'" + key + "': (" + value + ")"); - }, - - pushId: function(type, name) { - if (type === 'ID' || type === 'DATA') { - this.pushString(name); - } else if (type === 'sexpr') { - this.pushStackLiteral('true'); - } else { - this.pushStackLiteral('null'); - } - }, - - // HELPERS - - compiler: JavaScriptCompiler, - - compileChildren: function(environment, options) { - var children = environment.children, child, compiler; - - for(var i=0, l=children.length; i this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); } - return this.topStackName(); - }, - topStackName: function() { - return "stack" + this.stackSlot; - }, - flushInline: function() { - var inlineStack = this.inlineStack; - if (inlineStack.length) { - this.inlineStack = []; - for (var i = 0, len = inlineStack.length; i < len; i++) { - var entry = inlineStack[i]; - if (entry instanceof Literal) { - this.compileStack.push(entry); - } else { - this.pushStack(entry); - } - } - } - }, - isInline: function() { - return this.inlineStack.length; - }, - - popStack: function(wrapped) { - var inline = this.isInline(), - item = (inline ? this.inlineStack : this.compileStack).pop(); - - if (!wrapped && (item instanceof Literal)) { - return item.value; - } else { - if (!inline) { - /* istanbul ignore next */ - if (!this.stackSlot) { - throw new Exception('Invalid stack pop'); - } - this.stackSlot--; - } - return item; - } - }, - - topStack: function() { - var stack = (this.isInline() ? this.inlineStack : this.compileStack), - item = stack[stack.length - 1]; - - if (item instanceof Literal) { - return item.value; - } else { - return item; - } - }, - - contextName: function(context) { - if (this.useDepths && context) { - return 'depths[' + context + ']'; - } else { - return 'depth' + context; - } - }, - - quotedString: function(str) { - return '"' + str - .replace(/\\/g, '\\\\') - .replace(/"/g, '\\"') - .replace(/\n/g, '\\n') - .replace(/\r/g, '\\r') - .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4 - .replace(/\u2029/g, '\\u2029') + '"'; - }, - - objectLiteral: function(obj) { - var pairs = []; - - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - pairs.push(this.quotedString(key) + ':' + obj[key]); - } - } - - return '{' + pairs.join(',') + '}'; - }, - - setupHelper: function(paramSize, name, blockHelper) { - var params = [], - paramsInit = this.setupParams(name, paramSize, params, blockHelper); - var foundHelper = this.nameLookup('helpers', name, 'helper'); - - return { - params: params, - paramsInit: paramsInit, - name: foundHelper, - callParams: [this.contextName(0)].concat(params).join(", ") - }; - }, - - setupOptions: function(helper, paramSize, params) { - var options = {}, contexts = [], types = [], ids = [], param, inverse, program; - - options.name = this.quotedString(helper); - options.hash = this.popStack(); - - if (this.trackIds) { - options.hashIds = this.popStack(); - } - if (this.stringParams) { - options.hashTypes = this.popStack(); - options.hashContexts = this.popStack(); - } - - inverse = this.popStack(); - program = this.popStack(); - - // Avoid setting fn and inverse if neither are set. This allows - // helpers to do a check for `if (options.fn)` - if (program || inverse) { - if (!program) { - program = 'this.noop'; - } - - if (!inverse) { - inverse = 'this.noop'; - } - - options.fn = program; - options.inverse = inverse; - } - - // The parameters go on to the stack in order (making sure that they are evaluated in order) - // so we need to pop them off the stack in reverse order - var i = paramSize; - while (i--) { - param = this.popStack(); - params[i] = param; - - if (this.trackIds) { - ids[i] = this.popStack(); - } - if (this.stringParams) { - types[i] = this.popStack(); - contexts[i] = this.popStack(); - } - } - - if (this.trackIds) { - options.ids = "[" + ids.join(",") + "]"; - } - if (this.stringParams) { - options.types = "[" + types.join(",") + "]"; - options.contexts = "[" + contexts.join(",") + "]"; - } - - if (this.options.data) { - options.data = "data"; - } - - return options; - }, - - // the params and contexts arguments are passed in arrays - // to fill in - setupParams: function(helperName, paramSize, params, useRegister) { - var options = this.objectLiteral(this.setupOptions(helperName, paramSize, params)); - - if (useRegister) { - this.useRegister('options'); - params.push('options'); - return 'options=' + options; - } else { - params.push(options); - return ''; - } - } - }; - - var reservedWords = ( - "break else new var" + - " case finally return void" + - " catch for switch while" + - " continue function this with" + - " default if throw" + - " delete in try" + - " do instanceof typeof" + - " abstract enum int short" + - " boolean export interface static" + - " byte extends long super" + - " char final native synchronized" + - " class float package throws" + - " const goto private transient" + - " debugger implements protected volatile" + - " double import public let yield" - ).split(" "); - - var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {}; - - for(var i=0, l=reservedWords.length; i */ - -// -// Stub out `require` in rhino -// -function require(arg) { - var split = arg.split('/'); - var resultModule = split.length == 1 ? less.modules[split[0]] : less[split[1]]; - if (!resultModule) { - throw {message: "Cannot find module '" + arg + "'"}; - } - return resultModule; -} - - -if (typeof(window) === 'undefined') { - less = {} -} -else { - less = window.less = {} -} -tree = less.tree = {}; -less.mode = 'rhino'; - -(function () { - - console = function () { - function doLog(out) { - return function (a) { - //TODO: for some reason loging dosn't work,fix later - } - } - - return { - log: doLog(log.info), - info: doLog(log.info), - error: doLog(log.error), - warn: doLog(log.warn) - }; - }(); - - less.modules = {}; - - less.modules.path = { - join: function () { - var parts = []; - for (i in arguments) { - parts = parts.concat(arguments[i].split(/\/|\\/)); - } - var result = []; - for (i in parts) { - var part = parts[i]; - if (part === '..' && result.length > 0 && result[result.length - 1] !== '..') { - result.pop(); - } else if (part === '' && result.length > 0) { - // skip - } else if (part !== '.') { - if (part.slice(-1) === '\\' || part.slice(-1) === '/') { - part = part.slice(0, -1); - } - result.push(part); - } - } - return result.join('/'); - }, - dirname: function (p) { - var path = p.split('/'); - path.pop(); - return path.join('/'); - }, - basename: function (p, ext) { - var base = p.split('/').pop(); - if (ext) { - var index = base.lastIndexOf(ext); - if (base.length === index + ext.length) { - base = base.substr(0, index); - } - } - return base; - }, - extname: function (p) { - var index = p.lastIndexOf('.'); - return index > 0 ? p.substring(index) : ''; - } - }; - - less.modules.fs = { - readFileSync: function (name) { - // read a file into a byte array - var file = new java.io.File(name); - new Log('xxxxxxxx').info(file.getCanonicalPath()); - var stream = new java.io.FileInputStream(file); - var buffer = []; - var c; - while ((c = stream.read()) != -1) { - buffer.push(c); - } - stream.close(); - return { - length: buffer.length, - toString: function (enc) { - if (enc === 'base64') { - return encodeBase64Bytes(buffer); - } else if (enc) { - return java.lang.String["(byte[],java.lang.String)"](buffer, enc); - } else { - return java.lang.String["(byte[])"](buffer); - } - } - }; - } - }; - - less.encoder = { - encodeBase64: function (str) { - return encodeBase64String(str); - } - }; - - // --------------------------------------------------------------------------------------------- - // private helper functions - // --------------------------------------------------------------------------------------------- - - function encodeBase64Bytes(bytes) { - // requires at least a JRE Platform 6 (or JAXB 1.0 on the classpath) - return javax.xml.bind.DatatypeConverter.printBase64Binary(bytes) - } - - function encodeBase64String(str) { - return encodeBase64Bytes(new java.lang.String(str).getBytes()); - } - -})(); - -var less, tree; - -// Node.js does not have a header file added which defines less -if (less === undefined) { - less = exports; - tree = require('./tree'); - less.mode = 'node'; -} -// -// less.js - parser -// -// A relatively straight-forward predictive parser. -// There is no tokenization/lexing stage, the input is parsed -// in one sweep. -// -// To make the parser fast enough to run in the browser, several -// optimization had to be made: -// -// - Matching and slicing on a huge input is often cause of slowdowns. -// The solution is to chunkify the input into smaller strings. -// The chunks are stored in the `chunks` var, -// `j` holds the current chunk index, and `currentPos` holds -// the index of the current chunk in relation to `input`. -// This gives us an almost 4x speed-up. -// -// - In many cases, we don't need to match individual tokens; -// for example, if a value doesn't hold any variables, operations -// or dynamic references, the parser can effectively 'skip' it, -// treating it as a literal. -// An example would be '1px solid #000' - which evaluates to itself, -// we don't need to know what the individual components are. -// The drawback, of course is that you don't get the benefits of -// syntax-checking on the CSS. This gives us a 50% speed-up in the parser, -// and a smaller speed-up in the code-gen. -// -// -// Token matching is done with the `$` function, which either takes -// a terminal string or regexp, or a non-terminal function to call. -// It also takes care of moving all the indices forwards. -// -// -less.Parser = function Parser(env) { - var input, // LeSS input string - i, // current index in `input` - j, // current chunk - saveStack = [], // holds state for backtracking - furthest, // furthest index the parser has gone to - chunks, // chunkified input - current, // current chunk - currentPos, // index of current chunk, in `input` - parser, - parsers, - rootFilename = env && env.filename; - - // Top parser on an import tree must be sure there is one "env" - // which will then be passed around by reference. - if (!(env instanceof tree.parseEnv)) { - env = new tree.parseEnv(env); - } - - var imports = this.imports = { - paths: env.paths || [], // Search paths, when importing - queue: [], // Files which haven't been imported yet - files: env.files, // Holds the imported parse trees - contents: env.contents, // Holds the imported file contents - contentsIgnoredChars: env.contentsIgnoredChars, // lines inserted, not in the original less - mime: env.mime, // MIME type of .less files - error: null, // Error in parsing/evaluating an import - push: function (path, currentFileInfo, importOptions, callback) { - var parserImports = this; - this.queue.push(path); - - var fileParsedFunc = function (e, root, fullPath) { - parserImports.queue.splice(parserImports.queue.indexOf(path), 1); // Remove the path from the queue - - var importedPreviously = fullPath === rootFilename; - - parserImports.files[fullPath] = root; // Store the root - - if (e && !parserImports.error) { - parserImports.error = e; - } - - callback(e, root, importedPreviously, fullPath); - }; - - if (less.Parser.importer) { - less.Parser.importer(path, currentFileInfo, fileParsedFunc, env); - } else { - less.Parser.fileLoader(path, currentFileInfo, function (e, contents, fullPath, newFileInfo) { - if (e) { - fileParsedFunc(e); - return; - } - - var newEnv = new tree.parseEnv(env); - - newEnv.currentFileInfo = newFileInfo; - newEnv.processImports = false; - newEnv.contents[fullPath] = contents; - - if (currentFileInfo.reference || importOptions.reference) { - newFileInfo.reference = true; - } - - if (importOptions.inline) { - fileParsedFunc(null, contents, fullPath); - } else { - new (less.Parser)(newEnv).parse(contents, function (e, root) { - fileParsedFunc(e, root, fullPath); - }); - } - }, env); - } - } - }; - - function save() { - currentPos = i; - saveStack.push({current: current, i: i, j: j}); - } - - function restore() { - var state = saveStack.pop(); - current = state.current; - currentPos = i = state.i; - j = state.j; - } - - function forget() { - saveStack.pop(); - } - - function sync() { - if (i > currentPos) { - current = current.slice(i - currentPos); - currentPos = i; - } - } - - function isWhitespace(str, pos) { - var code = str.charCodeAt(pos | 0); - return (code <= 32) && (code === 32 || code === 10 || code === 9); - } - - // - // Parse from a token, regexp or string, and move forward if match - // - function $(tok) { - var tokType = typeof tok, - match, length; - - // Either match a single character in the input, - // or match a regexp in the current chunk (`current`). - // - if (tokType === "string") { - if (input.charAt(i) !== tok) { - return null; - } - skipWhitespace(1); - return tok; - } - - // regexp - sync(); - if (!(match = tok.exec(current))) { - return null; - } - - length = match[0].length; - - // The match is confirmed, add the match length to `i`, - // and consume any extra white-space characters (' ' || '\n') - // which come after that. The reason for this is that LeSS's - // grammar is mostly white-space insensitive. - // - skipWhitespace(length); - - if (typeof(match) === 'string') { - return match; - } else { - return match.length === 1 ? match[0] : match; - } - } - - // Specialization of $(tok) - function $re(tok) { - if (i > currentPos) { - current = current.slice(i - currentPos); - currentPos = i; - } - var m = tok.exec(current); - if (!m) { - return null; - } - - skipWhitespace(m[0].length); - if (typeof m === "string") { - return m; - } - - return m.length === 1 ? m[0] : m; - } - - var _$re = $re; - - // Specialization of $(tok) - function $char(tok) { - if (input.charAt(i) !== tok) { - return null; - } - skipWhitespace(1); - return tok; - } - - function skipWhitespace(length) { - var oldi = i, oldj = j, - curr = i - currentPos, - endIndex = i + current.length - curr, - mem = (i += length), - inp = input, - c; - - for (; i < endIndex; i++) { - c = inp.charCodeAt(i); - if (c > 32) { - break; - } - - if ((c !== 32) && (c !== 10) && (c !== 9) && (c !== 13)) { - break; - } - } - - current = current.slice(length + i - mem + curr); - currentPos = i; - - if (!current.length && (j < chunks.length - 1)) { - current = chunks[++j]; - skipWhitespace(0); // skip space at the beginning of a chunk - return true; // things changed - } - - return oldi !== i || oldj !== j; - } - - function expect(arg, msg, index) { - // some older browsers return typeof 'function' for RegExp - var result = (Object.prototype.toString.call(arg) === '[object Function]') ? arg.call(parsers) : $(arg); - if (result) { - return result; - } - error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'" - : "unexpected token")); - } - - // Specialization of expect() - function expectChar(arg, msg) { - if (input.charAt(i) === arg) { - skipWhitespace(1); - return arg; - } - error(msg || "expected '" + arg + "' got '" + input.charAt(i) + "'"); - } - - function error(msg, type) { - var e = new Error(msg); - e.index = i; - e.type = type || 'Syntax'; - throw e; - } - - // Same as $(), but don't change the state of the parser, - // just return the match. - function peek(tok) { - if (typeof(tok) === 'string') { - return input.charAt(i) === tok; - } else { - return tok.test(current); - } - } - - // Specialization of peek() - function peekChar(tok) { - return input.charAt(i) === tok; - } - - - function getInput(e, env) { - if (e.filename && env.currentFileInfo.filename && (e.filename !== env.currentFileInfo.filename)) { - return parser.imports.contents[e.filename]; - } else { - return input; - } - } - - function getLocation(index, inputStream) { - var n = index + 1, - line = null, - column = -1; - - while (--n >= 0 && inputStream.charAt(n) !== '\n') { - column++; - } - - if (typeof index === 'number') { - line = (inputStream.slice(0, index).match(/\n/g) || "").length; - } - - return { - line: line, - column: column - }; - } - - function getDebugInfo(index, inputStream, env) { - var filename = env.currentFileInfo.filename; - if (less.mode !== 'browser' && less.mode !== 'rhino') { - filename = require('path').resolve(filename); - } - - return { - lineNumber: getLocation(index, inputStream).line + 1, - fileName: filename - }; - } - - function LessError(e, env) { - var input = getInput(e, env), - loc = getLocation(e.index, input), - line = loc.line, - col = loc.column, - callLine = e.call && getLocation(e.call, input).line, - lines = input.split('\n'); - - this.type = e.type || 'Syntax'; - this.message = e.message; - this.filename = e.filename || env.currentFileInfo.filename; - this.index = e.index; - this.line = typeof(line) === 'number' ? line + 1 : null; - this.callLine = callLine + 1; - this.callExtract = lines[callLine]; - this.stack = e.stack; - this.column = col; - this.extract = [ - lines[line - 1], - lines[line], - lines[line + 1] - ]; - } - - LessError.prototype = new Error(); - LessError.prototype.constructor = LessError; - - this.env = env = env || {}; - - // The optimization level dictates the thoroughness of the parser, - // the lower the number, the less nodes it will create in the tree. - // This could matter for debugging, or if you want to access - // the individual nodes in the tree. - this.optimization = ('optimization' in this.env) ? this.env.optimization : 1; - - // - // The Parser - // - parser = { - - imports: imports, - // - // Parse an input string into an abstract syntax tree, - // @param str A string containing 'less' markup - // @param callback call `callback` when done. - // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply - // - parse: function (str, callback, additionalData) { - var root, line, lines, error = null, globalVars, modifyVars, preText = ""; - - i = j = currentPos = furthest = 0; - - globalVars = (additionalData && additionalData.globalVars) ? less.Parser.serializeVars(additionalData.globalVars) + '\n' : ''; - modifyVars = (additionalData && additionalData.modifyVars) ? '\n' + less.Parser.serializeVars(additionalData.modifyVars) : ''; - - if (globalVars || (additionalData && additionalData.banner)) { - preText = ((additionalData && additionalData.banner) ? additionalData.banner : "") + globalVars; - parser.imports.contentsIgnoredChars[env.currentFileInfo.filename] = preText.length; - } - - str = str.replace(/\r\n/g, '\n'); - // Remove potential UTF Byte Order Mark - input = str = preText + str.replace(/^\uFEFF/, '') + modifyVars; - parser.imports.contents[env.currentFileInfo.filename] = str; - - // Split the input into chunks. - chunks = (function (input) { - var len = input.length, level = 0, parenLevel = 0, - lastOpening, lastOpeningParen, lastMultiComment, lastMultiCommentEndBrace, - chunks = [], emitFrom = 0, - parserCurrentIndex, currentChunkStartIndex, cc, cc2, matched; - - function fail(msg, index) { - error = new (LessError)({ - index: index || parserCurrentIndex, - type: 'Parse', - message: msg, - filename: env.currentFileInfo.filename - }, env); - } - - function emitChunk(force) { - var len = parserCurrentIndex - emitFrom; - if (((len < 512) && !force) || !len) { - return; - } - chunks.push(input.slice(emitFrom, parserCurrentIndex + 1)); - emitFrom = parserCurrentIndex + 1; - } - - for (parserCurrentIndex = 0; parserCurrentIndex < len; parserCurrentIndex++) { - cc = input.charCodeAt(parserCurrentIndex); - if (((cc >= 97) && (cc <= 122)) || (cc < 34)) { - // a-z or whitespace - continue; - } - - switch (cc) { - case 40: // ( - parenLevel++; - lastOpeningParen = parserCurrentIndex; - continue; - case 41: // ) - if (--parenLevel < 0) { - return fail("missing opening `(`"); - } - continue; - case 59: // ; - if (!parenLevel) { - emitChunk(); - } - continue; - case 123: // { - level++; - lastOpening = parserCurrentIndex; - continue; - case 125: // } - if (--level < 0) { - return fail("missing opening `{`"); - } - if (!level && !parenLevel) { - emitChunk(); - } - continue; - case 92: // \ - if (parserCurrentIndex < len - 1) { - parserCurrentIndex++; - continue; - } - return fail("unescaped `\\`"); - case 34: - case 39: - case 96: // ", ' and ` - matched = 0; - currentChunkStartIndex = parserCurrentIndex; - for (parserCurrentIndex = parserCurrentIndex + 1; parserCurrentIndex < len; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if (cc2 > 96) { - continue; - } - if (cc2 == cc) { - matched = 1; - break; - } - if (cc2 == 92) { // \ - if (parserCurrentIndex == len - 1) { - return fail("unescaped `\\`"); - } - parserCurrentIndex++; - } - } - if (matched) { - continue; - } - return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex); - case 47: // /, check for comment - if (parenLevel || (parserCurrentIndex == len - 1)) { - continue; - } - cc2 = input.charCodeAt(parserCurrentIndex + 1); - if (cc2 == 47) { - // //, find lnfeed - for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { - break; - } - } - } else if (cc2 == 42) { - // /*, find */ - lastMultiComment = currentChunkStartIndex = parserCurrentIndex; - for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len - 1; parserCurrentIndex++) { - cc2 = input.charCodeAt(parserCurrentIndex); - if (cc2 == 125) { - lastMultiCommentEndBrace = parserCurrentIndex; - } - if (cc2 != 42) { - continue; - } - if (input.charCodeAt(parserCurrentIndex + 1) == 47) { - break; - } - } - if (parserCurrentIndex == len - 1) { - return fail("missing closing `*/`", currentChunkStartIndex); - } - parserCurrentIndex++; - } - continue; - case 42: // *, check for unmatched */ - if ((parserCurrentIndex < len - 1) && (input.charCodeAt(parserCurrentIndex + 1) == 47)) { - return fail("unmatched `/*`"); - } - continue; - } - } - - if (level !== 0) { - if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) { - return fail("missing closing `}` or `*/`", lastOpening); - } else { - return fail("missing closing `}`", lastOpening); - } - } else if (parenLevel !== 0) { - return fail("missing closing `)`", lastOpeningParen); - } - - emitChunk(true); - return chunks; - })(str); - - if (error) { - return callback(new (LessError)(error, env)); - } - - current = chunks[0]; - - // Start with the primary rule. - // The whole syntax tree is held under a Ruleset node, - // with the `root` property set to true, so no `{}` are - // output. The callback is called when the input is parsed. - try { - root = new (tree.Ruleset)(null, this.parsers.primary()); - root.root = true; - root.firstRoot = true; - } catch (e) { - return callback(new (LessError)(e, env)); - } - - root.toCSS = (function (evaluate) { - return function (options, variables) { - options = options || {}; - var evaldRoot, - css, - evalEnv = new tree.evalEnv(options); - - // - // Allows setting variables with a hash, so: - // - // `{ color: new(tree.Color)('#f01') }` will become: - // - // new(tree.Rule)('@color', - // new(tree.Value)([ - // new(tree.Expression)([ - // new(tree.Color)('#f01') - // ]) - // ]) - // ) - // - if (typeof(variables) === 'object' && !Array.isArray(variables)) { - variables = Object.keys(variables).map(function (k) { - var value = variables[k]; - - if (!(value instanceof tree.Value)) { - if (!(value instanceof tree.Expression)) { - value = new (tree.Expression)([value]); - } - value = new (tree.Value)([value]); - } - return new (tree.Rule)('@' + k, value, false, null, 0); - }); - evalEnv.frames = [new (tree.Ruleset)(null, variables)]; - } - - try { - var preEvalVisitors = [], - visitors = [ - new (tree.joinSelectorVisitor)(), - new (tree.processExtendsVisitor)(), - new (tree.toCSSVisitor)({compress: Boolean(options.compress)}) - ], i, root = this; - - if (options.plugins) { - for (i = 0; i < options.plugins.length; i++) { - if (options.plugins[i].isPreEvalVisitor) { - preEvalVisitors.push(options.plugins[i]); - } else { - if (options.plugins[i].isPreVisitor) { - visitors.splice(0, 0, options.plugins[i]); - } else { - visitors.push(options.plugins[i]); - } - } - } - } - - for (i = 0; i < preEvalVisitors.length; i++) { - preEvalVisitors[i].run(root); - } - - evaldRoot = evaluate.call(root, evalEnv); - - for (i = 0; i < visitors.length; i++) { - visitors[i].run(evaldRoot); - } - - if (options.sourceMap) { - evaldRoot = new tree.sourceMapOutput( - { - contentsIgnoredCharsMap: parser.imports.contentsIgnoredChars, - writeSourceMap: options.writeSourceMap, - rootNode: evaldRoot, - contentsMap: parser.imports.contents, - sourceMapFilename: options.sourceMapFilename, - sourceMapURL: options.sourceMapURL, - outputFilename: options.sourceMapOutputFilename, - sourceMapBasepath: options.sourceMapBasepath, - sourceMapRootpath: options.sourceMapRootpath, - outputSourceFiles: options.outputSourceFiles, - sourceMapGenerator: options.sourceMapGenerator - }); - } - - css = evaldRoot.toCSS({ - compress: Boolean(options.compress), - dumpLineNumbers: env.dumpLineNumbers, - strictUnits: Boolean(options.strictUnits), - numPrecision: 8 - }); - } catch (e) { - throw new (LessError)(e, env); - } - - if (options.cleancss && less.mode === 'node') { - var CleanCSS = require('clean-css'), - cleancssOptions = options.cleancssOptions || {}; - - if (cleancssOptions.keepSpecialComments === undefined) { - cleancssOptions.keepSpecialComments = "*"; - } - cleancssOptions.processImport = false; - cleancssOptions.noRebase = true; - if (cleancssOptions.noAdvanced === undefined) { - cleancssOptions.noAdvanced = true; - } - - return new CleanCSS(cleancssOptions).minify(css); - } else if (options.compress) { - return css.replace(/(^(\s)+)|((\s)+$)/g, ""); - } else { - return css; - } - }; - })(root.eval); - - // If `i` is smaller than the `input.length - 1`, - // it means the parser wasn't able to parse the whole - // string, so we've got a parsing error. - // - // We try to extract a \n delimited string, - // showing the line where the parse error occured. - // We split it up into two parts (the part which parsed, - // and the part which didn't), so we can color them differently. - if (i < input.length - 1) { - i = furthest; - var loc = getLocation(i, input); - lines = input.split('\n'); - line = loc.line + 1; - - error = { - type: "Parse", - message: "Unrecognised input", - index: i, - filename: env.currentFileInfo.filename, - line: line, - column: loc.column, - extract: [ - lines[line - 2], - lines[line - 1], - lines[line] - ] - }; - } - - var finish = function (e) { - e = error || e || parser.imports.error; - - if (e) { - if (!(e instanceof LessError)) { - e = new (LessError)(e, env); - } - - return callback(e); - } - else { - return callback(null, root); - } - }; - - if (env.processImports !== false) { - new tree.importVisitor(this.imports, finish) - .run(root); - } else { - return finish(); - } - }, - - // - // Here in, the parsing rules/functions - // - // The basic structure of the syntax tree generated is as follows: - // - // Ruleset -> Rule -> Value -> Expression -> Entity - // - // Here's some Less code: - // - // .class { - // color: #fff; - // border: 1px solid #000; - // width: @w + 4px; - // > .child {...} - // } - // - // And here's what the parse tree might look like: - // - // Ruleset (Selector '.class', [ - // Rule ("color", Value ([Expression [Color #fff]])) - // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) - // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]])) - // Ruleset (Selector [Element '>', '.child'], [...]) - // ]) - // - // In general, most rules will try to parse a token with the `$()` function, and if the return - // value is truly, will return a new node, of the relevant type. Sometimes, we need to check - // first, before parsing, that's when we use `peek()`. - // - parsers: parsers = { - // - // The `primary` rule is the *entry* and *exit* point of the parser. - // The rules here can appear at any level of the parse tree. - // - // The recursive nature of the grammar is an interplay between the `block` - // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, - // as represented by this simplified grammar: - // - // primary → (ruleset | rule)+ - // ruleset → selector+ block - // block → '{' primary '}' - // - // Only at one point is the primary rule not called from the - // block rule: at the root level. - // - primary: function () { - var mixin = this.mixin, $re = _$re, root = [], node; - - while (current) { - node = this.extendRule() || mixin.definition() || this.rule() || this.ruleset() || - mixin.call() || this.comment() || this.rulesetCall() || this.directive(); - if (node) { - root.push(node); - } else { - if (!($re(/^[\s\n]+/) || $re(/^;+/))) { - break; - } - } - if (peekChar('}')) { - break; - } - } - - return root; - }, - - // We create a Comment node for CSS comments `/* */`, - // but keep the LeSS comments `//` silent, by just skipping - // over them. - comment: function () { - var comment; - - if (input.charAt(i) !== '/') { - return; - } - - if (input.charAt(i + 1) === '/') { - return new (tree.Comment)($re(/^\/\/.*/), true, i, env.currentFileInfo); - } - comment = $re(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/); - if (comment) { - return new (tree.Comment)(comment, false, i, env.currentFileInfo); - } - }, - - comments: function () { - var comment, comments = []; - - while (true) { - comment = this.comment(); - if (!comment) { - break; - } - comments.push(comment); - } - - return comments; - }, - - // - // Entities are tokens which can be found inside an Expression - // - entities: { - // - // A string, which supports escaping " and ' - // - // "milky way" 'he\'s the one!' - // - quoted: function () { - var str, j = i, e, index = i; - - if (input.charAt(j) === '~') { - j++; - e = true; - } // Escaped strings - if (input.charAt(j) !== '"' && input.charAt(j) !== "'") { - return; - } - - if (e) { - $char('~'); - } - - str = $re(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/); - if (str) { - return new (tree.Quoted)(str[0], str[1] || str[2], e, index, env.currentFileInfo); - } - }, - - // - // A catch-all word, such as: - // - // black border-collapse - // - keyword: function () { - var k; - - k = $re(/^%|^[_A-Za-z-][_A-Za-z0-9-]*/); - if (k) { - var color = tree.Color.fromKeyword(k); - if (color) { - return color; - } - return new (tree.Keyword)(k); - } - }, - - // - // A function call - // - // rgb(255, 0, 255) - // - // We also try to catch IE's `alpha()`, but let the `alpha` parser - // deal with the details. - // - // The arguments are parsed with the `entities.arguments` parser. - // - call: function () { - var name, nameLC, args, alpha_ret, index = i; - - name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(current); - if (!name) { - return; - } - - name = name[1]; - nameLC = name.toLowerCase(); - if (nameLC === 'url') { - return null; - } - - i += name.length; - - if (nameLC === 'alpha') { - alpha_ret = parsers.alpha(); - if (typeof alpha_ret !== 'undefined') { - return alpha_ret; - } - } - - $char('('); // Parse the '(' and consume whitespace. - - args = this.arguments(); - - if (!$char(')')) { - return; - } - - if (name) { - return new (tree.Call)(name, args, index, env.currentFileInfo); - } - }, - arguments: function () { - var args = [], arg; - - while (true) { - arg = this.assignment() || parsers.expression(); - if (!arg) { - break; - } - args.push(arg); - if (!$char(',')) { - break; - } - } - return args; - }, - literal: function () { - return this.dimension() || - this.color() || - this.quoted() || - this.unicodeDescriptor(); - }, - - // Assignments are argument entities for calls. - // They are present in ie filter properties as shown below. - // - // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) - // - - assignment: function () { - var key, value; - key = $re(/^\w+(?=\s?=)/i); - if (!key) { - return; - } - if (!$char('=')) { - return; - } - value = parsers.entity(); - if (value) { - return new (tree.Assignment)(key, value); - } - }, - - // - // Parse url() tokens - // - // We use a specific rule for urls, because they don't really behave like - // standard function calls. The difference is that the argument doesn't have - // to be enclosed within a string, so it can't be parsed as an Expression. - // - url: function () { - var value; - - if (input.charAt(i) !== 'u' || !$re(/^url\(/)) { - return; - } - - value = this.quoted() || this.variable() || - $re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ""; - - expectChar(')'); - - return new (tree.URL)((value.value != null || value instanceof tree.Variable) - ? value : new (tree.Anonymous)(value), env.currentFileInfo); - }, - - // - // A Variable entity, such as `@fink`, in - // - // width: @fink + 2px - // - // We use a different parser for variable definitions, - // see `parsers.variable`. - // - variable: function () { - var name, index = i; - - if (input.charAt(i) === '@' && (name = $re(/^@@?[\w-]+/))) { - return new (tree.Variable)(name, index, env.currentFileInfo); - } - }, - - // A variable entity useing the protective {} e.g. @{var} - variableCurly: function () { - var curly, index = i; - - if (input.charAt(i) === '@' && (curly = $re(/^@\{([\w-]+)\}/))) { - return new (tree.Variable)("@" + curly[1], index, env.currentFileInfo); - } - }, - - // - // A Hexadecimal color - // - // #4F3C2F - // - // `rgb` and `hsl` colors are parsed through the `entities.call` parser. - // - color: function () { - var rgb; - - if (input.charAt(i) === '#' && (rgb = $re(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) { - var colorCandidateString = rgb.input.match(/^#([\w]+).*/); // strip colons, brackets, whitespaces and other characters that should not definitely be part of color string - colorCandidateString = colorCandidateString[1]; - if (!colorCandidateString.match(/^[A-Fa-f0-9]+$/)) { // verify if candidate consists only of allowed HEX characters - error("Invalid HEX color code"); - } - return new (tree.Color)(rgb[1]); - } - }, - - // - // A Dimension, that is, a number and a unit - // - // 0.5em 95% - // - dimension: function () { - var value, c = input.charCodeAt(i); - //Is the first char of the dimension 0-9, '.', '+' or '-' - if ((c > 57 || c < 43) || c === 47 || c == 44) { - return; - } - - value = $re(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/); - if (value) { - return new (tree.Dimension)(value[1], value[2]); - } - }, - - // - // A unicode descriptor, as is used in unicode-range - // - // U+0?? or U+00A1-00A9 - // - unicodeDescriptor: function () { - var ud; - - ud = $re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); - if (ud) { - return new (tree.UnicodeDescriptor)(ud[0]); - } - }, - - // - // JavaScript code to be evaluated - // - // `window.location.href` - // - javascript: function () { - var str, j = i, e; - - if (input.charAt(j) === '~') { - j++; - e = true; - } // Escaped strings - if (input.charAt(j) !== '`') { - return; - } - if (env.javascriptEnabled !== undefined && !env.javascriptEnabled) { - error("You are using JavaScript, which has been disabled."); - } - - if (e) { - $char('~'); - } - - str = $re(/^`([^`]*)`/); - if (str) { - return new (tree.JavaScript)(str[1], i, e); - } - } - }, - - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink: - // - variable: function () { - var name; - - if (input.charAt(i) === '@' && (name = $re(/^(@[\w-]+)\s*:/))) { - return name[1]; - } - }, - - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink(); - // - rulesetCall: function () { - var name; - - if (input.charAt(i) === '@' && (name = $re(/^(@[\w-]+)\s*\(\s*\)\s*;/))) { - return new tree.RulesetCall(name[1]); - } - }, - - // - // extend syntax - used to extend selectors - // - extend: function (isRule) { - var elements, e, index = i, option, extendList, extend; - - if (!(isRule ? $re(/^&:extend\(/) : $re(/^:extend\(/))) { - return; - } - - do { - option = null; - elements = null; - while (!(option = $re(/^(all)(?=\s*(\)|,))/))) { - e = this.element(); - if (!e) { - break; - } - if (elements) { - elements.push(e); - } else { - elements = [e]; - } - } - - option = option && option[1]; - if (!elements) - error("Missing target selector for :extend()."); - extend = new (tree.Extend)(new (tree.Selector)(elements), option, index); - if (extendList) { - extendList.push(extend); - } else { - extendList = [extend]; - } - - } while ($char(",")); - - expect(/^\)/); - - if (isRule) { - expect(/^;/); - } - - return extendList; - }, - - // - // extendRule - used in a rule to extend all the parent selectors - // - extendRule: function () { - return this.extend(true); - }, - - // - // Mixins - // - mixin: { - // - // A Mixin call, with an optional argument list - // - // #mixins > .square(#fff); - // .rounded(4px, black); - // .button; - // - // The `while` loop is there because mixins can be - // namespaced, but we only support the child and descendant - // selector for now. - // - call: function () { - var s = input.charAt(i), important = false, index = i, elemIndex, - elements, elem, e, c, args; - - if (s !== '.' && s !== '#') { - return; - } - - save(); // stop us absorbing part of an invalid selector - - while (true) { - elemIndex = i; - e = $re(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/); - if (!e) { - break; - } - elem = new (tree.Element)(c, e, elemIndex, env.currentFileInfo); - if (elements) { - elements.push(elem); - } else { - elements = [elem]; - } - c = $char('>'); - } - - if (elements) { - if ($char('(')) { - args = this.args(true).args; - expectChar(')'); - } - - if (parsers.important()) { - important = true; - } - - if (parsers.end()) { - forget(); - return new (tree.mixin.Call)(elements, args, index, env.currentFileInfo, important); - } - } - - restore(); - }, - args: function (isCall) { - var parsers = parser.parsers, entities = parsers.entities, - returner = {args: null, variadic: false}, - expressions = [], argsSemiColon = [], argsComma = [], - isSemiColonSeperated, expressionContainsNamed, name, nameLoop, value, arg; - - save(); - - while (true) { - if (isCall) { - arg = parsers.detachedRuleset() || parsers.expression(); - } else { - parsers.comments(); - if (input.charAt(i) === '.' && $re(/^\.{3}/)) { - returner.variadic = true; - if ($char(";") && !isSemiColonSeperated) { - isSemiColonSeperated = true; - } - (isSemiColonSeperated ? argsSemiColon : argsComma) - .push({variadic: true}); - break; - } - arg = entities.variable() || entities.literal() || entities.keyword(); - } - - if (!arg) { - break; - } - - nameLoop = null; - if (arg.throwAwayComments) { - arg.throwAwayComments(); - } - value = arg; - var val = null; - - if (isCall) { - // Variable - if (arg.value && arg.value.length == 1) { - val = arg.value[0]; - } - } else { - val = arg; - } - - if (val && val instanceof tree.Variable) { - if ($char(':')) { - if (expressions.length > 0) { - if (isSemiColonSeperated) { - error("Cannot mix ; and , as delimiter types"); - } - expressionContainsNamed = true; - } - - // we do not support setting a ruleset as a default variable - it doesn't make sense - // However if we do want to add it, there is nothing blocking it, just don't error - // and remove isCall dependency below - value = (isCall && parsers.detachedRuleset()) || parsers.expression(); - - if (!value) { - if (isCall) { - error("could not understand value for named argument"); - } else { - restore(); - returner.args = []; - return returner; - } - } - nameLoop = (name = val.name); - } else if (!isCall && $re(/^\.{3}/)) { - returner.variadic = true; - if ($char(";") && !isSemiColonSeperated) { - isSemiColonSeperated = true; - } - (isSemiColonSeperated ? argsSemiColon : argsComma) - .push({name: arg.name, variadic: true}); - break; - } else if (!isCall) { - name = nameLoop = val.name; - value = null; - } - } - - if (value) { - expressions.push(value); - } - - argsComma.push({name: nameLoop, value: value}); - - if ($char(',')) { - continue; - } - - if ($char(';') || isSemiColonSeperated) { - - if (expressionContainsNamed) { - error("Cannot mix ; and , as delimiter types"); - } - - isSemiColonSeperated = true; - - if (expressions.length > 1) { - value = new (tree.Value)(expressions); - } - argsSemiColon.push({name: name, value: value}); - - name = null; - expressions = []; - expressionContainsNamed = false; - } - } - - forget(); - returner.args = isSemiColonSeperated ? argsSemiColon : argsComma; - return returner; - }, - // - // A Mixin definition, with a list of parameters - // - // .rounded (@radius: 2px, @color) { - // ... - // } - // - // Until we have a finer grained state-machine, we have to - // do a look-ahead, to make sure we don't have a mixin call. - // See the `rule` function for more information. - // - // We start by matching `.rounded (`, and then proceed on to - // the argument list, which has optional default values. - // We store the parameters in `params`, with a `value` key, - // if there is a value, such as in the case of `@radius`. - // - // Once we've got our params list, and a closing `)`, we parse - // the `{...}` block. - // - definition: function () { - var name, params = [], match, ruleset, cond, variadic = false; - if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') || - peek(/^[^{]*\}/)) { - return; - } - - save(); - - match = $re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/); - if (match) { - name = match[1]; - - var argInfo = this.args(false); - params = argInfo.args; - variadic = argInfo.variadic; - - // .mixincall("@{a}"); - // looks a bit like a mixin definition.. - // also - // .mixincall(@a: {rule: set;}); - // so we have to be nice and restore - if (!$char(')')) { - furthest = i; - restore(); - return; - } - - parsers.comments(); - - if ($re(/^when/)) { // Guard - cond = expect(parsers.conditions, 'expected condition'); - } - - ruleset = parsers.block(); - - if (ruleset) { - forget(); - return new (tree.mixin.Definition)(name, params, ruleset, cond, variadic); - } else { - restore(); - } - } else { - forget(); - } - } - }, - - // - // Entities are the smallest recognized token, - // and can be found inside a rule's value. - // - entity: function () { - var entities = this.entities; - - return entities.literal() || entities.variable() || entities.url() || - entities.call() || entities.keyword() || entities.javascript() || - this.comment(); - }, - - // - // A Rule terminator. Note that we use `peek()` to check for '}', - // because the `block` rule will be expecting it, but we still need to make sure - // it's there, if ';' was ommitted. - // - end: function () { - return $char(';') || peekChar('}'); - }, - - // - // IE's alpha function - // - // alpha(opacity=88) - // - alpha: function () { - var value; - - if (!$re(/^\(opacity=/i)) { - return; - } - value = $re(/^\d+/) || this.entities.variable(); - if (value) { - expectChar(')'); - return new (tree.Alpha)(value); - } - }, - - // - // A Selector Element - // - // div - // + h1 - // #socks - // input[type="text"] - // - // Elements are the building blocks for Selectors, - // they are made out of a `Combinator` (see combinator rule), - // and an element name, such as a tag a class, or `*`. - // - element: function () { - var e, c, v, index = i; - - c = this.combinator(); - - e = $re(/^(?:\d+\.\d+|\d+)%/) || $re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || - $char('*') || $char('&') || this.attribute() || $re(/^\([^()@]+\)/) || $re(/^[\.#](?=@)/) || - this.entities.variableCurly(); - - if (!e) { - save(); - if ($char('(')) { - if ((v = this.selector()) && $char(')')) { - e = new (tree.Paren)(v); - forget(); - } else { - restore(); - } - } else { - forget(); - } - } - - if (e) { - return new (tree.Element)(c, e, index, env.currentFileInfo); - } - }, - - // - // Combinators combine elements together, in a Selector. - // - // Because our parser isn't white-space sensitive, special care - // has to be taken, when parsing the descendant combinator, ` `, - // as it's an empty space. We have to check the previous character - // in the input, to see if it's a ` ` character. More info on how - // we deal with this in *combinator.js*. - // - combinator: function () { - var c = input.charAt(i); - - if (c === '/') { - save(); - var slashedCombinator = $re(/^\/[a-z]+\//i); - if (slashedCombinator) { - forget(); - return new (tree.Combinator)(slashedCombinator); - } - restore(); - } - - if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') { - i++; - if (c === '^' && input.charAt(i) === '^') { - c = '^^'; - i++; - } - while (isWhitespace(input, i)) { - i++; - } - return new (tree.Combinator)(c); - } else if (isWhitespace(input, i - 1)) { - return new (tree.Combinator)(" "); - } else { - return new (tree.Combinator)(null); - } - }, - // - // A CSS selector (see selector below) - // with less extensions e.g. the ability to extend and guard - // - lessSelector: function () { - return this.selector(true); - }, - // - // A CSS Selector - // - // .class > div + h1 - // li a:hover - // - // Selectors are made out of one or more Elements, see above. - // - selector: function (isLess) { - var index = i, $re = _$re, elements, extendList, c, e, extend, when, condition; - - while ((isLess && (extend = this.extend())) || (isLess && (when = $re(/^when/))) || (e = this.element())) { - if (when) { - condition = expect(this.conditions, 'expected condition'); - } else if (condition) { - error("CSS guard can only be used at the end of selector"); - } else if (extend) { - if (extendList) { - extendList.push(extend); - } else { - extendList = [extend]; - } - } else { - if (extendList) { - error("Extend can only be used at the end of selector"); - } - c = input.charAt(i); - if (elements) { - elements.push(e); - } else { - elements = [e]; - } - e = null; - } - if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { - break; - } - } - - if (elements) { - return new (tree.Selector)(elements, extendList, condition, index, env.currentFileInfo); - } - if (extendList) { - error("Extend must be used to extend a selector, it cannot be used on its own"); - } - }, - attribute: function () { - if (!$char('[')) { - return; - } - - var entities = this.entities, - key, val, op; - - if (!(key = entities.variableCurly())) { - key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); - } - - op = $re(/^[|~*$^]?=/); - if (op) { - val = entities.quoted() || $re(/^[0-9]+%/) || $re(/^[\w-]+/) || entities.variableCurly(); - } - - expectChar(']'); - - return new (tree.Attribute)(key, op, val); - }, - - // - // The `block` rule is used by `ruleset` and `mixin.definition`. - // It's a wrapper around the `primary` rule, with added `{}`. - // - block: function () { - var content; - if ($char('{') && (content = this.primary()) && $char('}')) { - return content; - } - }, - - blockRuleset: function () { - var block = this.block(); - - if (block) { - block = new tree.Ruleset(null, block); - } - return block; - }, - - detachedRuleset: function () { - var blockRuleset = this.blockRuleset(); - if (blockRuleset) { - return new tree.DetachedRuleset(blockRuleset); - } - }, - - // - // div, .class, body > p {...} - // - ruleset: function () { - var selectors, s, rules, debugInfo; - - save(); - - if (env.dumpLineNumbers) { - debugInfo = getDebugInfo(i, input, env); - } - - while (true) { - s = this.lessSelector(); - if (!s) { - break; - } - if (selectors) { - selectors.push(s); - } else { - selectors = [s]; - } - this.comments(); - if (s.condition && selectors.length > 1) { - error("Guards are only currently allowed on a single selector."); - } - if (!$char(',')) { - break; - } - if (s.condition) { - error("Guards are only currently allowed on a single selector."); - } - this.comments(); - } - - if (selectors && (rules = this.block())) { - forget(); - var ruleset = new (tree.Ruleset)(selectors, rules, env.strictImports); - if (env.dumpLineNumbers) { - ruleset.debugInfo = debugInfo; - } - return ruleset; - } else { - // Backtrack - furthest = i; - restore(); - } - }, - rule: function (tryAnonymous) { - var name, value, startOfRule = i, c = input.charAt(startOfRule), important, merge, isVariable; - - if (c === '.' || c === '#' || c === '&') { - return; - } - - save(); - - name = this.variable() || this.ruleProperty(); - if (name) { - isVariable = typeof name === "string"; - - if (isVariable) { - value = this.detachedRuleset(); - } - - this.comments(); - if (!value) { - // prefer to try to parse first if its a variable or we are compressing - // but always fallback on the other one - value = !tryAnonymous && (env.compress || isVariable) ? - (this.value() || this.anonymousValue()) : - (this.anonymousValue() || this.value()); - - important = this.important(); - - // a name returned by this.ruleProperty() is always an array of the form: - // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"] - // where each item is a tree.Keyword or tree.Variable - merge = !isVariable && name.pop().value; - } - - if (value && this.end()) { - forget(); - return new (tree.Rule)(name, value, important, merge, startOfRule, env.currentFileInfo); - } else { - furthest = i; - restore(); - if (value && !tryAnonymous) { - return this.rule(true); - } - } - } else { - forget(); - } - }, - anonymousValue: function () { - var match; - match = /^([^@+\/'"*`(;{}-]*);/.exec(current); - if (match) { - i += match[0].length - 1; - return new (tree.Anonymous)(match[1]); - } - }, - - // - // An @import directive - // - // @import "lib"; - // - // Depending on our environment, importing is done differently: - // In the browser, it's an XHR request, in Node, it would be a - // file-system operation. The function used for importing is - // stored in `import`, which we pass to the Import constructor. - // - "import": function () { - var path, features, index = i; - - var dir = $re(/^@import?\s+/); - - if (dir) { - var options = (dir ? this.importOptions() : null) || {}; - - if ((path = this.entities.quoted() || this.entities.url())) { - features = this.mediaFeatures(); - - if (!$(';')) { - i = index; - error("missing semi-colon or unrecognised media features on import"); - } - features = features && new (tree.Value)(features); - return new (tree.Import)(path, features, options, index, env.currentFileInfo); - } - else { - i = index; - error("malformed import statement"); - } - } - }, - - importOptions: function () { - var o, options = {}, optionName, value; - - // list of options, surrounded by parens - if (!$char('(')) { - return null; - } - do { - o = this.importOption(); - if (o) { - optionName = o; - value = true; - switch (optionName) { - case "css": - optionName = "less"; - value = false; - break; - case "once": - optionName = "multiple"; - value = false; - break; - } - options[optionName] = value; - if (!$char(',')) { - break; - } - } - } while (o); - expectChar(')'); - return options; - }, - - importOption: function () { - var opt = $re(/^(less|css|multiple|once|inline|reference)/); - if (opt) { - return opt[1]; - } - }, - - mediaFeature: function () { - var entities = this.entities, nodes = [], e, p; - do { - e = entities.keyword() || entities.variable(); - if (e) { - nodes.push(e); - } else if ($char('(')) { - p = this.property(); - e = this.value(); - if ($char(')')) { - if (p && e) { - nodes.push(new (tree.Paren)(new (tree.Rule)(p, e, null, null, i, env.currentFileInfo, true))); - } else if (e) { - nodes.push(new (tree.Paren)(e)); - } else { - return null; - } - } else { - return null; - } - } - } while (e); - - if (nodes.length > 0) { - return new (tree.Expression)(nodes); - } - }, - - mediaFeatures: function () { - var entities = this.entities, features = [], e; - do { - e = this.mediaFeature(); - if (e) { - features.push(e); - if (!$char(',')) { - break; - } - } else { - e = entities.variable(); - if (e) { - features.push(e); - if (!$char(',')) { - break; - } - } - } - } while (e); - - return features.length > 0 ? features : null; - }, - - media: function () { - var features, rules, media, debugInfo; - - if (env.dumpLineNumbers) { - debugInfo = getDebugInfo(i, input, env); - } - - if ($re(/^@media/)) { - features = this.mediaFeatures(); - - rules = this.block(); - if (rules) { - media = new (tree.Media)(rules, features, i, env.currentFileInfo); - if (env.dumpLineNumbers) { - media.debugInfo = debugInfo; - } - return media; - } - } - }, - - // - // A CSS Directive - // - // @charset "utf-8"; - // - directive: function () { - var index = i, name, value, rules, nonVendorSpecificName, - hasIdentifier, hasExpression, hasUnknown, hasBlock = true; - - if (input.charAt(i) !== '@') { - return; - } - - value = this['import']() || this.media(); - if (value) { - return value; - } - - save(); - - name = $re(/^@[a-z-]+/); - - if (!name) { - return; - } - - nonVendorSpecificName = name; - if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { - nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1); - } - - switch (nonVendorSpecificName) { - /* - case "@font-face": - case "@viewport": - case "@top-left": - case "@top-left-corner": - case "@top-center": - case "@top-right": - case "@top-right-corner": - case "@bottom-left": - case "@bottom-left-corner": - case "@bottom-center": - case "@bottom-right": - case "@bottom-right-corner": - case "@left-top": - case "@left-middle": - case "@left-bottom": - case "@right-top": - case "@right-middle": - case "@right-bottom": - hasBlock = true; - break; - */ - case "@charset": - hasIdentifier = true; - hasBlock = false; - break; - case "@namespace": - hasExpression = true; - hasBlock = false; - break; - case "@keyframes": - hasIdentifier = true; - break; - case "@host": - case "@page": - case "@document": - case "@supports": - hasUnknown = true; - break; - } - - this.comments(); - - if (hasIdentifier) { - value = this.entity(); - if (!value) { - error("expected " + name + " identifier"); - } - } else if (hasExpression) { - value = this.expression(); - if (!value) { - error("expected " + name + " expression"); - } - } else if (hasUnknown) { - value = ($re(/^[^{;]+/) || '').trim(); - if (value) { - value = new (tree.Anonymous)(value); - } - } - - this.comments(); - - if (hasBlock) { - rules = this.blockRuleset(); - } - - if (rules || (!hasBlock && value && $char(';'))) { - forget(); - return new (tree.Directive)(name, value, rules, index, env.currentFileInfo, - env.dumpLineNumbers ? getDebugInfo(index, input, env) : null); - } - - restore(); - }, - - // - // A Value is a comma-delimited list of Expressions - // - // font-family: Baskerville, Georgia, serif; - // - // In a Rule, a Value represents everything after the `:`, - // and before the `;`. - // - value: function () { - var e, expressions = []; - - do { - e = this.expression(); - if (e) { - expressions.push(e); - if (!$char(',')) { - break; - } - } - } while (e); - - if (expressions.length > 0) { - return new (tree.Value)(expressions); - } - }, - important: function () { - if (input.charAt(i) === '!') { - return $re(/^! *important/); - } - }, - sub: function () { - var a, e; - - if ($char('(')) { - a = this.addition(); - if (a) { - e = new (tree.Expression)([a]); - expectChar(')'); - e.parens = true; - return e; - } - } - }, - multiplication: function () { - var m, a, op, operation, isSpaced; - m = this.operand(); - if (m) { - isSpaced = isWhitespace(input, i - 1); - while (true) { - if (peek(/^\/[*\/]/)) { - break; - } - - save(); - - op = $char('/') || $char('*'); - - if (!op) { - forget(); - break; - } - - a = this.operand(); - - if (!a) { - restore(); - break; - } - forget(); - - m.parensInOp = true; - a.parensInOp = true; - operation = new (tree.Operation)(op, [operation || m, a], isSpaced); - isSpaced = isWhitespace(input, i - 1); - } - return operation || m; - } - }, - addition: function () { - var m, a, op, operation, isSpaced; - m = this.multiplication(); - if (m) { - isSpaced = isWhitespace(input, i - 1); - while (true) { - op = $re(/^[-+]\s+/) || (!isSpaced && ($char('+') || $char('-'))); - if (!op) { - break; - } - a = this.multiplication(); - if (!a) { - break; - } - - m.parensInOp = true; - a.parensInOp = true; - operation = new (tree.Operation)(op, [operation || m, a], isSpaced); - isSpaced = isWhitespace(input, i - 1); - } - return operation || m; - } - }, - conditions: function () { - var a, b, index = i, condition; - - a = this.condition(); - if (a) { - while (true) { - if (!peek(/^,\s*(not\s*)?\(/) || !$char(',')) { - break; - } - b = this.condition(); - if (!b) { - break; - } - condition = new (tree.Condition)('or', condition || a, b, index); - } - return condition || a; - } - }, - condition: function () { - var entities = this.entities, index = i, negate = false, - a, b, c, op; - - if ($re(/^not/)) { - negate = true; - } - expectChar('('); - a = this.addition() || entities.keyword() || entities.quoted(); - if (a) { - op = $re(/^(?:>=|<=|=<|[<=>])/); - if (op) { - b = this.addition() || entities.keyword() || entities.quoted(); - if (b) { - c = new (tree.Condition)(op, a, b, index, negate); - } else { - error('expected expression'); - } - } else { - c = new (tree.Condition)('=', a, new (tree.Keyword)('true'), index, negate); - } - expectChar(')'); - return $re(/^and/) ? new (tree.Condition)('and', c, this.condition()) : c; - } - }, - - // - // An operand is anything that can be part of an operation, - // such as a Color, or a Variable - // - operand: function () { - var entities = this.entities, - p = input.charAt(i + 1), negate; - - if (input.charAt(i) === '-' && (p === '@' || p === '(')) { - negate = $char('-'); - } - var o = this.sub() || entities.dimension() || - entities.color() || entities.variable() || - entities.call(); - - if (negate) { - o.parensInOp = true; - o = new (tree.Negative)(o); - } - - return o; - }, - - // - // Expressions either represent mathematical operations, - // or white-space delimited Entities. - // - // 1px solid black - // @var * 2 - // - expression: function () { - var entities = [], e, delim; - - do { - e = this.addition() || this.entity(); - if (e) { - entities.push(e); - // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here - if (!peek(/^\/[\/*]/)) { - delim = $char('/'); - if (delim) { - entities.push(new (tree.Anonymous)(delim)); - } - } - } - } while (e); - if (entities.length > 0) { - return new (tree.Expression)(entities); - } - }, - property: function () { - var name = $re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/); - if (name) { - return name[1]; - } - }, - ruleProperty: function () { - var c = current, name = [], index = [], length = 0, s, k; - - function match(re) { - var a = re.exec(c); - if (a) { - index.push(i + length); - length += a[0].length; - c = c.slice(a[1].length); - return name.push(a[1]); - } - } - - function cutOutBlockComments() { - //match block comments - var a = /^\s*\/\*(?:[^*]|\*+[^\/*])*\*+\//.exec(c); - if (a) { - length += a[0].length; - c = c.slice(a[0].length); - return true; - } - return false; - } - - match(/^(\*?)/); - while (match(/^((?:[\w-]+)|(?:@\{[\w-]+\}))/)); // ! - while (cutOutBlockComments()); - if ((name.length > 1) && match(/^\s*((?:\+_|\+)?)\s*:/)) { - // at last, we have the complete match now. move forward, - // convert name particles to tree objects and return: - skipWhitespace(length); - if (name[0] === '') { - name.shift(); - index.shift(); - } - for (k = 0; k < name.length; k++) { - s = name[k]; - name[k] = (s.charAt(0) !== '@') - ? new (tree.Keyword)(s) - : new (tree.Variable)('@' + s.slice(2, -1), - index[k], env.currentFileInfo); - } - return name; - } - } - } - }; - return parser; -}; -less.Parser.serializeVars = function (vars) { - var s = ''; - - for (var name in vars) { - if (Object.hasOwnProperty.call(vars, name)) { - var value = vars[name]; - s += ((name[0] === '@') ? '' : '@') + name + ': ' + value + - ((('' + value).slice(-1) === ';') ? '' : ';'); - } - } - - return s; -}; - -(function (tree) { - - tree.functions = { - rgb: function (r, g, b) { - return this.rgba(r, g, b, 1.0); - }, - rgba: function (r, g, b, a) { - var rgb = [r, g, b].map(function (c) { - return scaled(c, 255); - }); - a = number(a); - return new (tree.Color)(rgb, a); - }, - hsl: function (h, s, l) { - return this.hsla(h, s, l, 1.0); - }, - hsla: function (h, s, l, a) { - function hue(h) { - h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h); - if (h * 6 < 1) { - return m1 + (m2 - m1) * h * 6; - } - else if (h * 2 < 1) { - return m2; - } - else if (h * 3 < 2) { - return m1 + (m2 - m1) * (2 / 3 - h) * 6; - } - else { - return m1; - } - } - - h = (number(h) % 360) / 360; - s = clamp(number(s)); - l = clamp(number(l)); - a = clamp(number(a)); - - var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; - var m1 = l * 2 - m2; - - return this.rgba(hue(h + 1 / 3) * 255, - hue(h) * 255, - hue(h - 1 / 3) * 255, - a); - }, - - hsv: function (h, s, v) { - return this.hsva(h, s, v, 1.0); - }, - - hsva: function (h, s, v, a) { - h = ((number(h) % 360) / 360) * 360; - s = number(s); - v = number(v); - a = number(a); - - var i, f; - i = Math.floor((h / 60) % 6); - f = (h / 60) - i; - - var vs = [v, - v * (1 - s), - v * (1 - f * s), - v * (1 - (1 - f) * s)]; - var perm = [[0, 3, 1], - [2, 0, 1], - [1, 0, 3], - [1, 2, 0], - [3, 1, 0], - [0, 1, 2]]; - - return this.rgba(vs[perm[i][0]] * 255, - vs[perm[i][1]] * 255, - vs[perm[i][2]] * 255, - a); - }, - - hue: function (color) { - return new (tree.Dimension)(color.toHSL().h); - }, - saturation: function (color) { - return new (tree.Dimension)(color.toHSL().s * 100, '%'); - }, - lightness: function (color) { - return new (tree.Dimension)(color.toHSL().l * 100, '%'); - }, - hsvhue: function (color) { - return new (tree.Dimension)(color.toHSV().h); - }, - hsvsaturation: function (color) { - return new (tree.Dimension)(color.toHSV().s * 100, '%'); - }, - hsvvalue: function (color) { - return new (tree.Dimension)(color.toHSV().v * 100, '%'); - }, - red: function (color) { - return new (tree.Dimension)(color.rgb[0]); - }, - green: function (color) { - return new (tree.Dimension)(color.rgb[1]); - }, - blue: function (color) { - return new (tree.Dimension)(color.rgb[2]); - }, - alpha: function (color) { - return new (tree.Dimension)(color.toHSL().a); - }, - luma: function (color) { - return new (tree.Dimension)(color.luma() * color.alpha * 100, '%'); - }, - luminance: function (color) { - var luminance = - (0.2126 * color.rgb[0] / 255) - + (0.7152 * color.rgb[1] / 255) - + (0.0722 * color.rgb[2] / 255); - - return new (tree.Dimension)(luminance * color.alpha * 100, '%'); - }, - saturate: function (color, amount) { - // filter: saturate(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - var hsl = color.toHSL(); - - hsl.s += amount.value / 100; - hsl.s = clamp(hsl.s); - return hsla(hsl); - }, - desaturate: function (color, amount) { - var hsl = color.toHSL(); - - hsl.s -= amount.value / 100; - hsl.s = clamp(hsl.s); - return hsla(hsl); - }, - lighten: function (color, amount) { - var hsl = color.toHSL(); - - hsl.l += amount.value / 100; - hsl.l = clamp(hsl.l); - return hsla(hsl); - }, - darken: function (color, amount) { - var hsl = color.toHSL(); - - hsl.l -= amount.value / 100; - hsl.l = clamp(hsl.l); - return hsla(hsl); - }, - fadein: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a += amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - fadeout: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a -= amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - fade: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a = amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - spin: function (color, amount) { - var hsl = color.toHSL(); - var hue = (hsl.h + amount.value) % 360; - - hsl.h = hue < 0 ? 360 + hue : hue; - - return hsla(hsl); - }, - // - // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein - // http://sass-lang.com - // - mix: function (color1, color2, weight) { - if (!weight) { - weight = new (tree.Dimension)(50); - } - var p = weight.value / 100.0; - var w = p * 2 - 1; - var a = color1.toHSL().a - color2.toHSL().a; - - var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; - var w2 = 1 - w1; - - var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, - color1.rgb[1] * w1 + color2.rgb[1] * w2, - color1.rgb[2] * w1 + color2.rgb[2] * w2]; - - var alpha = color1.alpha * p + color2.alpha * (1 - p); - - return new (tree.Color)(rgb, alpha); - }, - greyscale: function (color) { - return this.desaturate(color, new (tree.Dimension)(100)); - }, - contrast: function (color, dark, light, threshold) { - // filter: contrast(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - if (typeof light === 'undefined') { - light = this.rgba(255, 255, 255, 1.0); - } - if (typeof dark === 'undefined') { - dark = this.rgba(0, 0, 0, 1.0); - } - //Figure out which is actually light and dark! - if (dark.luma() > light.luma()) { - var t = light; - light = dark; - dark = t; - } - if (typeof threshold === 'undefined') { - threshold = 0.43; - } else { - threshold = number(threshold); - } - if (color.luma() < threshold) { - return light; - } else { - return dark; - } - }, - e: function (str) { - return new (tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str.value); - }, - escape: function (str) { - return new (tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29")); - }, - replace: function (string, pattern, replacement, flags) { - var result = string.value; - - result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement.value); - return new (tree.Quoted)(string.quote || '', result, string.escaped); - }, - '%': function (string /* arg, arg, ...*/) { - var args = Array.prototype.slice.call(arguments, 1), - result = string.value; - - for (var i = 0; i < args.length; i++) { - /*jshint loopfunc:true */ - result = result.replace(/%[sda]/i, function (token) { - var value = token.match(/s/i) ? args[i].value : args[i].toCSS(); - return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; - }); - } - result = result.replace(/%%/g, '%'); - return new (tree.Quoted)(string.quote || '', result, string.escaped); - }, - unit: function (val, unit) { - if (!(val instanceof tree.Dimension)) { - throw { - type: "Argument", - message: "the first argument to unit must be a number" + (val instanceof tree.Operation ? ". Have you forgotten parenthesis?" : "") - }; - } - if (unit) { - if (unit instanceof tree.Keyword) { - unit = unit.value; - } else { - unit = unit.toCSS(); - } - } else { - unit = ""; - } - return new (tree.Dimension)(val.value, unit); - }, - convert: function (val, unit) { - return val.convertTo(unit.value); - }, - round: function (n, f) { - var fraction = typeof(f) === "undefined" ? 0 : f.value; - return _math(function (num) { - return num.toFixed(fraction); - }, null, n); - }, - pi: function () { - return new (tree.Dimension)(Math.PI); - }, - mod: function (a, b) { - return new (tree.Dimension)(a.value % b.value, a.unit); - }, - pow: function (x, y) { - if (typeof x === "number" && typeof y === "number") { - x = new (tree.Dimension)(x); - y = new (tree.Dimension)(y); - } else if (!(x instanceof tree.Dimension) || !(y instanceof tree.Dimension)) { - throw {type: "Argument", message: "arguments must be numbers"}; - } - - return new (tree.Dimension)(Math.pow(x.value, y.value), x.unit); - }, - _minmax: function (isMin, args) { - args = Array.prototype.slice.call(args); - switch (args.length) { - case 0: - throw {type: "Argument", message: "one or more arguments required"}; - } - var i, j, current, currentUnified, referenceUnified, unit, unitStatic, unitClone, - order = [], // elems only contains original argument values. - values = {}; // key is the unit.toString() for unified tree.Dimension values, - // value is the index into the order array. - for (i = 0; i < args.length; i++) { - current = args[i]; - if (!(current instanceof tree.Dimension)) { - if (Array.isArray(args[i].value)) { - Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value)); - } - continue; - } - currentUnified = current.unit.toString() === "" && unitClone !== undefined ? new (tree.Dimension)(current.value, unitClone).unify() : current.unify(); - unit = currentUnified.unit.toString() === "" && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString(); - unitStatic = unit !== "" && unitStatic === undefined || unit !== "" && order[0].unify().unit.toString() === "" ? unit : unitStatic; - unitClone = unit !== "" && unitClone === undefined ? current.unit.toString() : unitClone; - j = values[""] !== undefined && unit !== "" && unit === unitStatic ? values[""] : values[unit]; - if (j === undefined) { - if (unitStatic !== undefined && unit !== unitStatic) { - throw{type: "Argument", message: "incompatible types"}; - } - values[unit] = order.length; - order.push(current); - continue; - } - referenceUnified = order[j].unit.toString() === "" && unitClone !== undefined ? new (tree.Dimension)(order[j].value, unitClone).unify() : order[j].unify(); - if (isMin && currentUnified.value < referenceUnified.value || - !isMin && currentUnified.value > referenceUnified.value) { - order[j] = current; - } - } - if (order.length == 1) { - return order[0]; - } - args = order.map(function (a) { - return a.toCSS(this.env); - }).join(this.env.compress ? "," : ", "); - return new (tree.Anonymous)((isMin ? "min" : "max") + "(" + args + ")"); - }, - min: function () { - return this._minmax(true, arguments); - }, - max: function () { - return this._minmax(false, arguments); - }, - "get-unit": function (n) { - return new (tree.Anonymous)(n.unit); - }, - argb: function (color) { - return new (tree.Anonymous)(color.toARGB()); - }, - percentage: function (n) { - return new (tree.Dimension)(n.value * 100, '%'); - }, - color: function (n) { - if (n instanceof tree.Quoted) { - var colorCandidate = n.value, - returnColor; - returnColor = tree.Color.fromKeyword(colorCandidate); - if (returnColor) { - return returnColor; - } - if (/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/.test(colorCandidate)) { - return new (tree.Color)(colorCandidate.slice(1)); - } - throw {type: "Argument", message: "argument must be a color keyword or 3/6 digit hex e.g. #FFF"}; - } else { - throw {type: "Argument", message: "argument must be a string"}; - } - }, - iscolor: function (n) { - return this._isa(n, tree.Color); - }, - isnumber: function (n) { - return this._isa(n, tree.Dimension); - }, - isstring: function (n) { - return this._isa(n, tree.Quoted); - }, - iskeyword: function (n) { - return this._isa(n, tree.Keyword); - }, - isurl: function (n) { - return this._isa(n, tree.URL); - }, - ispixel: function (n) { - return this.isunit(n, 'px'); - }, - ispercentage: function (n) { - return this.isunit(n, '%'); - }, - isem: function (n) { - return this.isunit(n, 'em'); - }, - isunit: function (n, unit) { - return (n instanceof tree.Dimension) && n.unit.is(unit.value || unit) ? tree.True : tree.False; - }, - _isa: function (n, Type) { - return (n instanceof Type) ? tree.True : tree.False; - }, - tint: function (color, amount) { - return this.mix(this.rgb(255, 255, 255), color, amount); - }, - shade: function (color, amount) { - return this.mix(this.rgb(0, 0, 0), color, amount); - }, - extract: function (values, index) { - index = index.value - 1; // (1-based index) - // handle non-array values as an array of length 1 - // return 'undefined' if index is invalid - return Array.isArray(values.value) - ? values.value[index] : Array(values)[index]; - }, - length: function (values) { - var n = Array.isArray(values.value) ? values.value.length : 1; - return new tree.Dimension(n); - }, - - "data-uri": function (mimetypeNode, filePathNode) { - - if (typeof window !== 'undefined') { - return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); - } - - var mimetype = mimetypeNode.value; - var filePath = (filePathNode && filePathNode.value); - - var fs = require('./fs'), - path = require('path'), - useBase64 = false; - - if (arguments.length < 2) { - filePath = mimetype; - } - - var fragmentStart = filePath.indexOf('#'); - var fragment = ''; - if (fragmentStart !== -1) { - fragment = filePath.slice(fragmentStart); - filePath = filePath.slice(0, fragmentStart); - } - - if (this.env.isPathRelative(filePath)) { - if (this.currentFileInfo.relativeUrls) { - filePath = path.join(this.currentFileInfo.currentDirectory, filePath); - } else { - filePath = path.join(this.currentFileInfo.entryPath, filePath); - } - } - - // detect the mimetype if not given - if (arguments.length < 2) { - var mime; - try { - mime = require('mime'); - } catch (ex) { - mime = tree._mime; - } - - mimetype = mime.lookup(filePath); - - // use base 64 unless it's an ASCII or UTF-8 format - var charset = mime.charsets.lookup(mimetype); - useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; - if (useBase64) { - mimetype += ';base64'; - } - } - else { - useBase64 = /;base64$/.test(mimetype); - } - - var buf = fs.readFileSync(filePath); - - // IE8 cannot handle a data-uri larger than 32KB. If this is exceeded - // and the --ieCompat flag is enabled, return a normal url() instead. - var DATA_URI_MAX_KB = 32, - fileSizeInKB = parseInt((buf.length / 1024), 10); - if (fileSizeInKB >= DATA_URI_MAX_KB) { - - if (this.env.ieCompat !== false) { - if (!this.env.silent) { - console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!", filePath, fileSizeInKB, DATA_URI_MAX_KB); - } - - return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); - } - } - - buf = useBase64 ? buf.toString('base64') - : encodeURIComponent(buf); - - var uri = "\"data:" + mimetype + ',' + buf + fragment + "\""; - return new (tree.URL)(new (tree.Anonymous)(uri)); - }, - - "svg-gradient": function (direction) { - - function throwArgumentDescriptor() { - throw { - type: "Argument", - message: "svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]" - }; - } - - if (arguments.length < 3) { - throwArgumentDescriptor(); - } - var stops = Array.prototype.slice.call(arguments, 1), - gradientDirectionSvg, - gradientType = "linear", - rectangleDimension = 'x="0" y="0" width="1" height="1"', - useBase64 = true, - renderEnv = {compress: false}, - returner, - directionValue = direction.toCSS(renderEnv), - i, color, position, positionValue, alpha; - - switch (directionValue) { - case "to bottom": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; - break; - case "to right": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; - break; - case "to bottom right": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; - break; - case "to top right": - gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; - break; - case "ellipse": - case "ellipse at center": - gradientType = "radial"; - gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; - rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; - break; - default: - throw { - type: "Argument", - message: "svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'" - }; - } - returner = '' + - '' + - '<' + gradientType + 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' + gradientDirectionSvg + '>'; - - for (i = 0; i < stops.length; i += 1) { - if (stops[i].value) { - color = stops[i].value[0]; - position = stops[i].value[1]; - } else { - color = stops[i]; - position = undefined; - } - - if (!(color instanceof tree.Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof tree.Dimension))) { - throwArgumentDescriptor(); - } - positionValue = position ? position.toCSS(renderEnv) : i === 0 ? "0%" : "100%"; - alpha = color.alpha; - returner += ''; - } - returner += '' + - ''; - - if (useBase64) { - try { - returner = require('./encoder').encodeBase64(returner); // TODO browser implementation - } catch (e) { - useBase64 = false; - } - } - - returner = "'data:image/svg+xml" + (useBase64 ? ";base64" : "") + "," + returner + "'"; - return new (tree.URL)(new (tree.Anonymous)(returner)); - } - }; - -// these static methods are used as a fallback when the optional 'mime' dependency is missing - tree._mime = { - // this map is intentionally incomplete - // if you want more, install 'mime' dep - _types: { - '.htm': 'text/html', - '.html': 'text/html', - '.gif': 'image/gif', - '.jpg': 'image/jpeg', - '.jpeg': 'image/jpeg', - '.png': 'image/png' - }, - lookup: function (filepath) { - var ext = require('path').extname(filepath), - type = tree._mime._types[ext]; - if (type === undefined) { - throw new Error('Optional dependency "mime" is required for ' + ext); - } - return type; - }, - charsets: { - lookup: function (type) { - // assumes all text types are UTF-8 - return type && (/^text\//).test(type) ? 'UTF-8' : ''; - } - } - }; - -// Math - - var mathFunctions = { - // name, unit - ceil: null, - floor: null, - sqrt: null, - abs: null, - tan: "", - sin: "", - cos: "", - atan: "rad", - asin: "rad", - acos: "rad" - }; - - function _math(fn, unit, n) { - if (!(n instanceof tree.Dimension)) { - throw {type: "Argument", message: "argument must be a number"}; - } - if (unit == null) { - unit = n.unit; - } else { - n = n.unify(); - } - return new (tree.Dimension)(fn(parseFloat(n.value)), unit); - } - -// ~ End of Math - -// Color Blending -// ref: http://www.w3.org/TR/compositing-1 - - function colorBlend(mode, color1, color2) { - var ab = color1.alpha, cb, // backdrop - as = color2.alpha, cs, // source - ar, cr, r = []; // result - - ar = as + ab * (1 - as); - for (var i = 0; i < 3; i++) { - cb = color1.rgb[i] / 255; - cs = color2.rgb[i] / 255; - cr = mode(cb, cs); - if (ar) { - cr = (as * cs + ab * (cb - - as * (cb + cs - cr))) / ar; - } - r[i] = cr * 255; - } - - return new (tree.Color)(r, ar); - } - - var colorBlendMode = { - multiply: function (cb, cs) { - return cb * cs; - }, - screen: function (cb, cs) { - return cb + cs - cb * cs; - }, - overlay: function (cb, cs) { - cb *= 2; - return (cb <= 1) - ? colorBlendMode.multiply(cb, cs) - : colorBlendMode.screen(cb - 1, cs); - }, - softlight: function (cb, cs) { - var d = 1, e = cb; - if (cs > 0.5) { - e = 1; - d = (cb > 0.25) ? Math.sqrt(cb) - : ((16 * cb - 12) * cb + 4) * cb; - } - return cb - (1 - 2 * cs) * e * (d - cb); - }, - hardlight: function (cb, cs) { - return colorBlendMode.overlay(cs, cb); - }, - difference: function (cb, cs) { - return Math.abs(cb - cs); - }, - exclusion: function (cb, cs) { - return cb + cs - 2 * cb * cs; - }, - - // non-w3c functions: - average: function (cb, cs) { - return (cb + cs) / 2; - }, - negation: function (cb, cs) { - return 1 - Math.abs(cb + cs - 1); - } - }; - -// ~ End of Color Blending - - tree.defaultFunc = { - eval: function () { - var v = this.value_, e = this.error_; - if (e) { - throw e; - } - if (v != null) { - return v ? tree.True : tree.False; - } - }, - value: function (v) { - this.value_ = v; - }, - error: function (e) { - this.error_ = e; - }, - reset: function () { - this.value_ = this.error_ = null; - } - }; - - function initFunctions() { - var f, tf = tree.functions; - - // math - for (f in mathFunctions) { - if (mathFunctions.hasOwnProperty(f)) { - tf[f] = _math.bind(null, Math[f], mathFunctions[f]); - } - } - - // color blending - for (f in colorBlendMode) { - if (colorBlendMode.hasOwnProperty(f)) { - tf[f] = colorBlend.bind(null, colorBlendMode[f]); - } - } - - // default - f = tree.defaultFunc; - tf["default"] = f.eval.bind(f); - - } - - initFunctions(); - - function hsla(color) { - return tree.functions.hsla(color.h, color.s, color.l, color.a); - } - - function scaled(n, size) { - if (n instanceof tree.Dimension && n.unit.is('%')) { - return parseFloat(n.value * size / 100); - } else { - return number(n); - } - } - - function number(n) { - if (n instanceof tree.Dimension) { - return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); - } else if (typeof(n) === 'number') { - return n; - } else { - throw { - error: "RuntimeError", - message: "color functions take numbers as parameters" - }; - } - } - - function clamp(val) { - return Math.min(1, Math.max(0, val)); - } - - tree.fround = function (env, value) { - var p = env && env.numPrecision; - //add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999....) are properly rounded... - return (p == null) ? value : Number((value + 2e-16).toFixed(p)); - }; - - tree.functionCall = function (env, currentFileInfo) { - this.env = env; - this.currentFileInfo = currentFileInfo; - }; - - tree.functionCall.prototype = tree.functions; - -})(require('./tree')); - -(function (tree) { - tree.colors = { - 'aliceblue': '#f0f8ff', - 'antiquewhite': '#faebd7', - 'aqua': '#00ffff', - 'aquamarine': '#7fffd4', - 'azure': '#f0ffff', - 'beige': '#f5f5dc', - 'bisque': '#ffe4c4', - 'black': '#000000', - 'blanchedalmond': '#ffebcd', - 'blue': '#0000ff', - 'blueviolet': '#8a2be2', - 'brown': '#a52a2a', - 'burlywood': '#deb887', - 'cadetblue': '#5f9ea0', - 'chartreuse': '#7fff00', - 'chocolate': '#d2691e', - 'coral': '#ff7f50', - 'cornflowerblue': '#6495ed', - 'cornsilk': '#fff8dc', - 'crimson': '#dc143c', - 'cyan': '#00ffff', - 'darkblue': '#00008b', - 'darkcyan': '#008b8b', - 'darkgoldenrod': '#b8860b', - 'darkgray': '#a9a9a9', - 'darkgrey': '#a9a9a9', - 'darkgreen': '#006400', - 'darkkhaki': '#bdb76b', - 'darkmagenta': '#8b008b', - 'darkolivegreen': '#556b2f', - 'darkorange': '#ff8c00', - 'darkorchid': '#9932cc', - 'darkred': '#8b0000', - 'darksalmon': '#e9967a', - 'darkseagreen': '#8fbc8f', - 'darkslateblue': '#483d8b', - 'darkslategray': '#2f4f4f', - 'darkslategrey': '#2f4f4f', - 'darkturquoise': '#00ced1', - 'darkviolet': '#9400d3', - 'deeppink': '#ff1493', - 'deepskyblue': '#00bfff', - 'dimgray': '#696969', - 'dimgrey': '#696969', - 'dodgerblue': '#1e90ff', - 'firebrick': '#b22222', - 'floralwhite': '#fffaf0', - 'forestgreen': '#228b22', - 'fuchsia': '#ff00ff', - 'gainsboro': '#dcdcdc', - 'ghostwhite': '#f8f8ff', - 'gold': '#ffd700', - 'goldenrod': '#daa520', - 'gray': '#808080', - 'grey': '#808080', - 'green': '#008000', - 'greenyellow': '#adff2f', - 'honeydew': '#f0fff0', - 'hotpink': '#ff69b4', - 'indianred': '#cd5c5c', - 'indigo': '#4b0082', - 'ivory': '#fffff0', - 'khaki': '#f0e68c', - 'lavender': '#e6e6fa', - 'lavenderblush': '#fff0f5', - 'lawngreen': '#7cfc00', - 'lemonchiffon': '#fffacd', - 'lightblue': '#add8e6', - 'lightcoral': '#f08080', - 'lightcyan': '#e0ffff', - 'lightgoldenrodyellow': '#fafad2', - 'lightgray': '#d3d3d3', - 'lightgrey': '#d3d3d3', - 'lightgreen': '#90ee90', - 'lightpink': '#ffb6c1', - 'lightsalmon': '#ffa07a', - 'lightseagreen': '#20b2aa', - 'lightskyblue': '#87cefa', - 'lightslategray': '#778899', - 'lightslategrey': '#778899', - 'lightsteelblue': '#b0c4de', - 'lightyellow': '#ffffe0', - 'lime': '#00ff00', - 'limegreen': '#32cd32', - 'linen': '#faf0e6', - 'magenta': '#ff00ff', - 'maroon': '#800000', - 'mediumaquamarine': '#66cdaa', - 'mediumblue': '#0000cd', - 'mediumorchid': '#ba55d3', - 'mediumpurple': '#9370d8', - 'mediumseagreen': '#3cb371', - 'mediumslateblue': '#7b68ee', - 'mediumspringgreen': '#00fa9a', - 'mediumturquoise': '#48d1cc', - 'mediumvioletred': '#c71585', - 'midnightblue': '#191970', - 'mintcream': '#f5fffa', - 'mistyrose': '#ffe4e1', - 'moccasin': '#ffe4b5', - 'navajowhite': '#ffdead', - 'navy': '#000080', - 'oldlace': '#fdf5e6', - 'olive': '#808000', - 'olivedrab': '#6b8e23', - 'orange': '#ffa500', - 'orangered': '#ff4500', - 'orchid': '#da70d6', - 'palegoldenrod': '#eee8aa', - 'palegreen': '#98fb98', - 'paleturquoise': '#afeeee', - 'palevioletred': '#d87093', - 'papayawhip': '#ffefd5', - 'peachpuff': '#ffdab9', - 'peru': '#cd853f', - 'pink': '#ffc0cb', - 'plum': '#dda0dd', - 'powderblue': '#b0e0e6', - 'purple': '#800080', - 'red': '#ff0000', - 'rosybrown': '#bc8f8f', - 'royalblue': '#4169e1', - 'saddlebrown': '#8b4513', - 'salmon': '#fa8072', - 'sandybrown': '#f4a460', - 'seagreen': '#2e8b57', - 'seashell': '#fff5ee', - 'sienna': '#a0522d', - 'silver': '#c0c0c0', - 'skyblue': '#87ceeb', - 'slateblue': '#6a5acd', - 'slategray': '#708090', - 'slategrey': '#708090', - 'snow': '#fffafa', - 'springgreen': '#00ff7f', - 'steelblue': '#4682b4', - 'tan': '#d2b48c', - 'teal': '#008080', - 'thistle': '#d8bfd8', - 'tomato': '#ff6347', - 'turquoise': '#40e0d0', - 'violet': '#ee82ee', - 'wheat': '#f5deb3', - 'white': '#ffffff', - 'whitesmoke': '#f5f5f5', - 'yellow': '#ffff00', - 'yellowgreen': '#9acd32' - }; -})(require('./tree')); - -(function (tree) { - - tree.debugInfo = function (env, ctx, lineSeperator) { - var result = ""; - if (env.dumpLineNumbers && !env.compress) { - switch (env.dumpLineNumbers) { - case 'comments': - result = tree.debugInfo.asComment(ctx); - break; - case 'mediaquery': - result = tree.debugInfo.asMediaQuery(ctx); - break; - case 'all': - result = tree.debugInfo.asComment(ctx) + (lineSeperator || "") + tree.debugInfo.asMediaQuery(ctx); - break; - } - } - return result; - }; - - tree.debugInfo.asComment = function (ctx) { - return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n'; - }; - - tree.debugInfo.asMediaQuery = function (ctx) { - return '@media -sass-debug-info{filename{font-family:' + - ('file://' + ctx.debugInfo.fileName).replace(/([.:\/\\])/g, function (a) { - if (a == '\\') { - a = '\/'; - } - return '\\' + a; - }) + - '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n'; - }; - - tree.find = function (obj, fun) { - for (var i = 0, r; i < obj.length; i++) { - r = fun.call(obj, obj[i]); - if (r) { - return r; - } - } - return null; - }; - - tree.jsify = function (obj) { - if (Array.isArray(obj.value) && (obj.value.length > 1)) { - return '[' + obj.value.map(function (v) { - return v.toCSS(); - }).join(', ') + ']'; - } else { - return obj.toCSS(); - } - }; - - tree.toCSS = function (env) { - var strs = []; - this.genCSS(env, { - add: function (chunk, fileInfo, index) { - strs.push(chunk); - }, - isEmpty: function () { - return strs.length === 0; - } - }); - return strs.join(''); - }; - - tree.outputRuleset = function (env, output, rules) { - var ruleCnt = rules.length, i; - env.tabLevel = (env.tabLevel | 0) + 1; - - // Compressed - if (env.compress) { - output.add('{'); - for (i = 0; i < ruleCnt; i++) { - rules[i].genCSS(env, output); - } - output.add('}'); - env.tabLevel--; - return; - } - - // Non-compressed - var tabSetStr = '\n' + Array(env.tabLevel).join(" "), tabRuleStr = tabSetStr + " "; - if (!ruleCnt) { - output.add(" {" + tabSetStr + '}'); - } else { - output.add(" {" + tabRuleStr); - rules[0].genCSS(env, output); - for (i = 1; i < ruleCnt; i++) { - output.add(tabRuleStr); - rules[i].genCSS(env, output); - } - output.add(tabSetStr + '}'); - } - - env.tabLevel--; - }; - -})(require('./tree')); - -(function (tree) { - - tree.Alpha = function (val) { - this.value = val; - }; - tree.Alpha.prototype = { - type: "Alpha", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - if (this.value.eval) { - return new tree.Alpha(this.value.eval(env)); - } - return this; - }, - genCSS: function (env, output) { - output.add("alpha(opacity="); - - if (this.value.genCSS) { - this.value.genCSS(env, output); - } else { - output.add(this.value); - } - - output.add(")"); - }, - toCSS: tree.toCSS - }; - -})(require('../tree')); - -(function (tree) { - - tree.Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike) { - this.value = value; - this.index = index; - this.mapLines = mapLines; - this.currentFileInfo = currentFileInfo; - this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike; - }; - tree.Anonymous.prototype = { - type: "Anonymous", - eval: function () { - return new tree.Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines, this.rulesetLike); - }, - compare: function (x) { - if (!x.toCSS) { - return -1; - } - - var left = this.toCSS(), - right = x.toCSS(); - - if (left === right) { - return 0; - } - - return left < right ? -1 : 1; - }, - isRulesetLike: function () { - return this.rulesetLike; - }, - genCSS: function (env, output) { - output.add(this.value, this.currentFileInfo, this.index, this.mapLines); - }, - toCSS: tree.toCSS - }; - -})(require('../tree')); - -(function (tree) { - - tree.Assignment = function (key, val) { - this.key = key; - this.value = val; - }; - tree.Assignment.prototype = { - type: "Assignment", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - if (this.value.eval) { - return new (tree.Assignment)(this.key, this.value.eval(env)); - } - return this; - }, - genCSS: function (env, output) { - output.add(this.key + '='); - if (this.value.genCSS) { - this.value.genCSS(env, output); - } else { - output.add(this.value); - } - }, - toCSS: tree.toCSS - }; - -})(require('../tree')); - -(function (tree) { - -// -// A function call node. -// - tree.Call = function (name, args, index, currentFileInfo) { - this.name = name; - this.args = args; - this.index = index; - this.currentFileInfo = currentFileInfo; - }; - tree.Call.prototype = { - type: "Call", - accept: function (visitor) { - if (this.args) { - this.args = visitor.visitArray(this.args); - } - }, - // - // When evaluating a function call, - // we either find the function in `tree.functions` [1], - // in which case we call it, passing the evaluated arguments, - // if this returns null or we cannot find the function, we - // simply print it out as it appeared originally [2]. - // - // The *functions.js* file contains the built-in functions. - // - // The reason why we evaluate the arguments, is in the case where - // we try to pass a variable to a function, like: `saturate(@color)`. - // The function should receive the value, not the variable. - // - eval: function (env) { - var args = this.args.map(function (a) { - return a.eval(env); - }), - nameLC = this.name.toLowerCase(), - result, func; - - if (nameLC in tree.functions) { // 1. - try { - func = new tree.functionCall(env, this.currentFileInfo); - result = func[nameLC].apply(func, args); - if (result != null) { - return result; - } - } catch (e) { - throw { - type: e.type || "Runtime", - message: "error evaluating function `" + this.name + "`" + - (e.message ? ': ' + e.message : ''), - index: this.index, filename: this.currentFileInfo.filename - }; - } - } - - return new tree.Call(this.name, args, this.index, this.currentFileInfo); - }, - - genCSS: function (env, output) { - output.add(this.name + "(", this.currentFileInfo, this.index); - - for (var i = 0; i < this.args.length; i++) { - this.args[i].genCSS(env, output); - if (i + 1 < this.args.length) { - output.add(", "); - } - } - - output.add(")"); - }, - - toCSS: tree.toCSS - }; - -})(require('../tree')); - -(function (tree) { -// -// RGB Colors - #ff0014, #eee -// - tree.Color = function (rgb, a) { - // - // The end goal here, is to parse the arguments - // into an integer triplet, such as `128, 255, 0` - // - // This facilitates operations and conversions. - // - if (Array.isArray(rgb)) { - this.rgb = rgb; - } else if (rgb.length == 6) { - this.rgb = rgb.match(/.{2}/g).map(function (c) { - return parseInt(c, 16); - }); - } else { - this.rgb = rgb.split('').map(function (c) { - return parseInt(c + c, 16); - }); - } - this.alpha = typeof(a) === 'number' ? a : 1; - }; - - var transparentKeyword = "transparent"; - - tree.Color.prototype = { - type: "Color", - eval: function () { - return this; - }, - luma: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255; - - r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4); - g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4); - b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4); - - return 0.2126 * r + 0.7152 * g + 0.0722 * b; - }, - - genCSS: function (env, output) { - output.add(this.toCSS(env)); - }, - toCSS: function (env, doNotCompress) { - var compress = env && env.compress && !doNotCompress, - alpha = tree.fround(env, this.alpha); - - // If we have some transparency, the only way to represent it - // is via `rgba`. Otherwise, we use the hex representation, - // which has better compatibility with older browsers. - // Values are capped between `0` and `255`, rounded and zero-padded. - if (alpha < 1) { - if (alpha === 0 && this.isTransparentKeyword) { - return transparentKeyword; - } - return "rgba(" + this.rgb.map(function (c) { - return clamp(Math.round(c), 255); - }).concat(clamp(alpha, 1)) - .join(',' + (compress ? '' : ' ')) + ")"; - } else { - var color = this.toRGB(); - - if (compress) { - var splitcolor = color.split(''); - - // Convert color to short format - if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { - color = '#' + splitcolor[1] + splitcolor[3] + splitcolor[5]; - } - } - - return color; - } - }, - - // - // Operations have to be done per-channel, if not, - // channels will spill onto each other. Once we have - // our result, in the form of an integer triplet, - // we create a new Color node to hold the result. - // - operate: function (env, op, other) { - var rgb = []; - var alpha = this.alpha * (1 - other.alpha) + other.alpha; - for (var c = 0; c < 3; c++) { - rgb[c] = tree.operate(env, op, this.rgb[c], other.rgb[c]); - } - return new (tree.Color)(rgb, alpha); - }, - - toRGB: function () { - return toHex(this.rgb); - }, - - toHSL: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255, - a = this.alpha; - - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, l = (max + min) / 2, d = max - min; - - if (max === min) { - h = s = 0; - } else { - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - case g: - h = (b - r) / d + 2; - break; - case b: - h = (r - g) / d + 4; - break; - } - h /= 6; - } - return {h: h * 360, s: s, l: l, a: a}; - }, - //Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - toHSV: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255, - a = this.alpha; - - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, v = max; - - var d = max - min; - if (max === 0) { - s = 0; - } else { - s = d / max; - } - - if (max === min) { - h = 0; - } else { - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - case g: - h = (b - r) / d + 2; - break; - case b: - h = (r - g) / d + 4; - break; - } - h /= 6; - } - return {h: h * 360, s: s, v: v, a: a}; - }, - toARGB: function () { - return toHex([this.alpha * 255].concat(this.rgb)); - }, - compare: function (x) { - if (!x.rgb) { - return -1; - } - - return (x.rgb[0] === this.rgb[0] && - x.rgb[1] === this.rgb[1] && - x.rgb[2] === this.rgb[2] && - x.alpha === this.alpha) ? 0 : -1; - } - }; - - tree.Color.fromKeyword = function (keyword) { - keyword = keyword.toLowerCase(); - - if (tree.colors.hasOwnProperty(keyword)) { - // detect named color - return new (tree.Color)(tree.colors[keyword].slice(1)); - } - if (keyword === transparentKeyword) { - var transparent = new (tree.Color)([0, 0, 0], 0); - transparent.isTransparentKeyword = true; - return transparent; - } - }; - - function toHex(v) { - return '#' + v.map(function (c) { - c = clamp(Math.round(c), 255); - return (c < 16 ? '0' : '') + c.toString(16); - }).join(''); - } - - function clamp(v, max) { - return Math.min(Math.max(v, 0), max); - } - -})(require('../tree')); - -(function (tree) { - - tree.Comment = function (value, silent, index, currentFileInfo) { - this.value = value; - this.silent = !!silent; - this.currentFileInfo = currentFileInfo; - }; - tree.Comment.prototype = { - type: "Comment", - genCSS: function (env, output) { - if (this.debugInfo) { - output.add(tree.debugInfo(env, this), this.currentFileInfo, this.index); - } - output.add(this.value.trim()); //TODO shouldn't need to trim, we shouldn't grab the \n - }, - toCSS: tree.toCSS, - isSilent: function (env) { - var isReference = (this.currentFileInfo && this.currentFileInfo.reference && !this.isReferenced), - isCompressed = env.compress && !this.value.match(/^\/\*!/); - return this.silent || isReference || isCompressed; - }, - eval: function () { - return this; - }, - markReferenced: function () { - this.isReferenced = true; - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.Condition = function (op, l, r, i, negate) { - this.op = op.trim(); - this.lvalue = l; - this.rvalue = r; - this.index = i; - this.negate = negate; - }; - tree.Condition.prototype = { - type: "Condition", - accept: function (visitor) { - this.lvalue = visitor.visit(this.lvalue); - this.rvalue = visitor.visit(this.rvalue); - }, - eval: function (env) { - var a = this.lvalue.eval(env), - b = this.rvalue.eval(env); - - var i = this.index, result; - - result = (function (op) { - switch (op) { - case 'and': - return a && b; - case 'or': - return a || b; - default: - if (a.compare) { - result = a.compare(b); - } else if (b.compare) { - result = b.compare(a); - } else { - throw { - type: "Type", - message: "Unable to perform comparison", - index: i - }; - } - switch (result) { - case -1: - return op === '<' || op === '=<' || op === '<='; - case 0: - return op === '=' || op === '>=' || op === '=<' || op === '<='; - case 1: - return op === '>' || op === '>='; - } - } - })(this.op); - return this.negate ? !result : result; - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.DetachedRuleset = function (ruleset, frames) { - this.ruleset = ruleset; - this.frames = frames; - }; - tree.DetachedRuleset.prototype = { - type: "DetachedRuleset", - accept: function (visitor) { - this.ruleset = visitor.visit(this.ruleset); - }, - eval: function (env) { - var frames = this.frames || env.frames.slice(0); - return new tree.DetachedRuleset(this.ruleset, frames); - }, - callEval: function (env) { - return this.ruleset.eval(this.frames ? new (tree.evalEnv)(env, this.frames.concat(env.frames)) : env); - } - }; -})(require('../tree')); - -(function (tree) { - -// -// A number with a unit -// - tree.Dimension = function (value, unit) { - this.value = parseFloat(value); - this.unit = (unit && unit instanceof tree.Unit) ? unit : - new (tree.Unit)(unit ? [unit] : undefined); - }; - - tree.Dimension.prototype = { - type: "Dimension", - accept: function (visitor) { - this.unit = visitor.visit(this.unit); - }, - eval: function (env) { - return this; - }, - toColor: function () { - return new (tree.Color)([this.value, this.value, this.value]); - }, - genCSS: function (env, output) { - if ((env && env.strictUnits) && !this.unit.isSingular()) { - throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: " + this.unit.toString()); - } - - var value = tree.fround(env, this.value), - strValue = String(value); - - if (value !== 0 && value < 0.000001 && value > -0.000001) { - // would be output 1e-6 etc. - strValue = value.toFixed(20).replace(/0+$/, ""); - } - - if (env && env.compress) { - // Zero values doesn't need a unit - if (value === 0 && this.unit.isLength()) { - output.add(strValue); - return; - } - - // Float values doesn't need a leading zero - if (value > 0 && value < 1) { - strValue = (strValue).substr(1); - } - } - - output.add(strValue); - this.unit.genCSS(env, output); - }, - toCSS: tree.toCSS, - - // In an operation between two Dimensions, - // we default to the first Dimension's unit, - // so `1px + 2` will yield `3px`. - operate: function (env, op, other) { - /*jshint noempty:false */ - var value = tree.operate(env, op, this.value, other.value), - unit = this.unit.clone(); - - if (op === '+' || op === '-') { - if (unit.numerator.length === 0 && unit.denominator.length === 0) { - unit.numerator = other.unit.numerator.slice(0); - unit.denominator = other.unit.denominator.slice(0); - } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) { - // do nothing - } else { - other = other.convertTo(this.unit.usedUnits()); - - if (env.strictUnits && other.unit.toString() !== unit.toString()) { - throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '" + unit.toString() + - "' and '" + other.unit.toString() + "'."); - } - - value = tree.operate(env, op, this.value, other.value); - } - } else if (op === '*') { - unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); - unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); - unit.cancel(); - } else if (op === '/') { - unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); - unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); - unit.cancel(); - } - return new (tree.Dimension)(value, unit); - }, - - compare: function (other) { - if (other instanceof tree.Dimension) { - var a, b, - aValue, bValue; - - if (this.unit.isEmpty() || other.unit.isEmpty()) { - a = this; - b = other; - } else { - a = this.unify(); - b = other.unify(); - if (a.unit.compare(b.unit) !== 0) { - return -1; - } - } - aValue = a.value; - bValue = b.value; - - if (bValue > aValue) { - return -1; - } else if (bValue < aValue) { - return 1; - } else { - return 0; - } - } else { - return -1; - } - }, - - unify: function () { - return this.convertTo({length: 'px', duration: 's', angle: 'rad'}); - }, - - convertTo: function (conversions) { - var value = this.value, unit = this.unit.clone(), - i, groupName, group, targetUnit, derivedConversions = {}, applyUnit; - - if (typeof conversions === 'string') { - for (i in tree.UnitConversions) { - if (tree.UnitConversions[i].hasOwnProperty(conversions)) { - derivedConversions = {}; - derivedConversions[i] = conversions; - } - } - conversions = derivedConversions; - } - applyUnit = function (atomicUnit, denominator) { - /*jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit)) { - if (denominator) { - value = value / (group[atomicUnit] / group[targetUnit]); - } else { - value = value * (group[atomicUnit] / group[targetUnit]); - } - - return targetUnit; - } - - return atomicUnit; - }; - - for (groupName in conversions) { - if (conversions.hasOwnProperty(groupName)) { - targetUnit = conversions[groupName]; - group = tree.UnitConversions[groupName]; - - unit.map(applyUnit); - } - } - - unit.cancel(); - - return new (tree.Dimension)(value, unit); - } - }; - -// http://www.w3.org/TR/css3-values/#absolute-lengths - tree.UnitConversions = { - length: { - 'm': 1, - 'cm': 0.01, - 'mm': 0.001, - 'in': 0.0254, - 'px': 0.0254 / 96, - 'pt': 0.0254 / 72, - 'pc': 0.0254 / 72 * 12 - }, - duration: { - 's': 1, - 'ms': 0.001 - }, - angle: { - 'rad': 1 / (2 * Math.PI), - 'deg': 1 / 360, - 'grad': 1 / 400, - 'turn': 1 - } - }; - - tree.Unit = function (numerator, denominator, backupUnit) { - this.numerator = numerator ? numerator.slice(0).sort() : []; - this.denominator = denominator ? denominator.slice(0).sort() : []; - this.backupUnit = backupUnit; - }; - - tree.Unit.prototype = { - type: "Unit", - clone: function () { - return new tree.Unit(this.numerator.slice(0), this.denominator.slice(0), this.backupUnit); - }, - genCSS: function (env, output) { - if (this.numerator.length >= 1) { - output.add(this.numerator[0]); - } else if (this.denominator.length >= 1) { - output.add(this.denominator[0]); - } else if ((!env || !env.strictUnits) && this.backupUnit) { - output.add(this.backupUnit); - } - }, - toCSS: tree.toCSS, - - toString: function () { - var i, returnStr = this.numerator.join("*"); - for (i = 0; i < this.denominator.length; i++) { - returnStr += "/" + this.denominator[i]; - } - return returnStr; - }, - - compare: function (other) { - return this.is(other.toString()) ? 0 : -1; - }, - - is: function (unitString) { - return this.toString() === unitString; - }, - - isLength: function () { - return Boolean(this.toCSS().match(/px|em|%|in|cm|mm|pc|pt|ex/)); - }, - - isEmpty: function () { - return this.numerator.length === 0 && this.denominator.length === 0; - }, - - isSingular: function () { - return this.numerator.length <= 1 && this.denominator.length === 0; - }, - - map: function (callback) { - var i; - - for (i = 0; i < this.numerator.length; i++) { - this.numerator[i] = callback(this.numerator[i], false); - } - - for (i = 0; i < this.denominator.length; i++) { - this.denominator[i] = callback(this.denominator[i], true); - } - }, - - usedUnits: function () { - var group, result = {}, mapUnit; - - mapUnit = function (atomicUnit) { - /*jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { - result[groupName] = atomicUnit; - } - - return atomicUnit; - }; - - for (var groupName in tree.UnitConversions) { - if (tree.UnitConversions.hasOwnProperty(groupName)) { - group = tree.UnitConversions[groupName]; - - this.map(mapUnit); - } - } - - return result; - }, - - cancel: function () { - var counter = {}, atomicUnit, i, backup; - - for (i = 0; i < this.numerator.length; i++) { - atomicUnit = this.numerator[i]; - if (!backup) { - backup = atomicUnit; - } - counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; - } - - for (i = 0; i < this.denominator.length; i++) { - atomicUnit = this.denominator[i]; - if (!backup) { - backup = atomicUnit; - } - counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; - } - - this.numerator = []; - this.denominator = []; - - for (atomicUnit in counter) { - if (counter.hasOwnProperty(atomicUnit)) { - var count = counter[atomicUnit]; - - if (count > 0) { - for (i = 0; i < count; i++) { - this.numerator.push(atomicUnit); - } - } else if (count < 0) { - for (i = 0; i < -count; i++) { - this.denominator.push(atomicUnit); - } - } - } - } - - if (this.numerator.length === 0 && this.denominator.length === 0 && backup) { - this.backupUnit = backup; - } - - this.numerator.sort(); - this.denominator.sort(); - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.Directive = function (name, value, rules, index, currentFileInfo, debugInfo) { - this.name = name; - this.value = value; - if (rules) { - this.rules = rules; - this.rules.allowImports = true; - } - this.index = index; - this.currentFileInfo = currentFileInfo; - this.debugInfo = debugInfo; - }; - - tree.Directive.prototype = { - type: "Directive", - accept: function (visitor) { - var value = this.value, rules = this.rules; - if (rules) { - rules = visitor.visit(rules); - } - if (value) { - value = visitor.visit(value); - } - }, - isRulesetLike: function () { - return !this.isCharset(); - }, - isCharset: function () { - return "@charset" === this.name; - }, - genCSS: function (env, output) { - var value = this.value, rules = this.rules; - output.add(this.name, this.currentFileInfo, this.index); - if (value) { - output.add(' '); - value.genCSS(env, output); - } - if (rules) { - tree.outputRuleset(env, output, [rules]); - } else { - output.add(';'); - } - }, - toCSS: tree.toCSS, - eval: function (env) { - var value = this.value, rules = this.rules; - if (value) { - value = value.eval(env); - } - if (rules) { - rules = rules.eval(env); - rules.root = true; - } - return new (tree.Directive)(this.name, value, rules, - this.index, this.currentFileInfo, this.debugInfo); - }, - variable: function (name) { - if (this.rules) return tree.Ruleset.prototype.variable.call(this.rules, name); - }, - find: function () { - if (this.rules) return tree.Ruleset.prototype.find.apply(this.rules, arguments); - }, - rulesets: function () { - if (this.rules) return tree.Ruleset.prototype.rulesets.apply(this.rules); - }, - markReferenced: function () { - var i, rules; - this.isReferenced = true; - if (this.rules) { - rules = this.rules.rules; - for (i = 0; i < rules.length; i++) { - if (rules[i].markReferenced) { - rules[i].markReferenced(); - } - } - } - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.Element = function (combinator, value, index, currentFileInfo) { - this.combinator = combinator instanceof tree.Combinator ? - combinator : new (tree.Combinator)(combinator); - - if (typeof(value) === 'string') { - this.value = value.trim(); - } else if (value) { - this.value = value; - } else { - this.value = ""; - } - this.index = index; - this.currentFileInfo = currentFileInfo; - }; - tree.Element.prototype = { - type: "Element", - accept: function (visitor) { - var value = this.value; - this.combinator = visitor.visit(this.combinator); - if (typeof value === "object") { - this.value = visitor.visit(value); - } - }, - eval: function (env) { - return new (tree.Element)(this.combinator, - this.value.eval ? this.value.eval(env) : this.value, - this.index, - this.currentFileInfo); - }, - genCSS: function (env, output) { - output.add(this.toCSS(env), this.currentFileInfo, this.index); - }, - toCSS: function (env) { - var value = (this.value.toCSS ? this.value.toCSS(env) : this.value); - if (value === '' && this.combinator.value.charAt(0) === '&') { - return ''; - } else { - return this.combinator.toCSS(env || {}) + value; - } - } - }; - - tree.Attribute = function (key, op, value) { - this.key = key; - this.op = op; - this.value = value; - }; - tree.Attribute.prototype = { - type: "Attribute", - eval: function (env) { - return new (tree.Attribute)(this.key.eval ? this.key.eval(env) : this.key, - this.op, (this.value && this.value.eval) ? this.value.eval(env) : this.value); - }, - genCSS: function (env, output) { - output.add(this.toCSS(env)); - }, - toCSS: function (env) { - var value = this.key.toCSS ? this.key.toCSS(env) : this.key; - - if (this.op) { - value += this.op; - value += (this.value.toCSS ? this.value.toCSS(env) : this.value); - } - - return '[' + value + ']'; - } - }; - - tree.Combinator = function (value) { - if (value === ' ') { - this.value = ' '; - } else { - this.value = value ? value.trim() : ""; - } - }; - tree.Combinator.prototype = { - type: "Combinator", - _noSpaceCombinators: { - '': true, - ' ': true, - '|': true - }, - genCSS: function (env, output) { - var spaceOrEmpty = (env.compress || this._noSpaceCombinators[this.value]) ? '' : ' '; - output.add(spaceOrEmpty + this.value + spaceOrEmpty); - }, - toCSS: tree.toCSS - }; - -})(require('../tree')); - -(function (tree) { - - tree.Expression = function (value) { - this.value = value; - }; - tree.Expression.prototype = { - type: "Expression", - accept: function (visitor) { - if (this.value) { - this.value = visitor.visitArray(this.value); - } - }, - eval: function (env) { - var returnValue, - inParenthesis = this.parens && !this.parensInOp, - doubleParen = false; - if (inParenthesis) { - env.inParenthesis(); - } - if (this.value.length > 1) { - returnValue = new (tree.Expression)(this.value.map(function (e) { - return e.eval(env); - })); - } else if (this.value.length === 1) { - if (this.value[0].parens && !this.value[0].parensInOp) { - doubleParen = true; - } - returnValue = this.value[0].eval(env); - } else { - returnValue = this; - } - if (inParenthesis) { - env.outOfParenthesis(); - } - if (this.parens && this.parensInOp && !(env.isMathOn()) && !doubleParen) { - returnValue = new (tree.Paren)(returnValue); - } - return returnValue; - }, - genCSS: function (env, output) { - for (var i = 0; i < this.value.length; i++) { - this.value[i].genCSS(env, output); - if (i + 1 < this.value.length) { - output.add(" "); - } - } - }, - toCSS: tree.toCSS, - throwAwayComments: function () { - this.value = this.value.filter(function (v) { - return !(v instanceof tree.Comment); - }); - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.Extend = function Extend(selector, option, index) { - this.selector = selector; - this.option = option; - this.index = index; - this.object_id = tree.Extend.next_id++; - this.parent_ids = [this.object_id]; - - switch (option) { - case "all": - this.allowBefore = true; - this.allowAfter = true; - break; - default: - this.allowBefore = false; - this.allowAfter = false; - break; - } - }; - tree.Extend.next_id = 0; - - tree.Extend.prototype = { - type: "Extend", - accept: function (visitor) { - this.selector = visitor.visit(this.selector); - }, - eval: function (env) { - return new (tree.Extend)(this.selector.eval(env), this.option, this.index); - }, - clone: function (env) { - return new (tree.Extend)(this.selector, this.option, this.index); - }, - findSelfSelectors: function (selectors) { - var selfElements = [], - i, - selectorElements; - - for (i = 0; i < selectors.length; i++) { - selectorElements = selectors[i].elements; - // duplicate the logic in genCSS function inside the selector node. - // future TODO - move both logics into the selector joiner visitor - if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === "") { - selectorElements[0].combinator.value = ' '; - } - selfElements = selfElements.concat(selectors[i].elements); - } - - this.selfSelectors = [{elements: selfElements}]; - } - }; - -})(require('../tree')); - -(function (tree) { -// -// CSS @import node -// -// The general strategy here is that we don't want to wait -// for the parsing to be completed, before we start importing -// the file. That's because in the context of a browser, -// most of the time will be spent waiting for the server to respond. -// -// On creation, we push the import path to our import queue, though -// `import,push`, we also pass it a callback, which it'll call once -// the file has been fetched, and parsed. -// - tree.Import = function (path, features, options, index, currentFileInfo) { - this.options = options; - this.index = index; - this.path = path; - this.features = features; - this.currentFileInfo = currentFileInfo; - - if (this.options.less !== undefined || this.options.inline) { - this.css = !this.options.less || this.options.inline; - } else { - var pathValue = this.getPath(); - if (pathValue && /css([\?;].*)?$/.test(pathValue)) { - this.css = true; - } - } - }; - -// -// The actual import node doesn't return anything, when converted to CSS. -// The reason is that it's used at the evaluation stage, so that the rules -// it imports can be treated like any other rules. -// -// In `eval`, we make sure all Import nodes get evaluated, recursively, so -// we end up with a flat structure, which can easily be imported in the parent -// ruleset. -// - tree.Import.prototype = { - type: "Import", - accept: function (visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - this.path = visitor.visit(this.path); - if (!this.options.inline && this.root) { - this.root = visitor.visit(this.root); - } - }, - genCSS: function (env, output) { - if (this.css) { - output.add("@import ", this.currentFileInfo, this.index); - this.path.genCSS(env, output); - if (this.features) { - output.add(" "); - this.features.genCSS(env, output); - } - output.add(';'); - } - }, - toCSS: tree.toCSS, - getPath: function () { - if (this.path instanceof tree.Quoted) { - var path = this.path.value; - return (this.css !== undefined || /(\.[a-z]*$)|([\?;].*)$/.test(path)) ? path : path + '.less'; - } else if (this.path instanceof tree.URL) { - return this.path.value.value; - } - return null; - }, - evalForImport: function (env) { - return new (tree.Import)(this.path.eval(env), this.features, this.options, this.index, this.currentFileInfo); - }, - evalPath: function (env) { - var path = this.path.eval(env); - var rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; - - if (!(path instanceof tree.URL)) { - if (rootpath) { - var pathValue = path.value; - // Add the base path if the import is relative - if (pathValue && env.isPathRelative(pathValue)) { - path.value = rootpath + pathValue; - } - } - path.value = env.normalizePath(path.value); - } - - return path; - }, - eval: function (env) { - var ruleset, features = this.features && this.features.eval(env); - - if (this.skip) { - if (typeof this.skip === "function") { - this.skip = this.skip(); - } - if (this.skip) { - return []; - } - } - - if (this.options.inline) { - //todo needs to reference css file not import - var contents = new (tree.Anonymous)(this.root, 0, {filename: this.importedFilename}, true, true); - return this.features ? new (tree.Media)([contents], this.features.value) : [contents]; - } else if (this.css) { - var newImport = new (tree.Import)(this.evalPath(env), features, this.options, this.index); - if (!newImport.css && this.error) { - throw this.error; - } - return newImport; - } else { - ruleset = new (tree.Ruleset)(null, this.root.rules.slice(0)); - - ruleset.evalImports(env); - - return this.features ? new (tree.Media)(ruleset.rules, this.features.value) : ruleset.rules; - } - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.JavaScript = function (string, index, escaped) { - this.escaped = escaped; - this.expression = string; - this.index = index; - }; - tree.JavaScript.prototype = { - type: "JavaScript", - eval: function (env) { - var result, - that = this, - context = {}; - - var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) { - return tree.jsify(new (tree.Variable)('@' + name, that.index).eval(env)); - }); - - try { - expression = new (Function)('return (' + expression + ')'); - } catch (e) { - throw { - message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`", - index: this.index - }; - } - - var variables = env.frames[0].variables(); - for (var k in variables) { - if (variables.hasOwnProperty(k)) { - /*jshint loopfunc:true */ - context[k.slice(1)] = { - value: variables[k].value, - toJS: function () { - return this.value.eval(env).toCSS(); - } - }; - } - } - - try { - result = expression.call(context); - } catch (e) { - throw { - message: "JavaScript evaluation error: '" + e.name + ': ' + e.message.replace(/["]/g, "'") + "'", - index: this.index - }; - } - if (typeof(result) === 'number') { - return new (tree.Dimension)(result); - } else if (typeof(result) === 'string') { - return new (tree.Quoted)('"' + result + '"', result, this.escaped, this.index); - } else if (Array.isArray(result)) { - return new (tree.Anonymous)(result.join(', ')); - } else { - return new (tree.Anonymous)(result); - } - } - }; - -})(require('../tree')); - - -(function (tree) { - - tree.Keyword = function (value) { - this.value = value; - }; - tree.Keyword.prototype = { - type: "Keyword", - eval: function () { - return this; - }, - genCSS: function (env, output) { - if (this.value === '%') { - throw {type: "Syntax", message: "Invalid % without number"}; - } - output.add(this.value); - }, - toCSS: tree.toCSS, - compare: function (other) { - if (other instanceof tree.Keyword) { - return other.value === this.value ? 0 : 1; - } else { - return -1; - } - } - }; - - tree.True = new (tree.Keyword)('true'); - tree.False = new (tree.Keyword)('false'); - -})(require('../tree')); - -(function (tree) { - - tree.Media = function (value, features, index, currentFileInfo) { - this.index = index; - this.currentFileInfo = currentFileInfo; - - var selectors = this.emptySelectors(); - - this.features = new (tree.Value)(features); - this.rules = [new (tree.Ruleset)(selectors, value)]; - this.rules[0].allowImports = true; - }; - tree.Media.prototype = { - type: "Media", - accept: function (visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - if (this.rules) { - this.rules = visitor.visitArray(this.rules); - } - }, - genCSS: function (env, output) { - output.add('@media ', this.currentFileInfo, this.index); - this.features.genCSS(env, output); - tree.outputRuleset(env, output, this.rules); - }, - toCSS: tree.toCSS, - eval: function (env) { - if (!env.mediaBlocks) { - env.mediaBlocks = []; - env.mediaPath = []; - } - - var media = new (tree.Media)(null, [], this.index, this.currentFileInfo); - if (this.debugInfo) { - this.rules[0].debugInfo = this.debugInfo; - media.debugInfo = this.debugInfo; - } - var strictMathBypass = false; - if (!env.strictMath) { - strictMathBypass = true; - env.strictMath = true; - } - try { - media.features = this.features.eval(env); - } - finally { - if (strictMathBypass) { - env.strictMath = false; - } - } - - env.mediaPath.push(media); - env.mediaBlocks.push(media); - - env.frames.unshift(this.rules[0]); - media.rules = [this.rules[0].eval(env)]; - env.frames.shift(); - - env.mediaPath.pop(); - - return env.mediaPath.length === 0 ? media.evalTop(env) : - media.evalNested(env); - }, - variable: function (name) { - return tree.Ruleset.prototype.variable.call(this.rules[0], name); - }, - find: function () { - return tree.Ruleset.prototype.find.apply(this.rules[0], arguments); - }, - rulesets: function () { - return tree.Ruleset.prototype.rulesets.apply(this.rules[0]); - }, - emptySelectors: function () { - var el = new (tree.Element)('', '&', this.index, this.currentFileInfo), - sels = [new (tree.Selector)([el], null, null, this.index, this.currentFileInfo)]; - sels[0].mediaEmpty = true; - return sels; - }, - markReferenced: function () { - var i, rules = this.rules[0].rules; - this.rules[0].markReferenced(); - this.isReferenced = true; - for (i = 0; i < rules.length; i++) { - if (rules[i].markReferenced) { - rules[i].markReferenced(); - } - } - }, - - evalTop: function (env) { - var result = this; - - // Render all dependent Media blocks. - if (env.mediaBlocks.length > 1) { - var selectors = this.emptySelectors(); - result = new (tree.Ruleset)(selectors, env.mediaBlocks); - result.multiMedia = true; - } - - delete env.mediaBlocks; - delete env.mediaPath; - - return result; - }, - evalNested: function (env) { - var i, value, - path = env.mediaPath.concat([this]); - - // Extract the media-query conditions separated with `,` (OR). - for (i = 0; i < path.length; i++) { - value = path[i].features instanceof tree.Value ? - path[i].features.value : path[i].features; - path[i] = Array.isArray(value) ? value : [value]; - } - - // Trace all permutations to generate the resulting media-query. - // - // (a, b and c) with nested (d, e) -> - // a and d - // a and e - // b and c and d - // b and c and e - this.features = new (tree.Value)(this.permute(path).map(function (path) { - path = path.map(function (fragment) { - return fragment.toCSS ? fragment : new (tree.Anonymous)(fragment); - }); - - for (i = path.length - 1; i > 0; i--) { - path.splice(i, 0, new (tree.Anonymous)("and")); - } - - return new (tree.Expression)(path); - })); - - // Fake a tree-node that doesn't output anything. - return new (tree.Ruleset)([], []); - }, - permute: function (arr) { - if (arr.length === 0) { - return []; - } else if (arr.length === 1) { - return arr[0]; - } else { - var result = []; - var rest = this.permute(arr.slice(1)); - for (var i = 0; i < rest.length; i++) { - for (var j = 0; j < arr[0].length; j++) { - result.push([arr[0][j]].concat(rest[i])); - } - } - return result; - } - }, - bubbleSelectors: function (selectors) { - if (!selectors) - return; - this.rules = [new (tree.Ruleset)(selectors.slice(0), [this.rules[0]])]; - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.mixin = {}; - tree.mixin.Call = function (elements, args, index, currentFileInfo, important) { - this.selector = new (tree.Selector)(elements); - this.arguments = (args && args.length) ? args : null; - this.index = index; - this.currentFileInfo = currentFileInfo; - this.important = important; - }; - tree.mixin.Call.prototype = { - type: "MixinCall", - accept: function (visitor) { - if (this.selector) { - this.selector = visitor.visit(this.selector); - } - if (this.arguments) { - this.arguments = visitor.visitArray(this.arguments); - } - }, - eval: function (env) { - var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule, - candidates = [], candidate, conditionResult = [], defaultFunc = tree.defaultFunc, - defaultResult, defNone = 0, defTrue = 1, defFalse = 2, count, originalRuleset; - - args = this.arguments && this.arguments.map(function (a) { - return {name: a.name, value: a.value.eval(env)}; - }); - - for (i = 0; i < env.frames.length; i++) { - if ((mixins = env.frames[i].find(this.selector)).length > 0) { - isOneFound = true; - - // To make `default()` function independent of definition order we have two "subpasses" here. - // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), - // and build candidate list with corresponding flags. Then, when we know all possible matches, - // we make a final decision. - - for (m = 0; m < mixins.length; m++) { - mixin = mixins[m]; - isRecursive = false; - for (f = 0; f < env.frames.length; f++) { - if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) { - isRecursive = true; - break; - } - } - if (isRecursive) { - continue; - } - - if (mixin.matchArgs(args, env)) { - candidate = {mixin: mixin, group: defNone}; - - if (mixin.matchCondition) { - for (f = 0; f < 2; f++) { - defaultFunc.value(f); - conditionResult[f] = mixin.matchCondition(args, env); - } - if (conditionResult[0] || conditionResult[1]) { - if (conditionResult[0] != conditionResult[1]) { - candidate.group = conditionResult[1] ? - defTrue : defFalse; - } - - candidates.push(candidate); - } - } - else { - candidates.push(candidate); - } - - match = true; - } - } - - defaultFunc.reset(); - - count = [0, 0, 0]; - for (m = 0; m < candidates.length; m++) { - count[candidates[m].group]++; - } - - if (count[defNone] > 0) { - defaultResult = defFalse; - } else { - defaultResult = defTrue; - if ((count[defTrue] + count[defFalse]) > 1) { - throw { - type: 'Runtime', - message: 'Ambiguous use of `default()` found when matching for `' - + this.format(args) + '`', - index: this.index, filename: this.currentFileInfo.filename - }; - } - } - - for (m = 0; m < candidates.length; m++) { - candidate = candidates[m].group; - if ((candidate === defNone) || (candidate === defaultResult)) { - try { - mixin = candidates[m].mixin; - if (!(mixin instanceof tree.mixin.Definition)) { - originalRuleset = mixin.originalRuleset || mixin; - mixin = new tree.mixin.Definition("", [], mixin.rules, null, false); - mixin.originalRuleset = originalRuleset; - } - Array.prototype.push.apply( - rules, mixin.evalCall(env, args, this.important).rules); - } catch (e) { - throw { - message: e.message, - index: this.index, - filename: this.currentFileInfo.filename, - stack: e.stack - }; - } - } - } - - if (match) { - if (!this.currentFileInfo || !this.currentFileInfo.reference) { - for (i = 0; i < rules.length; i++) { - rule = rules[i]; - if (rule.markReferenced) { - rule.markReferenced(); - } - } - } - return rules; - } - } - } - if (isOneFound) { - throw { - type: 'Runtime', - message: 'No matching definition was found for `' + this.format(args) + '`', - index: this.index, filename: this.currentFileInfo.filename - }; - } else { - throw { - type: 'Name', - message: this.selector.toCSS().trim() + " is undefined", - index: this.index, filename: this.currentFileInfo.filename - }; - } - }, - format: function (args) { - return this.selector.toCSS().trim() + '(' + - (args ? args.map(function (a) { - var argValue = ""; - if (a.name) { - argValue += a.name + ":"; - } - if (a.value.toCSS) { - argValue += a.value.toCSS(); - } else { - argValue += "???"; - } - return argValue; - }).join(', ') : "") + ")"; - } - }; - - tree.mixin.Definition = function (name, params, rules, condition, variadic, frames) { - this.name = name; - this.selectors = [new (tree.Selector)([new (tree.Element)(null, name, this.index, this.currentFileInfo)])]; - this.params = params; - this.condition = condition; - this.variadic = variadic; - this.arity = params.length; - this.rules = rules; - this._lookups = {}; - this.required = params.reduce(function (count, p) { - if (!p.name || (p.name && !p.value)) { - return count + 1; - } - else { - return count; - } - }, 0); - this.parent = tree.Ruleset.prototype; - this.frames = frames; - }; - tree.mixin.Definition.prototype = { - type: "MixinDefinition", - accept: function (visitor) { - if (this.params && this.params.length) { - this.params = visitor.visitArray(this.params); - } - this.rules = visitor.visitArray(this.rules); - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - }, - variable: function (name) { - return this.parent.variable.call(this, name); - }, - variables: function () { - return this.parent.variables.call(this); - }, - find: function () { - return this.parent.find.apply(this, arguments); - }, - rulesets: function () { - return this.parent.rulesets.apply(this); - }, - - evalParams: function (env, mixinEnv, args, evaldArguments) { - /*jshint boss:true */ - var frame = new (tree.Ruleset)(null, null), - varargs, arg, - params = this.params.slice(0), - i, j, val, name, isNamedFound, argIndex, argsLength = 0; - - mixinEnv = new tree.evalEnv(mixinEnv, [frame].concat(mixinEnv.frames)); - - if (args) { - args = args.slice(0); - argsLength = args.length; - - for (i = 0; i < argsLength; i++) { - arg = args[i]; - if (name = (arg && arg.name)) { - isNamedFound = false; - for (j = 0; j < params.length; j++) { - if (!evaldArguments[j] && name === params[j].name) { - evaldArguments[j] = arg.value.eval(env); - frame.prependRule(new (tree.Rule)(name, arg.value.eval(env))); - isNamedFound = true; - break; - } - } - if (isNamedFound) { - args.splice(i, 1); - i--; - continue; - } else { - throw { - type: 'Runtime', message: "Named argument for " + this.name + - ' ' + args[i].name + ' not found' - }; - } - } - } - } - argIndex = 0; - for (i = 0; i < params.length; i++) { - if (evaldArguments[i]) { - continue; - } - - arg = args && args[argIndex]; - - if (name = params[i].name) { - if (params[i].variadic) { - varargs = []; - for (j = argIndex; j < argsLength; j++) { - varargs.push(args[j].value.eval(env)); - } - frame.prependRule(new (tree.Rule)(name, new (tree.Expression)(varargs).eval(env))); - } else { - val = arg && arg.value; - if (val) { - val = val.eval(env); - } else if (params[i].value) { - val = params[i].value.eval(mixinEnv); - frame.resetCache(); - } else { - throw { - type: 'Runtime', message: "wrong number of arguments for " + this.name + - ' (' + argsLength + ' for ' + this.arity + ')' - }; - } - - frame.prependRule(new (tree.Rule)(name, val)); - evaldArguments[i] = val; - } - } - - if (params[i].variadic && args) { - for (j = argIndex; j < argsLength; j++) { - evaldArguments[j] = args[j].value.eval(env); - } - } - argIndex++; - } - - return frame; - }, - eval: function (env) { - return new tree.mixin.Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || env.frames.slice(0)); - }, - evalCall: function (env, args, important) { - var _arguments = [], - mixinFrames = this.frames ? this.frames.concat(env.frames) : env.frames, - frame = this.evalParams(env, new (tree.evalEnv)(env, mixinFrames), args, _arguments), - rules, ruleset; - - frame.prependRule(new (tree.Rule)('@arguments', new (tree.Expression)(_arguments).eval(env))); - - rules = this.rules.slice(0); - - ruleset = new (tree.Ruleset)(null, rules); - ruleset.originalRuleset = this; - ruleset = ruleset.eval(new (tree.evalEnv)(env, [this, frame].concat(mixinFrames))); - if (important) { - ruleset = this.parent.makeImportant.apply(ruleset); - } - return ruleset; - }, - matchCondition: function (args, env) { - if (this.condition && !this.condition.eval( - new (tree.evalEnv)(env, - [this.evalParams(env, new (tree.evalEnv)(env, this.frames ? this.frames.concat(env.frames) : env.frames), args, [])] // the parameter variables - .concat(this.frames) // the parent namespace/mixin frames - .concat(env.frames)))) { // the current environment frames - return false; - } - return true; - }, - matchArgs: function (args, env) { - var argsLength = (args && args.length) || 0, len; - - if (!this.variadic) { - if (argsLength < this.required) { - return false; - } - if (argsLength > this.params.length) { - return false; - } - } else { - if (argsLength < (this.required - 1)) { - return false; - } - } - - len = Math.min(argsLength, this.arity); - - for (var i = 0; i < len; i++) { - if (!this.params[i].name && !this.params[i].variadic) { - if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) { - return false; - } - } - } - return true; - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.Negative = function (node) { - this.value = node; - }; - tree.Negative.prototype = { - type: "Negative", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add('-'); - this.value.genCSS(env, output); - }, - toCSS: tree.toCSS, - eval: function (env) { - if (env.isMathOn()) { - return (new (tree.Operation)('*', [new (tree.Dimension)(-1), this.value])).eval(env); - } - return new (tree.Negative)(this.value.eval(env)); - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.Operation = function (op, operands, isSpaced) { - this.op = op.trim(); - this.operands = operands; - this.isSpaced = isSpaced; - }; - tree.Operation.prototype = { - type: "Operation", - accept: function (visitor) { - this.operands = visitor.visit(this.operands); - }, - eval: function (env) { - var a = this.operands[0].eval(env), - b = this.operands[1].eval(env); - - if (env.isMathOn()) { - if (a instanceof tree.Dimension && b instanceof tree.Color) { - a = a.toColor(); - } - if (b instanceof tree.Dimension && a instanceof tree.Color) { - b = b.toColor(); - } - if (!a.operate) { - throw { - type: "Operation", - message: "Operation on an invalid type" - }; - } - - return a.operate(env, this.op, b); - } else { - return new (tree.Operation)(this.op, [a, b], this.isSpaced); - } - }, - genCSS: function (env, output) { - this.operands[0].genCSS(env, output); - if (this.isSpaced) { - output.add(" "); - } - output.add(this.op); - if (this.isSpaced) { - output.add(" "); - } - this.operands[1].genCSS(env, output); - }, - toCSS: tree.toCSS - }; - - tree.operate = function (env, op, a, b) { - switch (op) { - case '+': - return a + b; - case '-': - return a - b; - case '*': - return a * b; - case '/': - return a / b; - } - }; - -})(require('../tree')); - - -(function (tree) { - - tree.Paren = function (node) { - this.value = node; - }; - tree.Paren.prototype = { - type: "Paren", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add('('); - this.value.genCSS(env, output); - output.add(')'); - }, - toCSS: tree.toCSS, - eval: function (env) { - return new (tree.Paren)(this.value.eval(env)); - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.Quoted = function (str, content, escaped, index, currentFileInfo) { - this.escaped = escaped; - this.value = content || ''; - this.quote = str.charAt(0); - this.index = index; - this.currentFileInfo = currentFileInfo; - }; - tree.Quoted.prototype = { - type: "Quoted", - genCSS: function (env, output) { - if (!this.escaped) { - output.add(this.quote, this.currentFileInfo, this.index); - } - output.add(this.value); - if (!this.escaped) { - output.add(this.quote); - } - }, - toCSS: tree.toCSS, - eval: function (env) { - var that = this; - var value = this.value.replace(/`([^`]+)`/g, function (_, exp) { - return new (tree.JavaScript)(exp, that.index, true).eval(env).value; - }).replace(/@\{([\w-]+)\}/g, function (_, name) { - var v = new (tree.Variable)('@' + name, that.index, that.currentFileInfo).eval(env, true); - return (v instanceof tree.Quoted) ? v.value : v.toCSS(); - }); - return new (tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index, this.currentFileInfo); - }, - compare: function (x) { - if (!x.toCSS) { - return -1; - } - - var left, right; - - // when comparing quoted strings allow the quote to differ - if (x.type === "Quoted" && !this.escaped && !x.escaped) { - left = x.value; - right = this.value; - } else { - left = this.toCSS(); - right = x.toCSS(); - } - - if (left === right) { - return 0; - } - - return left < right ? -1 : 1; - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.Rule = function (name, value, important, merge, index, currentFileInfo, inline, variable) { - this.name = name; - this.value = (value instanceof tree.Value || value instanceof tree.Ruleset) ? value : new (tree.Value)([value]); - this.important = important ? ' ' + important.trim() : ''; - this.merge = merge; - this.index = index; - this.currentFileInfo = currentFileInfo; - this.inline = inline || false; - this.variable = (variable !== undefined) ? variable - : (name.charAt && (name.charAt(0) === '@')); - }; - - tree.Rule.prototype = { - type: "Rule", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add(this.name + (env.compress ? ':' : ': '), this.currentFileInfo, this.index); - try { - this.value.genCSS(env, output); - } - catch (e) { - e.index = this.index; - e.filename = this.currentFileInfo.filename; - throw e; - } - output.add(this.important + ((this.inline || (env.lastRule && env.compress)) ? "" : ";"), this.currentFileInfo, this.index); - }, - toCSS: tree.toCSS, - eval: function (env) { - var strictMathBypass = false, name = this.name, variable = this.variable, evaldValue; - if (typeof name !== "string") { - // expand 'primitive' name directly to get - // things faster (~10% for benchmark.less): - name = (name.length === 1) - && (name[0] instanceof tree.Keyword) - ? name[0].value : evalName(env, name); - variable = false; // never treat expanded interpolation as new variable name - } - if (name === "font" && !env.strictMath) { - strictMathBypass = true; - env.strictMath = true; - } - try { - evaldValue = this.value.eval(env); - - if (!this.variable && evaldValue.type === "DetachedRuleset") { - throw { - message: "Rulesets cannot be evaluated on a property.", - index: this.index, filename: this.currentFileInfo.filename - }; - } - - return new (tree.Rule)(name, - evaldValue, - this.important, - this.merge, - this.index, this.currentFileInfo, this.inline, - variable); - } - catch (e) { - if (typeof e.index !== 'number') { - e.index = this.index; - e.filename = this.currentFileInfo.filename; - } - throw e; - } - finally { - if (strictMathBypass) { - env.strictMath = false; - } - } - }, - makeImportant: function () { - return new (tree.Rule)(this.name, - this.value, - "!important", - this.merge, - this.index, this.currentFileInfo, this.inline); - } - }; - - function evalName(env, name) { - var value = "", i, n = name.length, - output = { - add: function (s) { - value += s; - } - }; - for (i = 0; i < n; i++) { - name[i].eval(env).genCSS(env, output); - } - return value; - } - -})(require('../tree')); - -(function (tree) { - - tree.RulesetCall = function (variable) { - this.variable = variable; - }; - tree.RulesetCall.prototype = { - type: "RulesetCall", - accept: function (visitor) { - }, - eval: function (env) { - var detachedRuleset = new (tree.Variable)(this.variable).eval(env); - return detachedRuleset.callEval(env); - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.Ruleset = function (selectors, rules, strictImports) { - this.selectors = selectors; - this.rules = rules; - this._lookups = {}; - this.strictImports = strictImports; - }; - tree.Ruleset.prototype = { - type: "Ruleset", - accept: function (visitor) { - if (this.paths) { - visitor.visitArray(this.paths, true); - } else if (this.selectors) { - this.selectors = visitor.visitArray(this.selectors); - } - if (this.rules && this.rules.length) { - this.rules = visitor.visitArray(this.rules); - } - }, - eval: function (env) { - var thisSelectors = this.selectors, selectors, - selCnt, selector, i, defaultFunc = tree.defaultFunc, hasOnePassingSelector = false; - - if (thisSelectors && (selCnt = thisSelectors.length)) { - selectors = []; - defaultFunc.error({ - type: "Syntax", - message: "it is currently only allowed in parametric mixin guards," - }); - for (i = 0; i < selCnt; i++) { - selector = thisSelectors[i].eval(env); - selectors.push(selector); - if (selector.evaldCondition) { - hasOnePassingSelector = true; - } - } - defaultFunc.reset(); - } else { - hasOnePassingSelector = true; - } - - var rules = this.rules ? this.rules.slice(0) : null, - ruleset = new (tree.Ruleset)(selectors, rules, this.strictImports), - rule, subRule; - - ruleset.originalRuleset = this; - ruleset.root = this.root; - ruleset.firstRoot = this.firstRoot; - ruleset.allowImports = this.allowImports; - - if (this.debugInfo) { - ruleset.debugInfo = this.debugInfo; - } - - if (!hasOnePassingSelector) { - rules.length = 0; - } - - // push the current ruleset to the frames stack - var envFrames = env.frames; - envFrames.unshift(ruleset); - - // currrent selectors - var envSelectors = env.selectors; - if (!envSelectors) { - env.selectors = envSelectors = []; - } - envSelectors.unshift(this.selectors); - - // Evaluate imports - if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { - ruleset.evalImports(env); - } - - // Store the frames around mixin definitions, - // so they can be evaluated like closures when the time comes. - var rsRules = ruleset.rules, rsRuleCnt = rsRules ? rsRules.length : 0; - for (i = 0; i < rsRuleCnt; i++) { - if (rsRules[i] instanceof tree.mixin.Definition || rsRules[i] instanceof tree.DetachedRuleset) { - rsRules[i] = rsRules[i].eval(env); - } - } - - var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0; - - // Evaluate mixin calls. - for (i = 0; i < rsRuleCnt; i++) { - if (rsRules[i] instanceof tree.mixin.Call) { - /*jshint loopfunc:true */ - rules = rsRules[i].eval(env).filter(function (r) { - if ((r instanceof tree.Rule) && r.variable) { - // do not pollute the scope if the variable is - // already there. consider returning false here - // but we need a way to "return" variable from mixins - return !(ruleset.variable(r.name)); - } - return true; - }); - rsRules.splice.apply(rsRules, [i, 1].concat(rules)); - rsRuleCnt += rules.length - 1; - i += rules.length - 1; - ruleset.resetCache(); - } else if (rsRules[i] instanceof tree.RulesetCall) { - /*jshint loopfunc:true */ - rules = rsRules[i].eval(env).rules.filter(function (r) { - if ((r instanceof tree.Rule) && r.variable) { - // do not pollute the scope at all - return false; - } - return true; - }); - rsRules.splice.apply(rsRules, [i, 1].concat(rules)); - rsRuleCnt += rules.length - 1; - i += rules.length - 1; - ruleset.resetCache(); - } - } - - // Evaluate everything else - for (i = 0; i < rsRules.length; i++) { - rule = rsRules[i]; - if (!(rule instanceof tree.mixin.Definition || rule instanceof tree.DetachedRuleset)) { - rsRules[i] = rule = rule.eval ? rule.eval(env) : rule; - } - } - - // Evaluate everything else - for (i = 0; i < rsRules.length; i++) { - rule = rsRules[i]; - // for rulesets, check if it is a css guard and can be removed - if (rule instanceof tree.Ruleset && rule.selectors && rule.selectors.length === 1) { - // check if it can be folded in (e.g. & where) - if (rule.selectors[0].isJustParentSelector()) { - rsRules.splice(i--, 1); - - for (var j = 0; j < rule.rules.length; j++) { - subRule = rule.rules[j]; - if (!(subRule instanceof tree.Rule) || !subRule.variable) { - rsRules.splice(++i, 0, subRule); - } - } - } - } - } - - // Pop the stack - envFrames.shift(); - envSelectors.shift(); - - if (env.mediaBlocks) { - for (i = mediaBlockCount; i < env.mediaBlocks.length; i++) { - env.mediaBlocks[i].bubbleSelectors(selectors); - } - } - - return ruleset; - }, - evalImports: function (env) { - var rules = this.rules, i, importRules; - if (!rules) { - return; - } - - for (i = 0; i < rules.length; i++) { - if (rules[i] instanceof tree.Import) { - importRules = rules[i].eval(env); - if (importRules && importRules.length) { - rules.splice.apply(rules, [i, 1].concat(importRules)); - i += importRules.length - 1; - } else { - rules.splice(i, 1, importRules); - } - this.resetCache(); - } - } - }, - makeImportant: function () { - return new tree.Ruleset(this.selectors, this.rules.map(function (r) { - if (r.makeImportant) { - return r.makeImportant(); - } else { - return r; - } - }), this.strictImports); - }, - matchArgs: function (args) { - return !args || args.length === 0; - }, - // lets you call a css selector with a guard - matchCondition: function (args, env) { - var lastSelector = this.selectors[this.selectors.length - 1]; - if (!lastSelector.evaldCondition) { - return false; - } - if (lastSelector.condition && !lastSelector.condition.eval( - new (tree.evalEnv)(env, - env.frames))) { - return false; - } - return true; - }, - resetCache: function () { - this._rulesets = null; - this._variables = null; - this._lookups = {}; - }, - variables: function () { - if (!this._variables) { - this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) { - if (r instanceof tree.Rule && r.variable === true) { - hash[r.name] = r; - } - return hash; - }, {}); - } - return this._variables; - }, - variable: function (name) { - return this.variables()[name]; - }, - rulesets: function () { - if (!this.rules) { - return null; - } - - var _Ruleset = tree.Ruleset, _MixinDefinition = tree.mixin.Definition, - filtRules = [], rules = this.rules, cnt = rules.length, - i, rule; - - for (i = 0; i < cnt; i++) { - rule = rules[i]; - if ((rule instanceof _Ruleset) || (rule instanceof _MixinDefinition)) { - filtRules.push(rule); - } - } - - return filtRules; - }, - prependRule: function (rule) { - var rules = this.rules; - if (rules) { - rules.unshift(rule); - } else { - this.rules = [rule]; - } - }, - find: function (selector, self) { - self = self || this; - var rules = [], match, - key = selector.toCSS(); - - if (key in this._lookups) { - return this._lookups[key]; - } - - this.rulesets().forEach(function (rule) { - if (rule !== self) { - for (var j = 0; j < rule.selectors.length; j++) { - match = selector.match(rule.selectors[j]); - if (match) { - if (selector.elements.length > match) { - Array.prototype.push.apply(rules, rule.find( - new (tree.Selector)(selector.elements.slice(match)), self)); - } else { - rules.push(rule); - } - break; - } - } - } - }); - this._lookups[key] = rules; - return rules; - }, - genCSS: function (env, output) { - var i, j, - charsetRuleNodes = [], - ruleNodes = [], - rulesetNodes = [], - rulesetNodeCnt, - debugInfo, // Line number debugging - rule, - path; - - env.tabLevel = (env.tabLevel || 0); - - if (!this.root) { - env.tabLevel++; - } - - var tabRuleStr = env.compress ? '' : Array(env.tabLevel + 1).join(" "), - tabSetStr = env.compress ? '' : Array(env.tabLevel).join(" "), - sep; - - function isRulesetLikeNode(rule, root) { - // if it has nested rules, then it should be treated like a ruleset - if (rule.rules) - return true; - - // medias and comments do not have nested rules, but should be treated like rulesets anyway - if ((rule instanceof tree.Media) || (root && rule instanceof tree.Comment)) - return true; - - // some directives and anonumoust nodes are ruleset like, others are not - if ((rule instanceof tree.Directive) || (rule instanceof tree.Anonymous)) { - return rule.isRulesetLike(); - } - - //anything else is assumed to be a rule - return false; - } - - for (i = 0; i < this.rules.length; i++) { - rule = this.rules[i]; - if (isRulesetLikeNode(rule, this.root)) { - rulesetNodes.push(rule); - } else { - //charsets should float on top of everything - if (rule.isCharset && rule.isCharset()) { - charsetRuleNodes.push(rule); - } else { - ruleNodes.push(rule); - } - } - } - ruleNodes = charsetRuleNodes.concat(ruleNodes); - - // If this is the root node, we don't render - // a selector, or {}. - if (!this.root) { - debugInfo = tree.debugInfo(env, this, tabSetStr); - - if (debugInfo) { - output.add(debugInfo); - output.add(tabSetStr); - } - - var paths = this.paths, pathCnt = paths.length, - pathSubCnt; - - sep = env.compress ? ',' : (',\n' + tabSetStr); - - for (i = 0; i < pathCnt; i++) { - path = paths[i]; - if (!(pathSubCnt = path.length)) { - continue; - } - if (i > 0) { - output.add(sep); - } - - env.firstSelector = true; - path[0].genCSS(env, output); - - env.firstSelector = false; - for (j = 1; j < pathSubCnt; j++) { - path[j].genCSS(env, output); - } - } - - output.add((env.compress ? '{' : ' {\n') + tabRuleStr); - } - - // Compile rules and rulesets - for (i = 0; i < ruleNodes.length; i++) { - rule = ruleNodes[i]; - - // @page{ directive ends up with root elements inside it, a mix of rules and rulesets - // In this instance we do not know whether it is the last property - if (i + 1 === ruleNodes.length && (!this.root || rulesetNodes.length === 0 || this.firstRoot)) { - env.lastRule = true; - } - - if (rule.genCSS) { - rule.genCSS(env, output); - } else if (rule.value) { - output.add(rule.value.toString()); - } - - if (!env.lastRule) { - output.add(env.compress ? '' : ('\n' + tabRuleStr)); - } else { - env.lastRule = false; - } - } - - if (!this.root) { - output.add((env.compress ? '}' : '\n' + tabSetStr + '}')); - env.tabLevel--; - } - - sep = (env.compress ? "" : "\n") + (this.root ? tabRuleStr : tabSetStr); - rulesetNodeCnt = rulesetNodes.length; - if (rulesetNodeCnt) { - if (ruleNodes.length && sep) { - output.add(sep); - } - rulesetNodes[0].genCSS(env, output); - for (i = 1; i < rulesetNodeCnt; i++) { - if (sep) { - output.add(sep); - } - rulesetNodes[i].genCSS(env, output); - } - } - - if (!output.isEmpty() && !env.compress && this.firstRoot) { - output.add('\n'); - } - }, - - toCSS: tree.toCSS, - - markReferenced: function () { - if (!this.selectors) { - return; - } - for (var s = 0; s < this.selectors.length; s++) { - this.selectors[s].markReferenced(); - } - }, - - joinSelectors: function (paths, context, selectors) { - for (var s = 0; s < selectors.length; s++) { - this.joinSelector(paths, context, selectors[s]); - } - }, - - joinSelector: function (paths, context, selector) { - - var i, j, k, - hasParentSelector, newSelectors, el, sel, parentSel, - newSelectorPath, afterParentJoin, newJoinedSelector, - newJoinedSelectorEmpty, lastSelector, currentElements, - selectorsMultiplied; - - for (i = 0; i < selector.elements.length; i++) { - el = selector.elements[i]; - if (el.value === '&') { - hasParentSelector = true; - } - } - - if (!hasParentSelector) { - if (context.length > 0) { - for (i = 0; i < context.length; i++) { - paths.push(context[i].concat(selector)); - } - } - else { - paths.push([selector]); - } - return; - } - - // The paths are [[Selector]] - // The first list is a list of comma seperated selectors - // The inner list is a list of inheritance seperated selectors - // e.g. - // .a, .b { - // .c { - // } - // } - // == [[.a] [.c]] [[.b] [.c]] - // - - // the elements from the current selector so far - currentElements = []; - // the current list of new selectors to add to the path. - // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors - // by the parents - newSelectors = [[]]; - - for (i = 0; i < selector.elements.length; i++) { - el = selector.elements[i]; - // non parent reference elements just get added - if (el.value !== "&") { - currentElements.push(el); - } else { - // the new list of selectors to add - selectorsMultiplied = []; - - // merge the current list of non parent selector elements - // on to the current list of selectors to add - if (currentElements.length > 0) { - this.mergeElementsOnToSelectors(currentElements, newSelectors); - } - - // loop through our current selectors - for (j = 0; j < newSelectors.length; j++) { - sel = newSelectors[j]; - // if we don't have any parent paths, the & might be in a mixin so that it can be used - // whether there are parents or not - if (context.length === 0) { - // the combinator used on el should now be applied to the next element instead so that - // it is not lost - if (sel.length > 0) { - sel[0].elements = sel[0].elements.slice(0); - sel[0].elements.push(new (tree.Element)(el.combinator, '', el.index, el.currentFileInfo)); - } - selectorsMultiplied.push(sel); - } - else { - // and the parent selectors - for (k = 0; k < context.length; k++) { - parentSel = context[k]; - // We need to put the current selectors - // then join the last selector's elements on to the parents selectors - - // our new selector path - newSelectorPath = []; - // selectors from the parent after the join - afterParentJoin = []; - newJoinedSelectorEmpty = true; - - //construct the joined selector - if & is the first thing this will be empty, - // if not newJoinedSelector will be the last set of elements in the selector - if (sel.length > 0) { - newSelectorPath = sel.slice(0); - lastSelector = newSelectorPath.pop(); - newJoinedSelector = selector.createDerived(lastSelector.elements.slice(0)); - newJoinedSelectorEmpty = false; - } - else { - newJoinedSelector = selector.createDerived([]); - } - - //put together the parent selectors after the join - if (parentSel.length > 1) { - afterParentJoin = afterParentJoin.concat(parentSel.slice(1)); - } - - if (parentSel.length > 0) { - newJoinedSelectorEmpty = false; - - // join the elements so far with the first part of the parent - newJoinedSelector.elements.push(new (tree.Element)(el.combinator, parentSel[0].elements[0].value, el.index, el.currentFileInfo)); - newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1)); - } - - if (!newJoinedSelectorEmpty) { - // now add the joined selector - newSelectorPath.push(newJoinedSelector); - } - - // and the rest of the parent - newSelectorPath = newSelectorPath.concat(afterParentJoin); - - // add that to our new set of selectors - selectorsMultiplied.push(newSelectorPath); - } - } - } - - // our new selectors has been multiplied, so reset the state - newSelectors = selectorsMultiplied; - currentElements = []; - } - } - - // if we have any elements left over (e.g. .a& .b == .b) - // add them on to all the current selectors - if (currentElements.length > 0) { - this.mergeElementsOnToSelectors(currentElements, newSelectors); - } - - for (i = 0; i < newSelectors.length; i++) { - if (newSelectors[i].length > 0) { - paths.push(newSelectors[i]); - } - } - }, - - mergeElementsOnToSelectors: function (elements, selectors) { - var i, sel; - - if (selectors.length === 0) { - selectors.push([new (tree.Selector)(elements)]); - return; - } - - for (i = 0; i < selectors.length; i++) { - sel = selectors[i]; - - // if the previous thing in sel is a parent this needs to join on to it - if (sel.length > 0) { - sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); - } - else { - sel.push(new (tree.Selector)(elements)); - } - } - } - }; -})(require('../tree')); - -(function (tree) { - - tree.Selector = function (elements, extendList, condition, index, currentFileInfo, isReferenced) { - this.elements = elements; - this.extendList = extendList; - this.condition = condition; - this.currentFileInfo = currentFileInfo || {}; - this.isReferenced = isReferenced; - if (!condition) { - this.evaldCondition = true; - } - }; - tree.Selector.prototype = { - type: "Selector", - accept: function (visitor) { - if (this.elements) { - this.elements = visitor.visitArray(this.elements); - } - if (this.extendList) { - this.extendList = visitor.visitArray(this.extendList); - } - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - }, - createDerived: function (elements, extendList, evaldCondition) { - evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition; - var newSelector = new (tree.Selector)(elements, extendList || this.extendList, null, this.index, this.currentFileInfo, this.isReferenced); - newSelector.evaldCondition = evaldCondition; - newSelector.mediaEmpty = this.mediaEmpty; - return newSelector; - }, - match: function (other) { - var elements = this.elements, - len = elements.length, - olen, i; - - other.CacheElements(); - - olen = other._elements.length; - if (olen === 0 || len < olen) { - return 0; - } else { - for (i = 0; i < olen; i++) { - if (elements[i].value !== other._elements[i]) { - return 0; - } - } - } - - return olen; // return number of matched elements - }, - CacheElements: function () { - var css = '', len, v, i; - - if (!this._elements) { - - len = this.elements.length; - for (i = 0; i < len; i++) { - - v = this.elements[i]; - css += v.combinator.value; - - if (!v.value.value) { - css += v.value; - continue; - } - - if (typeof v.value.value !== "string") { - css = ''; - break; - } - css += v.value.value; - } - - this._elements = css.match(/[,&#\*\.\w-]([\w-]|(\\.))*/g); - - if (this._elements) { - if (this._elements[0] === "&") { - this._elements.shift(); - } - - } else { - this._elements = []; - } - - } - }, - isJustParentSelector: function () { - return !this.mediaEmpty && - this.elements.length === 1 && - this.elements[0].value === '&' && - (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === ''); - }, - eval: function (env) { - var evaldCondition = this.condition && this.condition.eval(env), - elements = this.elements, extendList = this.extendList; - - elements = elements && elements.map(function (e) { - return e.eval(env); - }); - extendList = extendList && extendList.map(function (extend) { - return extend.eval(env); - }); - - return this.createDerived(elements, extendList, evaldCondition); - }, - genCSS: function (env, output) { - var i, element; - if ((!env || !env.firstSelector) && this.elements[0].combinator.value === "") { - output.add(' ', this.currentFileInfo, this.index); - } - if (!this._css) { - //TODO caching? speed comparison? - for (i = 0; i < this.elements.length; i++) { - element = this.elements[i]; - element.genCSS(env, output); - } - } - }, - toCSS: tree.toCSS, - markReferenced: function () { - this.isReferenced = true; - }, - getIsReferenced: function () { - return !this.currentFileInfo.reference || this.isReferenced; - }, - getIsOutput: function () { - return this.evaldCondition; - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.UnicodeDescriptor = function (value) { - this.value = value; - }; - tree.UnicodeDescriptor.prototype = { - type: "UnicodeDescriptor", - genCSS: function (env, output) { - output.add(this.value); - }, - toCSS: tree.toCSS, - eval: function () { - return this; - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.URL = function (val, currentFileInfo, isEvald) { - this.value = val; - this.currentFileInfo = currentFileInfo; - this.isEvald = isEvald; - }; - tree.URL.prototype = { - type: "Url", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add("url("); - this.value.genCSS(env, output); - output.add(")"); - }, - toCSS: tree.toCSS, - eval: function (ctx) { - var val = this.value.eval(ctx), - rootpath; - - if (!this.isEvald) { - // Add the base path if the URL is relative - rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; - if (rootpath && typeof val.value === "string" && ctx.isPathRelative(val.value)) { - if (!val.quote) { - rootpath = rootpath.replace(/[\(\)'"\s]/g, function (match) { - return "\\" + match; - }); - } - val.value = rootpath + val.value; - } - - val.value = ctx.normalizePath(val.value); - - // Add url args if enabled - if (ctx.urlArgs) { - if (!val.value.match(/^\s*data:/)) { - var delimiter = val.value.indexOf('?') === -1 ? '?' : '&'; - var urlArgs = delimiter + ctx.urlArgs; - if (val.value.indexOf('#') !== -1) { - val.value = val.value.replace('#', urlArgs + '#'); - } else { - val.value += urlArgs; - } - } - } - } - - return new (tree.URL)(val, this.currentFileInfo, true); - } - }; - -})(require('../tree')); - -(function (tree) { - - tree.Value = function (value) { - this.value = value; - }; - tree.Value.prototype = { - type: "Value", - accept: function (visitor) { - if (this.value) { - this.value = visitor.visitArray(this.value); - } - }, - eval: function (env) { - if (this.value.length === 1) { - return this.value[0].eval(env); - } else { - return new (tree.Value)(this.value.map(function (v) { - return v.eval(env); - })); - } - }, - genCSS: function (env, output) { - var i; - for (i = 0; i < this.value.length; i++) { - this.value[i].genCSS(env, output); - if (i + 1 < this.value.length) { - output.add((env && env.compress) ? ',' : ', '); - } - } - }, - toCSS: tree.toCSS - }; - -})(require('../tree')); - -(function (tree) { - - tree.Variable = function (name, index, currentFileInfo) { - this.name = name; - this.index = index; - this.currentFileInfo = currentFileInfo || {}; - }; - tree.Variable.prototype = { - type: "Variable", - eval: function (env) { - var variable, name = this.name; - - if (name.indexOf('@@') === 0) { - name = '@' + new (tree.Variable)(name.slice(1)).eval(env).value; - } - - if (this.evaluating) { - throw { - type: 'Name', - message: "Recursive variable definition for " + name, - filename: this.currentFileInfo.file, - index: this.index - }; - } - - this.evaluating = true; - - variable = tree.find(env.frames, function (frame) { - var v = frame.variable(name); - if (v) { - return v.value.eval(env); - } - }); - if (variable) { - this.evaluating = false; - return variable; - } else { - throw { - type: 'Name', - message: "variable " + name + " is undefined", - filename: this.currentFileInfo.filename, - index: this.index - }; - } - } - }; - -})(require('../tree')); - -(function (tree) { - - var parseCopyProperties = [ - 'paths', // option - unmodified - paths to search for imports on - 'optimization', // option - optimization level (for the chunker) - 'files', // list of files that have been imported, used for import-once - 'contents', // map - filename to contents of all the files - 'contentsIgnoredChars', // map - filename to lines at the begining of each file to ignore - 'relativeUrls', // option - whether to adjust URL's to be relative - 'rootpath', // option - rootpath to append to URL's - 'strictImports', // option - - 'insecure', // option - whether to allow imports from insecure ssl hosts - 'dumpLineNumbers', // option - whether to dump line numbers - 'compress', // option - whether to compress - 'processImports', // option - whether to process imports. if false then imports will not be imported - 'syncImport', // option - whether to import synchronously - 'javascriptEnabled',// option - whether JavaScript is enabled. if undefined, defaults to true - 'mime', // browser only - mime type for sheet import - 'useFileCache', // browser only - whether to use the per file session cache - 'currentFileInfo' // information about the current file - for error reporting and importing and making urls relative etc. - ]; - - //currentFileInfo = { - // 'relativeUrls' - option - whether to adjust URL's to be relative - // 'filename' - full resolved filename of current file - // 'rootpath' - path to append to normal URLs for this node - // 'currentDirectory' - path to the current file, absolute - // 'rootFilename' - filename of the base file - // 'entryPath' - absolute path to the entry file - // 'reference' - whether the file should not be output and only output parts that are referenced - - tree.parseEnv = function (options) { - copyFromOriginal(options, this, parseCopyProperties); - - if (!this.contents) { - this.contents = {}; - } - if (!this.contentsIgnoredChars) { - this.contentsIgnoredChars = {}; - } - if (!this.files) { - this.files = {}; - } - - if (typeof this.paths === "string") { - this.paths = [this.paths]; - } - - if (!this.currentFileInfo) { - var filename = (options && options.filename) || "input"; - var entryPath = filename.replace(/[^\/\\]*$/, ""); - if (options) { - options.filename = null; - } - this.currentFileInfo = { - filename: filename, - relativeUrls: this.relativeUrls, - rootpath: (options && options.rootpath) || "", - currentDirectory: entryPath, - entryPath: entryPath, - rootFilename: filename - }; - } - }; - - var evalCopyProperties = [ - 'silent', // whether to swallow errors and warnings - 'verbose', // whether to log more activity - 'compress', // whether to compress - 'yuicompress', // whether to compress with the outside tool yui compressor - 'ieCompat', // whether to enforce IE compatibility (IE8 data-uri) - 'strictMath', // whether math has to be within parenthesis - 'strictUnits', // whether units need to evaluate correctly - 'cleancss', // whether to compress with clean-css - 'sourceMap', // whether to output a source map - 'importMultiple', // whether we are currently importing multiple copies - 'urlArgs' // whether to add args into url tokens - ]; - - tree.evalEnv = function (options, frames) { - copyFromOriginal(options, this, evalCopyProperties); - - this.frames = frames || []; - }; - - tree.evalEnv.prototype.inParenthesis = function () { - if (!this.parensStack) { - this.parensStack = []; - } - this.parensStack.push(true); - }; - - tree.evalEnv.prototype.outOfParenthesis = function () { - this.parensStack.pop(); - }; - - tree.evalEnv.prototype.isMathOn = function () { - return this.strictMath ? (this.parensStack && this.parensStack.length) : true; - }; - - tree.evalEnv.prototype.isPathRelative = function (path) { - return !/^(?:[a-z-]+:|\/)/.test(path); - }; - - tree.evalEnv.prototype.normalizePath = function (path) { - var - segments = path.split("/").reverse(), - segment; - - path = []; - while (segments.length !== 0) { - segment = segments.pop(); - switch (segment) { - case ".": - break; - case "..": - if ((path.length === 0) || (path[path.length - 1] === "..")) { - path.push(segment); - } else { - path.pop(); - } - break; - default: - path.push(segment); - break; - } - } - - return path.join("/"); - }; - - //todo - do the same for the toCSS env - //tree.toCSSEnv = function (options) { - //}; - - var copyFromOriginal = function (original, destination, propertiesToCopy) { - if (!original) { - return; - } - - for (var i = 0; i < propertiesToCopy.length; i++) { - if (original.hasOwnProperty(propertiesToCopy[i])) { - destination[propertiesToCopy[i]] = original[propertiesToCopy[i]]; - } - } - }; - -})(require('./tree')); - -(function (tree) { - - var _visitArgs = {visitDeeper: true}, - _hasIndexed = false; - - function _noop(node) { - return node; - } - - function indexNodeTypes(parent, ticker) { - // add .typeIndex to tree node types for lookup table - var key, child; - for (key in parent) { - if (parent.hasOwnProperty(key)) { - child = parent[key]; - switch (typeof child) { - case "function": - // ignore bound functions directly on tree which do not have a prototype - // or aren't nodes - if (child.prototype && child.prototype.type) { - child.prototype.typeIndex = ticker++; - } - break; - case "object": - ticker = indexNodeTypes(child, ticker); - break; - } - } - } - return ticker; - } - - tree.visitor = function (implementation) { - this._implementation = implementation; - this._visitFnCache = []; - - if (!_hasIndexed) { - indexNodeTypes(tree, 1); - _hasIndexed = true; - } - }; - - tree.visitor.prototype = { - visit: function (node) { - if (!node) { - return node; - } - - var nodeTypeIndex = node.typeIndex; - if (!nodeTypeIndex) { - return node; - } - - var visitFnCache = this._visitFnCache, - impl = this._implementation, - aryIndx = nodeTypeIndex << 1, - outAryIndex = aryIndx | 1, - func = visitFnCache[aryIndx], - funcOut = visitFnCache[outAryIndex], - visitArgs = _visitArgs, - fnName; - - visitArgs.visitDeeper = true; - - if (!func) { - fnName = "visit" + node.type; - func = impl[fnName] || _noop; - funcOut = impl[fnName + "Out"] || _noop; - visitFnCache[aryIndx] = func; - visitFnCache[outAryIndex] = funcOut; - } - - if (func !== _noop) { - var newNode = func.call(impl, node, visitArgs); - if (impl.isReplacing) { - node = newNode; - } - } - - if (visitArgs.visitDeeper && node && node.accept) { - node.accept(this); - } - - if (funcOut != _noop) { - funcOut.call(impl, node); - } - - return node; - }, - visitArray: function (nodes, nonReplacing) { - if (!nodes) { - return nodes; - } - - var cnt = nodes.length, i; - - // Non-replacing - if (nonReplacing || !this._implementation.isReplacing) { - for (i = 0; i < cnt; i++) { - this.visit(nodes[i]); - } - return nodes; - } - - // Replacing - var out = []; - for (i = 0; i < cnt; i++) { - var evald = this.visit(nodes[i]); - if (!evald.splice) { - out.push(evald); - } else if (evald.length) { - this.flatten(evald, out); - } - } - return out; - }, - flatten: function (arr, out) { - if (!out) { - out = []; - } - - var cnt, i, item, - nestedCnt, j, nestedItem; - - for (i = 0, cnt = arr.length; i < cnt; i++) { - item = arr[i]; - if (!item.splice) { - out.push(item); - continue; - } - - for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) { - nestedItem = item[j]; - if (!nestedItem.splice) { - out.push(nestedItem); - } else if (nestedItem.length) { - this.flatten(nestedItem, out); - } - } - } - - return out; - } - }; - -})(require('./tree')); -(function (tree) { - tree.importVisitor = function (importer, finish, evalEnv, onceFileDetectionMap, recursionDetector) { - this._visitor = new tree.visitor(this); - this._importer = importer; - this._finish = finish; - this.env = evalEnv || new tree.evalEnv(); - this.importCount = 0; - this.onceFileDetectionMap = onceFileDetectionMap || {}; - this.recursionDetector = {}; - if (recursionDetector) { - for (var fullFilename in recursionDetector) { - if (recursionDetector.hasOwnProperty(fullFilename)) { - this.recursionDetector[fullFilename] = true; - } - } - } - }; - - tree.importVisitor.prototype = { - isReplacing: true, - run: function (root) { - var error; - try { - // process the contents - this._visitor.visit(root); - } - catch (e) { - error = e; - } - - this.isFinished = true; - - if (this.importCount === 0) { - this._finish(error); - } - }, - visitImport: function (importNode, visitArgs) { - var importVisitor = this, - evaldImportNode, - inlineCSS = importNode.options.inline; - - if (!importNode.css || inlineCSS) { - - try { - evaldImportNode = importNode.evalForImport(this.env); - } catch (e) { - if (!e.filename) { - e.index = importNode.index; - e.filename = importNode.currentFileInfo.filename; - } - // attempt to eval properly and treat as css - importNode.css = true; - // if that fails, this error will be thrown - importNode.error = e; - } - - if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { - importNode = evaldImportNode; - this.importCount++; - var env = new tree.evalEnv(this.env, this.env.frames.slice(0)); - - if (importNode.options.multiple) { - env.importMultiple = true; - } - - this._importer.push(importNode.getPath(), importNode.currentFileInfo, importNode.options, function (e, root, importedAtRoot, fullPath) { - if (e && !e.filename) { - e.index = importNode.index; - e.filename = importNode.currentFileInfo.filename; - } - - var duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector; - if (!env.importMultiple) { - if (duplicateImport) { - importNode.skip = true; - } else { - importNode.skip = function () { - if (fullPath in importVisitor.onceFileDetectionMap) { - return true; - } - importVisitor.onceFileDetectionMap[fullPath] = true; - return false; - }; - } - } - - var subFinish = function (e) { - importVisitor.importCount--; - - if (importVisitor.importCount === 0 && importVisitor.isFinished) { - importVisitor._finish(e); - } - }; - - if (root) { - importNode.root = root; - importNode.importedFilename = fullPath; - - if (!inlineCSS && (env.importMultiple || !duplicateImport)) { - importVisitor.recursionDetector[fullPath] = true; - new (tree.importVisitor)(importVisitor._importer, subFinish, env, importVisitor.onceFileDetectionMap, importVisitor.recursionDetector) - .run(root); - return; - } - } - - subFinish(); - }); - } - } - visitArgs.visitDeeper = false; - return importNode; - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - return ruleNode; - }, - visitDirective: function (directiveNode, visitArgs) { - this.env.frames.unshift(directiveNode); - return directiveNode; - }, - visitDirectiveOut: function (directiveNode) { - this.env.frames.shift(); - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - this.env.frames.unshift(mixinDefinitionNode); - return mixinDefinitionNode; - }, - visitMixinDefinitionOut: function (mixinDefinitionNode) { - this.env.frames.shift(); - }, - visitRuleset: function (rulesetNode, visitArgs) { - this.env.frames.unshift(rulesetNode); - return rulesetNode; - }, - visitRulesetOut: function (rulesetNode) { - this.env.frames.shift(); - }, - visitMedia: function (mediaNode, visitArgs) { - this.env.frames.unshift(mediaNode.rules[0]); - return mediaNode; - }, - visitMediaOut: function (mediaNode) { - this.env.frames.shift(); - } - }; - -})(require('./tree')); -(function (tree) { - tree.joinSelectorVisitor = function () { - this.contexts = [[]]; - this._visitor = new tree.visitor(this); - }; - - tree.joinSelectorVisitor.prototype = { - run: function (root) { - return this._visitor.visit(root); - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - - visitRuleset: function (rulesetNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1], - paths = [], selectors; - - this.contexts.push(paths); - - if (!rulesetNode.root) { - selectors = rulesetNode.selectors; - if (selectors) { - selectors = selectors.filter(function (selector) { - return selector.getIsOutput(); - }); - rulesetNode.selectors = selectors.length ? selectors : (selectors = null); - if (selectors) { - rulesetNode.joinSelectors(paths, context, selectors); - } - } - if (!selectors) { - rulesetNode.rules = null; - } - rulesetNode.paths = paths; - } - }, - visitRulesetOut: function (rulesetNode) { - this.contexts.length = this.contexts.length - 1; - }, - visitMedia: function (mediaNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia); - } - }; - -})(require('./tree')); -(function (tree) { - tree.toCSSVisitor = function (env) { - this._visitor = new tree.visitor(this); - this._env = env; - }; - - tree.toCSSVisitor.prototype = { - isReplacing: true, - run: function (root) { - return this._visitor.visit(root); - }, - - visitRule: function (ruleNode, visitArgs) { - if (ruleNode.variable) { - return []; - } - return ruleNode; - }, - - visitMixinDefinition: function (mixinNode, visitArgs) { - // mixin definitions do not get eval'd - this means they keep state - // so we have to clear that state here so it isn't used if toCSS is called twice - mixinNode.frames = []; - return []; - }, - - visitExtend: function (extendNode, visitArgs) { - return []; - }, - - visitComment: function (commentNode, visitArgs) { - if (commentNode.isSilent(this._env)) { - return []; - } - return commentNode; - }, - - visitMedia: function (mediaNode, visitArgs) { - mediaNode.accept(this._visitor); - visitArgs.visitDeeper = false; - - if (!mediaNode.rules.length) { - return []; - } - return mediaNode; - }, - - visitDirective: function (directiveNode, visitArgs) { - if (directiveNode.currentFileInfo.reference && !directiveNode.isReferenced) { - return []; - } - if (directiveNode.name === "@charset") { - // Only output the debug info together with subsequent @charset definitions - // a comment (or @media statement) before the actual @charset directive would - // be considered illegal css as it has to be on the first line - if (this.charset) { - if (directiveNode.debugInfo) { - var comment = new tree.Comment("/* " + directiveNode.toCSS(this._env).replace(/\n/g, "") + " */\n"); - comment.debugInfo = directiveNode.debugInfo; - return this._visitor.visit(comment); - } - return []; - } - this.charset = true; - } - if (directiveNode.rules && directiveNode.rules.rules) { - this._mergeRules(directiveNode.rules.rules); - } - return directiveNode; - }, - - checkPropertiesInRoot: function (rules) { - var ruleNode; - for (var i = 0; i < rules.length; i++) { - ruleNode = rules[i]; - if (ruleNode instanceof tree.Rule && !ruleNode.variable) { - throw { - message: "properties must be inside selector blocks, they cannot be in the root.", - index: ruleNode.index, - filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null - }; - } - } - }, - - visitRuleset: function (rulesetNode, visitArgs) { - var rule, rulesets = []; - if (rulesetNode.firstRoot) { - this.checkPropertiesInRoot(rulesetNode.rules); - } - if (!rulesetNode.root) { - if (rulesetNode.paths) { - rulesetNode.paths = rulesetNode.paths - .filter(function (p) { - var i; - if (p[0].elements[0].combinator.value === ' ') { - p[0].elements[0].combinator = new (tree.Combinator)(''); - } - for (i = 0; i < p.length; i++) { - if (p[i].getIsReferenced() && p[i].getIsOutput()) { - return true; - } - } - return false; - }); - } - - // Compile rules and rulesets - var nodeRules = rulesetNode.rules, nodeRuleCnt = nodeRules ? nodeRules.length : 0; - for (var i = 0; i < nodeRuleCnt;) { - rule = nodeRules[i]; - if (rule && rule.rules) { - // visit because we are moving them out from being a child - rulesets.push(this._visitor.visit(rule)); - nodeRules.splice(i, 1); - nodeRuleCnt--; - continue; - } - i++; - } - // accept the visitor to remove rules and refactor itself - // then we can decide now whether we want it or not - if (nodeRuleCnt > 0) { - rulesetNode.accept(this._visitor); - } else { - rulesetNode.rules = null; - } - visitArgs.visitDeeper = false; - - nodeRules = rulesetNode.rules; - if (nodeRules) { - this._mergeRules(nodeRules); - nodeRules = rulesetNode.rules; - } - if (nodeRules) { - this._removeDuplicateRules(nodeRules); - nodeRules = rulesetNode.rules; - } - - // now decide whether we keep the ruleset - if (nodeRules && nodeRules.length > 0 && rulesetNode.paths.length > 0) { - rulesets.splice(0, 0, rulesetNode); - } - } else { - rulesetNode.accept(this._visitor); - visitArgs.visitDeeper = false; - if (rulesetNode.firstRoot || (rulesetNode.rules && rulesetNode.rules.length > 0)) { - rulesets.splice(0, 0, rulesetNode); - } - } - if (rulesets.length === 1) { - return rulesets[0]; - } - return rulesets; - }, - - _removeDuplicateRules: function (rules) { - if (!rules) { - return; - } - - // remove duplicates - var ruleCache = {}, - ruleList, rule, i; - - for (i = rules.length - 1; i >= 0; i--) { - rule = rules[i]; - if (rule instanceof tree.Rule) { - if (!ruleCache[rule.name]) { - ruleCache[rule.name] = rule; - } else { - ruleList = ruleCache[rule.name]; - if (ruleList instanceof tree.Rule) { - ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._env)]; - } - var ruleCSS = rule.toCSS(this._env); - if (ruleList.indexOf(ruleCSS) !== -1) { - rules.splice(i, 1); - } else { - ruleList.push(ruleCSS); - } - } - } - } - }, - - _mergeRules: function (rules) { - if (!rules) { - return; - } - - var groups = {}, - parts, - rule, - key; - - for (var i = 0; i < rules.length; i++) { - rule = rules[i]; - - if ((rule instanceof tree.Rule) && rule.merge) { - key = [rule.name, - rule.important ? "!" : ""].join(","); - - if (!groups[key]) { - groups[key] = []; - } else { - rules.splice(i--, 1); - } - - groups[key].push(rule); - } - } - - Object.keys(groups).map(function (k) { - - function toExpression(values) { - return new (tree.Expression)(values.map(function (p) { - return p.value; - })); - } - - function toValue(values) { - return new (tree.Value)(values.map(function (p) { - return p; - })); - } - - parts = groups[k]; - - if (parts.length > 1) { - rule = parts[0]; - var spacedGroups = []; - var lastSpacedGroup = []; - parts.map(function (p) { - if (p.merge === "+") { - if (lastSpacedGroup.length > 0) { - spacedGroups.push(toExpression(lastSpacedGroup)); - } - lastSpacedGroup = []; - } - lastSpacedGroup.push(p); - }); - spacedGroups.push(toExpression(lastSpacedGroup)); - rule.value = toValue(spacedGroups); - } - }); - } - }; - -})(require('./tree')); -(function (tree) { - /*jshint loopfunc:true */ - - tree.extendFinderVisitor = function () { - this._visitor = new tree.visitor(this); - this.contexts = []; - this.allExtendsStack = [[]]; - }; - - tree.extendFinderVisitor.prototype = { - run: function (root) { - root = this._visitor.visit(root); - root.allExtends = this.allExtendsStack[0]; - return root; - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitRuleset: function (rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - - var i, j, extend, allSelectorsExtendList = [], extendList; - - // get &:extend(.a); rules which apply to all selectors in this ruleset - var rules = rulesetNode.rules, ruleCnt = rules ? rules.length : 0; - for (i = 0; i < ruleCnt; i++) { - if (rulesetNode.rules[i] instanceof tree.Extend) { - allSelectorsExtendList.push(rules[i]); - rulesetNode.extendOnEveryPath = true; - } - } - - // now find every selector and apply the extends that apply to all extends - // and the ones which apply to an individual extend - var paths = rulesetNode.paths; - for (i = 0; i < paths.length; i++) { - var selectorPath = paths[i], - selector = selectorPath[selectorPath.length - 1], - selExtendList = selector.extendList; - - extendList = selExtendList ? selExtendList.slice(0).concat(allSelectorsExtendList) - : allSelectorsExtendList; - - if (extendList) { - extendList = extendList.map(function (allSelectorsExtend) { - return allSelectorsExtend.clone(); - }); - } - - for (j = 0; j < extendList.length; j++) { - this.foundExtends = true; - extend = extendList[j]; - extend.findSelfSelectors(selectorPath); - extend.ruleset = rulesetNode; - if (j === 0) { - extend.firstExtendOnThisSelectorPath = true; - } - this.allExtendsStack[this.allExtendsStack.length - 1].push(extend); - } - } - - this.contexts.push(rulesetNode.selectors); - }, - visitRulesetOut: function (rulesetNode) { - if (!rulesetNode.root) { - this.contexts.length = this.contexts.length - 1; - } - }, - visitMedia: function (mediaNode, visitArgs) { - mediaNode.allExtends = []; - this.allExtendsStack.push(mediaNode.allExtends); - }, - visitMediaOut: function (mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - }, - visitDirective: function (directiveNode, visitArgs) { - directiveNode.allExtends = []; - this.allExtendsStack.push(directiveNode.allExtends); - }, - visitDirectiveOut: function (directiveNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }; - - tree.processExtendsVisitor = function () { - this._visitor = new tree.visitor(this); - }; - - tree.processExtendsVisitor.prototype = { - run: function (root) { - var extendFinder = new tree.extendFinderVisitor(); - extendFinder.run(root); - if (!extendFinder.foundExtends) { - return root; - } - root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); - this.allExtendsStack = [root.allExtends]; - return this._visitor.visit(root); - }, - doExtendChaining: function (extendsList, extendsListTarget, iterationCount) { - // - // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering and pasting - // the selector we would do normally, but we are also adding an extend with the same target selector - // this means this new extend can then go and alter other extends - // - // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors - // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already processed if - // we look at each selector at a time, as is done in visitRuleset - - var extendIndex, targetExtendIndex, matches, extendsToAdd = [], newSelector, extendVisitor = this, selectorPath, extend, targetExtend, newExtend; - - iterationCount = iterationCount || 0; - - //loop through comparing every extend with every target extend. - // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place - // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one - // and the second is the target. - // the seperation into two lists allows us to process a subset of chains with a bigger set, as is the - // case when processing media queries - for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) { - for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) { - - extend = extendsList[extendIndex]; - targetExtend = extendsListTarget[targetExtendIndex]; - - // look for circular references - if (extend.parent_ids.indexOf(targetExtend.object_id) >= 0) { - continue; - } - - // find a match in the target extends self selector (the bit before :extend) - selectorPath = [targetExtend.selfSelectors[0]]; - matches = extendVisitor.findMatch(extend, selectorPath); - - if (matches.length) { - - // we found a match, so for each self selector.. - extend.selfSelectors.forEach(function (selfSelector) { - - // process the extend as usual - newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector); - - // but now we create a new extend from it - newExtend = new (tree.Extend)(targetExtend.selector, targetExtend.option, 0); - newExtend.selfSelectors = newSelector; - - // add the extend onto the list of extends for that selector - newSelector[newSelector.length - 1].extendList = [newExtend]; - - // record that we need to add it. - extendsToAdd.push(newExtend); - newExtend.ruleset = targetExtend.ruleset; - - //remember its parents for circular references - newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids); - - // only process the selector once.. if we have :extend(.a,.b) then multiple - // extends will look at the same selector path, so when extending - // we know that any others will be duplicates in terms of what is added to the css - if (targetExtend.firstExtendOnThisSelectorPath) { - newExtend.firstExtendOnThisSelectorPath = true; - targetExtend.ruleset.paths.push(newSelector); - } - }); - } - } - } - - if (extendsToAdd.length) { - // try to detect circular references to stop a stack overflow. - // may no longer be needed. - this.extendChainCount++; - if (iterationCount > 100) { - var selectorOne = "{unable to calculate}"; - var selectorTwo = "{unable to calculate}"; - try { - selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); - selectorTwo = extendsToAdd[0].selector.toCSS(); - } - catch (e) { - } - throw {message: "extend circular reference detected. One of the circular extends is currently:" + selectorOne + ":extend(" + selectorTwo + ")"}; - } - - // now process the new extends on the existing rules so that we can handle a extending b extending c ectending d extending e... - return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1)); - } else { - return extendsToAdd; - } - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitSelector: function (selectorNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitRuleset: function (rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - var matches, pathIndex, extendIndex, allExtends = this.allExtendsStack[this.allExtendsStack.length - 1], selectorsToAdd = [], extendVisitor = this, selectorPath; - - // look at each selector path in the ruleset, find any extend matches and then copy, find and replace - - for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { - for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { - selectorPath = rulesetNode.paths[pathIndex]; - - // extending extends happens initially, before the main pass - if (rulesetNode.extendOnEveryPath) { - continue; - } - var extendList = selectorPath[selectorPath.length - 1].extendList; - if (extendList && extendList.length) { - continue; - } - - matches = this.findMatch(allExtends[extendIndex], selectorPath); - - if (matches.length) { - - allExtends[extendIndex].selfSelectors.forEach(function (selfSelector) { - selectorsToAdd.push(extendVisitor.extendSelector(matches, selectorPath, selfSelector)); - }); - } - } - } - rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); - }, - findMatch: function (extend, haystackSelectorPath) { - // - // look through the haystack selector path to try and find the needle - extend.selector - // returns an array of selector matches that can then be replaced - // - var haystackSelectorIndex, hackstackSelector, hackstackElementIndex, haystackElement, - targetCombinator, i, - extendVisitor = this, - needleElements = extend.selector.elements, - potentialMatches = [], potentialMatch, matches = []; - - // loop through the haystack elements - for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { - hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; - - for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { - - haystackElement = hackstackSelector.elements[hackstackElementIndex]; - - // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. - if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) { - potentialMatches.push({ - pathIndex: haystackSelectorIndex, - index: hackstackElementIndex, - matched: 0, - initialCombinator: haystackElement.combinator - }); - } - - for (i = 0; i < potentialMatches.length; i++) { - potentialMatch = potentialMatches[i]; - - // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't - // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to work out - // what the resulting combinator will be - targetCombinator = haystackElement.combinator.value; - if (targetCombinator === '' && hackstackElementIndex === 0) { - targetCombinator = ' '; - } - - // if we don't match, null our match to indicate failure - if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || - (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) { - potentialMatch = null; - } else { - potentialMatch.matched++; - } - - // if we are still valid and have finished, test whether we have elements after and whether these are allowed - if (potentialMatch) { - potentialMatch.finished = potentialMatch.matched === needleElements.length; - if (potentialMatch.finished && - (!extend.allowAfter && (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length))) { - potentialMatch = null; - } - } - // if null we remove, if not, we are still valid, so either push as a valid match or continue - if (potentialMatch) { - if (potentialMatch.finished) { - potentialMatch.length = needleElements.length; - potentialMatch.endPathIndex = haystackSelectorIndex; - potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match - potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again - matches.push(potentialMatch); - } - } else { - potentialMatches.splice(i, 1); - i--; - } - } - } - } - return matches; - }, - isElementValuesEqual: function (elementValue1, elementValue2) { - if (typeof elementValue1 === "string" || typeof elementValue2 === "string") { - return elementValue1 === elementValue2; - } - if (elementValue1 instanceof tree.Attribute) { - if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { - return false; - } - if (!elementValue1.value || !elementValue2.value) { - if (elementValue1.value || elementValue2.value) { - return false; - } - return true; - } - elementValue1 = elementValue1.value.value || elementValue1.value; - elementValue2 = elementValue2.value.value || elementValue2.value; - return elementValue1 === elementValue2; - } - elementValue1 = elementValue1.value; - elementValue2 = elementValue2.value; - if (elementValue1 instanceof tree.Selector) { - if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { - return false; - } - for (var i = 0; i < elementValue1.elements.length; i++) { - if (elementValue1.elements[i].combinator.value !== elementValue2.elements[i].combinator.value) { - if (i !== 0 || (elementValue1.elements[i].combinator.value || ' ') !== (elementValue2.elements[i].combinator.value || ' ')) { - return false; - } - } - if (!this.isElementValuesEqual(elementValue1.elements[i].value, elementValue2.elements[i].value)) { - return false; - } - } - return true; - } - return false; - }, - extendSelector: function (matches, selectorPath, replacementSelector) { - - //for a set of matches, replace each match with the replacement selector - - var currentSelectorPathIndex = 0, - currentSelectorPathElementIndex = 0, - path = [], - matchIndex, - selector, - firstElement, - match, - newElements; - - for (matchIndex = 0; matchIndex < matches.length; matchIndex++) { - match = matches[matchIndex]; - selector = selectorPath[match.pathIndex]; - firstElement = new tree.Element( - match.initialCombinator, - replacementSelector.elements[0].value, - replacementSelector.elements[0].index, - replacementSelector.elements[0].currentFileInfo - ); - - if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; - } - - newElements = selector.elements - .slice(currentSelectorPathElementIndex, match.index) - .concat([firstElement]) - .concat(replacementSelector.elements.slice(1)); - - if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { - path[path.length - 1].elements = - path[path.length - 1].elements.concat(newElements); - } else { - path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); - - path.push(new tree.Selector( - newElements - )); - } - currentSelectorPathIndex = match.endPathIndex; - currentSelectorPathElementIndex = match.endPathElementIndex; - if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; - } - } - - if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathIndex++; - } - - path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); - - return path; - }, - visitRulesetOut: function (rulesetNode) { - }, - visitMedia: function (mediaNode, visitArgs) { - var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - }, - visitMediaOut: function (mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - }, - visitDirective: function (directiveNode, visitArgs) { - var newAllExtends = directiveNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, directiveNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - }, - visitDirectiveOut: function (directiveNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }; - -})(require('./tree')); - -(function (tree) { - - tree.sourceMapOutput = function (options) { - this._css = []; - this._rootNode = options.rootNode; - this._writeSourceMap = options.writeSourceMap; - this._contentsMap = options.contentsMap; - this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap; - this._sourceMapFilename = options.sourceMapFilename; - this._outputFilename = options.outputFilename; - this._sourceMapURL = options.sourceMapURL; - if (options.sourceMapBasepath) { - this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/'); - } - this._sourceMapRootpath = options.sourceMapRootpath; - this._outputSourceFiles = options.outputSourceFiles; - this._sourceMapGeneratorConstructor = options.sourceMapGenerator || require("source-map").SourceMapGenerator; - - if (this._sourceMapRootpath && this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') { - this._sourceMapRootpath += '/'; - } - - this._lineNumber = 0; - this._column = 0; - }; - - tree.sourceMapOutput.prototype.normalizeFilename = function (filename) { - filename = filename.replace(/\\/g, '/'); - - if (this._sourceMapBasepath && filename.indexOf(this._sourceMapBasepath) === 0) { - filename = filename.substring(this._sourceMapBasepath.length); - if (filename.charAt(0) === '\\' || filename.charAt(0) === '/') { - filename = filename.substring(1); - } - } - return (this._sourceMapRootpath || "") + filename; - }; - - tree.sourceMapOutput.prototype.add = function (chunk, fileInfo, index, mapLines) { - - //ignore adding empty strings - if (!chunk) { - return; - } - - var lines, - sourceLines, - columns, - sourceColumns, - i; - - if (fileInfo) { - var inputSource = this._contentsMap[fileInfo.filename]; - - // remove vars/banner added to the top of the file - if (this._contentsIgnoredCharsMap[fileInfo.filename]) { - // adjust the index - index -= this._contentsIgnoredCharsMap[fileInfo.filename]; - if (index < 0) { - index = 0; - } - // adjust the source - inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]); - } - inputSource = inputSource.substring(0, index); - sourceLines = inputSource.split("\n"); - sourceColumns = sourceLines[sourceLines.length - 1]; - } - - lines = chunk.split("\n"); - columns = lines[lines.length - 1]; - - if (fileInfo) { - if (!mapLines) { - this._sourceMapGenerator.addMapping({ - generated: {line: this._lineNumber + 1, column: this._column}, - original: {line: sourceLines.length, column: sourceColumns.length}, - source: this.normalizeFilename(fileInfo.filename) - }); - } else { - for (i = 0; i < lines.length; i++) { - this._sourceMapGenerator.addMapping({ - generated: {line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0}, - original: {line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0}, - source: this.normalizeFilename(fileInfo.filename) - }); - } - } - } - - if (lines.length === 1) { - this._column += columns.length; - } else { - this._lineNumber += lines.length - 1; - this._column = columns.length; - } - - this._css.push(chunk); - }; - - tree.sourceMapOutput.prototype.isEmpty = function () { - return this._css.length === 0; - }; - - tree.sourceMapOutput.prototype.toCSS = function (env) { - this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ - file: this._outputFilename, - sourceRoot: null - }); - - if (this._outputSourceFiles) { - for (var filename in this._contentsMap) { - if (this._contentsMap.hasOwnProperty(filename)) { - var source = this._contentsMap[filename]; - if (this._contentsIgnoredCharsMap[filename]) { - source = source.slice(this._contentsIgnoredCharsMap[filename]); - } - this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source); - } - } - } - - this._rootNode.genCSS(env, this); - - if (this._css.length > 0) { - var sourceMapURL, - sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); - - if (this._sourceMapURL) { - sourceMapURL = this._sourceMapURL; - } else if (this._sourceMapFilename) { - sourceMapURL = this.normalizeFilename(this._sourceMapFilename); - } - - if (this._writeSourceMap) { - this._writeSourceMap(sourceMapContent); - } else { - sourceMapURL = "data:application/json;base64," + require('./encoder.js').encodeBase64(sourceMapContent); - } - - if (sourceMapURL) { - this._css.push("/*# sourceMappingURL=" + sourceMapURL + " */"); - } - } - - return this._css.join(''); - }; - -})(require('./tree')); - -// wraps the source-map code in a less module -(function () { - less.modules["source-map"] = function () { - - /* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ - - /** - * Define a module along with a payload. - * @param {string} moduleName Name for the payload - * @param {ignored} deps Ignored. For compatibility with CommonJS AMD Spec - * @param {function} payload Function with (require, exports, module) params - */ - function define(moduleName, deps, payload) { - if (typeof moduleName != "string") { - throw new TypeError('Expected string, got: ' + moduleName); - } - - if (arguments.length == 2) { - payload = deps; - } - - if (moduleName in define.modules) { - throw new Error("Module already defined: " + moduleName); - } - define.modules[moduleName] = payload; - }; - - /** - * The global store of un-instantiated modules - */ - define.modules = {}; - - - /** - * We invoke require() in the context of a Domain so we can have multiple - * sets of modules running separate from each other. - * This contrasts with JSMs which are singletons, Domains allows us to - * optionally load a CommonJS module twice with separate data each time. - * Perhaps you want 2 command lines with a different set of commands in each, - * for example. - */ - function Domain() { - this.modules = {}; - this._currentModule = null; - } - - (function () { - - /** - * Lookup module names and resolve them by calling the definition function if - * needed. - * There are 2 ways to call this, either with an array of dependencies and a - * callback to call when the dependencies are found (which can happen - * asynchronously in an in-page context) or with a single string an no callback - * where the dependency is resolved synchronously and returned. - * The API is designed to be compatible with the CommonJS AMD spec and - * RequireJS. - * @param {string[]|string} deps A name, or names for the payload - * @param {function|undefined} callback Function to call when the dependencies - * are resolved - * @return {undefined|object} The module required or undefined for - * array/callback method - */ - Domain.prototype.require = function (deps, callback) { - if (Array.isArray(deps)) { - var params = deps.map(function (dep) { - return this.lookup(dep); - }, this); - if (callback) { - callback.apply(null, params); - } - return undefined; - } - else { - return this.lookup(deps); - } - }; - - function normalize(path) { - var bits = path.split('/'); - var i = 1; - while (i < bits.length) { - if (bits[i] === '..') { - bits.splice(i - 1, 1); - } else if (bits[i] === '.') { - bits.splice(i, 1); - } else { - i++; - } - } - return bits.join('/'); - } - - function join(a, b) { - a = a.trim(); - b = b.trim(); - if (/^\//.test(b)) { - return b; - } else { - return a.replace(/\/*$/, '/') + b; - } - } - - function dirname(path) { - var bits = path.split('/'); - bits.pop(); - return bits.join('/'); - } - - /** - * Lookup module names and resolve them by calling the definition function if - * needed. - * @param {string} moduleName A name for the payload to lookup - * @return {object} The module specified by aModuleName or null if not found. - */ - Domain.prototype.lookup = function (moduleName) { - if (/^\./.test(moduleName)) { - moduleName = normalize(join(dirname(this._currentModule), moduleName)); - } - - if (moduleName in this.modules) { - var module = this.modules[moduleName]; - return module; - } - - if (!(moduleName in define.modules)) { - throw new Error("Module not defined: " + moduleName); - } - - var module = define.modules[moduleName]; - - if (typeof module == "function") { - var exports = {}; - var previousModule = this._currentModule; - this._currentModule = moduleName; - module(this.require.bind(this), exports, {id: moduleName, uri: ""}); - this._currentModule = previousModule; - module = exports; - } - - // cache the resulting module object for next time - this.modules[moduleName] = module; - - return module; - }; - - }()); - - define.Domain = Domain; - define.globalDomain = new Domain(); - var require = define.globalDomain.require.bind(define.globalDomain); - /* -*- Mode: js; js-indent-level: 2; -*- */ - /* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ - define('source-map/source-map-generator', ['require', 'exports', 'module', 'source-map/base64-vlq', 'source-map/util', 'source-map/array-set'], function (require, exports, module) { - - var base64VLQ = require('./base64-vlq'); - var util = require('./util'); - var ArraySet = require('./array-set').ArraySet; - - /** - * An instance of the SourceMapGenerator represents a source map which is - * being built incrementally. To create a new one, you must pass an object - * with the following properties: - * - * - file: The filename of the generated source. - * - sourceRoot: An optional root for all URLs in this source map. - */ - function SourceMapGenerator(aArgs) { - this._file = util.getArg(aArgs, 'file'); - this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); - this._sources = new ArraySet(); - this._names = new ArraySet(); - this._mappings = []; - this._sourcesContents = null; - } - - SourceMapGenerator.prototype._version = 3; - - /** - * Creates a new SourceMapGenerator based on a SourceMapConsumer - * - * @param aSourceMapConsumer The SourceMap. - */ - SourceMapGenerator.fromSourceMap = - function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { - var sourceRoot = aSourceMapConsumer.sourceRoot; - var generator = new SourceMapGenerator({ - file: aSourceMapConsumer.file, - sourceRoot: sourceRoot - }); - aSourceMapConsumer.eachMapping(function (mapping) { - var newMapping = { - generated: { - line: mapping.generatedLine, - column: mapping.generatedColumn - } - }; - - if (mapping.source) { - newMapping.source = mapping.source; - if (sourceRoot) { - newMapping.source = util.relative(sourceRoot, newMapping.source); - } - - newMapping.original = { - line: mapping.originalLine, - column: mapping.originalColumn - }; - - if (mapping.name) { - newMapping.name = mapping.name; - } - } - - generator.addMapping(newMapping); - }); - aSourceMapConsumer.sources.forEach(function (sourceFile) { - var content = aSourceMapConsumer.sourceContentFor(sourceFile); - if (content) { - generator.setSourceContent(sourceFile, content); - } - }); - return generator; - }; - - /** - * Add a single mapping from original source line and column to the generated - * source's line and column for this source map being created. The mapping - * object should have the following properties: - * - * - generated: An object with the generated line and column positions. - * - original: An object with the original line and column positions. - * - source: The original source file (relative to the sourceRoot). - * - name: An optional original token name for this mapping. - */ - SourceMapGenerator.prototype.addMapping = - function SourceMapGenerator_addMapping(aArgs) { - var generated = util.getArg(aArgs, 'generated'); - var original = util.getArg(aArgs, 'original', null); - var source = util.getArg(aArgs, 'source', null); - var name = util.getArg(aArgs, 'name', null); - - this._validateMapping(generated, original, source, name); - - if (source && !this._sources.has(source)) { - this._sources.add(source); - } - - if (name && !this._names.has(name)) { - this._names.add(name); - } - - this._mappings.push({ - generatedLine: generated.line, - generatedColumn: generated.column, - originalLine: original != null && original.line, - originalColumn: original != null && original.column, - source: source, - name: name - }); - }; - - /** - * Set the source content for a source file. - */ - SourceMapGenerator.prototype.setSourceContent = - function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { - var source = aSourceFile; - if (this._sourceRoot) { - source = util.relative(this._sourceRoot, source); - } - - if (aSourceContent !== null) { - // Add the source content to the _sourcesContents map. - // Create a new _sourcesContents map if the property is null. - if (!this._sourcesContents) { - this._sourcesContents = {}; - } - this._sourcesContents[util.toSetString(source)] = aSourceContent; - } else { - // Remove the source file from the _sourcesContents map. - // If the _sourcesContents map is empty, set the property to null. - delete this._sourcesContents[util.toSetString(source)]; - if (Object.keys(this._sourcesContents).length === 0) { - this._sourcesContents = null; - } - } - }; - - /** - * Applies the mappings of a sub-source-map for a specific source file to the - * source map being generated. Each mapping to the supplied source file is - * rewritten using the supplied source map. Note: The resolution for the - * resulting mappings is the minimium of this map and the supplied map. - * - * @param aSourceMapConsumer The source map to be applied. - * @param aSourceFile Optional. The filename of the source file. - * If omitted, SourceMapConsumer's file property will be used. - */ - SourceMapGenerator.prototype.applySourceMap = - function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile) { - // If aSourceFile is omitted, we will use the file property of the SourceMap - if (!aSourceFile) { - aSourceFile = aSourceMapConsumer.file; - } - var sourceRoot = this._sourceRoot; - // Make "aSourceFile" relative if an absolute Url is passed. - if (sourceRoot) { - aSourceFile = util.relative(sourceRoot, aSourceFile); - } - // Applying the SourceMap can add and remove items from the sources and - // the names array. - var newSources = new ArraySet(); - var newNames = new ArraySet(); - - // Find mappings for the "aSourceFile" - this._mappings.forEach(function (mapping) { - if (mapping.source === aSourceFile && mapping.originalLine) { - // Check if it can be mapped by the source map, then update the mapping. - var original = aSourceMapConsumer.originalPositionFor({ - line: mapping.originalLine, - column: mapping.originalColumn - }); - if (original.source !== null) { - // Copy mapping - if (sourceRoot) { - mapping.source = util.relative(sourceRoot, original.source); - } else { - mapping.source = original.source; - } - mapping.originalLine = original.line; - mapping.originalColumn = original.column; - if (original.name !== null && mapping.name !== null) { - // Only use the identifier name if it's an identifier - // in both SourceMaps - mapping.name = original.name; - } - } - } - - var source = mapping.source; - if (source && !newSources.has(source)) { - newSources.add(source); - } - - var name = mapping.name; - if (name && !newNames.has(name)) { - newNames.add(name); - } - - }, this); - this._sources = newSources; - this._names = newNames; - - // Copy sourcesContents of applied map. - aSourceMapConsumer.sources.forEach(function (sourceFile) { - var content = aSourceMapConsumer.sourceContentFor(sourceFile); - if (content) { - if (sourceRoot) { - sourceFile = util.relative(sourceRoot, sourceFile); - } - this.setSourceContent(sourceFile, content); - } - }, this); - }; - - /** - * A mapping can have one of the three levels of data: - * - * 1. Just the generated position. - * 2. The Generated position, original position, and original source. - * 3. Generated and original position, original source, as well as a name - * token. - * - * To maintain consistency, we validate that any new mapping being added falls - * in to one of these categories. - */ - SourceMapGenerator.prototype._validateMapping = - function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, - aName) { - if (aGenerated && 'line' in aGenerated && 'column' in aGenerated - && aGenerated.line > 0 && aGenerated.column >= 0 - && !aOriginal && !aSource && !aName) { - // Case 1. - return; - } - else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated - && aOriginal && 'line' in aOriginal && 'column' in aOriginal - && aGenerated.line > 0 && aGenerated.column >= 0 - && aOriginal.line > 0 && aOriginal.column >= 0 - && aSource) { - // Cases 2 and 3. - return; - } - else { - throw new Error('Invalid mapping: ' + JSON.stringify({ - generated: aGenerated, - source: aSource, - original: aOriginal, - name: aName - })); - } - }; - - /** - * Serialize the accumulated mappings in to the stream of base 64 VLQs - * specified by the source map format. - */ - SourceMapGenerator.prototype._serializeMappings = - function SourceMapGenerator_serializeMappings() { - var previousGeneratedColumn = 0; - var previousGeneratedLine = 1; - var previousOriginalColumn = 0; - var previousOriginalLine = 0; - var previousName = 0; - var previousSource = 0; - var result = ''; - var mapping; - - // The mappings must be guaranteed to be in sorted order before we start - // serializing them or else the generated line numbers (which are defined - // via the ';' separators) will be all messed up. Note: it might be more - // performant to maintain the sorting as we insert them, rather than as we - // serialize them, but the big O is the same either way. - this._mappings.sort(util.compareByGeneratedPositions); - - for (var i = 0, len = this._mappings.length; i < len; i++) { - mapping = this._mappings[i]; - - if (mapping.generatedLine !== previousGeneratedLine) { - previousGeneratedColumn = 0; - while (mapping.generatedLine !== previousGeneratedLine) { - result += ';'; - previousGeneratedLine++; - } - } - else { - if (i > 0) { - if (!util.compareByGeneratedPositions(mapping, this._mappings[i - 1])) { - continue; - } - result += ','; - } - } - - result += base64VLQ.encode(mapping.generatedColumn - - previousGeneratedColumn); - previousGeneratedColumn = mapping.generatedColumn; - - if (mapping.source) { - result += base64VLQ.encode(this._sources.indexOf(mapping.source) - - previousSource); - previousSource = this._sources.indexOf(mapping.source); - - // lines are stored 0-based in SourceMap spec version 3 - result += base64VLQ.encode(mapping.originalLine - 1 - - previousOriginalLine); - previousOriginalLine = mapping.originalLine - 1; - - result += base64VLQ.encode(mapping.originalColumn - - previousOriginalColumn); - previousOriginalColumn = mapping.originalColumn; - - if (mapping.name) { - result += base64VLQ.encode(this._names.indexOf(mapping.name) - - previousName); - previousName = this._names.indexOf(mapping.name); - } - } - } - - return result; - }; - - SourceMapGenerator.prototype._generateSourcesContent = - function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { - return aSources.map(function (source) { - if (!this._sourcesContents) { - return null; - } - if (aSourceRoot) { - source = util.relative(aSourceRoot, source); - } - var key = util.toSetString(source); - return Object.prototype.hasOwnProperty.call(this._sourcesContents, - key) - ? this._sourcesContents[key] - : null; - }, this); - }; - - /** - * Externalize the source map. - */ - SourceMapGenerator.prototype.toJSON = - function SourceMapGenerator_toJSON() { - var map = { - version: this._version, - file: this._file, - sources: this._sources.toArray(), - names: this._names.toArray(), - mappings: this._serializeMappings() - }; - if (this._sourceRoot) { - map.sourceRoot = this._sourceRoot; - } - if (this._sourcesContents) { - map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); - } - - return map; - }; - - /** - * Render the source map being generated to a string. - */ - SourceMapGenerator.prototype.toString = - function SourceMapGenerator_toString() { - return JSON.stringify(this); - }; - - exports.SourceMapGenerator = SourceMapGenerator; - - }); - /* -*- Mode: js; js-indent-level: 2; -*- */ - /* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - * - * Based on the Base 64 VLQ implementation in Closure Compiler: - * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java - * - * Copyright 2011 The Closure Compiler Authors. All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - define('source-map/base64-vlq', ['require', 'exports', 'module', 'source-map/base64'], function (require, exports, module) { - - var base64 = require('./base64'); - - // A single base 64 digit can contain 6 bits of data. For the base 64 variable - // length quantities we use in the source map spec, the first bit is the sign, - // the next four bits are the actual value, and the 6th bit is the - // continuation bit. The continuation bit tells us whether there are more - // digits in this value following this digit. - // - // Continuation - // | Sign - // | | - // V V - // 101011 - - var VLQ_BASE_SHIFT = 5; - - // binary: 100000 - var VLQ_BASE = 1 << VLQ_BASE_SHIFT; - - // binary: 011111 - var VLQ_BASE_MASK = VLQ_BASE - 1; - - // binary: 100000 - var VLQ_CONTINUATION_BIT = VLQ_BASE; - - /** - * Converts from a two-complement value to a value where the sign bit is - * is placed in the least significant bit. For example, as decimals: - * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) - * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) - */ - function toVLQSigned(aValue) { - return aValue < 0 - ? ((-aValue) << 1) + 1 - : (aValue << 1) + 0; - } - - /** - * Converts to a two-complement value from a value where the sign bit is - * is placed in the least significant bit. For example, as decimals: - * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 - * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 - */ - function fromVLQSigned(aValue) { - var isNegative = (aValue & 1) === 1; - var shifted = aValue >> 1; - return isNegative - ? -shifted - : shifted; - } - - /** - * Returns the base 64 VLQ encoded value. - */ - exports.encode = function base64VLQ_encode(aValue) { - var encoded = ""; - var digit; - - var vlq = toVLQSigned(aValue); - - do { - digit = vlq & VLQ_BASE_MASK; - vlq >>>= VLQ_BASE_SHIFT; - if (vlq > 0) { - // There are still more digits in this value, so we must make sure the - // continuation bit is marked. - digit |= VLQ_CONTINUATION_BIT; - } - encoded += base64.encode(digit); - } while (vlq > 0); - - return encoded; - }; - - /** - * Decodes the next base 64 VLQ value from the given string and returns the - * value and the rest of the string. - */ - exports.decode = function base64VLQ_decode(aStr) { - var i = 0; - var strLen = aStr.length; - var result = 0; - var shift = 0; - var continuation, digit; - - do { - if (i >= strLen) { - throw new Error("Expected more digits in base 64 VLQ value."); - } - digit = base64.decode(aStr.charAt(i++)); - continuation = !!(digit & VLQ_CONTINUATION_BIT); - digit &= VLQ_BASE_MASK; - result = result + (digit << shift); - shift += VLQ_BASE_SHIFT; - } while (continuation); - - return { - value: fromVLQSigned(result), - rest: aStr.slice(i) - }; - }; - - }); - /* -*- Mode: js; js-indent-level: 2; -*- */ - /* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ - define('source-map/base64', ['require', 'exports', 'module',], function (require, exports, module) { - - var charToIntMap = {}; - var intToCharMap = {}; - - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - .split('') - .forEach(function (ch, index) { - charToIntMap[ch] = index; - intToCharMap[index] = ch; - }); - - /** - * Encode an integer in the range of 0 to 63 to a single base 64 digit. - */ - exports.encode = function base64_encode(aNumber) { - if (aNumber in intToCharMap) { - return intToCharMap[aNumber]; - } - throw new TypeError("Must be between 0 and 63: " + aNumber); - }; - - /** - * Decode a single base 64 digit to an integer. - */ - exports.decode = function base64_decode(aChar) { - if (aChar in charToIntMap) { - return charToIntMap[aChar]; - } - throw new TypeError("Not a valid base 64 digit: " + aChar); - }; - - }); - /* -*- Mode: js; js-indent-level: 2; -*- */ - /* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ - define('source-map/util', ['require', 'exports', 'module',], function (require, exports, module) { - - /** - * This is a helper function for getting values from parameter/options - * objects. - * - * @param args The object we are extracting values from - * @param name The name of the property we are getting. - * @param defaultValue An optional value to return if the property is missing - * from the object. If this is not specified and the property is missing, an - * error will be thrown. - */ - function getArg(aArgs, aName, aDefaultValue) { - if (aName in aArgs) { - return aArgs[aName]; - } else if (arguments.length === 3) { - return aDefaultValue; - } else { - throw new Error('"' + aName + '" is a required argument.'); - } - } - - exports.getArg = getArg; - - var urlRegexp = /([\w+\-.]+):\/\/((\w+:\w+)@)?([\w.]+)?(:(\d+))?(\S+)?/; - var dataUrlRegexp = /^data:.+\,.+/; - - function urlParse(aUrl) { - var match = aUrl.match(urlRegexp); - if (!match) { - return null; - } - return { - scheme: match[1], - auth: match[3], - host: match[4], - port: match[6], - path: match[7] - }; - } - - exports.urlParse = urlParse; - - function urlGenerate(aParsedUrl) { - var url = aParsedUrl.scheme + "://"; - if (aParsedUrl.auth) { - url += aParsedUrl.auth + "@" - } - if (aParsedUrl.host) { - url += aParsedUrl.host; - } - if (aParsedUrl.port) { - url += ":" + aParsedUrl.port - } - if (aParsedUrl.path) { - url += aParsedUrl.path; - } - return url; - } - - exports.urlGenerate = urlGenerate; - - function join(aRoot, aPath) { - var url; - - if (aPath.match(urlRegexp) || aPath.match(dataUrlRegexp)) { - return aPath; - } - - if (aPath.charAt(0) === '/' && (url = urlParse(aRoot))) { - url.path = aPath; - return urlGenerate(url); - } - - return aRoot.replace(/\/$/, '') + '/' + aPath; - } - - exports.join = join; - - /** - * Because behavior goes wacky when you set `__proto__` on objects, we - * have to prefix all the strings in our set with an arbitrary character. - * - * See https://github.com/mozilla/source-map/pull/31 and - * https://github.com/mozilla/source-map/issues/30 - * - * @param String aStr - */ - function toSetString(aStr) { - return '$' + aStr; - } - - exports.toSetString = toSetString; - - function fromSetString(aStr) { - return aStr.substr(1); - } - - exports.fromSetString = fromSetString; - - function relative(aRoot, aPath) { - aRoot = aRoot.replace(/\/$/, ''); - - var url = urlParse(aRoot); - if (aPath.charAt(0) == "/" && url && url.path == "/") { - return aPath.slice(1); - } - - return aPath.indexOf(aRoot + '/') === 0 - ? aPath.substr(aRoot.length + 1) - : aPath; - } - - exports.relative = relative; - - function strcmp(aStr1, aStr2) { - var s1 = aStr1 || ""; - var s2 = aStr2 || ""; - return (s1 > s2) - (s1 < s2); - } - - /** - * Comparator between two mappings where the original positions are compared. - * - * Optionally pass in `true` as `onlyCompareGenerated` to consider two - * mappings with the same original source/line/column, but different generated - * line and column the same. Useful when searching for a mapping with a - * stubbed out mapping. - */ - function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { - var cmp; - - cmp = strcmp(mappingA.source, mappingB.source); - if (cmp) { - return cmp; - } - - cmp = mappingA.originalLine - mappingB.originalLine; - if (cmp) { - return cmp; - } - - cmp = mappingA.originalColumn - mappingB.originalColumn; - if (cmp || onlyCompareOriginal) { - return cmp; - } - - cmp = strcmp(mappingA.name, mappingB.name); - if (cmp) { - return cmp; - } - - cmp = mappingA.generatedLine - mappingB.generatedLine; - if (cmp) { - return cmp; - } - - return mappingA.generatedColumn - mappingB.generatedColumn; - }; - exports.compareByOriginalPositions = compareByOriginalPositions; - - /** - * Comparator between two mappings where the generated positions are - * compared. - * - * Optionally pass in `true` as `onlyCompareGenerated` to consider two - * mappings with the same generated line and column, but different - * source/name/original line and column the same. Useful when searching for a - * mapping with a stubbed out mapping. - */ - function compareByGeneratedPositions(mappingA, mappingB, onlyCompareGenerated) { - var cmp; - - cmp = mappingA.generatedLine - mappingB.generatedLine; - if (cmp) { - return cmp; - } - - cmp = mappingA.generatedColumn - mappingB.generatedColumn; - if (cmp || onlyCompareGenerated) { - return cmp; - } - - cmp = strcmp(mappingA.source, mappingB.source); - if (cmp) { - return cmp; - } - - cmp = mappingA.originalLine - mappingB.originalLine; - if (cmp) { - return cmp; - } - - cmp = mappingA.originalColumn - mappingB.originalColumn; - if (cmp) { - return cmp; - } - - return strcmp(mappingA.name, mappingB.name); - }; - exports.compareByGeneratedPositions = compareByGeneratedPositions; - - }); - /* -*- Mode: js; js-indent-level: 2; -*- */ - /* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ - define('source-map/array-set', ['require', 'exports', 'module', 'source-map/util'], function (require, exports, module) { - - var util = require('./util'); - - /** - * A data structure which is a combination of an array and a set. Adding a new - * member is O(1), testing for membership is O(1), and finding the index of an - * element is O(1). Removing elements from the set is not supported. Only - * strings are supported for membership. - */ - function ArraySet() { - this._array = []; - this._set = {}; - } - - /** - * Static method for creating ArraySet instances from an existing array. - */ - ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { - var set = new ArraySet(); - for (var i = 0, len = aArray.length; i < len; i++) { - set.add(aArray[i], aAllowDuplicates); - } - return set; - }; - - /** - * Add the given string to this set. - * - * @param String aStr - */ - ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { - var isDuplicate = this.has(aStr); - var idx = this._array.length; - if (!isDuplicate || aAllowDuplicates) { - this._array.push(aStr); - } - if (!isDuplicate) { - this._set[util.toSetString(aStr)] = idx; - } - }; - - /** - * Is the given string a member of this set? - * - * @param String aStr - */ - ArraySet.prototype.has = function ArraySet_has(aStr) { - return Object.prototype.hasOwnProperty.call(this._set, - util.toSetString(aStr)); - }; - - /** - * What is the index of the given string in the array? - * - * @param String aStr - */ - ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { - if (this.has(aStr)) { - return this._set[util.toSetString(aStr)]; - } - throw new Error('"' + aStr + '" is not in the set.'); - }; - - /** - * What is the element at the given index? - * - * @param Number aIdx - */ - ArraySet.prototype.at = function ArraySet_at(aIdx) { - if (aIdx >= 0 && aIdx < this._array.length) { - return this._array[aIdx]; - } - throw new Error('No element indexed by ' + aIdx); - }; - - /** - * Returns the array representation of this set (which has the proper indices - * indicated by indexOf). Note that this is a copy of the internal array used - * for storing the members so that no one can mess with internal state. - */ - ArraySet.prototype.toArray = function ArraySet_toArray() { - return this._array.slice(); - }; - - exports.ArraySet = ArraySet; - - }); - /* -*- Mode: js; js-indent-level: 2; -*- */ - /* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ - define('source-map/source-map-consumer', ['require', 'exports', 'module', 'source-map/util', 'source-map/binary-search', 'source-map/array-set', 'source-map/base64-vlq'], function (require, exports, module) { - - var util = require('./util'); - var binarySearch = require('./binary-search'); - var ArraySet = require('./array-set').ArraySet; - var base64VLQ = require('./base64-vlq'); - - /** - * A SourceMapConsumer instance represents a parsed source map which we can - * query for information about the original file positions by giving it a file - * position in the generated source. - * - * The only parameter is the raw source map (either as a JSON string, or - * already parsed to an object). According to the spec, source maps have the - * following attributes: - * - * - version: Which version of the source map spec this map is following. - * - sources: An array of URLs to the original source files. - * - names: An array of identifiers which can be referrenced by individual mappings. - * - sourceRoot: Optional. The URL root from which all sources are relative. - * - sourcesContent: Optional. An array of contents of the original source files. - * - mappings: A string of base64 VLQs which contain the actual mappings. - * - file: The generated file this source map is associated with. - * - * Here is an example source map, taken from the source map spec[0]: - * - * { - * version : 3, - * file: "out.js", - * sourceRoot : "", - * sources: ["foo.js", "bar.js"], - * names: ["src", "maps", "are", "fun"], - * mappings: "AA,AB;;ABCDE;" - * } - * - * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# - */ - function SourceMapConsumer(aSourceMap) { - var sourceMap = aSourceMap; - if (typeof aSourceMap === 'string') { - sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); - } - - var version = util.getArg(sourceMap, 'version'); - var sources = util.getArg(sourceMap, 'sources'); - // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which - // requires the array) to play nice here. - var names = util.getArg(sourceMap, 'names', []); - var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); - var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); - var mappings = util.getArg(sourceMap, 'mappings'); - var file = util.getArg(sourceMap, 'file', null); - - // Once again, Sass deviates from the spec and supplies the version as a - // string rather than a number, so we use loose equality checking here. - if (version != this._version) { - throw new Error('Unsupported version: ' + version); - } - - // Pass `true` below to allow duplicate names and sources. While source maps - // are intended to be compressed and deduplicated, the TypeScript compiler - // sometimes generates source maps with duplicates in them. See Github issue - // #72 and bugzil.la/889492. - this._names = ArraySet.fromArray(names, true); - this._sources = ArraySet.fromArray(sources, true); - - this.sourceRoot = sourceRoot; - this.sourcesContent = sourcesContent; - this._mappings = mappings; - this.file = file; - } - - /** - * Create a SourceMapConsumer from a SourceMapGenerator. - * - * @param SourceMapGenerator aSourceMap - * The source map that will be consumed. - * @returns SourceMapConsumer - */ - SourceMapConsumer.fromSourceMap = - function SourceMapConsumer_fromSourceMap(aSourceMap) { - var smc = Object.create(SourceMapConsumer.prototype); - - smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); - smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); - smc.sourceRoot = aSourceMap._sourceRoot; - smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), - smc.sourceRoot); - smc.file = aSourceMap._file; - - smc.__generatedMappings = aSourceMap._mappings.slice() - .sort(util.compareByGeneratedPositions); - smc.__originalMappings = aSourceMap._mappings.slice() - .sort(util.compareByOriginalPositions); - - return smc; - }; - - /** - * The version of the source mapping spec that we are consuming. - */ - SourceMapConsumer.prototype._version = 3; - - /** - * The list of original sources. - */ - Object.defineProperty(SourceMapConsumer.prototype, 'sources', { - get: function () { - return this._sources.toArray().map(function (s) { - return this.sourceRoot ? util.join(this.sourceRoot, s) : s; - }, this); - } - }); - - // `__generatedMappings` and `__originalMappings` are arrays that hold the - // parsed mapping coordinates from the source map's "mappings" attribute. They - // are lazily instantiated, accessed via the `_generatedMappings` and - // `_originalMappings` getters respectively, and we only parse the mappings - // and create these arrays once queried for a source location. We jump through - // these hoops because there can be many thousands of mappings, and parsing - // them is expensive, so we only want to do it if we must. - // - // Each object in the arrays is of the form: - // - // { - // generatedLine: The line number in the generated code, - // generatedColumn: The column number in the generated code, - // source: The path to the original source file that generated this - // chunk of code, - // originalLine: The line number in the original source that - // corresponds to this chunk of generated code, - // originalColumn: The column number in the original source that - // corresponds to this chunk of generated code, - // name: The name of the original symbol which generated this chunk of - // code. - // } - // - // All properties except for `generatedLine` and `generatedColumn` can be - // `null`. - // - // `_generatedMappings` is ordered by the generated positions. - // - // `_originalMappings` is ordered by the original positions. - - SourceMapConsumer.prototype.__generatedMappings = null; - Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { - get: function () { - if (!this.__generatedMappings) { - this.__generatedMappings = []; - this.__originalMappings = []; - this._parseMappings(this._mappings, this.sourceRoot); - } - - return this.__generatedMappings; - } - }); - - SourceMapConsumer.prototype.__originalMappings = null; - Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { - get: function () { - if (!this.__originalMappings) { - this.__generatedMappings = []; - this.__originalMappings = []; - this._parseMappings(this._mappings, this.sourceRoot); - } - - return this.__originalMappings; - } - }); - - /** - * Parse the mappings in a string in to a data structure which we can easily - * query (the ordered arrays in the `this.__generatedMappings` and - * `this.__originalMappings` properties). - */ - SourceMapConsumer.prototype._parseMappings = - function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { - var generatedLine = 1; - var previousGeneratedColumn = 0; - var previousOriginalLine = 0; - var previousOriginalColumn = 0; - var previousSource = 0; - var previousName = 0; - var mappingSeparator = /^[,;]/; - var str = aStr; - var mapping; - var temp; - - while (str.length > 0) { - if (str.charAt(0) === ';') { - generatedLine++; - str = str.slice(1); - previousGeneratedColumn = 0; - } - else if (str.charAt(0) === ',') { - str = str.slice(1); - } - else { - mapping = {}; - mapping.generatedLine = generatedLine; - - // Generated column. - temp = base64VLQ.decode(str); - mapping.generatedColumn = previousGeneratedColumn + temp.value; - previousGeneratedColumn = mapping.generatedColumn; - str = temp.rest; - - if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) { - // Original source. - temp = base64VLQ.decode(str); - mapping.source = this._sources.at(previousSource + temp.value); - previousSource += temp.value; - str = temp.rest; - if (str.length === 0 || mappingSeparator.test(str.charAt(0))) { - throw new Error('Found a source, but no line and column'); - } - - // Original line. - temp = base64VLQ.decode(str); - mapping.originalLine = previousOriginalLine + temp.value; - previousOriginalLine = mapping.originalLine; - // Lines are stored 0-based - mapping.originalLine += 1; - str = temp.rest; - if (str.length === 0 || mappingSeparator.test(str.charAt(0))) { - throw new Error('Found a source and line, but no column'); - } - - // Original column. - temp = base64VLQ.decode(str); - mapping.originalColumn = previousOriginalColumn + temp.value; - previousOriginalColumn = mapping.originalColumn; - str = temp.rest; - - if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) { - // Original name. - temp = base64VLQ.decode(str); - mapping.name = this._names.at(previousName + temp.value); - previousName += temp.value; - str = temp.rest; - } - } - - this.__generatedMappings.push(mapping); - if (typeof mapping.originalLine === 'number') { - this.__originalMappings.push(mapping); - } - } - } - - this.__originalMappings.sort(util.compareByOriginalPositions); - }; - - /** - * Find the mapping that best matches the hypothetical "needle" mapping that - * we are searching for in the given "haystack" of mappings. - */ - SourceMapConsumer.prototype._findMapping = - function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, - aColumnName, aComparator) { - // To return the position we are searching for, we must first find the - // mapping for the given position and then return the opposite position it - // points to. Because the mappings are sorted, we can use binary search to - // find the best mapping. - - if (aNeedle[aLineName] <= 0) { - throw new TypeError('Line must be greater than or equal to 1, got ' - + aNeedle[aLineName]); - } - if (aNeedle[aColumnName] < 0) { - throw new TypeError('Column must be greater than or equal to 0, got ' - + aNeedle[aColumnName]); - } - - return binarySearch.search(aNeedle, aMappings, aComparator); - }; - - /** - * Returns the original source, line, and column information for the generated - * source's line and column positions provided. The only argument is an object - * with the following properties: - * - * - line: The line number in the generated source. - * - column: The column number in the generated source. - * - * and an object is returned with the following properties: - * - * - source: The original source file, or null. - * - line: The line number in the original source, or null. - * - column: The column number in the original source, or null. - * - name: The original identifier, or null. - */ - SourceMapConsumer.prototype.originalPositionFor = - function SourceMapConsumer_originalPositionFor(aArgs) { - var needle = { - generatedLine: util.getArg(aArgs, 'line'), - generatedColumn: util.getArg(aArgs, 'column') - }; - - var mapping = this._findMapping(needle, - this._generatedMappings, - "generatedLine", - "generatedColumn", - util.compareByGeneratedPositions); - - if (mapping) { - var source = util.getArg(mapping, 'source', null); - if (source && this.sourceRoot) { - source = util.join(this.sourceRoot, source); - } - return { - source: source, - line: util.getArg(mapping, 'originalLine', null), - column: util.getArg(mapping, 'originalColumn', null), - name: util.getArg(mapping, 'name', null) - }; - } - - return { - source: null, - line: null, - column: null, - name: null - }; - }; - - /** - * Returns the original source content. The only argument is the url of the - * original source file. Returns null if no original source content is - * availible. - */ - SourceMapConsumer.prototype.sourceContentFor = - function SourceMapConsumer_sourceContentFor(aSource) { - if (!this.sourcesContent) { - return null; - } - - if (this.sourceRoot) { - aSource = util.relative(this.sourceRoot, aSource); - } - - if (this._sources.has(aSource)) { - return this.sourcesContent[this._sources.indexOf(aSource)]; - } - - var url; - if (this.sourceRoot - && (url = util.urlParse(this.sourceRoot))) { - // XXX: file:// URIs and absolute paths lead to unexpected behavior for - // many users. We can help them out when they expect file:// URIs to - // behave like it would if they were running a local HTTP server. See - // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. - var fileUriAbsPath = aSource.replace(/^file:\/\//, ""); - if (url.scheme == "file" - && this._sources.has(fileUriAbsPath)) { - return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] - } - - if ((!url.path || url.path == "/") - && this._sources.has("/" + aSource)) { - return this.sourcesContent[this._sources.indexOf("/" + aSource)]; - } - } - - throw new Error('"' + aSource + '" is not in the SourceMap.'); - }; - - /** - * Returns the generated line and column information for the original source, - * line, and column positions provided. The only argument is an object with - * the following properties: - * - * - source: The filename of the original source. - * - line: The line number in the original source. - * - column: The column number in the original source. - * - * and an object is returned with the following properties: - * - * - line: The line number in the generated source, or null. - * - column: The column number in the generated source, or null. - */ - SourceMapConsumer.prototype.generatedPositionFor = - function SourceMapConsumer_generatedPositionFor(aArgs) { - var needle = { - source: util.getArg(aArgs, 'source'), - originalLine: util.getArg(aArgs, 'line'), - originalColumn: util.getArg(aArgs, 'column') - }; - - if (this.sourceRoot) { - needle.source = util.relative(this.sourceRoot, needle.source); - } - - var mapping = this._findMapping(needle, - this._originalMappings, - "originalLine", - "originalColumn", - util.compareByOriginalPositions); - - if (mapping) { - return { - line: util.getArg(mapping, 'generatedLine', null), - column: util.getArg(mapping, 'generatedColumn', null) - }; - } - - return { - line: null, - column: null - }; - }; - - SourceMapConsumer.GENERATED_ORDER = 1; - SourceMapConsumer.ORIGINAL_ORDER = 2; - - /** - * Iterate over each mapping between an original source/line/column and a - * generated line/column in this source map. - * - * @param Function aCallback - * The function that is called with each mapping. - * @param Object aContext - * Optional. If specified, this object will be the value of `this` every - * time that `aCallback` is called. - * @param aOrder - * Either `SourceMapConsumer.GENERATED_ORDER` or - * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to - * iterate over the mappings sorted by the generated file's line/column - * order or the original's source/line/column order, respectively. Defaults to - * `SourceMapConsumer.GENERATED_ORDER`. - */ - SourceMapConsumer.prototype.eachMapping = - function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { - var context = aContext || null; - var order = aOrder || SourceMapConsumer.GENERATED_ORDER; - - var mappings; - switch (order) { - case SourceMapConsumer.GENERATED_ORDER: - mappings = this._generatedMappings; - break; - case SourceMapConsumer.ORIGINAL_ORDER: - mappings = this._originalMappings; - break; - default: - throw new Error("Unknown order of iteration."); - } - - var sourceRoot = this.sourceRoot; - mappings.map(function (mapping) { - var source = mapping.source; - if (source && sourceRoot) { - source = util.join(sourceRoot, source); - } - return { - source: source, - generatedLine: mapping.generatedLine, - generatedColumn: mapping.generatedColumn, - originalLine: mapping.originalLine, - originalColumn: mapping.originalColumn, - name: mapping.name - }; - }).forEach(aCallback, context); - }; - - exports.SourceMapConsumer = SourceMapConsumer; - - }); - /* -*- Mode: js; js-indent-level: 2; -*- */ - /* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ - define('source-map/binary-search', ['require', 'exports', 'module',], function (require, exports, module) { - - /** - * Recursive implementation of binary search. - * - * @param aLow Indices here and lower do not contain the needle. - * @param aHigh Indices here and higher do not contain the needle. - * @param aNeedle The element being searched for. - * @param aHaystack The non-empty array being searched. - * @param aCompare Function which takes two elements and returns -1, 0, or 1. - */ - function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare) { - // This function terminates when one of the following is true: - // - // 1. We find the exact element we are looking for. - // - // 2. We did not find the exact element, but we can return the next - // closest element that is less than that element. - // - // 3. We did not find the exact element, and there is no next-closest - // element which is less than the one we are searching for, so we - // return null. - var mid = Math.floor((aHigh - aLow) / 2) + aLow; - var cmp = aCompare(aNeedle, aHaystack[mid], true); - if (cmp === 0) { - // Found the element we are looking for. - return aHaystack[mid]; - } - else if (cmp > 0) { - // aHaystack[mid] is greater than our needle. - if (aHigh - mid > 1) { - // The element is in the upper half. - return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare); - } - // We did not find an exact match, return the next closest one - // (termination case 2). - return aHaystack[mid]; - } - else { - // aHaystack[mid] is less than our needle. - if (mid - aLow > 1) { - // The element is in the lower half. - return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare); - } - // The exact needle element was not found in this haystack. Determine if - // we are in termination case (2) or (3) and return the appropriate thing. - return aLow < 0 - ? null - : aHaystack[aLow]; - } - } - - /** - * This is an implementation of binary search which will always try and return - * the next lowest value checked if there is no exact hit. This is because - * mappings between original and generated line/col pairs are single points, - * and there is an implicit region between each of them, so a miss just means - * that you aren't on the very start of a region. - * - * @param aNeedle The element you are looking for. - * @param aHaystack The array that is being searched. - * @param aCompare A function which takes the needle and an element in the - * array and returns -1, 0, or 1 depending on whether the needle is less - * than, equal to, or greater than the element, respectively. - */ - exports.search = function search(aNeedle, aHaystack, aCompare) { - return aHaystack.length > 0 - ? recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare) - : null; - }; - - }); - /* -*- Mode: js; js-indent-level: 2; -*- */ - /* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ - define('source-map/source-node', ['require', 'exports', 'module', 'source-map/source-map-generator', 'source-map/util'], function (require, exports, module) { - - var SourceMapGenerator = require('./source-map-generator').SourceMapGenerator; - var util = require('./util'); - - /** - * SourceNodes provide a way to abstract over interpolating/concatenating - * snippets of generated JavaScript source code while maintaining the line and - * column information associated with the original source code. - * - * @param aLine The original line number. - * @param aColumn The original column number. - * @param aSource The original source's filename. - * @param aChunks Optional. An array of strings which are snippets of - * generated JS, or other SourceNodes. - * @param aName The original identifier. - */ - function SourceNode(aLine, aColumn, aSource, aChunks, aName) { - this.children = []; - this.sourceContents = {}; - this.line = aLine === undefined ? null : aLine; - this.column = aColumn === undefined ? null : aColumn; - this.source = aSource === undefined ? null : aSource; - this.name = aName === undefined ? null : aName; - if (aChunks != null) this.add(aChunks); - } - - /** - * Creates a SourceNode from generated code and a SourceMapConsumer. - * - * @param aGeneratedCode The generated code - * @param aSourceMapConsumer The SourceMap for the generated code - */ - SourceNode.fromStringWithSourceMap = - function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer) { - // The SourceNode we want to fill with the generated code - // and the SourceMap - var node = new SourceNode(); - - // The generated code - // Processed fragments are removed from this array. - var remainingLines = aGeneratedCode.split('\n'); - - // We need to remember the position of "remainingLines" - var lastGeneratedLine = 1, lastGeneratedColumn = 0; - - // The generate SourceNodes we need a code range. - // To extract it current and last mapping is used. - // Here we store the last mapping. - var lastMapping = null; - - aSourceMapConsumer.eachMapping(function (mapping) { - if (lastMapping === null) { - // We add the generated code until the first mapping - // to the SourceNode without any mapping. - // Each line is added as separate string. - while (lastGeneratedLine < mapping.generatedLine) { - node.add(remainingLines.shift() + "\n"); - lastGeneratedLine++; - } - if (lastGeneratedColumn < mapping.generatedColumn) { - var nextLine = remainingLines[0]; - node.add(nextLine.substr(0, mapping.generatedColumn)); - remainingLines[0] = nextLine.substr(mapping.generatedColumn); - lastGeneratedColumn = mapping.generatedColumn; - } - } else { - // We add the code from "lastMapping" to "mapping": - // First check if there is a new line in between. - if (lastGeneratedLine < mapping.generatedLine) { - var code = ""; - // Associate full lines with "lastMapping" - do { - code += remainingLines.shift() + "\n"; - lastGeneratedLine++; - lastGeneratedColumn = 0; - } while (lastGeneratedLine < mapping.generatedLine); - // When we reached the correct line, we add code until we - // reach the correct column too. - if (lastGeneratedColumn < mapping.generatedColumn) { - var nextLine = remainingLines[0]; - code += nextLine.substr(0, mapping.generatedColumn); - remainingLines[0] = nextLine.substr(mapping.generatedColumn); - lastGeneratedColumn = mapping.generatedColumn; - } - // Create the SourceNode. - addMappingWithCode(lastMapping, code); - } else { - // There is no new line in between. - // Associate the code between "lastGeneratedColumn" and - // "mapping.generatedColumn" with "lastMapping" - var nextLine = remainingLines[0]; - var code = nextLine.substr(0, mapping.generatedColumn - - lastGeneratedColumn); - remainingLines[0] = nextLine.substr(mapping.generatedColumn - - lastGeneratedColumn); - lastGeneratedColumn = mapping.generatedColumn; - addMappingWithCode(lastMapping, code); - } - } - lastMapping = mapping; - }, this); - // We have processed all mappings. - // Associate the remaining code in the current line with "lastMapping" - // and add the remaining lines without any mapping - addMappingWithCode(lastMapping, remainingLines.join("\n")); - - // Copy sourcesContent into SourceNode - aSourceMapConsumer.sources.forEach(function (sourceFile) { - var content = aSourceMapConsumer.sourceContentFor(sourceFile); - if (content) { - node.setSourceContent(sourceFile, content); - } - }); - - return node; - - function addMappingWithCode(mapping, code) { - if (mapping === null || mapping.source === undefined) { - node.add(code); - } else { - node.add(new SourceNode(mapping.originalLine, - mapping.originalColumn, - mapping.source, - code, - mapping.name)); - } - } - }; - - /** - * Add a chunk of generated JS to this source node. - * - * @param aChunk A string snippet of generated JS code, another instance of - * SourceNode, or an array where each member is one of those things. - */ - SourceNode.prototype.add = function SourceNode_add(aChunk) { - if (Array.isArray(aChunk)) { - aChunk.forEach(function (chunk) { - this.add(chunk); - }, this); - } - else if (aChunk instanceof SourceNode || typeof aChunk === "string") { - if (aChunk) { - this.children.push(aChunk); - } - } - else { - throw new TypeError( - "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk - ); - } - return this; - }; - - /** - * Add a chunk of generated JS to the beginning of this source node. - * - * @param aChunk A string snippet of generated JS code, another instance of - * SourceNode, or an array where each member is one of those things. - */ - SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { - if (Array.isArray(aChunk)) { - for (var i = aChunk.length - 1; i >= 0; i--) { - this.prepend(aChunk[i]); - } - } - else if (aChunk instanceof SourceNode || typeof aChunk === "string") { - this.children.unshift(aChunk); - } - else { - throw new TypeError( - "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk - ); - } - return this; - }; - - /** - * Walk over the tree of JS snippets in this node and its children. The - * walking function is called once for each snippet of JS and is passed that - * snippet and the its original associated source's line/column location. - * - * @param aFn The traversal function. - */ - SourceNode.prototype.walk = function SourceNode_walk(aFn) { - var chunk; - for (var i = 0, len = this.children.length; i < len; i++) { - chunk = this.children[i]; - if (chunk instanceof SourceNode) { - chunk.walk(aFn); - } - else { - if (chunk !== '') { - aFn(chunk, { - source: this.source, - line: this.line, - column: this.column, - name: this.name - }); - } - } - } - }; - - /** - * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between - * each of `this.children`. - * - * @param aSep The separator. - */ - SourceNode.prototype.join = function SourceNode_join(aSep) { - var newChildren; - var i; - var len = this.children.length; - if (len > 0) { - newChildren = []; - for (i = 0; i < len - 1; i++) { - newChildren.push(this.children[i]); - newChildren.push(aSep); - } - newChildren.push(this.children[i]); - this.children = newChildren; - } - return this; - }; - - /** - * Call String.prototype.replace on the very right-most source snippet. Useful - * for trimming whitespace from the end of a source node, etc. - * - * @param aPattern The pattern to replace. - * @param aReplacement The thing to replace the pattern with. - */ - SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild instanceof SourceNode) { - lastChild.replaceRight(aPattern, aReplacement); - } - else if (typeof lastChild === 'string') { - this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); - } - else { - this.children.push(''.replace(aPattern, aReplacement)); - } - return this; - }; - - /** - * Set the source content for a source file. This will be added to the SourceMapGenerator - * in the sourcesContent field. - * - * @param aSourceFile The filename of the source file - * @param aSourceContent The content of the source file - */ - SourceNode.prototype.setSourceContent = - function SourceNode_setSourceContent(aSourceFile, aSourceContent) { - this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; - }; - - /** - * Walk over the tree of SourceNodes. The walking function is called for each - * source file content and is passed the filename and source content. - * - * @param aFn The traversal function. - */ - SourceNode.prototype.walkSourceContents = - function SourceNode_walkSourceContents(aFn) { - for (var i = 0, len = this.children.length; i < len; i++) { - if (this.children[i] instanceof SourceNode) { - this.children[i].walkSourceContents(aFn); - } - } - - var sources = Object.keys(this.sourceContents); - for (var i = 0, len = sources.length; i < len; i++) { - aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); - } - }; - - /** - * Return the string representation of this source node. Walks over the tree - * and concatenates all the various snippets together to one string. - */ - SourceNode.prototype.toString = function SourceNode_toString() { - var str = ""; - this.walk(function (chunk) { - str += chunk; - }); - return str; - }; - - /** - * Returns the string representation of this source node along with a source - * map. - */ - SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { - var generated = { - code: "", - line: 1, - column: 0 - }; - var map = new SourceMapGenerator(aArgs); - var sourceMappingActive = false; - var lastOriginalSource = null; - var lastOriginalLine = null; - var lastOriginalColumn = null; - var lastOriginalName = null; - this.walk(function (chunk, original) { - generated.code += chunk; - if (original.source !== null - && original.line !== null - && original.column !== null) { - if (lastOriginalSource !== original.source - || lastOriginalLine !== original.line - || lastOriginalColumn !== original.column - || lastOriginalName !== original.name) { - map.addMapping({ - source: original.source, - original: { - line: original.line, - column: original.column - }, - generated: { - line: generated.line, - column: generated.column - }, - name: original.name - }); - } - lastOriginalSource = original.source; - lastOriginalLine = original.line; - lastOriginalColumn = original.column; - lastOriginalName = original.name; - sourceMappingActive = true; - } else if (sourceMappingActive) { - map.addMapping({ - generated: { - line: generated.line, - column: generated.column - } - }); - lastOriginalSource = null; - sourceMappingActive = false; - } - chunk.split('').forEach(function (ch) { - if (ch === '\n') { - generated.line++; - generated.column = 0; - } else { - generated.column++; - } - }); - }); - this.walkSourceContents(function (sourceFile, sourceContent) { - map.setSourceContent(sourceFile, sourceContent); - }); - - return {code: generated.code, map: map}; - }; - - exports.SourceNode = SourceNode; - - }); - /* -*- Mode: js; js-indent-level: 2; -*- */ -/////////////////////////////////////////////////////////////////////////////// - - this.sourceMap = { - SourceMapConsumer: require('source-map/source-map-consumer').SourceMapConsumer, - SourceMapGenerator: require('source-map/source-map-generator').SourceMapGenerator, - SourceNode: require('source-map/source-node').SourceNode - }; - -// footer to wrap "source-map" module - return this.sourceMap; - }(); -})(); - - -/* Less.js v1.7.5 RHINO | Copyright (c) 2009-2014, Alexis Sellier */ - -/*global name:true, less, loadStyleSheet, os */ - -function formatError(ctx, options) { - options = options || {}; - - var message = ""; - var extract = ctx.extract; - var error = []; - -// var stylize = options.color ? require('./lessc_helper').stylize : function (str) { return str; }; - var stylize = function (str) { - return str; - }; - - // only output a stack if it isn't a less error - if (ctx.stack && !ctx.type) { - return stylize(ctx.stack, 'red'); - } - - if (!ctx.hasOwnProperty('index') || !extract) { - return ctx.stack || ctx.message; - } - - if (typeof(extract[0]) === 'string') { - error.push(stylize((ctx.line - 1) + ' ' + extract[0], 'grey')); - } - - if (typeof(extract[1]) === 'string') { - var errorTxt = ctx.line + ' '; - if (extract[1]) { - errorTxt += extract[1].slice(0, ctx.column) + - stylize(stylize(stylize(extract[1][ctx.column], 'bold') + - extract[1].slice(ctx.column + 1), 'red'), 'inverse'); - } - error.push(errorTxt); - } - - if (typeof(extract[2]) === 'string') { - error.push(stylize((ctx.line + 1) + ' ' + extract[2], 'grey')); - } - error = error.join('\n') + stylize('', 'reset') + '\n'; - - message += stylize(ctx.type + 'Error: ' + ctx.message, 'red'); - if (ctx.filename) { - message += stylize(' in ', 'red') + ctx.filename + - stylize(' on line ' + ctx.line + ', column ' + (ctx.column + 1) + ':', 'grey'); - } - - message += '\n' + error; - - if (ctx.callLine) { - message += stylize('from ', 'red') + (ctx.filename || '') + '/n'; - message += stylize(ctx.callLine, 'grey') + ' ' + ctx.callExtract + '/n'; - } - - return message; -} - -function writeError(ctx, options) { - options = options || {}; - if (options.silent) { - return; - } - var message = formatError(ctx, options); - throw new Error(message); -} - -function loadStyleSheet(sheet, callback, reload, remaining) { - var endOfPath = Math.max(name.lastIndexOf('/'), name.lastIndexOf('\\')), - sheetName = name.slice(0, endOfPath + 1) + sheet.href, - contents = sheet.contents || {}, - input = readFile(sheetName); - - input = input.replace(/^\xEF\xBB\xBF/, ''); - - contents[sheetName] = input; - - var parser = new less.Parser({ - paths: [sheet.href.replace(/[\w\.-]+$/, '')], - contents: contents - }); - parser.parse(input, function (e, root) { - if (e) { - return writeError(e); - } - //try { - callback(e, root, input, sheet, {local: false, lastModified: 0, remaining: remaining}, sheetName); - //} catch (e) { - //writeError(e); - //log.error(e); - //} - }); -} - -less.Parser.fileLoader = function (file, currentFileInfo, callback, env) { - - var href = file; - if (currentFileInfo && currentFileInfo.currentDirectory && !/^\//.test(file)) { - href = less.modules.path.join(currentFileInfo.currentDirectory, file); - } - - var path = less.modules.path.dirname(href); - - var newFileInfo = { - currentDirectory: path + '/', - filename: href - }; - - if (currentFileInfo) { - newFileInfo.entryPath = currentFileInfo.entryPath; - newFileInfo.rootpath = currentFileInfo.rootpath; - newFileInfo.rootFilename = currentFileInfo.rootFilename; - newFileInfo.relativeUrls = currentFileInfo.relativeUrls; - } else { - newFileInfo.entryPath = path; - newFileInfo.rootpath = less.rootpath || path; - newFileInfo.rootFilename = href; - newFileInfo.relativeUrls = env.relativeUrls; - } - - var j = file.lastIndexOf('/'); - if (newFileInfo.relativeUrls && !/^(?:[a-z-]+:|\/)/.test(file) && j != -1) { - var relativeSubDirectory = file.slice(0, j + 1); - newFileInfo.rootpath = newFileInfo.rootpath + relativeSubDirectory; // append (sub|sup) directory path of imported file - } - newFileInfo.currentDirectory = path; - newFileInfo.filename = href; - - var data = null; - try { - data = readFile(href); - } catch (e) { - log.error(e); - callback({type: 'File', message: "'" + less.modules.path.basename(href) + "' wasn't found"}); - return; - } - - try { - callback(null, data, href, newFileInfo, {lastModified: 0}); - } catch (e) { - callback(e, null, href); - } -}; - - -function writeFile(filename, content) { - var f = new File(filename); - f.open('w'); - f.write(content); - f.close(); -} - -// Command line integration via Rhino -var compile = function (args) { - - var options = { - depends: false, - compress: false, - cleancss: false, - max_line_len: -1, - optimization: 1, - silent: false, - verbose: false, - lint: false, - paths: [], - color: true, - strictImports: false, - rootpath: '', - relativeUrls: false, - ieCompat: true, - strictMath: false, - strictUnits: false - }; - var continueProcessing = true, - currentErrorcode; - - var checkArgFunc = function (arg, option) { - if (!option) { - print(arg + " option requires a parameter"); - continueProcessing = false; - return false; - } - return true; - }; - - var checkBooleanArg = function (arg) { - var onOff = /^((on|t|true|y|yes)|(off|f|false|n|no))$/i.exec(arg); - if (!onOff) { - print(" unable to parse " + arg + " as a boolean. use one of on/t/true/y/yes/off/f/false/n/no"); - continueProcessing = false; - return false; - } - return Boolean(onOff[2]); - }; - - var warningMessages = ""; - var sourceMapFileInline = false; - - args = args.filter(function (arg) { - var match = arg.match(/^-I(.+)$/); - - if (match) { - options.paths.push(match[1]); - return false; - } - - match = arg.match(/^--?([a-z][0-9a-z-]*)(?:=(.*))?$/i); - if (match) { - arg = match[1]; - } // was (?:=([^\s]*)), check! - else { - return arg; - } - - switch (arg) { - case 'v': - case 'version': - console.log("lessc " + less.version.join('.') + " (Less Compiler) [JavaScript]"); - continueProcessing = false; - break; - case 'verbose': - options.verbose = true; - break; - case 's': - case 'silent': - options.silent = true; - break; - case 'l': - case 'lint': - options.lint = true; - break; - case 'strict-imports': - options.strictImports = true; - break; - case 'h': - case 'help': - //TODO -// require('../lib/less/lessc_helper').printUsage(); - continueProcessing = false; - break; - case 'x': - case 'compress': - options.compress = true; - break; - case 'M': - case 'depends': - options.depends = true; - break; - case 'yui-compress': - warningMessages += "yui-compress option has been removed. assuming clean-css."; - options.cleancss = true; - break; - case 'clean-css': - options.cleancss = true; - break; - case 'max-line-len': - if (checkArgFunc(arg, match[2])) { - options.maxLineLen = parseInt(match[2], 10); - if (options.maxLineLen <= 0) { - options.maxLineLen = -1; - } - } - break; - case 'no-color': - options.color = false; - break; - case 'no-ie-compat': - options.ieCompat = false; - break; - case 'no-js': - options.javascriptEnabled = false; - break; - case 'include-path': - if (checkArgFunc(arg, match[2])) { - options.paths = match[2].split(os.type().match(/Windows/) ? ';' : ':') - .map(function (p) { - if (p) { -// return path.resolve(process.cwd(), p); - return p; - } - }); - } - break; - case 'O0': - options.optimization = 0; - break; - case 'O1': - options.optimization = 1; - break; - case 'O2': - options.optimization = 2; - break; - case 'line-numbers': - if (checkArgFunc(arg, match[2])) { - options.dumpLineNumbers = match[2]; - } - break; - case 'source-map': - if (!match[2]) { - options.sourceMap = true; - } else { - options.sourceMap = match[2]; - } - break; - case 'source-map-rootpath': - if (checkArgFunc(arg, match[2])) { - options.sourceMapRootpath = match[2]; - } - break; - case 'source-map-basepath': - if (checkArgFunc(arg, match[2])) { - options.sourceMapBasepath = match[2]; - } - break; - case 'source-map-map-inline': - sourceMapFileInline = true; - options.sourceMap = true; - break; - case 'source-map-less-inline': - options.outputSourceFiles = true; - break; - case 'source-map-url': - if (checkArgFunc(arg, match[2])) { - options.sourceMapURL = match[2]; - } - break; - case 'source-map-output-map-file': - if (checkArgFunc(arg, match[2])) { - options.writeSourceMap = function (sourceMapContent) { - writeFile(match[2], sourceMapContent); - }; - } - break; - case 'rp': - case 'rootpath': - if (checkArgFunc(arg, match[2])) { - options.rootpath = match[2].replace(/\\/g, '/'); - } - break; - case "ru": - case "relative-urls": - options.relativeUrls = true; - break; - case "sm": - case "strict-math": - if (checkArgFunc(arg, match[2])) { - options.strictMath = checkBooleanArg(match[2]); - } - break; - case "su": - case "strict-units": - if (checkArgFunc(arg, match[2])) { - options.strictUnits = checkBooleanArg(match[2]); - } - break; - default: - console.log('invalid option ' + arg); - continueProcessing = false; - } - }); - - if (!continueProcessing) { - return; - } - - var name = args[0]; - if (name && name != '-') { -// name = path.resolve(process.cwd(), name); - } - var output = args[1]; - var outputbase = args[1]; - if (output) { - options.sourceMapOutputFilename = output; -// output = path.resolve(process.cwd(), output); - if (warningMessages) { - console.log(warningMessages); - } - } - -// options.sourceMapBasepath = process.cwd(); -// options.sourceMapBasepath = ''; - - if (options.sourceMap === true) { - console.log("output: " + output); - if (!output && !sourceMapFileInline) { - console.log("the sourcemap option only has an optional filename if the css filename is given"); - return; - } - options.sourceMapFullFilename = options.sourceMapOutputFilename + ".map"; - options.sourceMap = less.modules.path.basename(options.sourceMapFullFilename); - } else if (options.sourceMap) { - options.sourceMapOutputFilename = options.sourceMap; - } - - - if (!name) { - console.log("lessc: no inout files"); - console.log(""); - // TODO -// require('../lib/less/lessc_helper').printUsage(); - currentErrorcode = 1; - return; - } - -// var ensureDirectory = function (filepath) { -// var dir = path.dirname(filepath), -// cmd, -// existsSync = fs.existsSync || path.existsSync; -// if (!existsSync(dir)) { -// if (mkdirp === undefined) { -// try {mkdirp = require('mkdirp');} -// catch(e) { mkdirp = null; } -// } -// cmd = mkdirp && mkdirp.sync || fs.mkdirSync; -// cmd(dir); -// } -// }; - - if (options.depends) { - if (!outputbase) { - console.log("option --depends requires an output path to be specified"); - return; - } - console.log(outputbase + ": "); - } - - if (!name) { - console.log('No files present in the fileset'); - quit(1); - } - - var input = null; - try { - input = readFile(name, 'utf-8'); - } catch (e) { - log.error(e); - quit(1); - } - - options.filename = name; - var result; - var parser = new less.Parser(options); - parser.parse(input, function (e, root) { - if (e) { - log.info(e); - writeError(e, options); - quit(1); - } else { - result = root.toCSS(options); - if (output) { - writeFile(output, result); - console.log("Written to " + output); - } else { - print(result); - } - quit(0); - } - }, { - globalVars: {'self-class': fuseState.currentUnit + '-unit'} - }); -}; diff --git a/modules/distribution/src/repository/jaggeryapps/iot/lib/login.jag b/modules/distribution/src/repository/jaggeryapps/iot/lib/login.jag deleted file mode 100644 index 7b93c3c7..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/lib/login.jag +++ /dev/null @@ -1,36 +0,0 @@ -<% -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -(function(){ - var constants = require('/modules/constants.js'); - if (!session.get(constants.USER_SESSION_KEY)) { - var dataConfig = require('/config/dc-props.js').config(); - var sso = require('/modules/sso.js').sso; - var keyStoreParams = { - keyStoreName : dataConfig.ssoConfiguration.keyStoreName, - keyStorePassword : dataConfig.ssoConfiguration.keyStorePassword, - identityAlias : dataConfig.ssoConfiguration.identityAlias - } - sso.configure(dataConfig.ssoConfiguration.issuer, dataConfig.ssoConfiguration.appName, keyStoreParams, - dataConfig.ssoConfiguration.identityProviderURL); - sso.login(); - }else{ - response.sendRedirect(dataConfig.appContext); - } -}()); -%> diff --git a/modules/distribution/src/repository/jaggeryapps/iot/lib/logout.jag b/modules/distribution/src/repository/jaggeryapps/iot/lib/logout.jag deleted file mode 100644 index 4ae365d9..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/lib/logout.jag +++ /dev/null @@ -1,37 +0,0 @@ -<% -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -var constants = require('/modules/constants.js'); -var user = session.get(constants.USER_SESSION_KEY); -var dataConfig = require('/config/dc-props.js').config(); -var log = new Log(); -if (user === null) { - log.debug("Cannot perform logout. No user session found."); - response.sendRedirect(dataConfig.appContext+'dashboard'); -} else { - var sso = require('/modules/sso.js').sso; - var keyStoreParams = { - keyStoreName: dataConfig.ssoConfiguration.keyStoreName, - keyStorePassword: dataConfig.ssoConfiguration.keyStorePassword, - identityAlias: dataConfig.ssoConfiguration.identityAlias - } - sso.configure(dataConfig.ssoConfiguration.issuer, dataConfig.ssoConfiguration.appName, keyStoreParams, - dataConfig.ssoConfiguration.identityProviderURL); - sso.logout(user); -} -%> \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/modules/constants.js b/modules/distribution/src/repository/jaggeryapps/iot/modules/constants.js deleted file mode 100644 index 182d319e..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/modules/constants.js +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -var WEB_APP_TITLE = "WSO2 DC - Device Cloud"; -var WEB_APP_CONTEXT = "/iot"; -var USER_SESSION_KEY = "USER"; -var UNSPECIFIED = "Unspecified"; - -var ERRORS = { - "USER_NOT_FOUND": "USER_NOT_FOUND" - }; diff --git a/modules/distribution/src/repository/jaggeryapps/iot/modules/device.js b/modules/distribution/src/repository/jaggeryapps/iot/modules/device.js deleted file mode 100644 index 70650ce1..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/modules/device.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -var deviceModule; -var carbon = require('carbon'); -var carbonHttpServletTransport = carbon.server.address('http'); -var carbonHttpsServletTransport = carbon.server.address('https'); - -deviceModule = function () { - var log = new Log("modules/device.js"); - - var constants = require("/modules/constants.js"); - var utility = require("/modules/utility.js").utility; - - var publicMethods = {}; - var privateMethods = {}; - - publicMethods.getAllDevicesTypes = function(){ - //URL: https://localhost:9443/devicecloud/manager/devices/username/{username} - deviceCloudService = carbonHttpsServletTransport + "/devicecloud/manager"; - listAllDeviceTypesEndPoint = deviceCloudService + "/devices/types"; - - var data = {}; - //XMLHTTPRequest's GET - return get(listAllDeviceTypesEndPoint, data, "json"); - }; - -}(); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/modules/download.js b/modules/distribution/src/repository/jaggeryapps/iot/modules/download.js deleted file mode 100644 index 5394c8bf..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/modules/download.js +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -var downloadModule; -var Handlebars = require('../lib/handlebars-v2.0.0.js').Handlebars; -downloadModule = function () { - var log = new Log("modules/download.js"); - - var constants = require("/modules/constants.js"); - - var publicMethods = {}; - var privateMethods = {}; - - /** - * Downloading a specified sketch file. - * - * @param file File name or file object of the downloading file - * @param replaceParams - */ - publicMethods.downloadSketch = function (file, response, replaceParams) { - var file = new File("../sketch/" + file); - - file.open('r'); - log.debug("Reading file '" + file.getPath() + "'"); - var content = file.readAll().trim(); - file.close(); - - var downloadFile = privateMethods.allReplace(content,replaceParams); - - response.contentType = "application/octet-stream"; - response.addHeader("Content-Disposition", "attachment; filename='sketch.hbs'"); - response.addHeader("Content-Length", String(downloadFile.length)); - response.content = downloadFile; - }; - - /** - * Find and replace all occurrences. - * @param inStr input string - * @param replaceParams key value array - * @returns retStr replaced string - */ - privateMethods.allReplace = function (inStr, replaceParams) { - var retStr = inStr; - for (var x in replaceParams) { - retStr = retStr.replace(new RegExp(x, 'g'), replaceParams[x]) - } - return retStr; - }; - - return publicMethods; -}(); - - diff --git a/modules/distribution/src/repository/jaggeryapps/iot/modules/pinch.min.js b/modules/distribution/src/repository/jaggeryapps/iot/modules/pinch.min.js deleted file mode 100644 index feccd2da..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/modules/pinch.min.js +++ /dev/null @@ -1,27 +0,0 @@ -/* -* Copyright (c) 2011 František Hába -* -* Permission is hereby granted, free of charge, to any person obtaining a copy of -* this software and associated documentation files (the 'Software'), to deal in -* the Software without restriction, including without limitation the rights to use, -* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the -* Software, and to permit persons to whom the Software is furnished to do so, -* subject to the following conditions: -* The above copyright notice and this permission notice shall be included in all -* copies or substantial portions of the Software. - -* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Reference:- https://github.com/Baggz/Pinch -* Pinch is a small JavaScript utility which is able to replace any data in a JavaScript object (or JSON). -* */ -(function(){var k=function(a,c){return a.length!==c.length?!1:a.every(function(a,b){return c[b]===a})},j=function(a,c,d){var b,e;if("[object Array]"===Object.prototype.toString.call(a)){b=0;for(e=a.length;b

You are now being redirected to SSO Provider. If the redirection fails, please click on the "+ - "button below.

" + - ""); - }; - - sso.logout = function (user) { - var sso_sessions = getSSOSessions(); - sso.sessionId = session.getId(); - sso.sessionIndex = sso_sessions[sso.sessionId]; - - var referer = request.getHeader("referer"); - sso.relayState = (referer ? referer : sso.relayState); - sso.relayState = sso.relayState + request.getQueryString(); // append query string - sso.encodedSAMLLogoutRequest = ssoMod.client.getEncodedSAMLLogoutRequest(user, sso.sessionIndex, sso.issuer); - var postUrl = sso.address + sso.ssoService; - - if (log.isDebugEnabled()) { - sso.log.debug("Logout request recieved from session id ::: " + sso.sessionId); - } - print("

You are now redirected to Stratos Identity. If theredirection fails, please click the post " + - "button.

"); - }; - - sso.acs = function (loginCallback, logoutCallback) { - var sso_sessions = getSSOSessions(); - sso.sessionId = session.getId(); - var samlResponse = request.getParameter('SAMLResponse'); - var samlRequest = request.getParameter('SAMLRequest'); - var relayState = request.getParameter('RelayState'); - var samlRespObj; - - if (samlResponse != null) { - samlRespObj = ssoMod.client.getSamlObject(samlResponse); - if (ssoMod.client.isLogoutResponse(samlRespObj)) { - logoutCallback(); - if (log.isDebugEnabled()) { - sso.log.debug('Session Id Invalidated :::' + sso.sessionId); - } - // Invalidating the session after the callback - session.invalidate(); - } else { - if (log.isDebugEnabled()) { - sso.log.debug("Login request"); - } - // validating the signature - if (sso.responseSign) { - if (ssoMod.client.validateSignature(samlRespObj, sso.keyStoreProps)) { - var sessionObj = ssoMod.client.decodeSAMLLoginResponse(samlRespObj, samlResponse, - sso.sessionId); - if (log.isDebugEnabled()) { - sso.log.debug("Saml object session ID :::" + sessionObj.sessionId); - } - if (sessionObj.sessionIndex != null || sessionObj.sessionIndex != 'undefined') { - sso_sessions[sso_sessions[sessionObj.sessionIndex] = sessionObj.sessionId] = - sessionObj.sessionIndex; - if (log.isDebugEnabled()) { - sso.log.debug("Login successful"); - sso.log.debug('User is set :::' + sessionObj.loggedInUser); - } - loginCallback(sessionObj.loggedInUser); - } else { - sso.log.error("Session index invalid"); - } - } else { - sso.log.error("Response Signing failed"); - } - } else { - if (log.isDebugEnabled()) { - sso.log.debug("Response Signing is disabled"); - } - } - } - } - /* - Executed for single logout requests - */ - if (samlRequest != null) { - var index = ssoMod.client.decodeSAMLLogoutRequest(ssoMod.client.getSamlObject(samlRequest)); - var jSessionId = getSSOSessions()[index]; - delete getSSOSessions()[index]; - if (log.isDebugEnabled()) { - sso.log.debug('Backend logout received from store. The index is :::' + index); - sso.log.debug('Session Id Invalidated :::' + jSessionId); - } - session.invalidate(); - } - } -})(); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/modules/user.js b/modules/distribution/src/repository/jaggeryapps/iot/modules/user.js deleted file mode 100644 index 2dfff33e..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/modules/user.js +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -var userModule; -userModule = function () { - var log = new Log("modules/user.js"); - - var constants = require("/modules/constants.js"); - var utility = require("/modules/utility.js").utility; - - //var userManagementService = utility.getUserManagementService(); - - var publicMethods = {}; - var privateMethods = {}; - - /** - * Authenticate a user when he or she attempts to login to DC. - * - * @param username Username of the user - * @param password Password of the user - * @param successCallback Function to be called at the event of successful authentication - * @param failureCallback Function to be called at the event of failed authentication - */ - publicMethods.login = function (username, password, successCallback, failureCallback) { - var carbonModule = require("carbon"); - var carbonServer = application.get("carbonServer"); - try { - // get tenant specific full user name. - username = username + "@" + carbonModule.server.tenantDomain(); - // check if the user is an authenticated user. - var isAuthenticated = carbonServer.authenticate(username, password); - if (isAuthenticated) { - var tenantUser = carbonModule.server.tenantUser(username); - session.put(constants.USER_SESSION_KEY, tenantUser); - successCallback(tenantUser); - } else { - failureCallback(); - } - } catch (e) { - throw e; - } - }; - - /** - * Register user to dc-user-store. - * - * @param username Username of the user - * @param firstname First name of the user - * @param lastname Last name of the user - * @param emailAddress Email address of the user - * @param password Password of the user - * @param userRoles Roles assigned to the user - * - * @returns {number} HTTP Status code 201 if succeeded, 409 if user already exists - */ - publicMethods.registerUser = function (username, firstname, lastname, emailAddress, password, userRoles) { - var carbon = require('carbon'); - var tenantId = carbon.server.tenantId(); - var url = carbon.server.address('https') + "/admin/services"; - var server = new carbon.server.Server(url); - var userManager = new carbon.user.UserManager(server, tenantId); - - try { - if (userManager.userExists(username)) { - if (log.isDebugEnabled()) { - log.debug("A user with name '" + username + "' already exists."); - } - // http status code 409 refers to - conflict. - return 409; - } else { - var defaultUserClaims = privateMethods.buildDefaultUserClaims(firstname, lastname, emailAddress); - - userManager.addUser(username, password, userRoles, defaultUserClaims, "default"); - if (log.isDebugEnabled()) { - log.debug("A new user with name '" + username + "' was created."); - } - // http status code 201 refers to - created. - return 201; - } - } catch (e) { - throw e; - } - }; - - /** - * Add user to dc-user-store. - * - * @param username Username of the user - * @param firstname First name of the user - * @param lastname Last name of the user - * @param emailAddress Email address of the user - * @param userRoles Roles assigned to the user - * - * @returns {number} HTTP Status code 201 if succeeded, 409 if user already exists - */ - publicMethods.addUser = function (username, firstname, lastname, emailAddress, userRoles) { - var carbon = require('carbon'); - var tenantId = carbon.server.tenantId(); - var url = carbon.server.address('https') + "/admin/services"; - var server = new carbon.server.Server(url); - var userManager = new carbon.user.UserManager(server, tenantId); - - try { - if (userManager.userExists(username)) { - if (log.isDebugEnabled()) { - log.debug("A user with name '" + username + "' already exists."); - } - // http status code 409 refers to - conflict. - return 409; - } else { - var initialUserPassword = privateMethods.generateInitialUserPassword(); - var defaultUserClaims = privateMethods.buildDefaultUserClaims(firstname, lastname, emailAddress); - - userManager.addUser(username, initialUserPassword, userRoles, defaultUserClaims, "default"); - privateMethods.inviteUserToEnroll(username, initialUserPassword); - if (log.isDebugEnabled()) { - log.debug("A new user with name '" + username + "' was created."); - } - // http status code 201 refers to - created. - return 201; - } - } catch (e) { - throw e; - } - }; - - /** - * Remove an existing user from mdm-user-store. - * - * @param username Username of the user - * @returns {number} HTTP Status code 200 if succeeded, 409 if the user does not exist - */ - publicMethods.removeUser = function (username) { - var carbon = require('carbon'); - var tenantId = carbon.server.tenantId(); - var url = carbon.server.address('https') + "/admin/services"; - var server = new carbon.server.Server(url); - var userManager = new carbon.user.UserManager(server, tenantId); - - try { - if (userManager.userExists(username)) { - userManager.removeUser(username); - if (log.isDebugEnabled()) { - log.debug("An existing user with name '" + username + "' was removed."); - } - // http status code 200 refers to - success. - return 200; - } else { - if (log.isDebugEnabled()) { - log.debug("A user with name '" + username + "' does not exist to remove."); - } - // http status code 409 refers to - conflict. - return 409; - } - } catch (e) { - throw e; - } - }; - - /** - * Private method to be used by addUser() to - * generate an initial user password for a user. - * This will be the password used by a user for his initial login to the system. - * - * @returns {string} Initial User Password - */ - privateMethods.generateInitialUserPassword = function () { - var passwordLength = 6; - //defining the pool of characters to be used for initial password generation - var lowerCaseCharset = "abcdefghijklmnopqrstuvwxyz"; - var upperCaseCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - var numericCharset = "0123456789"; - - var totalCharset = lowerCaseCharset + upperCaseCharset + numericCharset; - var totalCharsetLength = totalCharset.length; - - var initialUserPassword = ""; - for (var i = 0; i < passwordLength; ++i) { - initialUserPassword += totalCharset.charAt(Math.floor(Math.random() * totalCharsetLength)); - } - if (log.isDebugEnabled()) { - log.debug("Initial password created for new user : " + initialUserPassword); - } - return String(initialUserPassword); - }; - - /** - * Build default user claims. - * - * @param firstname First name of the user - * @param lastname Last name of the user - * @param emailAddress Email address of the user - * - * @returns {Object} Default user claims to be provided - */ - privateMethods.buildDefaultUserClaims = function (firstname, lastname, emailAddress) { - var defaultUserClaims = { - "http://wso2.org/claims/givenname": firstname, - "http://wso2.org/claims/lastname": lastname, - "http://wso2.org/claims/emailaddress": emailAddress - }; - if (log.isDebugEnabled()) { - log.debug("ClaimMap created for new user : " + stringify(defaultUserClaims)); - } - return defaultUserClaims; - }; - - publicMethods.addPermissions = function (permissionList, path, init) { - var carbonModule = require("carbon"); - var carbonServer = application.get("carbonServer"); - var options = {system: true}; - if (init == "login") { - var carbonUser = session.get(constants.USER_SESSION_KEY); - if (carbonUser) { - options.tenantId = carbonUser.tenantId; - } - } - var registry = new carbonModule.registry.Registry(carbonServer, options); - var i, permission, resource; - for (i = 0; i < permissionList.length; i++) { - permission = permissionList[i]; - resource = { - collection : true, - name : permission.name, - properties : { - name : permission.name - } - }; - registry.put("/_system/governance/permission/" + path + "/" + permission.key, resource); - } - }; - - //publicMethods.getUsers = function () { - // var carbon = require('carbon'); - // - // var carbonUser = session.get(constants.USER_SESSION_KEY); - // if (!carbonUser) { - // log.error("User object was not found in the session"); - // throw constants.ERRORS.USER_NOT_FOUND; - // } - // - // var userList; - // try{ - // userList = userManagementService.getUsersForTenant(carbonUser.tenantId); - // }catch(e){ - // log.error("Error occurred while reading all users"); - // return []; - // } - // - // var users = []; - // var i, userObject; - // for (i = 0; i < userList.size(); i++) { - // userObject = userList.get(i); - // users.push({ - // "username" : userObject.getUserName(), - // "email" : userObject.getEmail(), - // "name" : userObject.getFirstName() + " " + userObject.getLastName() - // }); - // } - // return users; - //}; - - publicMethods.isAuthorized = function (permission) { - var carbonModule = require("carbon"); - var carbonServer = application.get("carbonServer"); - var carbonUser = session.get(constants.USER_SESSION_KEY); - if (!carbonUser) { - log.error("User object was not found in the session"); - throw constants.ERRORS.USER_NOT_FOUND; - } - var userManager = new carbonModule.user.UserManager(carbonServer, carbonUser.tenantId); - var user = new carbonModule.user.User(userManager, carbonUser.username); - return user.isAuthorized(permission, "ui.execute"); - }; - - publicMethods.logout = function (successCallback) { - session.invalidate(); - successCallback(); - }; - - return publicMethods; -}(); - - diff --git a/modules/distribution/src/repository/jaggeryapps/iot/modules/utility.js b/modules/distribution/src/repository/jaggeryapps/iot/modules/utility.js deleted file mode 100644 index 6286701b..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/modules/utility.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -var utility; -utility = function () { - //var JavaClass = Packages.java.lang.Class; - //var PrivilegedCarbonContext = Packages.org.wso2.carbon.context.PrivilegedCarbonContext; - - //var getOsgiService = function (className) { - // var log = new Log(); - // log.info("###### Current Class : "+className); - // return PrivilegedCarbonContext.getThreadLocalCarbonContext().getOSGiService(JavaClass.forName(className)); - //}; - - var publicMethods = {}; - - //publicMethods.getUserManagementService = function () { - // return getOsgiService('org.wso2.carbon.device.mgt.user.core.service.UserManagementService'); - //}; - - publicMethods.insertAppPermissions = function (userModule, type) { - userModule.addPermissions([{key: "device-mgt", name: "Device Management"}], "", type); - userModule.addPermissions([{key: "admin", name: "Device Management Admin"}], "device-mgt", type); - userModule.addPermissions([{key: "user", name: "Device Management User"}], "device-mgt", type); - - userModule.addPermissions([{key: "devices", name: "Devices"}], "device-mgt/admin", type); - userModule.addPermissions([{key: "devices/list", name: "List Devices"}], "device-mgt/admin", type); - userModule.addPermissions([{key: "devices/operation", name: "Perform Operation"}], "device-mgt/admin", type); - - userModule.addPermissions([{key: "users", name: "Users"}], "device-mgt/admin", type); - userModule.addPermissions([{key: "users/add", name: "Add New Users"}], "device-mgt/admin", type); - userModule.addPermissions([{key: "users/invite", name: "Invite Users"}], "device-mgt/admin", type); - userModule.addPermissions([{key: "users/list", name: "List Users"}], "device-mgt/admin", type); - userModule.addPermissions([{key: "users/remove", name: "Remove Users"}], "device-mgt/admin", type); - - userModule.addPermissions([{key: "devices", name: "Devices"}], "device-mgt/user", type); - userModule.addPermissions([{key: "devices/list", name: "List Devices"}], "device-mgt/user", type); - userModule.addPermissions([{key: "devices/operation", name: "Perform Operation"}], "device-mgt/user", "init"); - }; - - return publicMethods; -}(); - - diff --git a/modules/distribution/src/repository/jaggeryapps/iot/pages/alldevices.hbs b/modules/distribution/src/repository/jaggeryapps/iot/pages/alldevices.hbs deleted file mode 100644 index 8eefbed6..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/pages/alldevices.hbs +++ /dev/null @@ -1,9 +0,0 @@ -{{authorized}} -{{layout "fluid"}} -{{#zone "title"}} - WSO2 DC | My Devices List -{{/zone}} -{{#zone "body"}} - {{unit "appbar"}} - {{unit "alldevices"}} -{{/zone}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/pages/arduino.hbs b/modules/distribution/src/repository/jaggeryapps/iot/pages/arduino.hbs deleted file mode 100644 index 4b98689f..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/pages/arduino.hbs +++ /dev/null @@ -1,8 +0,0 @@ -{{layout "fluid"}} -{{#zone "title"}} - WSO2 DC | Arduino -{{/zone}} -{{#zone "body"}} - {{unit "appbar"}} - {{unit "devices/arduino"}} -{{/zone}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/pages/digitaldisplay.hbs b/modules/distribution/src/repository/jaggeryapps/iot/pages/digitaldisplay.hbs deleted file mode 100644 index c5e1ea5c..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/pages/digitaldisplay.hbs +++ /dev/null @@ -1,8 +0,0 @@ -{{layout "fluid"}} -{{#zone "title"}} - WSO2 DC | FireAlarm -{{/zone}} -{{#zone "body"}} - {{unit "appbar"}} - {{unit "devices/digitaldisplay"}} -{{/zone}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/pages/firealarm.hbs b/modules/distribution/src/repository/jaggeryapps/iot/pages/firealarm.hbs deleted file mode 100644 index f08d7738..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/pages/firealarm.hbs +++ /dev/null @@ -1,8 +0,0 @@ -{{layout "fluid"}} -{{#zone "title"}} - WSO2 DC | FireAlarm -{{/zone}} -{{#zone "body"}} - {{unit "appbar"}} - {{unit "devices/firealarm"}} -{{/zone}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/pages/index.hbs b/modules/distribution/src/repository/jaggeryapps/iot/pages/index.hbs deleted file mode 100644 index c92fd19c..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/pages/index.hbs +++ /dev/null @@ -1,8 +0,0 @@ -{{layout "fluid"}} -{{#zone "title"}} - WSO2 DC | Device Cloud -{{/zone}} -{{#zone "body"}} - {{unit "appbar"}} - {{unit "showcase"}} -{{/zone}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/pages/login.hbs b/modules/distribution/src/repository/jaggeryapps/iot/pages/login.hbs deleted file mode 100644 index e6825e02..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/pages/login.hbs +++ /dev/null @@ -1,8 +0,0 @@ -{{layout "fluid"}} -{{#zone "title"}} -WSO2 Device Cloud | Login -{{/zone}} -{{#zone "body"}} - {{unit "appbar"}} - {{unit "login"}} -{{/zone}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/pages/mydevice.hbs b/modules/distribution/src/repository/jaggeryapps/iot/pages/mydevice.hbs deleted file mode 100644 index 3f8b077d..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/pages/mydevice.hbs +++ /dev/null @@ -1,9 +0,0 @@ -{{authorized}} -{{layout "fluid"}} -{{#zone "title"}} - WSO2 DC | FireAlarm -{{/zone}} -{{#zone "body"}} - {{unit "appbar"}} - {{unit "mydevice"}} -{{/zone}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/pages/sensebot.hbs b/modules/distribution/src/repository/jaggeryapps/iot/pages/sensebot.hbs deleted file mode 100644 index f9755dc8..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/pages/sensebot.hbs +++ /dev/null @@ -1,8 +0,0 @@ -{{layout "fluid"}} -{{#zone "title"}} - WSO2 DC | FireAlarm -{{/zone}} -{{#zone "body"}} - {{unit "appbar"}} - {{unit "devices/sensebot"}} -{{/zone}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/test/testExecutor.jag b/modules/distribution/src/repository/jaggeryapps/iot/test/testExecutor.jag deleted file mode 100644 index 8701e7ba..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/test/testExecutor.jag +++ /dev/null @@ -1,20 +0,0 @@ -<% -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -require("jaggery-test").test.run(); -%> \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/tmp/cached_theme_less_base.css b/modules/distribution/src/repository/jaggeryapps/iot/tmp/cached_theme_less_base.css deleted file mode 100644 index 6edb4b23..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/tmp/cached_theme_less_base.css +++ /dev/null @@ -1,6293 +0,0 @@ -/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ -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: bold; -} -dfn { - font-style: italic; -} -h1 { - font-size: 2em; - margin: 0.67em 0; -} -mark { - background: #ff0; - color: #000; -} -small { - font-size: 80%; -} -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} -sup { - top: -0.5em; -} -sub { - bottom: -0.25em; -} -img { - border: 0; -} -svg:not(:root) { - overflow: hidden; -} -figure { - margin: 1em 40px; -} -hr { - -moz-box-sizing: content-box; - 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; - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - box-sizing: content-box; -} -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} -legend { - border: 0; - padding: 0; -} -textarea { - overflow: auto; -} -optgroup { - font-weight: bold; -} -table { - border-collapse: collapse; - border-spacing: 0; -} -td, -th { - padding: 0; -} -/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ -@media print { - *, - *:before, - *:after { - background: transparent !important; - color: #000 !important; - box-shadow: none !important; - text-shadow: none !important; - } - a, - a:visited { - text-decoration: underline; - } - a[href]:after { - content: " (" attr(href) ")"; - } - abbr[title]:after { - content: " (" attr(title) ")"; - } - a[href^="#"]:after, - a[href^="javascript:"]:after { - content: ""; - } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - thead { - display: table-header-group; - } - tr, - img { - page-break-inside: avoid; - } - img { - max-width: 100% !important; - } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - h2, - h3 { - page-break-after: avoid; - } - select { - background: #fff !important; - } - .navbar { - display: none; - } - .btn > .caret, - .dropup > .btn > .caret { - border-top-color: #000 !important; - } - .label { - border: 1px solid #000; - } - .table { - border-collapse: collapse !important; - } - .table td, - .table th { - background-color: #fff !important; - } - .table-bordered th, - .table-bordered td { - border: 1px solid #ddd !important; - } -} -@font-face { - font-family: 'Glyphicons Halflings'; - src: url('../fonts/glyphicons-halflings-regular.eot'); - src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); -} -.glyphicon { - position: relative; - top: 1px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - font-style: normal; - font-weight: normal; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} -.glyphicon-asterisk:before { - content: "\2a"; -} -.glyphicon-plus:before { - content: "\2b"; -} -.glyphicon-euro:before, -.glyphicon-eur:before { - content: "\20ac"; -} -.glyphicon-minus:before { - content: "\2212"; -} -.glyphicon-cloud:before { - content: "\2601"; -} -.glyphicon-envelope:before { - content: "\2709"; -} -.glyphicon-pencil:before { - content: "\270f"; -} -.glyphicon-glass:before { - content: "\e001"; -} -.glyphicon-music:before { - content: "\e002"; -} -.glyphicon-search:before { - content: "\e003"; -} -.glyphicon-heart:before { - content: "\e005"; -} -.glyphicon-star:before { - content: "\e006"; -} -.glyphicon-star-empty:before { - content: "\e007"; -} -.glyphicon-user:before { - content: "\e008"; -} -.glyphicon-film:before { - content: "\e009"; -} -.glyphicon-th-large:before { - content: "\e010"; -} -.glyphicon-th:before { - content: "\e011"; -} -.glyphicon-th-list:before { - content: "\e012"; -} -.glyphicon-ok:before { - content: "\e013"; -} -.glyphicon-remove:before { - content: "\e014"; -} -.glyphicon-zoom-in:before { - content: "\e015"; -} -.glyphicon-zoom-out:before { - content: "\e016"; -} -.glyphicon-off:before { - content: "\e017"; -} -.glyphicon-signal:before { - content: "\e018"; -} -.glyphicon-cog:before { - content: "\e019"; -} -.glyphicon-trash:before { - content: "\e020"; -} -.glyphicon-home:before { - content: "\e021"; -} -.glyphicon-file:before { - content: "\e022"; -} -.glyphicon-time:before { - content: "\e023"; -} -.glyphicon-road:before { - content: "\e024"; -} -.glyphicon-download-alt:before { - content: "\e025"; -} -.glyphicon-download:before { - content: "\e026"; -} -.glyphicon-upload:before { - content: "\e027"; -} -.glyphicon-inbox:before { - content: "\e028"; -} -.glyphicon-play-circle:before { - content: "\e029"; -} -.glyphicon-repeat:before { - content: "\e030"; -} -.glyphicon-refresh:before { - content: "\e031"; -} -.glyphicon-list-alt:before { - content: "\e032"; -} -.glyphicon-lock:before { - content: "\e033"; -} -.glyphicon-flag:before { - content: "\e034"; -} -.glyphicon-headphones:before { - content: "\e035"; -} -.glyphicon-volume-off:before { - content: "\e036"; -} -.glyphicon-volume-down:before { - content: "\e037"; -} -.glyphicon-volume-up:before { - content: "\e038"; -} -.glyphicon-qrcode:before { - content: "\e039"; -} -.glyphicon-barcode:before { - content: "\e040"; -} -.glyphicon-tag:before { - content: "\e041"; -} -.glyphicon-tags:before { - content: "\e042"; -} -.glyphicon-book:before { - content: "\e043"; -} -.glyphicon-bookmark:before { - content: "\e044"; -} -.glyphicon-print:before { - content: "\e045"; -} -.glyphicon-camera:before { - content: "\e046"; -} -.glyphicon-font:before { - content: "\e047"; -} -.glyphicon-bold:before { - content: "\e048"; -} -.glyphicon-italic:before { - content: "\e049"; -} -.glyphicon-text-height:before { - content: "\e050"; -} -.glyphicon-text-width:before { - content: "\e051"; -} -.glyphicon-align-left:before { - content: "\e052"; -} -.glyphicon-align-center:before { - content: "\e053"; -} -.glyphicon-align-right:before { - content: "\e054"; -} -.glyphicon-align-justify:before { - content: "\e055"; -} -.glyphicon-list:before { - content: "\e056"; -} -.glyphicon-indent-left:before { - content: "\e057"; -} -.glyphicon-indent-right:before { - content: "\e058"; -} -.glyphicon-facetime-video:before { - content: "\e059"; -} -.glyphicon-picture:before { - content: "\e060"; -} -.glyphicon-map-marker:before { - content: "\e062"; -} -.glyphicon-adjust:before { - content: "\e063"; -} -.glyphicon-tint:before { - content: "\e064"; -} -.glyphicon-edit:before { - content: "\e065"; -} -.glyphicon-share:before { - content: "\e066"; -} -.glyphicon-check:before { - content: "\e067"; -} -.glyphicon-move:before { - content: "\e068"; -} -.glyphicon-step-backward:before { - content: "\e069"; -} -.glyphicon-fast-backward:before { - content: "\e070"; -} -.glyphicon-backward:before { - content: "\e071"; -} -.glyphicon-play:before { - content: "\e072"; -} -.glyphicon-pause:before { - content: "\e073"; -} -.glyphicon-stop:before { - content: "\e074"; -} -.glyphicon-forward:before { - content: "\e075"; -} -.glyphicon-fast-forward:before { - content: "\e076"; -} -.glyphicon-step-forward:before { - content: "\e077"; -} -.glyphicon-eject:before { - content: "\e078"; -} -.glyphicon-chevron-left:before { - content: "\e079"; -} -.glyphicon-chevron-right:before { - content: "\e080"; -} -.glyphicon-plus-sign:before { - content: "\e081"; -} -.glyphicon-minus-sign:before { - content: "\e082"; -} -.glyphicon-remove-sign:before { - content: "\e083"; -} -.glyphicon-ok-sign:before { - content: "\e084"; -} -.glyphicon-question-sign:before { - content: "\e085"; -} -.glyphicon-info-sign:before { - content: "\e086"; -} -.glyphicon-screenshot:before { - content: "\e087"; -} -.glyphicon-remove-circle:before { - content: "\e088"; -} -.glyphicon-ok-circle:before { - content: "\e089"; -} -.glyphicon-ban-circle:before { - content: "\e090"; -} -.glyphicon-arrow-left:before { - content: "\e091"; -} -.glyphicon-arrow-right:before { - content: "\e092"; -} -.glyphicon-arrow-up:before { - content: "\e093"; -} -.glyphicon-arrow-down:before { - content: "\e094"; -} -.glyphicon-share-alt:before { - content: "\e095"; -} -.glyphicon-resize-full:before { - content: "\e096"; -} -.glyphicon-resize-small:before { - content: "\e097"; -} -.glyphicon-exclamation-sign:before { - content: "\e101"; -} -.glyphicon-gift:before { - content: "\e102"; -} -.glyphicon-leaf:before { - content: "\e103"; -} -.glyphicon-fire:before { - content: "\e104"; -} -.glyphicon-eye-open:before { - content: "\e105"; -} -.glyphicon-eye-close:before { - content: "\e106"; -} -.glyphicon-warning-sign:before { - content: "\e107"; -} -.glyphicon-plane:before { - content: "\e108"; -} -.glyphicon-calendar:before { - content: "\e109"; -} -.glyphicon-random:before { - content: "\e110"; -} -.glyphicon-comment:before { - content: "\e111"; -} -.glyphicon-magnet:before { - content: "\e112"; -} -.glyphicon-chevron-up:before { - content: "\e113"; -} -.glyphicon-chevron-down:before { - content: "\e114"; -} -.glyphicon-retweet:before { - content: "\e115"; -} -.glyphicon-shopping-cart:before { - content: "\e116"; -} -.glyphicon-folder-close:before { - content: "\e117"; -} -.glyphicon-folder-open:before { - content: "\e118"; -} -.glyphicon-resize-vertical:before { - content: "\e119"; -} -.glyphicon-resize-horizontal:before { - content: "\e120"; -} -.glyphicon-hdd:before { - content: "\e121"; -} -.glyphicon-bullhorn:before { - content: "\e122"; -} -.glyphicon-bell:before { - content: "\e123"; -} -.glyphicon-certificate:before { - content: "\e124"; -} -.glyphicon-thumbs-up:before { - content: "\e125"; -} -.glyphicon-thumbs-down:before { - content: "\e126"; -} -.glyphicon-hand-right:before { - content: "\e127"; -} -.glyphicon-hand-left:before { - content: "\e128"; -} -.glyphicon-hand-up:before { - content: "\e129"; -} -.glyphicon-hand-down:before { - content: "\e130"; -} -.glyphicon-circle-arrow-right:before { - content: "\e131"; -} -.glyphicon-circle-arrow-left:before { - content: "\e132"; -} -.glyphicon-circle-arrow-up:before { - content: "\e133"; -} -.glyphicon-circle-arrow-down:before { - content: "\e134"; -} -.glyphicon-globe:before { - content: "\e135"; -} -.glyphicon-wrench:before { - content: "\e136"; -} -.glyphicon-tasks:before { - content: "\e137"; -} -.glyphicon-filter:before { - content: "\e138"; -} -.glyphicon-briefcase:before { - content: "\e139"; -} -.glyphicon-fullscreen:before { - content: "\e140"; -} -.glyphicon-dashboard:before { - content: "\e141"; -} -.glyphicon-paperclip:before { - content: "\e142"; -} -.glyphicon-heart-empty:before { - content: "\e143"; -} -.glyphicon-link:before { - content: "\e144"; -} -.glyphicon-phone:before { - content: "\e145"; -} -.glyphicon-pushpin:before { - content: "\e146"; -} -.glyphicon-usd:before { - content: "\e148"; -} -.glyphicon-gbp:before { - content: "\e149"; -} -.glyphicon-sort:before { - content: "\e150"; -} -.glyphicon-sort-by-alphabet:before { - content: "\e151"; -} -.glyphicon-sort-by-alphabet-alt:before { - content: "\e152"; -} -.glyphicon-sort-by-order:before { - content: "\e153"; -} -.glyphicon-sort-by-order-alt:before { - content: "\e154"; -} -.glyphicon-sort-by-attributes:before { - content: "\e155"; -} -.glyphicon-sort-by-attributes-alt:before { - content: "\e156"; -} -.glyphicon-unchecked:before { - content: "\e157"; -} -.glyphicon-expand:before { - content: "\e158"; -} -.glyphicon-collapse-down:before { - content: "\e159"; -} -.glyphicon-collapse-up:before { - content: "\e160"; -} -.glyphicon-log-in:before { - content: "\e161"; -} -.glyphicon-flash:before { - content: "\e162"; -} -.glyphicon-log-out:before { - content: "\e163"; -} -.glyphicon-new-window:before { - content: "\e164"; -} -.glyphicon-record:before { - content: "\e165"; -} -.glyphicon-save:before { - content: "\e166"; -} -.glyphicon-open:before { - content: "\e167"; -} -.glyphicon-saved:before { - content: "\e168"; -} -.glyphicon-import:before { - content: "\e169"; -} -.glyphicon-export:before { - content: "\e170"; -} -.glyphicon-send:before { - content: "\e171"; -} -.glyphicon-floppy-disk:before { - content: "\e172"; -} -.glyphicon-floppy-saved:before { - content: "\e173"; -} -.glyphicon-floppy-remove:before { - content: "\e174"; -} -.glyphicon-floppy-save:before { - content: "\e175"; -} -.glyphicon-floppy-open:before { - content: "\e176"; -} -.glyphicon-credit-card:before { - content: "\e177"; -} -.glyphicon-transfer:before { - content: "\e178"; -} -.glyphicon-cutlery:before { - content: "\e179"; -} -.glyphicon-header:before { - content: "\e180"; -} -.glyphicon-compressed:before { - content: "\e181"; -} -.glyphicon-earphone:before { - content: "\e182"; -} -.glyphicon-phone-alt:before { - content: "\e183"; -} -.glyphicon-tower:before { - content: "\e184"; -} -.glyphicon-stats:before { - content: "\e185"; -} -.glyphicon-sd-video:before { - content: "\e186"; -} -.glyphicon-hd-video:before { - content: "\e187"; -} -.glyphicon-subtitles:before { - content: "\e188"; -} -.glyphicon-sound-stereo:before { - content: "\e189"; -} -.glyphicon-sound-dolby:before { - content: "\e190"; -} -.glyphicon-sound-5-1:before { - content: "\e191"; -} -.glyphicon-sound-6-1:before { - content: "\e192"; -} -.glyphicon-sound-7-1:before { - content: "\e193"; -} -.glyphicon-copyright-mark:before { - content: "\e194"; -} -.glyphicon-registration-mark:before { - content: "\e195"; -} -.glyphicon-cloud-download:before { - content: "\e197"; -} -.glyphicon-cloud-upload:before { - content: "\e198"; -} -.glyphicon-tree-conifer:before { - content: "\e199"; -} -.glyphicon-tree-deciduous:before { - content: "\e200"; -} -* { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -*:before, -*:after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -html { - font-size: 10px; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -} -body { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - line-height: 1.42857143; - color: #333333; - background-color: #ffffff; -} -input, -button, -select, -textarea { - font-family: inherit; - font-size: inherit; - line-height: inherit; -} -a { - color: #337ab7; - text-decoration: none; -} -a:hover, -a:focus { - color: #23527c; - text-decoration: underline; -} -a:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -figure { - margin: 0; -} -img { - vertical-align: middle; -} -.img-responsive, -.thumbnail > img, -.thumbnail a > img, -.carousel-inner > .item > img, -.carousel-inner > .item > a > img { - display: block; - max-width: 100%; - height: auto; -} -.img-rounded { - border-radius: 6px; -} -.img-thumbnail { - padding: 4px; - line-height: 1.42857143; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 4px; - -webkit-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; - display: inline-block; - max-width: 100%; - height: auto; -} -.img-circle { - border-radius: 50%; -} -hr { - margin-top: 20px; - margin-bottom: 20px; - border: 0; - border-top: 1px solid #eeeeee; -} -.sr-only { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; -} -.sr-only-focusable:active, -.sr-only-focusable:focus { - position: static; - width: auto; - height: auto; - margin: 0; - overflow: visible; - clip: auto; -} -h1, -h2, -h3, -h4, -h5, -h6, -.h1, -.h2, -.h3, -.h4, -.h5, -.h6 { - font-family: inherit; - font-weight: 500; - line-height: 1.1; - color: inherit; -} -h1 small, -h2 small, -h3 small, -h4 small, -h5 small, -h6 small, -.h1 small, -.h2 small, -.h3 small, -.h4 small, -.h5 small, -.h6 small, -h1 .small, -h2 .small, -h3 .small, -h4 .small, -h5 .small, -h6 .small, -.h1 .small, -.h2 .small, -.h3 .small, -.h4 .small, -.h5 .small, -.h6 .small { - font-weight: normal; - line-height: 1; - color: #777777; -} -h1, -.h1, -h2, -.h2, -h3, -.h3 { - margin-top: 20px; - margin-bottom: 10px; -} -h1 small, -.h1 small, -h2 small, -.h2 small, -h3 small, -.h3 small, -h1 .small, -.h1 .small, -h2 .small, -.h2 .small, -h3 .small, -.h3 .small { - font-size: 65%; -} -h4, -.h4, -h5, -.h5, -h6, -.h6 { - margin-top: 10px; - margin-bottom: 10px; -} -h4 small, -.h4 small, -h5 small, -.h5 small, -h6 small, -.h6 small, -h4 .small, -.h4 .small, -h5 .small, -.h5 .small, -h6 .small, -.h6 .small { - font-size: 75%; -} -h1, -.h1 { - font-size: 36px; -} -h2, -.h2 { - font-size: 30px; -} -h3, -.h3 { - font-size: 24px; -} -h4, -.h4 { - font-size: 18px; -} -h5, -.h5 { - font-size: 14px; -} -h6, -.h6 { - font-size: 12px; -} -p { - margin: 0 0 10px; -} -.lead { - margin-bottom: 20px; - font-size: 16px; - font-weight: 300; - line-height: 1.4; -} -@media (min-width: 768px) { - .lead { - font-size: 21px; - } -} -small, -.small { - font-size: 85%; -} -mark, -.mark { - background-color: #fcf8e3; - padding: .2em; -} -.text-left { - text-align: left; -} -.text-right { - text-align: right; -} -.text-center { - text-align: center; -} -.text-justify { - text-align: justify; -} -.text-nowrap { - white-space: nowrap; -} -.text-lowercase { - text-transform: lowercase; -} -.text-uppercase { - text-transform: uppercase; -} -.text-capitalize { - text-transform: capitalize; -} -.text-muted { - color: #777777; -} -.text-primary { - color: #337ab7; -} -a.text-primary:hover { - color: #286090; -} -.text-success { - color: #3c763d; -} -a.text-success:hover { - color: #2b542c; -} -.text-info { - color: #31708f; -} -a.text-info:hover { - color: #245269; -} -.text-warning { - color: #8a6d3b; -} -a.text-warning:hover { - color: #66512c; -} -.text-danger { - color: #a94442; -} -a.text-danger:hover { - color: #843534; -} -.bg-primary { - color: #fff; - background-color: #337ab7; -} -a.bg-primary:hover { - background-color: #286090; -} -.bg-success { - background-color: #dff0d8; -} -a.bg-success:hover { - background-color: #c1e2b3; -} -.bg-info { - background-color: #d9edf7; -} -a.bg-info:hover { - background-color: #afd9ee; -} -.bg-warning { - background-color: #fcf8e3; -} -a.bg-warning:hover { - background-color: #f7ecb5; -} -.bg-danger { - background-color: #f2dede; -} -a.bg-danger:hover { - background-color: #e4b9b9; -} -.page-header { - padding-bottom: 9px; - margin: 40px 0 20px; - border-bottom: 1px solid #eeeeee; -} -ul, -ol { - margin-top: 0; - margin-bottom: 10px; -} -ul ul, -ol ul, -ul ol, -ol ol { - margin-bottom: 0; -} -.list-unstyled { - padding-left: 0; - list-style: none; -} -.list-inline { - padding-left: 0; - list-style: none; - margin-left: -5px; -} -.list-inline > li { - display: inline-block; - padding-left: 5px; - padding-right: 5px; -} -dl { - margin-top: 0; - margin-bottom: 20px; -} -dt, -dd { - line-height: 1.42857143; -} -dt { - font-weight: bold; -} -dd { - margin-left: 0; -} -@media (min-width: 768px) { - .dl-horizontal dt { - float: left; - width: 160px; - clear: left; - text-align: right; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .dl-horizontal dd { - margin-left: 180px; - } -} -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #777777; -} -.initialism { - font-size: 90%; - text-transform: uppercase; -} -blockquote { - padding: 10px 20px; - margin: 0 0 20px; - font-size: 17.5px; - border-left: 5px solid #eeeeee; -} -blockquote p:last-child, -blockquote ul:last-child, -blockquote ol:last-child { - margin-bottom: 0; -} -blockquote footer, -blockquote small, -blockquote .small { - display: block; - font-size: 80%; - line-height: 1.42857143; - color: #777777; -} -blockquote footer:before, -blockquote small:before, -blockquote .small:before { - content: '\2014 \00A0'; -} -.blockquote-reverse, -blockquote.pull-right { - padding-right: 15px; - padding-left: 0; - border-right: 5px solid #eeeeee; - border-left: 0; - text-align: right; -} -.blockquote-reverse footer:before, -blockquote.pull-right footer:before, -.blockquote-reverse small:before, -blockquote.pull-right small:before, -.blockquote-reverse .small:before, -blockquote.pull-right .small:before { - content: ''; -} -.blockquote-reverse footer:after, -blockquote.pull-right footer:after, -.blockquote-reverse small:after, -blockquote.pull-right small:after, -.blockquote-reverse .small:after, -blockquote.pull-right .small:after { - content: '\00A0 \2014'; -} -address { - margin-bottom: 20px; - font-style: normal; - line-height: 1.42857143; -} -code, -kbd, -pre, -samp { - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; -} -code { - padding: 2px 4px; - font-size: 90%; - color: #c7254e; - background-color: #f9f2f4; - border-radius: 4px; -} -kbd { - padding: 2px 4px; - font-size: 90%; - color: #ffffff; - background-color: #333333; - border-radius: 3px; - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); -} -kbd kbd { - padding: 0; - font-size: 100%; - font-weight: bold; - box-shadow: none; -} -pre { - display: block; - padding: 9.5px; - margin: 0 0 10px; - font-size: 13px; - line-height: 1.42857143; - word-break: break-all; - word-wrap: break-word; - color: #333333; - background-color: #f5f5f5; - border: 1px solid #cccccc; - border-radius: 4px; -} -pre code { - padding: 0; - font-size: inherit; - color: inherit; - white-space: pre-wrap; - background-color: transparent; - border-radius: 0; -} -.pre-scrollable { - max-height: 340px; - overflow-y: scroll; -} -.container { - margin-right: auto; - margin-left: auto; - padding-left: 15px; - padding-right: 15px; -} -@media (min-width: 768px) { - .container { - width: 750px; - } -} -@media (min-width: 992px) { - .container { - width: 970px; - } -} -@media (min-width: 1200px) { - .container { - width: 1170px; - } -} -.container-fluid { - margin-right: auto; - margin-left: auto; - padding-left: 15px; - padding-right: 15px; -} -.row { - margin-left: -15px; - margin-right: -15px; -} -.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { - position: relative; - min-height: 1px; - padding-left: 15px; - padding-right: 15px; -} -.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { - float: left; -} -.col-xs-12 { - width: 100%; -} -.col-xs-11 { - width: 91.66666667%; -} -.col-xs-10 { - width: 83.33333333%; -} -.col-xs-9 { - width: 75%; -} -.col-xs-8 { - width: 66.66666667%; -} -.col-xs-7 { - width: 58.33333333%; -} -.col-xs-6 { - width: 50%; -} -.col-xs-5 { - width: 41.66666667%; -} -.col-xs-4 { - width: 33.33333333%; -} -.col-xs-3 { - width: 25%; -} -.col-xs-2 { - width: 16.66666667%; -} -.col-xs-1 { - width: 8.33333333%; -} -.col-xs-pull-12 { - right: 100%; -} -.col-xs-pull-11 { - right: 91.66666667%; -} -.col-xs-pull-10 { - right: 83.33333333%; -} -.col-xs-pull-9 { - right: 75%; -} -.col-xs-pull-8 { - right: 66.66666667%; -} -.col-xs-pull-7 { - right: 58.33333333%; -} -.col-xs-pull-6 { - right: 50%; -} -.col-xs-pull-5 { - right: 41.66666667%; -} -.col-xs-pull-4 { - right: 33.33333333%; -} -.col-xs-pull-3 { - right: 25%; -} -.col-xs-pull-2 { - right: 16.66666667%; -} -.col-xs-pull-1 { - right: 8.33333333%; -} -.col-xs-pull-0 { - right: auto; -} -.col-xs-push-12 { - left: 100%; -} -.col-xs-push-11 { - left: 91.66666667%; -} -.col-xs-push-10 { - left: 83.33333333%; -} -.col-xs-push-9 { - left: 75%; -} -.col-xs-push-8 { - left: 66.66666667%; -} -.col-xs-push-7 { - left: 58.33333333%; -} -.col-xs-push-6 { - left: 50%; -} -.col-xs-push-5 { - left: 41.66666667%; -} -.col-xs-push-4 { - left: 33.33333333%; -} -.col-xs-push-3 { - left: 25%; -} -.col-xs-push-2 { - left: 16.66666667%; -} -.col-xs-push-1 { - left: 8.33333333%; -} -.col-xs-push-0 { - left: auto; -} -.col-xs-offset-12 { - margin-left: 100%; -} -.col-xs-offset-11 { - margin-left: 91.66666667%; -} -.col-xs-offset-10 { - margin-left: 83.33333333%; -} -.col-xs-offset-9 { - margin-left: 75%; -} -.col-xs-offset-8 { - margin-left: 66.66666667%; -} -.col-xs-offset-7 { - margin-left: 58.33333333%; -} -.col-xs-offset-6 { - margin-left: 50%; -} -.col-xs-offset-5 { - margin-left: 41.66666667%; -} -.col-xs-offset-4 { - margin-left: 33.33333333%; -} -.col-xs-offset-3 { - margin-left: 25%; -} -.col-xs-offset-2 { - margin-left: 16.66666667%; -} -.col-xs-offset-1 { - margin-left: 8.33333333%; -} -.col-xs-offset-0 { - margin-left: 0%; -} -@media (min-width: 768px) { - .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { - float: left; - } - .col-sm-12 { - width: 100%; - } - .col-sm-11 { - width: 91.66666667%; - } - .col-sm-10 { - width: 83.33333333%; - } - .col-sm-9 { - width: 75%; - } - .col-sm-8 { - width: 66.66666667%; - } - .col-sm-7 { - width: 58.33333333%; - } - .col-sm-6 { - width: 50%; - } - .col-sm-5 { - width: 41.66666667%; - } - .col-sm-4 { - width: 33.33333333%; - } - .col-sm-3 { - width: 25%; - } - .col-sm-2 { - width: 16.66666667%; - } - .col-sm-1 { - width: 8.33333333%; - } - .col-sm-pull-12 { - right: 100%; - } - .col-sm-pull-11 { - right: 91.66666667%; - } - .col-sm-pull-10 { - right: 83.33333333%; - } - .col-sm-pull-9 { - right: 75%; - } - .col-sm-pull-8 { - right: 66.66666667%; - } - .col-sm-pull-7 { - right: 58.33333333%; - } - .col-sm-pull-6 { - right: 50%; - } - .col-sm-pull-5 { - right: 41.66666667%; - } - .col-sm-pull-4 { - right: 33.33333333%; - } - .col-sm-pull-3 { - right: 25%; - } - .col-sm-pull-2 { - right: 16.66666667%; - } - .col-sm-pull-1 { - right: 8.33333333%; - } - .col-sm-pull-0 { - right: auto; - } - .col-sm-push-12 { - left: 100%; - } - .col-sm-push-11 { - left: 91.66666667%; - } - .col-sm-push-10 { - left: 83.33333333%; - } - .col-sm-push-9 { - left: 75%; - } - .col-sm-push-8 { - left: 66.66666667%; - } - .col-sm-push-7 { - left: 58.33333333%; - } - .col-sm-push-6 { - left: 50%; - } - .col-sm-push-5 { - left: 41.66666667%; - } - .col-sm-push-4 { - left: 33.33333333%; - } - .col-sm-push-3 { - left: 25%; - } - .col-sm-push-2 { - left: 16.66666667%; - } - .col-sm-push-1 { - left: 8.33333333%; - } - .col-sm-push-0 { - left: auto; - } - .col-sm-offset-12 { - margin-left: 100%; - } - .col-sm-offset-11 { - margin-left: 91.66666667%; - } - .col-sm-offset-10 { - margin-left: 83.33333333%; - } - .col-sm-offset-9 { - margin-left: 75%; - } - .col-sm-offset-8 { - margin-left: 66.66666667%; - } - .col-sm-offset-7 { - margin-left: 58.33333333%; - } - .col-sm-offset-6 { - margin-left: 50%; - } - .col-sm-offset-5 { - margin-left: 41.66666667%; - } - .col-sm-offset-4 { - margin-left: 33.33333333%; - } - .col-sm-offset-3 { - margin-left: 25%; - } - .col-sm-offset-2 { - margin-left: 16.66666667%; - } - .col-sm-offset-1 { - margin-left: 8.33333333%; - } - .col-sm-offset-0 { - margin-left: 0%; - } -} -@media (min-width: 992px) { - .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { - float: left; - } - .col-md-12 { - width: 100%; - } - .col-md-11 { - width: 91.66666667%; - } - .col-md-10 { - width: 83.33333333%; - } - .col-md-9 { - width: 75%; - } - .col-md-8 { - width: 66.66666667%; - } - .col-md-7 { - width: 58.33333333%; - } - .col-md-6 { - width: 50%; - } - .col-md-5 { - width: 41.66666667%; - } - .col-md-4 { - width: 33.33333333%; - } - .col-md-3 { - width: 25%; - } - .col-md-2 { - width: 16.66666667%; - } - .col-md-1 { - width: 8.33333333%; - } - .col-md-pull-12 { - right: 100%; - } - .col-md-pull-11 { - right: 91.66666667%; - } - .col-md-pull-10 { - right: 83.33333333%; - } - .col-md-pull-9 { - right: 75%; - } - .col-md-pull-8 { - right: 66.66666667%; - } - .col-md-pull-7 { - right: 58.33333333%; - } - .col-md-pull-6 { - right: 50%; - } - .col-md-pull-5 { - right: 41.66666667%; - } - .col-md-pull-4 { - right: 33.33333333%; - } - .col-md-pull-3 { - right: 25%; - } - .col-md-pull-2 { - right: 16.66666667%; - } - .col-md-pull-1 { - right: 8.33333333%; - } - .col-md-pull-0 { - right: auto; - } - .col-md-push-12 { - left: 100%; - } - .col-md-push-11 { - left: 91.66666667%; - } - .col-md-push-10 { - left: 83.33333333%; - } - .col-md-push-9 { - left: 75%; - } - .col-md-push-8 { - left: 66.66666667%; - } - .col-md-push-7 { - left: 58.33333333%; - } - .col-md-push-6 { - left: 50%; - } - .col-md-push-5 { - left: 41.66666667%; - } - .col-md-push-4 { - left: 33.33333333%; - } - .col-md-push-3 { - left: 25%; - } - .col-md-push-2 { - left: 16.66666667%; - } - .col-md-push-1 { - left: 8.33333333%; - } - .col-md-push-0 { - left: auto; - } - .col-md-offset-12 { - margin-left: 100%; - } - .col-md-offset-11 { - margin-left: 91.66666667%; - } - .col-md-offset-10 { - margin-left: 83.33333333%; - } - .col-md-offset-9 { - margin-left: 75%; - } - .col-md-offset-8 { - margin-left: 66.66666667%; - } - .col-md-offset-7 { - margin-left: 58.33333333%; - } - .col-md-offset-6 { - margin-left: 50%; - } - .col-md-offset-5 { - margin-left: 41.66666667%; - } - .col-md-offset-4 { - margin-left: 33.33333333%; - } - .col-md-offset-3 { - margin-left: 25%; - } - .col-md-offset-2 { - margin-left: 16.66666667%; - } - .col-md-offset-1 { - margin-left: 8.33333333%; - } - .col-md-offset-0 { - margin-left: 0%; - } -} -@media (min-width: 1200px) { - .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { - float: left; - } - .col-lg-12 { - width: 100%; - } - .col-lg-11 { - width: 91.66666667%; - } - .col-lg-10 { - width: 83.33333333%; - } - .col-lg-9 { - width: 75%; - } - .col-lg-8 { - width: 66.66666667%; - } - .col-lg-7 { - width: 58.33333333%; - } - .col-lg-6 { - width: 50%; - } - .col-lg-5 { - width: 41.66666667%; - } - .col-lg-4 { - width: 33.33333333%; - } - .col-lg-3 { - width: 25%; - } - .col-lg-2 { - width: 16.66666667%; - } - .col-lg-1 { - width: 8.33333333%; - } - .col-lg-pull-12 { - right: 100%; - } - .col-lg-pull-11 { - right: 91.66666667%; - } - .col-lg-pull-10 { - right: 83.33333333%; - } - .col-lg-pull-9 { - right: 75%; - } - .col-lg-pull-8 { - right: 66.66666667%; - } - .col-lg-pull-7 { - right: 58.33333333%; - } - .col-lg-pull-6 { - right: 50%; - } - .col-lg-pull-5 { - right: 41.66666667%; - } - .col-lg-pull-4 { - right: 33.33333333%; - } - .col-lg-pull-3 { - right: 25%; - } - .col-lg-pull-2 { - right: 16.66666667%; - } - .col-lg-pull-1 { - right: 8.33333333%; - } - .col-lg-pull-0 { - right: auto; - } - .col-lg-push-12 { - left: 100%; - } - .col-lg-push-11 { - left: 91.66666667%; - } - .col-lg-push-10 { - left: 83.33333333%; - } - .col-lg-push-9 { - left: 75%; - } - .col-lg-push-8 { - left: 66.66666667%; - } - .col-lg-push-7 { - left: 58.33333333%; - } - .col-lg-push-6 { - left: 50%; - } - .col-lg-push-5 { - left: 41.66666667%; - } - .col-lg-push-4 { - left: 33.33333333%; - } - .col-lg-push-3 { - left: 25%; - } - .col-lg-push-2 { - left: 16.66666667%; - } - .col-lg-push-1 { - left: 8.33333333%; - } - .col-lg-push-0 { - left: auto; - } - .col-lg-offset-12 { - margin-left: 100%; - } - .col-lg-offset-11 { - margin-left: 91.66666667%; - } - .col-lg-offset-10 { - margin-left: 83.33333333%; - } - .col-lg-offset-9 { - margin-left: 75%; - } - .col-lg-offset-8 { - margin-left: 66.66666667%; - } - .col-lg-offset-7 { - margin-left: 58.33333333%; - } - .col-lg-offset-6 { - margin-left: 50%; - } - .col-lg-offset-5 { - margin-left: 41.66666667%; - } - .col-lg-offset-4 { - margin-left: 33.33333333%; - } - .col-lg-offset-3 { - margin-left: 25%; - } - .col-lg-offset-2 { - margin-left: 16.66666667%; - } - .col-lg-offset-1 { - margin-left: 8.33333333%; - } - .col-lg-offset-0 { - margin-left: 0%; - } -} -table { - background-color: transparent; -} -caption { - padding-top: 8px; - padding-bottom: 8px; - color: #777777; - text-align: left; -} -th { - text-align: left; -} -.table { - width: 100%; - max-width: 100%; - margin-bottom: 20px; -} -.table > thead > tr > th, -.table > tbody > tr > th, -.table > tfoot > tr > th, -.table > thead > tr > td, -.table > tbody > tr > td, -.table > tfoot > tr > td { - padding: 8px; - line-height: 1.42857143; - vertical-align: top; - border-top: 1px solid #dddddd; -} -.table > thead > tr > th { - vertical-align: bottom; - border-bottom: 2px solid #dddddd; -} -.table > caption + thead > tr:first-child > th, -.table > colgroup + thead > tr:first-child > th, -.table > thead:first-child > tr:first-child > th, -.table > caption + thead > tr:first-child > td, -.table > colgroup + thead > tr:first-child > td, -.table > thead:first-child > tr:first-child > td { - border-top: 0; -} -.table > tbody + tbody { - border-top: 2px solid #dddddd; -} -.table .table { - background-color: #ffffff; -} -.table-condensed > thead > tr > th, -.table-condensed > tbody > tr > th, -.table-condensed > tfoot > tr > th, -.table-condensed > thead > tr > td, -.table-condensed > tbody > tr > td, -.table-condensed > tfoot > tr > td { - padding: 5px; -} -.table-bordered { - border: 1px solid #dddddd; -} -.table-bordered > thead > tr > th, -.table-bordered > tbody > tr > th, -.table-bordered > tfoot > tr > th, -.table-bordered > thead > tr > td, -.table-bordered > tbody > tr > td, -.table-bordered > tfoot > tr > td { - border: 1px solid #dddddd; -} -.table-bordered > thead > tr > th, -.table-bordered > thead > tr > td { - border-bottom-width: 2px; -} -.table-striped > tbody > tr:nth-child(odd) { - background-color: #f9f9f9; -} -.table-hover > tbody > tr:hover { - background-color: #f5f5f5; -} -table col[class*="col-"] { - position: static; - float: none; - display: table-column; -} -table td[class*="col-"], -table th[class*="col-"] { - position: static; - float: none; - display: table-cell; -} -.table > thead > tr > td.active, -.table > tbody > tr > td.active, -.table > tfoot > tr > td.active, -.table > thead > tr > th.active, -.table > tbody > tr > th.active, -.table > tfoot > tr > th.active, -.table > thead > tr.active > td, -.table > tbody > tr.active > td, -.table > tfoot > tr.active > td, -.table > thead > tr.active > th, -.table > tbody > tr.active > th, -.table > tfoot > tr.active > th { - background-color: #f5f5f5; -} -.table-hover > tbody > tr > td.active:hover, -.table-hover > tbody > tr > th.active:hover, -.table-hover > tbody > tr.active:hover > td, -.table-hover > tbody > tr:hover > .active, -.table-hover > tbody > tr.active:hover > th { - background-color: #e8e8e8; -} -.table > thead > tr > td.success, -.table > tbody > tr > td.success, -.table > tfoot > tr > td.success, -.table > thead > tr > th.success, -.table > tbody > tr > th.success, -.table > tfoot > tr > th.success, -.table > thead > tr.success > td, -.table > tbody > tr.success > td, -.table > tfoot > tr.success > td, -.table > thead > tr.success > th, -.table > tbody > tr.success > th, -.table > tfoot > tr.success > th { - background-color: #dff0d8; -} -.table-hover > tbody > tr > td.success:hover, -.table-hover > tbody > tr > th.success:hover, -.table-hover > tbody > tr.success:hover > td, -.table-hover > tbody > tr:hover > .success, -.table-hover > tbody > tr.success:hover > th { - background-color: #d0e9c6; -} -.table > thead > tr > td.info, -.table > tbody > tr > td.info, -.table > tfoot > tr > td.info, -.table > thead > tr > th.info, -.table > tbody > tr > th.info, -.table > tfoot > tr > th.info, -.table > thead > tr.info > td, -.table > tbody > tr.info > td, -.table > tfoot > tr.info > td, -.table > thead > tr.info > th, -.table > tbody > tr.info > th, -.table > tfoot > tr.info > th { - background-color: #d9edf7; -} -.table-hover > tbody > tr > td.info:hover, -.table-hover > tbody > tr > th.info:hover, -.table-hover > tbody > tr.info:hover > td, -.table-hover > tbody > tr:hover > .info, -.table-hover > tbody > tr.info:hover > th { - background-color: #c4e3f3; -} -.table > thead > tr > td.warning, -.table > tbody > tr > td.warning, -.table > tfoot > tr > td.warning, -.table > thead > tr > th.warning, -.table > tbody > tr > th.warning, -.table > tfoot > tr > th.warning, -.table > thead > tr.warning > td, -.table > tbody > tr.warning > td, -.table > tfoot > tr.warning > td, -.table > thead > tr.warning > th, -.table > tbody > tr.warning > th, -.table > tfoot > tr.warning > th { - background-color: #fcf8e3; -} -.table-hover > tbody > tr > td.warning:hover, -.table-hover > tbody > tr > th.warning:hover, -.table-hover > tbody > tr.warning:hover > td, -.table-hover > tbody > tr:hover > .warning, -.table-hover > tbody > tr.warning:hover > th { - background-color: #faf2cc; -} -.table > thead > tr > td.danger, -.table > tbody > tr > td.danger, -.table > tfoot > tr > td.danger, -.table > thead > tr > th.danger, -.table > tbody > tr > th.danger, -.table > tfoot > tr > th.danger, -.table > thead > tr.danger > td, -.table > tbody > tr.danger > td, -.table > tfoot > tr.danger > td, -.table > thead > tr.danger > th, -.table > tbody > tr.danger > th, -.table > tfoot > tr.danger > th { - background-color: #f2dede; -} -.table-hover > tbody > tr > td.danger:hover, -.table-hover > tbody > tr > th.danger:hover, -.table-hover > tbody > tr.danger:hover > td, -.table-hover > tbody > tr:hover > .danger, -.table-hover > tbody > tr.danger:hover > th { - background-color: #ebcccc; -} -.table-responsive { - overflow-x: auto; - min-height: 0.01%; -} -@media screen and (max-width: 767px) { - .table-responsive { - width: 100%; - margin-bottom: 15px; - overflow-y: hidden; - -ms-overflow-style: -ms-autohiding-scrollbar; - border: 1px solid #dddddd; - } - .table-responsive > .table { - margin-bottom: 0; - } - .table-responsive > .table > thead > tr > th, - .table-responsive > .table > tbody > tr > th, - .table-responsive > .table > tfoot > tr > th, - .table-responsive > .table > thead > tr > td, - .table-responsive > .table > tbody > tr > td, - .table-responsive > .table > tfoot > tr > td { - white-space: nowrap; - } - .table-responsive > .table-bordered { - border: 0; - } - .table-responsive > .table-bordered > thead > tr > th:first-child, - .table-responsive > .table-bordered > tbody > tr > th:first-child, - .table-responsive > .table-bordered > tfoot > tr > th:first-child, - .table-responsive > .table-bordered > thead > tr > td:first-child, - .table-responsive > .table-bordered > tbody > tr > td:first-child, - .table-responsive > .table-bordered > tfoot > tr > td:first-child { - border-left: 0; - } - .table-responsive > .table-bordered > thead > tr > th:last-child, - .table-responsive > .table-bordered > tbody > tr > th:last-child, - .table-responsive > .table-bordered > tfoot > tr > th:last-child, - .table-responsive > .table-bordered > thead > tr > td:last-child, - .table-responsive > .table-bordered > tbody > tr > td:last-child, - .table-responsive > .table-bordered > tfoot > tr > td:last-child { - border-right: 0; - } - .table-responsive > .table-bordered > tbody > tr:last-child > th, - .table-responsive > .table-bordered > tfoot > tr:last-child > th, - .table-responsive > .table-bordered > tbody > tr:last-child > td, - .table-responsive > .table-bordered > tfoot > tr:last-child > td { - border-bottom: 0; - } -} -fieldset { - padding: 0; - margin: 0; - border: 0; - min-width: 0; -} -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: 20px; - font-size: 21px; - line-height: inherit; - color: #333333; - border: 0; - border-bottom: 1px solid #e5e5e5; -} -label { - display: inline-block; - max-width: 100%; - margin-bottom: 5px; - font-weight: bold; -} -input[type="search"] { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - margin-top: 1px \9; - line-height: normal; -} -input[type="file"] { - display: block; -} -input[type="range"] { - display: block; - width: 100%; -} -select[multiple], -select[size] { - height: auto; -} -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -output { - display: block; - padding-top: 7px; - font-size: 14px; - line-height: 1.42857143; - color: #555555; -} -.form-control { - display: block; - width: 100%; - height: 34px; - padding: 6px 12px; - font-size: 14px; - line-height: 1.42857143; - color: #555555; - background-color: #ffffff; - background-image: none; - border: 1px solid #cccccc; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; -} -.form-control:focus { - border-color: #66afe9; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); -} -.form-control::-moz-placeholder { - color: #999999; - opacity: 1; -} -.form-control:-ms-input-placeholder { - color: #999999; -} -.form-control::-webkit-input-placeholder { - color: #999999; -} -.form-control[disabled], -.form-control[readonly], -fieldset[disabled] .form-control { - cursor: not-allowed; - background-color: #eeeeee; - opacity: 1; -} -textarea.form-control { - height: auto; -} -input[type="search"] { - -webkit-appearance: none; -} -@media screen and (-webkit-min-device-pixel-ratio: 0) { - input[type="date"], - input[type="time"], - input[type="datetime-local"], - input[type="month"] { - line-height: 34px; - } - input[type="date"].input-sm, - input[type="time"].input-sm, - input[type="datetime-local"].input-sm, - input[type="month"].input-sm { - line-height: 30px; - } - input[type="date"].input-lg, - input[type="time"].input-lg, - input[type="datetime-local"].input-lg, - input[type="month"].input-lg { - line-height: 46px; - } -} -.form-group { - margin-bottom: 15px; -} -.radio, -.checkbox { - position: relative; - display: block; - margin-top: 10px; - margin-bottom: 10px; -} -.radio label, -.checkbox label { - min-height: 20px; - padding-left: 20px; - margin-bottom: 0; - font-weight: normal; - cursor: pointer; -} -.radio input[type="radio"], -.radio-inline input[type="radio"], -.checkbox input[type="checkbox"], -.checkbox-inline input[type="checkbox"] { - position: absolute; - margin-left: -20px; - margin-top: 4px \9; -} -.radio + .radio, -.checkbox + .checkbox { - margin-top: -5px; -} -.radio-inline, -.checkbox-inline { - display: inline-block; - padding-left: 20px; - margin-bottom: 0; - vertical-align: middle; - font-weight: normal; - cursor: pointer; -} -.radio-inline + .radio-inline, -.checkbox-inline + .checkbox-inline { - margin-top: 0; - margin-left: 10px; -} -input[type="radio"][disabled], -input[type="checkbox"][disabled], -input[type="radio"].disabled, -input[type="checkbox"].disabled, -fieldset[disabled] input[type="radio"], -fieldset[disabled] input[type="checkbox"] { - cursor: not-allowed; -} -.radio-inline.disabled, -.checkbox-inline.disabled, -fieldset[disabled] .radio-inline, -fieldset[disabled] .checkbox-inline { - cursor: not-allowed; -} -.radio.disabled label, -.checkbox.disabled label, -fieldset[disabled] .radio label, -fieldset[disabled] .checkbox label { - cursor: not-allowed; -} -.form-control-static { - padding-top: 7px; - padding-bottom: 7px; - margin-bottom: 0; -} -.form-control-static.input-lg, -.form-control-static.input-sm { - padding-left: 0; - padding-right: 0; -} -.input-sm, -.form-group-sm .form-control { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -select.input-sm, -select.form-group-sm .form-control { - height: 30px; - line-height: 30px; -} -textarea.input-sm, -textarea.form-group-sm .form-control, -select[multiple].input-sm, -select[multiple].form-group-sm .form-control { - height: auto; -} -.input-lg, -.form-group-lg .form-control { - height: 46px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} -select.input-lg, -select.form-group-lg .form-control { - height: 46px; - line-height: 46px; -} -textarea.input-lg, -textarea.form-group-lg .form-control, -select[multiple].input-lg, -select[multiple].form-group-lg .form-control { - height: auto; -} -.has-feedback { - position: relative; -} -.has-feedback .form-control { - padding-right: 42.5px; -} -.form-control-feedback { - position: absolute; - top: 0; - right: 0; - z-index: 2; - display: block; - width: 34px; - height: 34px; - line-height: 34px; - text-align: center; - pointer-events: none; -} -.input-lg + .form-control-feedback { - width: 46px; - height: 46px; - line-height: 46px; -} -.input-sm + .form-control-feedback { - width: 30px; - height: 30px; - line-height: 30px; -} -.has-success .help-block, -.has-success .control-label, -.has-success .radio, -.has-success .checkbox, -.has-success .radio-inline, -.has-success .checkbox-inline, -.has-success.radio label, -.has-success.checkbox label, -.has-success.radio-inline label, -.has-success.checkbox-inline label { - color: #3c763d; -} -.has-success .form-control { - border-color: #3c763d; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-success .form-control:focus { - border-color: #2b542c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; -} -.has-success .input-group-addon { - color: #3c763d; - border-color: #3c763d; - background-color: #dff0d8; -} -.has-success .form-control-feedback { - color: #3c763d; -} -.has-warning .help-block, -.has-warning .control-label, -.has-warning .radio, -.has-warning .checkbox, -.has-warning .radio-inline, -.has-warning .checkbox-inline, -.has-warning.radio label, -.has-warning.checkbox label, -.has-warning.radio-inline label, -.has-warning.checkbox-inline label { - color: #8a6d3b; -} -.has-warning .form-control { - border-color: #8a6d3b; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-warning .form-control:focus { - border-color: #66512c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; -} -.has-warning .input-group-addon { - color: #8a6d3b; - border-color: #8a6d3b; - background-color: #fcf8e3; -} -.has-warning .form-control-feedback { - color: #8a6d3b; -} -.has-error .help-block, -.has-error .control-label, -.has-error .radio, -.has-error .checkbox, -.has-error .radio-inline, -.has-error .checkbox-inline, -.has-error.radio label, -.has-error.checkbox label, -.has-error.radio-inline label, -.has-error.checkbox-inline label { - color: #a94442; -} -.has-error .form-control { - border-color: #a94442; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-error .form-control:focus { - border-color: #843534; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; -} -.has-error .input-group-addon { - color: #a94442; - border-color: #a94442; - background-color: #f2dede; -} -.has-error .form-control-feedback { - color: #a94442; -} -.has-feedback label ~ .form-control-feedback { - top: 25px; -} -.has-feedback label.sr-only ~ .form-control-feedback { - top: 0; -} -.help-block { - display: block; - margin-top: 5px; - margin-bottom: 10px; - color: #737373; -} -@media (min-width: 768px) { - .form-inline .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .form-control { - display: inline-block; - width: auto; - vertical-align: middle; - } - .form-inline .form-control-static { - display: inline-block; - } - .form-inline .input-group { - display: inline-table; - vertical-align: middle; - } - .form-inline .input-group .input-group-addon, - .form-inline .input-group .input-group-btn, - .form-inline .input-group .form-control { - width: auto; - } - .form-inline .input-group > .form-control { - width: 100%; - } - .form-inline .control-label { - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .radio, - .form-inline .checkbox { - display: inline-block; - margin-top: 0; - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .radio label, - .form-inline .checkbox label { - padding-left: 0; - } - .form-inline .radio input[type="radio"], - .form-inline .checkbox input[type="checkbox"] { - position: relative; - margin-left: 0; - } - .form-inline .has-feedback .form-control-feedback { - top: 0; - } -} -.form-horizontal .radio, -.form-horizontal .checkbox, -.form-horizontal .radio-inline, -.form-horizontal .checkbox-inline { - margin-top: 0; - margin-bottom: 0; - padding-top: 7px; -} -.form-horizontal .radio, -.form-horizontal .checkbox { - min-height: 27px; -} -.form-horizontal .form-group { - margin-left: -15px; - margin-right: -15px; -} -@media (min-width: 768px) { - .form-horizontal .control-label { - text-align: right; - margin-bottom: 0; - padding-top: 7px; - } -} -.form-horizontal .has-feedback .form-control-feedback { - right: 15px; -} -@media (min-width: 768px) { - .form-horizontal .form-group-lg .control-label { - padding-top: 14.3px; - } -} -@media (min-width: 768px) { - .form-horizontal .form-group-sm .control-label { - padding-top: 6px; - } -} -.btn { - display: inline-block; - margin-bottom: 0; - font-weight: normal; - text-align: center; - vertical-align: middle; - touch-action: manipulation; - cursor: pointer; - background-image: none; - border: 1px solid transparent; - white-space: nowrap; - padding: 6px 12px; - font-size: 14px; - line-height: 1.42857143; - border-radius: 4px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.btn:focus, -.btn:active:focus, -.btn.active:focus, -.btn.focus, -.btn:active.focus, -.btn.active.focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -.btn:hover, -.btn:focus, -.btn.focus { - color: #333333; - text-decoration: none; -} -.btn:active, -.btn.active { - outline: 0; - background-image: none; - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} -.btn.disabled, -.btn[disabled], -fieldset[disabled] .btn { - cursor: not-allowed; - pointer-events: none; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - box-shadow: none; -} -.btn-default { - color: #333333; - background-color: #ffffff; - border-color: #cccccc; -} -.btn-default:hover, -.btn-default:focus, -.btn-default.focus, -.btn-default:active, -.btn-default.active, -.open > .dropdown-toggle.btn-default { - color: #333333; - background-color: #e6e6e6; - border-color: #adadad; -} -.btn-default:active, -.btn-default.active, -.open > .dropdown-toggle.btn-default { - background-image: none; -} -.btn-default.disabled, -.btn-default[disabled], -fieldset[disabled] .btn-default, -.btn-default.disabled:hover, -.btn-default[disabled]:hover, -fieldset[disabled] .btn-default:hover, -.btn-default.disabled:focus, -.btn-default[disabled]:focus, -fieldset[disabled] .btn-default:focus, -.btn-default.disabled.focus, -.btn-default[disabled].focus, -fieldset[disabled] .btn-default.focus, -.btn-default.disabled:active, -.btn-default[disabled]:active, -fieldset[disabled] .btn-default:active, -.btn-default.disabled.active, -.btn-default[disabled].active, -fieldset[disabled] .btn-default.active { - background-color: #ffffff; - border-color: #cccccc; -} -.btn-default .badge { - color: #ffffff; - background-color: #333333; -} -.btn-primary { - color: #ffffff; - background-color: #337ab7; - border-color: #2e6da4; -} -.btn-primary:hover, -.btn-primary:focus, -.btn-primary.focus, -.btn-primary:active, -.btn-primary.active, -.open > .dropdown-toggle.btn-primary { - color: #ffffff; - background-color: #286090; - border-color: #204d74; -} -.btn-primary:active, -.btn-primary.active, -.open > .dropdown-toggle.btn-primary { - background-image: none; -} -.btn-primary.disabled, -.btn-primary[disabled], -fieldset[disabled] .btn-primary, -.btn-primary.disabled:hover, -.btn-primary[disabled]:hover, -fieldset[disabled] .btn-primary:hover, -.btn-primary.disabled:focus, -.btn-primary[disabled]:focus, -fieldset[disabled] .btn-primary:focus, -.btn-primary.disabled.focus, -.btn-primary[disabled].focus, -fieldset[disabled] .btn-primary.focus, -.btn-primary.disabled:active, -.btn-primary[disabled]:active, -fieldset[disabled] .btn-primary:active, -.btn-primary.disabled.active, -.btn-primary[disabled].active, -fieldset[disabled] .btn-primary.active { - background-color: #337ab7; - border-color: #2e6da4; -} -.btn-primary .badge { - color: #337ab7; - background-color: #ffffff; -} -.btn-success { - color: #ffffff; - background-color: #5cb85c; - border-color: #4cae4c; -} -.btn-success:hover, -.btn-success:focus, -.btn-success.focus, -.btn-success:active, -.btn-success.active, -.open > .dropdown-toggle.btn-success { - color: #ffffff; - background-color: #449d44; - border-color: #398439; -} -.btn-success:active, -.btn-success.active, -.open > .dropdown-toggle.btn-success { - background-image: none; -} -.btn-success.disabled, -.btn-success[disabled], -fieldset[disabled] .btn-success, -.btn-success.disabled:hover, -.btn-success[disabled]:hover, -fieldset[disabled] .btn-success:hover, -.btn-success.disabled:focus, -.btn-success[disabled]:focus, -fieldset[disabled] .btn-success:focus, -.btn-success.disabled.focus, -.btn-success[disabled].focus, -fieldset[disabled] .btn-success.focus, -.btn-success.disabled:active, -.btn-success[disabled]:active, -fieldset[disabled] .btn-success:active, -.btn-success.disabled.active, -.btn-success[disabled].active, -fieldset[disabled] .btn-success.active { - background-color: #5cb85c; - border-color: #4cae4c; -} -.btn-success .badge { - color: #5cb85c; - background-color: #ffffff; -} -.btn-info { - color: #ffffff; - background-color: #5bc0de; - border-color: #46b8da; -} -.btn-info:hover, -.btn-info:focus, -.btn-info.focus, -.btn-info:active, -.btn-info.active, -.open > .dropdown-toggle.btn-info { - color: #ffffff; - background-color: #31b0d5; - border-color: #269abc; -} -.btn-info:active, -.btn-info.active, -.open > .dropdown-toggle.btn-info { - background-image: none; -} -.btn-info.disabled, -.btn-info[disabled], -fieldset[disabled] .btn-info, -.btn-info.disabled:hover, -.btn-info[disabled]:hover, -fieldset[disabled] .btn-info:hover, -.btn-info.disabled:focus, -.btn-info[disabled]:focus, -fieldset[disabled] .btn-info:focus, -.btn-info.disabled.focus, -.btn-info[disabled].focus, -fieldset[disabled] .btn-info.focus, -.btn-info.disabled:active, -.btn-info[disabled]:active, -fieldset[disabled] .btn-info:active, -.btn-info.disabled.active, -.btn-info[disabled].active, -fieldset[disabled] .btn-info.active { - background-color: #5bc0de; - border-color: #46b8da; -} -.btn-info .badge { - color: #5bc0de; - background-color: #ffffff; -} -.btn-warning { - color: #ffffff; - background-color: #f0ad4e; - border-color: #eea236; -} -.btn-warning:hover, -.btn-warning:focus, -.btn-warning.focus, -.btn-warning:active, -.btn-warning.active, -.open > .dropdown-toggle.btn-warning { - color: #ffffff; - background-color: #ec971f; - border-color: #d58512; -} -.btn-warning:active, -.btn-warning.active, -.open > .dropdown-toggle.btn-warning { - background-image: none; -} -.btn-warning.disabled, -.btn-warning[disabled], -fieldset[disabled] .btn-warning, -.btn-warning.disabled:hover, -.btn-warning[disabled]:hover, -fieldset[disabled] .btn-warning:hover, -.btn-warning.disabled:focus, -.btn-warning[disabled]:focus, -fieldset[disabled] .btn-warning:focus, -.btn-warning.disabled.focus, -.btn-warning[disabled].focus, -fieldset[disabled] .btn-warning.focus, -.btn-warning.disabled:active, -.btn-warning[disabled]:active, -fieldset[disabled] .btn-warning:active, -.btn-warning.disabled.active, -.btn-warning[disabled].active, -fieldset[disabled] .btn-warning.active { - background-color: #f0ad4e; - border-color: #eea236; -} -.btn-warning .badge { - color: #f0ad4e; - background-color: #ffffff; -} -.btn-danger { - color: #ffffff; - background-color: #d9534f; - border-color: #d43f3a; -} -.btn-danger:hover, -.btn-danger:focus, -.btn-danger.focus, -.btn-danger:active, -.btn-danger.active, -.open > .dropdown-toggle.btn-danger { - color: #ffffff; - background-color: #c9302c; - border-color: #ac2925; -} -.btn-danger:active, -.btn-danger.active, -.open > .dropdown-toggle.btn-danger { - background-image: none; -} -.btn-danger.disabled, -.btn-danger[disabled], -fieldset[disabled] .btn-danger, -.btn-danger.disabled:hover, -.btn-danger[disabled]:hover, -fieldset[disabled] .btn-danger:hover, -.btn-danger.disabled:focus, -.btn-danger[disabled]:focus, -fieldset[disabled] .btn-danger:focus, -.btn-danger.disabled.focus, -.btn-danger[disabled].focus, -fieldset[disabled] .btn-danger.focus, -.btn-danger.disabled:active, -.btn-danger[disabled]:active, -fieldset[disabled] .btn-danger:active, -.btn-danger.disabled.active, -.btn-danger[disabled].active, -fieldset[disabled] .btn-danger.active { - background-color: #d9534f; - border-color: #d43f3a; -} -.btn-danger .badge { - color: #d9534f; - background-color: #ffffff; -} -.btn-link { - color: #337ab7; - font-weight: normal; - border-radius: 0; -} -.btn-link, -.btn-link:active, -.btn-link.active, -.btn-link[disabled], -fieldset[disabled] .btn-link { - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; -} -.btn-link, -.btn-link:hover, -.btn-link:focus, -.btn-link:active { - border-color: transparent; -} -.btn-link:hover, -.btn-link:focus { - color: #23527c; - text-decoration: underline; - background-color: transparent; -} -.btn-link[disabled]:hover, -fieldset[disabled] .btn-link:hover, -.btn-link[disabled]:focus, -fieldset[disabled] .btn-link:focus { - color: #777777; - text-decoration: none; -} -.btn-lg, -.btn-group-lg > .btn { - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} -.btn-sm, -.btn-group-sm > .btn { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -.btn-xs, -.btn-group-xs > .btn { - padding: 1px 5px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -.btn-block { - display: block; - width: 100%; -} -.btn-block + .btn-block { - margin-top: 5px; -} -input[type="submit"].btn-block, -input[type="reset"].btn-block, -input[type="button"].btn-block { - width: 100%; -} -.fade { - opacity: 0; - -webkit-transition: opacity 0.15s linear; - -o-transition: opacity 0.15s linear; - transition: opacity 0.15s linear; -} -.fade.in { - opacity: 1; -} -.collapse { - display: none; - visibility: hidden; -} -.collapse.in { - display: block; - visibility: visible; -} -tr.collapse.in { - display: table-row; -} -tbody.collapse.in { - display: table-row-group; -} -.collapsing { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition-property: height, visibility; - transition-property: height, visibility; - -webkit-transition-duration: 0.35s; - transition-duration: 0.35s; - -webkit-transition-timing-function: ease; - transition-timing-function: ease; -} -.caret { - display: inline-block; - width: 0; - height: 0; - margin-left: 2px; - vertical-align: middle; - border-top: 4px solid; - border-right: 4px solid transparent; - border-left: 4px solid transparent; -} -.dropdown { - position: relative; -} -.dropdown-toggle:focus { - outline: 0; -} -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - font-size: 14px; - text-align: left; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 4px; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - background-clip: padding-box; -} -.dropdown-menu.pull-right { - right: 0; - left: auto; -} -.dropdown-menu .divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5; -} -.dropdown-menu > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.42857143; - color: #333333; - white-space: nowrap; -} -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus { - text-decoration: none; - color: #262626; - background-color: #f5f5f5; -} -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - color: #ffffff; - text-decoration: none; - outline: 0; - background-color: #337ab7; -} -.dropdown-menu > .disabled > a, -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - color: #777777; -} -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - text-decoration: none; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - cursor: not-allowed; -} -.open > .dropdown-menu { - display: block; -} -.open > a { - outline: 0; -} -.dropdown-menu-right { - left: auto; - right: 0; -} -.dropdown-menu-left { - left: 0; - right: auto; -} -.dropdown-header { - display: block; - padding: 3px 20px; - font-size: 12px; - line-height: 1.42857143; - color: #777777; - white-space: nowrap; -} -.dropdown-backdrop { - position: fixed; - left: 0; - right: 0; - bottom: 0; - top: 0; - z-index: 990; -} -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} -.dropup .caret, -.navbar-fixed-bottom .dropdown .caret { - border-top: 0; - border-bottom: 4px solid; - content: ""; -} -.dropup .dropdown-menu, -.navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 1px; -} -@media (min-width: 768px) { - .navbar-right .dropdown-menu { - left: auto; - right: 0; - } - .navbar-right .dropdown-menu-left { - left: 0; - right: auto; - } -} -.btn-group, -.btn-group-vertical { - position: relative; - display: inline-block; - vertical-align: middle; -} -.btn-group > .btn, -.btn-group-vertical > .btn { - position: relative; - float: left; -} -.btn-group > .btn:hover, -.btn-group-vertical > .btn:hover, -.btn-group > .btn:focus, -.btn-group-vertical > .btn:focus, -.btn-group > .btn:active, -.btn-group-vertical > .btn:active, -.btn-group > .btn.active, -.btn-group-vertical > .btn.active { - z-index: 2; -} -.btn-group .btn + .btn, -.btn-group .btn + .btn-group, -.btn-group .btn-group + .btn, -.btn-group .btn-group + .btn-group { - margin-left: -1px; -} -.btn-toolbar { - margin-left: -5px; -} -.btn-toolbar .btn-group, -.btn-toolbar .input-group { - float: left; -} -.btn-toolbar > .btn, -.btn-toolbar > .btn-group, -.btn-toolbar > .input-group { - margin-left: 5px; -} -.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { - border-radius: 0; -} -.btn-group > .btn:first-child { - margin-left: 0; -} -.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.btn-group > .btn:last-child:not(:first-child), -.btn-group > .dropdown-toggle:not(:first-child) { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} -.btn-group > .btn-group { - float: left; -} -.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} -.btn-group > .btn-group:first-child > .btn:last-child, -.btn-group > .btn-group:first-child > .dropdown-toggle { - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.btn-group > .btn-group:last-child > .btn:first-child { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} -.btn-group > .btn + .dropdown-toggle { - padding-left: 8px; - padding-right: 8px; -} -.btn-group > .btn-lg + .dropdown-toggle { - padding-left: 12px; - padding-right: 12px; -} -.btn-group.open .dropdown-toggle { - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} -.btn-group.open .dropdown-toggle.btn-link { - -webkit-box-shadow: none; - box-shadow: none; -} -.btn .caret { - margin-left: 0; -} -.btn-lg .caret { - border-width: 5px 5px 0; - border-bottom-width: 0; -} -.dropup .btn-lg .caret { - border-width: 0 5px 5px; -} -.btn-group-vertical > .btn, -.btn-group-vertical > .btn-group, -.btn-group-vertical > .btn-group > .btn { - display: block; - float: none; - width: 100%; - max-width: 100%; -} -.btn-group-vertical > .btn-group > .btn { - float: none; -} -.btn-group-vertical > .btn + .btn, -.btn-group-vertical > .btn + .btn-group, -.btn-group-vertical > .btn-group + .btn, -.btn-group-vertical > .btn-group + .btn-group { - margin-top: -1px; - margin-left: 0; -} -.btn-group-vertical > .btn:not(:first-child):not(:last-child) { - border-radius: 0; -} -.btn-group-vertical > .btn:first-child:not(:last-child) { - border-top-right-radius: 4px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -.btn-group-vertical > .btn:last-child:not(:first-child) { - border-bottom-left-radius: 4px; - border-top-right-radius: 0; - border-top-left-radius: 0; -} -.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} -.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, -.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; -} -.btn-group-justified { - display: table; - width: 100%; - table-layout: fixed; - border-collapse: separate; -} -.btn-group-justified > .btn, -.btn-group-justified > .btn-group { - float: none; - display: table-cell; - width: 1%; -} -.btn-group-justified > .btn-group .btn { - width: 100%; -} -.btn-group-justified > .btn-group .dropdown-menu { - left: auto; -} -[data-toggle="buttons"] > .btn input[type="radio"], -[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], -[data-toggle="buttons"] > .btn input[type="checkbox"], -[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { - position: absolute; - clip: rect(0, 0, 0, 0); - pointer-events: none; -} -.input-group { - position: relative; - display: table; - border-collapse: separate; -} -.input-group[class*="col-"] { - float: none; - padding-left: 0; - padding-right: 0; -} -.input-group .form-control { - position: relative; - z-index: 2; - float: left; - width: 100%; - margin-bottom: 0; -} -.input-group-lg > .form-control, -.input-group-lg > .input-group-addon, -.input-group-lg > .input-group-btn > .btn { - height: 46px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} -select.input-group-lg > .form-control, -select.input-group-lg > .input-group-addon, -select.input-group-lg > .input-group-btn > .btn { - height: 46px; - line-height: 46px; -} -textarea.input-group-lg > .form-control, -textarea.input-group-lg > .input-group-addon, -textarea.input-group-lg > .input-group-btn > .btn, -select[multiple].input-group-lg > .form-control, -select[multiple].input-group-lg > .input-group-addon, -select[multiple].input-group-lg > .input-group-btn > .btn { - height: auto; -} -.input-group-sm > .form-control, -.input-group-sm > .input-group-addon, -.input-group-sm > .input-group-btn > .btn { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -select.input-group-sm > .form-control, -select.input-group-sm > .input-group-addon, -select.input-group-sm > .input-group-btn > .btn { - height: 30px; - line-height: 30px; -} -textarea.input-group-sm > .form-control, -textarea.input-group-sm > .input-group-addon, -textarea.input-group-sm > .input-group-btn > .btn, -select[multiple].input-group-sm > .form-control, -select[multiple].input-group-sm > .input-group-addon, -select[multiple].input-group-sm > .input-group-btn > .btn { - height: auto; -} -.input-group-addon, -.input-group-btn, -.input-group .form-control { - display: table-cell; -} -.input-group-addon:not(:first-child):not(:last-child), -.input-group-btn:not(:first-child):not(:last-child), -.input-group .form-control:not(:first-child):not(:last-child) { - border-radius: 0; -} -.input-group-addon, -.input-group-btn { - width: 1%; - white-space: nowrap; - vertical-align: middle; -} -.input-group-addon { - padding: 6px 12px; - font-size: 14px; - font-weight: normal; - line-height: 1; - color: #555555; - text-align: center; - background-color: #eeeeee; - border: 1px solid #cccccc; - border-radius: 4px; -} -.input-group-addon.input-sm { - padding: 5px 10px; - font-size: 12px; - border-radius: 3px; -} -.input-group-addon.input-lg { - padding: 10px 16px; - font-size: 18px; - border-radius: 6px; -} -.input-group-addon input[type="radio"], -.input-group-addon input[type="checkbox"] { - margin-top: 0; -} -.input-group .form-control:first-child, -.input-group-addon:first-child, -.input-group-btn:first-child > .btn, -.input-group-btn:first-child > .btn-group > .btn, -.input-group-btn:first-child > .dropdown-toggle, -.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), -.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.input-group-addon:first-child { - border-right: 0; -} -.input-group .form-control:last-child, -.input-group-addon:last-child, -.input-group-btn:last-child > .btn, -.input-group-btn:last-child > .btn-group > .btn, -.input-group-btn:last-child > .dropdown-toggle, -.input-group-btn:first-child > .btn:not(:first-child), -.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} -.input-group-addon:last-child { - border-left: 0; -} -.input-group-btn { - position: relative; - font-size: 0; - white-space: nowrap; -} -.input-group-btn > .btn { - position: relative; -} -.input-group-btn > .btn + .btn { - margin-left: -1px; -} -.input-group-btn > .btn:hover, -.input-group-btn > .btn:focus, -.input-group-btn > .btn:active { - z-index: 2; -} -.input-group-btn:first-child > .btn, -.input-group-btn:first-child > .btn-group { - margin-right: -1px; -} -.input-group-btn:last-child > .btn, -.input-group-btn:last-child > .btn-group { - margin-left: -1px; -} -.nav { - margin-bottom: 0; - padding-left: 0; - list-style: none; -} -.nav > li { - position: relative; - display: block; -} -.nav > li > a { - position: relative; - display: block; - padding: 10px 15px; -} -.nav > li > a:hover, -.nav > li > a:focus { - text-decoration: none; - background-color: #eeeeee; -} -.nav > li.disabled > a { - color: #777777; -} -.nav > li.disabled > a:hover, -.nav > li.disabled > a:focus { - color: #777777; - text-decoration: none; - background-color: transparent; - cursor: not-allowed; -} -.nav .open > a, -.nav .open > a:hover, -.nav .open > a:focus { - background-color: #eeeeee; - border-color: #337ab7; -} -.nav .nav-divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5; -} -.nav > li > a > img { - max-width: none; -} -.nav-tabs { - border-bottom: 1px solid #dddddd; -} -.nav-tabs > li { - float: left; - margin-bottom: -1px; -} -.nav-tabs > li > a { - margin-right: 2px; - line-height: 1.42857143; - border: 1px solid transparent; - border-radius: 4px 4px 0 0; -} -.nav-tabs > li > a:hover { - border-color: #eeeeee #eeeeee #dddddd; -} -.nav-tabs > li.active > a, -.nav-tabs > li.active > a:hover, -.nav-tabs > li.active > a:focus { - color: #555555; - background-color: #ffffff; - border: 1px solid #dddddd; - border-bottom-color: transparent; - cursor: default; -} -.nav-tabs.nav-justified { - width: 100%; - border-bottom: 0; -} -.nav-tabs.nav-justified > li { - float: none; -} -.nav-tabs.nav-justified > li > a { - text-align: center; - margin-bottom: 5px; -} -.nav-tabs.nav-justified > .dropdown .dropdown-menu { - top: auto; - left: auto; -} -@media (min-width: 768px) { - .nav-tabs.nav-justified > li { - display: table-cell; - width: 1%; - } - .nav-tabs.nav-justified > li > a { - margin-bottom: 0; - } -} -.nav-tabs.nav-justified > li > a { - margin-right: 0; - border-radius: 4px; -} -.nav-tabs.nav-justified > .active > a, -.nav-tabs.nav-justified > .active > a:hover, -.nav-tabs.nav-justified > .active > a:focus { - border: 1px solid #dddddd; -} -@media (min-width: 768px) { - .nav-tabs.nav-justified > li > a { - border-bottom: 1px solid #dddddd; - border-radius: 4px 4px 0 0; - } - .nav-tabs.nav-justified > .active > a, - .nav-tabs.nav-justified > .active > a:hover, - .nav-tabs.nav-justified > .active > a:focus { - border-bottom-color: #ffffff; - } -} -.nav-pills > li { - float: left; -} -.nav-pills > li > a { - border-radius: 4px; -} -.nav-pills > li + li { - margin-left: 2px; -} -.nav-pills > li.active > a, -.nav-pills > li.active > a:hover, -.nav-pills > li.active > a:focus { - color: #ffffff; - background-color: #337ab7; -} -.nav-stacked > li { - float: none; -} -.nav-stacked > li + li { - margin-top: 2px; - margin-left: 0; -} -.nav-justified { - width: 100%; -} -.nav-justified > li { - float: none; -} -.nav-justified > li > a { - text-align: center; - margin-bottom: 5px; -} -.nav-justified > .dropdown .dropdown-menu { - top: auto; - left: auto; -} -@media (min-width: 768px) { - .nav-justified > li { - display: table-cell; - width: 1%; - } - .nav-justified > li > a { - margin-bottom: 0; - } -} -.nav-tabs-justified { - border-bottom: 0; -} -.nav-tabs-justified > li > a { - margin-right: 0; - border-radius: 4px; -} -.nav-tabs-justified > .active > a, -.nav-tabs-justified > .active > a:hover, -.nav-tabs-justified > .active > a:focus { - border: 1px solid #dddddd; -} -@media (min-width: 768px) { - .nav-tabs-justified > li > a { - border-bottom: 1px solid #dddddd; - border-radius: 4px 4px 0 0; - } - .nav-tabs-justified > .active > a, - .nav-tabs-justified > .active > a:hover, - .nav-tabs-justified > .active > a:focus { - border-bottom-color: #ffffff; - } -} -.tab-content > .tab-pane { - display: none; - visibility: hidden; -} -.tab-content > .active { - display: block; - visibility: visible; -} -.nav-tabs .dropdown-menu { - margin-top: -1px; - border-top-right-radius: 0; - border-top-left-radius: 0; -} -.navbar { - position: relative; - min-height: 70px; - margin-bottom: 20px; - border: 1px solid transparent; -} -@media (min-width: 768px) { - .navbar { - border-radius: 4px; - } -} -@media (min-width: 768px) { - .navbar-header { - float: left; - } -} -.navbar-collapse { - overflow-x: visible; - padding-right: 15px; - padding-left: 15px; - border-top: 1px solid transparent; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); - -webkit-overflow-scrolling: touch; -} -.navbar-collapse.in { - overflow-y: auto; -} -@media (min-width: 768px) { - .navbar-collapse { - width: auto; - border-top: 0; - box-shadow: none; - } - .navbar-collapse.collapse { - display: block !important; - visibility: visible !important; - height: auto !important; - padding-bottom: 0; - overflow: visible !important; - } - .navbar-collapse.in { - overflow-y: visible; - } - .navbar-fixed-top .navbar-collapse, - .navbar-static-top .navbar-collapse, - .navbar-fixed-bottom .navbar-collapse { - padding-left: 0; - padding-right: 0; - } -} -.navbar-fixed-top .navbar-collapse, -.navbar-fixed-bottom .navbar-collapse { - max-height: 340px; -} -@media (max-device-width: 480px) and (orientation: landscape) { - .navbar-fixed-top .navbar-collapse, - .navbar-fixed-bottom .navbar-collapse { - max-height: 200px; - } -} -.container > .navbar-header, -.container-fluid > .navbar-header, -.container > .navbar-collapse, -.container-fluid > .navbar-collapse { - margin-right: -15px; - margin-left: -15px; -} -@media (min-width: 768px) { - .container > .navbar-header, - .container-fluid > .navbar-header, - .container > .navbar-collapse, - .container-fluid > .navbar-collapse { - margin-right: 0; - margin-left: 0; - } -} -.navbar-static-top { - z-index: 1000; - border-width: 0 0 1px; -} -@media (min-width: 768px) { - .navbar-static-top { - border-radius: 0; - } -} -.navbar-fixed-top, -.navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - z-index: 1030; -} -@media (min-width: 768px) { - .navbar-fixed-top, - .navbar-fixed-bottom { - border-radius: 0; - } -} -.navbar-fixed-top { - top: 0; - border-width: 0 0 1px; -} -.navbar-fixed-bottom { - bottom: 0; - margin-bottom: 0; - border-width: 1px 0 0; -} -.navbar-brand { - float: left; - padding: 25px 15px; - font-size: 18px; - line-height: 20px; - height: 70px; -} -.navbar-brand:hover, -.navbar-brand:focus { - text-decoration: none; -} -.navbar-brand > img { - display: block; -} -@media (min-width: 768px) { - .navbar > .container .navbar-brand, - .navbar > .container-fluid .navbar-brand { - margin-left: -15px; - } -} -.navbar-toggle { - position: relative; - float: right; - margin-right: 15px; - padding: 9px 10px; - margin-top: 18px; - margin-bottom: 18px; - background-color: transparent; - background-image: none; - border: 1px solid transparent; - border-radius: 4px; -} -.navbar-toggle:focus { - outline: 0; -} -.navbar-toggle .icon-bar { - display: block; - width: 22px; - height: 2px; - border-radius: 1px; -} -.navbar-toggle .icon-bar + .icon-bar { - margin-top: 4px; -} -@media (min-width: 768px) { - .navbar-toggle { - display: none; - } -} -.navbar-nav { - margin: 12.5px -15px; -} -.navbar-nav > li > a { - padding-top: 10px; - padding-bottom: 10px; - line-height: 20px; -} -@media (max-width: 767px) { - .navbar-nav .open .dropdown-menu { - position: static; - float: none; - width: auto; - margin-top: 0; - background-color: transparent; - border: 0; - box-shadow: none; - } - .navbar-nav .open .dropdown-menu > li > a, - .navbar-nav .open .dropdown-menu .dropdown-header { - padding: 5px 15px 5px 25px; - } - .navbar-nav .open .dropdown-menu > li > a { - line-height: 20px; - } - .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-nav .open .dropdown-menu > li > a:focus { - background-image: none; - } -} -@media (min-width: 768px) { - .navbar-nav { - float: left; - margin: 0; - } - .navbar-nav > li { - float: left; - } - .navbar-nav > li > a { - padding-top: 25px; - padding-bottom: 25px; - } -} -.navbar-form { - margin-left: -15px; - margin-right: -15px; - padding: 10px 15px; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - margin-top: 18px; - margin-bottom: 18px; -} -@media (min-width: 768px) { - .navbar-form .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .form-control { - display: inline-block; - width: auto; - vertical-align: middle; - } - .navbar-form .form-control-static { - display: inline-block; - } - .navbar-form .input-group { - display: inline-table; - vertical-align: middle; - } - .navbar-form .input-group .input-group-addon, - .navbar-form .input-group .input-group-btn, - .navbar-form .input-group .form-control { - width: auto; - } - .navbar-form .input-group > .form-control { - width: 100%; - } - .navbar-form .control-label { - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .radio, - .navbar-form .checkbox { - display: inline-block; - margin-top: 0; - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .radio label, - .navbar-form .checkbox label { - padding-left: 0; - } - .navbar-form .radio input[type="radio"], - .navbar-form .checkbox input[type="checkbox"] { - position: relative; - margin-left: 0; - } - .navbar-form .has-feedback .form-control-feedback { - top: 0; - } -} -@media (max-width: 767px) { - .navbar-form .form-group { - margin-bottom: 5px; - } - .navbar-form .form-group:last-child { - margin-bottom: 0; - } -} -@media (min-width: 768px) { - .navbar-form { - width: auto; - border: 0; - margin-left: 0; - margin-right: 0; - padding-top: 0; - padding-bottom: 0; - -webkit-box-shadow: none; - box-shadow: none; - } -} -.navbar-nav > li > .dropdown-menu { - margin-top: 0; - border-top-right-radius: 0; - border-top-left-radius: 0; -} -.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { - border-top-right-radius: 4px; - border-top-left-radius: 4px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -.navbar-btn { - margin-top: 18px; - margin-bottom: 18px; -} -.navbar-btn.btn-sm { - margin-top: 20px; - margin-bottom: 20px; -} -.navbar-btn.btn-xs { - margin-top: 24px; - margin-bottom: 24px; -} -.navbar-text { - margin-top: 25px; - margin-bottom: 25px; -} -@media (min-width: 768px) { - .navbar-text { - float: left; - margin-left: 15px; - margin-right: 15px; - } -} -@media (min-width: 768px) { - .navbar-left { - float: left !important; - } - .navbar-right { - float: right !important; - margin-right: -15px; - } - .navbar-right ~ .navbar-right { - margin-right: 0; - } -} -.navbar-default { - background-color: #f8f8f8; - border-color: #e7e7e7; -} -.navbar-default .navbar-brand { - color: #777777; -} -.navbar-default .navbar-brand:hover, -.navbar-default .navbar-brand:focus { - color: #5e5e5e; - background-color: transparent; -} -.navbar-default .navbar-text { - color: #777777; -} -.navbar-default .navbar-nav > li > a { - color: #777777; -} -.navbar-default .navbar-nav > li > a:hover, -.navbar-default .navbar-nav > li > a:focus { - color: #333333; - background-color: transparent; -} -.navbar-default .navbar-nav > .active > a, -.navbar-default .navbar-nav > .active > a:hover, -.navbar-default .navbar-nav > .active > a:focus { - color: #555555; - background-color: #e7e7e7; -} -.navbar-default .navbar-nav > .disabled > a, -.navbar-default .navbar-nav > .disabled > a:hover, -.navbar-default .navbar-nav > .disabled > a:focus { - color: #cccccc; - background-color: transparent; -} -.navbar-default .navbar-toggle { - border-color: #dddddd; -} -.navbar-default .navbar-toggle:hover, -.navbar-default .navbar-toggle:focus { - background-color: #dddddd; -} -.navbar-default .navbar-toggle .icon-bar { - background-color: #888888; -} -.navbar-default .navbar-collapse, -.navbar-default .navbar-form { - border-color: #e7e7e7; -} -.navbar-default .navbar-nav > .open > a, -.navbar-default .navbar-nav > .open > a:hover, -.navbar-default .navbar-nav > .open > a:focus { - background-color: #e7e7e7; - color: #555555; -} -@media (max-width: 767px) { - .navbar-default .navbar-nav .open .dropdown-menu > li > a { - color: #777777; - } - .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { - color: #333333; - background-color: transparent; - } - .navbar-default .navbar-nav .open .dropdown-menu > .active > a, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #555555; - background-color: #e7e7e7; - } - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #cccccc; - background-color: transparent; - } -} -.navbar-default .navbar-link { - color: #777777; -} -.navbar-default .navbar-link:hover { - color: #333333; -} -.navbar-default .btn-link { - color: #777777; -} -.navbar-default .btn-link:hover, -.navbar-default .btn-link:focus { - color: #333333; -} -.navbar-default .btn-link[disabled]:hover, -fieldset[disabled] .navbar-default .btn-link:hover, -.navbar-default .btn-link[disabled]:focus, -fieldset[disabled] .navbar-default .btn-link:focus { - color: #cccccc; -} -.navbar-inverse { - background-color: #222222; - border-color: #080808; -} -.navbar-inverse .navbar-brand { - color: #9d9d9d; -} -.navbar-inverse .navbar-brand:hover, -.navbar-inverse .navbar-brand:focus { - color: #ffffff; - background-color: transparent; -} -.navbar-inverse .navbar-text { - color: #9d9d9d; -} -.navbar-inverse .navbar-nav > li > a { - color: #9d9d9d; -} -.navbar-inverse .navbar-nav > li > a:hover, -.navbar-inverse .navbar-nav > li > a:focus { - color: #ffffff; - background-color: transparent; -} -.navbar-inverse .navbar-nav > .active > a, -.navbar-inverse .navbar-nav > .active > a:hover, -.navbar-inverse .navbar-nav > .active > a:focus { - color: #ffffff; - background-color: #080808; -} -.navbar-inverse .navbar-nav > .disabled > a, -.navbar-inverse .navbar-nav > .disabled > a:hover, -.navbar-inverse .navbar-nav > .disabled > a:focus { - color: #444444; - background-color: transparent; -} -.navbar-inverse .navbar-toggle { - border-color: #333333; -} -.navbar-inverse .navbar-toggle:hover, -.navbar-inverse .navbar-toggle:focus { - background-color: #333333; -} -.navbar-inverse .navbar-toggle .icon-bar { - background-color: #ffffff; -} -.navbar-inverse .navbar-collapse, -.navbar-inverse .navbar-form { - border-color: #101010; -} -.navbar-inverse .navbar-nav > .open > a, -.navbar-inverse .navbar-nav > .open > a:hover, -.navbar-inverse .navbar-nav > .open > a:focus { - background-color: #080808; - color: #ffffff; -} -@media (max-width: 767px) { - .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { - border-color: #080808; - } - .navbar-inverse .navbar-nav .open .dropdown-menu .divider { - background-color: #080808; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { - color: #9d9d9d; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { - color: #ffffff; - background-color: transparent; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #ffffff; - background-color: #080808; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #444444; - background-color: transparent; - } -} -.navbar-inverse .navbar-link { - color: #9d9d9d; -} -.navbar-inverse .navbar-link:hover { - color: #ffffff; -} -.navbar-inverse .btn-link { - color: #9d9d9d; -} -.navbar-inverse .btn-link:hover, -.navbar-inverse .btn-link:focus { - color: #ffffff; -} -.navbar-inverse .btn-link[disabled]:hover, -fieldset[disabled] .navbar-inverse .btn-link:hover, -.navbar-inverse .btn-link[disabled]:focus, -fieldset[disabled] .navbar-inverse .btn-link:focus { - color: #444444; -} -.breadcrumb { - padding: 8px 15px; - margin-bottom: 20px; - list-style: none; - background-color: #f5f5f5; - border-radius: 4px; -} -.breadcrumb > li { - display: inline-block; -} -.breadcrumb > li + li:before { - content: "/\00a0"; - padding: 0 5px; - color: #cccccc; -} -.breadcrumb > .active { - color: #777777; -} -.pagination { - display: inline-block; - padding-left: 0; - margin: 20px 0; - border-radius: 4px; -} -.pagination > li { - display: inline; -} -.pagination > li > a, -.pagination > li > span { - position: relative; - float: left; - padding: 6px 12px; - line-height: 1.42857143; - text-decoration: none; - color: #337ab7; - background-color: #ffffff; - border: 1px solid #dddddd; - margin-left: -1px; -} -.pagination > li:first-child > a, -.pagination > li:first-child > span { - margin-left: 0; - border-bottom-left-radius: 4px; - border-top-left-radius: 4px; -} -.pagination > li:last-child > a, -.pagination > li:last-child > span { - border-bottom-right-radius: 4px; - border-top-right-radius: 4px; -} -.pagination > li > a:hover, -.pagination > li > span:hover, -.pagination > li > a:focus, -.pagination > li > span:focus { - color: #23527c; - background-color: #eeeeee; - border-color: #dddddd; -} -.pagination > .active > a, -.pagination > .active > span, -.pagination > .active > a:hover, -.pagination > .active > span:hover, -.pagination > .active > a:focus, -.pagination > .active > span:focus { - z-index: 2; - color: #ffffff; - background-color: #337ab7; - border-color: #337ab7; - cursor: default; -} -.pagination > .disabled > span, -.pagination > .disabled > span:hover, -.pagination > .disabled > span:focus, -.pagination > .disabled > a, -.pagination > .disabled > a:hover, -.pagination > .disabled > a:focus { - color: #777777; - background-color: #ffffff; - border-color: #dddddd; - cursor: not-allowed; -} -.pagination-lg > li > a, -.pagination-lg > li > span { - padding: 10px 16px; - font-size: 18px; -} -.pagination-lg > li:first-child > a, -.pagination-lg > li:first-child > span { - border-bottom-left-radius: 6px; - border-top-left-radius: 6px; -} -.pagination-lg > li:last-child > a, -.pagination-lg > li:last-child > span { - border-bottom-right-radius: 6px; - border-top-right-radius: 6px; -} -.pagination-sm > li > a, -.pagination-sm > li > span { - padding: 5px 10px; - font-size: 12px; -} -.pagination-sm > li:first-child > a, -.pagination-sm > li:first-child > span { - border-bottom-left-radius: 3px; - border-top-left-radius: 3px; -} -.pagination-sm > li:last-child > a, -.pagination-sm > li:last-child > span { - border-bottom-right-radius: 3px; - border-top-right-radius: 3px; -} -.pager { - padding-left: 0; - margin: 20px 0; - list-style: none; - text-align: center; -} -.pager li { - display: inline; -} -.pager li > a, -.pager li > span { - display: inline-block; - padding: 5px 14px; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 15px; -} -.pager li > a:hover, -.pager li > a:focus { - text-decoration: none; - background-color: #eeeeee; -} -.pager .next > a, -.pager .next > span { - float: right; -} -.pager .previous > a, -.pager .previous > span { - float: left; -} -.pager .disabled > a, -.pager .disabled > a:hover, -.pager .disabled > a:focus, -.pager .disabled > span { - color: #777777; - background-color: #ffffff; - cursor: not-allowed; -} -.label { - display: inline; - padding: .2em .6em .3em; - font-size: 75%; - font-weight: bold; - line-height: 1; - color: #ffffff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: .25em; -} -a.label:hover, -a.label:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; -} -.label:empty { - display: none; -} -.btn .label { - position: relative; - top: -1px; -} -.label-default { - background-color: #777777; -} -.label-default[href]:hover, -.label-default[href]:focus { - background-color: #5e5e5e; -} -.label-primary { - background-color: #337ab7; -} -.label-primary[href]:hover, -.label-primary[href]:focus { - background-color: #286090; -} -.label-success { - background-color: #5cb85c; -} -.label-success[href]:hover, -.label-success[href]:focus { - background-color: #449d44; -} -.label-info { - background-color: #5bc0de; -} -.label-info[href]:hover, -.label-info[href]:focus { - background-color: #31b0d5; -} -.label-warning { - background-color: #f0ad4e; -} -.label-warning[href]:hover, -.label-warning[href]:focus { - background-color: #ec971f; -} -.label-danger { - background-color: #d9534f; -} -.label-danger[href]:hover, -.label-danger[href]:focus { - background-color: #c9302c; -} -.badge { - display: inline-block; - min-width: 10px; - padding: 3px 7px; - font-size: 12px; - font-weight: bold; - color: #ffffff; - line-height: 1; - vertical-align: baseline; - white-space: nowrap; - text-align: center; - background-color: #777777; - border-radius: 10px; -} -.badge:empty { - display: none; -} -.btn .badge { - position: relative; - top: -1px; -} -.btn-xs .badge { - top: 0; - padding: 1px 5px; -} -a.badge:hover, -a.badge:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; -} -.list-group-item.active > .badge, -.nav-pills > .active > a > .badge { - color: #337ab7; - background-color: #ffffff; -} -.list-group-item > .badge { - float: right; -} -.list-group-item > .badge + .badge { - margin-right: 5px; -} -.nav-pills > li > a > .badge { - margin-left: 3px; -} -.jumbotron { - padding: 30px 15px; - margin-bottom: 30px; - color: inherit; - background-color: #eeeeee; -} -.jumbotron h1, -.jumbotron .h1 { - color: inherit; -} -.jumbotron p { - margin-bottom: 15px; - font-size: 21px; - font-weight: 200; -} -.jumbotron > hr { - border-top-color: #d5d5d5; -} -.container .jumbotron, -.container-fluid .jumbotron { - border-radius: 6px; -} -.jumbotron .container { - max-width: 100%; -} -@media screen and (min-width: 768px) { - .jumbotron { - padding: 48px 0; - } - .container .jumbotron, - .container-fluid .jumbotron { - padding-left: 60px; - padding-right: 60px; - } - .jumbotron h1, - .jumbotron .h1 { - font-size: 63px; - } -} -.thumbnail { - display: block; - padding: 4px; - margin-bottom: 20px; - line-height: 1.42857143; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 4px; - -webkit-transition: border 0.2s ease-in-out; - -o-transition: border 0.2s ease-in-out; - transition: border 0.2s ease-in-out; -} -.thumbnail > img, -.thumbnail a > img { - margin-left: auto; - margin-right: auto; -} -a.thumbnail:hover, -a.thumbnail:focus, -a.thumbnail.active { - border-color: #337ab7; -} -.thumbnail .caption { - padding: 9px; - color: #333333; -} -.alert { - padding: 15px; - margin-bottom: 20px; - border: 1px solid transparent; - border-radius: 4px; -} -.alert h4 { - margin-top: 0; - color: inherit; -} -.alert .alert-link { - font-weight: bold; -} -.alert > p, -.alert > ul { - margin-bottom: 0; -} -.alert > p + p { - margin-top: 5px; -} -.alert-dismissable, -.alert-dismissible { - padding-right: 35px; -} -.alert-dismissable .close, -.alert-dismissible .close { - position: relative; - top: -2px; - right: -21px; - color: inherit; -} -.alert-success { - background-color: #dff0d8; - border-color: #d6e9c6; - color: #3c763d; -} -.alert-success hr { - border-top-color: #c9e2b3; -} -.alert-success .alert-link { - color: #2b542c; -} -.alert-info { - background-color: #d9edf7; - border-color: #bce8f1; - color: #31708f; -} -.alert-info hr { - border-top-color: #a6e1ec; -} -.alert-info .alert-link { - color: #245269; -} -.alert-warning { - background-color: #fcf8e3; - border-color: #faebcc; - color: #8a6d3b; -} -.alert-warning hr { - border-top-color: #f7e1b5; -} -.alert-warning .alert-link { - color: #66512c; -} -.alert-danger { - background-color: #f2dede; - border-color: #ebccd1; - color: #a94442; -} -.alert-danger hr { - border-top-color: #e4b9c0; -} -.alert-danger .alert-link { - color: #843534; -} -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -.progress { - overflow: hidden; - height: 20px; - margin-bottom: 20px; - background-color: #f5f5f5; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -} -.progress-bar { - float: left; - width: 0%; - height: 100%; - font-size: 12px; - line-height: 20px; - color: #ffffff; - text-align: center; - background-color: #337ab7; - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -webkit-transition: width 0.6s ease; - -o-transition: width 0.6s ease; - transition: width 0.6s ease; -} -.progress-striped .progress-bar, -.progress-bar-striped { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-size: 40px 40px; -} -.progress.active .progress-bar, -.progress-bar.active { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} -.progress-bar-success { - background-color: #5cb85c; -} -.progress-striped .progress-bar-success { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-bar-info { - background-color: #5bc0de; -} -.progress-striped .progress-bar-info { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-bar-warning { - background-color: #f0ad4e; -} -.progress-striped .progress-bar-warning { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-bar-danger { - background-color: #d9534f; -} -.progress-striped .progress-bar-danger { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.media { - margin-top: 15px; -} -.media:first-child { - margin-top: 0; -} -.media-right, -.media > .pull-right { - padding-left: 10px; -} -.media-left, -.media > .pull-left { - padding-right: 10px; -} -.media-left, -.media-right, -.media-body { - display: table-cell; - vertical-align: top; -} -.media-middle { - vertical-align: middle; -} -.media-bottom { - vertical-align: bottom; -} -.media-heading { - margin-top: 0; - margin-bottom: 5px; -} -.media-list { - padding-left: 0; - list-style: none; -} -.list-group { - margin-bottom: 20px; - padding-left: 0; -} -.list-group-item { - position: relative; - display: block; - padding: 10px 15px; - margin-bottom: -1px; - background-color: #ffffff; - border: 1px solid #dddddd; -} -.list-group-item:first-child { - border-top-right-radius: 4px; - border-top-left-radius: 4px; -} -.list-group-item:last-child { - margin-bottom: 0; - border-bottom-right-radius: 4px; - border-bottom-left-radius: 4px; -} -a.list-group-item { - color: #555555; -} -a.list-group-item .list-group-item-heading { - color: #333333; -} -a.list-group-item:hover, -a.list-group-item:focus { - text-decoration: none; - color: #555555; - background-color: #f5f5f5; -} -.list-group-item.disabled, -.list-group-item.disabled:hover, -.list-group-item.disabled:focus { - background-color: #eeeeee; - color: #777777; - cursor: not-allowed; -} -.list-group-item.disabled .list-group-item-heading, -.list-group-item.disabled:hover .list-group-item-heading, -.list-group-item.disabled:focus .list-group-item-heading { - color: inherit; -} -.list-group-item.disabled .list-group-item-text, -.list-group-item.disabled:hover .list-group-item-text, -.list-group-item.disabled:focus .list-group-item-text { - color: #777777; -} -.list-group-item.active, -.list-group-item.active:hover, -.list-group-item.active:focus { - z-index: 2; - color: #ffffff; - background-color: #337ab7; - border-color: #337ab7; -} -.list-group-item.active .list-group-item-heading, -.list-group-item.active:hover .list-group-item-heading, -.list-group-item.active:focus .list-group-item-heading, -.list-group-item.active .list-group-item-heading > small, -.list-group-item.active:hover .list-group-item-heading > small, -.list-group-item.active:focus .list-group-item-heading > small, -.list-group-item.active .list-group-item-heading > .small, -.list-group-item.active:hover .list-group-item-heading > .small, -.list-group-item.active:focus .list-group-item-heading > .small { - color: inherit; -} -.list-group-item.active .list-group-item-text, -.list-group-item.active:hover .list-group-item-text, -.list-group-item.active:focus .list-group-item-text { - color: #c7ddef; -} -.list-group-item-success { - color: #3c763d; - background-color: #dff0d8; -} -a.list-group-item-success { - color: #3c763d; -} -a.list-group-item-success .list-group-item-heading { - color: inherit; -} -a.list-group-item-success:hover, -a.list-group-item-success:focus { - color: #3c763d; - background-color: #d0e9c6; -} -a.list-group-item-success.active, -a.list-group-item-success.active:hover, -a.list-group-item-success.active:focus { - color: #fff; - background-color: #3c763d; - border-color: #3c763d; -} -.list-group-item-info { - color: #31708f; - background-color: #d9edf7; -} -a.list-group-item-info { - color: #31708f; -} -a.list-group-item-info .list-group-item-heading { - color: inherit; -} -a.list-group-item-info:hover, -a.list-group-item-info:focus { - color: #31708f; - background-color: #c4e3f3; -} -a.list-group-item-info.active, -a.list-group-item-info.active:hover, -a.list-group-item-info.active:focus { - color: #fff; - background-color: #31708f; - border-color: #31708f; -} -.list-group-item-warning { - color: #8a6d3b; - background-color: #fcf8e3; -} -a.list-group-item-warning { - color: #8a6d3b; -} -a.list-group-item-warning .list-group-item-heading { - color: inherit; -} -a.list-group-item-warning:hover, -a.list-group-item-warning:focus { - color: #8a6d3b; - background-color: #faf2cc; -} -a.list-group-item-warning.active, -a.list-group-item-warning.active:hover, -a.list-group-item-warning.active:focus { - color: #fff; - background-color: #8a6d3b; - border-color: #8a6d3b; -} -.list-group-item-danger { - color: #a94442; - background-color: #f2dede; -} -a.list-group-item-danger { - color: #a94442; -} -a.list-group-item-danger .list-group-item-heading { - color: inherit; -} -a.list-group-item-danger:hover, -a.list-group-item-danger:focus { - color: #a94442; - background-color: #ebcccc; -} -a.list-group-item-danger.active, -a.list-group-item-danger.active:hover, -a.list-group-item-danger.active:focus { - color: #fff; - background-color: #a94442; - border-color: #a94442; -} -.list-group-item-heading { - margin-top: 0; - margin-bottom: 5px; -} -.list-group-item-text { - margin-bottom: 0; - line-height: 1.3; -} -.panel { - margin-bottom: 20px; - background-color: #ffffff; - border: 1px solid transparent; - border-radius: 4px; - -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); -} -.panel-body { - padding: 15px; -} -.panel-heading { - padding: 10px 15px; - border-bottom: 1px solid transparent; - border-top-right-radius: 3px; - border-top-left-radius: 3px; -} -.panel-heading > .dropdown .dropdown-toggle { - color: inherit; -} -.panel-title { - margin-top: 0; - margin-bottom: 0; - font-size: 16px; - color: inherit; -} -.panel-title > a { - color: inherit; -} -.panel-footer { - padding: 10px 15px; - background-color: #f5f5f5; - border-top: 1px solid #dddddd; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; -} -.panel > .list-group, -.panel > .panel-collapse > .list-group { - margin-bottom: 0; -} -.panel > .list-group .list-group-item, -.panel > .panel-collapse > .list-group .list-group-item { - border-width: 1px 0; - border-radius: 0; -} -.panel > .list-group:first-child .list-group-item:first-child, -.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { - border-top: 0; - border-top-right-radius: 3px; - border-top-left-radius: 3px; -} -.panel > .list-group:last-child .list-group-item:last-child, -.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { - border-bottom: 0; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; -} -.panel-heading + .list-group .list-group-item:first-child { - border-top-width: 0; -} -.list-group + .panel-footer { - border-top-width: 0; -} -.panel > .table, -.panel > .table-responsive > .table, -.panel > .panel-collapse > .table { - margin-bottom: 0; -} -.panel > .table caption, -.panel > .table-responsive > .table caption, -.panel > .panel-collapse > .table caption { - padding-left: 15px; - padding-right: 15px; -} -.panel > .table:first-child, -.panel > .table-responsive:first-child > .table:first-child { - border-top-right-radius: 3px; - border-top-left-radius: 3px; -} -.panel > .table:first-child > thead:first-child > tr:first-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, -.panel > .table:first-child > tbody:first-child > tr:first-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { - border-top-left-radius: 3px; - border-top-right-radius: 3px; -} -.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, -.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, -.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, -.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { - border-top-left-radius: 3px; -} -.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, -.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, -.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, -.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { - border-top-right-radius: 3px; -} -.panel > .table:last-child, -.panel > .table-responsive:last-child > .table:last-child { - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; -} -.panel > .table:last-child > tbody:last-child > tr:last-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { - border-bottom-left-radius: 3px; - border-bottom-right-radius: 3px; -} -.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, -.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { - border-bottom-left-radius: 3px; -} -.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, -.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { - border-bottom-right-radius: 3px; -} -.panel > .panel-body + .table, -.panel > .panel-body + .table-responsive, -.panel > .table + .panel-body, -.panel > .table-responsive + .panel-body { - border-top: 1px solid #dddddd; -} -.panel > .table > tbody:first-child > tr:first-child th, -.panel > .table > tbody:first-child > tr:first-child td { - border-top: 0; -} -.panel > .table-bordered, -.panel > .table-responsive > .table-bordered { - border: 0; -} -.panel > .table-bordered > thead > tr > th:first-child, -.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, -.panel > .table-bordered > tbody > tr > th:first-child, -.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, -.panel > .table-bordered > tfoot > tr > th:first-child, -.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, -.panel > .table-bordered > thead > tr > td:first-child, -.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, -.panel > .table-bordered > tbody > tr > td:first-child, -.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, -.panel > .table-bordered > tfoot > tr > td:first-child, -.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { - border-left: 0; -} -.panel > .table-bordered > thead > tr > th:last-child, -.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, -.panel > .table-bordered > tbody > tr > th:last-child, -.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, -.panel > .table-bordered > tfoot > tr > th:last-child, -.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, -.panel > .table-bordered > thead > tr > td:last-child, -.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, -.panel > .table-bordered > tbody > tr > td:last-child, -.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, -.panel > .table-bordered > tfoot > tr > td:last-child, -.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { - border-right: 0; -} -.panel > .table-bordered > thead > tr:first-child > td, -.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, -.panel > .table-bordered > tbody > tr:first-child > td, -.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, -.panel > .table-bordered > thead > tr:first-child > th, -.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, -.panel > .table-bordered > tbody > tr:first-child > th, -.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { - border-bottom: 0; -} -.panel > .table-bordered > tbody > tr:last-child > td, -.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, -.panel > .table-bordered > tfoot > tr:last-child > td, -.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, -.panel > .table-bordered > tbody > tr:last-child > th, -.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, -.panel > .table-bordered > tfoot > tr:last-child > th, -.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { - border-bottom: 0; -} -.panel > .table-responsive { - border: 0; - margin-bottom: 0; -} -.panel-group { - margin-bottom: 20px; -} -.panel-group .panel { - margin-bottom: 0; - border-radius: 4px; -} -.panel-group .panel + .panel { - margin-top: 5px; -} -.panel-group .panel-heading { - border-bottom: 0; -} -.panel-group .panel-heading + .panel-collapse > .panel-body, -.panel-group .panel-heading + .panel-collapse > .list-group { - border-top: 1px solid #dddddd; -} -.panel-group .panel-footer { - border-top: 0; -} -.panel-group .panel-footer + .panel-collapse .panel-body { - border-bottom: 1px solid #dddddd; -} -.panel-default { - border-color: #dddddd; -} -.panel-default > .panel-heading { - color: #333333; - background-color: #f5f5f5; - border-color: #dddddd; -} -.panel-default > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #dddddd; -} -.panel-default > .panel-heading .badge { - color: #f5f5f5; - background-color: #333333; -} -.panel-default > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #dddddd; -} -.panel-primary { - border-color: #337ab7; -} -.panel-primary > .panel-heading { - color: #ffffff; - background-color: #337ab7; - border-color: #337ab7; -} -.panel-primary > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #337ab7; -} -.panel-primary > .panel-heading .badge { - color: #337ab7; - background-color: #ffffff; -} -.panel-primary > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #337ab7; -} -.panel-success { - border-color: #d6e9c6; -} -.panel-success > .panel-heading { - color: #3c763d; - background-color: #dff0d8; - border-color: #d6e9c6; -} -.panel-success > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #d6e9c6; -} -.panel-success > .panel-heading .badge { - color: #dff0d8; - background-color: #3c763d; -} -.panel-success > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #d6e9c6; -} -.panel-info { - border-color: #bce8f1; -} -.panel-info > .panel-heading { - color: #31708f; - background-color: #d9edf7; - border-color: #bce8f1; -} -.panel-info > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #bce8f1; -} -.panel-info > .panel-heading .badge { - color: #d9edf7; - background-color: #31708f; -} -.panel-info > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #bce8f1; -} -.panel-warning { - border-color: #faebcc; -} -.panel-warning > .panel-heading { - color: #8a6d3b; - background-color: #fcf8e3; - border-color: #faebcc; -} -.panel-warning > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #faebcc; -} -.panel-warning > .panel-heading .badge { - color: #fcf8e3; - background-color: #8a6d3b; -} -.panel-warning > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #faebcc; -} -.panel-danger { - border-color: #ebccd1; -} -.panel-danger > .panel-heading { - color: #a94442; - background-color: #f2dede; - border-color: #ebccd1; -} -.panel-danger > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #ebccd1; -} -.panel-danger > .panel-heading .badge { - color: #f2dede; - background-color: #a94442; -} -.panel-danger > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #ebccd1; -} -.embed-responsive { - position: relative; - display: block; - height: 0; - padding: 0; - overflow: hidden; -} -.embed-responsive .embed-responsive-item, -.embed-responsive iframe, -.embed-responsive embed, -.embed-responsive object, -.embed-responsive video { - position: absolute; - top: 0; - left: 0; - bottom: 0; - height: 100%; - width: 100%; - border: 0; -} -.embed-responsive.embed-responsive-16by9 { - padding-bottom: 56.25%; -} -.embed-responsive.embed-responsive-4by3 { - padding-bottom: 75%; -} -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: #f5f5f5; - border: 1px solid #e3e3e3; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -} -.well blockquote { - border-color: #ddd; - border-color: rgba(0, 0, 0, 0.15); -} -.well-lg { - padding: 24px; - border-radius: 6px; -} -.well-sm { - padding: 9px; - border-radius: 3px; -} -.close { - float: right; - font-size: 21px; - font-weight: bold; - line-height: 1; - color: #000000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); -} -.close:hover, -.close:focus { - color: #000000; - text-decoration: none; - cursor: pointer; - opacity: 0.5; - filter: alpha(opacity=50); -} -button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} -.modal-open { - overflow: hidden; -} -.modal { - display: none; - overflow: hidden; - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - -webkit-overflow-scrolling: touch; - outline: 0; -} -.modal.fade .modal-dialog { - -webkit-transform: translate(0, -25%); - -ms-transform: translate(0, -25%); - -o-transform: translate(0, -25%); - transform: translate(0, -25%); - -webkit-transition: -webkit-transform 0.3s ease-out; - -moz-transition: -moz-transform 0.3s ease-out; - -o-transition: -o-transform 0.3s ease-out; - transition: transform 0.3s ease-out; -} -.modal.in .modal-dialog { - -webkit-transform: translate(0, 0); - -ms-transform: translate(0, 0); - -o-transform: translate(0, 0); - transform: translate(0, 0); -} -.modal-open .modal { - overflow-x: hidden; - overflow-y: auto; -} -.modal-dialog { - position: relative; - width: auto; - margin: 10px; -} -.modal-content { - position: relative; - background-color: #ffffff; - border: 1px solid #999999; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 6px; - -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - background-clip: padding-box; - outline: 0; -} -.modal-backdrop { - position: absolute; - top: 0; - right: 0; - left: 0; - background-color: #000000; -} -.modal-backdrop.fade { - opacity: 0; - filter: alpha(opacity=0); -} -.modal-backdrop.in { - opacity: 0.5; - filter: alpha(opacity=50); -} -.modal-header { - padding: 15px; - border-bottom: 1px solid #e5e5e5; - min-height: 16.42857143px; -} -.modal-header .close { - margin-top: -2px; -} -.modal-title { - margin: 0; - line-height: 1.42857143; -} -.modal-body { - position: relative; - padding: 15px; -} -.modal-footer { - padding: 15px; - text-align: right; - border-top: 1px solid #e5e5e5; -} -.modal-footer .btn + .btn { - margin-left: 5px; - margin-bottom: 0; -} -.modal-footer .btn-group .btn + .btn { - margin-left: -1px; -} -.modal-footer .btn-block + .btn-block { - margin-left: 0; -} -.modal-scrollbar-measure { - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll; -} -@media (min-width: 768px) { - .modal-dialog { - width: 600px; - margin: 30px auto; - } - .modal-content { - -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - } - .modal-sm { - width: 300px; - } -} -@media (min-width: 992px) { - .modal-lg { - width: 900px; - } -} -.tooltip { - position: absolute; - z-index: 1070; - display: block; - visibility: visible; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 12px; - font-weight: normal; - line-height: 1.4; - opacity: 0; - filter: alpha(opacity=0); -} -.tooltip.in { - opacity: 0.9; - filter: alpha(opacity=90); -} -.tooltip.top { - margin-top: -3px; - padding: 5px 0; -} -.tooltip.right { - margin-left: 3px; - padding: 0 5px; -} -.tooltip.bottom { - margin-top: 3px; - padding: 5px 0; -} -.tooltip.left { - margin-left: -3px; - padding: 0 5px; -} -.tooltip-inner { - max-width: 200px; - padding: 3px 8px; - color: #ffffff; - text-align: center; - text-decoration: none; - background-color: #000000; - border-radius: 4px; -} -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.tooltip.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-width: 5px 5px 0; - border-top-color: #000000; -} -.tooltip.top-left .tooltip-arrow { - bottom: 0; - right: 5px; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #000000; -} -.tooltip.top-right .tooltip-arrow { - bottom: 0; - left: 5px; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #000000; -} -.tooltip.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-width: 5px 5px 5px 0; - border-right-color: #000000; -} -.tooltip.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-width: 5px 0 5px 5px; - border-left-color: #000000; -} -.tooltip.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000000; -} -.tooltip.bottom-left .tooltip-arrow { - top: 0; - right: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000000; -} -.tooltip.bottom-right .tooltip-arrow { - top: 0; - left: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000000; -} -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1060; - display: none; - max-width: 276px; - padding: 1px; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - font-weight: normal; - line-height: 1.42857143; - text-align: left; - background-color: #ffffff; - background-clip: padding-box; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - white-space: normal; -} -.popover.top { - margin-top: -10px; -} -.popover.right { - margin-left: 10px; -} -.popover.bottom { - margin-top: 10px; -} -.popover.left { - margin-left: -10px; -} -.popover-title { - margin: 0; - padding: 8px 14px; - font-size: 14px; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - border-radius: 5px 5px 0 0; -} -.popover-content { - padding: 9px 14px; -} -.popover > .arrow, -.popover > .arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.popover > .arrow { - border-width: 11px; -} -.popover > .arrow:after { - border-width: 10px; - content: ""; -} -.popover.top > .arrow { - left: 50%; - margin-left: -11px; - border-bottom-width: 0; - border-top-color: #999999; - border-top-color: rgba(0, 0, 0, 0.25); - bottom: -11px; -} -.popover.top > .arrow:after { - content: " "; - bottom: 1px; - margin-left: -10px; - border-bottom-width: 0; - border-top-color: #ffffff; -} -.popover.right > .arrow { - top: 50%; - left: -11px; - margin-top: -11px; - border-left-width: 0; - border-right-color: #999999; - border-right-color: rgba(0, 0, 0, 0.25); -} -.popover.right > .arrow:after { - content: " "; - left: 1px; - bottom: -10px; - border-left-width: 0; - border-right-color: #ffffff; -} -.popover.bottom > .arrow { - left: 50%; - margin-left: -11px; - border-top-width: 0; - border-bottom-color: #999999; - border-bottom-color: rgba(0, 0, 0, 0.25); - top: -11px; -} -.popover.bottom > .arrow:after { - content: " "; - top: 1px; - margin-left: -10px; - border-top-width: 0; - border-bottom-color: #ffffff; -} -.popover.left > .arrow { - top: 50%; - right: -11px; - margin-top: -11px; - border-right-width: 0; - border-left-color: #999999; - border-left-color: rgba(0, 0, 0, 0.25); -} -.popover.left > .arrow:after { - content: " "; - right: 1px; - border-right-width: 0; - border-left-color: #ffffff; - bottom: -10px; -} -.carousel { - position: relative; -} -.carousel-inner { - position: relative; - overflow: hidden; - width: 100%; -} -.carousel-inner > .item { - display: none; - position: relative; - -webkit-transition: 0.6s ease-in-out left; - -o-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; -} -.carousel-inner > .item > img, -.carousel-inner > .item > a > img { - line-height: 1; -} -@media all and (transform-3d), (-webkit-transform-3d) { - .carousel-inner > .item { - transition: transform 0.6s ease-in-out; - backface-visibility: hidden; - perspective: 1000; - } - .carousel-inner > .item.next, - .carousel-inner > .item.active.right { - transform: translate3d(100%, 0, 0); - left: 0; - } - .carousel-inner > .item.prev, - .carousel-inner > .item.active.left { - transform: translate3d(-100%, 0, 0); - left: 0; - } - .carousel-inner > .item.next.left, - .carousel-inner > .item.prev.right, - .carousel-inner > .item.active { - transform: translate3d(0, 0, 0); - left: 0; - } -} -.carousel-inner > .active, -.carousel-inner > .next, -.carousel-inner > .prev { - display: block; -} -.carousel-inner > .active { - left: 0; -} -.carousel-inner > .next, -.carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; -} -.carousel-inner > .next { - left: 100%; -} -.carousel-inner > .prev { - left: -100%; -} -.carousel-inner > .next.left, -.carousel-inner > .prev.right { - left: 0; -} -.carousel-inner > .active.left { - left: -100%; -} -.carousel-inner > .active.right { - left: 100%; -} -.carousel-control { - position: absolute; - top: 0; - left: 0; - bottom: 0; - width: 15%; - opacity: 0.5; - filter: alpha(opacity=50); - font-size: 20px; - color: #ffffff; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); -} -.carousel-control.left { - background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); - background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); -} -.carousel-control.right { - left: auto; - right: 0; - background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); - background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); -} -.carousel-control:hover, -.carousel-control:focus { - outline: 0; - color: #ffffff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); -} -.carousel-control .icon-prev, -.carousel-control .icon-next, -.carousel-control .glyphicon-chevron-left, -.carousel-control .glyphicon-chevron-right { - position: absolute; - top: 50%; - z-index: 5; - display: inline-block; -} -.carousel-control .icon-prev, -.carousel-control .glyphicon-chevron-left { - left: 50%; - margin-left: -10px; -} -.carousel-control .icon-next, -.carousel-control .glyphicon-chevron-right { - right: 50%; - margin-right: -10px; -} -.carousel-control .icon-prev, -.carousel-control .icon-next { - width: 20px; - height: 20px; - margin-top: -10px; - font-family: serif; -} -.carousel-control .icon-prev:before { - content: '\2039'; -} -.carousel-control .icon-next:before { - content: '\203a'; -} -.carousel-indicators { - position: absolute; - bottom: 10px; - left: 50%; - z-index: 15; - width: 60%; - margin-left: -30%; - padding-left: 0; - list-style: none; - text-align: center; -} -.carousel-indicators li { - display: inline-block; - width: 10px; - height: 10px; - margin: 1px; - text-indent: -999px; - border: 1px solid #ffffff; - border-radius: 10px; - cursor: pointer; - background-color: #000 \9; - background-color: rgba(0, 0, 0, 0); -} -.carousel-indicators .active { - margin: 0; - width: 12px; - height: 12px; - background-color: #ffffff; -} -.carousel-caption { - position: absolute; - left: 15%; - right: 15%; - bottom: 20px; - z-index: 10; - padding-top: 20px; - padding-bottom: 20px; - color: #ffffff; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); -} -.carousel-caption .btn { - text-shadow: none; -} -@media screen and (min-width: 768px) { - .carousel-control .glyphicon-chevron-left, - .carousel-control .glyphicon-chevron-right, - .carousel-control .icon-prev, - .carousel-control .icon-next { - width: 30px; - height: 30px; - margin-top: -15px; - font-size: 30px; - } - .carousel-control .glyphicon-chevron-left, - .carousel-control .icon-prev { - margin-left: -15px; - } - .carousel-control .glyphicon-chevron-right, - .carousel-control .icon-next { - margin-right: -15px; - } - .carousel-caption { - left: 20%; - right: 20%; - padding-bottom: 30px; - } - .carousel-indicators { - bottom: 20px; - } -} -.clearfix:before, -.clearfix:after, -.dl-horizontal dd:before, -.dl-horizontal dd:after, -.container:before, -.container:after, -.container-fluid:before, -.container-fluid:after, -.row:before, -.row:after, -.form-horizontal .form-group:before, -.form-horizontal .form-group:after, -.btn-toolbar:before, -.btn-toolbar:after, -.btn-group-vertical > .btn-group:before, -.btn-group-vertical > .btn-group:after, -.nav:before, -.nav:after, -.navbar:before, -.navbar:after, -.navbar-header:before, -.navbar-header:after, -.navbar-collapse:before, -.navbar-collapse:after, -.pager:before, -.pager:after, -.panel-body:before, -.panel-body:after, -.modal-footer:before, -.modal-footer:after { - content: " "; - display: table; -} -.clearfix:after, -.dl-horizontal dd:after, -.container:after, -.container-fluid:after, -.row:after, -.form-horizontal .form-group:after, -.btn-toolbar:after, -.btn-group-vertical > .btn-group:after, -.nav:after, -.navbar:after, -.navbar-header:after, -.navbar-collapse:after, -.pager:after, -.panel-body:after, -.modal-footer:after { - clear: both; -} -.center-block { - display: block; - margin-left: auto; - margin-right: auto; -} -.pull-right { - float: right !important; -} -.pull-left { - float: left !important; -} -.hide { - display: none !important; -} -.show { - display: block !important; -} -.invisible { - visibility: hidden; -} -.text-hide { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} -.hidden { - display: none !important; - visibility: hidden !important; -} -.affix { - position: fixed; -} -@-ms-viewport { - width: device-width; -} -.visible-xs, -.visible-sm, -.visible-md, -.visible-lg { - display: none !important; -} -.visible-xs-block, -.visible-xs-inline, -.visible-xs-inline-block, -.visible-sm-block, -.visible-sm-inline, -.visible-sm-inline-block, -.visible-md-block, -.visible-md-inline, -.visible-md-inline-block, -.visible-lg-block, -.visible-lg-inline, -.visible-lg-inline-block { - display: none !important; -} -@media (max-width: 767px) { - .visible-xs { - display: block !important; - } - table.visible-xs { - display: table; - } - tr.visible-xs { - display: table-row !important; - } - th.visible-xs, - td.visible-xs { - display: table-cell !important; - } -} -@media (max-width: 767px) { - .visible-xs-block { - display: block !important; - } -} -@media (max-width: 767px) { - .visible-xs-inline { - display: inline !important; - } -} -@media (max-width: 767px) { - .visible-xs-inline-block { - display: inline-block !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm { - display: block !important; - } - table.visible-sm { - display: table; - } - tr.visible-sm { - display: table-row !important; - } - th.visible-sm, - td.visible-sm { - display: table-cell !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm-block { - display: block !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm-inline { - display: inline !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm-inline-block { - display: inline-block !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md { - display: block !important; - } - table.visible-md { - display: table; - } - tr.visible-md { - display: table-row !important; - } - th.visible-md, - td.visible-md { - display: table-cell !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md-block { - display: block !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md-inline { - display: inline !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md-inline-block { - display: inline-block !important; - } -} -@media (min-width: 1200px) { - .visible-lg { - display: block !important; - } - table.visible-lg { - display: table; - } - tr.visible-lg { - display: table-row !important; - } - th.visible-lg, - td.visible-lg { - display: table-cell !important; - } -} -@media (min-width: 1200px) { - .visible-lg-block { - display: block !important; - } -} -@media (min-width: 1200px) { - .visible-lg-inline { - display: inline !important; - } -} -@media (min-width: 1200px) { - .visible-lg-inline-block { - display: inline-block !important; - } -} -@media (max-width: 767px) { - .hidden-xs { - display: none !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .hidden-sm { - display: none !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-md { - display: none !important; - } -} -@media (min-width: 1200px) { - .hidden-lg { - display: none !important; - } -} -.visible-print { - display: none !important; -} -@media print { - .visible-print { - display: block !important; - } - table.visible-print { - display: table; - } - tr.visible-print { - display: table-row !important; - } - th.visible-print, - td.visible-print { - display: table-cell !important; - } -} -.visible-print-block { - display: none !important; -} -@media print { - .visible-print-block { - display: block !important; - } -} -.visible-print-inline { - display: none !important; -} -@media print { - .visible-print-inline { - display: inline !important; - } -} -.visible-print-inline-block { - display: none !important; -} -@media print { - .visible-print-inline-block { - display: inline-block !important; - } -} -@media print { - .hidden-print { - display: none !important; - } -} -#wrap { - padding-top: 70px; -} -.navbar-nav.navbar-right:last-child { - margin-right: 0; -} diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/alldevices.hbs b/modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/alldevices.hbs deleted file mode 100644 index 818a000a..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/alldevices.hbs +++ /dev/null @@ -1,39 +0,0 @@ -{{#zone "main"}} -
-
-
-
-

My Devices

-
-
-
-
-
-
- - - - - - - - - - - {{! All devices will be listed here @see: alldevices_util.js}} - - - - - -
Device IDNameTypeAction
- No Devices available. -
-
-
-
-{{/zone}} -{{#zone "bottomJs"}} - -{{/zone}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/alldevices.js b/modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/alldevices.js deleted file mode 100644 index 780b8f3e..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/alldevices.js +++ /dev/null @@ -1,4 +0,0 @@ -function onRequest(context) { - context.myDevicePath = "/iot/mydevice"; - return context; -} diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/alldevices.json b/modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/alldevices.json deleted file mode 100644 index 795898d0..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/alldevices.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "predicate": "true" -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/public/js/alldevices_util.js b/modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/public/js/alldevices_util.js deleted file mode 100644 index 0b9c881c..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/alldevices/public/js/alldevices_util.js +++ /dev/null @@ -1,49 +0,0 @@ -function getAllDevices() { - var getDevicesRequest = $.ajax({ - url: "api/devices/all/", - method: "GET", - contentType: "application/json" - }); - - getDevicesRequest.done(function (data) { - updateDevicesTable(JSON.parse(data)); - }); - - getDevicesRequest.fail(function (jqXHR, textStatus) { - var err = jqXHR; - alert("Request failed: " + textStatus); - }); -} - -function updateDevicesTable(data) { - devices = data.data.device; - if (devices.length > 0) { - clearTable('devicesTable'); - for (var i = 0; i < devices.length; i++) { - var deviceIdentifier = devices[i].deviceIdentifier; - var deviceName = devices[i].name; - var deviceType = devices[i].type; - $('#devicesTable tbody').append( - "" + deviceIdentifier + "" + - "" + deviceName + "" + - "" + deviceType + "" + - "" + - "" + - "" + - "" + - "" + - ""); - } - } -} - -function clearTable(tableId) { - $('#' + tableId + ' tbody > tr').remove(); -} - -$(document).ready(function () { - getAllDevices(); -}); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/appbar/appbar.hbs b/modules/distribution/src/repository/jaggeryapps/iot/units/appbar/appbar.hbs deleted file mode 100644 index c7279a1f..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/appbar/appbar.hbs +++ /dev/null @@ -1,164 +0,0 @@ -{{#zone "main"}} - -
-
- - -
-
-
-
Register

-
- -
-
-
- First Name -
-
- -
-
-
-
- Last Name -
-
- -
-
-
-
- Username -
-
- -
-
-
-
- Email -
-
- -
-
-
-
- Password -
-
- -
-
-
-
- Confirm Password -
-
- -
-
-
- - I Agree by Clicking register, you agree to the Terms and Conditions set out by this site -
- -
- - -
-
-
- -
- -
-
- -{{/zone}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/appbar/appbar.js b/modules/distribution/src/repository/jaggeryapps/iot/units/appbar/appbar.js deleted file mode 100644 index be564964..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/appbar/appbar.js +++ /dev/null @@ -1,19 +0,0 @@ -function onRequest(context){ - var dcProps = require('/config/dc-props.js').config(); - if (dcProps.ssoConfiguration.enabled) { - response.sendRedirect(dcProps.appContext + "sso/login"); - exit(); - }else{ - context.loginPath = "api/user/login"; - } - - var constants = require("/modules/constants.js"); - var localLogoutURL = dcProps.appContext + "api/user/logout"; - var ssoLogoutURL = dcProps.appContext + "sso/logout"; - context.logoutURL = dcProps.ssoConfiguration.enabled? ssoLogoutURL : localLogoutURL; - context.user = session.get(constants.USER_SESSION_KEY); - - context.viewonly = !context.user; - - return context; -} diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/appbar/appbar.json b/modules/distribution/src/repository/jaggeryapps/iot/units/appbar/appbar.json deleted file mode 100644 index 6240cff5..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/appbar/appbar.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "predicate": "false" -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/appbar/public/images/logo.png b/modules/distribution/src/repository/jaggeryapps/iot/units/appbar/public/images/logo.png deleted file mode 100644 index 8a89f0f833b81b9917fc77053afdbdf86e6ded5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5028 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 -
-
-
-

ArduinoUno

-
-

Connect your Arduino Uno device - to the WSO2 Device Cloud.

-
-
-
-
- -
-
-

Ingredients

-
-

Hardware Requirements

-

- - - - Arduino Uno

- - - - Arduino Ethernet / WiFi Shield -

- -
-
-

Prepare


-

Get your device ready

-
- 01 Mount the Ethernet / Wifi shield on the Arduino Uno device. -
-
- 02 Mount the Ethernet / Wifi shield on the Arduino Uno device. -
-
- 03 Mount the Ethernet / Wifi shield on the Arduino Uno device. -
-
-
-
-
-

Connect (Quickstart)

-
-

Internet of Things Foundation Quickstart connection

-
- 01 Use the following command to download the installer from GitHub:
-
-
- 02 Download the Sketch installer from the Arduino website http://arduino.cc/en/Main/Software
-
-
- 03 Install the Sketch program
-
-
- 04 Use the Sketch program to open the samples code samples/quickstart/quickstart.ino
-
-
- 05 View the lower part of the Sketch pad window to check that the COM connection is shown as active
-
-
-
-
-{{/zone}} -{{#zone "topCss"}} - - -{{/zone}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/arduino.js b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/arduino.js deleted file mode 100644 index dae1a137..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/arduino.js +++ /dev/null @@ -1,4 +0,0 @@ -function onRequest(context){ - context.sketchPath = "api/device/sketch/download"; - return context; -} diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/arduino.json b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/arduino.json deleted file mode 100644 index 3dbff381..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/arduino.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "predicate": "false" -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/public/images/arduino-thumb.png b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/public/images/arduino-thumb.png deleted file mode 100644 index 31cb9fa364acb9e8684c981be706980a187a9c8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9862 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 diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/public/images/arduino.png b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/arduino/public/images/arduino.png deleted file mode 100644 index 2ea44288f5508dbc5da9df76a48be2aa0d5db780..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1162747 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

}0{XO=J57uxk_d~Pl z<~omb`BzkxTVadxv%<)5>)NZshCWczc z*h!X^IUbBisNB?(teeWyO2~ESSUusiU3LtUQyXTp4)Pd0z5H#ve8D8U>#pzE)2nvb zN#A?KYStZMo_OufE2*&k+w1JQ(-zq|H$Q4`?ml9d%r3UwAAVr_-+hwV)NR+0>}~F% z#g4|Eddhr;Ak?;R-U^K;b7ppyb#)NcqgMbtYblQ+7ex~^O9fteJEtj%M~j?I##QAR zs;jHB!n}09#~;b zHnvZM0irp`B$iev2qMQcVnN6(q9js-n9|T}F+l}nXo3SE zZc>kcAORbvK>|>@2o3Hn`!zq^y>&-{18JzF5pyZt*%t^IbUs;*fHUs|swBa(K>T5W zJdjQI*SkyOBwr>u%MWQ)uxarL)VVwk{8sJ>f8jthYN((Ex?Dy$BzKuQyIGu)e585M zCV#Cy0Eq*cx+lL?+)=<&h4N(bs;VgGuhPyseZJlQm#6Hs3$LVwsJfdg?bCN&wACNH zX9pU3$%q|ksh9%#c>e(;WC5fgB+Ve4r)549PmtQ0Cb@TrMtiVf{c033O?K|Nm!saM zpIH3Qd>{hdWh*z7Yker zM&X2Fb}sUW_i`bI?3V=S9Aw3aI4&kC#>Q8E(4j1RO*%Qs>stBfC_|zAvhZVbj3)*S zQ(TILCMS`ydWEg|c&nX%+H9L!kU=KV3IHW(*-14n4Q3~f!LcNly8g>&lGN*jE&X7p zU2)S7?81vLv+q9shJE<_M!*#fE`T7(l%zySa?o~}t9ZUdT$!y@Kra;#CQ97|V^Q=N z^AmkPikEtuT}rYmGNit@ZY@~RXK`fz97f|XOrjePNuhc`4V`EvGpU?Dd2BI(3H9(| zgbn7w(XzufWn3wEGZgdU`w;p@rvS;yPO-^T##=3YF0G;nz9x2TbPN~?A_`cJgoqAx zRM`)|{{zdLx{&s?*^eK6%c>hV*9Rk3)SHUl$*j~VW=!8IB21ZJrL~b6NJL%WLF<6! z`oZ3Mdtmbkr1@qFRG+X5PF-MCXub|(;t^fG{DO;Y&prU|l6UM&=bU8MTyl;rUA@89 ze6ruls~a&79k63%RW>F+*5(w&+p3+I3jvsx0fAR81OW~$Edd*8f&{RYSWPAi=Ab`$ z75iwWOSmM7TML>3a@Nmz(!%L|0G=+kT;HYr;uPUH7B~OsVmA5xX~L7W)&))|xs?FC zfIp^jmlr{~5fr88aw~8hyImlL&XfG(f-?B7Tm*84m+zO%gaV8D)ST6v(OhOsc;Mf> zANOM&xwfetobKMmbpY+uZ*6)%^@V_^KpC0|1NT@g@2Xr4b$pjKK>K3YCm`0y^#XWG zFs4f4=?d+z_cJ0@`ZllMbovW(0=Bf%yC9owS5qAgx zK_yXt_01&z!tx-YYnXW+ir=1u{nFxM%Oqcla@}N+U3d_hCXmyGnLdvk45uzyM6@9p zhw&K}U=rWyM}w!~?I2}&nEWxdF{a`P8fazT7EhAkDifgxIx@_C41xsmbMl@jv7pXf19$ey}DvcMPMAWoYqTcRe1PSoO`X-|(j+-Dq`UlF-t( z6Ny1}V3?zC044_EQw;zWhy$}TNst5pAM&A+H0yz2$)Ve6o?t+&gu@FMNt4BiZnANa z14Bw8<<6sBY8#4NCOrU%i7t(pz)L8O@|vjP>w1%5q})L!bTDR07p2GI@S6qw(ur~# zXw!m`&zA_FBD!S$b5ez)`?QsX=d@&~>H{D$h{d5u4iVje32>Nb0coWa9j4?VL1-O@ zNX8S2UqC<6K&tg47aQ5+6=EBU&3uree^TdnBK6iE+G#md9=`9-4^qeER>$AzeLJ%A z6WjjL20M71lI@`|E=09RfK(ONM1xks@K=aHE6@RujfKeg(7;HNLucr~WfV~{(Awn4o|cfYX5$B{{;U;PbG3 zInpM=7zDBu&DRA%7k!ie6Vlxq&%Hxe)Dxy&Oyu8X_S%~-<6qT)zex;QKXP0UdDqfh zOQc)9{p|ZU+WPJH+tpWp)5grb+#+XAH#|9E?EJ~ZQpcZssv^W7`4poOqg0I>y?``r z04QtYa}c$Ud}-(lRjM8pABlGHxT|{+%X!I3i9}pN6afo9jX&DRg!l-{AD`{Obr#W3 z5n)qp)AmCSTV$nX!qdWR{KR6HkZr@3T_i6ZMPayZ8&^_jIR*JRnty^n8Q_&}=qLMM zBw(x;ZJ`HXd+k@gWT$-f4mTe^{VNH?sCi)#Xc#0J30$eq+IScBv(wP9?(|wPAR5U% zIY*BB?tMj!K@}D3?>}K5K6;m(H2-Y7?%#iDySGr(4ei1=uf5zJdiXcCbje%xvnQXi zRcm+IyPNi~cDWG<6HA_izRDxL#mN=jnXChwdi{ zP~Y`TT`Or)Al%J!^*P6(J*Xc!kNzDwuDkY1o4xQX{O?1o@_2={ z)i-=jYjNbT1+!<^DS)JV@BgjU)i+vkaS~)mHQf4LM$dTM1!A*fp^p^o!-^2n-NHR8 zY%0E1V+u>~XM|U=cAYW-+D|Vy*`rH||DdrFH08!I1dtM4mwDa;f6`|s+NmITQm_|a zC){EBh$xQ0N)U>m?Ty6r$67;N^_wZVZv^-0>&BN0I?;`ZPe9B&>`!*(Az+{%4R0_& z2M&a?H`p2hrD13)m2N%^nwW%U@dL}SidM8zayua9jH|33N6}H*b3ze<(y}UHSv;T4 z^y{^+q%_#g(+LQfP>M1+!P?sZVnkXhb9Cr{Qd3~P=Zq?wW|G|`q9Xw0LAn*P4iS-H5)C>6<-HY$y~hXv9*m0fn+wBprf*s}C8O!nl`k(Y zM}?e1)RqXiOlF#3A!LM;DR77h-%tGs0V_FPO9d<7p?E%}DAxqnpEOJ^G6V!K&5%^I z+T=K|?{X}Zc1nq&BRRAv@h4;>VM;65B@PP=Oao}8VXbM&ca z%Nd=^9GG)jEIpY0K1nHj>bVYFsnsIfoX`IwG*^ixbS>?}G}(_CCmd(%J{FQR6%k02 zlqCdAM&c_Kf1xc3K|STg^fQPmTG5QGam<4F`vBa!iH`Ci$tbjU7^x>dA=4V0>g>%oU$yCI zpQcWqLnw2Le_UWxdY54sg@#(=BI!x0>H)o+@CWa-=g>h2hoqej+qHi`(wPtGP-)5u zs}tQP*Gp6rV-t}U6T)}QF(KZ=nF8rsr@_LJ)-e@nx!@IaoS!jC zlLf6uOr&vq2Xr){+1avVuN_9?(nZA4m;$t?-Sswe`Xrk&brv;aj@yCy0Xqu^@bb1U zTle7+lK_Zq&Cf{GKnI-o6wn8dyLRe*)h=mD@azvFnlGVcgXMT@EE8XqL~5&)M0Hs@ znJ)Vwz@cQ@6dRL<4qs3(W~Ali<5z{IupfZBaONyryhd4FV-0BvB8fVO5aP>LOutoC zR{~0Q*i?L=lG5TW9&JfJ4)^6J>TTbS-MlN2N>KYKgbX>gOF#%~tF$kD=`7N*KTUri zNVFZdpFg_Pj#SlHry?8WC!@Sv0t?Vyr*Tnam;y}%s?@jr?UobYZUrfW){e%bU;aPL zSC^(7rnh+REGx{8vMpP8+skj`d&k(FKR?e(iVN)Q)6ci^vLo#OkSP&LA;(w?r2~ej z%@PZUTDM^v6|%{L^!3ZFC?VGV^6o*vj+<0&I=Ea^0#E`u0#I$V31-AZgdwm`;8y!P z`DB+{S<+NR@k3@TFB3yRMP3vrgT-m6^_sFUO??QyO($>r8lj zO0xGU?_P0oyxgGR#A3>%%U~8$MxFB zdym^e-eZtrlUD)6{_^W@S@DF)cH{la><16N!aaDGDS5W;?l0MCv&Y%5maMVK`AIf; z{A84Dl;qjHM? zT)~!;nN5%rj^#Bcpko9YF+Y+3d9_VsT0M9G{)0G7rir{80TJU&Py^9i7$2qbGh^Kdv zY5FJFDpu^`YJ@hJpbGzKzsz4s zf1rX}E=@ew3#@5jxMF@hM>Ime^-a-z+Vm_f4z*)Q-~xgiFbnFq%!Rr}8nI!{34B-o zNF%0DdpV}MzJfVPvQZlO5EhB5Jj)qB27j7h0Fut>M-m*s5i>42-Vp-{x}7lEV9b*O zV9hnhY+^y7-TB}Wn||)4TArxfaU|ckmZ+CaR*fW*3IPen1l3pHP7nx00HPN`y9cRN zG=Mfh3V~o4aUXvnO16meY%n0q6B0}0T|L@}4{X-NF*f(4)5zCE?i&EFq%WsQV>e)`W;HCU!Dsu(*k z=IgR@z@$Z_F<4#J5|v^L#?H3+3m4it(p=l<1@`F)k7Z52kn{_=W+zWJS4EfPi%u#R z7!iYR=dXkNN+Y7*lIAs|nL}ThS7^7Km2R82#oA}2W3O%MVw}n?EiDUI8MH}lfF3T1 zfMK`wqwzyS7?1W~LTNs}!^!q3+Nw31cG=XTYyvuP#%Ih*XBJrh=3oL0j@g(}987E5 zZU4djcG(4I*fTG@WACha(Fr6#Dgd~;g!h)F6YWQ2UyXh1j&IrG>+g2+qpSRYJ@NW7 z`xwnr!ce0vC=bS|U>fO{g>OTmv{CY&~Ai1IHb*(^=ohpa1S*pIGLhU^I~kU3cKT^&SZQ9q-TUC5tf9Wm5=Q~5 zF>y7v)Vk{1-@M}A2-e86U%b4M0EiZR*qBSwK5=_E8ExX71eP^^k_t38;^=po^ax6D zY0Q<{oT0a{4m&w*$QH)?^9ofHx%zxH(z_<0OG&}C2oWUxVGMbOa$V^;(kyYv%^l~I z%@6J4uzQ|v?!XY&YJO?H31|qw>pE$YSm$ozFvH=$)*W;&!g+yva;@$m=|uYkwlwbr zYTbqOy*6=A0Uz1z_5M0vn*gDnDc`6V7IBj9$FVy4LZ)360#wd0sU_vepB{>`G19iJ z0lan}qmXEwtz(>$#^%#s+*|&GdLOMpgoS9*i61>uZ#xeiv$(`I8=sqM9_2?8m{mle z=9t=z=GFa{u%Ucv%2_7|dmYo9(mipso;zu=73OC<^I3Exf(<|+7`haVg(4=kxmjC|DdONdtyS@GV zbGB#iHoN>w7g+J6SuO&w0|895IRe2n8uQx0gVe%0xWg9Aoq*^x%vn%|h1 z7+dCIt_Q6H~@Py z>!4rJrSKj%zeG52!k>vJ&u!y;cJjnba*CGNQM91lJ*`X&v{n2kUf9-Nef>~)Y|p|o zFL~3w>_6c@L3iJM_ZRZo9nJMI-eB){09t5;amZy-$$?w>c9i}=CNlvJ5BqS&yA^ZN zLp`m{!Oa4cZ^uz~{YR^w`f6<}YmqG2J|-rZ_-K$IBCkk6_}oxcpM?X`&;vLB}}n^G}_x<0Ea+LeVkhuhJ$hkL={(7}%YoI*Uq9^--v9 zReM2gQauzoDu<%Mii8QPQu6@JWte?sm4_`JGvD{V{T=(olS?eUcp_~ZvZ|fy?CsZ{ zw-2}Orv?b15eY4XNVzu5r`@eR^c`i*`A@mGd}y9RkeDO!uNVR(1fe( zDhgucz>WN`6e*=BJ%NK5exn6)lCuDp{^VPLnb4thmjo0h5rtWddLSL0F}53z-}lSw zZF6}Y`?yxmiv)m)&_R$~Z4IS?5U3KPS29sCWN8z`OyqDaa}XiwxwTttbZE6@PMBa# zoj#now^EV14dnu=bs_^h@Q(_Cz_ySoA%geG&P=oE6UWlmkuZQ`;E7%vUzB6jj6oS~ z>LVAKm-9nmFq++Rer>}ccT5TXA<1#JcGF(lvF9*H$a%)P7{*Kx86Hb|A{=7T8jK?g z`pAB*pK7>Az9~ML#I?8wYQ{#dr zXhCL&EsVw4c=c9W{qbH)=6MOpDYhG*4rdm_55)%X`)KBR63dQ`tF_nf{SJMTWDh?5 zl5N8GO$x8`PMc?QF*ock+lB8{1KNRJyJ*2Qd+hN)+oCfsvd3QEVE3=y$8{q5>Qk5l zedn|{st2R>(@x(Dgut9F2Bs^OliDpGD&`$hf}NB%X!qwf+Va)w2(3S1=a0>{T$s)# zsrGcPn2Jnv;oM^s_mFl-CM`6^u2_tGlH_WD(BU*l0-fTUs#6oiJycv!HEjegnKEwP z$^S}088Vqg^Ihlbx3r(qH)cMe!&;R)8{10ia zhR5Zd(jwG)!CBpsXrC%7H|ji|uWPkNB>BkHt2v6Wu?xmJCe>rv%-xL4Bpc2vw3Xf* z8`8K*D4dcNy5^O&~c)ibOvqs@739nE}~?ol-Qd4Z@1~Q7TObU zthRH$^Q`q(HkeJ%v8zs*VY^OHot>h9d1=&RLd!XIY=OP-m&fdhhknD7AGFl8Gy*?L z0S_^l``f8OQ|~}gHQJ#!UVod&!L69p2dtv1*0QscY{8tlXt&63hd|c}a2q$SlzejG zuFA7`iU-~`3JviTQjaJn9%7{fO<~YX6&chvKtGAz@z!+NfA9){FVQ@0qKWdQRY%Dm zSJTW{QJ{B0tl4(JZ+ZC%*XL54s*tF(^V(Cm=K+=&KsIGJ55rW!%ps9z=Lt#z6x1Kt9h_P?0i`fo$>Oz7 zKK15Vciec%JDZw`oKW^`G&Ej_NF>hN12`WmX`x+?i?15O9YBKTAAmy>3L2Y#;4Ll_$3;OLjhz2u$*6&dj{Gi zBnc0oMUs~iOL~zmy{t+f{v|DhGB?-N+PNn$vhV)zXO=eu{~#fU&N};a)lz%!vklfn zm~(JY6oNh>zJSwOvQrSQ^CZ8<(DI ztN!{D3GliALA_KrW|$xb!aM>~j!5Xeqy=D1^$xDC5kzK~zL%wAh<=VI>L@EU#WroL zWZb-V(#&yo&s{&Vg=d^)?|rzz9$vc5jvk;d$w@oCu z1~_#Z1NxlCxc73Q#4-sA=tzSiQ;|#+YF+>U!7xZ^%s$SM{}w-8rfXMCZP zt)-#dUVP$NtHzuZPDbb<%$7-jgH(V_kT20j^;g=S=zPB>hIV@!LsoCTgVp%tws zpS^bOt@|MW_&;?s|GH;#vy1Z_Q0G&cJ%J?&0GfxIb2`U0nD3ew0*3B7edmw>kJ>FQ zl-9cDk2dXgf*|b@fOK?#<5~-1wlH>gUuo=gKbt|ACE4`m9K_7vgNtpjOz<#-;$ zxhljb6Sw>tDFAD=UfYl|4bAKnc5*-E|2hFMQ+^{YS~M&UEa|<`D!-LjYBoEMa|f(a z-NW@Rpu_`RS9>rex_|>^%a?|&mFs-%Ha%m=Cd85kp{v?@lG5yz_GH=^ZCAdu#cIiy zw0LeF89+kpGkgG#`%(Z`*;Gil4DBvKG64K$v^tr2pv+i*5EIvbw*PXobn~ zws7G*d*s+J5{AMl`;!FFtRX+(>ShEV z356-lYk_YNV>s8E`{xh4<|$%fkxv5SpPIvO1k8P;%YPijj3cn7k=C!N3g;TPVU`km{~-nRKz75=l- ze*;`eRV_a(mCFeOsVo17l8_42gkd)51xN@`MI$8%94SSDa!iR1$pj`4CSWCyBnLxn zGGofjr%#2KD!H2$NGOu679cawImSjT3uz z+N^O!_SHLoWM_Zn>r8qU2yHsB>1|u})@xQ)(N0F)NEoNmTC||_!B-3oKsQW22rXg= zny_9m%i(SmFlffm)~J7i@CWk35DuU&Pv!U@?){-1-@d_i?cGItf{Adcu$0lcii4h_&airHujg#gGWO$<{S zD>O$=+Sf6eER@zkj8x1~CL;OMI86upl=+;*dQNjeby6l9Knu>Ts4tx_$9gn>szPk3 z9Bbg7vRT6%h%1*J!15y@Y@P}$D9*Bw*d$AcB||*EQ%L}&5WrPCl5n{EvzW&{(i*~K zr%frsr3sTT8k~;KF8g@PR-A5U+j#^5ytDpO<}}eg^Cy#c3?H=vN36Cv8w+WaEqP^? zMbf?=d_acqmrJG8M=-!j^V`j@?glGG;=S(HKib@Lucom>_U2p9*@~qrEh4j&swSh6 zkbTyKy+@DRb*Wx^qE`LG+?D1|b6CU`pP>!ap>|UCG&}8#7;9=r z_D#>V!*SV+4}C3X4`~TSaT4g$tZdr{V@bLB5&S(6n_B=&LES|7$1!~I_}$dv3Xo)v zz6g_x&9cW=Y_fY-d;%tB>=Yg@)sO7fm^l46<(}N0L191V=sbx7do;iEse0^_mODAY)~R}JBll2yr8PoOauF>GiV(0-DiChr2R6J+V2Xn|{s z17*4oe>$wT>z2}Q9;zmK z6yb@c-Faa#CUB2EDsUW}YPY{r&EH|3LEXWb$@a7BF0tIA@%H3j*V=WDtu`ZNfn|l; zg_Fln`8?ECqowVjeb*rLRaG_GS8w^Q{dLJpmPXe2_^d1&B)ResU_-P>9aD`fglEeR z>MSPNhD}?o27y#g;nEsmY2ggO5$o`KKYh^7BeCkDljqx>iW*z--g{`bDs1w&JfaUL zSQ__Mx}PrmnWQ<6qzZzMzUYVUyCl(!t@AnNQ&E8eQ}RKLfe(oe>bGdR&T+oPboC(X zT3}1*cm%wZex;t26m8I+NI;V`TK#=YP})h#NXL^J8k#JfGCqUMKY>PBGgMx#rwbYn z{n38KawPM2G$hYHYL~_eK%2;TYTd{@%x5q8_56gDACyOOf+oZEmE2ytVVc(p3&&zz zj)8w_tg#yPkX;@iA5I%R9j(`-re>B;nEB7;$WDj-r<-Qm7qbNgQ-Pd86oCVQD`h}3 zS+xg|I8{e!i2O-?L^brmkb0P$ky2UWIo#?C@5?Qk=&3xgGd-(hQjKeD{=)6|KfGf0 zk8Zwn<0nMD1<9cj2{@d|=c3v`@BMNTWg!p2C|n8$skKD|n9Ry~rAe)*KL=Q3S7y_s z)}(h69#A7-(+zWD*)gd}$_T;ZFq4}1U;{@1KF~U7=g8(vgxq@w!o-KuI%yxRan}Wa zoNVOUq}>|gxdMN~sQv{$<*yWjnJNr|<>fr*2+4bd0u)s{N?UA9EDI0cGt|~SNU$x0 z#16GJ+qb@X9Z@x8TvqN9+TC(|yRBLMj(xU$uhk>HQdI&erI(z8El6R!8LIxyF2_xr z#>{1>=e;CJC#C{ecnQ^~t3x|gU3S10&z@@6-+ZI(-T0B+{ksRKF-ZD?@DubE{W&5{ z`++Kp6ODnFHp`by=0+#E0Rk0SDZ-%)!>Oc9sBLJVhS_wx>4tAo(`>wL*uKXec=;V$ zeT2p)rvj!R+9axTrU^L&x6odhPzI}Q#$co6r1sdlGU|rK&W3>`F_7&XXRra%yojHn zh*?QHpd@)X$htg2XgU3+9DYm7AZcGA>;h-n1RSKPfS~yYUdK464Ist1Ie>?+f{PH8 z=2f-NhOmnyaDE$Yr@mq2s4)B8S##~J_m)^=dk}tRUfZ#GqXnTEiqY5;+TZS+QX#UG zo=76sR`#f5>m(PD7;Oa6i{+KgHfemGC8sA~ra;uK5vxEZjR?R;FhL;dgJFQWD~U|+iMEW7pYKl1L$Ru8lI{Ui6;uH87tm%=bc zXIU){#RHnWFvLaK33lPBlkEhNlU0>3qjd%gSw}WngS`09R#()j{?PR3YfOxg}pEfmKIfbS>xTyXKGx^y-^aB{$9c96 z>OGy`72nmz?zr~zU0@Bt42g#T}>E4{y7k*Xy^-e*6qc+PAu{v#B}u={HWX*$Ymho5Jkq z(IaR;58ES8EwfGQm)nx(UaAyUDl zvF6&F2?Bx+Du_vLYvKWj+R(&cJ9xaBq`qscs$S;!E}J)NoXwhj5~LxPh&dvqnRj|^ z3G_Wmp3VFDLh9VC45V`)-+M^_Ac(( zhDqO2imisVA5MQKp}kcMw|s*`h!|E7kq`bVONy*OometDn(&EY?u8O`k%tgbi}m57 zo@^_V&zm!)Ge)se07TL*_PO>VxVX8=yzFMqAou*BsNOE05P?iI*{X1MZ*FY^=uwA~ zc6xcQ$Ufg?eZJqEoAl!UH*R+i|MUxQmVX+20grW|eI8E%DCVfpNeHTx z@EAgzNJ2D>$mJL`vn>Q~$Mj^fxHX)xS6_b64j`gmcl(3GCoMX~(_DTaE^%~8o0=Ou z=G4#bduI9gd+)qq&)b`iyBPL3@&m*{#T6E)5QLv-OCtOz+R z1q%Dg2IpVC%shQ#)=OojO-WFMxU^w$goBYj9dSr18X+AaH`x{aE9LL61v@#S?8GA> zOg5o3dDF|J;6h43J1VZIa1x=sevT{4q>SaFPI6RJ^=sE2R)X3i>Z;!ggJ~@GC$hU!q8nJ_w2c;DS1FE@QPQ z^|}Zu?H`nWaSk{?1K+KAT{_YRBaw>xyx7Clk2yTg?l_4C529d zqbL?%oI;yWkyKc!*y}hJZIUyI@+pW*$QD993^ypwYnXE#GH1WICn`QB5r6!4oKIuJ zizud9DXSSHw@FoiDl0Xjm45!%?z{S0n>%m3?Ko0wTUM>Z76-aTZ3cb9$A-E?9g0XG z$qwqs2yB#Ni?XaRE7Pj0s+h0Tg*kG_+7RXI@thr3n8O_LQm1B@oxXsOJk-9Q?l{2M zson)h3I^JV>L3E{<_e90+=D>dM32}IHil`1X?El7KeZ`meAR{SzWK`26gFG|*UYkc z^XC&O5r^}5rInGnfrH13&pu}*sd093fyb6nyT>K;5*L+o zlaLg1h5&Q8H!x+0{pv3bw!|BGQ_K5Ve_}&T{Fa@TBzLY-a&M}QoqDb%kIt~F*Vfo0 zD>m3|5!v>e_cz#kyACj>S^jZSBBmTTaShLr9ar}ff|e~x>K%;}L+{io4t?+(hi*8A z{S{pzb}aU3+{lJ%M+a?VIOt94DLIPC(MXF<-ta7UDSkA)i8fpd(IvynjqU6 zr#mF>I3?e;N&Tbwp+znw1ZXwmV=Bz$- zUu^+ortfNp>~gw?F4b=(!&1#0YR$MLaB|{mr0;}A6@?+h8AFHp_$>!BY{||EO=>Q| z4LwFkOMR?Y*P0@H){QkPBA3lfk_T(qshNc+)z93{KOWpe;~?9j9QItJcs}#xU|gQf zn$&6)2Y1`2<=bs&%p#t}m~7f^qbDWW)(7sgq=HGdd(S?bc;|CYYO&08?$K$LKe)&; z$4{{D{rOd-l6d>pMd#Z3P222_8~zR8=(BHJagI%!cdC`+P&Il~B9d5wy|#QcY1V7W zuuL5`)gXWV<}0g&g;CciInj;){UDn+los{ zAsNHuW@vR$R{q=y>I!6h=9(g?v_(L39PQ(~vjfrx;v3q8;=D+igQ(qwxcazO>Mg06 z9S`8U&QUugX?F|tr{{AaG^4$lY64V`1}PG_2Wf*&b8atle^}@7coo>~LCOgQIp<&p ztO|;^_q%fFItDSG6HxVM;m8+DG{`470>q>OfPzV&v3dPUd+YUQ5vNaB8X#=r@<%NrIeIuY zB_+7FY=7LSypc-LS@ZVZ^_SOTB5u5}W9i0n64s?#D(ClWV!OH?Og|hDVjVn3L;&V{ z00E)cQdD?Qbr6C8WJ6Bf0gXWYrJ4as@}y0RAp$#=ibW|yoN5FO~6RN!i55|$ig7JF)&l5TOR`GXralFPR=--sydMx zgYg)SX8{1{qNqj;Q)z2!C8hCE9A*dX8`#xu`_Zo;Xi_^3+5U|yZ8fFd%NpBA5J}N6 zG7LtbVo~9`aJ)bx@o?^kxX44kAA&3AD0#F8!xUAZ&VvUpl9BD*vj;O*hkgB$v+d$D z7ow#ZuwVZ8SGKRb$>L$azP@(C2)mqrNgsU@L|BRkbx<$Q0&ap&$SHvMDgK~T@15j; z@Qw7X%5x;4iW?voL^QzS0O^@u!<+rFO-Jb=h=d3_b~JjC@ARA05fxi(@<6Sn%#5^o zi%YG&j+_oYY5+y%+QM@$vWAuy?9;u6?Xbe60Pc>d6KnptXRu^&*_Jd8@)8!k7blWR zM7BXOtq_R6m@2kQrvlL2kaLfSki7b|$$sd*Gf&vQI>#WG7o1;35i7->GCL z)p&TLQK4b0P=2GyDM_{rr$_7Ohg5^A8qEJLe9r*~zRLm0ad|#N0lDN`Kx*Kn>AM!F zvlzRFeIA&#YSm;Cssx3|#W@}P~$;!{AG^P1?pbmj;4O27S4 z_vgFji_(%i@B+XS!$6pDz)#-d0#E{ivRkEbD<$&La7yJu6I`}bwO3g-rKXXpO&~); zkr<{vrTXdPA}4Io2JA6@pv3iZveG=!rsMo{Z4rg#a;KBfVc8l-Xol+^cdky>HTq=Z z6n9@8Q~zo|9}dLmxKx4K0>DcT(|hPaFk1H)XbWl@2W&`C+U-Xb9f=>nm_%~J6ctg&hq_dZx%@IB5c+*2i%KMK z$hdLiES*B6!XNzzl=7Pxpl|egDx=`?4#9hdpd-V~$05eTgC;B zUzB=ZVdshlil82sfRda773rdLLQ!uHz)LCx{*~~I+%Zc2){V-$d!WTewbff23HmYpVo}lg=nnI zD|Gc8qkHYk6IEO`2f21MY$XzNM+5#S6k%lIdObtu#D)h4#b*?KRx-x#!=owkukG)9 z;0p^S)MM*wD$?Q-lW*^e2rF z`=z1s?^3v*e#>JXV4-KRv4;iZ-#-9>*ERanV%4VXp}Ik!w7HzT1jd5U0(fES?mG*r z2j;1J4xl4en(ZXoN`w=k%yA?$8MYHu<xEs1Nw@H`%XDJV=+nmR375l+<$lEaz^d^pmlY(m}iL%$1E48p6j&GzrwWu^HA z_T5{qv&qvZ+Dprp*^6(kpc*Ow4UbPb84RH_A0#}ltfG$f8D!&2N=PT1fQAr#JAFL> z@sK3tY7s%4r6ZT~nKHHt$i|VBB@K__vg#IFbOeGXIOQ0 zwG|c>+KwH2EIvBQW= z$u)lr&uX@F7R=^21QyLu2bH-$SoNaadgJ$P+o1+q{mC&jBJ`8qUEo6+3~7D%@Ow7v z_sDlSu1R~NdLjI*u`bLyD1z8S`g+&jseGV~b|70fm;GNF zB_aS^QYQ_I>{ZgD2r9_uLo%`fI?*7`L_Z)eSJH`XmKWeYe5s`Fl;#22IfKflV`!g;|3da9(hU>t`qpFp) zy5l&tp!#j|{nyxKSAGQzb+w)Py$5W`3!ia*o1J!QsoizeEL*s6B4MA$5zeA)#-xch z*jQzomp^MQ)!RwJH_@)R_)5zzo_;gMX%JpzL{PLcn z+j>9o1ceQXc59z8bVG4C?!~s7NFux>oGa^FaJqtyCo-Qq!&3+gEwN8}(fCTJQ-TIA z>yIW(*@JMaS_;bIEII~{lYmr&HvZXpL3Y{HcpHeyv9@8Z#hTJja>8zWd4P|!qx0&> z@X(%_3om?|K9P9xukAnS0Z%{!^Pe35|8@7_oolDZ#-(o#MtidL;}up@QAWuMst%)R znFg_sL6hOb2`ekN5IRYEbR?h_h{Hf{JMp??euQ9V7tJHyHZO8`s3$(HXkyLZHt?xi zCJZlmr_y?HFzG^SjSh~0W&$us*wd}a%pwa%W6+8DDgtw2DAHlCyr-EnTJe1l30J|H zU&{I^v!SdGfj$yg()S^V2!aUr^ZyoLQPL~{2!(Vg=feO%LiZW~NcbyxiUH^vnf68` z8VvHH=~`Hk04aGiE1a>H_wIpkDdoI8>^&@)gt!E!WjcI#j}@gQ*bTS-&@TDrx7

T3cGJtEG_)d#(2V`fd1eMA@k) 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
=tV05&Xkc0u1%qa6Utc;tNCz#Y@0b;%X_-q( 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%0D? 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

G) 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 O^_RWw`xjpG@&5yBOT)bY diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/digitaldisplay.hbs b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/digitaldisplay.hbs deleted file mode 100644 index 16249bca..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/digitaldisplay.hbs +++ /dev/null @@ -1,80 +0,0 @@ -{{#zone "main"}} -

-
-
-
-

Digital Display

-
-

Connect your Digital Display device - to the WSO2 device cloud.

-
-
-
-
- -
-
-

Ingredients

-
-

Hardware Requirements

-

- - - - Arduino Uno

- - - - Arduino Ethernet / WiFi Shield -

-
- - - -
- -
-
-

Prepare


-

Get your device ready

-
- 01 Mount the Ethernet / Wifi shield on the Arduino Uno device. -
-
- 02 Mount the Ethernet / Wifi shield on the Arduino Uno device. -
-
- 03 Mount the Ethernet / Wifi shield on the Arduino Uno device. -
-
-
-
-
-

Connect (Quickstart)

-
-

Internet of Things Foundation Quickstart connection

-
- 01 Use the following command to download the installer from GitHub:
-
-
- 02 Download the Sketch installer from the Arduino website http://arduino.cc/en/Main/Software
-
-
- 03 Install the Sketch program
-
-
- 04 Use the Sketch program to open the samples code samples/quickstart/quickstart.ino
-
-
- 05 View the lower part of the Sketch pad window to check that the COM connection is shown as active
-
-
-
-
-{{/zone}} -{{#zone "topCss"}} - - -{{/zone}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/digitaldisplay.js b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/digitaldisplay.js deleted file mode 100644 index dae1a137..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/digitaldisplay.js +++ /dev/null @@ -1,4 +0,0 @@ -function onRequest(context){ - context.sketchPath = "api/device/sketch/download"; - return context; -} diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/digitaldisplay.json b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/digitaldisplay.json deleted file mode 100644 index 3dbff381..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/digitaldisplay.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "predicate": "false" -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/public/images/digitaldisplay-thumb.png b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/public/images/digitaldisplay-thumb.png deleted file mode 100644 index fb1f624c3f308505d4b3c5e5b730526d10252665..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8161 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 diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/public/images/digitaldisplay.png b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/digitaldisplay/public/images/digitaldisplay.png deleted file mode 100644 index 1f98d73fd29c351f118173c763e45d3276f42d39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121889 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%0D58|jv6T!Yea=iAX>DDlrzZVJ}z}aHzWVbht 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 diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/firealarm.hbs b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/firealarm.hbs deleted file mode 100644 index 559e299f..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/firealarm.hbs +++ /dev/null @@ -1,89 +0,0 @@ -{{#zone "main"}} -'; - - - return $(html); - } - - function getHideClass() - { - if (opt.autoClose === true) { - return 'hide'; - } - return ''; - } - - function getWeekHead() - { - if (opt.startOfWeek == 'monday') - { - return ''+lang('week-1')+'\ - '+lang('week-2')+'\ - '+lang('week-3')+'\ - '+lang('week-4')+'\ - '+lang('week-5')+'\ - '+lang('week-6')+'\ - '+lang('week-7')+''; - } - else - { - return ''+lang('week-7')+'\ - '+lang('week-1')+'\ - '+lang('week-2')+'\ - '+lang('week-3')+'\ - '+lang('week-4')+'\ - '+lang('week-5')+'\ - '+lang('week-6')+''; - } - } - function isMonthOutOfBounds(month) - { - var month = moment(month); - if (opt.startDate && month.endOf('month').isBefore(opt.startDate)) - { - return true; - } - if (opt.endDate && month.startOf('month').isAfter(opt.endDate)) - { - return true; - } - return false; - } - - function getGapHTML() - { - var html = ['
']; - for(var i=0;i<20;i++) - { - html.push('
\ -
\ -
\ -
\ -
'); - } - html.push('
'); - return html.join(''); - } - - function createMonthHTML(d) - { - var days = []; - d.setDate(1); - var lastMonth = new Date(d.getTime() - 86400000); - var now = new Date(); - - var dayOfWeek = d.getDay(); - if((dayOfWeek == 0) && (opt.startOfWeek == 'monday')) { - // add one week - dayOfWeek = 7; - } - - if (dayOfWeek > 0) - { - for (var i = dayOfWeek; i > 0; i--) - { - var day = new Date(d.getTime() - 86400000*i); - var valid = true; - if (opt.startDate && compare_day(day,opt.startDate) < 0) valid = false; - if (opt.endDate && compare_day(day,opt.endDate) > 0) valid = false; - days.push({type:'lastMonth',day: day.getDate(),time:day.getTime(), valid:valid }); - } - } - var toMonth = d.getMonth(); - for(var i=0; i<40; i++) - { - var today = moment(d).add(i,'days').toDate(); - var valid = true; - if (opt.startDate && compare_day(today,opt.startDate) < 0) valid = false; - if (opt.endDate && compare_day(today,opt.endDate) > 0) valid = false; - days.push({type: today.getMonth() == toMonth ? 'toMonth' : 'nextMonth',day: today.getDate(),time:today.getTime(), valid:valid }); - } - var html = []; - for(var week=0; week<6; week++) - { - if (days[week*7].type == 'nextMonth') break; - html.push(''); - for(var day = 0; day<7; day++) - { - var _day = (opt.startOfWeek == 'monday') ? day+1 : day; - var today = days[week*7+_day]; - var highlightToday = moment(today.time).format('L') == moment(now).format('L'); - today.extraClass = ''; - today.tooltip = ''; - if(opt.beforeShowDay && typeof opt.beforeShowDay == 'function') - { - var _r = opt.beforeShowDay(moment(today.time).toDate()); - today.valid = _r[0]; - today.extraClass = _r[1] || ''; - today.tooltip = _r[2] || ''; - if (today.tooltip != '') today.extraClass += ' has-tooltip '; - } - html.push('
'+today.day+'
'); - } - html.push(''); - } - return html.join(''); - } - - function getLanguages() - { - if (opt.language == 'auto') - { - var language = navigator.language ? navigator.language : navigator.browserLanguage; - if (!language) return $.dateRangePickerLanguages['en']; - var language = language.toLowerCase(); - for(var key in $.dateRangePickerLanguages) - { - if (language.indexOf(key) != -1) - { - return $.dateRangePickerLanguages[key]; - } - } - return $.dateRangePickerLanguages['en']; - } - else if ( opt.language && opt.language in $.dateRangePickerLanguages) - { - return $.dateRangePickerLanguages[opt.language]; - } - else - { - return $.dateRangePickerLanguages['en']; - } - } - - function lang(t) - { - return (t in langs)? langs[t] : t; - } - - - }; -})(jQuery); diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/moment.min.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/moment.min.js deleted file mode 100644 index d0b48f73..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/moment.min.js +++ /dev/null @@ -1,7 +0,0 @@ -//! moment.js -//! version : 2.10.2 -//! authors : Tim Wood, Iskren Chernev, Moment.js contributors -//! license : MIT -//! momentjs.com -!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return Ac.apply(null,arguments)}function b(a){Ac=a}function c(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function d(a){return"[object Array]"===Object.prototype.toString.call(a)}function e(a){return"[object Date]"===Object.prototype.toString.call(a)||a instanceof Date}function f(a,b){var c,d=[];for(c=0;c0)for(c in Cc)d=Cc[c],e=b[d],"undefined"!=typeof e&&(a[d]=e);return a}function m(b){l(this,b),this._d=new Date(+b._d),Dc===!1&&(Dc=!0,a.updateOffset(this),Dc=!1)}function n(a){return a instanceof m||null!=a&&g(a,"_isAMomentObject")}function o(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=b>=0?Math.floor(b):Math.ceil(b)),c}function p(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&o(a[d])!==o(b[d]))&&g++;return g+f}function q(){}function r(a){return a?a.toLowerCase().replace("_","-"):a}function s(a){for(var b,c,d,e,f=0;f0;){if(d=t(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&p(e,c,!0)>=b-1)break;b--}f++}return null}function t(a){var b=null;if(!Ec[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=Bc._abbr,require("./locale/"+a),u(b)}catch(c){}return Ec[a]}function u(a,b){var c;return a&&(c="undefined"==typeof b?w(a):v(a,b),c&&(Bc=c)),Bc._abbr}function v(a,b){return null!==b?(b.abbr=a,Ec[a]||(Ec[a]=new q),Ec[a].set(b),u(a),Ec[a]):(delete Ec[a],null)}function w(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return Bc;if(!d(a)){if(b=t(a))return b;a=[a]}return s(a)}function x(a,b){var c=a.toLowerCase();Fc[c]=Fc[c+"s"]=Fc[b]=a}function y(a){return"string"==typeof a?Fc[a]||Fc[a.toLowerCase()]:void 0}function z(a){var b,c,d={};for(c in a)g(a,c)&&(b=y(c),b&&(d[b]=a[c]));return d}function A(b,c){return function(d){return null!=d?(C(this,b,d),a.updateOffset(this,c),this):B(this,b)}}function B(a,b){return a._d["get"+(a._isUTC?"UTC":"")+b]()}function C(a,b,c){return a._d["set"+(a._isUTC?"UTC":"")+b](c)}function D(a,b){var c;if("object"==typeof a)for(c in a)this.set(c,a[c]);else if(a=y(a),"function"==typeof this[a])return this[a](b);return this}function E(a,b,c){for(var d=""+Math.abs(a),e=a>=0;d.lengthb;b++)d[b]=Jc[d[b]]?Jc[d[b]]:G(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function I(a,b){return a.isValid()?(b=J(b,a.localeData()),Ic[b]||(Ic[b]=H(b)),Ic[b](a)):a.localeData().invalidDate()}function J(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Hc.lastIndex=0;d>=0&&Hc.test(a);)a=a.replace(Hc,c),Hc.lastIndex=0,d-=1;return a}function K(a,b,c){Yc[a]="function"==typeof b?b:function(a){return a&&c?c:b}}function L(a,b){return g(Yc,a)?Yc[a](b._strict,b._locale):new RegExp(M(a))}function M(a){return a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}).replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function N(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),"number"==typeof b&&(d=function(a,c){c[b]=o(a)}),c=0;cd;d++){if(e=i([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}}function U(a,b){var c;return"string"==typeof b&&(b=a.localeData().monthsParse(b),"number"!=typeof b)?a:(c=Math.min(a.date(),Q(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a)}function V(b){return null!=b?(U(this,b),a.updateOffset(this,!0),this):B(this,"Month")}function W(){return Q(this.year(),this.month())}function X(a){var b,c=a._a;return c&&-2===a._pf.overflow&&(b=c[_c]<0||c[_c]>11?_c:c[ad]<1||c[ad]>Q(c[$c],c[_c])?ad:c[bd]<0||c[bd]>24||24===c[bd]&&(0!==c[cd]||0!==c[dd]||0!==c[ed])?bd:c[cd]<0||c[cd]>59?cd:c[dd]<0||c[dd]>59?dd:c[ed]<0||c[ed]>999?ed:-1,a._pf._overflowDayOfYear&&($c>b||b>ad)&&(b=ad),a._pf.overflow=b),a}function Y(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function Z(a,b){var c=!0;return h(function(){return c&&(Y(a),c=!1),b.apply(this,arguments)},b)}function $(a,b){hd[a]||(Y(b),hd[a]=!0)}function _(a){var b,c,d=a._i,e=id.exec(d);if(e){for(a._pf.iso=!0,b=0,c=jd.length;c>b;b++)if(jd[b][1].exec(d)){a._f=jd[b][0]+(e[6]||" ");break}for(b=0,c=kd.length;c>b;b++)if(kd[b][1].exec(d)){a._f+=kd[b][0];break}d.match(Vc)&&(a._f+="Z"),sa(a)}else a._isValid=!1}function aa(b){var c=ld.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(_(b),void(b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b))))}function ba(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 1970>a&&h.setFullYear(a),h}function ca(a){var b=new Date(Date.UTC.apply(null,arguments));return 1970>a&&b.setUTCFullYear(a),b}function da(a){return ea(a)?366:365}function ea(a){return a%4===0&&a%100!==0||a%400===0}function fa(){return ea(this.year())}function ga(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=za(a).add(f,"d"),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function ha(a){return ga(a,this._week.dow,this._week.doy).week}function ia(){return this._week.dow}function ja(){return this._week.doy}function ka(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function la(a){var b=ga(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function ma(a,b,c,d,e){var f,g,h=ca(a,0,1).getUTCDay();return h=0===h?7:h,c=null!=c?c:e,f=e-h+(h>d?7:0)-(e>h?7:0),g=7*(b-1)+(c-e)+f+1,{year:g>0?a:a-1,dayOfYear:g>0?g:da(a-1)+g}}function na(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function oa(a,b,c){return null!=a?a:null!=b?b:c}function pa(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function qa(a){var b,c,d,e,f=[];if(!a._d){for(d=pa(a),a._w&&null==a._a[ad]&&null==a._a[_c]&&ra(a),a._dayOfYear&&(e=oa(a._a[$c],d[$c]),a._dayOfYear>da(e)&&(a._pf._overflowDayOfYear=!0),c=ca(e,0,a._dayOfYear),a._a[_c]=c.getUTCMonth(),a._a[ad]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;7>b;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[bd]&&0===a._a[cd]&&0===a._a[dd]&&0===a._a[ed]&&(a._nextDay=!0,a._a[bd]=0),a._d=(a._useUTC?ca:ba).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[bd]=24)}}function ra(a){var b,c,d,e,f,g,h;b=a._w,null!=b.GG||null!=b.W||null!=b.E?(f=1,g=4,c=oa(b.GG,a._a[$c],ga(za(),1,4).year),d=oa(b.W,1),e=oa(b.E,1)):(f=a._locale._week.dow,g=a._locale._week.doy,c=oa(b.gg,a._a[$c],ga(za(),f,g).year),d=oa(b.w,1),null!=b.d?(e=b.d,f>e&&++d):e=null!=b.e?b.e+f:f),h=ma(c,d,e,g,f),a._a[$c]=h.year,a._dayOfYear=h.dayOfYear}function sa(b){if(b._f===a.ISO_8601)return void _(b);b._a=[],b._pf.empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,j=0;for(e=J(b._f,b._locale).match(Gc)||[],c=0;c0&&b._pf.unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),j+=d.length),Jc[f]?(d?b._pf.empty=!1:b._pf.unusedTokens.push(f),P(f,d,b)):b._strict&&!d&&b._pf.unusedTokens.push(f);b._pf.charsLeftOver=i-j,h.length>0&&b._pf.unusedInput.push(h),b._pf.bigHour===!0&&b._a[bd]<=12&&(b._pf.bigHour=void 0),b._a[bd]=ta(b._locale,b._a[bd],b._meridiem),qa(b),X(b)}function ta(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function ua(a){var b,d,e,f,g;if(0===a._f.length)return a._pf.invalidFormat=!0,void(a._d=new Date(0/0));for(f=0;fg)&&(e=g,d=b));h(a,d||b)}function va(a){if(!a._d){var b=z(a._i);a._a=[b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],qa(a)}}function wa(a){var b,c=a._i,e=a._f;return a._locale=a._locale||w(a._l),null===c||void 0===e&&""===c?k({nullInput:!0}):("string"==typeof c&&(a._i=c=a._locale.preparse(c)),n(c)?new m(X(c)):(d(e)?ua(a):e?sa(a):xa(a),b=new m(X(a)),b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b))}function xa(b){var c=b._i;void 0===c?b._d=new Date:e(c)?b._d=new Date(+c):"string"==typeof c?aa(b):d(c)?(b._a=f(c.slice(0),function(a){return parseInt(a,10)}),qa(b)):"object"==typeof c?va(b):"number"==typeof c?b._d=new Date(c):a.createFromInputFallback(b)}function ya(a,b,d,e,f){var g={};return"boolean"==typeof d&&(e=d,d=void 0),g._isAMomentObject=!0,g._useUTC=g._isUTC=f,g._l=d,g._i=a,g._f=b,g._strict=e,g._pf=c(),wa(g)}function za(a,b,c,d){return ya(a,b,c,d,!1)}function Aa(a,b){var c,e;if(1===b.length&&d(b[0])&&(b=b[0]),!b.length)return za();for(c=b[0],e=1;ea&&(a=-a,c="-"),c+E(~~(a/60),2)+b+E(~~a%60,2)})}function Ga(a){var b=(a||"").match(Vc)||[],c=b[b.length-1]||[],d=(c+"").match(qd)||["-",0,0],e=+(60*d[1])+o(d[2]);return"+"===d[0]?e:-e}function Ha(b,c){var d,f;return c._isUTC?(d=c.clone(),f=(n(b)||e(b)?+b:+za(b))-+d,d._d.setTime(+d._d+f),a.updateOffset(d,!1),d):za(b).local();return c._isUTC?za(b).zone(c._offset||0):za(b).local()}function Ia(a){return 15*-Math.round(a._d.getTimezoneOffset()/15)}function Ja(b,c){var d,e=this._offset||0;return null!=b?("string"==typeof b&&(b=Ga(b)),Math.abs(b)<16&&(b=60*b),!this._isUTC&&c&&(d=Ia(this)),this._offset=b,this._isUTC=!0,null!=d&&this.add(d,"m"),e!==b&&(!c||this._changeInProgress?Za(this,Ua(b-e,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?e:Ia(this)}function Ka(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function La(a){return this.utcOffset(0,a)}function Ma(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Ia(this),"m")),this}function Na(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(Ga(this._i)),this}function Oa(a){return a=a?za(a).utcOffset():0,(this.utcOffset()-a)%60===0}function Pa(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Qa(){if(this._a){var a=this._isUTC?i(this._a):za(this._a);return this.isValid()&&p(this._a,a.toArray())>0}return!1}function Ra(){return!this._isUTC}function Sa(){return this._isUTC}function Ta(){return this._isUTC&&0===this._offset}function Ua(a,b){var c,d,e,f=a,h=null;return Ea(a)?f={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(f={},b?f[b]=a:f.milliseconds=a):(h=rd.exec(a))?(c="-"===h[1]?-1:1,f={y:0,d:o(h[ad])*c,h:o(h[bd])*c,m:o(h[cd])*c,s:o(h[dd])*c,ms:o(h[ed])*c}):(h=sd.exec(a))?(c="-"===h[1]?-1:1,f={y:Va(h[2],c),M:Va(h[3],c),d:Va(h[4],c),h:Va(h[5],c),m:Va(h[6],c),s:Va(h[7],c),w:Va(h[8],c)}):null==f?f={}:"object"==typeof f&&("from"in f||"to"in f)&&(e=Xa(za(f.from),za(f.to)),f={},f.ms=e.milliseconds,f.M=e.months),d=new Da(f),Ea(a)&&g(a,"_locale")&&(d._locale=a._locale),d}function Va(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function Wa(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function Xa(a,b){var c;return b=Ha(b,a),a.isBefore(b)?c=Wa(a,b):(c=Wa(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c}function Ya(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||($(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period)."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=Ua(c,d),Za(this,e,a),this}}function Za(b,c,d,e){var f=c._milliseconds,g=c._days,h=c._months;e=null==e?!0:e,f&&b._d.setTime(+b._d+f*d),g&&C(b,"Date",B(b,"Date")+g*d),h&&U(b,B(b,"Month")+h*d),e&&a.updateOffset(b,g||h)}function $a(a){var b=a||za(),c=Ha(b,this).startOf("day"),d=this.diff(c,"days",!0),e=-6>d?"sameElse":-1>d?"lastWeek":0>d?"lastDay":1>d?"sameDay":2>d?"nextDay":7>d?"nextWeek":"sameElse";return this.format(this.localeData().calendar(e,this,za(b)))}function _a(){return new m(this)}function ab(a,b){var c;return b=y("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=n(a)?a:za(a),+this>+a):(c=n(a)?+a:+za(a),c<+this.clone().startOf(b))}function bb(a,b){var c;return b=y("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=n(a)?a:za(a),+a>+this):(c=n(a)?+a:+za(a),+this.clone().endOf(b)a?Math.ceil(a):Math.floor(a)}function fb(a,b,c){var d,e,f=Ha(a,this),g=6e4*(f.utcOffset()-this.utcOffset());return b=y(b),"year"===b||"month"===b||"quarter"===b?(e=gb(this,f),"quarter"===b?e/=3:"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:eb(e)}function gb(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return 0>b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)}function hb(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function ib(){var a=this.clone().utc();return 0b;b++)if(this._weekdaysParse[b]||(c=za([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b}function Jb(a){var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=Eb(a,this.localeData()),this.add(a-b,"d")):b}function Kb(a){var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function Lb(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)}function Mb(a,b){F(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function Nb(a,b){return b._meridiemParse}function Ob(a){return"p"===(a+"").toLowerCase().charAt(0)}function Pb(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function Qb(a){F(0,[a,3],0,"millisecond")}function Rb(){return this._isUTC?"UTC":""}function Sb(){return this._isUTC?"Coordinated Universal Time":""}function Tb(a){return za(1e3*a)}function Ub(){return za.apply(null,arguments).parseZone()}function Vb(a,b,c){var d=this._calendar[a];return"function"==typeof d?d.call(b,c):d}function Wb(a){var b=this._longDateFormat[a];return!b&&this._longDateFormat[a.toUpperCase()]&&(b=this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a]=b),b}function Xb(){return this._invalidDate}function Yb(a){return this._ordinal.replace("%d",a)}function Zb(a){return a}function $b(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)}function _b(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)}function ac(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b;this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function bc(a,b,c,d){var e=w(),f=i().set(d,b);return e[c](f,a)}function cc(a,b,c,d,e){if("number"==typeof a&&(b=a,a=void 0),a=a||"",null!=b)return bc(a,b,c,e);var f,g=[];for(f=0;d>f;f++)g[f]=bc(a,f,c,e);return g}function dc(a,b){return cc(a,b,"months",12,"month")}function ec(a,b){return cc(a,b,"monthsShort",12,"month")}function fc(a,b){return cc(a,b,"weekdays",7,"day")}function gc(a,b){return cc(a,b,"weekdaysShort",7,"day")}function hc(a,b){return cc(a,b,"weekdaysMin",7,"day")}function ic(){var a=this._data;return this._milliseconds=Od(this._milliseconds),this._days=Od(this._days),this._months=Od(this._months),a.milliseconds=Od(a.milliseconds),a.seconds=Od(a.seconds),a.minutes=Od(a.minutes),a.hours=Od(a.hours),a.months=Od(a.months),a.years=Od(a.years),this}function jc(a,b,c,d){var e=Ua(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function kc(a,b){return jc(this,a,b,1)}function lc(a,b){return jc(this,a,b,-1)}function mc(){var a,b,c,d=this._milliseconds,e=this._days,f=this._months,g=this._data,h=0;return g.milliseconds=d%1e3,a=eb(d/1e3),g.seconds=a%60,b=eb(a/60),g.minutes=b%60,c=eb(b/60),g.hours=c%24,e+=eb(c/24),h=eb(nc(e)),e-=eb(oc(h)),f+=eb(e/30),e%=30,h+=eb(f/12),f%=12,g.days=e,g.months=f,g.years=h,this}function nc(a){return 400*a/146097}function oc(a){return 146097*a/400}function pc(a){var b,c,d=this._milliseconds;if(a=y(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+12*nc(b),"month"===a?c:c/12;switch(b=this._days+Math.round(oc(this._months/12)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 24*b*60+d/6e4;case"second":return 24*b*60*60+d/1e3;case"millisecond":return Math.floor(24*b*60*60*1e3)+d;default:throw new Error("Unknown unit "+a)}}function qc(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*o(this._months/12)}function rc(a){return function(){return this.as(a)}}function sc(a){return a=y(a),this[a+"s"]()}function tc(a){return function(){return this._data[a]}}function uc(){return eb(this.days()/7)}function vc(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function wc(a,b,c){var d=Ua(a).abs(),e=ce(d.as("s")),f=ce(d.as("m")),g=ce(d.as("h")),h=ce(d.as("d")),i=ce(d.as("M")),j=ce(d.as("y")),k=e0,k[4]=c,vc.apply(null,k)}function xc(a,b){return void 0===de[a]?!1:void 0===b?de[a]:(de[a]=b,!0)}function yc(a){var b=this.localeData(),c=wc(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function zc(){var a=ee(this.years()),b=ee(this.months()),c=ee(this.days()),d=ee(this.hours()),e=ee(this.minutes()),f=ee(this.seconds()+this.milliseconds()/1e3),g=this.asSeconds();return g?(0>g?"-":"")+"P"+(a?a+"Y":"")+(b?b+"M":"")+(c?c+"D":"")+(d||e||f?"T":"")+(d?d+"H":"")+(e?e+"M":"")+(f?f+"S":""):"P0D"}var Ac,Bc,Cc=a.momentProperties=[],Dc=!1,Ec={},Fc={},Gc=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g,Hc=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Ic={},Jc={},Kc=/\d/,Lc=/\d\d/,Mc=/\d{3}/,Nc=/\d{4}/,Oc=/[+-]?\d{6}/,Pc=/\d\d?/,Qc=/\d{1,3}/,Rc=/\d{1,4}/,Sc=/[+-]?\d{1,6}/,Tc=/\d+/,Uc=/[+-]?\d+/,Vc=/Z|[+-]\d\d:?\d\d/gi,Wc=/[+-]?\d+(\.\d{1,3})?/,Xc=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Yc={},Zc={},$c=0,_c=1,ad=2,bd=3,cd=4,dd=5,ed=6;F("M",["MM",2],"Mo",function(){return this.month()+1}),F("MMM",0,0,function(a){return this.localeData().monthsShort(this,a)}),F("MMMM",0,0,function(a){return this.localeData().months(this,a)}),x("month","M"),K("M",Pc),K("MM",Pc,Lc),K("MMM",Xc),K("MMMM",Xc),N(["M","MM"],function(a,b){b[_c]=o(a)-1}),N(["MMM","MMMM"],function(a,b,c,d){var e=c._locale.monthsParse(a,d,c._strict);null!=e?b[_c]=e:c._pf.invalidMonth=a});var fd="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),gd="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),hd={};a.suppressDeprecationWarnings=!1;var id=/^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,jd=[["YYYYYY-MM-DD",/[+-]\d{6}-\d{2}-\d{2}/],["YYYY-MM-DD",/\d{4}-\d{2}-\d{2}/],["GGGG-[W]WW-E",/\d{4}-W\d{2}-\d/],["GGGG-[W]WW",/\d{4}-W\d{2}/],["YYYY-DDD",/\d{4}-\d{3}/]],kd=[["HH:mm:ss.SSSS",/(T| )\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],ld=/^\/?Date\((\-?\d+)/i;a.createFromInputFallback=Z("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),F(0,["YY",2],0,function(){return this.year()%100}),F(0,["YYYY",4],0,"year"),F(0,["YYYYY",5],0,"year"),F(0,["YYYYYY",6,!0],0,"year"),x("year","y"),K("Y",Uc),K("YY",Pc,Lc),K("YYYY",Rc,Nc),K("YYYYY",Sc,Oc),K("YYYYYY",Sc,Oc),N(["YYYY","YYYYY","YYYYYY"],$c),N("YY",function(b,c){c[$c]=a.parseTwoDigitYear(b)}),a.parseTwoDigitYear=function(a){return o(a)+(o(a)>68?1900:2e3)};var md=A("FullYear",!1);F("w",["ww",2],"wo","week"),F("W",["WW",2],"Wo","isoWeek"),x("week","w"),x("isoWeek","W"),K("w",Pc),K("ww",Pc,Lc),K("W",Pc),K("WW",Pc,Lc),O(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=o(a)});var nd={dow:0,doy:6};F("DDD",["DDDD",3],"DDDo","dayOfYear"),x("dayOfYear","DDD"),K("DDD",Qc),K("DDDD",Mc),N(["DDD","DDDD"],function(a,b,c){c._dayOfYear=o(a)}),a.ISO_8601=function(){};var od=Z("moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(){var a=za.apply(null,arguments);return this>a?this:a}),pd=Z("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(){var a=za.apply(null,arguments);return a>this?this:a});Fa("Z",":"),Fa("ZZ",""),K("Z",Vc),K("ZZ",Vc),N(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=Ga(a)});var qd=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var rd=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,sd=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;Ua.fn=Da.prototype;var td=Ya(1,"add"),ud=Ya(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ";var vd=Z("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});F(0,["gg",2],0,function(){return this.weekYear()%100}),F(0,["GG",2],0,function(){return this.isoWeekYear()%100}),xb("gggg","weekYear"),xb("ggggg","weekYear"),xb("GGGG","isoWeekYear"),xb("GGGGG","isoWeekYear"),x("weekYear","gg"),x("isoWeekYear","GG"),K("G",Uc),K("g",Uc),K("GG",Pc,Lc),K("gg",Pc,Lc),K("GGGG",Rc,Nc),K("gggg",Rc,Nc),K("GGGGG",Sc,Oc),K("ggggg",Sc,Oc),O(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=o(a)}),O(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),F("Q",0,0,"quarter"),x("quarter","Q"),K("Q",Kc),N("Q",function(a,b){b[_c]=3*(o(a)-1)}),F("D",["DD",2],"Do","date"),x("date","D"),K("D",Pc),K("DD",Pc,Lc),K("Do",function(a,b){return a?b._ordinalParse:b._ordinalParseLenient}),N(["D","DD"],ad),N("Do",function(a,b){b[ad]=o(a.match(Pc)[0],10)});var wd=A("Date",!0);F("d",0,"do","day"),F("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),F("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),F("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),F("e",0,0,"weekday"),F("E",0,0,"isoWeekday"),x("day","d"),x("weekday","e"),x("isoWeekday","E"),K("d",Pc),K("e",Pc),K("E",Pc),K("dd",Xc),K("ddd",Xc),K("dddd",Xc),O(["dd","ddd","dddd"],function(a,b,c){var d=c._locale.weekdaysParse(a);null!=d?b.d=d:c._pf.invalidWeekday=a}),O(["d","e","E"],function(a,b,c,d){b[d]=o(a)});var xd="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),yd="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),zd="Su_Mo_Tu_We_Th_Fr_Sa".split("_");F("H",["HH",2],0,"hour"),F("h",["hh",2],0,function(){return this.hours()%12||12}),Mb("a",!0),Mb("A",!1),x("hour","h"),K("a",Nb),K("A",Nb),K("H",Pc),K("h",Pc),K("HH",Pc,Lc),K("hh",Pc,Lc),N(["H","HH"],bd),N(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),N(["h","hh"],function(a,b,c){b[bd]=o(a),c._pf.bigHour=!0});var Ad=/[ap]\.?m?\.?/i,Bd=A("Hours",!0);F("m",["mm",2],0,"minute"),x("minute","m"),K("m",Pc),K("mm",Pc,Lc),N(["m","mm"],cd);var Cd=A("Minutes",!1);F("s",["ss",2],0,"second"),x("second","s"),K("s",Pc),K("ss",Pc,Lc),N(["s","ss"],dd);var Dd=A("Seconds",!1);F("S",0,0,function(){return~~(this.millisecond()/100)}),F(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),Qb("SSS"),Qb("SSSS"),x("millisecond","ms"),K("S",Qc,Kc),K("SS",Qc,Lc),K("SSS",Qc,Mc),K("SSSS",Tc),N(["S","SS","SSS","SSSS"],function(a,b){b[ed]=o(1e3*("0."+a))});var Ed=A("Milliseconds",!1);F("z",0,0,"zoneAbbr"),F("zz",0,0,"zoneName");var Fd=m.prototype;Fd.add=td,Fd.calendar=$a,Fd.clone=_a,Fd.diff=fb,Fd.endOf=pb,Fd.format=jb,Fd.from=kb,Fd.fromNow=lb,Fd.get=D,Fd.invalidAt=wb,Fd.isAfter=ab,Fd.isBefore=bb,Fd.isBetween=cb,Fd.isSame=db,Fd.isValid=ub,Fd.lang=vd,Fd.locale=mb,Fd.localeData=nb,Fd.max=pd,Fd.min=od,Fd.parsingFlags=vb,Fd.set=D,Fd.startOf=ob,Fd.subtract=ud,Fd.toArray=tb,Fd.toDate=sb,Fd.toISOString=ib,Fd.toJSON=ib,Fd.toString=hb,Fd.unix=rb,Fd.valueOf=qb,Fd.year=md,Fd.isLeapYear=fa,Fd.weekYear=zb,Fd.isoWeekYear=Ab,Fd.quarter=Fd.quarters=Db,Fd.month=V,Fd.daysInMonth=W,Fd.week=Fd.weeks=ka,Fd.isoWeek=Fd.isoWeeks=la,Fd.weeksInYear=Cb,Fd.isoWeeksInYear=Bb,Fd.date=wd,Fd.day=Fd.days=Jb,Fd.weekday=Kb,Fd.isoWeekday=Lb,Fd.dayOfYear=na,Fd.hour=Fd.hours=Bd,Fd.minute=Fd.minutes=Cd,Fd.second=Fd.seconds=Dd,Fd.millisecond=Fd.milliseconds=Ed,Fd.utcOffset=Ja,Fd.utc=La,Fd.local=Ma,Fd.parseZone=Na,Fd.hasAlignedHourOffset=Oa,Fd.isDST=Pa,Fd.isDSTShifted=Qa,Fd.isLocal=Ra,Fd.isUtcOffset=Sa,Fd.isUtc=Ta,Fd.isUTC=Ta,Fd.zoneAbbr=Rb,Fd.zoneName=Sb,Fd.dates=Z("dates accessor is deprecated. Use date instead.",wd),Fd.months=Z("months accessor is deprecated. Use month instead",V),Fd.years=Z("years accessor is deprecated. Use year instead",md),Fd.zone=Z("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",Ka);var Gd=Fd,Hd={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Id={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY LT",LLLL:"dddd, MMMM D, YYYY LT"},Jd="Invalid date",Kd="%d",Ld=/\d{1,2}/,Md={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},Nd=q.prototype;Nd._calendar=Hd,Nd.calendar=Vb,Nd._longDateFormat=Id,Nd.longDateFormat=Wb,Nd._invalidDate=Jd,Nd.invalidDate=Xb,Nd._ordinal=Kd,Nd.ordinal=Yb,Nd._ordinalParse=Ld, -Nd.preparse=Zb,Nd.postformat=Zb,Nd._relativeTime=Md,Nd.relativeTime=$b,Nd.pastFuture=_b,Nd.set=ac,Nd.months=R,Nd._months=fd,Nd.monthsShort=S,Nd._monthsShort=gd,Nd.monthsParse=T,Nd.week=ha,Nd._week=nd,Nd.firstDayOfYear=ja,Nd.firstDayOfWeek=ia,Nd.weekdays=Fb,Nd._weekdays=xd,Nd.weekdaysMin=Hb,Nd._weekdaysMin=zd,Nd.weekdaysShort=Gb,Nd._weekdaysShort=yd,Nd.weekdaysParse=Ib,Nd.isPM=Ob,Nd._meridiemParse=Ad,Nd.meridiem=Pb,u("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===o(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=Z("moment.lang is deprecated. Use moment.locale instead.",u),a.langData=Z("moment.langData is deprecated. Use moment.localeData instead.",w);var Od=Math.abs,Pd=rc("ms"),Qd=rc("s"),Rd=rc("m"),Sd=rc("h"),Td=rc("d"),Ud=rc("w"),Vd=rc("M"),Wd=rc("y"),Xd=tc("milliseconds"),Yd=tc("seconds"),Zd=tc("minutes"),$d=tc("hours"),_d=tc("days"),ae=tc("months"),be=tc("years"),ce=Math.round,de={s:45,m:45,h:22,d:26,M:11},ee=Math.abs,fe=Da.prototype;fe.abs=ic,fe.add=kc,fe.subtract=lc,fe.as=pc,fe.asMilliseconds=Pd,fe.asSeconds=Qd,fe.asMinutes=Rd,fe.asHours=Sd,fe.asDays=Td,fe.asWeeks=Ud,fe.asMonths=Vd,fe.asYears=Wd,fe.valueOf=qc,fe._bubble=mc,fe.get=sc,fe.milliseconds=Xd,fe.seconds=Yd,fe.minutes=Zd,fe.hours=$d,fe.days=_d,fe.weeks=uc,fe.months=ae,fe.years=be,fe.humanize=yc,fe.toISOString=zc,fe.toString=zc,fe.toJSON=zc,fe.locale=mb,fe.localeData=nb,fe.toIsoString=Z("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",zc),fe.lang=vd,F("X",0,0,"unix"),F("x",0,0,"valueOf"),K("x",Uc),K("X",Wc),N("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),N("x",function(a,b,c){c._d=new Date(o(a))}),a.version="2.10.2",b(za),a.fn=Gd,a.min=Ba,a.max=Ca,a.utc=i,a.unix=Tb,a.months=dc,a.isDate=e,a.locale=u,a.invalid=k,a.duration=Ua,a.isMoment=n,a.weekdays=fc,a.parseZone=Ub,a.localeData=w,a.isDuration=Ea,a.monthsShort=ec,a.weekdaysMin=hc,a.defineLocale=v,a.weekdaysShort=gc,a.normalizeUnits=y,a.relativeTimeThreshold=xc;var ge=a;return ge}); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/nv.d3.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/nv.d3.js deleted file mode 100644 index 949a04d5..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/nv.d3.js +++ /dev/null @@ -1,13435 +0,0 @@ -/* nvd3 version 1.8.1 (https://github.com/novus/nvd3) 2015-06-17 */ -(function(){ - -// set up main nv object - var nv = {}; - -// the major global objects under the nv namespace - nv.dev = false; //set false when in production - nv.tooltip = nv.tooltip || {}; // For the tooltip system - nv.utils = nv.utils || {}; // Utility subsystem - nv.models = nv.models || {}; //stores all the possible models/components - nv.charts = {}; //stores all the ready to use charts - nv.logs = {}; //stores some statistics and potential error messages - nv.dom = {}; //DOM manipulation functions - - nv.dispatch = d3.dispatch('render_start', 'render_end'); - -// Function bind polyfill -// Needed ONLY for phantomJS as it's missing until version 2.0 which is unreleased as of this comment -// https://github.com/ariya/phantomjs/issues/10522 -// http://kangax.github.io/compat-table/es5/#Function.prototype.bind -// phantomJS is used for running the test suite - if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== "function") { - // closest thing possible to the ECMAScript 5 internal IsCallable function - throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); - } - - var aArgs = Array.prototype.slice.call(arguments, 1), - fToBind = this, - fNOP = function () {}, - fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis - ? this - : oThis, - aArgs.concat(Array.prototype.slice.call(arguments))); - }; - - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - return fBound; - }; - } - -// Development render timers - disabled if dev = false - if (nv.dev) { - nv.dispatch.on('render_start', function(e) { - nv.logs.startTime = +new Date(); - }); - - nv.dispatch.on('render_end', function(e) { - nv.logs.endTime = +new Date(); - nv.logs.totalTime = nv.logs.endTime - nv.logs.startTime; - nv.log('total', nv.logs.totalTime); // used for development, to keep track of graph generation times - }); - } - -// Logs all arguments, and returns the last so you can test things in place -// Note: in IE8 console.log is an object not a function, and if modernizr is used -// then calling Function.prototype.bind with with anything other than a function -// causes a TypeError to be thrown. - nv.log = function() { - if (nv.dev && window.console && console.log && console.log.apply) - console.log.apply(console, arguments); - else if (nv.dev && window.console && typeof console.log == "function" && Function.prototype.bind) { - var log = Function.prototype.bind.call(console.log, console); - log.apply(console, arguments); - } - return arguments[arguments.length - 1]; - }; - -// print console warning, should be used by deprecated functions - nv.deprecated = function(name, info) { - if (console && console.warn) { - console.warn('nvd3 warning: `' + name + '` has been deprecated. ', info || ''); - } - }; - -// The nv.render function is used to queue up chart rendering -// in non-blocking async functions. -// When all queued charts are done rendering, nv.dispatch.render_end is invoked. - nv.render = function render(step) { - // number of graphs to generate in each timeout loop - step = step || 1; - - nv.render.active = true; - nv.dispatch.render_start(); - - var renderLoop = function() { - var chart, graph; - - for (var i = 0; i < step && (graph = nv.render.queue[i]); i++) { - chart = graph.generate(); - if (typeof graph.callback == typeof(Function)) graph.callback(chart); - } - - nv.render.queue.splice(0, i); - - if (nv.render.queue.length) { - setTimeout(renderLoop); - } - else { - nv.dispatch.render_end(); - nv.render.active = false; - } - }; - - setTimeout(renderLoop); - }; - - nv.render.active = false; - nv.render.queue = []; - - /* - Adds a chart to the async rendering queue. This method can take arguments in two forms: - nv.addGraph({ - generate: - callback: - }) - - or - - nv.addGraph(, ) - - The generate function should contain code that creates the NVD3 model, sets options - on it, adds data to an SVG element, and invokes the chart model. The generate function - should return the chart model. See examples/lineChart.html for a usage example. - - The callback function is optional, and it is called when the generate function completes. - */ - nv.addGraph = function(obj) { - if (typeof arguments[0] === typeof(Function)) { - obj = {generate: arguments[0], callback: arguments[1]}; - } - - nv.render.queue.push(obj); - - if (!nv.render.active) { - nv.render(); - } - }; - -// Node/CommonJS exports - if (typeof(module) !== 'undefined' && typeof(exports) !== 'undefined') { - module.exports = nv; - } - - if (typeof(window) !== 'undefined') { - window.nv = nv; - } - /* Facade for queueing DOM write operations - * with Fastdom (https://github.com/wilsonpage/fastdom) - * if available. - * This could easily be extended to support alternate - * implementations in the future. - */ - nv.dom.write = function(callback) { - if (window.fastdom !== undefined) { - return fastdom.write(callback); - } - return callback(); - }; - - /* Facade for queueing DOM read operations - * with Fastdom (https://github.com/wilsonpage/fastdom) - * if available. - * This could easily be extended to support alternate - * implementations in the future. - */ - nv.dom.read = function(callback) { - if (window.fastdom !== undefined) { - return fastdom.read(callback); - } - return callback(); - };/* Utility class to handle creation of an interactive layer. - This places a rectangle on top of the chart. When you mouse move over it, it sends a dispatch - containing the X-coordinate. It can also render a vertical line where the mouse is located. - - dispatch.elementMousemove is the important event to latch onto. It is fired whenever the mouse moves over - the rectangle. The dispatch is given one object which contains the mouseX/Y location. - It also has 'pointXValue', which is the conversion of mouseX to the x-axis scale. - */ - nv.interactiveGuideline = function() { - "use strict"; - - var tooltip = nv.models.tooltip(); - tooltip.duration(0).hideDelay(0)._isInteractiveLayer(true).hidden(false); - - //Public settings - var width = null; - var height = null; - - //Please pass in the bounding chart's top and left margins - //This is important for calculating the correct mouseX/Y positions. - var margin = {left: 0, top: 0} - , xScale = d3.scale.linear() - , dispatch = d3.dispatch('elementMousemove', 'elementMouseout', 'elementClick', 'elementDblclick') - , showGuideLine = true; - //Must pass in the bounding chart's container. - //The mousemove event is attached to this container. - var svgContainer = null; - - // check if IE by looking for activeX - var isMSIE = "ActiveXObject" in window; - - - function layer(selection) { - selection.each(function(data) { - var container = d3.select(this); - var availableWidth = (width || 960), availableHeight = (height || 400); - var wrap = container.selectAll("g.nv-wrap.nv-interactiveLineLayer") - .data([data]); - var wrapEnter = wrap.enter() - .append("g").attr("class", " nv-wrap nv-interactiveLineLayer"); - wrapEnter.append("g").attr("class","nv-interactiveGuideLine"); - - if (!svgContainer) { - return; - } - - function mouseHandler() { - var d3mouse = d3.mouse(this); - var mouseX = d3mouse[0]; - var mouseY = d3mouse[1]; - var subtractMargin = true; - var mouseOutAnyReason = false; - if (isMSIE) { - /* - D3.js (or maybe SVG.getScreenCTM) has a nasty bug in Internet Explorer 10. - d3.mouse() returns incorrect X,Y mouse coordinates when mouse moving - over a rect in IE 10. - However, d3.event.offsetX/Y also returns the mouse coordinates - relative to the triggering . So we use offsetX/Y on IE. - */ - mouseX = d3.event.offsetX; - mouseY = d3.event.offsetY; - - /* - On IE, if you attach a mouse event listener to the container, - it will actually trigger it for all the child elements (like , , etc). - When this happens on IE, the offsetX/Y is set to where ever the child element - is located. - As a result, we do NOT need to subtract margins to figure out the mouse X/Y - position under this scenario. Removing the line below *will* cause - the interactive layer to not work right on IE. - */ - if(d3.event.target.tagName !== "svg") { - subtractMargin = false; - } - - if (d3.event.target.className.baseVal.match("nv-legend")) { - mouseOutAnyReason = true; - } - - } - - if(subtractMargin) { - mouseX -= margin.left; - mouseY -= margin.top; - } - - /* If mouseX/Y is outside of the chart's bounds, - trigger a mouseOut event. - */ - if (mouseX < 0 || mouseY < 0 - || mouseX > availableWidth || mouseY > availableHeight - || (d3.event.relatedTarget && d3.event.relatedTarget.ownerSVGElement === undefined) - || mouseOutAnyReason - ) { - - if (isMSIE) { - if (d3.event.relatedTarget - && d3.event.relatedTarget.ownerSVGElement === undefined - && (d3.event.relatedTarget.className === undefined - || d3.event.relatedTarget.className.match(tooltip.nvPointerEventsClass))) { - - return; - } - } - dispatch.elementMouseout({ - mouseX: mouseX, - mouseY: mouseY - }); - layer.renderGuideLine(null); //hide the guideline - tooltip.hidden(true); - return; - } else { - tooltip.hidden(false); - } - - var pointXValue = xScale.invert(mouseX); - dispatch.elementMousemove({ - mouseX: mouseX, - mouseY: mouseY, - pointXValue: pointXValue - }); - - //If user double clicks the layer, fire a elementDblclick - if (d3.event.type === "dblclick") { - dispatch.elementDblclick({ - mouseX: mouseX, - mouseY: mouseY, - pointXValue: pointXValue - }); - } - - // if user single clicks the layer, fire elementClick - if (d3.event.type === 'click') { - dispatch.elementClick({ - mouseX: mouseX, - mouseY: mouseY, - pointXValue: pointXValue - }); - } - } - - svgContainer - .on("touchmove",mouseHandler) - .on("mousemove",mouseHandler, true) - .on("mouseout" ,mouseHandler,true) - .on("dblclick" ,mouseHandler) - .on("click", mouseHandler) - ; - - layer.guideLine = null; - //Draws a vertical guideline at the given X postion. - layer.renderGuideLine = function(x) { - if (!showGuideLine) return; - if (layer.guideLine && layer.guideLine.attr("x1") === x) return; - nv.dom.write(function() { - var line = wrap.select(".nv-interactiveGuideLine") - .selectAll("line") - .data((x != null) ? [nv.utils.NaNtoZero(x)] : [], String); - line.enter() - .append("line") - .attr("class", "nv-guideline") - .attr("x1", function(d) { return d;}) - .attr("x2", function(d) { return d;}) - .attr("y1", availableHeight) - .attr("y2",0); - line.exit().remove(); - }); - } - }); - } - - layer.dispatch = dispatch; - layer.tooltip = tooltip; - - layer.margin = function(_) { - if (!arguments.length) return margin; - margin.top = typeof _.top != 'undefined' ? _.top : margin.top; - margin.left = typeof _.left != 'undefined' ? _.left : margin.left; - return layer; - }; - - layer.width = function(_) { - if (!arguments.length) return width; - width = _; - return layer; - }; - - layer.height = function(_) { - if (!arguments.length) return height; - height = _; - return layer; - }; - - layer.xScale = function(_) { - if (!arguments.length) return xScale; - xScale = _; - return layer; - }; - - layer.showGuideLine = function(_) { - if (!arguments.length) return showGuideLine; - showGuideLine = _; - return layer; - }; - - layer.svgContainer = function(_) { - if (!arguments.length) return svgContainer; - svgContainer = _; - return layer; - }; - - return layer; - }; - - /* Utility class that uses d3.bisect to find the index in a given array, where a search value can be inserted. - This is different from normal bisectLeft; this function finds the nearest index to insert the search value. - - For instance, lets say your array is [1,2,3,5,10,30], and you search for 28. - Normal d3.bisectLeft will return 4, because 28 is inserted after the number 10. But interactiveBisect will return 5 - because 28 is closer to 30 than 10. - - Unit tests can be found in: interactiveBisectTest.html - - Has the following known issues: - * Will not work if the data points move backwards (ie, 10,9,8,7, etc) or if the data points are in random order. - * Won't work if there are duplicate x coordinate values. - */ - nv.interactiveBisect = function (values, searchVal, xAccessor) { - "use strict"; - if (! (values instanceof Array)) { - return null; - } - var _xAccessor; - if (typeof xAccessor !== 'function') { - _xAccessor = function(d) { - return d.x; - } - } else { - _xAccessor = xAccessor; - } - var _cmp = function(d, v) { - // Accessors are no longer passed the index of the element along with - // the element itself when invoked by d3.bisector. - // - // Starting at D3 v3.4.4, d3.bisector() started inspecting the - // function passed to determine if it should consider it an accessor - // or a comparator. This meant that accessors that take two arguments - // (expecting an index as the second parameter) are treated as - // comparators where the second argument is the search value against - // which the first argument is compared. - return _xAccessor(d) - v; - }; - - var bisect = d3.bisector(_cmp).left; - var index = d3.max([0, bisect(values,searchVal) - 1]); - var currentValue = _xAccessor(values[index]); - - if (typeof currentValue === 'undefined') { - currentValue = index; - } - - if (currentValue === searchVal) { - return index; //found exact match - } - - var nextIndex = d3.min([index+1, values.length - 1]); - var nextValue = _xAccessor(values[nextIndex]); - - if (typeof nextValue === 'undefined') { - nextValue = nextIndex; - } - - if (Math.abs(nextValue - searchVal) >= Math.abs(currentValue - searchVal)) { - return index; - } else { - return nextIndex - } - }; - - /* - Returns the index in the array "values" that is closest to searchVal. - Only returns an index if searchVal is within some "threshold". - Otherwise, returns null. - */ - nv.nearestValueIndex = function (values, searchVal, threshold) { - "use strict"; - var yDistMax = Infinity, indexToHighlight = null; - values.forEach(function(d,i) { - var delta = Math.abs(searchVal - d); - if ( d != null && delta <= yDistMax && delta < threshold) { - yDistMax = delta; - indexToHighlight = i; - } - }); - return indexToHighlight; - }; - /* Tooltip rendering model for nvd3 charts. - window.nv.models.tooltip is the updated,new way to render tooltips. - - window.nv.tooltip.show is the old tooltip code. - window.nv.tooltip.* also has various helper methods. - */ - (function() { - "use strict"; - - /* Model which can be instantiated to handle tooltip rendering. - Example usage: - var tip = nv.models.tooltip().gravity('w').distance(23) - .data(myDataObject); - - tip(); //just invoke the returned function to render tooltip. - */ - nv.models.tooltip = function() { - - /* - Tooltip data. If data is given in the proper format, a consistent tooltip is generated. - Example Format of data: - { - key: "Date", - value: "August 2009", - series: [ - {key: "Series 1", value: "Value 1", color: "#000"}, - {key: "Series 2", value: "Value 2", color: "#00f"} - ] - } - */ - var data = null; - var gravity = 'w' //Can be 'n','s','e','w'. Determines how tooltip is positioned. - , distance = 25 //Distance to offset tooltip from the mouse location. - , snapDistance = 0 //Tolerance allowed before tooltip is moved from its current position (creates 'snapping' effect) - , fixedTop = null //If not null, this fixes the top position of the tooltip. - , classes = null //Attaches additional CSS classes to the tooltip DIV that is created. - , chartContainer = null //Parent dom element of the SVG that holds the chart. - , hidden = true // start off hidden, toggle with hide/show functions below - , hideDelay = 400 // delay before the tooltip hides after calling hide() - , tooltip = null // d3 select of tooltipElem below - , tooltipElem = null //actual DOM element representing the tooltip. - , position = {left: null, top: null} //Relative position of the tooltip inside chartContainer. - , offset = {left: 0, top: 0} //Offset of tooltip against the pointer - , enabled = true //True -> tooltips are rendered. False -> don't render tooltips. - , duration = 100 // duration for tooltip movement - , headerEnabled = true - ; - - // set to true by interactive layer to adjust tooltip positions - // eventually we should probably fix interactive layer to get the position better. - // for now this is needed if you want to set chartContainer for normal tooltips, else it "fixes" it to broken - var isInteractiveLayer = false; - - //Generates a unique id when you create a new tooltip() object - var id = "nvtooltip-" + Math.floor(Math.random() * 100000); - - //CSS class to specify whether element should not have mouse events. - var nvPointerEventsClass = "nv-pointer-events-none"; - - //Format function for the tooltip values column - var valueFormatter = function(d,i) { - return d; - }; - - //Format function for the tooltip header value. - var headerFormatter = function(d) { - return d; - }; - - var keyFormatter = function(d, i) { - return d; - }; - - //By default, the tooltip model renders a beautiful table inside a DIV. - //You can override this function if a custom tooltip is desired. - var contentGenerator = function(d) { - if (d === null) { - return ''; - } - - var table = d3.select(document.createElement("table")); - if (headerEnabled) { - var theadEnter = table.selectAll("thead") - .data([d]) - .enter().append("thead"); - - theadEnter.append("tr") - .append("td") - .attr("colspan", 3) - .append("strong") - .classed("x-value", true) - .html(headerFormatter(d.value)); - } - - var tbodyEnter = table.selectAll("tbody") - .data([d]) - .enter().append("tbody"); - - var trowEnter = tbodyEnter.selectAll("tr") - .data(function(p) { return p.series}) - .enter() - .append("tr") - .classed("highlight", function(p) { return p.highlight}); - - trowEnter.append("td") - .classed("legend-color-guide",true) - .append("div") - .style("background-color", function(p) { return p.color}); - - trowEnter.append("td") - .classed("key",true) - .html(function(p, i) {return keyFormatter(p.key, i)}); - - trowEnter.append("td") - .classed("value",true) - .html(function(p, i) { return valueFormatter(p.value, i) }); - - - trowEnter.selectAll("td").each(function(p) { - if (p.highlight) { - var opacityScale = d3.scale.linear().domain([0,1]).range(["#fff",p.color]); - var opacity = 0.6; - d3.select(this) - .style("border-bottom-color", opacityScale(opacity)) - .style("border-top-color", opacityScale(opacity)) - ; - } - }); - - var html = table.node().outerHTML; - if (d.footer !== undefined) - html += ""; - return html; - - }; - - var dataSeriesExists = function(d) { - if (d && d.series) { - if (d.series instanceof Array) { - return !!d.series.length; - } - // if object, it's okay just convert to array of the object - if (d.series instanceof Object) { - d.series = [d.series]; - return true; - } - } - return false; - }; - - var calcTooltipPosition = function(pos) { - if (!tooltipElem) return; - - nv.dom.read(function() { - var height = parseInt(tooltipElem.offsetHeight, 10), - width = parseInt(tooltipElem.offsetWidth, 10), - windowWidth = nv.utils.windowSize().width, - windowHeight = nv.utils.windowSize().height, - scrollTop = window.pageYOffset, - scrollLeft = window.pageXOffset, - left, top; - - windowHeight = window.innerWidth >= document.body.scrollWidth ? windowHeight : windowHeight - 16; - windowWidth = window.innerHeight >= document.body.scrollHeight ? windowWidth : windowWidth - 16; - - - //Helper functions to find the total offsets of a given DOM element. - //Looks up the entire ancestry of an element, up to the first relatively positioned element. - var tooltipTop = function ( Elem ) { - var offsetTop = top; - do { - if( !isNaN( Elem.offsetTop ) ) { - offsetTop += (Elem.offsetTop); - } - Elem = Elem.offsetParent; - } while( Elem ); - return offsetTop; - }; - var tooltipLeft = function ( Elem ) { - var offsetLeft = left; - do { - if( !isNaN( Elem.offsetLeft ) ) { - offsetLeft += (Elem.offsetLeft); - } - Elem = Elem.offsetParent; - } while( Elem ); - return offsetLeft; - }; - - // calculate position based on gravity - var tLeft, tTop; - switch (gravity) { - case 'e': - left = pos[0] - width - distance; - top = pos[1] - (height / 2); - tLeft = tooltipLeft(tooltipElem); - tTop = tooltipTop(tooltipElem); - if (tLeft < scrollLeft) left = pos[0] + distance > scrollLeft ? pos[0] + distance : scrollLeft - tLeft + left; - if (tTop < scrollTop) top = scrollTop - tTop + top; - if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height; - break; - case 'w': - left = pos[0] + distance; - top = pos[1] - (height / 2); - tLeft = tooltipLeft(tooltipElem); - tTop = tooltipTop(tooltipElem); - if (tLeft + width > windowWidth) left = pos[0] - width - distance; - if (tTop < scrollTop) top = scrollTop + 5; - if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height; - break; - case 'n': - left = pos[0] - (width / 2) - 5; - top = pos[1] + distance; - tLeft = tooltipLeft(tooltipElem); - tTop = tooltipTop(tooltipElem); - if (tLeft < scrollLeft) left = scrollLeft + 5; - if (tLeft + width > windowWidth) left = left - width/2 + 5; - if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height; - break; - case 's': - left = pos[0] - (width / 2); - top = pos[1] - height - distance; - tLeft = tooltipLeft(tooltipElem); - tTop = tooltipTop(tooltipElem); - if (tLeft < scrollLeft) left = scrollLeft + 5; - if (tLeft + width > windowWidth) left = left - width/2 + 5; - if (scrollTop > tTop) top = scrollTop; - break; - case 'none': - left = pos[0]; - top = pos[1] - distance; - tLeft = tooltipLeft(tooltipElem); - tTop = tooltipTop(tooltipElem); - break; - } - - // adjust tooltip offsets - left -= offset.left; - top -= offset.top; - - // using tooltip.style('transform') returns values un-usable for tween - var box = tooltipElem.getBoundingClientRect(); - var scrollTop = window.pageYOffset || document.documentElement.scrollTop; - var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft; - var old_translate = 'translate(' + (box.left + scrollLeft) + 'px, ' + (box.top + scrollTop) + 'px)'; - var new_translate = 'translate(' + left + 'px, ' + top + 'px)'; - var translateInterpolator = d3.interpolateString(old_translate, new_translate); - - var is_hidden = tooltip.style('opacity') < 0.1; - - // delay hiding a bit to avoid flickering - if (hidden) { - tooltip - .transition() - .delay(hideDelay) - .duration(0) - .style('opacity', 0); - } else { - tooltip - .interrupt() // cancel running transitions - .transition() - .duration(is_hidden ? 0 : duration) - // using tween since some versions of d3 can't auto-tween a translate on a div - .styleTween('transform', function (d) { - return translateInterpolator; - }, 'important') - // Safari has its own `-webkit-transform` and does not support `transform` - // transform tooltip without transition only in Safari - .style('-webkit-transform', new_translate) - .style('opacity', 1); - } - - - - }); - }; - - //In situations where the chart is in a 'viewBox', re-position the tooltip based on how far chart is zoomed. - function convertViewBoxRatio() { - if (chartContainer) { - var svg = d3.select(chartContainer); - if (svg.node().tagName !== "svg") { - svg = svg.select("svg"); - } - var viewBox = (svg.node()) ? svg.attr('viewBox') : null; - if (viewBox) { - viewBox = viewBox.split(' '); - var ratio = parseInt(svg.style('width'), 10) / viewBox[2]; - - position.left = position.left * ratio; - position.top = position.top * ratio; - } - } - } - - //Creates new tooltip container, or uses existing one on DOM. - function initTooltip() { - if (!tooltip) { - var body; - if (chartContainer) { - body = chartContainer; - } else { - body = document.body; - } - //Create new tooltip div if it doesn't exist on DOM. - tooltip = d3.select(body).append("div") - .attr("class", "nvtooltip " + (classes ? classes : "xy-tooltip")) - .attr("id", id); - tooltip.style("top", 0).style("left", 0); - tooltip.style('opacity', 0); - tooltip.selectAll("div, table, td, tr").classed(nvPointerEventsClass, true); - tooltip.classed(nvPointerEventsClass, true); - tooltipElem = tooltip.node(); - } - } - - //Draw the tooltip onto the DOM. - function nvtooltip() { - if (!enabled) return; - if (!dataSeriesExists(data)) return; - - convertViewBoxRatio(); - - var left = position.left; - var top = (fixedTop !== null) ? fixedTop : position.top; - - nv.dom.write(function () { - initTooltip(); - // generate data and set it into tooltip - // Bonus - If you override contentGenerator and return falsey you can use something like - // React or Knockout to bind the data for your tooltip - var newContent = contentGenerator(data); - if (newContent) { - tooltipElem.innerHTML = newContent; - } - - if (chartContainer && isInteractiveLayer) { - nv.dom.read(function() { - var svgComp = chartContainer.getElementsByTagName("svg")[0]; - var svgOffset = {left:0,top:0}; - if (svgComp) { - var svgBound = svgComp.getBoundingClientRect(); - var chartBound = chartContainer.getBoundingClientRect(); - var svgBoundTop = svgBound.top; - - //Defensive code. Sometimes, svgBoundTop can be a really negative - // number, like -134254. That's a bug. - // If such a number is found, use zero instead. FireFox bug only - if (svgBoundTop < 0) { - var containerBound = chartContainer.getBoundingClientRect(); - svgBoundTop = (Math.abs(svgBoundTop) > containerBound.height) ? 0 : svgBoundTop; - } - svgOffset.top = Math.abs(svgBoundTop - chartBound.top); - svgOffset.left = Math.abs(svgBound.left - chartBound.left); - } - //If the parent container is an overflow
with scrollbars, subtract the scroll offsets. - //You need to also add any offset between the element and its containing
- //Finally, add any offset of the containing
on the whole page. - left += chartContainer.offsetLeft + svgOffset.left - 2*chartContainer.scrollLeft; - top += chartContainer.offsetTop + svgOffset.top - 2*chartContainer.scrollTop; - - if (snapDistance && snapDistance > 0) { - top = Math.floor(top/snapDistance) * snapDistance; - } - calcTooltipPosition([left,top]); - }); - } else { - calcTooltipPosition([left,top]); - } - }); - - return nvtooltip; - } - - nvtooltip.nvPointerEventsClass = nvPointerEventsClass; - nvtooltip.options = nv.utils.optionsFunc.bind(nvtooltip); - - nvtooltip._options = Object.create({}, { - // simple read/write options - duration: {get: function(){return duration;}, set: function(_){duration=_;}}, - gravity: {get: function(){return gravity;}, set: function(_){gravity=_;}}, - distance: {get: function(){return distance;}, set: function(_){distance=_;}}, - snapDistance: {get: function(){return snapDistance;}, set: function(_){snapDistance=_;}}, - classes: {get: function(){return classes;}, set: function(_){classes=_;}}, - chartContainer: {get: function(){return chartContainer;}, set: function(_){chartContainer=_;}}, - fixedTop: {get: function(){return fixedTop;}, set: function(_){fixedTop=_;}}, - enabled: {get: function(){return enabled;}, set: function(_){enabled=_;}}, - hideDelay: {get: function(){return hideDelay;}, set: function(_){hideDelay=_;}}, - contentGenerator: {get: function(){return contentGenerator;}, set: function(_){contentGenerator=_;}}, - valueFormatter: {get: function(){return valueFormatter;}, set: function(_){valueFormatter=_;}}, - headerFormatter: {get: function(){return headerFormatter;}, set: function(_){headerFormatter=_;}}, - keyFormatter: {get: function(){return keyFormatter;}, set: function(_){keyFormatter=_;}}, - headerEnabled: {get: function(){return headerEnabled;}, set: function(_){headerEnabled=_;}}, - - // internal use only, set by interactive layer to adjust position. - _isInteractiveLayer: {get: function(){return isInteractiveLayer;}, set: function(_){isInteractiveLayer=!!_;}}, - - // options with extra logic - position: {get: function(){return position;}, set: function(_){ - position.left = _.left !== undefined ? _.left : position.left; - position.top = _.top !== undefined ? _.top : position.top; - }}, - offset: {get: function(){return offset;}, set: function(_){ - offset.left = _.left !== undefined ? _.left : offset.left; - offset.top = _.top !== undefined ? _.top : offset.top; - }}, - hidden: {get: function(){return hidden;}, set: function(_){ - if (hidden != _) { - hidden = !!_; - nvtooltip(); - } - }}, - data: {get: function(){return data;}, set: function(_){ - // if showing a single data point, adjust data format with that - if (_.point) { - _.value = _.point.x; - _.series = _.series || {}; - _.series.value = _.point.y; - _.series.color = _.point.color || _.series.color; - } - data = _; - }}, - - // read only properties - tooltipElem: {get: function(){return tooltipElem;}, set: function(_){}}, - id: {get: function(){return id;}, set: function(_){}} - }); - - nv.utils.initOptions(nvtooltip); - return nvtooltip; - }; - - })(); - - - /* - Gets the browser window size - - Returns object with height and width properties - */ - nv.utils.windowSize = function() { - // Sane defaults - var size = {width: 640, height: 480}; - - // Most recent browsers use - if (window.innerWidth && window.innerHeight) { - size.width = window.innerWidth; - size.height = window.innerHeight; - return (size); - } - - // IE can use depending on mode it is in - if (document.compatMode=='CSS1Compat' && - document.documentElement && - document.documentElement.offsetWidth ) { - - size.width = document.documentElement.offsetWidth; - size.height = document.documentElement.offsetHeight; - return (size); - } - - // Earlier IE uses Doc.body - if (document.body && document.body.offsetWidth) { - size.width = document.body.offsetWidth; - size.height = document.body.offsetHeight; - return (size); - } - - return (size); - }; - - /* - Binds callback function to run when window is resized - */ - nv.utils.windowResize = function(handler) { - if (window.addEventListener) { - window.addEventListener('resize', handler); - } else { - nv.log("ERROR: Failed to bind to window.resize with: ", handler); - } - // return object with clear function to remove the single added callback. - return { - callback: handler, - clear: function() { - window.removeEventListener('resize', handler); - } - } - }; - - - /* - Backwards compatible way to implement more d3-like coloring of graphs. - Can take in nothing, an array, or a function/scale - To use a normal scale, get the range and pass that because we must be able - to take two arguments and use the index to keep backward compatibility - */ - nv.utils.getColor = function(color) { - //if you pass in nothing, get default colors back - if (color === undefined) { - return nv.utils.defaultColor(); - - //if passed an array, turn it into a color scale - // use isArray, instanceof fails if d3 range is created in an iframe - } else if(Array.isArray(color)) { - var color_scale = d3.scale.ordinal().range(color); - return function(d, i) { - var key = i === undefined ? d : i; - return d.color || color_scale(key); - }; - - //if passed a function or scale, return it, or whatever it may be - //external libs, such as angularjs-nvd3-directives use this - } else { - //can't really help it if someone passes rubbish as color - return color; - } - }; - - - /* - Default color chooser uses a color scale of 20 colors from D3 - https://github.com/mbostock/d3/wiki/Ordinal-Scales#categorical-colors - */ - nv.utils.defaultColor = function() { - // get range of the scale so we'll turn it into our own function. - return nv.utils.getColor(d3.scale.category20().range()); - }; - - - /* - Returns a color function that takes the result of 'getKey' for each series and - looks for a corresponding color from the dictionary - */ - nv.utils.customTheme = function(dictionary, getKey, defaultColors) { - // use default series.key if getKey is undefined - getKey = getKey || function(series) { return series.key }; - defaultColors = defaultColors || d3.scale.category20().range(); - - // start at end of default color list and walk back to index 0 - var defIndex = defaultColors.length; - - return function(series, index) { - var key = getKey(series); - if (typeof dictionary[key] === 'function') { - return dictionary[key](); - } else if (dictionary[key] !== undefined) { - return dictionary[key]; - } else { - // no match in dictionary, use a default color - if (!defIndex) { - // used all the default colors, start over - defIndex = defaultColors.length; - } - defIndex = defIndex - 1; - return defaultColors[defIndex]; - } - }; - }; - - - /* - From the PJAX example on d3js.org, while this is not really directly needed - it's a very cool method for doing pjax, I may expand upon it a little bit, - open to suggestions on anything that may be useful - */ - nv.utils.pjax = function(links, content) { - - var load = function(href) { - d3.html(href, function(fragment) { - var target = d3.select(content).node(); - target.parentNode.replaceChild( - d3.select(fragment).select(content).node(), - target); - nv.utils.pjax(links, content); - }); - }; - - d3.selectAll(links).on("click", function() { - history.pushState(this.href, this.textContent, this.href); - load(this.href); - d3.event.preventDefault(); - }); - - d3.select(window).on("popstate", function() { - if (d3.event.state) { - load(d3.event.state); - } - }); - }; - - - /* - For when we want to approximate the width in pixels for an SVG:text element. - Most common instance is when the element is in a display:none; container. - Forumla is : text.length * font-size * constant_factor - */ - nv.utils.calcApproxTextWidth = function (svgTextElem) { - if (typeof svgTextElem.style === 'function' - && typeof svgTextElem.text === 'function') { - - var fontSize = parseInt(svgTextElem.style("font-size").replace("px",""), 10); - var textLength = svgTextElem.text().length; - return textLength * fontSize * 0.5; - } - return 0; - }; - - - /* - Numbers that are undefined, null or NaN, convert them to zeros. - */ - nv.utils.NaNtoZero = function(n) { - if (typeof n !== 'number' - || isNaN(n) - || n === null - || n === Infinity - || n === -Infinity) { - - return 0; - } - return n; - }; - - /* - Add a way to watch for d3 transition ends to d3 - */ - d3.selection.prototype.watchTransition = function(renderWatch){ - var args = [this].concat([].slice.call(arguments, 1)); - return renderWatch.transition.apply(renderWatch, args); - }; - - - /* - Helper object to watch when d3 has rendered something - */ - nv.utils.renderWatch = function(dispatch, duration) { - if (!(this instanceof nv.utils.renderWatch)) { - return new nv.utils.renderWatch(dispatch, duration); - } - - var _duration = duration !== undefined ? duration : 250; - var renderStack = []; - var self = this; - - this.models = function(models) { - models = [].slice.call(arguments, 0); - models.forEach(function(model){ - model.__rendered = false; - (function(m){ - m.dispatch.on('renderEnd', function(arg){ - m.__rendered = true; - self.renderEnd('model'); - }); - })(model); - - if (renderStack.indexOf(model) < 0) { - renderStack.push(model); - } - }); - return this; - }; - - this.reset = function(duration) { - if (duration !== undefined) { - _duration = duration; - } - renderStack = []; - }; - - this.transition = function(selection, args, duration) { - args = arguments.length > 1 ? [].slice.call(arguments, 1) : []; - - if (args.length > 1) { - duration = args.pop(); - } else { - duration = _duration !== undefined ? _duration : 250; - } - selection.__rendered = false; - - if (renderStack.indexOf(selection) < 0) { - renderStack.push(selection); - } - - if (duration === 0) { - selection.__rendered = true; - selection.delay = function() { return this; }; - selection.duration = function() { return this; }; - return selection; - } else { - if (selection.length === 0) { - selection.__rendered = true; - } else if (selection.every( function(d){ return !d.length; } )) { - selection.__rendered = true; - } else { - selection.__rendered = false; - } - - var n = 0; - return selection - .transition() - .duration(duration) - .each(function(){ ++n; }) - .each('end', function(d, i) { - if (--n === 0) { - selection.__rendered = true; - self.renderEnd.apply(this, args); - } - }); - } - }; - - this.renderEnd = function() { - if (renderStack.every( function(d){ return d.__rendered; } )) { - renderStack.forEach( function(d){ d.__rendered = false; }); - dispatch.renderEnd.apply(this, arguments); - } - } - - }; - - - /* - Takes multiple objects and combines them into the first one (dst) - example: nv.utils.deepExtend({a: 1}, {a: 2, b: 3}, {c: 4}); - gives: {a: 2, b: 3, c: 4} - */ - nv.utils.deepExtend = function(dst){ - var sources = arguments.length > 1 ? [].slice.call(arguments, 1) : []; - sources.forEach(function(source) { - for (var key in source) { - var isArray = dst[key] instanceof Array; - var isObject = typeof dst[key] === 'object'; - var srcObj = typeof source[key] === 'object'; - - if (isObject && !isArray && srcObj) { - nv.utils.deepExtend(dst[key], source[key]); - } else { - dst[key] = source[key]; - } - } - }); - }; - - - /* - state utility object, used to track d3 states in the models - */ - nv.utils.state = function(){ - if (!(this instanceof nv.utils.state)) { - return new nv.utils.state(); - } - var state = {}; - var _self = this; - var _setState = function(){}; - var _getState = function(){ return {}; }; - var init = null; - var changed = null; - - this.dispatch = d3.dispatch('change', 'set'); - - this.dispatch.on('set', function(state){ - _setState(state, true); - }); - - this.getter = function(fn){ - _getState = fn; - return this; - }; - - this.setter = function(fn, callback) { - if (!callback) { - callback = function(){}; - } - _setState = function(state, update){ - fn(state); - if (update) { - callback(); - } - }; - return this; - }; - - this.init = function(state){ - init = init || {}; - nv.utils.deepExtend(init, state); - }; - - var _set = function(){ - var settings = _getState(); - - if (JSON.stringify(settings) === JSON.stringify(state)) { - return false; - } - - for (var key in settings) { - if (state[key] === undefined) { - state[key] = {}; - } - state[key] = settings[key]; - changed = true; - } - return true; - }; - - this.update = function(){ - if (init) { - _setState(init, false); - init = null; - } - if (_set.call(this)) { - this.dispatch.change(state); - } - }; - - }; - - - /* - Snippet of code you can insert into each nv.models.* to give you the ability to - do things like: - chart.options({ - showXAxis: true, - tooltips: true - }); - - To enable in the chart: - chart.options = nv.utils.optionsFunc.bind(chart); - */ - nv.utils.optionsFunc = function(args) { - if (args) { - d3.map(args).forEach((function(key,value) { - if (typeof this[key] === "function") { - this[key](value); - } - }).bind(this)); - } - return this; - }; - - - /* - numTicks: requested number of ticks - data: the chart data - - returns the number of ticks to actually use on X axis, based on chart data - to avoid duplicate ticks with the same value - */ - nv.utils.calcTicksX = function(numTicks, data) { - // find max number of values from all data streams - var numValues = 1; - var i = 0; - for (i; i < data.length; i += 1) { - var stream_len = data[i] && data[i].values ? data[i].values.length : 0; - numValues = stream_len > numValues ? stream_len : numValues; - } - nv.log("Requested number of ticks: ", numTicks); - nv.log("Calculated max values to be: ", numValues); - // make sure we don't have more ticks than values to avoid duplicates - numTicks = numTicks > numValues ? numTicks = numValues - 1 : numTicks; - // make sure we have at least one tick - numTicks = numTicks < 1 ? 1 : numTicks; - // make sure it's an integer - numTicks = Math.floor(numTicks); - nv.log("Calculating tick count as: ", numTicks); - return numTicks; - }; - - - /* - returns number of ticks to actually use on Y axis, based on chart data - */ - nv.utils.calcTicksY = function(numTicks, data) { - // currently uses the same logic but we can adjust here if needed later - return nv.utils.calcTicksX(numTicks, data); - }; - - - /* - Add a particular option from an options object onto chart - Options exposed on a chart are a getter/setter function that returns chart - on set to mimic typical d3 option chaining, e.g. svg.option1('a').option2('b'); - - option objects should be generated via Object.create() to provide - the option of manipulating data via get/set functions. - */ - nv.utils.initOption = function(chart, name) { - // if it's a call option, just call it directly, otherwise do get/set - if (chart._calls && chart._calls[name]) { - chart[name] = chart._calls[name]; - } else { - chart[name] = function (_) { - if (!arguments.length) return chart._options[name]; - chart._overrides[name] = true; - chart._options[name] = _; - return chart; - }; - // calling the option as _option will ignore if set by option already - // so nvd3 can set options internally but the stop if set manually - chart['_' + name] = function(_) { - if (!arguments.length) return chart._options[name]; - if (!chart._overrides[name]) { - chart._options[name] = _; - } - return chart; - } - } - }; - - - /* - Add all options in an options object to the chart - */ - nv.utils.initOptions = function(chart) { - chart._overrides = chart._overrides || {}; - var ops = Object.getOwnPropertyNames(chart._options || {}); - var calls = Object.getOwnPropertyNames(chart._calls || {}); - ops = ops.concat(calls); - for (var i in ops) { - nv.utils.initOption(chart, ops[i]); - } - }; - - - /* - Inherit options from a D3 object - d3.rebind makes calling the function on target actually call it on source - Also use _d3options so we can track what we inherit for documentation and chained inheritance - */ - nv.utils.inheritOptionsD3 = function(target, d3_source, oplist) { - target._d3options = oplist.concat(target._d3options || []); - oplist.unshift(d3_source); - oplist.unshift(target); - d3.rebind.apply(this, oplist); - }; - - - /* - Remove duplicates from an array - */ - nv.utils.arrayUnique = function(a) { - return a.sort().filter(function(item, pos) { - return !pos || item != a[pos - 1]; - }); - }; - - - /* - Keeps a list of custom symbols to draw from in addition to d3.svg.symbol - Necessary since d3 doesn't let you extend its list -_- - Add new symbols by doing nv.utils.symbols.set('name', function(size){...}); - */ - nv.utils.symbolMap = d3.map(); - - - /* - Replaces d3.svg.symbol so that we can look both there and our own map - */ - nv.utils.symbol = function() { - var type, - size = 64; - function symbol(d,i) { - var t = type.call(this,d,i); - var s = size.call(this,d,i); - if (d3.svg.symbolTypes.indexOf(t) !== -1) { - return d3.svg.symbol().type(t).size(s)(); - } else { - return nv.utils.symbolMap.get(t)(s); - } - } - symbol.type = function(_) { - if (!arguments.length) return type; - type = d3.functor(_); - return symbol; - }; - symbol.size = function(_) { - if (!arguments.length) return size; - size = d3.functor(_); - return symbol; - }; - return symbol; - }; - - - /* - Inherit option getter/setter functions from source to target - d3.rebind makes calling the function on target actually call it on source - Also track via _inherited and _d3options so we can track what we inherit - for documentation generation purposes and chained inheritance - */ - nv.utils.inheritOptions = function(target, source) { - // inherit all the things - var ops = Object.getOwnPropertyNames(source._options || {}); - var calls = Object.getOwnPropertyNames(source._calls || {}); - var inherited = source._inherited || []; - var d3ops = source._d3options || []; - var args = ops.concat(calls).concat(inherited).concat(d3ops); - args.unshift(source); - args.unshift(target); - d3.rebind.apply(this, args); - // pass along the lists to keep track of them, don't allow duplicates - target._inherited = nv.utils.arrayUnique(ops.concat(calls).concat(inherited).concat(ops).concat(target._inherited || [])); - target._d3options = nv.utils.arrayUnique(d3ops.concat(target._d3options || [])); - }; - - - /* - Runs common initialize code on the svg before the chart builds - */ - nv.utils.initSVG = function(svg) { - svg.classed({'nvd3-svg':true}); - }; - - - /* - Sanitize and provide default for the container height. - */ - nv.utils.sanitizeHeight = function(height, container) { - return (height || parseInt(container.style('height'), 10) || 400); - }; - - - /* - Sanitize and provide default for the container width. - */ - nv.utils.sanitizeWidth = function(width, container) { - return (width || parseInt(container.style('width'), 10) || 960); - }; - - - /* - Calculate the available height for a chart. - */ - nv.utils.availableHeight = function(height, container, margin) { - return nv.utils.sanitizeHeight(height, container) - margin.top - margin.bottom; - }; - - /* - Calculate the available width for a chart. - */ - nv.utils.availableWidth = function(width, container, margin) { - return nv.utils.sanitizeWidth(width, container) - margin.left - margin.right; - }; - - /* - Clear any rendered chart components and display a chart's 'noData' message - */ - nv.utils.noData = function(chart, container) { - var opt = chart.options(), - margin = opt.margin(), - noData = opt.noData(), - data = (noData == null) ? ["No Data Available."] : [noData], - height = nv.utils.availableHeight(opt.height(), container, margin), - width = nv.utils.availableWidth(opt.width(), container, margin), - x = margin.left + width/2, - y = margin.top + height/2; - - //Remove any previously created chart components - container.selectAll('g').remove(); - - var noDataText = container.selectAll('.nv-noData').data(data); - - noDataText.enter().append('text') - .attr('class', 'nvd3 nv-noData') - .attr('dy', '-.7em') - .style('text-anchor', 'middle'); - - noDataText - .attr('x', x) - .attr('y', y) - .text(function(t){ return t; }); - }; - - nv.models.axis = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var axis = d3.svg.axis(); - var scale = d3.scale.linear(); - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = 75 //only used for tickLabel currently - , height = 60 //only used for tickLabel currently - , axisLabelText = null - , showMaxMin = true //TODO: showMaxMin should be disabled on all ordinal scaled axes - , rotateLabels = 0 - , rotateYLabel = true - , staggerLabels = false - , isOrdinal = false - , ticks = null - , axisLabelDistance = 0 - , duration = 250 - , dispatch = d3.dispatch('renderEnd') - ; - axis - .scale(scale) - .orient('bottom') - .tickFormat(function(d) { return d }) - ; - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var scale0; - var renderWatch = nv.utils.renderWatch(dispatch, duration); - - function chart(selection) { - renderWatch.reset(); - selection.each(function(data) { - var container = d3.select(this); - nv.utils.initSVG(container); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-axis').data([data]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-axis'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - if (ticks !== null) - axis.ticks(ticks); - else if (axis.orient() == 'top' || axis.orient() == 'bottom') - axis.ticks(Math.abs(scale.range()[1] - scale.range()[0]) / 100); - - //TODO: consider calculating width/height based on whether or not label is added, for reference in charts using this component - g.watchTransition(renderWatch, 'axis').call(axis); - - scale0 = scale0 || axis.scale(); - - var fmt = axis.tickFormat(); - if (fmt == null) { - fmt = scale0.tickFormat(); - } - - var axisLabel = g.selectAll('text.nv-axislabel') - .data([axisLabelText || null]); - axisLabel.exit().remove(); - - var xLabelMargin; - var axisMaxMin; - var w; - switch (axis.orient()) { - case 'top': - axisLabel.enter().append('text').attr('class', 'nv-axislabel'); - if (scale.range().length < 2) { - w = 0; - } else if (scale.range().length === 2) { - w = scale.range()[1]; - } else { - w = scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0]); - } - axisLabel - .attr('text-anchor', 'middle') - .attr('y', 0) - .attr('x', w/2); - if (showMaxMin) { - axisMaxMin = wrap.selectAll('g.nv-axisMaxMin') - .data(scale.domain()); - axisMaxMin.enter().append('g').attr('class',function(d,i){ - return ['nv-axisMaxMin','nv-axisMaxMin-x',(i == 0 ? 'nv-axisMin-x':'nv-axisMax-x')].join(' ') - }).append('text'); - axisMaxMin.exit().remove(); - axisMaxMin - .attr('transform', function(d,i) { - return 'translate(' + nv.utils.NaNtoZero(scale(d)) + ',0)' - }) - .select('text') - .attr('dy', '-0.5em') - .attr('y', -axis.tickPadding()) - .attr('text-anchor', 'middle') - .text(function(d,i) { - var v = fmt(d); - return ('' + v).match('NaN') ? '' : v; - }); - axisMaxMin.watchTransition(renderWatch, 'min-max top') - .attr('transform', function(d,i) { - return 'translate(' + nv.utils.NaNtoZero(scale.range()[i]) + ',0)' - }); - } - break; - case 'bottom': - xLabelMargin = axisLabelDistance + 36; - var maxTextWidth = 30; - var textHeight = 0; - var xTicks = g.selectAll('g').select("text"); - var rotateLabelsRule = ''; - if (rotateLabels%360) { - //Calculate the longest xTick width - xTicks.each(function(d,i){ - var box = this.getBoundingClientRect(); - var width = box.width; - textHeight = box.height; - if(width > maxTextWidth) maxTextWidth = width; - }); - rotateLabelsRule = 'rotate(' + rotateLabels + ' 0,' + (textHeight/2 + axis.tickPadding()) + ')'; - //Convert to radians before calculating sin. Add 30 to margin for healthy padding. - var sin = Math.abs(Math.sin(rotateLabels*Math.PI/180)); - xLabelMargin = (sin ? sin*maxTextWidth : maxTextWidth)+30; - //Rotate all xTicks - xTicks - .attr('transform', rotateLabelsRule) - .style('text-anchor', rotateLabels%360 > 0 ? 'start' : 'end'); - } - axisLabel.enter().append('text').attr('class', 'nv-axislabel'); - if (scale.range().length < 2) { - w = 0; - } else if (scale.range().length === 2) { - w = scale.range()[1]; - } else { - w = scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0]); - } - axisLabel - .attr('text-anchor', 'middle') - .attr('y', xLabelMargin) - .attr('x', w/2); - if (showMaxMin) { - //if (showMaxMin && !isOrdinal) { - axisMaxMin = wrap.selectAll('g.nv-axisMaxMin') - //.data(scale.domain()) - .data([scale.domain()[0], scale.domain()[scale.domain().length - 1]]); - axisMaxMin.enter().append('g').attr('class',function(d,i){ - return ['nv-axisMaxMin','nv-axisMaxMin-x',(i == 0 ? 'nv-axisMin-x':'nv-axisMax-x')].join(' ') - }).append('text'); - axisMaxMin.exit().remove(); - axisMaxMin - .attr('transform', function(d,i) { - return 'translate(' + nv.utils.NaNtoZero((scale(d) + (isOrdinal ? scale.rangeBand() / 2 : 0))) + ',0)' - }) - .select('text') - .attr('dy', '.71em') - .attr('y', axis.tickPadding()) - .attr('transform', rotateLabelsRule) - .style('text-anchor', rotateLabels ? (rotateLabels%360 > 0 ? 'start' : 'end') : 'middle') - .text(function(d,i) { - var v = fmt(d); - return ('' + v).match('NaN') ? '' : v; - }); - axisMaxMin.watchTransition(renderWatch, 'min-max bottom') - .attr('transform', function(d,i) { - return 'translate(' + nv.utils.NaNtoZero((scale(d) + (isOrdinal ? scale.rangeBand() / 2 : 0))) + ',0)' - }); - } - if (staggerLabels) - xTicks - .attr('transform', function(d,i) { - return 'translate(0,' + (i % 2 == 0 ? '0' : '12') + ')' - }); - - break; - case 'right': - axisLabel.enter().append('text').attr('class', 'nv-axislabel'); - axisLabel - .style('text-anchor', rotateYLabel ? 'middle' : 'begin') - .attr('transform', rotateYLabel ? 'rotate(90)' : '') - .attr('y', rotateYLabel ? (-Math.max(margin.right, width) + 12) : -10) //TODO: consider calculating this based on largest tick width... OR at least expose this on chart - .attr('x', rotateYLabel ? (d3.max(scale.range()) / 2) : axis.tickPadding()); - if (showMaxMin) { - axisMaxMin = wrap.selectAll('g.nv-axisMaxMin') - .data(scale.domain()); - axisMaxMin.enter().append('g').attr('class',function(d,i){ - return ['nv-axisMaxMin','nv-axisMaxMin-y',(i == 0 ? 'nv-axisMin-y':'nv-axisMax-y')].join(' ') - }).append('text') - .style('opacity', 0); - axisMaxMin.exit().remove(); - axisMaxMin - .attr('transform', function(d,i) { - return 'translate(0,' + nv.utils.NaNtoZero(scale(d)) + ')' - }) - .select('text') - .attr('dy', '.32em') - .attr('y', 0) - .attr('x', axis.tickPadding()) - .style('text-anchor', 'start') - .text(function(d, i) { - var v = fmt(d); - return ('' + v).match('NaN') ? '' : v; - }); - axisMaxMin.watchTransition(renderWatch, 'min-max right') - .attr('transform', function(d,i) { - return 'translate(0,' + nv.utils.NaNtoZero(scale.range()[i]) + ')' - }) - .select('text') - .style('opacity', 1); - } - break; - case 'left': - /* - //For dynamically placing the label. Can be used with dynamically-sized chart axis margins - var yTicks = g.selectAll('g').select("text"); - yTicks.each(function(d,i){ - var labelPadding = this.getBoundingClientRect().width + axis.tickPadding() + 16; - if(labelPadding > width) width = labelPadding; - }); - */ - axisLabel.enter().append('text').attr('class', 'nv-axislabel'); - axisLabel - .style('text-anchor', rotateYLabel ? 'middle' : 'end') - .attr('transform', rotateYLabel ? 'rotate(-90)' : '') - .attr('y', rotateYLabel ? (-Math.max(margin.left, width) + 25 - (axisLabelDistance || 0)) : -10) - .attr('x', rotateYLabel ? (-d3.max(scale.range()) / 2) : -axis.tickPadding()); - if (showMaxMin) { - axisMaxMin = wrap.selectAll('g.nv-axisMaxMin') - .data(scale.domain()); - axisMaxMin.enter().append('g').attr('class',function(d,i){ - return ['nv-axisMaxMin','nv-axisMaxMin-y',(i == 0 ? 'nv-axisMin-y':'nv-axisMax-y')].join(' ') - }).append('text') - .style('opacity', 0); - axisMaxMin.exit().remove(); - axisMaxMin - .attr('transform', function(d,i) { - return 'translate(0,' + nv.utils.NaNtoZero(scale0(d)) + ')' - }) - .select('text') - .attr('dy', '.32em') - .attr('y', 0) - .attr('x', -axis.tickPadding()) - .attr('text-anchor', 'end') - .text(function(d,i) { - var v = fmt(d); - return ('' + v).match('NaN') ? '' : v; - }); - axisMaxMin.watchTransition(renderWatch, 'min-max right') - .attr('transform', function(d,i) { - return 'translate(0,' + nv.utils.NaNtoZero(scale.range()[i]) + ')' - }) - .select('text') - .style('opacity', 1); - } - break; - } - axisLabel.text(function(d) { return d }); - - if (showMaxMin && (axis.orient() === 'left' || axis.orient() === 'right')) { - //check if max and min overlap other values, if so, hide the values that overlap - g.selectAll('g') // the g's wrapping each tick - .each(function(d,i) { - d3.select(this).select('text').attr('opacity', 1); - if (scale(d) < scale.range()[1] + 10 || scale(d) > scale.range()[0] - 10) { // 10 is assuming text height is 16... if d is 0, leave it! - if (d > 1e-10 || d < -1e-10) // accounts for minor floating point errors... though could be problematic if the scale is EXTREMELY SMALL - d3.select(this).attr('opacity', 0); - - d3.select(this).select('text').attr('opacity', 0); // Don't remove the ZERO line!! - } - }); - - //if Max and Min = 0 only show min, Issue #281 - if (scale.domain()[0] == scale.domain()[1] && scale.domain()[0] == 0) { - wrap.selectAll('g.nv-axisMaxMin').style('opacity', function (d, i) { - return !i ? 1 : 0 - }); - } - } - - if (showMaxMin && (axis.orient() === 'top' || axis.orient() === 'bottom')) { - var maxMinRange = []; - wrap.selectAll('g.nv-axisMaxMin') - .each(function(d,i) { - try { - if (i) // i== 1, max position - maxMinRange.push(scale(d) - this.getBoundingClientRect().width - 4); //assuming the max and min labels are as wide as the next tick (with an extra 4 pixels just in case) - else // i==0, min position - maxMinRange.push(scale(d) + this.getBoundingClientRect().width + 4) - }catch (err) { - if (i) // i== 1, max position - maxMinRange.push(scale(d) - 4); //assuming the max and min labels are as wide as the next tick (with an extra 4 pixels just in case) - else // i==0, min position - maxMinRange.push(scale(d) + 4); - } - }); - // the g's wrapping each tick - g.selectAll('g').each(function(d, i) { - if (scale(d) < maxMinRange[0] || scale(d) > maxMinRange[1]) { - if (d > 1e-10 || d < -1e-10) // accounts for minor floating point errors... though could be problematic if the scale is EXTREMELY SMALL - d3.select(this).remove(); - else - d3.select(this).select('text').remove(); // Don't remove the ZERO line!! - } - }); - } - - //Highlight zero tick line - g.selectAll('.tick') - .filter(function (d) { - /* - The filter needs to return only ticks at or near zero. - Numbers like 0.00001 need to count as zero as well, - and the arithmetic trick below solves that. - */ - return !parseFloat(Math.round(d * 100000) / 1000000) && (d !== undefined) - }) - .classed('zero', true); - - //store old scales for use in transitions on update - scale0 = scale.copy(); - - }); - - renderWatch.renderEnd('axis immediate'); - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - // expose chart's sub-components - chart.axis = axis; - chart.dispatch = dispatch; - - chart.options = nv.utils.optionsFunc.bind(chart); - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - axisLabelDistance: {get: function(){return axisLabelDistance;}, set: function(_){axisLabelDistance=_;}}, - staggerLabels: {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}}, - rotateLabels: {get: function(){return rotateLabels;}, set: function(_){rotateLabels=_;}}, - rotateYLabel: {get: function(){return rotateYLabel;}, set: function(_){rotateYLabel=_;}}, - showMaxMin: {get: function(){return showMaxMin;}, set: function(_){showMaxMin=_;}}, - axisLabel: {get: function(){return axisLabelText;}, set: function(_){axisLabelText=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - ticks: {get: function(){return ticks;}, set: function(_){ticks=_;}}, - width: {get: function(){return width;}, set: function(_){width=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration=_; - renderWatch.reset(duration); - }}, - scale: {get: function(){return scale;}, set: function(_){ - scale = _; - axis.scale(scale); - isOrdinal = typeof scale.rangeBands === 'function'; - nv.utils.inheritOptionsD3(chart, scale, ['domain', 'range', 'rangeBand', 'rangeBands']); - }} - }); - - nv.utils.initOptions(chart); - nv.utils.inheritOptionsD3(chart, axis, ['orient', 'tickValues', 'tickSubdivide', 'tickSize', 'tickPadding', 'tickFormat']); - nv.utils.inheritOptionsD3(chart, scale, ['domain', 'range', 'rangeBand', 'rangeBands']); - - return chart; - }; - nv.models.boxPlot = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = 960 - , height = 500 - , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one - , x = d3.scale.ordinal() - , y = d3.scale.linear() - , getX = function(d) { return d.x } - , getY = function(d) { return d.y } - , color = nv.utils.defaultColor() - , container = null - , xDomain - , yDomain - , xRange - , yRange - , dispatch = d3.dispatch('elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd') - , duration = 250 - , maxBoxWidth = null - ; - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var x0, y0; - var renderWatch = nv.utils.renderWatch(dispatch, duration); - - function chart(selection) { - renderWatch.reset(); - selection.each(function(data) { - var availableWidth = width - margin.left - margin.right, - availableHeight = height - margin.top - margin.bottom; - - container = d3.select(this); - nv.utils.initSVG(container); - - // Setup Scales - x .domain(xDomain || data.map(function(d,i) { return getX(d,i); })) - .rangeBands(xRange || [0, availableWidth], .1); - - // if we know yDomain, no need to calculate - var yData = [] - if (!yDomain) { - // (y-range is based on quartiles, whiskers and outliers) - - // lower values - var yMin = d3.min(data.map(function(d) { - var min_arr = []; - - min_arr.push(d.values.Q1); - if (d.values.hasOwnProperty('whisker_low') && d.values.whisker_low !== null) { min_arr.push(d.values.whisker_low); } - if (d.values.hasOwnProperty('outliers') && d.values.outliers !== null) { min_arr = min_arr.concat(d.values.outliers); } - - return d3.min(min_arr); - })); - - // upper values - var yMax = d3.max(data.map(function(d) { - var max_arr = []; - - max_arr.push(d.values.Q3); - if (d.values.hasOwnProperty('whisker_high') && d.values.whisker_high !== null) { max_arr.push(d.values.whisker_high); } - if (d.values.hasOwnProperty('outliers') && d.values.outliers !== null) { max_arr = max_arr.concat(d.values.outliers); } - - return d3.max(max_arr); - })); - - yData = [ yMin, yMax ] ; - } - - y.domain(yDomain || yData); - y.range(yRange || [availableHeight, 0]); - - //store old scales if they exist - x0 = x0 || x; - y0 = y0 || y.copy().range([y(0),y(0)]); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap').data([data]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap'); - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - var boxplots = wrap.selectAll('.nv-boxplot').data(function(d) { return d }); - var boxEnter = boxplots.enter().append('g').style('stroke-opacity', 1e-6).style('fill-opacity', 1e-6); - boxplots - .attr('class', 'nv-boxplot') - .attr('transform', function(d,i,j) { return 'translate(' + (x(getX(d,i)) + x.rangeBand() * .05) + ', 0)'; }) - .classed('hover', function(d) { return d.hover }); - boxplots - .watchTransition(renderWatch, 'nv-boxplot: boxplots') - .style('stroke-opacity', 1) - .style('fill-opacity', .75) - .delay(function(d,i) { return i * duration / data.length }) - .attr('transform', function(d,i) { - return 'translate(' + (x(getX(d,i)) + x.rangeBand() * .05) + ', 0)'; - }); - boxplots.exit().remove(); - - // ----- add the SVG elements for each boxPlot ----- - - // conditionally append whisker lines - boxEnter.each(function(d,i) { - var box = d3.select(this); - - ['low', 'high'].forEach(function(key) { - if (d.values.hasOwnProperty('whisker_' + key) && d.values['whisker_' + key] !== null) { - box.append('line') - .style('stroke', (d.color) ? d.color : color(d,i)) - .attr('class', 'nv-boxplot-whisker nv-boxplot-' + key); - - box.append('line') - .style('stroke', (d.color) ? d.color : color(d,i)) - .attr('class', 'nv-boxplot-tick nv-boxplot-' + key); - } - }); - }); - - // outliers - // TODO: support custom colors here - var outliers = boxplots.selectAll('.nv-boxplot-outlier').data(function(d) { - if (d.values.hasOwnProperty('outliers') && d.values.outliers !== null) { return d.values.outliers; } - else { return []; } - }); - outliers.enter().append('circle') - .style('fill', function(d,i,j) { return color(d,j) }).style('stroke', function(d,i,j) { return color(d,j) }) - .on('mouseover', function(d,i,j) { - d3.select(this).classed('hover', true); - dispatch.elementMouseover({ - series: { key: d, color: color(d,j) }, - e: d3.event - }); - }) - .on('mouseout', function(d,i,j) { - d3.select(this).classed('hover', false); - dispatch.elementMouseout({ - series: { key: d, color: color(d,j) }, - e: d3.event - }); - }) - .on('mousemove', function(d,i) { - dispatch.elementMousemove({e: d3.event}); - }); - - outliers.attr('class', 'nv-boxplot-outlier'); - outliers - .watchTransition(renderWatch, 'nv-boxplot: nv-boxplot-outlier') - .attr('cx', x.rangeBand() * .45) - .attr('cy', function(d,i,j) { return y(d); }) - .attr('r', '3'); - outliers.exit().remove(); - - var box_width = function() { return (maxBoxWidth === null ? x.rangeBand() * .9 : Math.min(75, x.rangeBand() * .9)); }; - var box_left = function() { return x.rangeBand() * .45 - box_width()/2; }; - var box_right = function() { return x.rangeBand() * .45 + box_width()/2; }; - - // update whisker lines and ticks - ['low', 'high'].forEach(function(key) { - var endpoint = (key === 'low') ? 'Q1' : 'Q3'; - - boxplots.select('line.nv-boxplot-whisker.nv-boxplot-' + key) - .watchTransition(renderWatch, 'nv-boxplot: boxplots') - .attr('x1', x.rangeBand() * .45 ) - .attr('y1', function(d,i) { return y(d.values['whisker_' + key]); }) - .attr('x2', x.rangeBand() * .45 ) - .attr('y2', function(d,i) { return y(d.values[endpoint]); }); - - boxplots.select('line.nv-boxplot-tick.nv-boxplot-' + key) - .watchTransition(renderWatch, 'nv-boxplot: boxplots') - .attr('x1', box_left ) - .attr('y1', function(d,i) { return y(d.values['whisker_' + key]); }) - .attr('x2', box_right ) - .attr('y2', function(d,i) { return y(d.values['whisker_' + key]); }); - }); - - ['low', 'high'].forEach(function(key) { - boxEnter.selectAll('.nv-boxplot-' + key) - .on('mouseover', function(d,i,j) { - d3.select(this).classed('hover', true); - dispatch.elementMouseover({ - series: { key: d.values['whisker_' + key], color: color(d,j) }, - e: d3.event - }); - }) - .on('mouseout', function(d,i,j) { - d3.select(this).classed('hover', false); - dispatch.elementMouseout({ - series: { key: d.values['whisker_' + key], color: color(d,j) }, - e: d3.event - }); - }) - .on('mousemove', function(d,i) { - dispatch.elementMousemove({e: d3.event}); - }); - }); - - // boxes - boxEnter.append('rect') - .attr('class', 'nv-boxplot-box') - // tooltip events - .on('mouseover', function(d,i) { - d3.select(this).classed('hover', true); - dispatch.elementMouseover({ - key: d.label, - value: d.label, - series: [ - { key: 'Q3', value: d.values.Q3, color: d.color || color(d,i) }, - { key: 'Q2', value: d.values.Q2, color: d.color || color(d,i) }, - { key: 'Q1', value: d.values.Q1, color: d.color || color(d,i) } - ], - data: d, - index: i, - e: d3.event - }); - }) - .on('mouseout', function(d,i) { - d3.select(this).classed('hover', false); - dispatch.elementMouseout({ - key: d.label, - value: d.label, - series: [ - { key: 'Q3', value: d.values.Q3, color: d.color || color(d,i) }, - { key: 'Q2', value: d.values.Q2, color: d.color || color(d,i) }, - { key: 'Q1', value: d.values.Q1, color: d.color || color(d,i) } - ], - data: d, - index: i, - e: d3.event - }); - }) - .on('mousemove', function(d,i) { - dispatch.elementMousemove({e: d3.event}); - }); - - // box transitions - boxplots.select('rect.nv-boxplot-box') - .watchTransition(renderWatch, 'nv-boxplot: boxes') - .attr('y', function(d,i) { return y(d.values.Q3); }) - .attr('width', box_width) - .attr('x', box_left ) - - .attr('height', function(d,i) { return Math.abs(y(d.values.Q3) - y(d.values.Q1)) || 1 }) - .style('fill', function(d,i) { return d.color || color(d,i) }) - .style('stroke', function(d,i) { return d.color || color(d,i) }); - - // median line - boxEnter.append('line').attr('class', 'nv-boxplot-median'); - - boxplots.select('line.nv-boxplot-median') - .watchTransition(renderWatch, 'nv-boxplot: boxplots line') - .attr('x1', box_left) - .attr('y1', function(d,i) { return y(d.values.Q2); }) - .attr('x2', box_right) - .attr('y2', function(d,i) { return y(d.values.Q2); }); - - //store old scales for use in transitions on update - x0 = x.copy(); - y0 = y.copy(); - }); - - renderWatch.renderEnd('nv-boxplot immediate'); - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - maxBoxWidth: {get: function(){return maxBoxWidth;}, set: function(_){maxBoxWidth=_;}}, - x: {get: function(){return getX;}, set: function(_){getX=_;}}, - y: {get: function(){return getY;}, set: function(_){getY=_;}}, - xScale: {get: function(){return x;}, set: function(_){x=_;}}, - yScale: {get: function(){return y;}, set: function(_){y=_;}}, - xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}}, - yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}}, - xRange: {get: function(){return xRange;}, set: function(_){xRange=_;}}, - yRange: {get: function(){return yRange;}, set: function(_){yRange=_;}}, - id: {get: function(){return id;}, set: function(_){id=_;}}, - // rectClass: {get: function(){return rectClass;}, set: function(_){rectClass=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - }} - }); - - nv.utils.initOptions(chart); - - return chart; - }; - nv.models.boxPlotChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var boxplot = nv.models.boxPlot() - , xAxis = nv.models.axis() - , yAxis = nv.models.axis() - ; - - var margin = {top: 15, right: 10, bottom: 50, left: 60} - , width = null - , height = null - , color = nv.utils.getColor() - , showXAxis = true - , showYAxis = true - , rightAlignYAxis = false - , staggerLabels = false - , tooltip = nv.models.tooltip() - , x - , y - , noData = "No Data Available." - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'beforeUpdate', 'renderEnd') - , duration = 250 - ; - - xAxis - .orient('bottom') - .showMaxMin(false) - .tickFormat(function(d) { return d }) - ; - yAxis - .orient((rightAlignYAxis) ? 'right' : 'left') - .tickFormat(d3.format(',.1f')) - ; - - tooltip.duration(0); - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var renderWatch = nv.utils.renderWatch(dispatch, duration); - - function chart(selection) { - renderWatch.reset(); - renderWatch.models(boxplot); - if (showXAxis) renderWatch.models(xAxis); - if (showYAxis) renderWatch.models(yAxis); - - selection.each(function(data) { - var container = d3.select(this), - that = this; - nv.utils.initSVG(container); - var availableWidth = (width || parseInt(container.style('width')) || 960) - - margin.left - margin.right, - availableHeight = (height || parseInt(container.style('height')) || 400) - - margin.top - margin.bottom; - - chart.update = function() { - dispatch.beforeUpdate(); - container.transition().duration(duration).call(chart); - }; - chart.container = this; - - // Display No Data message if there's nothing to show. (quartiles required at minimum) - if (!data || !data.length || - !data.filter(function(d) { return d.values.hasOwnProperty("Q1") && d.values.hasOwnProperty("Q2") && d.values.hasOwnProperty("Q3"); }).length) { - var noDataText = container.selectAll('.nv-noData').data([noData]); - - noDataText.enter().append('text') - .attr('class', 'nvd3 nv-noData') - .attr('dy', '-.7em') - .style('text-anchor', 'middle'); - - noDataText - .attr('x', margin.left + availableWidth / 2) - .attr('y', margin.top + availableHeight / 2) - .text(function(d) { return d }); - - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - // Setup Scales - x = boxplot.xScale(); - y = boxplot.yScale().clamp(true); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-boxPlotWithAxes').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-boxPlotWithAxes').append('g'); - var defsEnter = gEnter.append('defs'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-x nv-axis'); - gEnter.append('g').attr('class', 'nv-y nv-axis') - .append('g').attr('class', 'nv-zeroLine') - .append('line'); - - gEnter.append('g').attr('class', 'nv-barsWrap'); - - g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - if (rightAlignYAxis) { - g.select(".nv-y.nv-axis") - .attr("transform", "translate(" + availableWidth + ",0)"); - } - - // Main Chart Component(s) - boxplot - .width(availableWidth) - .height(availableHeight); - - var barsWrap = g.select('.nv-barsWrap') - .datum(data.filter(function(d) { return !d.disabled })) - - barsWrap.transition().call(boxplot); - - - defsEnter.append('clipPath') - .attr('id', 'nv-x-label-clip-' + boxplot.id()) - .append('rect'); - - g.select('#nv-x-label-clip-' + boxplot.id() + ' rect') - .attr('width', x.rangeBand() * (staggerLabels ? 2 : 1)) - .attr('height', 16) - .attr('x', -x.rangeBand() / (staggerLabels ? 1 : 2 )); - - // Setup Axes - if (showXAxis) { - xAxis - .scale(x) - .ticks( nv.utils.calcTicksX(availableWidth/100, data) ) - .tickSize(-availableHeight, 0); - - g.select('.nv-x.nv-axis').attr('transform', 'translate(0,' + y.range()[0] + ')'); - g.select('.nv-x.nv-axis').call(xAxis); - - var xTicks = g.select('.nv-x.nv-axis').selectAll('g'); - if (staggerLabels) { - xTicks - .selectAll('text') - .attr('transform', function(d,i,j) { return 'translate(0,' + (j % 2 == 0 ? '5' : '17') + ')' }) - } - } - - if (showYAxis) { - yAxis - .scale(y) - .ticks( Math.floor(availableHeight/36) ) // can't use nv.utils.calcTicksY with Object data - .tickSize( -availableWidth, 0); - - g.select('.nv-y.nv-axis').call(yAxis); - } - - // Zero line - g.select(".nv-zeroLine line") - .attr("x1",0) - .attr("x2",availableWidth) - .attr("y1", y(0)) - .attr("y2", y(0)) - ; - - //============================================================ - // Event Handling/Dispatching (in chart's scope) - //------------------------------------------------------------ - }); - - renderWatch.renderEnd('nv-boxplot chart immediate'); - return chart; - } - - //============================================================ - // Event Handling/Dispatching (out of chart's scope) - //------------------------------------------------------------ - - boxplot.dispatch.on('elementMouseover.tooltip', function(evt) { - tooltip.data(evt).hidden(false); - }); - - boxplot.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.data(evt).hidden(true); - }); - - boxplot.dispatch.on('elementMousemove.tooltip', function(evt) { - tooltip.position({top: d3.event.pageY, left: d3.event.pageX})(); - }); - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.boxplot = boxplot; - chart.xAxis = xAxis; - chart.yAxis = yAxis; - chart.tooltip = tooltip; - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - staggerLabels: {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}}, - showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}}, - showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}}, - tooltips: {get: function(){return tooltips;}, set: function(_){tooltips=_;}}, - tooltipContent: {get: function(){return tooltip;}, set: function(_){tooltip=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - boxplot.duration(duration); - xAxis.duration(duration); - yAxis.duration(duration); - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - boxplot.color(color); - }}, - rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){ - rightAlignYAxis = _; - yAxis.orient( (_) ? 'right' : 'left'); - }} - }); - - nv.utils.inheritOptions(chart, boxplot); - nv.utils.initOptions(chart); - - return chart; - } -// Chart design based on the recommendations of Stephen Few. Implementation -// based on the work of Clint Ivy, Jamie Love, and Jason Davies. -// http://projects.instantcognition.com/protovis/bulletchart/ - - nv.models.bullet = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , orient = 'left' // TODO top & bottom - , reverse = false - , ranges = function(d) { return d.ranges } - , markers = function(d) { return d.markers ? d.markers : [0] } - , measures = function(d) { return d.measures } - , rangeLabels = function(d) { return d.rangeLabels ? d.rangeLabels : [] } - , markerLabels = function(d) { return d.markerLabels ? d.markerLabels : [] } - , measureLabels = function(d) { return d.measureLabels ? d.measureLabels : [] } - , forceX = [0] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.) - , width = 380 - , height = 30 - , container = null - , tickFormat = null - , color = nv.utils.getColor(['#1f77b4']) - , dispatch = d3.dispatch('elementMouseover', 'elementMouseout', 'elementMousemove') - ; - - function chart(selection) { - selection.each(function(d, i) { - var availableWidth = width - margin.left - margin.right, - availableHeight = height - margin.top - margin.bottom; - - container = d3.select(this); - nv.utils.initSVG(container); - - var rangez = ranges.call(this, d, i).slice().sort(d3.descending), - markerz = markers.call(this, d, i).slice().sort(d3.descending), - measurez = measures.call(this, d, i).slice().sort(d3.descending), - rangeLabelz = rangeLabels.call(this, d, i).slice(), - markerLabelz = markerLabels.call(this, d, i).slice(), - measureLabelz = measureLabels.call(this, d, i).slice(); - - // Setup Scales - // Compute the new x-scale. - var x1 = d3.scale.linear() - .domain( d3.extent(d3.merge([forceX, rangez])) ) - .range(reverse ? [availableWidth, 0] : [0, availableWidth]); - - // Retrieve the old x-scale, if this is an update. - var x0 = this.__chart__ || d3.scale.linear() - .domain([0, Infinity]) - .range(x1.range()); - - // Stash the new scale. - this.__chart__ = x1; - - var rangeMin = d3.min(rangez), //rangez[2] - rangeMax = d3.max(rangez), //rangez[0] - rangeAvg = rangez[1]; - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-bullet').data([d]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-bullet'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - gEnter.append('rect').attr('class', 'nv-range nv-rangeMax'); - gEnter.append('rect').attr('class', 'nv-range nv-rangeAvg'); - gEnter.append('rect').attr('class', 'nv-range nv-rangeMin'); - gEnter.append('rect').attr('class', 'nv-measure'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - var w0 = function(d) { return Math.abs(x0(d) - x0(0)) }, // TODO: could optimize by precalculating x0(0) and x1(0) - w1 = function(d) { return Math.abs(x1(d) - x1(0)) }; - var xp0 = function(d) { return d < 0 ? x0(d) : x0(0) }, - xp1 = function(d) { return d < 0 ? x1(d) : x1(0) }; - - g.select('rect.nv-rangeMax') - .attr('height', availableHeight) - .attr('width', w1(rangeMax > 0 ? rangeMax : rangeMin)) - .attr('x', xp1(rangeMax > 0 ? rangeMax : rangeMin)) - .datum(rangeMax > 0 ? rangeMax : rangeMin) - - g.select('rect.nv-rangeAvg') - .attr('height', availableHeight) - .attr('width', w1(rangeAvg)) - .attr('x', xp1(rangeAvg)) - .datum(rangeAvg) - - g.select('rect.nv-rangeMin') - .attr('height', availableHeight) - .attr('width', w1(rangeMax)) - .attr('x', xp1(rangeMax)) - .attr('width', w1(rangeMax > 0 ? rangeMin : rangeMax)) - .attr('x', xp1(rangeMax > 0 ? rangeMin : rangeMax)) - .datum(rangeMax > 0 ? rangeMin : rangeMax) - - g.select('rect.nv-measure') - .style('fill', color) - .attr('height', availableHeight / 3) - .attr('y', availableHeight / 3) - .attr('width', measurez < 0 ? - x1(0) - x1(measurez[0]) - : x1(measurez[0]) - x1(0)) - .attr('x', xp1(measurez)) - .on('mouseover', function() { - dispatch.elementMouseover({ - value: measurez[0], - label: measureLabelz[0] || 'Current', - color: d3.select(this).style("fill") - }) - }) - .on('mousemove', function() { - dispatch.elementMousemove({ - value: measurez[0], - label: measureLabelz[0] || 'Current', - color: d3.select(this).style("fill") - }) - }) - .on('mouseout', function() { - dispatch.elementMouseout({ - value: measurez[0], - label: measureLabelz[0] || 'Current', - color: d3.select(this).style("fill") - }) - }); - - var h3 = availableHeight / 6; - - var markerData = markerz.map( function(marker, index) { - return {value: marker, label: markerLabelz[index]} - }); - gEnter - .selectAll("path.nv-markerTriangle") - .data(markerData) - .enter() - .append('path') - .attr('class', 'nv-markerTriangle') - .attr('transform', function(d) { return 'translate(' + x1(d.value) + ',' + (availableHeight / 2) + ')' }) - .attr('d', 'M0,' + h3 + 'L' + h3 + ',' + (-h3) + ' ' + (-h3) + ',' + (-h3) + 'Z') - .on('mouseover', function(d) { - dispatch.elementMouseover({ - value: d.value, - label: d.label || 'Previous', - color: d3.select(this).style("fill"), - pos: [x1(d.value), availableHeight/2] - }) - - }) - .on('mousemove', function(d) { - dispatch.elementMousemove({ - value: d.value, - label: d.label || 'Previous', - color: d3.select(this).style("fill") - }) - }) - .on('mouseout', function(d, i) { - dispatch.elementMouseout({ - value: d.value, - label: d.label || 'Previous', - color: d3.select(this).style("fill") - }) - }); - - wrap.selectAll('.nv-range') - .on('mouseover', function(d,i) { - var label = rangeLabelz[i] || (!i ? "Maximum" : i == 1 ? "Mean" : "Minimum"); - dispatch.elementMouseover({ - value: d, - label: label, - color: d3.select(this).style("fill") - }) - }) - .on('mousemove', function() { - dispatch.elementMousemove({ - value: measurez[0], - label: measureLabelz[0] || 'Previous', - color: d3.select(this).style("fill") - }) - }) - .on('mouseout', function(d,i) { - var label = rangeLabelz[i] || (!i ? "Maximum" : i == 1 ? "Mean" : "Minimum"); - dispatch.elementMouseout({ - value: d, - label: label, - color: d3.select(this).style("fill") - }) - }); - }); - - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - ranges: {get: function(){return ranges;}, set: function(_){ranges=_;}}, // ranges (bad, satisfactory, good) - markers: {get: function(){return markers;}, set: function(_){markers=_;}}, // markers (previous, goal) - measures: {get: function(){return measures;}, set: function(_){measures=_;}}, // measures (actual, forecast) - forceX: {get: function(){return forceX;}, set: function(_){forceX=_;}}, - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - tickFormat: {get: function(){return tickFormat;}, set: function(_){tickFormat=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - orient: {get: function(){return orient;}, set: function(_){ // left, right, top, bottom - orient = _; - reverse = orient == 'right' || orient == 'bottom'; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }} - }); - - nv.utils.initOptions(chart); - return chart; - }; - - - -// Chart design based on the recommendations of Stephen Few. Implementation -// based on the work of Clint Ivy, Jamie Love, and Jason Davies. -// http://projects.instantcognition.com/protovis/bulletchart/ - nv.models.bulletChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var bullet = nv.models.bullet(); - var tooltip = nv.models.tooltip(); - - var orient = 'left' // TODO top & bottom - , reverse = false - , margin = {top: 5, right: 40, bottom: 20, left: 120} - , ranges = function(d) { return d.ranges } - , markers = function(d) { return d.markers ? d.markers : [0] } - , measures = function(d) { return d.measures } - , width = null - , height = 55 - , tickFormat = null - , ticks = null - , noData = null - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide') - ; - - tooltip.duration(0).headerEnabled(false); - - function chart(selection) { - selection.each(function(d, i) { - var container = d3.select(this); - nv.utils.initSVG(container); - - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = height - margin.top - margin.bottom, - that = this; - - chart.update = function() { chart(selection) }; - chart.container = this; - - // Display No Data message if there's nothing to show. - if (!d || !ranges.call(this, d, i)) { - nv.utils.noData(chart, container) - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - var rangez = ranges.call(this, d, i).slice().sort(d3.descending), - markerz = markers.call(this, d, i).slice().sort(d3.descending), - measurez = measures.call(this, d, i).slice().sort(d3.descending); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-bulletChart').data([d]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-bulletChart'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-bulletWrap'); - gEnter.append('g').attr('class', 'nv-titles'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - // Compute the new x-scale. - var x1 = d3.scale.linear() - .domain([0, Math.max(rangez[0], markerz[0], measurez[0])]) // TODO: need to allow forceX and forceY, and xDomain, yDomain - .range(reverse ? [availableWidth, 0] : [0, availableWidth]); - - // Retrieve the old x-scale, if this is an update. - var x0 = this.__chart__ || d3.scale.linear() - .domain([0, Infinity]) - .range(x1.range()); - - // Stash the new scale. - this.__chart__ = x1; - - var w0 = function(d) { return Math.abs(x0(d) - x0(0)) }, // TODO: could optimize by precalculating x0(0) and x1(0) - w1 = function(d) { return Math.abs(x1(d) - x1(0)) }; - - var title = gEnter.select('.nv-titles').append('g') - .attr('text-anchor', 'end') - .attr('transform', 'translate(-6,' + (height - margin.top - margin.bottom) / 2 + ')'); - title.append('text') - .attr('class', 'nv-title') - .text(function(d) { return d.title; }); - - title.append('text') - .attr('class', 'nv-subtitle') - .attr('dy', '1em') - .text(function(d) { return d.subtitle; }); - - bullet - .width(availableWidth) - .height(availableHeight) - - var bulletWrap = g.select('.nv-bulletWrap'); - d3.transition(bulletWrap).call(bullet); - - // Compute the tick format. - var format = tickFormat || x1.tickFormat( availableWidth / 100 ); - - // Update the tick groups. - var tick = g.selectAll('g.nv-tick') - .data(x1.ticks( ticks ? ticks : (availableWidth / 50) ), function(d) { - return this.textContent || format(d); - }); - - // Initialize the ticks with the old scale, x0. - var tickEnter = tick.enter().append('g') - .attr('class', 'nv-tick') - .attr('transform', function(d) { return 'translate(' + x0(d) + ',0)' }) - .style('opacity', 1e-6); - - tickEnter.append('line') - .attr('y1', availableHeight) - .attr('y2', availableHeight * 7 / 6); - - tickEnter.append('text') - .attr('text-anchor', 'middle') - .attr('dy', '1em') - .attr('y', availableHeight * 7 / 6) - .text(format); - - // Transition the updating ticks to the new scale, x1. - var tickUpdate = d3.transition(tick) - .attr('transform', function(d) { return 'translate(' + x1(d) + ',0)' }) - .style('opacity', 1); - - tickUpdate.select('line') - .attr('y1', availableHeight) - .attr('y2', availableHeight * 7 / 6); - - tickUpdate.select('text') - .attr('y', availableHeight * 7 / 6); - - // Transition the exiting ticks to the new scale, x1. - d3.transition(tick.exit()) - .attr('transform', function(d) { return 'translate(' + x1(d) + ',0)' }) - .style('opacity', 1e-6) - .remove(); - }); - - d3.timer.flush(); - return chart; - } - - //============================================================ - // Event Handling/Dispatching (out of chart's scope) - //------------------------------------------------------------ - - bullet.dispatch.on('elementMouseover.tooltip', function(evt) { - evt['series'] = { - key: evt.label, - value: evt.value, - color: evt.color - }; - tooltip.data(evt).hidden(false); - }); - - bullet.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true); - }); - - bullet.dispatch.on('elementMousemove.tooltip', function(evt) { - tooltip.position({top: d3.event.pageY, left: d3.event.pageX})(); - }); - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.bullet = bullet; - chart.dispatch = dispatch; - chart.tooltip = tooltip; - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - ranges: {get: function(){return ranges;}, set: function(_){ranges=_;}}, // ranges (bad, satisfactory, good) - markers: {get: function(){return markers;}, set: function(_){markers=_;}}, // markers (previous, goal) - measures: {get: function(){return measures;}, set: function(_){measures=_;}}, // measures (actual, forecast) - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - tickFormat: {get: function(){return tickFormat;}, set: function(_){tickFormat=_;}}, - ticks: {get: function(){return ticks;}, set: function(_){ticks=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - - // deprecated options - tooltips: {get: function(){return tooltip.enabled();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltips', 'use chart.tooltip.enabled() instead'); - tooltip.enabled(!!_); - }}, - tooltipContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'use chart.tooltip.contentGenerator() instead'); - tooltip.contentGenerator(_); - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - orient: {get: function(){return orient;}, set: function(_){ // left, right, top, bottom - orient = _; - reverse = orient == 'right' || orient == 'bottom'; - }} - }); - - nv.utils.inheritOptions(chart, bullet); - nv.utils.initOptions(chart); - - return chart; - }; - - - - nv.models.candlestickBar = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = null - , height = null - , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one - , container - , x = d3.scale.linear() - , y = d3.scale.linear() - , getX = function(d) { return d.x } - , getY = function(d) { return d.y } - , getOpen = function(d) { return d.open } - , getClose = function(d) { return d.close } - , getHigh = function(d) { return d.high } - , getLow = function(d) { return d.low } - , forceX = [] - , forceY = [] - , padData = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart - , clipEdge = true - , color = nv.utils.defaultColor() - , interactive = false - , xDomain - , yDomain - , xRange - , yRange - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState', 'renderEnd', 'chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove') - ; - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - function chart(selection) { - selection.each(function(data) { - container = d3.select(this); - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - nv.utils.initSVG(container); - - // Width of the candlestick bars. - var barWidth = (availableWidth / data[0].values.length) * .45; - - // Setup Scales - x.domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) )); - - if (padData) - x.range(xRange || [availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5) / data[0].values.length ]); - else - x.range(xRange || [5 + barWidth / 2, availableWidth - barWidth / 2 - 5]); - - y.domain(yDomain || [ - d3.min(data[0].values.map(getLow).concat(forceY)), - d3.max(data[0].values.map(getHigh).concat(forceY)) - ] - ).range(yRange || [availableHeight, 0]); - - // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point - if (x.domain()[0] === x.domain()[1]) - x.domain()[0] ? - x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01]) - : x.domain([-1,1]); - - if (y.domain()[0] === y.domain()[1]) - y.domain()[0] ? - y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01]) - : y.domain([-1,1]); - - // Setup containers and skeleton of chart - var wrap = d3.select(this).selectAll('g.nv-wrap.nv-candlestickBar').data([data[0].values]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-candlestickBar'); - var defsEnter = wrapEnter.append('defs'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-ticks'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - container - .on('click', function(d,i) { - dispatch.chartClick({ - data: d, - index: i, - pos: d3.event, - id: id - }); - }); - - defsEnter.append('clipPath') - .attr('id', 'nv-chart-clip-path-' + id) - .append('rect'); - - wrap.select('#nv-chart-clip-path-' + id + ' rect') - .attr('width', availableWidth) - .attr('height', availableHeight); - - g .attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id + ')' : ''); - - var ticks = wrap.select('.nv-ticks').selectAll('.nv-tick') - .data(function(d) { return d }); - ticks.exit().remove(); - - // The colors are currently controlled by CSS. - var tickGroups = ticks.enter().append('g') - .attr('class', function(d, i, j) { return (getOpen(d, i) > getClose(d, i) ? 'nv-tick negative' : 'nv-tick positive') + ' nv-tick-' + j + '-' + i}); - - var lines = tickGroups.append('line') - .attr('class', 'nv-candlestick-lines') - .attr('transform', function(d, i) { return 'translate(' + x(getX(d, i)) + ',0)'; }) - .attr('x1', 0) - .attr('y1', function(d, i) { return y(getHigh(d, i)); }) - .attr('x2', 0) - .attr('y2', function(d, i) { return y(getLow(d, i)); }); - - var rects = tickGroups.append('rect') - .attr('class', 'nv-candlestick-rects nv-bars') - .attr('transform', function(d, i) { - return 'translate(' + (x(getX(d, i)) - barWidth/2) + ',' - + (y(getY(d, i)) - (getOpen(d, i) > getClose(d, i) ? (y(getClose(d, i)) - y(getOpen(d, i))) : 0)) - + ')'; - }) - .attr('x', 0) - .attr('y', 0) - .attr('width', barWidth) - .attr('height', function(d, i) { - var open = getOpen(d, i); - var close = getClose(d, i); - return open > close ? y(close) - y(open) : y(open) - y(close); - }); - - container.selectAll('.nv-candlestick-lines').transition() - .attr('transform', function(d, i) { return 'translate(' + x(getX(d, i)) + ',0)'; }) - .attr('x1', 0) - .attr('y1', function(d, i) { return y(getHigh(d, i)); }) - .attr('x2', 0) - .attr('y2', function(d, i) { return y(getLow(d, i)); }); - - container.selectAll('.nv-candlestick-rects').transition() - .attr('transform', function(d, i) { - return 'translate(' + (x(getX(d, i)) - barWidth/2) + ',' - + (y(getY(d, i)) - (getOpen(d, i) > getClose(d, i) ? (y(getClose(d, i)) - y(getOpen(d, i))) : 0)) - + ')'; - }) - .attr('x', 0) - .attr('y', 0) - .attr('width', barWidth) - .attr('height', function(d, i) { - var open = getOpen(d, i); - var close = getClose(d, i); - return open > close ? y(close) - y(open) : y(open) - y(close); - }); - }); - - return chart; - } - - - //Create methods to allow outside functions to highlight a specific bar. - chart.highlightPoint = function(pointIndex, isHoverOver) { - chart.clearHighlights(); - container.select(".nv-candlestickBar .nv-tick-0-" + pointIndex) - .classed("hover", isHoverOver) - ; - }; - - chart.clearHighlights = function() { - container.select(".nv-candlestickBar .nv-tick.hover") - .classed("hover", false) - ; - }; - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - xScale: {get: function(){return x;}, set: function(_){x=_;}}, - yScale: {get: function(){return y;}, set: function(_){y=_;}}, - xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}}, - yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}}, - xRange: {get: function(){return xRange;}, set: function(_){xRange=_;}}, - yRange: {get: function(){return yRange;}, set: function(_){yRange=_;}}, - forceX: {get: function(){return forceX;}, set: function(_){forceX=_;}}, - forceY: {get: function(){return forceY;}, set: function(_){forceY=_;}}, - padData: {get: function(){return padData;}, set: function(_){padData=_;}}, - clipEdge: {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}}, - id: {get: function(){return id;}, set: function(_){id=_;}}, - interactive: {get: function(){return interactive;}, set: function(_){interactive=_;}}, - - x: {get: function(){return getX;}, set: function(_){getX=_;}}, - y: {get: function(){return getY;}, set: function(_){getY=_;}}, - open: {get: function(){return getOpen();}, set: function(_){getOpen=_;}}, - close: {get: function(){return getClose();}, set: function(_){getClose=_;}}, - high: {get: function(){return getHigh;}, set: function(_){getHigh=_;}}, - low: {get: function(){return getLow;}, set: function(_){getLow=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top != undefined ? _.top : margin.top; - margin.right = _.right != undefined ? _.right : margin.right; - margin.bottom = _.bottom != undefined ? _.bottom : margin.bottom; - margin.left = _.left != undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }} - }); - - nv.utils.initOptions(chart); - return chart; - }; - - nv.models.cumulativeLineChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var lines = nv.models.line() - , xAxis = nv.models.axis() - , yAxis = nv.models.axis() - , legend = nv.models.legend() - , controls = nv.models.legend() - , interactiveLayer = nv.interactiveGuideline() - , tooltip = nv.models.tooltip() - ; - - var margin = {top: 30, right: 30, bottom: 50, left: 60} - , color = nv.utils.defaultColor() - , width = null - , height = null - , showLegend = true - , showXAxis = true - , showYAxis = true - , rightAlignYAxis = false - , showControls = true - , useInteractiveGuideline = false - , rescaleY = true - , x //can be accessed via chart.xScale() - , y //can be accessed via chart.yScale() - , id = lines.id() - , state = nv.utils.state() - , defaultState = null - , noData = null - , average = function(d) { return d.average } - , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd') - , transitionDuration = 250 - , duration = 250 - , noErrorCheck = false //if set to TRUE, will bypass an error check in the indexify function. - ; - - state.index = 0; - state.rescaleY = rescaleY; - - xAxis.orient('bottom').tickPadding(7); - yAxis.orient((rightAlignYAxis) ? 'right' : 'left'); - - tooltip.valueFormatter(function(d, i) { - return yAxis.tickFormat()(d, i); - }).headerFormatter(function(d, i) { - return xAxis.tickFormat()(d, i); - }); - - controls.updateState(false); - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var dx = d3.scale.linear() - , index = {i: 0, x: 0} - , renderWatch = nv.utils.renderWatch(dispatch, duration) - ; - - var stateGetter = function(data) { - return function(){ - return { - active: data.map(function(d) { return !d.disabled }), - index: index.i, - rescaleY: rescaleY - }; - } - }; - - var stateSetter = function(data) { - return function(state) { - if (state.index !== undefined) - index.i = state.index; - if (state.rescaleY !== undefined) - rescaleY = state.rescaleY; - if (state.active !== undefined) - data.forEach(function(series,i) { - series.disabled = !state.active[i]; - }); - } - }; - - function chart(selection) { - renderWatch.reset(); - renderWatch.models(lines); - if (showXAxis) renderWatch.models(xAxis); - if (showYAxis) renderWatch.models(yAxis); - selection.each(function(data) { - var container = d3.select(this); - nv.utils.initSVG(container); - container.classed('nv-chart-' + id, true); - var that = this; - - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - chart.update = function() { - if (duration === 0) - container.call(chart); - else - container.transition().duration(duration).call(chart) - }; - chart.container = this; - - state - .setter(stateSetter(data), chart.update) - .getter(stateGetter(data)) - .update(); - - // DEPRECATED set state.disableddisabled - state.disabled = data.map(function(d) { return !!d.disabled }); - - if (!defaultState) { - var key; - defaultState = {}; - for (key in state) { - if (state[key] instanceof Array) - defaultState[key] = state[key].slice(0); - else - defaultState[key] = state[key]; - } - } - - var indexDrag = d3.behavior.drag() - .on('dragstart', dragStart) - .on('drag', dragMove) - .on('dragend', dragEnd); - - - function dragStart(d,i) { - d3.select(chart.container) - .style('cursor', 'ew-resize'); - } - - function dragMove(d,i) { - index.x = d3.event.x; - index.i = Math.round(dx.invert(index.x)); - updateZero(); - } - - function dragEnd(d,i) { - d3.select(chart.container) - .style('cursor', 'auto'); - - // update state and send stateChange with new index - state.index = index.i; - dispatch.stateChange(state); - } - - // Display No Data message if there's nothing to show. - if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) { - nv.utils.noData(chart, container) - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - // Setup Scales - x = lines.xScale(); - y = lines.yScale(); - - if (!rescaleY) { - var seriesDomains = data - .filter(function(series) { return !series.disabled }) - .map(function(series,i) { - var initialDomain = d3.extent(series.values, lines.y()); - - //account for series being disabled when losing 95% or more - if (initialDomain[0] < -.95) initialDomain[0] = -.95; - - return [ - (initialDomain[0] - initialDomain[1]) / (1 + initialDomain[1]), - (initialDomain[1] - initialDomain[0]) / (1 + initialDomain[0]) - ]; - }); - - var completeDomain = [ - d3.min(seriesDomains, function(d) { return d[0] }), - d3.max(seriesDomains, function(d) { return d[1] }) - ]; - - lines.yDomain(completeDomain); - } else { - lines.yDomain(null); - } - - dx.domain([0, data[0].values.length - 1]) //Assumes all series have same length - .range([0, availableWidth]) - .clamp(true); - - var data = indexify(index.i, data); - - // Setup containers and skeleton of chart - var interactivePointerEvents = (useInteractiveGuideline) ? "none" : "all"; - var wrap = container.selectAll('g.nv-wrap.nv-cumulativeLine').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-cumulativeLine').append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-interactive'); - gEnter.append('g').attr('class', 'nv-x nv-axis').style("pointer-events","none"); - gEnter.append('g').attr('class', 'nv-y nv-axis'); - gEnter.append('g').attr('class', 'nv-background'); - gEnter.append('g').attr('class', 'nv-linesWrap').style("pointer-events",interactivePointerEvents); - gEnter.append('g').attr('class', 'nv-avgLinesWrap').style("pointer-events","none"); - gEnter.append('g').attr('class', 'nv-legendWrap'); - gEnter.append('g').attr('class', 'nv-controlsWrap'); - - // Legend - if (showLegend) { - legend.width(availableWidth); - - g.select('.nv-legendWrap') - .datum(data) - .call(legend); - - if ( margin.top != legend.height()) { - margin.top = legend.height(); - availableHeight = nv.utils.availableHeight(height, container, margin); - } - - g.select('.nv-legendWrap') - .attr('transform', 'translate(0,' + (-margin.top) +')') - } - - // Controls - if (showControls) { - var controlsData = [ - { key: 'Re-scale y-axis', disabled: !rescaleY } - ]; - - controls - .width(140) - .color(['#444', '#444', '#444']) - .rightAlign(false) - .margin({top: 5, right: 0, bottom: 5, left: 20}) - ; - - g.select('.nv-controlsWrap') - .datum(controlsData) - .attr('transform', 'translate(0,' + (-margin.top) +')') - .call(controls); - } - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - if (rightAlignYAxis) { - g.select(".nv-y.nv-axis") - .attr("transform", "translate(" + availableWidth + ",0)"); - } - - // Show error if series goes below 100% - var tempDisabled = data.filter(function(d) { return d.tempDisabled }); - - wrap.select('.tempDisabled').remove(); //clean-up and prevent duplicates - if (tempDisabled.length) { - wrap.append('text').attr('class', 'tempDisabled') - .attr('x', availableWidth / 2) - .attr('y', '-.71em') - .style('text-anchor', 'end') - .text(tempDisabled.map(function(d) { return d.key }).join(', ') + ' values cannot be calculated for this time period.'); - } - - //Set up interactive layer - if (useInteractiveGuideline) { - interactiveLayer - .width(availableWidth) - .height(availableHeight) - .margin({left:margin.left,top:margin.top}) - .svgContainer(container) - .xScale(x); - wrap.select(".nv-interactive").call(interactiveLayer); - } - - gEnter.select('.nv-background') - .append('rect'); - - g.select('.nv-background rect') - .attr('width', availableWidth) - .attr('height', availableHeight); - - lines - //.x(function(d) { return d.x }) - .y(function(d) { return d.display.y }) - .width(availableWidth) - .height(availableHeight) - .color(data.map(function(d,i) { - return d.color || color(d, i); - }).filter(function(d,i) { return !data[i].disabled && !data[i].tempDisabled; })); - - var linesWrap = g.select('.nv-linesWrap') - .datum(data.filter(function(d) { return !d.disabled && !d.tempDisabled })); - - linesWrap.call(lines); - - //Store a series index number in the data array. - data.forEach(function(d,i) { - d.seriesIndex = i; - }); - - var avgLineData = data.filter(function(d) { - return !d.disabled && !!average(d); - }); - - var avgLines = g.select(".nv-avgLinesWrap").selectAll("line") - .data(avgLineData, function(d) { return d.key; }); - - var getAvgLineY = function(d) { - //If average lines go off the svg element, clamp them to the svg bounds. - var yVal = y(average(d)); - if (yVal < 0) return 0; - if (yVal > availableHeight) return availableHeight; - return yVal; - }; - - avgLines.enter() - .append('line') - .style('stroke-width',2) - .style('stroke-dasharray','10,10') - .style('stroke',function (d,i) { - return lines.color()(d,d.seriesIndex); - }) - .attr('x1',0) - .attr('x2',availableWidth) - .attr('y1', getAvgLineY) - .attr('y2', getAvgLineY); - - avgLines - .style('stroke-opacity',function(d){ - //If average lines go offscreen, make them transparent - var yVal = y(average(d)); - if (yVal < 0 || yVal > availableHeight) return 0; - return 1; - }) - .attr('x1',0) - .attr('x2',availableWidth) - .attr('y1', getAvgLineY) - .attr('y2', getAvgLineY); - - avgLines.exit().remove(); - - //Create index line - var indexLine = linesWrap.selectAll('.nv-indexLine') - .data([index]); - indexLine.enter().append('rect').attr('class', 'nv-indexLine') - .attr('width', 3) - .attr('x', -2) - .attr('fill', 'red') - .attr('fill-opacity', .5) - .style("pointer-events","all") - .call(indexDrag); - - indexLine - .attr('transform', function(d) { return 'translate(' + dx(d.i) + ',0)' }) - .attr('height', availableHeight); - - // Setup Axes - if (showXAxis) { - xAxis - .scale(x) - ._ticks( nv.utils.calcTicksX(availableWidth/70, data) ) - .tickSize(-availableHeight, 0); - - g.select('.nv-x.nv-axis') - .attr('transform', 'translate(0,' + y.range()[0] + ')'); - g.select('.nv-x.nv-axis') - .call(xAxis); - } - - if (showYAxis) { - yAxis - .scale(y) - ._ticks( nv.utils.calcTicksY(availableHeight/36, data) ) - .tickSize( -availableWidth, 0); - - g.select('.nv-y.nv-axis') - .call(yAxis); - } - - //============================================================ - // Event Handling/Dispatching (in chart's scope) - //------------------------------------------------------------ - - function updateZero() { - indexLine - .data([index]); - - //When dragging the index line, turn off line transitions. - // Then turn them back on when done dragging. - var oldDuration = chart.duration(); - chart.duration(0); - chart.update(); - chart.duration(oldDuration); - } - - g.select('.nv-background rect') - .on('click', function() { - index.x = d3.mouse(this)[0]; - index.i = Math.round(dx.invert(index.x)); - - // update state and send stateChange with new index - state.index = index.i; - dispatch.stateChange(state); - - updateZero(); - }); - - lines.dispatch.on('elementClick', function(e) { - index.i = e.pointIndex; - index.x = dx(index.i); - - // update state and send stateChange with new index - state.index = index.i; - dispatch.stateChange(state); - - updateZero(); - }); - - controls.dispatch.on('legendClick', function(d,i) { - d.disabled = !d.disabled; - rescaleY = !d.disabled; - - state.rescaleY = rescaleY; - dispatch.stateChange(state); - chart.update(); - }); - - legend.dispatch.on('stateChange', function(newState) { - for (var key in newState) - state[key] = newState[key]; - dispatch.stateChange(state); - chart.update(); - }); - - interactiveLayer.dispatch.on('elementMousemove', function(e) { - lines.clearHighlights(); - var singlePoint, pointIndex, pointXLocation, allData = []; - - data - .filter(function(series, i) { - series.seriesIndex = i; - return !series.disabled; - }) - .forEach(function(series,i) { - pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x()); - lines.highlightPoint(i, pointIndex, true); - var point = series.values[pointIndex]; - if (typeof point === 'undefined') return; - if (typeof singlePoint === 'undefined') singlePoint = point; - if (typeof pointXLocation === 'undefined') pointXLocation = chart.xScale()(chart.x()(point,pointIndex)); - allData.push({ - key: series.key, - value: chart.y()(point, pointIndex), - color: color(series,series.seriesIndex) - }); - }); - - //Highlight the tooltip entry based on which point the mouse is closest to. - if (allData.length > 2) { - var yValue = chart.yScale().invert(e.mouseY); - var domainExtent = Math.abs(chart.yScale().domain()[0] - chart.yScale().domain()[1]); - var threshold = 0.03 * domainExtent; - var indexToHighlight = nv.nearestValueIndex(allData.map(function(d){return d.value}),yValue,threshold); - if (indexToHighlight !== null) - allData[indexToHighlight].highlight = true; - } - - var xValue = xAxis.tickFormat()(chart.x()(singlePoint,pointIndex), pointIndex); - interactiveLayer.tooltip - .position({left: pointXLocation + margin.left, top: e.mouseY + margin.top}) - .chartContainer(that.parentNode) - .valueFormatter(function(d,i) { - return yAxis.tickFormat()(d); - }) - .data( - { - value: xValue, - series: allData - } - )(); - - interactiveLayer.renderGuideLine(pointXLocation); - }); - - interactiveLayer.dispatch.on("elementMouseout",function(e) { - lines.clearHighlights(); - }); - - // Update chart from a state object passed to event handler - dispatch.on('changeState', function(e) { - if (typeof e.disabled !== 'undefined') { - data.forEach(function(series,i) { - series.disabled = e.disabled[i]; - }); - - state.disabled = e.disabled; - } - - if (typeof e.index !== 'undefined') { - index.i = e.index; - index.x = dx(index.i); - - state.index = e.index; - - indexLine - .data([index]); - } - - if (typeof e.rescaleY !== 'undefined') { - rescaleY = e.rescaleY; - } - - chart.update(); - }); - - }); - - renderWatch.renderEnd('cumulativeLineChart immediate'); - - return chart; - } - - //============================================================ - // Event Handling/Dispatching (out of chart's scope) - //------------------------------------------------------------ - - lines.dispatch.on('elementMouseover.tooltip', function(evt) { - var point = { - x: chart.x()(evt.point), - y: chart.y()(evt.point), - color: evt.point.color - }; - evt.point = point; - tooltip.data(evt).position(evt.pos).hidden(false); - }); - - lines.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true) - }); - - //============================================================ - // Functions - //------------------------------------------------------------ - - var indexifyYGetter = null; - /* Normalize the data according to an index point. */ - function indexify(idx, data) { - if (!indexifyYGetter) indexifyYGetter = lines.y(); - return data.map(function(line, i) { - if (!line.values) { - return line; - } - var indexValue = line.values[idx]; - if (indexValue == null) { - return line; - } - var v = indexifyYGetter(indexValue, idx); - - //TODO: implement check below, and disable series if series loses 100% or more cause divide by 0 issue - if (v < -.95 && !noErrorCheck) { - //if a series loses more than 100%, calculations fail.. anything close can cause major distortion (but is mathematically correct till it hits 100) - - line.tempDisabled = true; - return line; - } - - line.tempDisabled = false; - - line.values = line.values.map(function(point, pointIndex) { - point.display = {'y': (indexifyYGetter(point, pointIndex) - v) / (1 + v) }; - return point; - }); - - return line; - }) - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - // expose chart's sub-components - chart.dispatch = dispatch; - chart.lines = lines; - chart.legend = legend; - chart.controls = controls; - chart.xAxis = xAxis; - chart.yAxis = yAxis; - chart.interactiveLayer = interactiveLayer; - chart.state = state; - chart.tooltip = tooltip; - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - rescaleY: {get: function(){return rescaleY;}, set: function(_){rescaleY=_;}}, - showControls: {get: function(){return showControls;}, set: function(_){showControls=_;}}, - showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}}, - average: {get: function(){return average;}, set: function(_){average=_;}}, - defaultState: {get: function(){return defaultState;}, set: function(_){defaultState=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}}, - showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}}, - noErrorCheck: {get: function(){return noErrorCheck;}, set: function(_){noErrorCheck=_;}}, - - // deprecated options - tooltips: {get: function(){return tooltip.enabled();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltips', 'use chart.tooltip.enabled() instead'); - tooltip.enabled(!!_); - }}, - tooltipContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'use chart.tooltip.contentGenerator() instead'); - tooltip.contentGenerator(_); - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - legend.color(color); - }}, - useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){ - useInteractiveGuideline = _; - if (_ === true) { - chart.interactive(false); - chart.useVoronoi(false); - } - }}, - rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){ - rightAlignYAxis = _; - yAxis.orient( (_) ? 'right' : 'left'); - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - lines.duration(duration); - xAxis.duration(duration); - yAxis.duration(duration); - renderWatch.reset(duration); - }} - }); - - nv.utils.inheritOptions(chart, lines); - nv.utils.initOptions(chart); - - return chart; - }; -//TODO: consider deprecating by adding necessary features to multiBar model - nv.models.discreteBar = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = 960 - , height = 500 - , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one - , container - , x = d3.scale.ordinal() - , y = d3.scale.linear() - , getX = function(d) { return d.x } - , getY = function(d) { return d.y } - , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar graphs... user can always do chart.forceY([]) to remove - , color = nv.utils.defaultColor() - , showValues = false - , valueFormat = d3.format(',.2f') - , xDomain - , yDomain - , xRange - , yRange - , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd') - , rectClass = 'discreteBar' - , duration = 250 - ; - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var x0, y0; - var renderWatch = nv.utils.renderWatch(dispatch, duration); - - function chart(selection) { - renderWatch.reset(); - selection.each(function(data) { - var availableWidth = width - margin.left - margin.right, - availableHeight = height - margin.top - margin.bottom; - - container = d3.select(this); - nv.utils.initSVG(container); - - //add series index to each data point for reference - data.forEach(function(series, i) { - series.values.forEach(function(point) { - point.series = i; - }); - }); - - // Setup Scales - // remap and flatten the data for use in calculating the scales' domains - var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and yDomain, no need to calculate - data.map(function(d) { - return d.values.map(function(d,i) { - return { x: getX(d,i), y: getY(d,i), y0: d.y0 } - }) - }); - - x .domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x })) - .rangeBands(xRange || [0, availableWidth], .1); - y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return d.y }).concat(forceY))); - - // If showValues, pad the Y axis range to account for label height - if (showValues) y.range(yRange || [availableHeight - (y.domain()[0] < 0 ? 12 : 0), y.domain()[1] > 0 ? 12 : 0]); - else y.range(yRange || [availableHeight, 0]); - - //store old scales if they exist - x0 = x0 || x; - y0 = y0 || y.copy().range([y(0),y(0)]); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-discretebar').data([data]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-discretebar'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-groups'); - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - //TODO: by definition, the discrete bar should not have multiple groups, will modify/remove later - var groups = wrap.select('.nv-groups').selectAll('.nv-group') - .data(function(d) { return d }, function(d) { return d.key }); - groups.enter().append('g') - .style('stroke-opacity', 1e-6) - .style('fill-opacity', 1e-6); - groups.exit() - .watchTransition(renderWatch, 'discreteBar: exit groups') - .style('stroke-opacity', 1e-6) - .style('fill-opacity', 1e-6) - .remove(); - groups - .attr('class', function(d,i) { return 'nv-group nv-series-' + i }) - .classed('hover', function(d) { return d.hover }); - groups - .watchTransition(renderWatch, 'discreteBar: groups') - .style('stroke-opacity', 1) - .style('fill-opacity', .75); - - var bars = groups.selectAll('g.nv-bar') - .data(function(d) { return d.values }); - bars.exit().remove(); - - var barsEnter = bars.enter().append('g') - .attr('transform', function(d,i,j) { - return 'translate(' + (x(getX(d,i)) + x.rangeBand() * .05 ) + ', ' + y(0) + ')' - }) - .on('mouseover', function(d,i) { //TODO: figure out why j works above, but not here - d3.select(this).classed('hover', true); - dispatch.elementMouseover({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - }) - .on('mouseout', function(d,i) { - d3.select(this).classed('hover', false); - dispatch.elementMouseout({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - }) - .on('mousemove', function(d,i) { - dispatch.elementMousemove({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - }) - .on('click', function(d,i) { - dispatch.elementClick({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - d3.event.stopPropagation(); - }) - .on('dblclick', function(d,i) { - dispatch.elementDblClick({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - d3.event.stopPropagation(); - }); - - barsEnter.append('rect') - .attr('height', 0) - .attr('width', x.rangeBand() * .9 / data.length ) - - if (showValues) { - barsEnter.append('text') - .attr('text-anchor', 'middle') - ; - - bars.select('text') - .text(function(d,i) { return valueFormat(getY(d,i)) }) - .watchTransition(renderWatch, 'discreteBar: bars text') - .attr('x', x.rangeBand() * .9 / 2) - .attr('y', function(d,i) { return getY(d,i) < 0 ? y(getY(d,i)) - y(0) + 12 : -4 }) - - ; - } else { - bars.selectAll('text').remove(); - } - - bars - .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive' }) - .style('fill', function(d,i) { return d.color || color(d,i) }) - .style('stroke', function(d,i) { return d.color || color(d,i) }) - .select('rect') - .attr('class', rectClass) - .watchTransition(renderWatch, 'discreteBar: bars rect') - .attr('width', x.rangeBand() * .9 / data.length); - bars.watchTransition(renderWatch, 'discreteBar: bars') - //.delay(function(d,i) { return i * 1200 / data[0].values.length }) - .attr('transform', function(d,i) { - var left = x(getX(d,i)) + x.rangeBand() * .05, - top = getY(d,i) < 0 ? - y(0) : - y(0) - y(getY(d,i)) < 1 ? - y(0) - 1 : //make 1 px positive bars show up above y=0 - y(getY(d,i)); - - return 'translate(' + left + ', ' + top + ')' - }) - .select('rect') - .attr('height', function(d,i) { - return Math.max(Math.abs(y(getY(d,i)) - y((yDomain && yDomain[0]) || 0)) || 1) - }); - - - //store old scales for use in transitions on update - x0 = x.copy(); - y0 = y.copy(); - - }); - - renderWatch.renderEnd('discreteBar immediate'); - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - forceY: {get: function(){return forceY;}, set: function(_){forceY=_;}}, - showValues: {get: function(){return showValues;}, set: function(_){showValues=_;}}, - x: {get: function(){return getX;}, set: function(_){getX=_;}}, - y: {get: function(){return getY;}, set: function(_){getY=_;}}, - xScale: {get: function(){return x;}, set: function(_){x=_;}}, - yScale: {get: function(){return y;}, set: function(_){y=_;}}, - xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}}, - yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}}, - xRange: {get: function(){return xRange;}, set: function(_){xRange=_;}}, - yRange: {get: function(){return yRange;}, set: function(_){yRange=_;}}, - valueFormat: {get: function(){return valueFormat;}, set: function(_){valueFormat=_;}}, - id: {get: function(){return id;}, set: function(_){id=_;}}, - rectClass: {get: function(){return rectClass;}, set: function(_){rectClass=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - }} - }); - - nv.utils.initOptions(chart); - - return chart; - }; - - nv.models.discreteBarChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var discretebar = nv.models.discreteBar() - , xAxis = nv.models.axis() - , yAxis = nv.models.axis() - , tooltip = nv.models.tooltip() - ; - - var margin = {top: 15, right: 10, bottom: 50, left: 60} - , width = null - , height = null - , color = nv.utils.getColor() - , showXAxis = true - , showYAxis = true - , rightAlignYAxis = false - , staggerLabels = false - , x - , y - , noData = null - , dispatch = d3.dispatch('beforeUpdate','renderEnd') - , duration = 250 - ; - - xAxis - .orient('bottom') - .showMaxMin(false) - .tickFormat(function(d) { return d }) - ; - yAxis - .orient((rightAlignYAxis) ? 'right' : 'left') - .tickFormat(d3.format(',.1f')) - ; - - tooltip - .duration(0) - .headerEnabled(false) - .valueFormatter(function(d, i) { - return yAxis.tickFormat()(d, i); - }) - .keyFormatter(function(d, i) { - return xAxis.tickFormat()(d, i); - }); - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var renderWatch = nv.utils.renderWatch(dispatch, duration); - - function chart(selection) { - renderWatch.reset(); - renderWatch.models(discretebar); - if (showXAxis) renderWatch.models(xAxis); - if (showYAxis) renderWatch.models(yAxis); - - selection.each(function(data) { - var container = d3.select(this), - that = this; - nv.utils.initSVG(container); - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - chart.update = function() { - dispatch.beforeUpdate(); - container.transition().duration(duration).call(chart); - }; - chart.container = this; - - // Display No Data message if there's nothing to show. - if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) { - nv.utils.noData(chart, container); - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - // Setup Scales - x = discretebar.xScale(); - y = discretebar.yScale().clamp(true); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-discreteBarWithAxes').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-discreteBarWithAxes').append('g'); - var defsEnter = gEnter.append('defs'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-x nv-axis'); - gEnter.append('g').attr('class', 'nv-y nv-axis') - .append('g').attr('class', 'nv-zeroLine') - .append('line'); - - gEnter.append('g').attr('class', 'nv-barsWrap'); - - g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - if (rightAlignYAxis) { - g.select(".nv-y.nv-axis") - .attr("transform", "translate(" + availableWidth + ",0)"); - } - - // Main Chart Component(s) - discretebar - .width(availableWidth) - .height(availableHeight); - - var barsWrap = g.select('.nv-barsWrap') - .datum(data.filter(function(d) { return !d.disabled })); - - barsWrap.transition().call(discretebar); - - - defsEnter.append('clipPath') - .attr('id', 'nv-x-label-clip-' + discretebar.id()) - .append('rect'); - - g.select('#nv-x-label-clip-' + discretebar.id() + ' rect') - .attr('width', x.rangeBand() * (staggerLabels ? 2 : 1)) - .attr('height', 16) - .attr('x', -x.rangeBand() / (staggerLabels ? 1 : 2 )); - - // Setup Axes - if (showXAxis) { - xAxis - .scale(x) - ._ticks( nv.utils.calcTicksX(availableWidth/100, data) ) - .tickSize(-availableHeight, 0); - - g.select('.nv-x.nv-axis') - .attr('transform', 'translate(0,' + (y.range()[0] + ((discretebar.showValues() && y.domain()[0] < 0) ? 16 : 0)) + ')'); - g.select('.nv-x.nv-axis').call(xAxis); - - var xTicks = g.select('.nv-x.nv-axis').selectAll('g'); - if (staggerLabels) { - xTicks - .selectAll('text') - .attr('transform', function(d,i,j) { return 'translate(0,' + (j % 2 == 0 ? '5' : '17') + ')' }) - } - } - - if (showYAxis) { - yAxis - .scale(y) - ._ticks( nv.utils.calcTicksY(availableHeight/36, data) ) - .tickSize( -availableWidth, 0); - - g.select('.nv-y.nv-axis').call(yAxis); - } - - // Zero line - g.select(".nv-zeroLine line") - .attr("x1",0) - .attr("x2",availableWidth) - .attr("y1", y(0)) - .attr("y2", y(0)) - ; - }); - - renderWatch.renderEnd('discreteBar chart immediate'); - return chart; - } - - //============================================================ - // Event Handling/Dispatching (out of chart's scope) - //------------------------------------------------------------ - - discretebar.dispatch.on('elementMouseover.tooltip', function(evt) { - evt['series'] = { - key: chart.x()(evt.data), - value: chart.y()(evt.data), - color: evt.color - }; - tooltip.data(evt).hidden(false); - }); - - discretebar.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true); - }); - - discretebar.dispatch.on('elementMousemove.tooltip', function(evt) { - tooltip.position({top: d3.event.pageY, left: d3.event.pageX})(); - }); - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.discretebar = discretebar; - chart.xAxis = xAxis; - chart.yAxis = yAxis; - chart.tooltip = tooltip; - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - staggerLabels: {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}}, - showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}}, - showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - - // deprecated options - tooltips: {get: function(){return tooltip.enabled();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltips', 'use chart.tooltip.enabled() instead'); - tooltip.enabled(!!_); - }}, - tooltipContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'use chart.tooltip.contentGenerator() instead'); - tooltip.contentGenerator(_); - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - discretebar.duration(duration); - xAxis.duration(duration); - yAxis.duration(duration); - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - discretebar.color(color); - }}, - rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){ - rightAlignYAxis = _; - yAxis.orient( (_) ? 'right' : 'left'); - }} - }); - - nv.utils.inheritOptions(chart, discretebar); - nv.utils.initOptions(chart); - - return chart; - } - - nv.models.distribution = function() { - "use strict"; - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = 400 //technically width or height depending on x or y.... - , size = 8 - , axis = 'x' // 'x' or 'y'... horizontal or vertical - , getData = function(d) { return d[axis] } // defaults d.x or d.y - , color = nv.utils.defaultColor() - , scale = d3.scale.linear() - , domain - , duration = 250 - , dispatch = d3.dispatch('renderEnd') - ; - - //============================================================ - - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var scale0; - var renderWatch = nv.utils.renderWatch(dispatch, duration); - - //============================================================ - - - function chart(selection) { - renderWatch.reset(); - selection.each(function(data) { - var availableLength = width - (axis === 'x' ? margin.left + margin.right : margin.top + margin.bottom), - naxis = axis == 'x' ? 'y' : 'x', - container = d3.select(this); - nv.utils.initSVG(container); - - //------------------------------------------------------------ - // Setup Scales - - scale0 = scale0 || scale; - - //------------------------------------------------------------ - - - //------------------------------------------------------------ - // Setup containers and skeleton of chart - - var wrap = container.selectAll('g.nv-distribution').data([data]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-distribution'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')') - - //------------------------------------------------------------ - - - var distWrap = g.selectAll('g.nv-dist') - .data(function(d) { return d }, function(d) { return d.key }); - - distWrap.enter().append('g'); - distWrap - .attr('class', function(d,i) { return 'nv-dist nv-series-' + i }) - .style('stroke', function(d,i) { return color(d, i) }); - - var dist = distWrap.selectAll('line.nv-dist' + axis) - .data(function(d) { return d.values }) - dist.enter().append('line') - .attr(axis + '1', function(d,i) { return scale0(getData(d,i)) }) - .attr(axis + '2', function(d,i) { return scale0(getData(d,i)) }) - renderWatch.transition(distWrap.exit().selectAll('line.nv-dist' + axis), 'dist exit') - // .transition() - .attr(axis + '1', function(d,i) { return scale(getData(d,i)) }) - .attr(axis + '2', function(d,i) { return scale(getData(d,i)) }) - .style('stroke-opacity', 0) - .remove(); - dist - .attr('class', function(d,i) { return 'nv-dist' + axis + ' nv-dist' + axis + '-' + i }) - .attr(naxis + '1', 0) - .attr(naxis + '2', size); - renderWatch.transition(dist, 'dist') - // .transition() - .attr(axis + '1', function(d,i) { return scale(getData(d,i)) }) - .attr(axis + '2', function(d,i) { return scale(getData(d,i)) }) - - - scale0 = scale.copy(); - - }); - renderWatch.renderEnd('distribution immediate'); - return chart; - } - - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - chart.options = nv.utils.optionsFunc.bind(chart); - chart.dispatch = dispatch; - - chart.margin = function(_) { - if (!arguments.length) return margin; - margin.top = typeof _.top != 'undefined' ? _.top : margin.top; - margin.right = typeof _.right != 'undefined' ? _.right : margin.right; - margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom; - margin.left = typeof _.left != 'undefined' ? _.left : margin.left; - return chart; - }; - - chart.width = function(_) { - if (!arguments.length) return width; - width = _; - return chart; - }; - - chart.axis = function(_) { - if (!arguments.length) return axis; - axis = _; - return chart; - }; - - chart.size = function(_) { - if (!arguments.length) return size; - size = _; - return chart; - }; - - chart.getData = function(_) { - if (!arguments.length) return getData; - getData = d3.functor(_); - return chart; - }; - - chart.scale = function(_) { - if (!arguments.length) return scale; - scale = _; - return chart; - }; - - chart.color = function(_) { - if (!arguments.length) return color; - color = nv.utils.getColor(_); - return chart; - }; - - chart.duration = function(_) { - if (!arguments.length) return duration; - duration = _; - renderWatch.reset(duration); - return chart; - }; - //============================================================ - - - return chart; - } - nv.models.furiousLegend = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 5, right: 0, bottom: 5, left: 0} - , width = 400 - , height = 20 - , getKey = function(d) { return d.key } - , color = nv.utils.getColor() - , align = true - , padding = 28 //define how much space between legend items. - recommend 32 for furious version - , rightAlign = true - , updateState = true //If true, legend will update data.disabled and trigger a 'stateChange' dispatch. - , radioButtonMode = false //If true, clicking legend items will cause it to behave like a radio button. (only one can be selected at a time) - , expanded = false - , dispatch = d3.dispatch('legendClick', 'legendDblclick', 'legendMouseover', 'legendMouseout', 'stateChange') - , vers = 'classic' //Options are "classic" and "furious" - ; - - function chart(selection) { - selection.each(function(data) { - var availableWidth = width - margin.left - margin.right, - container = d3.select(this); - nv.utils.initSVG(container); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-legend').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-legend').append('g'); - var g = wrap.select('g'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - var series = g.selectAll('.nv-series') - .data(function(d) { - if(vers != 'furious') return d; - - return d.filter(function(n) { - return expanded ? true : !n.disengaged; - }); - }); - var seriesEnter = series.enter().append('g').attr('class', 'nv-series') - - var seriesShape; - - if(vers == 'classic') { - seriesEnter.append('circle') - .style('stroke-width', 2) - .attr('class','nv-legend-symbol') - .attr('r', 5); - - seriesShape = series.select('circle'); - } else if (vers == 'furious') { - seriesEnter.append('rect') - .style('stroke-width', 2) - .attr('class','nv-legend-symbol') - .attr('rx', 3) - .attr('ry', 3); - - seriesShape = series.select('rect'); - - seriesEnter.append('g') - .attr('class', 'nv-check-box') - .property('innerHTML','') - .attr('transform', 'translate(-10,-8)scale(0.5)'); - - var seriesCheckbox = series.select('.nv-check-box'); - - seriesCheckbox.each(function(d,i) { - d3.select(this).selectAll('path') - .attr('stroke', setTextColor(d,i)); - }); - } - - seriesEnter.append('text') - .attr('text-anchor', 'start') - .attr('class','nv-legend-text') - .attr('dy', '.32em') - .attr('dx', '8'); - - var seriesText = series.select('text.nv-legend-text'); - - series - .on('mouseover', function(d,i) { - dispatch.legendMouseover(d,i); //TODO: Make consistent with other event objects - }) - .on('mouseout', function(d,i) { - dispatch.legendMouseout(d,i); - }) - .on('click', function(d,i) { - dispatch.legendClick(d,i); - // make sure we re-get data in case it was modified - var data = series.data(); - if (updateState) { - if(vers =='classic') { - if (radioButtonMode) { - //Radio button mode: set every series to disabled, - // and enable the clicked series. - data.forEach(function(series) { series.disabled = true}); - d.disabled = false; - } - else { - d.disabled = !d.disabled; - if (data.every(function(series) { return series.disabled})) { - //the default behavior of NVD3 legends is, if every single series - // is disabled, turn all series' back on. - data.forEach(function(series) { series.disabled = false}); - } - } - } else if(vers == 'furious') { - if(expanded) { - d.disengaged = !d.disengaged; - d.userDisabled = d.userDisabled == undefined ? !!d.disabled : d.userDisabled; - d.disabled = d.disengaged || d.userDisabled; - } else if (!expanded) { - d.disabled = !d.disabled; - d.userDisabled = d.disabled; - var engaged = data.filter(function(d) { return !d.disengaged; }); - if (engaged.every(function(series) { return series.userDisabled })) { - //the default behavior of NVD3 legends is, if every single series - // is disabled, turn all series' back on. - data.forEach(function(series) { - series.disabled = series.userDisabled = false; - }); - } - } - } - dispatch.stateChange({ - disabled: data.map(function(d) { return !!d.disabled }), - disengaged: data.map(function(d) { return !!d.disengaged }) - }); - - } - }) - .on('dblclick', function(d,i) { - if(vers == 'furious' && expanded) return; - dispatch.legendDblclick(d,i); - if (updateState) { - // make sure we re-get data in case it was modified - var data = series.data(); - //the default behavior of NVD3 legends, when double clicking one, - // is to set all other series' to false, and make the double clicked series enabled. - data.forEach(function(series) { - series.disabled = true; - if(vers == 'furious') series.userDisabled = series.disabled; - }); - d.disabled = false; - if(vers == 'furious') d.userDisabled = d.disabled; - dispatch.stateChange({ - disabled: data.map(function(d) { return !!d.disabled }) - }); - } - }); - - series.classed('nv-disabled', function(d) { return d.userDisabled }); - series.exit().remove(); - - seriesText - .attr('fill', setTextColor) - .text(getKey); - - //TODO: implement fixed-width and max-width options (max-width is especially useful with the align option) - // NEW ALIGNING CODE, TODO: clean up - - var versPadding; - switch(vers) { - case 'furious' : - versPadding = 23; - break; - case 'classic' : - versPadding = 20; - } - - if (align) { - - var seriesWidths = []; - series.each(function(d,i) { - var legendText = d3.select(this).select('text'); - var nodeTextLength; - try { - nodeTextLength = legendText.node().getComputedTextLength(); - // If the legendText is display:none'd (nodeTextLength == 0), simulate an error so we approximate, instead - if(nodeTextLength <= 0) throw Error(); - } - catch(e) { - nodeTextLength = nv.utils.calcApproxTextWidth(legendText); - } - - seriesWidths.push(nodeTextLength + padding); - }); - - var seriesPerRow = 0; - var legendWidth = 0; - var columnWidths = []; - - while ( legendWidth < availableWidth && seriesPerRow < seriesWidths.length) { - columnWidths[seriesPerRow] = seriesWidths[seriesPerRow]; - legendWidth += seriesWidths[seriesPerRow++]; - } - if (seriesPerRow === 0) seriesPerRow = 1; //minimum of one series per row - - while ( legendWidth > availableWidth && seriesPerRow > 1 ) { - columnWidths = []; - seriesPerRow--; - - for (var k = 0; k < seriesWidths.length; k++) { - if (seriesWidths[k] > (columnWidths[k % seriesPerRow] || 0) ) - columnWidths[k % seriesPerRow] = seriesWidths[k]; - } - - legendWidth = columnWidths.reduce(function(prev, cur, index, array) { - return prev + cur; - }); - } - - var xPositions = []; - for (var i = 0, curX = 0; i < seriesPerRow; i++) { - xPositions[i] = curX; - curX += columnWidths[i]; - } - - series - .attr('transform', function(d, i) { - return 'translate(' + xPositions[i % seriesPerRow] + ',' + (5 + Math.floor(i / seriesPerRow) * versPadding) + ')'; - }); - - //position legend as far right as possible within the total width - if (rightAlign) { - g.attr('transform', 'translate(' + (width - margin.right - legendWidth) + ',' + margin.top + ')'); - } - else { - g.attr('transform', 'translate(0' + ',' + margin.top + ')'); - } - - height = margin.top + margin.bottom + (Math.ceil(seriesWidths.length / seriesPerRow) * versPadding); - - } else { - - var ypos = 5, - newxpos = 5, - maxwidth = 0, - xpos; - series - .attr('transform', function(d, i) { - var length = d3.select(this).select('text').node().getComputedTextLength() + padding; - xpos = newxpos; - - if (width < margin.left + margin.right + xpos + length) { - newxpos = xpos = 5; - ypos += versPadding; - } - - newxpos += length; - if (newxpos > maxwidth) maxwidth = newxpos; - - return 'translate(' + xpos + ',' + ypos + ')'; - }); - - //position legend as far right as possible within the total width - g.attr('transform', 'translate(' + (width - margin.right - maxwidth) + ',' + margin.top + ')'); - - height = margin.top + margin.bottom + ypos + 15; - } - - if(vers == 'furious') { - // Size rectangles after text is placed - seriesShape - .attr('width', function(d,i) { - return seriesText[0][i].getComputedTextLength() + 27; - }) - .attr('height', 18) - .attr('y', -9) - .attr('x', -15) - } - - seriesShape - .style('fill', setBGColor) - .style('stroke', function(d,i) { return d.color || color(d, i) }); - }); - - function setTextColor(d,i) { - if(vers != 'furious') return '#000'; - if(expanded) { - return d.disengaged ? color(d,i) : '#fff'; - } else if (!expanded) { - return !!d.disabled ? color(d,i) : '#fff'; - } - } - - function setBGColor(d,i) { - if(expanded && vers == 'furious') { - return d.disengaged ? '#fff' : color(d,i); - } else { - return !!d.disabled ? '#fff' : color(d,i); - } - } - - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - key: {get: function(){return getKey;}, set: function(_){getKey=_;}}, - align: {get: function(){return align;}, set: function(_){align=_;}}, - rightAlign: {get: function(){return rightAlign;}, set: function(_){rightAlign=_;}}, - padding: {get: function(){return padding;}, set: function(_){padding=_;}}, - updateState: {get: function(){return updateState;}, set: function(_){updateState=_;}}, - radioButtonMode: {get: function(){return radioButtonMode;}, set: function(_){radioButtonMode=_;}}, - expanded: {get: function(){return expanded;}, set: function(_){expanded=_;}}, - vers: {get: function(){return vers;}, set: function(_){vers=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }} - }); - - nv.utils.initOptions(chart); - - return chart; - }; -//TODO: consider deprecating and using multibar with single series for this - nv.models.historicalBar = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = null - , height = null - , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one - , container = null - , x = d3.scale.linear() - , y = d3.scale.linear() - , getX = function(d) { return d.x } - , getY = function(d) { return d.y } - , forceX = [] - , forceY = [0] - , padData = false - , clipEdge = true - , color = nv.utils.defaultColor() - , xDomain - , yDomain - , xRange - , yRange - , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd') - , interactive = true - ; - - var renderWatch = nv.utils.renderWatch(dispatch, 0); - - function chart(selection) { - selection.each(function(data) { - renderWatch.reset(); - - container = d3.select(this); - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - nv.utils.initSVG(container); - - // Setup Scales - x.domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) )); - - if (padData) - x.range(xRange || [availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5) / data[0].values.length ]); - else - x.range(xRange || [0, availableWidth]); - - y.domain(yDomain || d3.extent(data[0].values.map(getY).concat(forceY) )) - .range(yRange || [availableHeight, 0]); - - // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point - if (x.domain()[0] === x.domain()[1]) - x.domain()[0] ? - x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01]) - : x.domain([-1,1]); - - if (y.domain()[0] === y.domain()[1]) - y.domain()[0] ? - y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01]) - : y.domain([-1,1]); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-historicalBar-' + id).data([data[0].values]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-historicalBar-' + id); - var defsEnter = wrapEnter.append('defs'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-bars'); - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - container - .on('click', function(d,i) { - dispatch.chartClick({ - data: d, - index: i, - pos: d3.event, - id: id - }); - }); - - defsEnter.append('clipPath') - .attr('id', 'nv-chart-clip-path-' + id) - .append('rect'); - - wrap.select('#nv-chart-clip-path-' + id + ' rect') - .attr('width', availableWidth) - .attr('height', availableHeight); - - g.attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id + ')' : ''); - - var bars = wrap.select('.nv-bars').selectAll('.nv-bar') - .data(function(d) { return d }, function(d,i) {return getX(d,i)}); - bars.exit().remove(); - - bars.enter().append('rect') - .attr('x', 0 ) - .attr('y', function(d,i) { return nv.utils.NaNtoZero(y(Math.max(0, getY(d,i)))) }) - .attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.abs(y(getY(d,i)) - y(0))) }) - .attr('transform', function(d,i) { return 'translate(' + (x(getX(d,i)) - availableWidth / data[0].values.length * .45) + ',0)'; }) - .on('mouseover', function(d,i) { - if (!interactive) return; - d3.select(this).classed('hover', true); - dispatch.elementMouseover({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - - }) - .on('mouseout', function(d,i) { - if (!interactive) return; - d3.select(this).classed('hover', false); - dispatch.elementMouseout({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - }) - .on('mousemove', function(d,i) { - if (!interactive) return; - dispatch.elementMousemove({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - }) - .on('click', function(d,i) { - if (!interactive) return; - dispatch.elementClick({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - d3.event.stopPropagation(); - }) - .on('dblclick', function(d,i) { - if (!interactive) return; - dispatch.elementDblClick({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - d3.event.stopPropagation(); - }); - - bars - .attr('fill', function(d,i) { return color(d, i); }) - .attr('class', function(d,i,j) { return (getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive') + ' nv-bar-' + j + '-' + i }) - .watchTransition(renderWatch, 'bars') - .attr('transform', function(d,i) { return 'translate(' + (x(getX(d,i)) - availableWidth / data[0].values.length * .45) + ',0)'; }) - //TODO: better width calculations that don't assume always uniform data spacing;w - .attr('width', (availableWidth / data[0].values.length) * .9 ); - - bars.watchTransition(renderWatch, 'bars') - .attr('y', function(d,i) { - var rval = getY(d,i) < 0 ? - y(0) : - y(0) - y(getY(d,i)) < 1 ? - y(0) - 1 : - y(getY(d,i)); - return nv.utils.NaNtoZero(rval); - }) - .attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.max(Math.abs(y(getY(d,i)) - y(0)),1)) }); - - }); - - renderWatch.renderEnd('historicalBar immediate'); - return chart; - } - - //Create methods to allow outside functions to highlight a specific bar. - chart.highlightPoint = function(pointIndex, isHoverOver) { - container - .select(".nv-bars .nv-bar-0-" + pointIndex) - .classed("hover", isHoverOver) - ; - }; - - chart.clearHighlights = function() { - container - .select(".nv-bars .nv-bar.hover") - .classed("hover", false) - ; - }; - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - forceX: {get: function(){return forceX;}, set: function(_){forceX=_;}}, - forceY: {get: function(){return forceY;}, set: function(_){forceY=_;}}, - padData: {get: function(){return padData;}, set: function(_){padData=_;}}, - x: {get: function(){return getX;}, set: function(_){getX=_;}}, - y: {get: function(){return getY;}, set: function(_){getY=_;}}, - xScale: {get: function(){return x;}, set: function(_){x=_;}}, - yScale: {get: function(){return y;}, set: function(_){y=_;}}, - xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}}, - yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}}, - xRange: {get: function(){return xRange;}, set: function(_){xRange=_;}}, - yRange: {get: function(){return yRange;}, set: function(_){yRange=_;}}, - clipEdge: {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}}, - id: {get: function(){return id;}, set: function(_){id=_;}}, - interactive: {get: function(){return interactive;}, set: function(_){interactive=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }} - }); - - nv.utils.initOptions(chart); - - return chart; - }; - - nv.models.historicalBarChart = function(bar_model) { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var bars = bar_model || nv.models.historicalBar() - , xAxis = nv.models.axis() - , yAxis = nv.models.axis() - , legend = nv.models.legend() - , interactiveLayer = nv.interactiveGuideline() - , tooltip = nv.models.tooltip() - ; - - - var margin = {top: 30, right: 90, bottom: 50, left: 90} - , color = nv.utils.defaultColor() - , width = null - , height = null - , showLegend = false - , showXAxis = true - , showYAxis = true - , rightAlignYAxis = false - , useInteractiveGuideline = false - , x - , y - , state = {} - , defaultState = null - , noData = null - , dispatch = d3.dispatch('tooltipHide', 'stateChange', 'changeState', 'renderEnd') - , transitionDuration = 250 - ; - - xAxis.orient('bottom').tickPadding(7); - yAxis.orient( (rightAlignYAxis) ? 'right' : 'left'); - tooltip - .duration(0) - .headerEnabled(false) - .valueFormatter(function(d, i) { - return yAxis.tickFormat()(d, i); - }) - .headerFormatter(function(d, i) { - return xAxis.tickFormat()(d, i); - }); - - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var renderWatch = nv.utils.renderWatch(dispatch, 0); - - function chart(selection) { - selection.each(function(data) { - renderWatch.reset(); - renderWatch.models(bars); - if (showXAxis) renderWatch.models(xAxis); - if (showYAxis) renderWatch.models(yAxis); - - var container = d3.select(this), - that = this; - nv.utils.initSVG(container); - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - chart.update = function() { container.transition().duration(transitionDuration).call(chart) }; - chart.container = this; - - //set state.disabled - state.disabled = data.map(function(d) { return !!d.disabled }); - - if (!defaultState) { - var key; - defaultState = {}; - for (key in state) { - if (state[key] instanceof Array) - defaultState[key] = state[key].slice(0); - else - defaultState[key] = state[key]; - } - } - - // Display noData message if there's nothing to show. - if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) { - nv.utils.noData(chart, container) - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - // Setup Scales - x = bars.xScale(); - y = bars.yScale(); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-historicalBarChart').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-historicalBarChart').append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-x nv-axis'); - gEnter.append('g').attr('class', 'nv-y nv-axis'); - gEnter.append('g').attr('class', 'nv-barsWrap'); - gEnter.append('g').attr('class', 'nv-legendWrap'); - gEnter.append('g').attr('class', 'nv-interactive'); - - // Legend - if (showLegend) { - legend.width(availableWidth); - - g.select('.nv-legendWrap') - .datum(data) - .call(legend); - - if ( margin.top != legend.height()) { - margin.top = legend.height(); - availableHeight = nv.utils.availableHeight(height, container, margin); - } - - wrap.select('.nv-legendWrap') - .attr('transform', 'translate(0,' + (-margin.top) +')') - } - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - if (rightAlignYAxis) { - g.select(".nv-y.nv-axis") - .attr("transform", "translate(" + availableWidth + ",0)"); - } - - //Set up interactive layer - if (useInteractiveGuideline) { - interactiveLayer - .width(availableWidth) - .height(availableHeight) - .margin({left:margin.left, top:margin.top}) - .svgContainer(container) - .xScale(x); - wrap.select(".nv-interactive").call(interactiveLayer); - } - bars - .width(availableWidth) - .height(availableHeight) - .color(data.map(function(d,i) { - return d.color || color(d, i); - }).filter(function(d,i) { return !data[i].disabled })); - - var barsWrap = g.select('.nv-barsWrap') - .datum(data.filter(function(d) { return !d.disabled })); - barsWrap.transition().call(bars); - - // Setup Axes - if (showXAxis) { - xAxis - .scale(x) - ._ticks( nv.utils.calcTicksX(availableWidth/100, data) ) - .tickSize(-availableHeight, 0); - - g.select('.nv-x.nv-axis') - .attr('transform', 'translate(0,' + y.range()[0] + ')'); - g.select('.nv-x.nv-axis') - .transition() - .call(xAxis); - } - - if (showYAxis) { - yAxis - .scale(y) - ._ticks( nv.utils.calcTicksY(availableHeight/36, data) ) - .tickSize( -availableWidth, 0); - - g.select('.nv-y.nv-axis') - .transition() - .call(yAxis); - } - - //============================================================ - // Event Handling/Dispatching (in chart's scope) - //------------------------------------------------------------ - - interactiveLayer.dispatch.on('elementMousemove', function(e) { - bars.clearHighlights(); - - var singlePoint, pointIndex, pointXLocation, allData = []; - data - .filter(function(series, i) { - series.seriesIndex = i; - return !series.disabled; - }) - .forEach(function(series,i) { - pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x()); - bars.highlightPoint(pointIndex,true); - var point = series.values[pointIndex]; - if (point === undefined) return; - if (singlePoint === undefined) singlePoint = point; - if (pointXLocation === undefined) pointXLocation = chart.xScale()(chart.x()(point,pointIndex)); - allData.push({ - key: series.key, - value: chart.y()(point, pointIndex), - color: color(series,series.seriesIndex), - data: series.values[pointIndex] - }); - }); - - var xValue = xAxis.tickFormat()(chart.x()(singlePoint,pointIndex)); - interactiveLayer.tooltip - .position({left: pointXLocation + margin.left, top: e.mouseY + margin.top}) - .chartContainer(that.parentNode) - .valueFormatter(function(d,i) { - return yAxis.tickFormat()(d); - }) - .data({ - value: xValue, - index: pointIndex, - series: allData - })(); - - interactiveLayer.renderGuideLine(pointXLocation); - - }); - - interactiveLayer.dispatch.on("elementMouseout",function(e) { - dispatch.tooltipHide(); - bars.clearHighlights(); - }); - - legend.dispatch.on('legendClick', function(d,i) { - d.disabled = !d.disabled; - - if (!data.filter(function(d) { return !d.disabled }).length) { - data.map(function(d) { - d.disabled = false; - wrap.selectAll('.nv-series').classed('disabled', false); - return d; - }); - } - - state.disabled = data.map(function(d) { return !!d.disabled }); - dispatch.stateChange(state); - - selection.transition().call(chart); - }); - - legend.dispatch.on('legendDblclick', function(d) { - //Double clicking should always enable current series, and disabled all others. - data.forEach(function(d) { - d.disabled = true; - }); - d.disabled = false; - - state.disabled = data.map(function(d) { return !!d.disabled }); - dispatch.stateChange(state); - chart.update(); - }); - - dispatch.on('changeState', function(e) { - if (typeof e.disabled !== 'undefined') { - data.forEach(function(series,i) { - series.disabled = e.disabled[i]; - }); - - state.disabled = e.disabled; - } - - chart.update(); - }); - }); - - renderWatch.renderEnd('historicalBarChart immediate'); - return chart; - } - - //============================================================ - // Event Handling/Dispatching (out of chart's scope) - //------------------------------------------------------------ - - bars.dispatch.on('elementMouseover.tooltip', function(evt) { - evt['series'] = { - key: chart.x()(evt.data), - value: chart.y()(evt.data), - color: evt.color - }; - tooltip.data(evt).hidden(false); - }); - - bars.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true); - }); - - bars.dispatch.on('elementMousemove.tooltip', function(evt) { - tooltip.position({top: d3.event.pageY, left: d3.event.pageX})(); - }); - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - // expose chart's sub-components - chart.dispatch = dispatch; - chart.bars = bars; - chart.legend = legend; - chart.xAxis = xAxis; - chart.yAxis = yAxis; - chart.interactiveLayer = interactiveLayer; - chart.tooltip = tooltip; - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}}, - showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}}, - showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}}, - defaultState: {get: function(){return defaultState;}, set: function(_){defaultState=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - - // deprecated options - tooltips: {get: function(){return tooltip.enabled();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltips', 'use chart.tooltip.enabled() instead'); - tooltip.enabled(!!_); - }}, - tooltipContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'use chart.tooltip.contentGenerator() instead'); - tooltip.contentGenerator(_); - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - legend.color(color); - bars.color(color); - }}, - duration: {get: function(){return transitionDuration;}, set: function(_){ - transitionDuration=_; - renderWatch.reset(transitionDuration); - yAxis.duration(transitionDuration); - xAxis.duration(transitionDuration); - }}, - rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){ - rightAlignYAxis = _; - yAxis.orient( (_) ? 'right' : 'left'); - }}, - useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){ - useInteractiveGuideline = _; - if (_ === true) { - chart.interactive(false); - } - }} - }); - - nv.utils.inheritOptions(chart, bars); - nv.utils.initOptions(chart); - - return chart; - }; - - -// ohlcChart is just a historical chart with ohlc bars and some tweaks - nv.models.ohlcBarChart = function() { - var chart = nv.models.historicalBarChart(nv.models.ohlcBar()); - - // special default tooltip since we show multiple values per x - chart.useInteractiveGuideline(true); - chart.interactiveLayer.tooltip.contentGenerator(function(data) { - // we assume only one series exists for this chart - var d = data.series[0].data; - // match line colors as defined in nv.d3.css - var color = d.open < d.close ? "2ca02c" : "d62728"; - return '' + - '

' + data.value + '

' + - '' + - '' + - '' + - '' + - '' + - '
open:' + chart.yAxis.tickFormat()(d.open) + '
close:' + chart.yAxis.tickFormat()(d.close) + '
high' + chart.yAxis.tickFormat()(d.high) + '
low:' + chart.yAxis.tickFormat()(d.low) + '
'; - }); - return chart; - }; - -// candlestickChart is just a historical chart with candlestick bars and some tweaks - nv.models.candlestickBarChart = function() { - var chart = nv.models.historicalBarChart(nv.models.candlestickBar()); - - // special default tooltip since we show multiple values per x - chart.useInteractiveGuideline(true); - chart.interactiveLayer.tooltip.contentGenerator(function(data) { - // we assume only one series exists for this chart - var d = data.series[0].data; - // match line colors as defined in nv.d3.css - var color = d.open < d.close ? "2ca02c" : "d62728"; - return '' + - '

' + data.value + '

' + - '' + - '' + - '' + - '' + - '' + - '
open:' + chart.yAxis.tickFormat()(d.open) + '
close:' + chart.yAxis.tickFormat()(d.close) + '
high' + chart.yAxis.tickFormat()(d.high) + '
low:' + chart.yAxis.tickFormat()(d.low) + '
'; - }); - return chart; - }; - nv.models.legend = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 5, right: 0, bottom: 5, left: 0} - , width = 400 - , height = 20 - , getKey = function(d) { return d.key } - , color = nv.utils.getColor() - , align = true - , padding = 32 //define how much space between legend items. - recommend 32 for furious version - , rightAlign = true - , updateState = true //If true, legend will update data.disabled and trigger a 'stateChange' dispatch. - , radioButtonMode = false //If true, clicking legend items will cause it to behave like a radio button. (only one can be selected at a time) - , expanded = false - , dispatch = d3.dispatch('legendClick', 'legendDblclick', 'legendMouseover', 'legendMouseout', 'stateChange') - , vers = 'classic' //Options are "classic" and "furious" - ; - - function chart(selection) { - selection.each(function(data) { - var availableWidth = width - margin.left - margin.right, - container = d3.select(this); - nv.utils.initSVG(container); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-legend').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-legend').append('g'); - var g = wrap.select('g'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - var series = g.selectAll('.nv-series') - .data(function(d) { - if(vers != 'furious') return d; - - return d.filter(function(n) { - return expanded ? true : !n.disengaged; - }); - }); - - var seriesEnter = series.enter().append('g').attr('class', 'nv-series'); - var seriesShape; - - var versPadding; - switch(vers) { - case 'furious' : - versPadding = 23; - break; - case 'classic' : - versPadding = 20; - } - - if(vers == 'classic') { - seriesEnter.append('circle') - .style('stroke-width', 2) - .attr('class','nv-legend-symbol') - .attr('r', 5); - - seriesShape = series.select('circle'); - } else if (vers == 'furious') { - seriesEnter.append('rect') - .style('stroke-width', 2) - .attr('class','nv-legend-symbol') - .attr('rx', 3) - .attr('ry', 3); - - seriesShape = series.select('.nv-legend-symbol'); - - seriesEnter.append('g') - .attr('class', 'nv-check-box') - .property('innerHTML','') - .attr('transform', 'translate(-10,-8)scale(0.5)'); - - var seriesCheckbox = series.select('.nv-check-box'); - - seriesCheckbox.each(function(d,i) { - d3.select(this).selectAll('path') - .attr('stroke', setTextColor(d,i)); - }); - } - - seriesEnter.append('text') - .attr('text-anchor', 'start') - .attr('class','nv-legend-text') - .attr('dy', '.32em') - .attr('dx', '8'); - - var seriesText = series.select('text.nv-legend-text'); - - series - .on('mouseover', function(d,i) { - dispatch.legendMouseover(d,i); //TODO: Make consistent with other event objects - }) - .on('mouseout', function(d,i) { - dispatch.legendMouseout(d,i); - }) - .on('click', function(d,i) { - dispatch.legendClick(d,i); - // make sure we re-get data in case it was modified - var data = series.data(); - if (updateState) { - if(vers =='classic') { - if (radioButtonMode) { - //Radio button mode: set every series to disabled, - // and enable the clicked series. - data.forEach(function(series) { series.disabled = true}); - d.disabled = false; - } - else { - d.disabled = !d.disabled; - if (data.every(function(series) { return series.disabled})) { - //the default behavior of NVD3 legends is, if every single series - // is disabled, turn all series' back on. - data.forEach(function(series) { series.disabled = false}); - } - } - } else if(vers == 'furious') { - if(expanded) { - d.disengaged = !d.disengaged; - d.userDisabled = d.userDisabled == undefined ? !!d.disabled : d.userDisabled; - d.disabled = d.disengaged || d.userDisabled; - } else if (!expanded) { - d.disabled = !d.disabled; - d.userDisabled = d.disabled; - var engaged = data.filter(function(d) { return !d.disengaged; }); - if (engaged.every(function(series) { return series.userDisabled })) { - //the default behavior of NVD3 legends is, if every single series - // is disabled, turn all series' back on. - data.forEach(function(series) { - series.disabled = series.userDisabled = false; - }); - } - } - } - dispatch.stateChange({ - disabled: data.map(function(d) { return !!d.disabled }), - disengaged: data.map(function(d) { return !!d.disengaged }) - }); - - } - }) - .on('dblclick', function(d,i) { - if(vers == 'furious' && expanded) return; - dispatch.legendDblclick(d,i); - if (updateState) { - // make sure we re-get data in case it was modified - var data = series.data(); - //the default behavior of NVD3 legends, when double clicking one, - // is to set all other series' to false, and make the double clicked series enabled. - data.forEach(function(series) { - series.disabled = true; - if(vers == 'furious') series.userDisabled = series.disabled; - }); - d.disabled = false; - if(vers == 'furious') d.userDisabled = d.disabled; - dispatch.stateChange({ - disabled: data.map(function(d) { return !!d.disabled }) - }); - } - }); - - series.classed('nv-disabled', function(d) { return d.userDisabled }); - series.exit().remove(); - - seriesText - .attr('fill', setTextColor) - .text(getKey); - - //TODO: implement fixed-width and max-width options (max-width is especially useful with the align option) - // NEW ALIGNING CODE, TODO: clean up - var legendWidth = 0; - if (align) { - - var seriesWidths = []; - series.each(function(d,i) { - var legendText = d3.select(this).select('text'); - var nodeTextLength; - try { - nodeTextLength = legendText.node().getComputedTextLength(); - // If the legendText is display:none'd (nodeTextLength == 0), simulate an error so we approximate, instead - if(nodeTextLength <= 0) throw Error(); - } - catch(e) { - nodeTextLength = nv.utils.calcApproxTextWidth(legendText); - } - - seriesWidths.push(nodeTextLength + padding); - }); - - var seriesPerRow = 0; - var columnWidths = []; - legendWidth = 0; - - while ( legendWidth < availableWidth && seriesPerRow < seriesWidths.length) { - columnWidths[seriesPerRow] = seriesWidths[seriesPerRow]; - legendWidth += seriesWidths[seriesPerRow++]; - } - if (seriesPerRow === 0) seriesPerRow = 1; //minimum of one series per row - - while ( legendWidth > availableWidth && seriesPerRow > 1 ) { - columnWidths = []; - seriesPerRow--; - - for (var k = 0; k < seriesWidths.length; k++) { - if (seriesWidths[k] > (columnWidths[k % seriesPerRow] || 0) ) - columnWidths[k % seriesPerRow] = seriesWidths[k]; - } - - legendWidth = columnWidths.reduce(function(prev, cur, index, array) { - return prev + cur; - }); - } - - var xPositions = []; - for (var i = 0, curX = 0; i < seriesPerRow; i++) { - xPositions[i] = curX; - curX += columnWidths[i]; - } - - series - .attr('transform', function(d, i) { - return 'translate(' + xPositions[i % seriesPerRow] + ',' + (5 + Math.floor(i / seriesPerRow) * versPadding) + ')'; - }); - - //position legend as far right as possible within the total width - if (rightAlign) { - g.attr('transform', 'translate(' + (width - margin.right - legendWidth) + ',' + margin.top + ')'); - } - else { - g.attr('transform', 'translate(0' + ',' + margin.top + ')'); - } - - height = margin.top + margin.bottom + (Math.ceil(seriesWidths.length / seriesPerRow) * versPadding); - - } else { - - var ypos = 5, - newxpos = 5, - maxwidth = 0, - xpos; - series - .attr('transform', function(d, i) { - var length = d3.select(this).select('text').node().getComputedTextLength() + padding; - xpos = newxpos; - - if (width < margin.left + margin.right + xpos + length) { - newxpos = xpos = 5; - ypos += versPadding; - } - - newxpos += length; - if (newxpos > maxwidth) maxwidth = newxpos; - - if(legendWidth < xpos + maxwidth) { - legendWidth = xpos + maxwidth; - } - return 'translate(' + xpos + ',' + ypos + ')'; - }); - - //position legend as far right as possible within the total width - g.attr('transform', 'translate(' + (width - margin.right - maxwidth) + ',' + margin.top + ')'); - - height = margin.top + margin.bottom + ypos + 15; - } - - if(vers == 'furious') { - // Size rectangles after text is placed - seriesShape - .attr('width', function(d,i) { - return seriesText[0][i].getComputedTextLength() + 27; - }) - .attr('height', 18) - .attr('y', -9) - .attr('x', -15); - - // The background for the expanded legend (UI) - gEnter.insert('rect',':first-child') - .attr('class', 'nv-legend-bg') - .attr('fill', '#eee') - // .attr('stroke', '#444') - .attr('opacity',0); - - var seriesBG = g.select('.nv-legend-bg'); - - seriesBG - .transition().duration(300) - .attr('x', -versPadding ) - .attr('width', legendWidth + versPadding - 12) - .attr('height', height + 10) - .attr('y', -margin.top - 10) - .attr('opacity', expanded ? 1 : 0); - - - } - - seriesShape - .style('fill', setBGColor) - .style('fill-opacity', setBGOpacity) - .style('stroke', setBGColor); - }); - - function setTextColor(d,i) { - if(vers != 'furious') return '#000'; - if(expanded) { - return d.disengaged ? '#000' : '#fff'; - } else if (!expanded) { - if(!d.color) d.color = color(d,i); - return !!d.disabled ? d.color : '#fff'; - } - } - - function setBGColor(d,i) { - if(expanded && vers == 'furious') { - return d.disengaged ? '#eee' : d.color || color(d,i); - } else { - return d.color || color(d,i); - } - } - - - function setBGOpacity(d,i) { - if(expanded && vers == 'furious') { - return 1; - } else { - return !!d.disabled ? 0 : 1; - } - } - - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - key: {get: function(){return getKey;}, set: function(_){getKey=_;}}, - align: {get: function(){return align;}, set: function(_){align=_;}}, - rightAlign: {get: function(){return rightAlign;}, set: function(_){rightAlign=_;}}, - padding: {get: function(){return padding;}, set: function(_){padding=_;}}, - updateState: {get: function(){return updateState;}, set: function(_){updateState=_;}}, - radioButtonMode: {get: function(){return radioButtonMode;}, set: function(_){radioButtonMode=_;}}, - expanded: {get: function(){return expanded;}, set: function(_){expanded=_;}}, - vers: {get: function(){return vers;}, set: function(_){vers=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }} - }); - - nv.utils.initOptions(chart); - - return chart; - }; - - nv.models.line = function() { - "use strict"; - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var scatter = nv.models.scatter() - ; - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = 960 - , height = 500 - , container = null - , strokeWidth = 1.5 - , color = nv.utils.defaultColor() // a function that returns a color - , getX = function(d) { return d.x } // accessor to get the x value from a data point - , getY = function(d) { return d.y } // accessor to get the y value from a data point - , defined = function(d,i) { return !isNaN(getY(d,i)) && getY(d,i) !== null } // allows a line to be not continuous when it is not defined - , isArea = function(d) { return d.area } // decides if a line is an area or just a line - , clipEdge = false // if true, masks lines within x and y scale - , x //can be accessed via chart.xScale() - , y //can be accessed via chart.yScale() - , interpolate = "linear" // controls the line interpolation - , duration = 250 - , dispatch = d3.dispatch('elementClick', 'elementMouseover', 'elementMouseout', 'renderEnd') - ; - - scatter - .pointSize(16) // default size - .pointDomain([16,256]) //set to speed up calculation, needs to be unset if there is a custom size accessor - ; - - //============================================================ - - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var x0, y0 //used to store previous scales - , renderWatch = nv.utils.renderWatch(dispatch, duration) - ; - - //============================================================ - - - function chart(selection) { - renderWatch.reset(); - renderWatch.models(scatter); - selection.each(function(data) { - container = d3.select(this); - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - nv.utils.initSVG(container); - - // Setup Scales - x = scatter.xScale(); - y = scatter.yScale(); - - x0 = x0 || x; - y0 = y0 || y; - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-line').data([data]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-line'); - var defsEnter = wrapEnter.append('defs'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-groups'); - gEnter.append('g').attr('class', 'nv-scatterWrap'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - scatter - .width(availableWidth) - .height(availableHeight); - - var scatterWrap = wrap.select('.nv-scatterWrap'); - scatterWrap.call(scatter); - - defsEnter.append('clipPath') - .attr('id', 'nv-edge-clip-' + scatter.id()) - .append('rect'); - - wrap.select('#nv-edge-clip-' + scatter.id() + ' rect') - .attr('width', availableWidth) - .attr('height', (availableHeight > 0) ? availableHeight : 0); - - g .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + scatter.id() + ')' : ''); - scatterWrap - .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + scatter.id() + ')' : ''); - - var groups = wrap.select('.nv-groups').selectAll('.nv-group') - .data(function(d) { return d }, function(d) { return d.key }); - groups.enter().append('g') - .style('stroke-opacity', 1e-6) - .style('stroke-width', function(d) { return d.strokeWidth || strokeWidth }) - .style('fill-opacity', 1e-6); - - groups.exit().remove(); - - groups - .attr('class', function(d,i) { - return (d.classed || '') + ' nv-group nv-series-' + i; - }) - .classed('hover', function(d) { return d.hover }) - .style('fill', function(d,i){ return color(d, i) }) - .style('stroke', function(d,i){ return color(d, i)}); - groups.watchTransition(renderWatch, 'line: groups') - .style('stroke-opacity', 1) - .style('fill-opacity', function(d) { return d.fillOpacity || .5}); - - var areaPaths = groups.selectAll('path.nv-area') - .data(function(d) { return isArea(d) ? [d] : [] }); // this is done differently than lines because I need to check if series is an area - areaPaths.enter().append('path') - .attr('class', 'nv-area') - .attr('d', function(d) { - return d3.svg.area() - .interpolate(interpolate) - .defined(defined) - .x(function(d,i) { return nv.utils.NaNtoZero(x0(getX(d,i))) }) - .y0(function(d,i) { return nv.utils.NaNtoZero(y0(getY(d,i))) }) - .y1(function(d,i) { return y0( y.domain()[0] <= 0 ? y.domain()[1] >= 0 ? 0 : y.domain()[1] : y.domain()[0] ) }) - //.y1(function(d,i) { return y0(0) }) //assuming 0 is within y domain.. may need to tweak this - .apply(this, [d.values]) - }); - groups.exit().selectAll('path.nv-area') - .remove(); - - areaPaths.watchTransition(renderWatch, 'line: areaPaths') - .attr('d', function(d) { - return d3.svg.area() - .interpolate(interpolate) - .defined(defined) - .x(function(d,i) { return nv.utils.NaNtoZero(x(getX(d,i))) }) - .y0(function(d,i) { return nv.utils.NaNtoZero(y(getY(d,i))) }) - .y1(function(d,i) { return y( y.domain()[0] <= 0 ? y.domain()[1] >= 0 ? 0 : y.domain()[1] : y.domain()[0] ) }) - //.y1(function(d,i) { return y0(0) }) //assuming 0 is within y domain.. may need to tweak this - .apply(this, [d.values]) - }); - - var linePaths = groups.selectAll('path.nv-line') - .data(function(d) { return [d.values] }); - - linePaths.enter().append('path') - .attr('class', 'nv-line') - .attr('d', - d3.svg.line() - .interpolate(interpolate) - .defined(defined) - .x(function(d,i) { return nv.utils.NaNtoZero(x0(getX(d,i))) }) - .y(function(d,i) { return nv.utils.NaNtoZero(y0(getY(d,i))) }) - ); - - linePaths.watchTransition(renderWatch, 'line: linePaths') - .attr('d', - d3.svg.line() - .interpolate(interpolate) - .defined(defined) - .x(function(d,i) { return nv.utils.NaNtoZero(x(getX(d,i))) }) - .y(function(d,i) { return nv.utils.NaNtoZero(y(getY(d,i))) }) - ); - - //store old scales for use in transitions on update - x0 = x.copy(); - y0 = y.copy(); - }); - renderWatch.renderEnd('line immediate'); - return chart; - } - - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.scatter = scatter; - // Pass through events - scatter.dispatch.on('elementClick', function(){ dispatch.elementClick.apply(this, arguments); }); - scatter.dispatch.on('elementMouseover', function(){ dispatch.elementMouseover.apply(this, arguments); }); - scatter.dispatch.on('elementMouseout', function(){ dispatch.elementMouseout.apply(this, arguments); }); - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - defined: {get: function(){return defined;}, set: function(_){defined=_;}}, - interpolate: {get: function(){return interpolate;}, set: function(_){interpolate=_;}}, - clipEdge: {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - scatter.duration(duration); - }}, - isArea: {get: function(){return isArea;}, set: function(_){ - isArea = d3.functor(_); - }}, - x: {get: function(){return getX;}, set: function(_){ - getX = _; - scatter.x(_); - }}, - y: {get: function(){return getY;}, set: function(_){ - getY = _; - scatter.y(_); - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - scatter.color(color); - }} - }); - - nv.utils.inheritOptions(chart, scatter); - nv.utils.initOptions(chart); - - return chart; - }; - nv.models.lineChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var lines = nv.models.line() - , xAxis = nv.models.axis() - , yAxis = nv.models.axis() - , legend = nv.models.legend() - , interactiveLayer = nv.interactiveGuideline() - , tooltip = nv.models.tooltip() - ; - - var margin = {top: 30, right: 20, bottom: 50, left: 60} - , color = nv.utils.defaultColor() - , width = null - , height = null - , showLegend = true - , showXAxis = true - , showYAxis = true - , rightAlignYAxis = false - , useInteractiveGuideline = false - , x - , y - , state = nv.utils.state() - , defaultState = null - , noData = null - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState', 'renderEnd') - , duration = 250 - ; - - // set options on sub-objects for this chart - xAxis.orient('bottom').tickPadding(7); - yAxis.orient(rightAlignYAxis ? 'right' : 'left'); - tooltip.valueFormatter(function(d, i) { - return yAxis.tickFormat()(d, i); - }).headerFormatter(function(d, i) { - return xAxis.tickFormat()(d, i); - }); - - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var renderWatch = nv.utils.renderWatch(dispatch, duration); - - var stateGetter = function(data) { - return function(){ - return { - active: data.map(function(d) { return !d.disabled }) - }; - } - }; - - var stateSetter = function(data) { - return function(state) { - if (state.active !== undefined) - data.forEach(function(series,i) { - series.disabled = !state.active[i]; - }); - } - }; - - function chart(selection) { - renderWatch.reset(); - renderWatch.models(lines); - if (showXAxis) renderWatch.models(xAxis); - if (showYAxis) renderWatch.models(yAxis); - - selection.each(function(data) { - var container = d3.select(this), - that = this; - nv.utils.initSVG(container); - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - chart.update = function() { - if (duration === 0) - container.call(chart); - else - container.transition().duration(duration).call(chart) - }; - chart.container = this; - - state - .setter(stateSetter(data), chart.update) - .getter(stateGetter(data)) - .update(); - - // DEPRECATED set state.disableddisabled - state.disabled = data.map(function(d) { return !!d.disabled }); - - if (!defaultState) { - var key; - defaultState = {}; - for (key in state) { - if (state[key] instanceof Array) - defaultState[key] = state[key].slice(0); - else - defaultState[key] = state[key]; - } - } - - // Display noData message if there's nothing to show. - if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) { - nv.utils.noData(chart, container) - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - - // Setup Scales - x = lines.xScale(); - y = lines.yScale(); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-lineChart').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-lineChart').append('g'); - var g = wrap.select('g'); - - gEnter.append("rect").style("opacity",0); - gEnter.append('g').attr('class', 'nv-x nv-axis'); - gEnter.append('g').attr('class', 'nv-y nv-axis'); - gEnter.append('g').attr('class', 'nv-linesWrap'); - gEnter.append('g').attr('class', 'nv-legendWrap'); - gEnter.append('g').attr('class', 'nv-interactive'); - - g.select("rect") - .attr("width",availableWidth) - .attr("height",(availableHeight > 0) ? availableHeight : 0); - - // Legend - if (showLegend) { - legend.width(availableWidth); - - g.select('.nv-legendWrap') - .datum(data) - .call(legend); - - if ( margin.top != legend.height()) { - margin.top = legend.height(); - availableHeight = nv.utils.availableHeight(height, container, margin); - } - - wrap.select('.nv-legendWrap') - .attr('transform', 'translate(0,' + (-margin.top) +')') - } - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - if (rightAlignYAxis) { - g.select(".nv-y.nv-axis") - .attr("transform", "translate(" + availableWidth + ",0)"); - } - - //Set up interactive layer - if (useInteractiveGuideline) { - interactiveLayer - .width(availableWidth) - .height(availableHeight) - .margin({left:margin.left, top:margin.top}) - .svgContainer(container) - .xScale(x); - wrap.select(".nv-interactive").call(interactiveLayer); - } - - lines - .width(availableWidth) - .height(availableHeight) - .color(data.map(function(d,i) { - return d.color || color(d, i); - }).filter(function(d,i) { return !data[i].disabled })); - - - var linesWrap = g.select('.nv-linesWrap') - .datum(data.filter(function(d) { return !d.disabled })); - - linesWrap.call(lines); - - // Setup Axes - if (showXAxis) { - xAxis - .scale(x) - ._ticks(nv.utils.calcTicksX(availableWidth/100, data) ) - .tickSize(-availableHeight, 0); - - g.select('.nv-x.nv-axis') - .attr('transform', 'translate(0,' + y.range()[0] + ')'); - g.select('.nv-x.nv-axis') - .call(xAxis); - } - - if (showYAxis) { - yAxis - .scale(y) - ._ticks(nv.utils.calcTicksY(availableHeight/36, data) ) - .tickSize( -availableWidth, 0); - - g.select('.nv-y.nv-axis') - .call(yAxis); - } - - //============================================================ - // Event Handling/Dispatching (in chart's scope) - //------------------------------------------------------------ - - legend.dispatch.on('stateChange', function(newState) { - for (var key in newState) - state[key] = newState[key]; - dispatch.stateChange(state); - chart.update(); - }); - - interactiveLayer.dispatch.on('elementMousemove', function(e) { - lines.clearHighlights(); - var singlePoint, pointIndex, pointXLocation, allData = []; - data - .filter(function(series, i) { - series.seriesIndex = i; - return !series.disabled; - }) - .forEach(function(series,i) { - pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x()); - var point = series.values[pointIndex]; - var pointYValue = chart.y()(point, pointIndex); - if (pointYValue != null) { - lines.highlightPoint(i, pointIndex, true); - } - if (point === undefined) return; - if (singlePoint === undefined) singlePoint = point; - if (pointXLocation === undefined) pointXLocation = chart.xScale()(chart.x()(point,pointIndex)); - allData.push({ - key: series.key, - value: pointYValue, - color: color(series,series.seriesIndex) - }); - }); - //Highlight the tooltip entry based on which point the mouse is closest to. - if (allData.length > 2) { - var yValue = chart.yScale().invert(e.mouseY); - var domainExtent = Math.abs(chart.yScale().domain()[0] - chart.yScale().domain()[1]); - var threshold = 0.03 * domainExtent; - var indexToHighlight = nv.nearestValueIndex(allData.map(function(d){return d.value}),yValue,threshold); - if (indexToHighlight !== null) - allData[indexToHighlight].highlight = true; - } - - var xValue = xAxis.tickFormat()(chart.x()(singlePoint,pointIndex)); - interactiveLayer.tooltip - .position({left: e.mouseX + margin.left, top: e.mouseY + margin.top}) - .chartContainer(that.parentNode) - .valueFormatter(function(d,i) { - return d == null ? "N/A" : yAxis.tickFormat()(d); - }) - .data({ - value: xValue, - index: pointIndex, - series: allData - })(); - - interactiveLayer.renderGuideLine(pointXLocation); - - }); - - interactiveLayer.dispatch.on('elementClick', function(e) { - var pointXLocation, allData = []; - - data.filter(function(series, i) { - series.seriesIndex = i; - return !series.disabled; - }).forEach(function(series) { - var pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x()); - var point = series.values[pointIndex]; - if (typeof point === 'undefined') return; - if (typeof pointXLocation === 'undefined') pointXLocation = chart.xScale()(chart.x()(point,pointIndex)); - var yPos = chart.yScale()(chart.y()(point,pointIndex)); - allData.push({ - point: point, - pointIndex: pointIndex, - pos: [pointXLocation, yPos], - seriesIndex: series.seriesIndex, - series: series - }); - }); - - lines.dispatch.elementClick(allData); - }); - - interactiveLayer.dispatch.on("elementMouseout",function(e) { - lines.clearHighlights(); - }); - - dispatch.on('changeState', function(e) { - if (typeof e.disabled !== 'undefined' && data.length === e.disabled.length) { - data.forEach(function(series,i) { - series.disabled = e.disabled[i]; - }); - - state.disabled = e.disabled; - } - - chart.update(); - }); - - }); - - renderWatch.renderEnd('lineChart immediate'); - return chart; - } - - //============================================================ - // Event Handling/Dispatching (out of chart's scope) - //------------------------------------------------------------ - - lines.dispatch.on('elementMouseover.tooltip', function(evt) { - tooltip.data(evt).position(evt.pos).hidden(false); - }); - - lines.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true) - }); - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - // expose chart's sub-components - chart.dispatch = dispatch; - chart.lines = lines; - chart.legend = legend; - chart.xAxis = xAxis; - chart.yAxis = yAxis; - chart.interactiveLayer = interactiveLayer; - chart.tooltip = tooltip; - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}}, - showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}}, - showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}}, - defaultState: {get: function(){return defaultState;}, set: function(_){defaultState=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - - // deprecated options - tooltips: {get: function(){return tooltip.enabled();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltips', 'use chart.tooltip.enabled() instead'); - tooltip.enabled(!!_); - }}, - tooltipContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'use chart.tooltip.contentGenerator() instead'); - tooltip.contentGenerator(_); - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - lines.duration(duration); - xAxis.duration(duration); - yAxis.duration(duration); - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - legend.color(color); - lines.color(color); - }}, - rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){ - rightAlignYAxis = _; - yAxis.orient( rightAlignYAxis ? 'right' : 'left'); - }}, - useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){ - useInteractiveGuideline = _; - if (useInteractiveGuideline) { - lines.interactive(false); - lines.useVoronoi(false); - } - }} - }); - - nv.utils.inheritOptions(chart, lines); - nv.utils.initOptions(chart); - - return chart; - }; - nv.models.linePlusBarChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var lines = nv.models.line() - , lines2 = nv.models.line() - , bars = nv.models.historicalBar() - , bars2 = nv.models.historicalBar() - , xAxis = nv.models.axis() - , x2Axis = nv.models.axis() - , y1Axis = nv.models.axis() - , y2Axis = nv.models.axis() - , y3Axis = nv.models.axis() - , y4Axis = nv.models.axis() - , legend = nv.models.legend() - , brush = d3.svg.brush() - , tooltip = nv.models.tooltip() - ; - - var margin = {top: 30, right: 30, bottom: 30, left: 60} - , margin2 = {top: 0, right: 30, bottom: 20, left: 60} - , width = null - , height = null - , getX = function(d) { return d.x } - , getY = function(d) { return d.y } - , color = nv.utils.defaultColor() - , showLegend = true - , focusEnable = true - , focusShowAxisY = false - , focusShowAxisX = true - , focusHeight = 50 - , extent - , brushExtent = null - , x - , x2 - , y1 - , y2 - , y3 - , y4 - , noData = null - , dispatch = d3.dispatch('brush', 'stateChange', 'changeState') - , transitionDuration = 0 - , state = nv.utils.state() - , defaultState = null - , legendLeftAxisHint = ' (left axis)' - , legendRightAxisHint = ' (right axis)' - ; - - lines.clipEdge(true); - lines2.interactive(false); - // We don't want any points emitted for the focus chart's scatter graph. - lines2.pointActive(function(d) { return false }); - xAxis.orient('bottom').tickPadding(5); - y1Axis.orient('left'); - y2Axis.orient('right'); - x2Axis.orient('bottom').tickPadding(5); - y3Axis.orient('left'); - y4Axis.orient('right'); - - tooltip.headerEnabled(true).headerFormatter(function(d, i) { - return xAxis.tickFormat()(d, i); - }); - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var stateGetter = function(data) { - return function(){ - return { - active: data.map(function(d) { return !d.disabled }) - }; - } - }; - - var stateSetter = function(data) { - return function(state) { - if (state.active !== undefined) - data.forEach(function(series,i) { - series.disabled = !state.active[i]; - }); - } - }; - - function chart(selection) { - selection.each(function(data) { - var container = d3.select(this), - that = this; - nv.utils.initSVG(container); - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight1 = nv.utils.availableHeight(height, container, margin) - - (focusEnable ? focusHeight : 0), - availableHeight2 = focusHeight - margin2.top - margin2.bottom; - - chart.update = function() { container.transition().duration(transitionDuration).call(chart); }; - chart.container = this; - - state - .setter(stateSetter(data), chart.update) - .getter(stateGetter(data)) - .update(); - - // DEPRECATED set state.disableddisabled - state.disabled = data.map(function(d) { return !!d.disabled }); - - if (!defaultState) { - var key; - defaultState = {}; - for (key in state) { - if (state[key] instanceof Array) - defaultState[key] = state[key].slice(0); - else - defaultState[key] = state[key]; - } - } - - // Display No Data message if there's nothing to show. - if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) { - nv.utils.noData(chart, container) - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - // Setup Scales - var dataBars = data.filter(function(d) { return !d.disabled && d.bar }); - var dataLines = data.filter(function(d) { return !d.bar }); // removed the !d.disabled clause here to fix Issue #240 - - x = bars.xScale(); - x2 = x2Axis.scale(); - y1 = bars.yScale(); - y2 = lines.yScale(); - y3 = bars2.yScale(); - y4 = lines2.yScale(); - - var series1 = data - .filter(function(d) { return !d.disabled && d.bar }) - .map(function(d) { - return d.values.map(function(d,i) { - return { x: getX(d,i), y: getY(d,i) } - }) - }); - - var series2 = data - .filter(function(d) { return !d.disabled && !d.bar }) - .map(function(d) { - return d.values.map(function(d,i) { - return { x: getX(d,i), y: getY(d,i) } - }) - }); - - x.range([0, availableWidth]); - - x2 .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return d.x } )) - .range([0, availableWidth]); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-linePlusBar').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-linePlusBar').append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-legendWrap'); - - // this is the main chart - var focusEnter = gEnter.append('g').attr('class', 'nv-focus'); - focusEnter.append('g').attr('class', 'nv-x nv-axis'); - focusEnter.append('g').attr('class', 'nv-y1 nv-axis'); - focusEnter.append('g').attr('class', 'nv-y2 nv-axis'); - focusEnter.append('g').attr('class', 'nv-barsWrap'); - focusEnter.append('g').attr('class', 'nv-linesWrap'); - - // context chart is where you can focus in - var contextEnter = gEnter.append('g').attr('class', 'nv-context'); - contextEnter.append('g').attr('class', 'nv-x nv-axis'); - contextEnter.append('g').attr('class', 'nv-y1 nv-axis'); - contextEnter.append('g').attr('class', 'nv-y2 nv-axis'); - contextEnter.append('g').attr('class', 'nv-barsWrap'); - contextEnter.append('g').attr('class', 'nv-linesWrap'); - contextEnter.append('g').attr('class', 'nv-brushBackground'); - contextEnter.append('g').attr('class', 'nv-x nv-brush'); - - //============================================================ - // Legend - //------------------------------------------------------------ - - if (showLegend) { - var legendWidth = legend.align() ? availableWidth / 2 : availableWidth; - var legendXPosition = legend.align() ? legendWidth : 0; - - legend.width(legendWidth); - - g.select('.nv-legendWrap') - .datum(data.map(function(series) { - series.originalKey = series.originalKey === undefined ? series.key : series.originalKey; - series.key = series.originalKey + (series.bar ? legendLeftAxisHint : legendRightAxisHint); - return series; - })) - .call(legend); - - if ( margin.top != legend.height()) { - margin.top = legend.height(); - // FIXME: shouldn't this be "- (focusEnabled ? focusHeight : 0)"? - availableHeight1 = nv.utils.availableHeight(height, container, margin) - focusHeight; - } - - g.select('.nv-legendWrap') - .attr('transform', 'translate(' + legendXPosition + ',' + (-margin.top) +')'); - } - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - //============================================================ - // Context chart (focus chart) components - //------------------------------------------------------------ - - // hide or show the focus context chart - g.select('.nv-context').style('display', focusEnable ? 'initial' : 'none'); - - bars2 - .width(availableWidth) - .height(availableHeight2) - .color(data.map(function (d, i) { - return d.color || color(d, i); - }).filter(function (d, i) { - return !data[i].disabled && data[i].bar - })); - lines2 - .width(availableWidth) - .height(availableHeight2) - .color(data.map(function (d, i) { - return d.color || color(d, i); - }).filter(function (d, i) { - return !data[i].disabled && !data[i].bar - })); - - var bars2Wrap = g.select('.nv-context .nv-barsWrap') - .datum(dataBars.length ? dataBars : [ - {values: []} - ]); - var lines2Wrap = g.select('.nv-context .nv-linesWrap') - .datum(!dataLines[0].disabled ? dataLines : [ - {values: []} - ]); - - g.select('.nv-context') - .attr('transform', 'translate(0,' + ( availableHeight1 + margin.bottom + margin2.top) + ')'); - - bars2Wrap.transition().call(bars2); - lines2Wrap.transition().call(lines2); - - // context (focus chart) axis controls - if (focusShowAxisX) { - x2Axis - ._ticks( nv.utils.calcTicksX(availableWidth / 100, data)) - .tickSize(-availableHeight2, 0); - g.select('.nv-context .nv-x.nv-axis') - .attr('transform', 'translate(0,' + y3.range()[0] + ')'); - g.select('.nv-context .nv-x.nv-axis').transition() - .call(x2Axis); - } - - if (focusShowAxisY) { - y3Axis - .scale(y3) - ._ticks( availableHeight2 / 36 ) - .tickSize( -availableWidth, 0); - y4Axis - .scale(y4) - ._ticks( availableHeight2 / 36 ) - .tickSize(dataBars.length ? 0 : -availableWidth, 0); // Show the y2 rules only if y1 has none - - g.select('.nv-context .nv-y3.nv-axis') - .style('opacity', dataBars.length ? 1 : 0) - .attr('transform', 'translate(0,' + x2.range()[0] + ')'); - g.select('.nv-context .nv-y2.nv-axis') - .style('opacity', dataLines.length ? 1 : 0) - .attr('transform', 'translate(' + x2.range()[1] + ',0)'); - - g.select('.nv-context .nv-y1.nv-axis').transition() - .call(y3Axis); - g.select('.nv-context .nv-y2.nv-axis').transition() - .call(y4Axis); - } - - // Setup Brush - brush.x(x2).on('brush', onBrush); - - if (brushExtent) brush.extent(brushExtent); - - var brushBG = g.select('.nv-brushBackground').selectAll('g') - .data([brushExtent || brush.extent()]); - - var brushBGenter = brushBG.enter() - .append('g'); - - brushBGenter.append('rect') - .attr('class', 'left') - .attr('x', 0) - .attr('y', 0) - .attr('height', availableHeight2); - - brushBGenter.append('rect') - .attr('class', 'right') - .attr('x', 0) - .attr('y', 0) - .attr('height', availableHeight2); - - var gBrush = g.select('.nv-x.nv-brush') - .call(brush); - gBrush.selectAll('rect') - //.attr('y', -5) - .attr('height', availableHeight2); - gBrush.selectAll('.resize').append('path').attr('d', resizePath); - - //============================================================ - // Event Handling/Dispatching (in chart's scope) - //------------------------------------------------------------ - - legend.dispatch.on('stateChange', function(newState) { - for (var key in newState) - state[key] = newState[key]; - dispatch.stateChange(state); - chart.update(); - }); - - // Update chart from a state object passed to event handler - dispatch.on('changeState', function(e) { - if (typeof e.disabled !== 'undefined') { - data.forEach(function(series,i) { - series.disabled = e.disabled[i]; - }); - state.disabled = e.disabled; - } - chart.update(); - }); - - //============================================================ - // Functions - //------------------------------------------------------------ - - // Taken from crossfilter (http://square.github.com/crossfilter/) - function resizePath(d) { - var e = +(d == 'e'), - x = e ? 1 : -1, - y = availableHeight2 / 3; - return 'M' + (.5 * x) + ',' + y - + 'A6,6 0 0 ' + e + ' ' + (6.5 * x) + ',' + (y + 6) - + 'V' + (2 * y - 6) - + 'A6,6 0 0 ' + e + ' ' + (.5 * x) + ',' + (2 * y) - + 'Z' - + 'M' + (2.5 * x) + ',' + (y + 8) - + 'V' + (2 * y - 8) - + 'M' + (4.5 * x) + ',' + (y + 8) - + 'V' + (2 * y - 8); - } - - - function updateBrushBG() { - if (!brush.empty()) brush.extent(brushExtent); - brushBG - .data([brush.empty() ? x2.domain() : brushExtent]) - .each(function(d,i) { - var leftWidth = x2(d[0]) - x2.range()[0], - rightWidth = x2.range()[1] - x2(d[1]); - d3.select(this).select('.left') - .attr('width', leftWidth < 0 ? 0 : leftWidth); - - d3.select(this).select('.right') - .attr('x', x2(d[1])) - .attr('width', rightWidth < 0 ? 0 : rightWidth); - }); - } - - function onBrush() { - brushExtent = brush.empty() ? null : brush.extent(); - extent = brush.empty() ? x2.domain() : brush.extent(); - dispatch.brush({extent: extent, brush: brush}); - updateBrushBG(); - - // Prepare Main (Focus) Bars and Lines - bars - .width(availableWidth) - .height(availableHeight1) - .color(data.map(function(d,i) { - return d.color || color(d, i); - }).filter(function(d,i) { return !data[i].disabled && data[i].bar })); - - lines - .width(availableWidth) - .height(availableHeight1) - .color(data.map(function(d,i) { - return d.color || color(d, i); - }).filter(function(d,i) { return !data[i].disabled && !data[i].bar })); - - var focusBarsWrap = g.select('.nv-focus .nv-barsWrap') - .datum(!dataBars.length ? [{values:[]}] : - dataBars - .map(function(d,i) { - return { - key: d.key, - values: d.values.filter(function(d,i) { - return bars.x()(d,i) >= extent[0] && bars.x()(d,i) <= extent[1]; - }) - } - }) - ); - - var focusLinesWrap = g.select('.nv-focus .nv-linesWrap') - .datum(dataLines[0].disabled ? [{values:[]}] : - dataLines - .map(function(d,i) { - return { - area: d.area, - fillOpacity: d.fillOpacity, - key: d.key, - values: d.values.filter(function(d,i) { - return lines.x()(d,i) >= extent[0] && lines.x()(d,i) <= extent[1]; - }) - } - }) - ); - - // Update Main (Focus) X Axis - if (dataBars.length) { - x = bars.xScale(); - } else { - x = lines.xScale(); - } - - xAxis - .scale(x) - ._ticks( nv.utils.calcTicksX(availableWidth/100, data) ) - .tickSize(-availableHeight1, 0); - - xAxis.domain([Math.ceil(extent[0]), Math.floor(extent[1])]); - - g.select('.nv-x.nv-axis').transition().duration(transitionDuration) - .call(xAxis); - - // Update Main (Focus) Bars and Lines - focusBarsWrap.transition().duration(transitionDuration).call(bars); - focusLinesWrap.transition().duration(transitionDuration).call(lines); - - // Setup and Update Main (Focus) Y Axes - g.select('.nv-focus .nv-x.nv-axis') - .attr('transform', 'translate(0,' + y1.range()[0] + ')'); - - y1Axis - .scale(y1) - ._ticks( nv.utils.calcTicksY(availableHeight1/36, data) ) - .tickSize(-availableWidth, 0); - y2Axis - .scale(y2) - ._ticks( nv.utils.calcTicksY(availableHeight1/36, data) ) - .tickSize(dataBars.length ? 0 : -availableWidth, 0); // Show the y2 rules only if y1 has none - - g.select('.nv-focus .nv-y1.nv-axis') - .style('opacity', dataBars.length ? 1 : 0); - g.select('.nv-focus .nv-y2.nv-axis') - .style('opacity', dataLines.length && !dataLines[0].disabled ? 1 : 0) - .attr('transform', 'translate(' + x.range()[1] + ',0)'); - - g.select('.nv-focus .nv-y1.nv-axis').transition().duration(transitionDuration) - .call(y1Axis); - g.select('.nv-focus .nv-y2.nv-axis').transition().duration(transitionDuration) - .call(y2Axis); - } - - onBrush(); - - }); - - return chart; - } - - //============================================================ - // Event Handling/Dispatching (out of chart's scope) - //------------------------------------------------------------ - - lines.dispatch.on('elementMouseover.tooltip', function(evt) { - tooltip - .duration(100) - .valueFormatter(function(d, i) { - return y2Axis.tickFormat()(d, i); - }) - .data(evt) - .position(evt.pos) - .hidden(false); - }); - - lines.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true) - }); - - bars.dispatch.on('elementMouseover.tooltip', function(evt) { - evt.value = chart.x()(evt.data); - evt['series'] = { - value: chart.y()(evt.data), - color: evt.color - }; - tooltip - .duration(0) - .valueFormatter(function(d, i) { - return y1Axis.tickFormat()(d, i); - }) - .data(evt) - .hidden(false); - }); - - bars.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true); - }); - - bars.dispatch.on('elementMousemove.tooltip', function(evt) { - tooltip.position({top: d3.event.pageY, left: d3.event.pageX})(); - }); - - //============================================================ - - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - // expose chart's sub-components - chart.dispatch = dispatch; - chart.legend = legend; - chart.lines = lines; - chart.lines2 = lines2; - chart.bars = bars; - chart.bars2 = bars2; - chart.xAxis = xAxis; - chart.x2Axis = x2Axis; - chart.y1Axis = y1Axis; - chart.y2Axis = y2Axis; - chart.y3Axis = y3Axis; - chart.y4Axis = y4Axis; - chart.tooltip = tooltip; - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}}, - brushExtent: {get: function(){return brushExtent;}, set: function(_){brushExtent=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - focusEnable: {get: function(){return focusEnable;}, set: function(_){focusEnable=_;}}, - focusHeight: {get: function(){return focusHeight;}, set: function(_){focusHeight=_;}}, - focusShowAxisX: {get: function(){return focusShowAxisX;}, set: function(_){focusShowAxisX=_;}}, - focusShowAxisY: {get: function(){return focusShowAxisY;}, set: function(_){focusShowAxisY=_;}}, - legendLeftAxisHint: {get: function(){return legendLeftAxisHint;}, set: function(_){legendLeftAxisHint=_;}}, - legendRightAxisHint: {get: function(){return legendRightAxisHint;}, set: function(_){legendRightAxisHint=_;}}, - - // deprecated options - tooltips: {get: function(){return tooltip.enabled();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltips', 'use chart.tooltip.enabled() instead'); - tooltip.enabled(!!_); - }}, - tooltipContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'use chart.tooltip.contentGenerator() instead'); - tooltip.contentGenerator(_); - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - focusMargin: {get: function(){return margin2;}, set: function(_){ - margin2.top = _.top !== undefined ? _.top : margin2.top; - margin2.right = _.right !== undefined ? _.right : margin2.right; - margin2.bottom = _.bottom !== undefined ? _.bottom : margin2.bottom; - margin2.left = _.left !== undefined ? _.left : margin2.left; - }}, - duration: {get: function(){return transitionDuration;}, set: function(_){ - transitionDuration = _; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - legend.color(color); - }}, - x: {get: function(){return getX;}, set: function(_){ - getX = _; - lines.x(_); - lines2.x(_); - bars.x(_); - bars2.x(_); - }}, - y: {get: function(){return getY;}, set: function(_){ - getY = _; - lines.y(_); - lines2.y(_); - bars.y(_); - bars2.y(_); - }} - }); - - nv.utils.inheritOptions(chart, lines); - nv.utils.initOptions(chart); - - return chart; - }; - nv.models.lineWithFocusChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var lines = nv.models.line() - , lines2 = nv.models.line() - , xAxis = nv.models.axis() - , yAxis = nv.models.axis() - , x2Axis = nv.models.axis() - , y2Axis = nv.models.axis() - , legend = nv.models.legend() - , brush = d3.svg.brush() - , tooltip = nv.models.tooltip() - , interactiveLayer = nv.interactiveGuideline() - ; - - var margin = {top: 30, right: 30, bottom: 30, left: 60} - , margin2 = {top: 0, right: 30, bottom: 20, left: 60} - , color = nv.utils.defaultColor() - , width = null - , height = null - , height2 = 50 - , useInteractiveGuideline = false - , x - , y - , x2 - , y2 - , showLegend = true - , brushExtent = null - , noData = null - , dispatch = d3.dispatch('brush', 'stateChange', 'changeState') - , transitionDuration = 250 - , state = nv.utils.state() - , defaultState = null - ; - - lines.clipEdge(true).duration(0); - lines2.interactive(false); - // We don't want any points emitted for the focus chart's scatter graph. - lines2.pointActive(function(d) { return false }); - xAxis.orient('bottom').tickPadding(5); - yAxis.orient('left'); - x2Axis.orient('bottom').tickPadding(5); - y2Axis.orient('left'); - - tooltip.valueFormatter(function(d, i) { - return yAxis.tickFormat()(d, i); - }).headerFormatter(function(d, i) { - return xAxis.tickFormat()(d, i); - }); - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var stateGetter = function(data) { - return function(){ - return { - active: data.map(function(d) { return !d.disabled }) - }; - } - }; - - var stateSetter = function(data) { - return function(state) { - if (state.active !== undefined) - data.forEach(function(series,i) { - series.disabled = !state.active[i]; - }); - } - }; - - function chart(selection) { - selection.each(function(data) { - var container = d3.select(this), - that = this; - nv.utils.initSVG(container); - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight1 = nv.utils.availableHeight(height, container, margin) - height2, - availableHeight2 = height2 - margin2.top - margin2.bottom; - - chart.update = function() { container.transition().duration(transitionDuration).call(chart) }; - chart.container = this; - - state - .setter(stateSetter(data), chart.update) - .getter(stateGetter(data)) - .update(); - - // DEPRECATED set state.disableddisabled - state.disabled = data.map(function(d) { return !!d.disabled }); - - if (!defaultState) { - var key; - defaultState = {}; - for (key in state) { - if (state[key] instanceof Array) - defaultState[key] = state[key].slice(0); - else - defaultState[key] = state[key]; - } - } - - // Display No Data message if there's nothing to show. - if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) { - nv.utils.noData(chart, container) - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - // Setup Scales - x = lines.xScale(); - y = lines.yScale(); - x2 = lines2.xScale(); - y2 = lines2.yScale(); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-lineWithFocusChart').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-lineWithFocusChart').append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-legendWrap'); - - var focusEnter = gEnter.append('g').attr('class', 'nv-focus'); - focusEnter.append('g').attr('class', 'nv-x nv-axis'); - focusEnter.append('g').attr('class', 'nv-y nv-axis'); - focusEnter.append('g').attr('class', 'nv-linesWrap'); - focusEnter.append('g').attr('class', 'nv-interactive'); - - var contextEnter = gEnter.append('g').attr('class', 'nv-context'); - contextEnter.append('g').attr('class', 'nv-x nv-axis'); - contextEnter.append('g').attr('class', 'nv-y nv-axis'); - contextEnter.append('g').attr('class', 'nv-linesWrap'); - contextEnter.append('g').attr('class', 'nv-brushBackground'); - contextEnter.append('g').attr('class', 'nv-x nv-brush'); - - // Legend - if (showLegend) { - legend.width(availableWidth); - - g.select('.nv-legendWrap') - .datum(data) - .call(legend); - - if ( margin.top != legend.height()) { - margin.top = legend.height(); - availableHeight1 = nv.utils.availableHeight(height, container, margin) - height2; - } - - g.select('.nv-legendWrap') - .attr('transform', 'translate(0,' + (-margin.top) +')') - } - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - - //Set up interactive layer - if (useInteractiveGuideline) { - interactiveLayer - .width(availableWidth) - .height(availableHeight1) - .margin({left:margin.left, top:margin.top}) - .svgContainer(container) - .xScale(x); - wrap.select(".nv-interactive").call(interactiveLayer); - } - - // Main Chart Component(s) - lines - .width(availableWidth) - .height(availableHeight1) - .color( - data - .map(function(d,i) { - return d.color || color(d, i); - }) - .filter(function(d,i) { - return !data[i].disabled; - }) - ); - - lines2 - .defined(lines.defined()) - .width(availableWidth) - .height(availableHeight2) - .color( - data - .map(function(d,i) { - return d.color || color(d, i); - }) - .filter(function(d,i) { - return !data[i].disabled; - }) - ); - - g.select('.nv-context') - .attr('transform', 'translate(0,' + ( availableHeight1 + margin.bottom + margin2.top) + ')') - - var contextLinesWrap = g.select('.nv-context .nv-linesWrap') - .datum(data.filter(function(d) { return !d.disabled })) - - d3.transition(contextLinesWrap).call(lines2); - - // Setup Main (Focus) Axes - xAxis - .scale(x) - ._ticks( nv.utils.calcTicksX(availableWidth/100, data) ) - .tickSize(-availableHeight1, 0); - - yAxis - .scale(y) - ._ticks( nv.utils.calcTicksY(availableHeight1/36, data) ) - .tickSize( -availableWidth, 0); - - g.select('.nv-focus .nv-x.nv-axis') - .attr('transform', 'translate(0,' + availableHeight1 + ')'); - - // Setup Brush - brush - .x(x2) - .on('brush', function() { - onBrush(); - }); - - if (brushExtent) brush.extent(brushExtent); - - var brushBG = g.select('.nv-brushBackground').selectAll('g') - .data([brushExtent || brush.extent()]) - - var brushBGenter = brushBG.enter() - .append('g'); - - brushBGenter.append('rect') - .attr('class', 'left') - .attr('x', 0) - .attr('y', 0) - .attr('height', availableHeight2); - - brushBGenter.append('rect') - .attr('class', 'right') - .attr('x', 0) - .attr('y', 0) - .attr('height', availableHeight2); - - var gBrush = g.select('.nv-x.nv-brush') - .call(brush); - gBrush.selectAll('rect') - .attr('height', availableHeight2); - gBrush.selectAll('.resize').append('path').attr('d', resizePath); - - onBrush(); - - // Setup Secondary (Context) Axes - x2Axis - .scale(x2) - ._ticks( nv.utils.calcTicksX(availableWidth/100, data) ) - .tickSize(-availableHeight2, 0); - - g.select('.nv-context .nv-x.nv-axis') - .attr('transform', 'translate(0,' + y2.range()[0] + ')'); - d3.transition(g.select('.nv-context .nv-x.nv-axis')) - .call(x2Axis); - - y2Axis - .scale(y2) - ._ticks( nv.utils.calcTicksY(availableHeight2/36, data) ) - .tickSize( -availableWidth, 0); - - d3.transition(g.select('.nv-context .nv-y.nv-axis')) - .call(y2Axis); - - g.select('.nv-context .nv-x.nv-axis') - .attr('transform', 'translate(0,' + y2.range()[0] + ')'); - - //============================================================ - // Event Handling/Dispatching (in chart's scope) - //------------------------------------------------------------ - - legend.dispatch.on('stateChange', function(newState) { - for (var key in newState) - state[key] = newState[key]; - dispatch.stateChange(state); - chart.update(); - }); - - interactiveLayer.dispatch.on('elementMousemove', function(e) { - lines.clearHighlights(); - var singlePoint, pointIndex, pointXLocation, allData = []; - data - .filter(function(series, i) { - series.seriesIndex = i; - return !series.disabled; - }) - .forEach(function(series,i) { - var extent = brush.empty() ? x2.domain() : brush.extent(); - var currentValues = series.values.filter(function(d,i) { - return lines.x()(d,i) >= extent[0] && lines.x()(d,i) <= extent[1]; - }); - - pointIndex = nv.interactiveBisect(currentValues, e.pointXValue, lines.x()); - var point = currentValues[pointIndex]; - var pointYValue = chart.y()(point, pointIndex); - if (pointYValue != null) { - lines.highlightPoint(i, pointIndex, true); - } - if (point === undefined) return; - if (singlePoint === undefined) singlePoint = point; - if (pointXLocation === undefined) pointXLocation = chart.xScale()(chart.x()(point,pointIndex)); - allData.push({ - key: series.key, - value: chart.y()(point, pointIndex), - color: color(series,series.seriesIndex) - }); - }); - //Highlight the tooltip entry based on which point the mouse is closest to. - if (allData.length > 2) { - var yValue = chart.yScale().invert(e.mouseY); - var domainExtent = Math.abs(chart.yScale().domain()[0] - chart.yScale().domain()[1]); - var threshold = 0.03 * domainExtent; - var indexToHighlight = nv.nearestValueIndex(allData.map(function(d){return d.value}),yValue,threshold); - if (indexToHighlight !== null) - allData[indexToHighlight].highlight = true; - } - - var xValue = xAxis.tickFormat()(chart.x()(singlePoint,pointIndex)); - interactiveLayer.tooltip - .position({left: e.mouseX + margin.left, top: e.mouseY + margin.top}) - .chartContainer(that.parentNode) - .valueFormatter(function(d,i) { - return d == null ? "N/A" : yAxis.tickFormat()(d); - }) - .data({ - value: xValue, - index: pointIndex, - series: allData - })(); - - interactiveLayer.renderGuideLine(pointXLocation); - - }); - - interactiveLayer.dispatch.on("elementMouseout",function(e) { - lines.clearHighlights(); - }); - - dispatch.on('changeState', function(e) { - if (typeof e.disabled !== 'undefined') { - data.forEach(function(series,i) { - series.disabled = e.disabled[i]; - }); - } - chart.update(); - }); - - //============================================================ - // Functions - //------------------------------------------------------------ - - // Taken from crossfilter (http://square.github.com/crossfilter/) - function resizePath(d) { - var e = +(d == 'e'), - x = e ? 1 : -1, - y = availableHeight2 / 3; - return 'M' + (.5 * x) + ',' + y - + 'A6,6 0 0 ' + e + ' ' + (6.5 * x) + ',' + (y + 6) - + 'V' + (2 * y - 6) - + 'A6,6 0 0 ' + e + ' ' + (.5 * x) + ',' + (2 * y) - + 'Z' - + 'M' + (2.5 * x) + ',' + (y + 8) - + 'V' + (2 * y - 8) - + 'M' + (4.5 * x) + ',' + (y + 8) - + 'V' + (2 * y - 8); - } - - - function updateBrushBG() { - if (!brush.empty()) brush.extent(brushExtent); - brushBG - .data([brush.empty() ? x2.domain() : brushExtent]) - .each(function(d,i) { - var leftWidth = x2(d[0]) - x.range()[0], - rightWidth = availableWidth - x2(d[1]); - d3.select(this).select('.left') - .attr('width', leftWidth < 0 ? 0 : leftWidth); - - d3.select(this).select('.right') - .attr('x', x2(d[1])) - .attr('width', rightWidth < 0 ? 0 : rightWidth); - }); - } - - - function onBrush() { - brushExtent = brush.empty() ? null : brush.extent(); - var extent = brush.empty() ? x2.domain() : brush.extent(); - - //The brush extent cannot be less than one. If it is, don't update the line chart. - if (Math.abs(extent[0] - extent[1]) <= 1) { - return; - } - - dispatch.brush({extent: extent, brush: brush}); - - - updateBrushBG(); - - // Update Main (Focus) - var focusLinesWrap = g.select('.nv-focus .nv-linesWrap') - .datum( - data - .filter(function(d) { return !d.disabled }) - .map(function(d,i) { - return { - key: d.key, - area: d.area, - values: d.values.filter(function(d,i) { - return lines.x()(d,i) >= extent[0] && lines.x()(d,i) <= extent[1]; - }) - } - }) - ); - focusLinesWrap.transition().duration(transitionDuration).call(lines); - - - // Update Main (Focus) Axes - g.select('.nv-focus .nv-x.nv-axis').transition().duration(transitionDuration) - .call(xAxis); - g.select('.nv-focus .nv-y.nv-axis').transition().duration(transitionDuration) - .call(yAxis); - } - }); - - return chart; - } - - //============================================================ - // Event Handling/Dispatching (out of chart's scope) - //------------------------------------------------------------ - - lines.dispatch.on('elementMouseover.tooltip', function(evt) { - tooltip.data(evt).position(evt.pos).hidden(false); - }); - - lines.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true) - }); - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - // expose chart's sub-components - chart.dispatch = dispatch; - chart.legend = legend; - chart.lines = lines; - chart.lines2 = lines2; - chart.xAxis = xAxis; - chart.yAxis = yAxis; - chart.x2Axis = x2Axis; - chart.y2Axis = y2Axis; - chart.interactiveLayer = interactiveLayer; - chart.tooltip = tooltip; - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - focusHeight: {get: function(){return height2;}, set: function(_){height2=_;}}, - showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}}, - brushExtent: {get: function(){return brushExtent;}, set: function(_){brushExtent=_;}}, - defaultState: {get: function(){return defaultState;}, set: function(_){defaultState=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - - // deprecated options - tooltips: {get: function(){return tooltip.enabled();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltips', 'use chart.tooltip.enabled() instead'); - tooltip.enabled(!!_); - }}, - tooltipContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'use chart.tooltip.contentGenerator() instead'); - tooltip.contentGenerator(_); - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - focusMargin: {get: function(){return margin2;}, set: function(_){ - margin2.top = _.top !== undefined ? _.top : margin2.top; - margin2.right = _.right !== undefined ? _.right : margin2.right; - margin2.bottom = _.bottom !== undefined ? _.bottom : margin2.bottom; - margin2.left = _.left !== undefined ? _.left : margin2.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - legend.color(color); - // line color is handled above? - }}, - interpolate: {get: function(){return lines.interpolate();}, set: function(_){ - lines.interpolate(_); - lines2.interpolate(_); - }}, - xTickFormat: {get: function(){return xAxis.tickFormat();}, set: function(_){ - xAxis.tickFormat(_); - x2Axis.tickFormat(_); - }}, - yTickFormat: {get: function(){return yAxis.tickFormat();}, set: function(_){ - yAxis.tickFormat(_); - y2Axis.tickFormat(_); - }}, - duration: {get: function(){return transitionDuration;}, set: function(_){ - transitionDuration=_; - yAxis.duration(transitionDuration); - y2Axis.duration(transitionDuration); - xAxis.duration(transitionDuration); - x2Axis.duration(transitionDuration); - }}, - x: {get: function(){return lines.x();}, set: function(_){ - lines.x(_); - lines2.x(_); - }}, - y: {get: function(){return lines.y();}, set: function(_){ - lines.y(_); - lines2.y(_); - }}, - useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){ - useInteractiveGuideline = _; - if (useInteractiveGuideline) { - lines.interactive(false); - lines.useVoronoi(false); - } - }} - }); - - nv.utils.inheritOptions(chart, lines); - nv.utils.initOptions(chart); - - return chart; - }; - nv.models.multiBar = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = 960 - , height = 500 - , x = d3.scale.ordinal() - , y = d3.scale.linear() - , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one - , container = null - , getX = function(d) { return d.x } - , getY = function(d) { return d.y } - , getYerr = function(d) { return d.yErr } - , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar graphs... user can always do chart.forceY([]) to remove - , clipEdge = true - , stacked = false - , stackOffset = 'zero' // options include 'silhouette', 'wiggle', 'expand', 'zero', or a custom function - , color = nv.utils.defaultColor() - , errorBarColor = nv.utils.defaultColor() - , hideable = false - , barColor = null // adding the ability to set the color for each rather than the whole group - , disabled // used in conjunction with barColor to communicate from multiBarHorizontalChart what series are disabled - , duration = 500 - , xDomain - , yDomain - , xRange - , yRange - , groupSpacing = 0.1 - , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd') - ; - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var x0, y0 //used to store previous scales - , renderWatch = nv.utils.renderWatch(dispatch, duration) - ; - - var last_datalength = 0; - - function chart(selection) { - renderWatch.reset(); - selection.each(function(data) { - var availableWidth = width - margin.left - margin.right, - availableHeight = height - margin.top - margin.bottom; - - container = d3.select(this); - nv.utils.initSVG(container); - var nonStackableCount = 0; - // This function defines the requirements for render complete - var endFn = function(d, i) { - if (d.series === data.length - 1 && i === data[0].values.length - 1) - return true; - return false; - }; - - if(hideable && data.length) hideable = [{ - values: data[0].values.map(function(d) { - return { - x: d.x, - y: 0, - series: d.series, - size: 0.01 - };} - )}]; - - if (stacked) { - var parsed = d3.layout.stack() - .offset(stackOffset) - .values(function(d){ return d.values }) - .y(getY) - (!data.length && hideable ? hideable : data); - - parsed.forEach(function(series, i){ - // if series is non-stackable, use un-parsed data - if (series.nonStackable) { - data[i].nonStackableSeries = nonStackableCount++; - parsed[i] = data[i]; - } else { - // don't stack this seires on top of the nonStackable seriees - if (i > 0 && parsed[i - 1].nonStackable){ - parsed[i].values.map(function(d,j){ - d.y0 -= parsed[i - 1].values[j].y; - d.y1 = d.y0 + d.y; - }); - } - } - }); - data = parsed; - } - //add series index and key to each data point for reference - data.forEach(function(series, i) { - series.values.forEach(function(point) { - point.series = i; - point.key = series.key; - }); - }); - - // HACK for negative value stacking - if (stacked) { - data[0].values.map(function(d,i) { - var posBase = 0, negBase = 0; - data.map(function(d, idx) { - if (!data[idx].nonStackable) { - var f = d.values[i] - f.size = Math.abs(f.y); - if (f.y<0) { - f.y1 = negBase; - negBase = negBase - f.size; - } else - { - f.y1 = f.size + posBase; - posBase = posBase + f.size; - } - } - - }); - }); - } - // Setup Scales - // remap and flatten the data for use in calculating the scales' domains - var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and yDomain, no need to calculate - data.map(function(d, idx) { - return d.values.map(function(d,i) { - return { x: getX(d,i), y: getY(d,i), y0: d.y0, y1: d.y1, idx:idx, yErr: getYerr(d,i)} - }) - }); - - x.domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x })) - .rangeBands(xRange || [0, availableWidth], groupSpacing); - - y.domain(yDomain || d3.extent(d3.merge( - d3.merge(seriesData).map(function(d) { - var domain = d.y; - // increase the domain range if this series is stackable - if (stacked && !data[d.idx].nonStackable) { - if (d.y > 0){ - domain = d.y1 - } else { - domain = d.y1 + d.y - } - } - var yerr = d.yErr; - if (yerr) { - if (yerr.length) { - return [domain + yerr[0], domain + yerr[1]]; - } else { - yerr = Math.abs(yerr) - return [domain - yerr, domain + yerr]; - } - } else { - return [domain]; - } - })).concat(forceY))) - .range(yRange || [availableHeight, 0]); - - // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point - if (x.domain()[0] === x.domain()[1]) - x.domain()[0] ? - x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01]) - : x.domain([-1,1]); - - if (y.domain()[0] === y.domain()[1]) - y.domain()[0] ? - y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01]) - : y.domain([-1,1]); - - x0 = x0 || x; - y0 = y0 || y; - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-multibar').data([data]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multibar'); - var defsEnter = wrapEnter.append('defs'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-groups'); - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - defsEnter.append('clipPath') - .attr('id', 'nv-edge-clip-' + id) - .append('rect'); - wrap.select('#nv-edge-clip-' + id + ' rect') - .attr('width', availableWidth) - .attr('height', availableHeight); - - g.attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id + ')' : ''); - - var groups = wrap.select('.nv-groups').selectAll('.nv-group') - .data(function(d) { return d }, function(d,i) { return i }); - groups.enter().append('g') - .style('stroke-opacity', 1e-6) - .style('fill-opacity', 1e-6); - - var exitTransition = renderWatch - .transition(groups.exit().selectAll('g.nv-bar'), 'multibarExit', Math.min(100, duration)) - .attr('y', function(d, i, j) { - var yVal = y0(0) || 0; - if (stacked) { - if (data[d.series] && !data[d.series].nonStackable) { - yVal = y0(d.y0); - } - } - return yVal; - }) - .attr('height', 0) - .remove(); - if (exitTransition.delay) - exitTransition.delay(function(d,i) { - var delay = i * (duration / (last_datalength + 1)) - i; - return delay; - }); - groups - .attr('class', function(d,i) { return 'nv-group nv-series-' + i }) - .classed('hover', function(d) { return d.hover }) - .style('fill', function(d,i){ return color(d, i) }) - .style('stroke', function(d,i){ return color(d, i) }); - groups - .style('stroke-opacity', 1) - .style('fill-opacity', 0.75); - - var bars = groups.selectAll('g.nv-bar') - .data(function(d) { return (hideable && !data.length) ? hideable.values : d.values }); - bars.exit().remove(); - - var barsEnter = bars.enter().append('g') - .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive'}) - .attr('transform', function(d,i,j) { - var _x = stacked && !data[j].nonStackable ? 0 : (j * x.rangeBand() / data.length ); - var _y = y0(stacked && !data[j].nonStackable ? d.y0 : 0) || 0; - return 'translate(' + _x + ',' + _y + ')'; - }) - ; - - barsEnter.append('rect') - .attr('height', 0) - .attr('width', function(d,i,j) { return x.rangeBand() / (stacked && !data[j].nonStackable ? 1 : data.length) }) - .style('fill', function(d,i,j){ return color(d, j, i); }) - .style('stroke', function(d,i,j){ return color(d, j, i); }) - ; - bars - .on('mouseover', function(d,i) { //TODO: figure out why j works above, but not here - d3.select(this).classed('hover', true); - dispatch.elementMouseover({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - }) - .on('mouseout', function(d,i) { - d3.select(this).classed('hover', false); - dispatch.elementMouseout({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - }) - .on('mousemove', function(d,i) { - dispatch.elementMousemove({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - }) - .on('click', function(d,i) { - dispatch.elementClick({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - d3.event.stopPropagation(); - }) - .on('dblclick', function(d,i) { - dispatch.elementDblClick({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - d3.event.stopPropagation(); - }); - - if (getYerr(data[0].values[0], 0)) { - barsEnter.append('polyline'); - - bars.select('polyline') - .attr('fill', 'none') - .attr('stroke', function(d, i, j) { return errorBarColor(d, j, i); }) - .attr('points', function(d,i) { - var yerr = getYerr(d,i) - , mid = 0.8 * x.rangeBand() / ((stacked ? 1 : data.length) * 2); - yerr = yerr.length ? yerr : [-Math.abs(yerr), Math.abs(yerr)]; - yerr = yerr.map(function(e) { return y(e) - y(0); }); - var a = [[-mid, yerr[0]], [mid, yerr[0]], [0, yerr[0]], [0, yerr[1]], [-mid, yerr[1]], [mid, yerr[1]]]; - return a.map(function (path) { return path.join(',') }).join(' '); - }) - .attr('transform', function(d, i) { - var xOffset = x.rangeBand() / ((stacked ? 1 : data.length) * 2); - var yOffset = getY(d,i) < 0 ? y(getY(d, i)) - y(0) : 0; - return 'translate(' + xOffset + ', ' + yOffset + ')'; - }) - } - - bars - .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive'}) - - if (barColor) { - if (!disabled) disabled = data.map(function() { return true }); - bars.select('rect') - .style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker( disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j] ).toString(); }) - .style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker( disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j] ).toString(); }); - } - - var barSelection = - bars.watchTransition(renderWatch, 'multibar', Math.min(250, duration)) - .delay(function(d,i) { - return i * duration / data[0].values.length; - }); - if (stacked){ - barSelection - .attr('transform', function(d,i,j) { - var yVal = 0; - // if stackable, stack it on top of the previous series - if (!data[j].nonStackable) { - yVal = y(d.y1); - } else { - if (getY(d,i) < 0){ - yVal = y(0); - } else { - if (y(0) - y(getY(d,i)) < -1){ - yVal = y(0) - 1; - } else { - yVal = y(getY(d, i)) || 0; - } - } - } - var width = 0; - if (data[j].nonStackable) { - width = d.series * x.rangeBand() / data.length; - if (data.length !== nonStackableCount){ - width = data[j].nonStackableSeries * x.rangeBand()/(nonStackableCount*2); - } - } - var xVal = width + x(getX(d, i)); - return 'translate(' + xVal + ',' + yVal + ')'; - }) - .select('rect') - .attr('height', function(d,i,j) { - if (!data[j].nonStackable) { - return Math.max(Math.abs(y(d.y+d.y0) - y(d.y0)), 1); - } else { - return Math.max(Math.abs(y(getY(d,i)) - y(0)),1) || 0; - } - }) - .attr('width', function(d,i,j){ - if (!data[j].nonStackable) { - return x.rangeBand(); - } else { - // if all series are nonStacable, take the full width - var width = (x.rangeBand() / nonStackableCount); - // otherwise, nonStackable graph will be only taking the half-width - // of the x rangeBand - if (data.length !== nonStackableCount) { - width = x.rangeBand()/(nonStackableCount*2); - } - return width; - } - }); - } - else { - barSelection.attr('transform', function(d,i) { - var xVal = d.series * x.rangeBand() / data.length + x(getX(d, i)); - var yVal = getY(d,i) < 0 ? - y(0) : - y(0) - y(getY(d,i)) < 1 ? - y(0) - 1 : - y(getY(d,i)) || 0; - return 'translate(' + xVal + ',' + yVal + ')'; - }) - .select('rect') - .attr('width', x.rangeBand() / data.length) - .attr('height', function(d,i) { - return Math.max(Math.abs(y(getY(d,i)) - y(0)),1) || 0; - }); - } - - //store old scales for use in transitions on update - x0 = x.copy(); - y0 = y.copy(); - - // keep track of the last data value length for transition calculations - if (data[0] && data[0].values) { - last_datalength = data[0].values.length; - } - - }); - - renderWatch.renderEnd('multibar immediate'); - - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - x: {get: function(){return getX;}, set: function(_){getX=_;}}, - y: {get: function(){return getY;}, set: function(_){getY=_;}}, - yErr: {get: function(){return getYerr;}, set: function(_){getYerr=_;}}, - xScale: {get: function(){return x;}, set: function(_){x=_;}}, - yScale: {get: function(){return y;}, set: function(_){y=_;}}, - xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}}, - yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}}, - xRange: {get: function(){return xRange;}, set: function(_){xRange=_;}}, - yRange: {get: function(){return yRange;}, set: function(_){yRange=_;}}, - forceY: {get: function(){return forceY;}, set: function(_){forceY=_;}}, - stacked: {get: function(){return stacked;}, set: function(_){stacked=_;}}, - stackOffset: {get: function(){return stackOffset;}, set: function(_){stackOffset=_;}}, - clipEdge: {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}}, - disabled: {get: function(){return disabled;}, set: function(_){disabled=_;}}, - id: {get: function(){return id;}, set: function(_){id=_;}}, - hideable: {get: function(){return hideable;}, set: function(_){hideable=_;}}, - groupSpacing:{get: function(){return groupSpacing;}, set: function(_){groupSpacing=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }}, - barColor: {get: function(){return barColor;}, set: function(_){ - barColor = _ ? nv.utils.getColor(_) : null; - }}, - errorBarColor: {get: function(){return errorBarColor;}, set: function(_){ - errorBarColor = _ ? nv.utils.getColor(_) : null; - }} - }); - - nv.utils.initOptions(chart); - - return chart; - }; - - nv.models.multiBarChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var multibar = nv.models.multiBar() - , xAxis = nv.models.axis() - , yAxis = nv.models.axis() - , legend = nv.models.legend() - , controls = nv.models.legend() - , tooltip = nv.models.tooltip() - ; - - var margin = {top: 30, right: 20, bottom: 50, left: 60} - , width = null - , height = null - , color = nv.utils.defaultColor() - , showControls = true - , controlLabels = {} - , showLegend = true - , showXAxis = true - , showYAxis = true - , rightAlignYAxis = false - , reduceXTicks = true // if false a tick will show for every data point - , staggerLabels = false - , rotateLabels = 0 - , x //can be accessed via chart.xScale() - , y //can be accessed via chart.yScale() - , state = nv.utils.state() - , defaultState = null - , noData = null - , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd') - , controlWidth = function() { return showControls ? 180 : 0 } - , duration = 250 - ; - - state.stacked = false // DEPRECATED Maintained for backward compatibility - - multibar.stacked(false); - xAxis - .orient('bottom') - .tickPadding(7) - .showMaxMin(false) - .tickFormat(function(d) { return d }) - ; - yAxis - .orient((rightAlignYAxis) ? 'right' : 'left') - .tickFormat(d3.format(',.1f')) - ; - - tooltip - .duration(0) - .valueFormatter(function(d, i) { - return yAxis.tickFormat()(d, i); - }) - .headerFormatter(function(d, i) { - return xAxis.tickFormat()(d, i); - }); - - controls.updateState(false); - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var renderWatch = nv.utils.renderWatch(dispatch); - var stacked = false; - - var stateGetter = function(data) { - return function(){ - return { - active: data.map(function(d) { return !d.disabled }), - stacked: stacked - }; - } - }; - - var stateSetter = function(data) { - return function(state) { - if (state.stacked !== undefined) - stacked = state.stacked; - if (state.active !== undefined) - data.forEach(function(series,i) { - series.disabled = !state.active[i]; - }); - } - }; - - function chart(selection) { - renderWatch.reset(); - renderWatch.models(multibar); - if (showXAxis) renderWatch.models(xAxis); - if (showYAxis) renderWatch.models(yAxis); - - selection.each(function(data) { - var container = d3.select(this), - that = this; - nv.utils.initSVG(container); - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - chart.update = function() { - if (duration === 0) - container.call(chart); - else - container.transition() - .duration(duration) - .call(chart); - }; - chart.container = this; - - state - .setter(stateSetter(data), chart.update) - .getter(stateGetter(data)) - .update(); - - // DEPRECATED set state.disableddisabled - state.disabled = data.map(function(d) { return !!d.disabled }); - - if (!defaultState) { - var key; - defaultState = {}; - for (key in state) { - if (state[key] instanceof Array) - defaultState[key] = state[key].slice(0); - else - defaultState[key] = state[key]; - } - } - - // Display noData message if there's nothing to show. - if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) { - nv.utils.noData(chart, container) - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - // Setup Scales - x = multibar.xScale(); - y = multibar.yScale(); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-multiBarWithLegend').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multiBarWithLegend').append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-x nv-axis'); - gEnter.append('g').attr('class', 'nv-y nv-axis'); - gEnter.append('g').attr('class', 'nv-barsWrap'); - gEnter.append('g').attr('class', 'nv-legendWrap'); - gEnter.append('g').attr('class', 'nv-controlsWrap'); - - // Legend - if (showLegend) { - legend.width(availableWidth - controlWidth()); - - g.select('.nv-legendWrap') - .datum(data) - .call(legend); - - if ( margin.top != legend.height()) { - margin.top = legend.height(); - availableHeight = nv.utils.availableHeight(height, container, margin); - } - - g.select('.nv-legendWrap') - .attr('transform', 'translate(' + controlWidth() + ',' + (-margin.top) +')'); - } - - // Controls - if (showControls) { - var controlsData = [ - { key: controlLabels.grouped || 'Grouped', disabled: multibar.stacked() }, - { key: controlLabels.stacked || 'Stacked', disabled: !multibar.stacked() } - ]; - - controls.width(controlWidth()).color(['#444', '#444', '#444']); - g.select('.nv-controlsWrap') - .datum(controlsData) - .attr('transform', 'translate(0,' + (-margin.top) +')') - .call(controls); - } - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - if (rightAlignYAxis) { - g.select(".nv-y.nv-axis") - .attr("transform", "translate(" + availableWidth + ",0)"); - } - - // Main Chart Component(s) - multibar - .disabled(data.map(function(series) { return series.disabled })) - .width(availableWidth) - .height(availableHeight) - .color(data.map(function(d,i) { - return d.color || color(d, i); - }).filter(function(d,i) { return !data[i].disabled })); - - - var barsWrap = g.select('.nv-barsWrap') - .datum(data.filter(function(d) { return !d.disabled })); - - barsWrap.call(multibar); - - // Setup Axes - if (showXAxis) { - xAxis - .scale(x) - ._ticks( nv.utils.calcTicksX(availableWidth/100, data) ) - .tickSize(-availableHeight, 0); - - g.select('.nv-x.nv-axis') - .attr('transform', 'translate(0,' + y.range()[0] + ')'); - g.select('.nv-x.nv-axis') - .call(xAxis); - - var xTicks = g.select('.nv-x.nv-axis > g').selectAll('g'); - - xTicks - .selectAll('line, text') - .style('opacity', 1) - - if (staggerLabels) { - var getTranslate = function(x,y) { - return "translate(" + x + "," + y + ")"; - }; - - var staggerUp = 5, staggerDown = 17; //pixels to stagger by - // Issue #140 - xTicks - .selectAll("text") - .attr('transform', function(d,i,j) { - return getTranslate(0, (j % 2 == 0 ? staggerUp : staggerDown)); - }); - - var totalInBetweenTicks = d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length; - g.selectAll(".nv-x.nv-axis .nv-axisMaxMin text") - .attr("transform", function(d,i) { - return getTranslate(0, (i === 0 || totalInBetweenTicks % 2 !== 0) ? staggerDown : staggerUp); - }); - } - - if (reduceXTicks) - xTicks - .filter(function(d,i) { - return i % Math.ceil(data[0].values.length / (availableWidth / 100)) !== 0; - }) - .selectAll('text, line') - .style('opacity', 0); - - if(rotateLabels) - xTicks - .selectAll('.tick text') - .attr('transform', 'rotate(' + rotateLabels + ' 0,0)') - .style('text-anchor', rotateLabels > 0 ? 'start' : 'end'); - - g.select('.nv-x.nv-axis').selectAll('g.nv-axisMaxMin text') - .style('opacity', 1); - } - - if (showYAxis) { - yAxis - .scale(y) - ._ticks( nv.utils.calcTicksY(availableHeight/36, data) ) - .tickSize( -availableWidth, 0); - - g.select('.nv-y.nv-axis') - .call(yAxis); - } - - //============================================================ - // Event Handling/Dispatching (in chart's scope) - //------------------------------------------------------------ - - legend.dispatch.on('stateChange', function(newState) { - for (var key in newState) - state[key] = newState[key]; - dispatch.stateChange(state); - chart.update(); - }); - - controls.dispatch.on('legendClick', function(d,i) { - if (!d.disabled) return; - controlsData = controlsData.map(function(s) { - s.disabled = true; - return s; - }); - d.disabled = false; - - switch (d.key) { - case 'Grouped': - case controlLabels.grouped: - multibar.stacked(false); - break; - case 'Stacked': - case controlLabels.stacked: - multibar.stacked(true); - break; - } - - state.stacked = multibar.stacked(); - dispatch.stateChange(state); - chart.update(); - }); - - // Update chart from a state object passed to event handler - dispatch.on('changeState', function(e) { - if (typeof e.disabled !== 'undefined') { - data.forEach(function(series,i) { - series.disabled = e.disabled[i]; - }); - state.disabled = e.disabled; - } - if (typeof e.stacked !== 'undefined') { - multibar.stacked(e.stacked); - state.stacked = e.stacked; - stacked = e.stacked; - } - chart.update(); - }); - }); - - renderWatch.renderEnd('multibarchart immediate'); - return chart; - } - - //============================================================ - // Event Handling/Dispatching (out of chart's scope) - //------------------------------------------------------------ - - multibar.dispatch.on('elementMouseover.tooltip', function(evt) { - evt.value = chart.x()(evt.data); - evt['series'] = { - key: evt.data.key, - value: chart.y()(evt.data), - color: evt.color - }; - tooltip.data(evt).hidden(false); - }); - - multibar.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true); - }); - - multibar.dispatch.on('elementMousemove.tooltip', function(evt) { - tooltip.position({top: d3.event.pageY, left: d3.event.pageX})(); - }); - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - // expose chart's sub-components - chart.dispatch = dispatch; - chart.multibar = multibar; - chart.legend = legend; - chart.controls = controls; - chart.xAxis = xAxis; - chart.yAxis = yAxis; - chart.state = state; - chart.tooltip = tooltip; - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}}, - showControls: {get: function(){return showControls;}, set: function(_){showControls=_;}}, - controlLabels: {get: function(){return controlLabels;}, set: function(_){controlLabels=_;}}, - showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}}, - showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}}, - defaultState: {get: function(){return defaultState;}, set: function(_){defaultState=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - reduceXTicks: {get: function(){return reduceXTicks;}, set: function(_){reduceXTicks=_;}}, - rotateLabels: {get: function(){return rotateLabels;}, set: function(_){rotateLabels=_;}}, - staggerLabels: {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}}, - - // deprecated options - tooltips: {get: function(){return tooltip.enabled();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltips', 'use chart.tooltip.enabled() instead'); - tooltip.enabled(!!_); - }}, - tooltipContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'use chart.tooltip.contentGenerator() instead'); - tooltip.contentGenerator(_); - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - multibar.duration(duration); - xAxis.duration(duration); - yAxis.duration(duration); - renderWatch.reset(duration); - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - legend.color(color); - }}, - rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){ - rightAlignYAxis = _; - yAxis.orient( rightAlignYAxis ? 'right' : 'left'); - }}, - barColor: {get: function(){return multibar.barColor;}, set: function(_){ - multibar.barColor(_); - legend.color(function(d,i) {return d3.rgb('#ccc').darker(i * 1.5).toString();}) - }} - }); - - nv.utils.inheritOptions(chart, multibar); - nv.utils.initOptions(chart); - - return chart; - }; - - nv.models.multiBarHorizontal = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = 960 - , height = 500 - , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one - , container = null - , x = d3.scale.ordinal() - , y = d3.scale.linear() - , getX = function(d) { return d.x } - , getY = function(d) { return d.y } - , getYerr = function(d) { return d.yErr } - , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar graphs... user can always do chart.forceY([]) to remove - , color = nv.utils.defaultColor() - , barColor = null // adding the ability to set the color for each rather than the whole group - , errorBarColor = nv.utils.defaultColor() - , disabled // used in conjunction with barColor to communicate from multiBarHorizontalChart what series are disabled - , stacked = false - , showValues = false - , showBarLabels = false - , valuePadding = 60 - , groupSpacing = 0.1 - , valueFormat = d3.format(',.2f') - , delay = 1200 - , xDomain - , yDomain - , xRange - , yRange - , duration = 250 - , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd') - ; - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var x0, y0; //used to store previous scales - var renderWatch = nv.utils.renderWatch(dispatch, duration); - - function chart(selection) { - renderWatch.reset(); - selection.each(function(data) { - var availableWidth = width - margin.left - margin.right, - availableHeight = height - margin.top - margin.bottom; - - container = d3.select(this); - nv.utils.initSVG(container); - - if (stacked) - data = d3.layout.stack() - .offset('zero') - .values(function(d){ return d.values }) - .y(getY) - (data); - - //add series index and key to each data point for reference - data.forEach(function(series, i) { - series.values.forEach(function(point) { - point.series = i; - point.key = series.key; - }); - }); - - // HACK for negative value stacking - if (stacked) - data[0].values.map(function(d,i) { - var posBase = 0, negBase = 0; - data.map(function(d) { - var f = d.values[i] - f.size = Math.abs(f.y); - if (f.y<0) { - f.y1 = negBase - f.size; - negBase = negBase - f.size; - } else - { - f.y1 = posBase; - posBase = posBase + f.size; - } - }); - }); - - // Setup Scales - // remap and flatten the data for use in calculating the scales' domains - var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and yDomain, no need to calculate - data.map(function(d) { - return d.values.map(function(d,i) { - return { x: getX(d,i), y: getY(d,i), y0: d.y0, y1: d.y1, yErr: getYerr(d,i) } - }) - }); - - x.domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x })) - .rangeBands(xRange || [0, availableHeight], groupSpacing); - - y.domain(yDomain || d3.extent(d3.merge( - d3.merge(seriesData).map(function(d) { - var domain = d.y; - if (stacked) { - if (d.y > 0){ - domain = d.y1 + d.y - } else { - domain = d.y1 - } - } - var yerr = d.yErr; - if (yerr) { - if (yerr.length) { - return [domain + yerr[0], domain + yerr[1]]; - } else { - yerr = Math.abs(yerr) - return [domain - yerr, domain + yerr]; - } - } else { - return [domain]; - } - })).concat(forceY))) - - if (showValues && !stacked) - y.range(yRange || [(y.domain()[0] < 0 ? valuePadding : 0), availableWidth - (y.domain()[1] > 0 ? valuePadding : 0) ]); - else - y.range(yRange || [0, availableWidth]); - - x0 = x0 || x; - y0 = y0 || d3.scale.linear().domain(y.domain()).range([y(0),y(0)]); - - // Setup containers and skeleton of chart - var wrap = d3.select(this).selectAll('g.nv-wrap.nv-multibarHorizontal').data([data]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multibarHorizontal'); - var defsEnter = wrapEnter.append('defs'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-groups'); - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - var groups = wrap.select('.nv-groups').selectAll('.nv-group') - .data(function(d) { return d }, function(d,i) { return i }); - groups.enter().append('g') - .style('stroke-opacity', 1e-6) - .style('fill-opacity', 1e-6); - groups.exit().watchTransition(renderWatch, 'multibarhorizontal: exit groups') - .style('stroke-opacity', 1e-6) - .style('fill-opacity', 1e-6) - .remove(); - groups - .attr('class', function(d,i) { return 'nv-group nv-series-' + i }) - .classed('hover', function(d) { return d.hover }) - .style('fill', function(d,i){ return color(d, i) }) - .style('stroke', function(d,i){ return color(d, i) }); - groups.watchTransition(renderWatch, 'multibarhorizontal: groups') - .style('stroke-opacity', 1) - .style('fill-opacity', .75); - - var bars = groups.selectAll('g.nv-bar') - .data(function(d) { return d.values }); - bars.exit().remove(); - - var barsEnter = bars.enter().append('g') - .attr('transform', function(d,i,j) { - return 'translate(' + y0(stacked ? d.y0 : 0) + ',' + (stacked ? 0 : (j * x.rangeBand() / data.length ) + x(getX(d,i))) + ')' - }); - - barsEnter.append('rect') - .attr('width', 0) - .attr('height', x.rangeBand() / (stacked ? 1 : data.length) ) - - bars - .on('mouseover', function(d,i) { //TODO: figure out why j works above, but not here - d3.select(this).classed('hover', true); - dispatch.elementMouseover({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - }) - .on('mouseout', function(d,i) { - d3.select(this).classed('hover', false); - dispatch.elementMouseout({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - }) - .on('mouseout', function(d,i) { - dispatch.elementMouseout({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - }) - .on('mousemove', function(d,i) { - dispatch.elementMousemove({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - }) - .on('click', function(d,i) { - dispatch.elementClick({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - d3.event.stopPropagation(); - }) - .on('dblclick', function(d,i) { - dispatch.elementDblClick({ - data: d, - index: i, - color: d3.select(this).style("fill") - }); - d3.event.stopPropagation(); - }); - - if (getYerr(data[0].values[0], 0)) { - barsEnter.append('polyline'); - - bars.select('polyline') - .attr('fill', 'none') - .attr('stroke', function(d,i,j) { return errorBarColor(d, j, i); }) - .attr('points', function(d,i) { - var xerr = getYerr(d,i) - , mid = 0.8 * x.rangeBand() / ((stacked ? 1 : data.length) * 2); - xerr = xerr.length ? xerr : [-Math.abs(xerr), Math.abs(xerr)]; - xerr = xerr.map(function(e) { return y(e) - y(0); }); - var a = [[xerr[0],-mid], [xerr[0],mid], [xerr[0],0], [xerr[1],0], [xerr[1],-mid], [xerr[1],mid]]; - return a.map(function (path) { return path.join(',') }).join(' '); - }) - .attr('transform', function(d,i) { - var mid = x.rangeBand() / ((stacked ? 1 : data.length) * 2); - return 'translate(' + (getY(d,i) < 0 ? 0 : y(getY(d,i)) - y(0)) + ', ' + mid + ')' - }); - } - - barsEnter.append('text'); - - if (showValues && !stacked) { - bars.select('text') - .attr('text-anchor', function(d,i) { return getY(d,i) < 0 ? 'end' : 'start' }) - .attr('y', x.rangeBand() / (data.length * 2)) - .attr('dy', '.32em') - .text(function(d,i) { - var t = valueFormat(getY(d,i)) - , yerr = getYerr(d,i); - if (yerr === undefined) - return t; - if (!yerr.length) - return t + '±' + valueFormat(Math.abs(yerr)); - return t + '+' + valueFormat(Math.abs(yerr[1])) + '-' + valueFormat(Math.abs(yerr[0])); - }); - bars.watchTransition(renderWatch, 'multibarhorizontal: bars') - .select('text') - .attr('x', function(d,i) { return getY(d,i) < 0 ? -4 : y(getY(d,i)) - y(0) + 4 }) - } else { - bars.selectAll('text').text(''); - } - - if (showBarLabels && !stacked) { - barsEnter.append('text').classed('nv-bar-label',true); - bars.select('text.nv-bar-label') - .attr('text-anchor', function(d,i) { return getY(d,i) < 0 ? 'start' : 'end' }) - .attr('y', x.rangeBand() / (data.length * 2)) - .attr('dy', '.32em') - .text(function(d,i) { return getX(d,i) }); - bars.watchTransition(renderWatch, 'multibarhorizontal: bars') - .select('text.nv-bar-label') - .attr('x', function(d,i) { return getY(d,i) < 0 ? y(0) - y(getY(d,i)) + 4 : -4 }); - } - else { - bars.selectAll('text.nv-bar-label').text(''); - } - - bars - .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive'}) - - if (barColor) { - if (!disabled) disabled = data.map(function() { return true }); - bars - .style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker( disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j] ).toString(); }) - .style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker( disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j] ).toString(); }); - } - - if (stacked) - bars.watchTransition(renderWatch, 'multibarhorizontal: bars') - .attr('transform', function(d,i) { - return 'translate(' + y(d.y1) + ',' + x(getX(d,i)) + ')' - }) - .select('rect') - .attr('width', function(d,i) { - return Math.abs(y(getY(d,i) + d.y0) - y(d.y0)) - }) - .attr('height', x.rangeBand() ); - else - bars.watchTransition(renderWatch, 'multibarhorizontal: bars') - .attr('transform', function(d,i) { - //TODO: stacked must be all positive or all negative, not both? - return 'translate(' + - (getY(d,i) < 0 ? y(getY(d,i)) : y(0)) - + ',' + - (d.series * x.rangeBand() / data.length - + - x(getX(d,i)) ) - + ')' - }) - .select('rect') - .attr('height', x.rangeBand() / data.length ) - .attr('width', function(d,i) { - return Math.max(Math.abs(y(getY(d,i)) - y(0)),1) - }); - - //store old scales for use in transitions on update - x0 = x.copy(); - y0 = y.copy(); - - }); - - renderWatch.renderEnd('multibarHorizontal immediate'); - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - x: {get: function(){return getX;}, set: function(_){getX=_;}}, - y: {get: function(){return getY;}, set: function(_){getY=_;}}, - yErr: {get: function(){return getYerr;}, set: function(_){getYerr=_;}}, - xScale: {get: function(){return x;}, set: function(_){x=_;}}, - yScale: {get: function(){return y;}, set: function(_){y=_;}}, - xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}}, - yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}}, - xRange: {get: function(){return xRange;}, set: function(_){xRange=_;}}, - yRange: {get: function(){return yRange;}, set: function(_){yRange=_;}}, - forceY: {get: function(){return forceY;}, set: function(_){forceY=_;}}, - stacked: {get: function(){return stacked;}, set: function(_){stacked=_;}}, - showValues: {get: function(){return showValues;}, set: function(_){showValues=_;}}, - // this shows the group name, seems pointless? - //showBarLabels: {get: function(){return showBarLabels;}, set: function(_){showBarLabels=_;}}, - disabled: {get: function(){return disabled;}, set: function(_){disabled=_;}}, - id: {get: function(){return id;}, set: function(_){id=_;}}, - valueFormat: {get: function(){return valueFormat;}, set: function(_){valueFormat=_;}}, - valuePadding: {get: function(){return valuePadding;}, set: function(_){valuePadding=_;}}, - groupSpacing:{get: function(){return groupSpacing;}, set: function(_){groupSpacing=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }}, - barColor: {get: function(){return barColor;}, set: function(_){ - barColor = _ ? nv.utils.getColor(_) : null; - }}, - errorBarColor: {get: function(){return errorBarColor;}, set: function(_){ - errorBarColor = _ ? nv.utils.getColor(_) : null; - }} - }); - - nv.utils.initOptions(chart); - - return chart; - }; - - nv.models.multiBarHorizontalChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var multibar = nv.models.multiBarHorizontal() - , xAxis = nv.models.axis() - , yAxis = nv.models.axis() - , legend = nv.models.legend().height(30) - , controls = nv.models.legend().height(30) - , tooltip = nv.models.tooltip() - ; - - var margin = {top: 30, right: 20, bottom: 50, left: 60} - , width = null - , height = null - , color = nv.utils.defaultColor() - , showControls = true - , controlLabels = {} - , showLegend = true - , showXAxis = true - , showYAxis = true - , stacked = false - , x //can be accessed via chart.xScale() - , y //can be accessed via chart.yScale() - , state = nv.utils.state() - , defaultState = null - , noData = null - , dispatch = d3.dispatch('stateChange', 'changeState','renderEnd') - , controlWidth = function() { return showControls ? 180 : 0 } - , duration = 250 - ; - - state.stacked = false; // DEPRECATED Maintained for backward compatibility - - multibar.stacked(stacked); - - xAxis - .orient('left') - .tickPadding(5) - .showMaxMin(false) - .tickFormat(function(d) { return d }) - ; - yAxis - .orient('bottom') - .tickFormat(d3.format(',.1f')) - ; - - tooltip - .duration(0) - .valueFormatter(function(d, i) { - return yAxis.tickFormat()(d, i); - }) - .headerFormatter(function(d, i) { - return xAxis.tickFormat()(d, i); - }); - - controls.updateState(false); - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var stateGetter = function(data) { - return function(){ - return { - active: data.map(function(d) { return !d.disabled }), - stacked: stacked - }; - } - }; - - var stateSetter = function(data) { - return function(state) { - if (state.stacked !== undefined) - stacked = state.stacked; - if (state.active !== undefined) - data.forEach(function(series,i) { - series.disabled = !state.active[i]; - }); - } - }; - - var renderWatch = nv.utils.renderWatch(dispatch, duration); - - function chart(selection) { - renderWatch.reset(); - renderWatch.models(multibar); - if (showXAxis) renderWatch.models(xAxis); - if (showYAxis) renderWatch.models(yAxis); - - selection.each(function(data) { - var container = d3.select(this), - that = this; - nv.utils.initSVG(container); - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - chart.update = function() { container.transition().duration(duration).call(chart) }; - chart.container = this; - - stacked = multibar.stacked(); - - state - .setter(stateSetter(data), chart.update) - .getter(stateGetter(data)) - .update(); - - // DEPRECATED set state.disableddisabled - state.disabled = data.map(function(d) { return !!d.disabled }); - - if (!defaultState) { - var key; - defaultState = {}; - for (key in state) { - if (state[key] instanceof Array) - defaultState[key] = state[key].slice(0); - else - defaultState[key] = state[key]; - } - } - - // Display No Data message if there's nothing to show. - if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) { - nv.utils.noData(chart, container) - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - // Setup Scales - x = multibar.xScale(); - y = multibar.yScale(); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-multiBarHorizontalChart').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multiBarHorizontalChart').append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-x nv-axis'); - gEnter.append('g').attr('class', 'nv-y nv-axis') - .append('g').attr('class', 'nv-zeroLine') - .append('line'); - gEnter.append('g').attr('class', 'nv-barsWrap'); - gEnter.append('g').attr('class', 'nv-legendWrap'); - gEnter.append('g').attr('class', 'nv-controlsWrap'); - - // Legend - if (showLegend) { - legend.width(availableWidth - controlWidth()); - - g.select('.nv-legendWrap') - .datum(data) - .call(legend); - - if ( margin.top != legend.height()) { - margin.top = legend.height(); - availableHeight = nv.utils.availableHeight(height, container, margin); - } - - g.select('.nv-legendWrap') - .attr('transform', 'translate(' + controlWidth() + ',' + (-margin.top) +')'); - } - - // Controls - if (showControls) { - var controlsData = [ - { key: controlLabels.grouped || 'Grouped', disabled: multibar.stacked() }, - { key: controlLabels.stacked || 'Stacked', disabled: !multibar.stacked() } - ]; - - controls.width(controlWidth()).color(['#444', '#444', '#444']); - g.select('.nv-controlsWrap') - .datum(controlsData) - .attr('transform', 'translate(0,' + (-margin.top) +')') - .call(controls); - } - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - // Main Chart Component(s) - multibar - .disabled(data.map(function(series) { return series.disabled })) - .width(availableWidth) - .height(availableHeight) - .color(data.map(function(d,i) { - return d.color || color(d, i); - }).filter(function(d,i) { return !data[i].disabled })); - - var barsWrap = g.select('.nv-barsWrap') - .datum(data.filter(function(d) { return !d.disabled })); - - barsWrap.transition().call(multibar); - - // Setup Axes - if (showXAxis) { - xAxis - .scale(x) - ._ticks( nv.utils.calcTicksY(availableHeight/24, data) ) - .tickSize(-availableWidth, 0); - - g.select('.nv-x.nv-axis').call(xAxis); - - var xTicks = g.select('.nv-x.nv-axis').selectAll('g'); - - xTicks - .selectAll('line, text'); - } - - if (showYAxis) { - yAxis - .scale(y) - ._ticks( nv.utils.calcTicksX(availableWidth/100, data) ) - .tickSize( -availableHeight, 0); - - g.select('.nv-y.nv-axis') - .attr('transform', 'translate(0,' + availableHeight + ')'); - g.select('.nv-y.nv-axis').call(yAxis); - } - - // Zero line - g.select(".nv-zeroLine line") - .attr("x1", y(0)) - .attr("x2", y(0)) - .attr("y1", 0) - .attr("y2", -availableHeight) - ; - - //============================================================ - // Event Handling/Dispatching (in chart's scope) - //------------------------------------------------------------ - - legend.dispatch.on('stateChange', function(newState) { - for (var key in newState) - state[key] = newState[key]; - dispatch.stateChange(state); - chart.update(); - }); - - controls.dispatch.on('legendClick', function(d,i) { - if (!d.disabled) return; - controlsData = controlsData.map(function(s) { - s.disabled = true; - return s; - }); - d.disabled = false; - - switch (d.key) { - case 'Grouped': - multibar.stacked(false); - break; - case 'Stacked': - multibar.stacked(true); - break; - } - - state.stacked = multibar.stacked(); - dispatch.stateChange(state); - stacked = multibar.stacked(); - - chart.update(); - }); - - // Update chart from a state object passed to event handler - dispatch.on('changeState', function(e) { - - if (typeof e.disabled !== 'undefined') { - data.forEach(function(series,i) { - series.disabled = e.disabled[i]; - }); - - state.disabled = e.disabled; - } - - if (typeof e.stacked !== 'undefined') { - multibar.stacked(e.stacked); - state.stacked = e.stacked; - stacked = e.stacked; - } - - chart.update(); - }); - }); - renderWatch.renderEnd('multibar horizontal chart immediate'); - return chart; - } - - //============================================================ - // Event Handling/Dispatching (out of chart's scope) - //------------------------------------------------------------ - - multibar.dispatch.on('elementMouseover.tooltip', function(evt) { - evt.value = chart.x()(evt.data); - evt['series'] = { - key: evt.data.key, - value: chart.y()(evt.data), - color: evt.color - }; - tooltip.data(evt).hidden(false); - }); - - multibar.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true); - }); - - multibar.dispatch.on('elementMousemove.tooltip', function(evt) { - tooltip.position({top: d3.event.pageY, left: d3.event.pageX})(); - }); - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - // expose chart's sub-components - chart.dispatch = dispatch; - chart.multibar = multibar; - chart.legend = legend; - chart.controls = controls; - chart.xAxis = xAxis; - chart.yAxis = yAxis; - chart.state = state; - chart.tooltip = tooltip; - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}}, - showControls: {get: function(){return showControls;}, set: function(_){showControls=_;}}, - controlLabels: {get: function(){return controlLabels;}, set: function(_){controlLabels=_;}}, - showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}}, - showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}}, - defaultState: {get: function(){return defaultState;}, set: function(_){defaultState=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - - // deprecated options - tooltips: {get: function(){return tooltip.enabled();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltips', 'use chart.tooltip.enabled() instead'); - tooltip.enabled(!!_); - }}, - tooltipContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'use chart.tooltip.contentGenerator() instead'); - tooltip.contentGenerator(_); - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - multibar.duration(duration); - xAxis.duration(duration); - yAxis.duration(duration); - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - legend.color(color); - }}, - barColor: {get: function(){return multibar.barColor;}, set: function(_){ - multibar.barColor(_); - legend.color(function(d,i) {return d3.rgb('#ccc').darker(i * 1.5).toString();}) - }} - }); - - nv.utils.inheritOptions(chart, multibar); - nv.utils.initOptions(chart); - - return chart; - }; - nv.models.multiChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 30, right: 20, bottom: 50, left: 60}, - color = nv.utils.defaultColor(), - width = null, - height = null, - showLegend = true, - noData = null, - yDomain1, - yDomain2, - getX = function(d) { return d.x }, - getY = function(d) { return d.y}, - interpolate = 'monotone', - useVoronoi = true - ; - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var x = d3.scale.linear(), - yScale1 = d3.scale.linear(), - yScale2 = d3.scale.linear(), - - lines1 = nv.models.line().yScale(yScale1), - lines2 = nv.models.line().yScale(yScale2), - - scatters1 = nv.models.scatter().yScale(yScale1), - scatters2 = nv.models.scatter().yScale(yScale2), - - bars1 = nv.models.multiBar().stacked(false).yScale(yScale1), - bars2 = nv.models.multiBar().stacked(false).yScale(yScale2), - - stack1 = nv.models.stackedArea().yScale(yScale1), - stack2 = nv.models.stackedArea().yScale(yScale2), - - xAxis = nv.models.axis().scale(x).orient('bottom').tickPadding(5), - yAxis1 = nv.models.axis().scale(yScale1).orient('left'), - yAxis2 = nv.models.axis().scale(yScale2).orient('right'), - - legend = nv.models.legend().height(30), - tooltip = nv.models.tooltip(), - dispatch = d3.dispatch(); - - function chart(selection) { - selection.each(function(data) { - var container = d3.select(this), - that = this; - nv.utils.initSVG(container); - - chart.update = function() { container.transition().call(chart); }; - chart.container = this; - - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - var dataLines1 = data.filter(function(d) {return d.type == 'line' && d.yAxis == 1}); - var dataLines2 = data.filter(function(d) {return d.type == 'line' && d.yAxis == 2}); - var dataScatters1 = data.filter(function(d) {return d.type == 'scatter' && d.yAxis == 1}); - var dataScatters2 = data.filter(function(d) {return d.type == 'scatter' && d.yAxis == 2}); - var dataBars1 = data.filter(function(d) {return d.type == 'bar' && d.yAxis == 1}); - var dataBars2 = data.filter(function(d) {return d.type == 'bar' && d.yAxis == 2}); - var dataStack1 = data.filter(function(d) {return d.type == 'area' && d.yAxis == 1}); - var dataStack2 = data.filter(function(d) {return d.type == 'area' && d.yAxis == 2}); - - // Display noData message if there's nothing to show. - if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) { - nv.utils.noData(chart, container); - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - var series1 = data.filter(function(d) {return !d.disabled && d.yAxis == 1}) - .map(function(d) { - return d.values.map(function(d,i) { - return { x: d.x, y: d.y } - }) - }); - - var series2 = data.filter(function(d) {return !d.disabled && d.yAxis == 2}) - .map(function(d) { - return d.values.map(function(d,i) { - return { x: d.x, y: d.y } - }) - }); - - x .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return d.x } )) - .range([0, availableWidth]); - - var wrap = container.selectAll('g.wrap.multiChart').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'wrap nvd3 multiChart').append('g'); - - gEnter.append('g').attr('class', 'nv-x nv-axis'); - gEnter.append('g').attr('class', 'nv-y1 nv-axis'); - gEnter.append('g').attr('class', 'nv-y2 nv-axis'); - gEnter.append('g').attr('class', 'lines1Wrap'); - gEnter.append('g').attr('class', 'lines2Wrap'); - gEnter.append('g').attr('class', 'scatters1Wrap'); - gEnter.append('g').attr('class', 'scatters2Wrap'); - gEnter.append('g').attr('class', 'bars1Wrap'); - gEnter.append('g').attr('class', 'bars2Wrap'); - gEnter.append('g').attr('class', 'stack1Wrap'); - gEnter.append('g').attr('class', 'stack2Wrap'); - gEnter.append('g').attr('class', 'legendWrap'); - - var g = wrap.select('g'); - - var color_array = data.map(function(d,i) { - return data[i].color || color(d, i); - }); - - if (showLegend) { - var legendWidth = legend.align() ? availableWidth / 2 : availableWidth; - var legendXPosition = legend.align() ? legendWidth : 0; - - legend.width(legendWidth); - legend.color(color_array); - - g.select('.legendWrap') - .datum(data.map(function(series) { - series.originalKey = series.originalKey === undefined ? series.key : series.originalKey; - series.key = series.originalKey + (series.yAxis == 1 ? '' : ' (right axis)'); - return series; - })) - .call(legend); - - if ( margin.top != legend.height()) { - margin.top = legend.height(); - availableHeight = nv.utils.availableHeight(height, container, margin); - } - - g.select('.legendWrap') - .attr('transform', 'translate(' + legendXPosition + ',' + (-margin.top) +')'); - } - - lines1 - .width(availableWidth) - .height(availableHeight) - .interpolate(interpolate) - .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1 && data[i].type == 'line'})); - lines2 - .width(availableWidth) - .height(availableHeight) - .interpolate(interpolate) - .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2 && data[i].type == 'line'})); - scatters1 - .width(availableWidth) - .height(availableHeight) - .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1 && data[i].type == 'scatter'})); - scatters2 - .width(availableWidth) - .height(availableHeight) - .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2 && data[i].type == 'scatter'})); - bars1 - .width(availableWidth) - .height(availableHeight) - .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1 && data[i].type == 'bar'})); - bars2 - .width(availableWidth) - .height(availableHeight) - .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2 && data[i].type == 'bar'})); - stack1 - .width(availableWidth) - .height(availableHeight) - .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1 && data[i].type == 'area'})); - stack2 - .width(availableWidth) - .height(availableHeight) - .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2 && data[i].type == 'area'})); - - g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - var lines1Wrap = g.select('.lines1Wrap') - .datum(dataLines1.filter(function(d){return !d.disabled})); - var scatters1Wrap = g.select('.scatters1Wrap') - .datum(dataScatters1.filter(function(d){return !d.disabled})); - var bars1Wrap = g.select('.bars1Wrap') - .datum(dataBars1.filter(function(d){return !d.disabled})); - var stack1Wrap = g.select('.stack1Wrap') - .datum(dataStack1.filter(function(d){return !d.disabled})); - var lines2Wrap = g.select('.lines2Wrap') - .datum(dataLines2.filter(function(d){return !d.disabled})); - var scatters2Wrap = g.select('.scatters2Wrap') - .datum(dataScatters2.filter(function(d){return !d.disabled})); - var bars2Wrap = g.select('.bars2Wrap') - .datum(dataBars2.filter(function(d){return !d.disabled})); - var stack2Wrap = g.select('.stack2Wrap') - .datum(dataStack2.filter(function(d){return !d.disabled})); - - var extraValue1 = dataStack1.length ? dataStack1.map(function(a){return a.values}).reduce(function(a,b){ - return a.map(function(aVal,i){return {x: aVal.x, y: aVal.y + b[i].y}}) - }).concat([{x:0, y:0}]) : []; - var extraValue2 = dataStack2.length ? dataStack2.map(function(a){return a.values}).reduce(function(a,b){ - return a.map(function(aVal,i){return {x: aVal.x, y: aVal.y + b[i].y}}) - }).concat([{x:0, y:0}]) : []; - - yScale1 .domain(yDomain1 || d3.extent(d3.merge(series1).concat(extraValue1), function(d) { return d.y } )) - .range([0, availableHeight]); - - yScale2 .domain(yDomain2 || d3.extent(d3.merge(series2).concat(extraValue2), function(d) { return d.y } )) - .range([0, availableHeight]); - - lines1.yDomain(yScale1.domain()); - scatters1.yDomain(yScale1.domain()); - bars1.yDomain(yScale1.domain()); - stack1.yDomain(yScale1.domain()); - - lines2.yDomain(yScale2.domain()); - scatters2.yDomain(yScale2.domain()); - bars2.yDomain(yScale2.domain()); - stack2.yDomain(yScale2.domain()); - - if(dataStack1.length){d3.transition(stack1Wrap).call(stack1);} - if(dataStack2.length){d3.transition(stack2Wrap).call(stack2);} - - if(dataBars1.length){d3.transition(bars1Wrap).call(bars1);} - if(dataBars2.length){d3.transition(bars2Wrap).call(bars2);} - - if(dataLines1.length){d3.transition(lines1Wrap).call(lines1);} - if(dataLines2.length){d3.transition(lines2Wrap).call(lines2);} - - if(dataScatters1.length){d3.transition(scatters1Wrap).call(scatters1);} - if(dataScatters2.length){d3.transition(scatters2Wrap).call(scatters2);} - - xAxis - ._ticks( nv.utils.calcTicksX(availableWidth/100, data) ) - .tickSize(-availableHeight, 0); - - g.select('.nv-x.nv-axis') - .attr('transform', 'translate(0,' + availableHeight + ')'); - d3.transition(g.select('.nv-x.nv-axis')) - .call(xAxis); - - yAxis1 - ._ticks( nv.utils.calcTicksY(availableHeight/36, data) ) - .tickSize( -availableWidth, 0); - - - d3.transition(g.select('.nv-y1.nv-axis')) - .call(yAxis1); - - yAxis2 - ._ticks( nv.utils.calcTicksY(availableHeight/36, data) ) - .tickSize( -availableWidth, 0); - - d3.transition(g.select('.nv-y2.nv-axis')) - .call(yAxis2); - - g.select('.nv-y1.nv-axis') - .classed('nv-disabled', series1.length ? false : true) - .attr('transform', 'translate(' + x.range()[0] + ',0)'); - - g.select('.nv-y2.nv-axis') - .classed('nv-disabled', series2.length ? false : true) - .attr('transform', 'translate(' + x.range()[1] + ',0)'); - - legend.dispatch.on('stateChange', function(newState) { - chart.update(); - }); - - //============================================================ - // Event Handling/Dispatching - //------------------------------------------------------------ - - function mouseover_line(evt) { - var yaxis = data[evt.seriesIndex].yAxis === 2 ? yAxis2 : yAxis1; - evt.value = evt.point.x; - evt.series = { - value: evt.point.y, - color: evt.point.color - }; - tooltip - .duration(100) - .valueFormatter(function(d, i) { - return yaxis.tickFormat()(d, i); - }) - .data(evt) - .position(evt.pos) - .hidden(false); - } - - function mouseover_scatter(evt) { - var yaxis = data[evt.seriesIndex].yAxis === 2 ? yAxis2 : yAxis1; - evt.value = evt.point.x; - evt.series = { - value: evt.point.y, - color: evt.point.color - }; - tooltip - .duration(100) - .valueFormatter(function(d, i) { - return yaxis.tickFormat()(d, i); - }) - .data(evt) - .position(evt.pos) - .hidden(false); - } - - function mouseover_stack(evt) { - var yaxis = data[evt.seriesIndex].yAxis === 2 ? yAxis2 : yAxis1; - evt.point['x'] = stack1.x()(evt.point); - evt.point['y'] = stack1.y()(evt.point); - tooltip - .duration(100) - .valueFormatter(function(d, i) { - return yaxis.tickFormat()(d, i); - }) - .data(evt) - .position(evt.pos) - .hidden(false); - } - - function mouseover_bar(evt) { - var yaxis = data[evt.data.series].yAxis === 2 ? yAxis2 : yAxis1; - - evt.value = bars1.x()(evt.data); - evt['series'] = { - value: bars1.y()(evt.data), - color: evt.color - }; - tooltip - .duration(0) - .valueFormatter(function(d, i) { - return yaxis.tickFormat()(d, i); - }) - .data(evt) - .hidden(false); - } - - lines1.dispatch.on('elementMouseover.tooltip', mouseover_line); - lines2.dispatch.on('elementMouseover.tooltip', mouseover_line); - lines1.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true) - }); - lines2.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true) - }); - - scatters1.dispatch.on('elementMouseover.tooltip', mouseover_scatter); - scatters2.dispatch.on('elementMouseover.tooltip', mouseover_scatter); - scatters1.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true) - }); - scatters2.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true) - }); - - stack1.dispatch.on('elementMouseover.tooltip', mouseover_stack); - stack2.dispatch.on('elementMouseover.tooltip', mouseover_stack); - stack1.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true) - }); - stack2.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true) - }); - - bars1.dispatch.on('elementMouseover.tooltip', mouseover_bar); - bars2.dispatch.on('elementMouseover.tooltip', mouseover_bar); - - bars1.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true); - }); - bars2.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true); - }); - bars1.dispatch.on('elementMousemove.tooltip', function(evt) { - tooltip.position({top: d3.event.pageY, left: d3.event.pageX})(); - }); - bars2.dispatch.on('elementMousemove.tooltip', function(evt) { - tooltip.position({top: d3.event.pageY, left: d3.event.pageX})(); - }); - - }); - - return chart; - } - - //============================================================ - // Global getters and setters - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.lines1 = lines1; - chart.lines2 = lines2; - chart.scatters1 = scatters1; - chart.scatters2 = scatters2; - chart.bars1 = bars1; - chart.bars2 = bars2; - chart.stack1 = stack1; - chart.stack2 = stack2; - chart.xAxis = xAxis; - chart.yAxis1 = yAxis1; - chart.yAxis2 = yAxis2; - chart.tooltip = tooltip; - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}}, - yDomain1: {get: function(){return yDomain1;}, set: function(_){yDomain1=_;}}, - yDomain2: {get: function(){return yDomain2;}, set: function(_){yDomain2=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - interpolate: {get: function(){return interpolate;}, set: function(_){interpolate=_;}}, - - // deprecated options - tooltips: {get: function(){return tooltip.enabled();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltips', 'use chart.tooltip.enabled() instead'); - tooltip.enabled(!!_); - }}, - tooltipContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'use chart.tooltip.contentGenerator() instead'); - tooltip.contentGenerator(_); - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }}, - x: {get: function(){return getX;}, set: function(_){ - getX = _; - lines1.x(_); - lines2.x(_); - scatters1.x(_); - scatters2.x(_); - bars1.x(_); - bars2.x(_); - stack1.x(_); - stack2.x(_); - }}, - y: {get: function(){return getY;}, set: function(_){ - getY = _; - lines1.y(_); - lines2.y(_); - scatters1.y(_); - scatters2.y(_); - stack1.y(_); - stack2.y(_); - bars1.y(_); - bars2.y(_); - }}, - useVoronoi: {get: function(){return useVoronoi;}, set: function(_){ - useVoronoi=_; - lines1.useVoronoi(_); - lines2.useVoronoi(_); - stack1.useVoronoi(_); - stack2.useVoronoi(_); - }} - }); - - nv.utils.initOptions(chart); - - return chart; - }; - - - nv.models.ohlcBar = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = null - , height = null - , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one - , container = null - , x = d3.scale.linear() - , y = d3.scale.linear() - , getX = function(d) { return d.x } - , getY = function(d) { return d.y } - , getOpen = function(d) { return d.open } - , getClose = function(d) { return d.close } - , getHigh = function(d) { return d.high } - , getLow = function(d) { return d.low } - , forceX = [] - , forceY = [] - , padData = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart - , clipEdge = true - , color = nv.utils.defaultColor() - , interactive = false - , xDomain - , yDomain - , xRange - , yRange - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState', 'renderEnd', 'chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove') - ; - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - function chart(selection) { - selection.each(function(data) { - container = d3.select(this); - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - nv.utils.initSVG(container); - - // ohlc bar width. - var w = (availableWidth / data[0].values.length) * .9; - - // Setup Scales - x.domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) )); - - if (padData) - x.range(xRange || [availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5) / data[0].values.length ]); - else - x.range(xRange || [5 + w/2, availableWidth - w/2 - 5]); - - y.domain(yDomain || [ - d3.min(data[0].values.map(getLow).concat(forceY)), - d3.max(data[0].values.map(getHigh).concat(forceY)) - ] - ).range(yRange || [availableHeight, 0]); - - // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point - if (x.domain()[0] === x.domain()[1]) - x.domain()[0] ? - x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01]) - : x.domain([-1,1]); - - if (y.domain()[0] === y.domain()[1]) - y.domain()[0] ? - y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01]) - : y.domain([-1,1]); - - // Setup containers and skeleton of chart - var wrap = d3.select(this).selectAll('g.nv-wrap.nv-ohlcBar').data([data[0].values]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-ohlcBar'); - var defsEnter = wrapEnter.append('defs'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-ticks'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - container - .on('click', function(d,i) { - dispatch.chartClick({ - data: d, - index: i, - pos: d3.event, - id: id - }); - }); - - defsEnter.append('clipPath') - .attr('id', 'nv-chart-clip-path-' + id) - .append('rect'); - - wrap.select('#nv-chart-clip-path-' + id + ' rect') - .attr('width', availableWidth) - .attr('height', availableHeight); - - g .attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id + ')' : ''); - - var ticks = wrap.select('.nv-ticks').selectAll('.nv-tick') - .data(function(d) { return d }); - ticks.exit().remove(); - - ticks.enter().append('path') - .attr('class', function(d,i,j) { return (getOpen(d,i) > getClose(d,i) ? 'nv-tick negative' : 'nv-tick positive') + ' nv-tick-' + j + '-' + i }) - .attr('d', function(d,i) { - return 'm0,0l0,' - + (y(getOpen(d,i)) - - y(getHigh(d,i))) - + 'l' - + (-w/2) - + ',0l' - + (w/2) - + ',0l0,' - + (y(getLow(d,i)) - y(getOpen(d,i))) - + 'l0,' - + (y(getClose(d,i)) - - y(getLow(d,i))) - + 'l' - + (w/2) - + ',0l' - + (-w/2) - + ',0z'; - }) - .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',' + y(getHigh(d,i)) + ')'; }) - .attr('fill', function(d,i) { return color[0]; }) - .attr('stroke', function(d,i) { return color[0]; }) - .attr('x', 0 ) - .attr('y', function(d,i) { return y(Math.max(0, getY(d,i))) }) - .attr('height', function(d,i) { return Math.abs(y(getY(d,i)) - y(0)) }); - - // the bar colors are controlled by CSS currently - ticks.attr('class', function(d,i,j) { - return (getOpen(d,i) > getClose(d,i) ? 'nv-tick negative' : 'nv-tick positive') + ' nv-tick-' + j + '-' + i; - }); - - d3.transition(ticks) - .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',' + y(getHigh(d,i)) + ')'; }) - .attr('d', function(d,i) { - var w = (availableWidth / data[0].values.length) * .9; - return 'm0,0l0,' - + (y(getOpen(d,i)) - - y(getHigh(d,i))) - + 'l' - + (-w/2) - + ',0l' - + (w/2) - + ',0l0,' - + (y(getLow(d,i)) - - y(getOpen(d,i))) - + 'l0,' - + (y(getClose(d,i)) - - y(getLow(d,i))) - + 'l' - + (w/2) - + ',0l' - + (-w/2) - + ',0z'; - }); - }); - - return chart; - } - - - //Create methods to allow outside functions to highlight a specific bar. - chart.highlightPoint = function(pointIndex, isHoverOver) { - chart.clearHighlights(); - container.select(".nv-ohlcBar .nv-tick-0-" + pointIndex) - .classed("hover", isHoverOver) - ; - }; - - chart.clearHighlights = function() { - container.select(".nv-ohlcBar .nv-tick.hover") - .classed("hover", false) - ; - }; - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - xScale: {get: function(){return x;}, set: function(_){x=_;}}, - yScale: {get: function(){return y;}, set: function(_){y=_;}}, - xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}}, - yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}}, - xRange: {get: function(){return xRange;}, set: function(_){xRange=_;}}, - yRange: {get: function(){return yRange;}, set: function(_){yRange=_;}}, - forceX: {get: function(){return forceX;}, set: function(_){forceX=_;}}, - forceY: {get: function(){return forceY;}, set: function(_){forceY=_;}}, - padData: {get: function(){return padData;}, set: function(_){padData=_;}}, - clipEdge: {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}}, - id: {get: function(){return id;}, set: function(_){id=_;}}, - interactive: {get: function(){return interactive;}, set: function(_){interactive=_;}}, - - x: {get: function(){return getX;}, set: function(_){getX=_;}}, - y: {get: function(){return getY;}, set: function(_){getY=_;}}, - open: {get: function(){return getOpen();}, set: function(_){getOpen=_;}}, - close: {get: function(){return getClose();}, set: function(_){getClose=_;}}, - high: {get: function(){return getHigh;}, set: function(_){getHigh=_;}}, - low: {get: function(){return getLow;}, set: function(_){getLow=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top != undefined ? _.top : margin.top; - margin.right = _.right != undefined ? _.right : margin.right; - margin.bottom = _.bottom != undefined ? _.bottom : margin.bottom; - margin.left = _.left != undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }} - }); - - nv.utils.initOptions(chart); - return chart; - }; -// Code adapted from Jason Davies' "Parallel Coordinates" -// http://bl.ocks.org/jasondavies/1341281 - nv.models.parallelCoordinates = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 30, right: 0, bottom: 10, left: 0} - , width = null - , height = null - , x = d3.scale.ordinal() - , y = {} - , dimensionNames = [] - , dimensionFormats = [] - , color = nv.utils.defaultColor() - , filters = [] - , active = [] - , dragging = [] - , lineTension = 1 - , dispatch = d3.dispatch('brush', 'elementMouseover', 'elementMouseout') - ; - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - function chart(selection) { - selection.each(function(data) { - var container = d3.select(this); - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - nv.utils.initSVG(container); - - active = data; //set all active before first brush call - - // Setup Scales - x.rangePoints([0, availableWidth], 1).domain(dimensionNames); - - //Set as true if all values on an axis are missing. - var onlyNanValues = {}; - // Extract the list of dimensions and create a scale for each. - dimensionNames.forEach(function(d) { - var extent = d3.extent(data, function(p) { return +p[d]; }); - onlyNanValues[d] = false; - //If there is no values to display on an axis, set the extent to 0 - if (extent[0] === undefined) { - onlyNanValues[d] = true; - extent[0] = 0; - extent[1] = 0; - } - //Scale axis if there is only one value - if (extent[0] === extent[1]) { - extent[0] = extent[0] - 1; - extent[1] = extent[1] + 1; - } - //Use 90% of (availableHeight - 12) for the axis range, 12 reprensenting the space necessary to display "undefined values" text. - //The remaining 10% are used to display the missingValue line. - y[d] = d3.scale.linear() - .domain(extent) - .range([(availableHeight - 12) * 0.9, 0]); - - y[d].brush = d3.svg.brush().y(y[d]).on('brush', brush); - - return d != 'name'; - }); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-parallelCoordinates').data([data]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-parallelCoordinates'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-parallelCoordinates background'); - gEnter.append('g').attr('class', 'nv-parallelCoordinates foreground'); - gEnter.append('g').attr('class', 'nv-parallelCoordinates missingValuesline'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - var line = d3.svg.line().interpolate('cardinal').tension(lineTension), - axis = d3.svg.axis().orient('left'), - axisDrag = d3.behavior.drag() - .on('dragstart', dragStart) - .on('drag', dragMove) - .on('dragend', dragEnd); - - //Add missing value line at the bottom of the chart - var missingValuesline, missingValueslineText; - var step = x.range()[1] - x.range()[0]; - var axisWithMissingValues = []; - var lineData = [0 + step / 2, availableHeight - 12, availableWidth - step / 2, availableHeight - 12]; - missingValuesline = wrap.select('.missingValuesline').selectAll('line').data([lineData]); - missingValuesline.enter().append('line'); - missingValuesline.exit().remove(); - missingValuesline.attr("x1", function(d) { return d[0]; }) - .attr("y1", function(d) { return d[1]; }) - .attr("x2", function(d) { return d[2]; }) - .attr("y2", function(d) { return d[3]; }); - - //Add the text "undefined values" under the missing value line - missingValueslineText = wrap.select('.missingValuesline').selectAll('text').data(["undefined values"]); - missingValueslineText.append('text').data(["undefined values"]); - missingValueslineText.enter().append('text'); - missingValueslineText.exit().remove(); - missingValueslineText.attr("y", availableHeight) - //To have the text right align with the missingValues line, substract 92 representing the text size. - .attr("x", availableWidth - 92 - step / 2) - .text(function(d) { return d; }); - - // Add grey background lines for context. - var background = wrap.select('.background').selectAll('path').data(data); - background.enter().append('path'); - background.exit().remove(); - background.attr('d', path); - - // Add blue foreground lines for focus. - var foreground = wrap.select('.foreground').selectAll('path').data(data); - foreground.enter().append('path') - foreground.exit().remove(); - foreground.attr('d', path).attr('stroke', color); - foreground.on("mouseover", function (d, i) { - d3.select(this).classed('hover', true); - dispatch.elementMouseover({ - label: d.name, - data: d.data, - index: i, - pos: [d3.mouse(this.parentNode)[0], d3.mouse(this.parentNode)[1]] - }); - - }); - foreground.on("mouseout", function (d, i) { - d3.select(this).classed('hover', false); - dispatch.elementMouseout({ - label: d.name, - data: d.data, - index: i - }); - }); - - // Add a group element for each dimension. - var dimensions = g.selectAll('.dimension').data(dimensionNames); - var dimensionsEnter = dimensions.enter().append('g').attr('class', 'nv-parallelCoordinates dimension'); - dimensionsEnter.append('g').attr('class', 'nv-parallelCoordinates nv-axis'); - dimensionsEnter.append('g').attr('class', 'nv-parallelCoordinates-brush'); - dimensionsEnter.append('text').attr('class', 'nv-parallelCoordinates nv-label'); - - dimensions.attr('transform', function(d) { return 'translate(' + x(d) + ',0)'; }); - dimensions.exit().remove(); - - // Add an axis and title. - dimensions.select('.nv-label') - .style("cursor", "move") - .attr('dy', '-1em') - .attr('text-anchor', 'middle') - .text(String) - .on("mouseover", function(d, i) { - dispatch.elementMouseover({ - dim: d, - pos: [d3.mouse(this.parentNode.parentNode)[0], d3.mouse(this.parentNode.parentNode)[1]] - }); - }) - .on("mouseout", function(d, i) { - dispatch.elementMouseout({ - dim: d - }); - }) - .call(axisDrag); - - dimensions.select('.nv-axis') - .each(function (d, i) { - d3.select(this).call(axis.scale(y[d]).tickFormat(d3.format(dimensionFormats[i]))); - }); - - dimensions.select('.nv-parallelCoordinates-brush') - .each(function (d) { - d3.select(this).call(y[d].brush); - }) - .selectAll('rect') - .attr('x', -8) - .attr('width', 16); - - // Returns the path for a given data point. - function path(d) { - return line(dimensionNames.map(function (p) { - //If value if missing, put the value on the missing value line - if(isNaN(d[p]) || isNaN(parseFloat(d[p]))) { - var domain = y[p].domain(); - var range = y[p].range(); - var min = domain[0] - (domain[1] - domain[0]) / 9; - - //If it's not already the case, allow brush to select undefined values - if(axisWithMissingValues.indexOf(p) < 0) { - - var newscale = d3.scale.linear().domain([min, domain[1]]).range([availableHeight - 12, range[1]]); - y[p].brush.y(newscale); - axisWithMissingValues.push(p); - } - - return [x(p), y[p](min)]; - } - - //If parallelCoordinate contain missing values show the missing values line otherwise, hide it. - if(axisWithMissingValues.length > 0) { - missingValuesline.style("display", "inline"); - missingValueslineText.style("display", "inline"); - } else { - missingValuesline.style("display", "none"); - missingValueslineText.style("display", "none"); - } - - return [x(p), y[p](d[p])]; - })); - } - - // Handles a brush event, toggling the display of foreground lines. - function brush() { - var actives = dimensionNames.filter(function(p) { return !y[p].brush.empty(); }), - extents = actives.map(function(p) { return y[p].brush.extent(); }); - - filters = []; //erase current filters - actives.forEach(function(d,i) { - filters[i] = { - dimension: d, - extent: extents[i] - } - }); - - active = []; //erase current active list - foreground.style('display', function(d) { - var isActive = actives.every(function(p, i) { - if(isNaN(d[p]) && extents[i][0] == y[p].brush.y().domain()[0]) return true; - return extents[i][0] <= d[p] && d[p] <= extents[i][1]; - }); - if (isActive) active.push(d); - return isActive ? null : 'none'; - }); - - dispatch.brush({ - filters: filters, - active: active - }); - } - - function dragStart(d, i) { - dragging[d] = this.parentNode.__origin__ = x(d); - background.attr("visibility", "hidden"); - - } - - function dragMove(d, i) { - dragging[d] = Math.min(availableWidth, Math.max(0, this.parentNode.__origin__ += d3.event.x)); - foreground.attr("d", path); - dimensionNames.sort(function (a, b) { return position(a) - position(b); }); - x.domain(dimensionNames); - dimensions.attr("transform", function(d) { return "translate(" + position(d) + ")"; }); - } - - function dragEnd(d, i) { - delete this.parentNode.__origin__; - delete dragging[d]; - d3.select(this.parentNode).attr("transform", "translate(" + x(d) + ")"); - foreground - .attr("d", path); - background - .attr("d", path) - .attr("visibility", null); - - } - - function position(d) { - var v = dragging[d]; - return v == null ? x(d) : v; - } - }); - - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width= _;}}, - height: {get: function(){return height;}, set: function(_){height= _;}}, - dimensionNames: {get: function() { return dimensionNames;}, set: function(_){dimensionNames= _;}}, - dimensionFormats : {get: function(){return dimensionFormats;}, set: function (_){dimensionFormats=_;}}, - lineTension: {get: function(){return lineTension;}, set: function(_){lineTension = _;}}, - - // deprecated options - dimensions: {get: function (){return dimensionNames;}, set: function(_){ - // deprecated after 1.8.1 - nv.deprecated('dimensions', 'use dimensionNames instead'); - dimensionNames = _; - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }} - }); - - nv.utils.initOptions(chart); - return chart; - }; - nv.models.pie = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = 500 - , height = 500 - , getX = function(d) { return d.x } - , getY = function(d) { return d.y } - , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one - , container = null - , color = nv.utils.defaultColor() - , valueFormat = d3.format(',.2f') - , showLabels = true - , labelsOutside = false - , labelType = "key" - , labelThreshold = .02 //if slice percentage is under this, don't show label - , donut = false - , title = false - , growOnHover = true - , titleOffset = 0 - , labelSunbeamLayout = false - , startAngle = false - , padAngle = false - , endAngle = false - , cornerRadius = 0 - , donutRatio = 0.5 - , arcsRadius = [] - , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd') - ; - - var arcs = []; - var arcsOver = []; - - //============================================================ - // chart function - //------------------------------------------------------------ - - var renderWatch = nv.utils.renderWatch(dispatch); - - function chart(selection) { - renderWatch.reset(); - selection.each(function(data) { - var availableWidth = width - margin.left - margin.right - , availableHeight = height - margin.top - margin.bottom - , radius = Math.min(availableWidth, availableHeight) / 2 - , arcsRadiusOuter = [] - , arcsRadiusInner = [] - ; - - container = d3.select(this) - if (arcsRadius.length === 0) { - var outer = radius - radius / 5; - var inner = donutRatio * radius; - for (var i = 0; i < data[0].length; i++) { - arcsRadiusOuter.push(outer); - arcsRadiusInner.push(inner); - } - } else { - arcsRadiusOuter = arcsRadius.map(function (d) { return (d.outer - d.outer / 5) * radius; }); - arcsRadiusInner = arcsRadius.map(function (d) { return (d.inner - d.inner / 5) * radius; }); - donutRatio = d3.min(arcsRadius.map(function (d) { return (d.inner - d.inner / 5); })); - } - nv.utils.initSVG(container); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('.nv-wrap.nv-pie').data(data); - var wrapEnter = wrap.enter().append('g').attr('class','nvd3 nv-wrap nv-pie nv-chart-' + id); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - var g_pie = gEnter.append('g').attr('class', 'nv-pie'); - gEnter.append('g').attr('class', 'nv-pieLabels'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - g.select('.nv-pie').attr('transform', 'translate(' + availableWidth / 2 + ',' + availableHeight / 2 + ')'); - g.select('.nv-pieLabels').attr('transform', 'translate(' + availableWidth / 2 + ',' + availableHeight / 2 + ')'); - - // - container.on('click', function(d,i) { - dispatch.chartClick({ - data: d, - index: i, - pos: d3.event, - id: id - }); - }); - - arcs = []; - arcsOver = []; - for (var i = 0; i < data[0].length; i++) { - - var arc = d3.svg.arc().outerRadius(arcsRadiusOuter[i]); - var arcOver = d3.svg.arc().outerRadius(arcsRadiusOuter[i] + 5); - - if (startAngle !== false) { - arc.startAngle(startAngle); - arcOver.startAngle(startAngle); - } - if (endAngle !== false) { - arc.endAngle(endAngle); - arcOver.endAngle(endAngle); - } - if (donut) { - arc.innerRadius(arcsRadiusInner[i]); - arcOver.innerRadius(arcsRadiusInner[i]); - } - - if (arc.cornerRadius && cornerRadius) { - arc.cornerRadius(cornerRadius); - arcOver.cornerRadius(cornerRadius); - } - - arcs.push(arc); - arcsOver.push(arcOver); - } - - // Setup the Pie chart and choose the data element - var pie = d3.layout.pie() - .sort(null) - .value(function(d) { return d.disabled ? 0 : getY(d) }); - - // padAngle added in d3 3.5 - if (pie.padAngle && padAngle) { - pie.padAngle(padAngle); - } - - // if title is specified and donut, put it in the middle - if (donut && title) { - g_pie.append("text").attr('class', 'nv-pie-title'); - - wrap.select('.nv-pie-title') - .style("text-anchor", "middle") - .text(function (d) { - return title; - }) - .style("font-size", (Math.min(availableWidth, availableHeight)) * donutRatio * 2 / (title.length + 2) + "px") - .attr("dy", "0.35em") // trick to vertically center text - .attr('transform', function(d, i) { - return 'translate(0, '+ titleOffset + ')'; - }); - } - - var slices = wrap.select('.nv-pie').selectAll('.nv-slice').data(pie); - var pieLabels = wrap.select('.nv-pieLabels').selectAll('.nv-label').data(pie); - - slices.exit().remove(); - pieLabels.exit().remove(); - - var ae = slices.enter().append('g'); - ae.attr('class', 'nv-slice'); - ae.on('mouseover', function(d, i) { - d3.select(this).classed('hover', true); - if (growOnHover) { - d3.select(this).select("path").transition() - .duration(70) - .attr("d", arcsOver[i]); - } - dispatch.elementMouseover({ - data: d.data, - index: i, - color: d3.select(this).style("fill") - }); - }); - ae.on('mouseout', function(d, i) { - d3.select(this).classed('hover', false); - if (growOnHover) { - d3.select(this).select("path").transition() - .duration(50) - .attr("d", arcs[i]); - } - dispatch.elementMouseout({data: d.data, index: i}); - }); - ae.on('mousemove', function(d, i) { - dispatch.elementMousemove({data: d.data, index: i}); - }); - ae.on('click', function(d, i) { - dispatch.elementClick({ - data: d.data, - index: i, - color: d3.select(this).style("fill") - }); - }); - ae.on('dblclick', function(d, i) { - dispatch.elementDblClick({ - data: d.data, - index: i, - color: d3.select(this).style("fill") - }); - }); - - slices.attr('fill', function(d,i) { return color(d.data, i); }); - slices.attr('stroke', function(d,i) { return color(d.data, i); }); - - var paths = ae.append('path').each(function(d) { - this._current = d; - }); - - slices.select('path') - .transition() - .attr('d', function (d, i) { return arcs[i](d); }) - .attrTween('d', arcTween); - - if (showLabels) { - // This does the normal label - var labelsArc = []; - for (var i = 0; i < data[0].length; i++) { - labelsArc.push(arcs[i]); - - if (labelsOutside) { - if (donut) { - labelsArc[i] = d3.svg.arc().outerRadius(arcs[i].outerRadius()); - if (startAngle !== false) labelsArc[i].startAngle(startAngle); - if (endAngle !== false) labelsArc[i].endAngle(endAngle); - } - } else if (!donut) { - labelsArc[i].innerRadius(0); - } - } - - pieLabels.enter().append("g").classed("nv-label",true).each(function(d,i) { - var group = d3.select(this); - - group.attr('transform', function (d, i) { - if (labelSunbeamLayout) { - d.outerRadius = arcsRadiusOuter[i] + 10; // Set Outer Coordinate - d.innerRadius = arcsRadiusOuter[i] + 15; // Set Inner Coordinate - var rotateAngle = (d.startAngle + d.endAngle) / 2 * (180 / Math.PI); - if ((d.startAngle + d.endAngle) / 2 < Math.PI) { - rotateAngle -= 90; - } else { - rotateAngle += 90; - } - return 'translate(' + labelsArc[i].centroid(d) + ') rotate(' + rotateAngle + ')'; - } else { - d.outerRadius = radius + 10; // Set Outer Coordinate - d.innerRadius = radius + 15; // Set Inner Coordinate - return 'translate(' + labelsArc[i].centroid(d) + ')' - } - }); - - group.append('rect') - .style('stroke', '#fff') - .style('fill', '#fff') - .attr("rx", 3) - .attr("ry", 3); - - group.append('text') - .style('text-anchor', labelSunbeamLayout ? ((d.startAngle + d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle') //center the text on it's origin or begin/end if orthogonal aligned - .style('fill', '#000') - }); - - var labelLocationHash = {}; - var avgHeight = 14; - var avgWidth = 140; - var createHashKey = function(coordinates) { - return Math.floor(coordinates[0]/avgWidth) * avgWidth + ',' + Math.floor(coordinates[1]/avgHeight) * avgHeight; - }; - - pieLabels.watchTransition(renderWatch, 'pie labels').attr('transform', function (d, i) { - if (labelSunbeamLayout) { - d.outerRadius = arcsRadiusOuter[i] + 10; // Set Outer Coordinate - d.innerRadius = arcsRadiusOuter[i] + 15; // Set Inner Coordinate - var rotateAngle = (d.startAngle + d.endAngle) / 2 * (180 / Math.PI); - if ((d.startAngle + d.endAngle) / 2 < Math.PI) { - rotateAngle -= 90; - } else { - rotateAngle += 90; - } - return 'translate(' + labelsArc[i].centroid(d) + ') rotate(' + rotateAngle + ')'; - } else { - d.outerRadius = radius + 10; // Set Outer Coordinate - d.innerRadius = radius + 15; // Set Inner Coordinate - - /* - Overlapping pie labels are not good. What this attempts to do is, prevent overlapping. - Each label location is hashed, and if a hash collision occurs, we assume an overlap. - Adjust the label's y-position to remove the overlap. - */ - var center = labelsArc[i].centroid(d); - if (d.value) { - var hashKey = createHashKey(center); - if (labelLocationHash[hashKey]) { - center[1] -= avgHeight; - } - labelLocationHash[createHashKey(center)] = true; - } - return 'translate(' + center + ')' - } - }); - - pieLabels.select(".nv-label text") - .style('text-anchor', function(d,i) { - //center the text on it's origin or begin/end if orthogonal aligned - return labelSunbeamLayout ? ((d.startAngle + d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle'; - }) - .text(function(d, i) { - var percent = (d.endAngle - d.startAngle) / (2 * Math.PI); - var label = ''; - if (!d.value || percent < labelThreshold) return ''; - - if(typeof labelType === 'function') { - label = labelType(d, i, { - 'key': getX(d.data), - 'value': getY(d.data), - 'percent': valueFormat(percent) - }); - } else { - switch (labelType) { - case 'key': - label = getX(d.data); - break; - case 'value': - label = valueFormat(getY(d.data)); - break; - case 'percent': - label = d3.format('%')(percent); - break; - } - } - return label; - }) - ; - } - - - // Computes the angle of an arc, converting from radians to degrees. - function angle(d) { - var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90; - return a > 90 ? a - 180 : a; - } - - function arcTween(a, idx) { - a.endAngle = isNaN(a.endAngle) ? 0 : a.endAngle; - a.startAngle = isNaN(a.startAngle) ? 0 : a.startAngle; - if (!donut) a.innerRadius = 0; - var i = d3.interpolate(this._current, a); - this._current = i(0); - return function (t) { - return arcs[idx](i(t)); - }; - } - }); - - renderWatch.renderEnd('pie immediate'); - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - arcsRadius: { get: function () { return arcsRadius; }, set: function (_) { arcsRadius = _; } }, - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - showLabels: {get: function(){return showLabels;}, set: function(_){showLabels=_;}}, - title: {get: function(){return title;}, set: function(_){title=_;}}, - titleOffset: {get: function(){return titleOffset;}, set: function(_){titleOffset=_;}}, - labelThreshold: {get: function(){return labelThreshold;}, set: function(_){labelThreshold=_;}}, - valueFormat: {get: function(){return valueFormat;}, set: function(_){valueFormat=_;}}, - x: {get: function(){return getX;}, set: function(_){getX=_;}}, - id: {get: function(){return id;}, set: function(_){id=_;}}, - endAngle: {get: function(){return endAngle;}, set: function(_){endAngle=_;}}, - startAngle: {get: function(){return startAngle;}, set: function(_){startAngle=_;}}, - padAngle: {get: function(){return padAngle;}, set: function(_){padAngle=_;}}, - cornerRadius: {get: function(){return cornerRadius;}, set: function(_){cornerRadius=_;}}, - donutRatio: {get: function(){return donutRatio;}, set: function(_){donutRatio=_;}}, - labelsOutside: {get: function(){return labelsOutside;}, set: function(_){labelsOutside=_;}}, - labelSunbeamLayout: {get: function(){return labelSunbeamLayout;}, set: function(_){labelSunbeamLayout=_;}}, - donut: {get: function(){return donut;}, set: function(_){donut=_;}}, - growOnHover: {get: function(){return growOnHover;}, set: function(_){growOnHover=_;}}, - - // depreciated after 1.7.1 - pieLabelsOutside: {get: function(){return labelsOutside;}, set: function(_){ - labelsOutside=_; - nv.deprecated('pieLabelsOutside', 'use labelsOutside instead'); - }}, - // depreciated after 1.7.1 - donutLabelsOutside: {get: function(){return labelsOutside;}, set: function(_){ - labelsOutside=_; - nv.deprecated('donutLabelsOutside', 'use labelsOutside instead'); - }}, - // deprecated after 1.7.1 - labelFormat: {get: function(){ return valueFormat;}, set: function(_) { - valueFormat=_; - nv.deprecated('labelFormat','use valueFormat instead'); - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = typeof _.top != 'undefined' ? _.top : margin.top; - margin.right = typeof _.right != 'undefined' ? _.right : margin.right; - margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom; - margin.left = typeof _.left != 'undefined' ? _.left : margin.left; - }}, - y: {get: function(){return getY;}, set: function(_){ - getY=d3.functor(_); - }}, - color: {get: function(){return color;}, set: function(_){ - color=nv.utils.getColor(_); - }}, - labelType: {get: function(){return labelType;}, set: function(_){ - labelType= _ || 'key'; - }} - }); - - nv.utils.initOptions(chart); - return chart; - }; - nv.models.pieChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var pie = nv.models.pie(); - var legend = nv.models.legend(); - var tooltip = nv.models.tooltip(); - - var margin = {top: 30, right: 20, bottom: 20, left: 20} - , width = null - , height = null - , showLegend = true - , legendPosition = "top" - , color = nv.utils.defaultColor() - , state = nv.utils.state() - , defaultState = null - , noData = null - , duration = 250 - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState','renderEnd') - ; - - tooltip - .headerEnabled(false) - .duration(0) - .valueFormatter(function(d, i) { - return pie.valueFormat()(d, i); - }); - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var renderWatch = nv.utils.renderWatch(dispatch); - - var stateGetter = function(data) { - return function(){ - return { - active: data.map(function(d) { return !d.disabled }) - }; - } - }; - - var stateSetter = function(data) { - return function(state) { - if (state.active !== undefined) { - data.forEach(function (series, i) { - series.disabled = !state.active[i]; - }); - } - } - }; - - //============================================================ - // Chart function - //------------------------------------------------------------ - - function chart(selection) { - renderWatch.reset(); - renderWatch.models(pie); - - selection.each(function(data) { - var container = d3.select(this); - nv.utils.initSVG(container); - - var that = this; - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - chart.update = function() { container.transition().call(chart); }; - chart.container = this; - - state.setter(stateSetter(data), chart.update) - .getter(stateGetter(data)) - .update(); - - //set state.disabled - state.disabled = data.map(function(d) { return !!d.disabled }); - - if (!defaultState) { - var key; - defaultState = {}; - for (key in state) { - if (state[key] instanceof Array) - defaultState[key] = state[key].slice(0); - else - defaultState[key] = state[key]; - } - } - - // Display No Data message if there's nothing to show. - if (!data || !data.length) { - nv.utils.noData(chart, container); - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-pieChart').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-pieChart').append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-pieWrap'); - gEnter.append('g').attr('class', 'nv-legendWrap'); - - // Legend - if (showLegend) { - if (legendPosition === "top") { - legend.width( availableWidth ).key(pie.x()); - - wrap.select('.nv-legendWrap') - .datum(data) - .call(legend); - - if ( margin.top != legend.height()) { - margin.top = legend.height(); - availableHeight = nv.utils.availableHeight(height, container, margin); - } - - wrap.select('.nv-legendWrap') - .attr('transform', 'translate(0,' + (-margin.top) +')'); - } else if (legendPosition === "right") { - var legendWidth = nv.models.legend().width(); - if (availableWidth / 2 < legendWidth) { - legendWidth = (availableWidth / 2) - } - legend.height(availableHeight).key(pie.x()); - legend.width(legendWidth); - availableWidth -= legend.width(); - - wrap.select('.nv-legendWrap') - .datum(data) - .call(legend) - .attr('transform', 'translate(' + (availableWidth) +',0)'); - } - } - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - // Main Chart Component(s) - pie.width(availableWidth).height(availableHeight); - var pieWrap = g.select('.nv-pieWrap').datum([data]); - d3.transition(pieWrap).call(pie); - - //============================================================ - // Event Handling/Dispatching (in chart's scope) - //------------------------------------------------------------ - - legend.dispatch.on('stateChange', function(newState) { - for (var key in newState) { - state[key] = newState[key]; - } - dispatch.stateChange(state); - chart.update(); - }); - - // Update chart from a state object passed to event handler - dispatch.on('changeState', function(e) { - if (typeof e.disabled !== 'undefined') { - data.forEach(function(series,i) { - series.disabled = e.disabled[i]; - }); - state.disabled = e.disabled; - } - chart.update(); - }); - }); - - renderWatch.renderEnd('pieChart immediate'); - return chart; - } - - //============================================================ - // Event Handling/Dispatching (out of chart's scope) - //------------------------------------------------------------ - - pie.dispatch.on('elementMouseover.tooltip', function(evt) { - evt['series'] = { - key: chart.x()(evt.data), - value: chart.y()(evt.data), - color: evt.color - }; - tooltip.data(evt).hidden(false); - }); - - pie.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true); - }); - - pie.dispatch.on('elementMousemove.tooltip', function(evt) { - tooltip.position({top: d3.event.pageY, left: d3.event.pageX})(); - }); - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - // expose chart's sub-components - chart.legend = legend; - chart.dispatch = dispatch; - chart.pie = pie; - chart.tooltip = tooltip; - chart.options = nv.utils.optionsFunc.bind(chart); - - // use Object get/set functionality to map between vars and chart functions - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}}, - legendPosition: {get: function(){return legendPosition;}, set: function(_){legendPosition=_;}}, - defaultState: {get: function(){return defaultState;}, set: function(_){defaultState=_;}}, - - // deprecated options - tooltips: {get: function(){return tooltip.enabled();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltips', 'use chart.tooltip.enabled() instead'); - tooltip.enabled(!!_); - }}, - tooltipContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'use chart.tooltip.contentGenerator() instead'); - tooltip.contentGenerator(_); - }}, - - // options that require extra logic in the setter - color: {get: function(){return color;}, set: function(_){ - color = _; - legend.color(color); - pie.color(color); - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - }}, - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }} - }); - nv.utils.inheritOptions(chart, pie); - nv.utils.initOptions(chart); - return chart; - }; - - nv.models.scatter = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = null - , height = null - , color = nv.utils.defaultColor() // chooses color - , id = Math.floor(Math.random() * 100000) //Create semi-unique ID incase user doesn't select one - , container = null - , x = d3.scale.linear() - , y = d3.scale.linear() - , z = d3.scale.linear() //linear because d3.svg.shape.size is treated as area - , getX = function(d) { return d.x } // accessor to get the x value - , getY = function(d) { return d.y } // accessor to get the y value - , getSize = function(d) { return d.size || 1} // accessor to get the point size - , getShape = function(d) { return d.shape || 'circle' } // accessor to get point shape - , forceX = [] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.) - , forceY = [] // List of numbers to Force into the Y scale - , forceSize = [] // List of numbers to Force into the Size scale - , interactive = true // If true, plots a voronoi overlay for advanced point intersection - , pointActive = function(d) { return !d.notActive } // any points that return false will be filtered out - , padData = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart - , padDataOuter = .1 //outerPadding to imitate ordinal scale outer padding - , clipEdge = false // if true, masks points within x and y scale - , clipVoronoi = true // if true, masks each point with a circle... can turn off to slightly increase performance - , showVoronoi = false // display the voronoi areas - , clipRadius = function() { return 25 } // function to get the radius for voronoi point clips - , xDomain = null // Override x domain (skips the calculation from data) - , yDomain = null // Override y domain - , xRange = null // Override x range - , yRange = null // Override y range - , sizeDomain = null // Override point size domain - , sizeRange = null - , singlePoint = false - , dispatch = d3.dispatch('elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'renderEnd') - , useVoronoi = true - , duration = 250 - ; - - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var x0, y0, z0 // used to store previous scales - , timeoutID - , needsUpdate = false // Flag for when the points are visually updating, but the interactive layer is behind, to disable tooltips - , renderWatch = nv.utils.renderWatch(dispatch, duration) - , _sizeRange_def = [16, 256] - ; - - function chart(selection) { - renderWatch.reset(); - selection.each(function(data) { - container = d3.select(this); - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - nv.utils.initSVG(container); - - //add series index to each data point for reference - data.forEach(function(series, i) { - series.values.forEach(function(point) { - point.series = i; - }); - }); - - // Setup Scales - // remap and flatten the data for use in calculating the scales' domains - var seriesData = (xDomain && yDomain && sizeDomain) ? [] : // if we know xDomain and yDomain and sizeDomain, no need to calculate.... if Size is constant remember to set sizeDomain to speed up performance - d3.merge( - data.map(function(d) { - return d.values.map(function(d,i) { - return { x: getX(d,i), y: getY(d,i), size: getSize(d,i) } - }) - }) - ); - - x .domain(xDomain || d3.extent(seriesData.map(function(d) { return d.x; }).concat(forceX))) - - if (padData && data[0]) - x.range(xRange || [(availableWidth * padDataOuter + availableWidth) / (2 *data[0].values.length), availableWidth - availableWidth * (1 + padDataOuter) / (2 * data[0].values.length) ]); - //x.range([availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5) / data[0].values.length ]); - else - x.range(xRange || [0, availableWidth]); - - y .domain(yDomain || d3.extent(seriesData.map(function(d) { return d.y }).concat(forceY))) - .range(yRange || [availableHeight, 0]); - - z .domain(sizeDomain || d3.extent(seriesData.map(function(d) { return d.size }).concat(forceSize))) - .range(sizeRange || _sizeRange_def); - - // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point - singlePoint = x.domain()[0] === x.domain()[1] || y.domain()[0] === y.domain()[1]; - - if (x.domain()[0] === x.domain()[1]) - x.domain()[0] ? - x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01]) - : x.domain([-1,1]); - - if (y.domain()[0] === y.domain()[1]) - y.domain()[0] ? - y.domain([y.domain()[0] - y.domain()[0] * 0.01, y.domain()[1] + y.domain()[1] * 0.01]) - : y.domain([-1,1]); - - if ( isNaN(x.domain()[0])) { - x.domain([-1,1]); - } - - if ( isNaN(y.domain()[0])) { - y.domain([-1,1]); - } - - x0 = x0 || x; - y0 = y0 || y; - z0 = z0 || z; - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-scatter').data([data]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-scatter nv-chart-' + id); - var defsEnter = wrapEnter.append('defs'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - wrap.classed('nv-single-point', singlePoint); - gEnter.append('g').attr('class', 'nv-groups'); - gEnter.append('g').attr('class', 'nv-point-paths'); - wrapEnter.append('g').attr('class', 'nv-point-clips'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - defsEnter.append('clipPath') - .attr('id', 'nv-edge-clip-' + id) - .append('rect'); - - wrap.select('#nv-edge-clip-' + id + ' rect') - .attr('width', availableWidth) - .attr('height', (availableHeight > 0) ? availableHeight : 0); - - g.attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id + ')' : ''); - - function updateInteractiveLayer() { - // Always clear needs-update flag regardless of whether or not - // we will actually do anything (avoids needless invocations). - needsUpdate = false; - - if (!interactive) return false; - - // inject series and point index for reference into voronoi - if (useVoronoi === true) { - var vertices = d3.merge(data.map(function(group, groupIndex) { - return group.values - .map(function(point, pointIndex) { - // *Adding noise to make duplicates very unlikely - // *Injecting series and point index for reference - /* *Adding a 'jitter' to the points, because there's an issue in d3.geom.voronoi. - */ - var pX = getX(point,pointIndex); - var pY = getY(point,pointIndex); - - return [x(pX)+ Math.random() * 1e-4, - y(pY)+ Math.random() * 1e-4, - groupIndex, - pointIndex, point]; //temp hack to add noise until I think of a better way so there are no duplicates - }) - .filter(function(pointArray, pointIndex) { - return pointActive(pointArray[4], pointIndex); // Issue #237.. move filter to after map, so pointIndex is correct! - }) - }) - ); - - if (vertices.length == 0) return false; // No active points, we're done - if (vertices.length < 3) { - // Issue #283 - Adding 2 dummy points to the voronoi b/c voronoi requires min 3 points to work - vertices.push([x.range()[0] - 20, y.range()[0] - 20, null, null]); - vertices.push([x.range()[1] + 20, y.range()[1] + 20, null, null]); - vertices.push([x.range()[0] - 20, y.range()[0] + 20, null, null]); - vertices.push([x.range()[1] + 20, y.range()[1] - 20, null, null]); - } - - // keep voronoi sections from going more than 10 outside of graph - // to avoid overlap with other things like legend etc - var bounds = d3.geom.polygon([ - [-10,-10], - [-10,height + 10], - [width + 10,height + 10], - [width + 10,-10] - ]); - - var voronoi = d3.geom.voronoi(vertices).map(function(d, i) { - return { - 'data': bounds.clip(d), - 'series': vertices[i][2], - 'point': vertices[i][3] - } - }); - - // nuke all voronoi paths on reload and recreate them - wrap.select('.nv-point-paths').selectAll('path').remove(); - var pointPaths = wrap.select('.nv-point-paths').selectAll('path').data(voronoi); - var vPointPaths = pointPaths - .enter().append("svg:path") - .attr("d", function(d) { - if (!d || !d.data || d.data.length === 0) - return 'M 0 0'; - else - return "M" + d.data.join(",") + "Z"; - }) - .attr("id", function(d,i) { - return "nv-path-"+i; }) - .attr("clip-path", function(d,i) { return "url(#nv-clip-"+id+"-"+i+")"; }) - ; - - // good for debugging point hover issues - if (showVoronoi) { - vPointPaths.style("fill", d3.rgb(230, 230, 230)) - .style('fill-opacity', 0.4) - .style('stroke-opacity', 1) - .style("stroke", d3.rgb(200,200,200)); - } - - if (clipVoronoi) { - // voronoi sections are already set to clip, - // just create the circles with the IDs they expect - wrap.select('.nv-point-clips').selectAll('clipPath').remove(); - wrap.select('.nv-point-clips').selectAll("clipPath") - .data(vertices) - .enter().append("svg:clipPath") - .attr("id", function(d, i) { return "nv-clip-"+id+"-"+i;}) - .append("svg:circle") - .attr('cx', function(d) { return d[0]; }) - .attr('cy', function(d) { return d[1]; }) - .attr('r', clipRadius); - } - - var mouseEventCallback = function(d, mDispatch) { - if (needsUpdate) return 0; - var series = data[d.series]; - if (series === undefined) return; - var point = series.values[d.point]; - point['color'] = color(series, d.series); - - // standardize attributes for tooltip. - point['x'] = getX(point); - point['y'] = getY(point); - - // can't just get box of event node since it's actually a voronoi polygon - var box = container.node().getBoundingClientRect(); - var scrollTop = window.pageYOffset || document.documentElement.scrollTop; - var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft; - - var pos = { - left: x(getX(point, d.point)) + box.left + scrollLeft + margin.left + 10, - top: y(getY(point, d.point)) + box.top + scrollTop + margin.top + 10 - }; - - mDispatch({ - point: point, - series: series, - pos: pos, - seriesIndex: d.series, - pointIndex: d.point - }); - }; - - pointPaths - .on('click', function(d) { - mouseEventCallback(d, dispatch.elementClick); - }) - .on('dblclick', function(d) { - mouseEventCallback(d, dispatch.elementDblClick); - }) - .on('mouseover', function(d) { - mouseEventCallback(d, dispatch.elementMouseover); - }) - .on('mouseout', function(d, i) { - mouseEventCallback(d, dispatch.elementMouseout); - }); - - } else { - // add event handlers to points instead voronoi paths - wrap.select('.nv-groups').selectAll('.nv-group') - .selectAll('.nv-point') - //.data(dataWithPoints) - //.style('pointer-events', 'auto') // recativate events, disabled by css - .on('click', function(d,i) { - //nv.log('test', d, i); - if (needsUpdate || !data[d.series]) return 0; //check if this is a dummy point - var series = data[d.series], - point = series.values[i]; - - dispatch.elementClick({ - point: point, - series: series, - pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top], - seriesIndex: d.series, - pointIndex: i - }); - }) - .on('dblclick', function(d,i) { - if (needsUpdate || !data[d.series]) return 0; //check if this is a dummy point - var series = data[d.series], - point = series.values[i]; - - dispatch.elementDblClick({ - point: point, - series: series, - pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top], - seriesIndex: d.series, - pointIndex: i - }); - }) - .on('mouseover', function(d,i) { - if (needsUpdate || !data[d.series]) return 0; //check if this is a dummy point - var series = data[d.series], - point = series.values[i]; - - dispatch.elementMouseover({ - point: point, - series: series, - pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top], - seriesIndex: d.series, - pointIndex: i, - color: color(d, i) - }); - }) - .on('mouseout', function(d,i) { - if (needsUpdate || !data[d.series]) return 0; //check if this is a dummy point - var series = data[d.series], - point = series.values[i]; - - dispatch.elementMouseout({ - point: point, - series: series, - seriesIndex: d.series, - pointIndex: i, - color: color(d, i) - }); - }); - } - } - - needsUpdate = true; - var groups = wrap.select('.nv-groups').selectAll('.nv-group') - .data(function(d) { return d }, function(d) { return d.key }); - groups.enter().append('g') - .style('stroke-opacity', 1e-6) - .style('fill-opacity', 1e-6); - groups.exit() - .remove(); - groups - .attr('class', function(d,i) { return 'nv-group nv-series-' + i }) - .classed('hover', function(d) { return d.hover }); - groups.watchTransition(renderWatch, 'scatter: groups') - .style('fill', function(d,i) { return color(d, i) }) - .style('stroke', function(d,i) { return color(d, i) }) - .style('stroke-opacity', 1) - .style('fill-opacity', .5); - - // create the points, maintaining their IDs from the original data set - var points = groups.selectAll('path.nv-point') - .data(function(d) { - return d.values.map( - function (point, pointIndex) { - return [point, pointIndex] - }).filter( - function(pointArray, pointIndex) { - return pointActive(pointArray[0], pointIndex) - }) - }); - points.enter().append('path') - .style('fill', function (d) { return d.color }) - .style('stroke', function (d) { return d.color }) - .attr('transform', function(d) { - return 'translate(' + x0(getX(d[0],d[1])) + ',' + y0(getY(d[0],d[1])) + ')' - }) - .attr('d', - nv.utils.symbol() - .type(function(d) { return getShape(d[0]); }) - .size(function(d) { return z(getSize(d[0],d[1])) }) - ); - points.exit().remove(); - groups.exit().selectAll('path.nv-point') - .watchTransition(renderWatch, 'scatter exit') - .attr('transform', function(d) { - return 'translate(' + x(getX(d[0],d[1])) + ',' + y(getY(d[0],d[1])) + ')' - }) - .remove(); - points.each(function(d) { - d3.select(this) - .classed('nv-point', true) - .classed('nv-point-' + d[1], true) - .classed('nv-noninteractive', !interactive) - .classed('hover',false) - ; - }); - points - .watchTransition(renderWatch, 'scatter points') - .attr('transform', function(d) { - //nv.log(d, getX(d[0],d[1]), x(getX(d[0],d[1]))); - return 'translate(' + x(getX(d[0],d[1])) + ',' + y(getY(d[0],d[1])) + ')' - }) - .attr('d', - nv.utils.symbol() - .type(function(d) { return getShape(d[0]); }) - .size(function(d) { return z(getSize(d[0],d[1])) }) - ); - - // Delay updating the invisible interactive layer for smoother animation - clearTimeout(timeoutID); // stop repeat calls to updateInteractiveLayer - timeoutID = setTimeout(updateInteractiveLayer, 300); - //updateInteractiveLayer(); - - //store old scales for use in transitions on update - x0 = x.copy(); - y0 = y.copy(); - z0 = z.copy(); - - }); - renderWatch.renderEnd('scatter immediate'); - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - // utility function calls provided by this chart - chart._calls = new function() { - this.clearHighlights = function () { - nv.dom.write(function() { - container.selectAll(".nv-point.hover").classed("hover", false); - }); - return null; - }; - this.highlightPoint = function (seriesIndex, pointIndex, isHoverOver) { - nv.dom.write(function() { - container.select(" .nv-series-" + seriesIndex + " .nv-point-" + pointIndex) - .classed("hover", isHoverOver); - }); - }; - }; - - // trigger calls from events too - dispatch.on('elementMouseover.point', function(d) { - if (interactive) chart._calls.highlightPoint(d.seriesIndex,d.pointIndex,true); - }); - - dispatch.on('elementMouseout.point', function(d) { - if (interactive) chart._calls.highlightPoint(d.seriesIndex,d.pointIndex,false); - }); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - xScale: {get: function(){return x;}, set: function(_){x=_;}}, - yScale: {get: function(){return y;}, set: function(_){y=_;}}, - pointScale: {get: function(){return z;}, set: function(_){z=_;}}, - xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}}, - yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}}, - pointDomain: {get: function(){return sizeDomain;}, set: function(_){sizeDomain=_;}}, - xRange: {get: function(){return xRange;}, set: function(_){xRange=_;}}, - yRange: {get: function(){return yRange;}, set: function(_){yRange=_;}}, - pointRange: {get: function(){return sizeRange;}, set: function(_){sizeRange=_;}}, - forceX: {get: function(){return forceX;}, set: function(_){forceX=_;}}, - forceY: {get: function(){return forceY;}, set: function(_){forceY=_;}}, - forcePoint: {get: function(){return forceSize;}, set: function(_){forceSize=_;}}, - interactive: {get: function(){return interactive;}, set: function(_){interactive=_;}}, - pointActive: {get: function(){return pointActive;}, set: function(_){pointActive=_;}}, - padDataOuter: {get: function(){return padDataOuter;}, set: function(_){padDataOuter=_;}}, - padData: {get: function(){return padData;}, set: function(_){padData=_;}}, - clipEdge: {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}}, - clipVoronoi: {get: function(){return clipVoronoi;}, set: function(_){clipVoronoi=_;}}, - clipRadius: {get: function(){return clipRadius;}, set: function(_){clipRadius=_;}}, - showVoronoi: {get: function(){return showVoronoi;}, set: function(_){showVoronoi=_;}}, - id: {get: function(){return id;}, set: function(_){id=_;}}, - - - // simple functor options - x: {get: function(){return getX;}, set: function(_){getX = d3.functor(_);}}, - y: {get: function(){return getY;}, set: function(_){getY = d3.functor(_);}}, - pointSize: {get: function(){return getSize;}, set: function(_){getSize = d3.functor(_);}}, - pointShape: {get: function(){return getShape;}, set: function(_){getShape = d3.functor(_);}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }}, - useVoronoi: {get: function(){return useVoronoi;}, set: function(_){ - useVoronoi = _; - if (useVoronoi === false) { - clipVoronoi = false; - } - }} - }); - - nv.utils.initOptions(chart); - return chart; - }; - - nv.models.scatterChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var scatter = nv.models.scatter() - , xAxis = nv.models.axis() - , yAxis = nv.models.axis() - , legend = nv.models.legend() - , distX = nv.models.distribution() - , distY = nv.models.distribution() - , tooltip = nv.models.tooltip() - ; - - var margin = {top: 30, right: 20, bottom: 50, left: 75} - , width = null - , height = null - , container = null - , color = nv.utils.defaultColor() - , x = scatter.xScale() - , y = scatter.yScale() - , showDistX = false - , showDistY = false - , showLegend = true - , showXAxis = true - , showYAxis = true - , rightAlignYAxis = false - , state = nv.utils.state() - , defaultState = null - , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd') - , noData = null - , duration = 250 - ; - - scatter.xScale(x).yScale(y); - xAxis.orient('bottom').tickPadding(10); - yAxis - .orient((rightAlignYAxis) ? 'right' : 'left') - .tickPadding(10) - ; - distX.axis('x'); - distY.axis('y'); - tooltip - .headerFormatter(function(d, i) { - return xAxis.tickFormat()(d, i); - }) - .valueFormatter(function(d, i) { - return yAxis.tickFormat()(d, i); - }); - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var x0, y0 - , renderWatch = nv.utils.renderWatch(dispatch, duration); - - var stateGetter = function(data) { - return function(){ - return { - active: data.map(function(d) { return !d.disabled }) - }; - } - }; - - var stateSetter = function(data) { - return function(state) { - if (state.active !== undefined) - data.forEach(function(series,i) { - series.disabled = !state.active[i]; - }); - } - }; - - function chart(selection) { - renderWatch.reset(); - renderWatch.models(scatter); - if (showXAxis) renderWatch.models(xAxis); - if (showYAxis) renderWatch.models(yAxis); - if (showDistX) renderWatch.models(distX); - if (showDistY) renderWatch.models(distY); - - selection.each(function(data) { - var that = this; - - container = d3.select(this); - nv.utils.initSVG(container); - - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - chart.update = function() { - if (duration === 0) - container.call(chart); - else - container.transition().duration(duration).call(chart); - }; - chart.container = this; - - state - .setter(stateSetter(data), chart.update) - .getter(stateGetter(data)) - .update(); - - // DEPRECATED set state.disableddisabled - state.disabled = data.map(function(d) { return !!d.disabled }); - - if (!defaultState) { - var key; - defaultState = {}; - for (key in state) { - if (state[key] instanceof Array) - defaultState[key] = state[key].slice(0); - else - defaultState[key] = state[key]; - } - } - - // Display noData message if there's nothing to show. - if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) { - nv.utils.noData(chart, container); - renderWatch.renderEnd('scatter immediate'); - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - // Setup Scales - x = scatter.xScale(); - y = scatter.yScale(); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-scatterChart').data([data]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-scatterChart nv-chart-' + scatter.id()); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - // background for pointer events - gEnter.append('rect').attr('class', 'nvd3 nv-background').style("pointer-events","none"); - - gEnter.append('g').attr('class', 'nv-x nv-axis'); - gEnter.append('g').attr('class', 'nv-y nv-axis'); - gEnter.append('g').attr('class', 'nv-scatterWrap'); - gEnter.append('g').attr('class', 'nv-regressionLinesWrap'); - gEnter.append('g').attr('class', 'nv-distWrap'); - gEnter.append('g').attr('class', 'nv-legendWrap'); - - if (rightAlignYAxis) { - g.select(".nv-y.nv-axis") - .attr("transform", "translate(" + availableWidth + ",0)"); - } - - // Legend - if (showLegend) { - var legendWidth = availableWidth; - legend.width(legendWidth); - - wrap.select('.nv-legendWrap') - .datum(data) - .call(legend); - - if ( margin.top != legend.height()) { - margin.top = legend.height(); - availableHeight = nv.utils.availableHeight(height, container, margin); - } - - wrap.select('.nv-legendWrap') - .attr('transform', 'translate(0' + ',' + (-margin.top) +')'); - } - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - // Main Chart Component(s) - scatter - .width(availableWidth) - .height(availableHeight) - .color(data.map(function(d,i) { - d.color = d.color || color(d, i); - return d.color; - }).filter(function(d,i) { return !data[i].disabled })); - - wrap.select('.nv-scatterWrap') - .datum(data.filter(function(d) { return !d.disabled })) - .call(scatter); - - - wrap.select('.nv-regressionLinesWrap') - .attr('clip-path', 'url(#nv-edge-clip-' + scatter.id() + ')'); - - var regWrap = wrap.select('.nv-regressionLinesWrap').selectAll('.nv-regLines') - .data(function (d) { - return d; - }); - - regWrap.enter().append('g').attr('class', 'nv-regLines'); - - var regLine = regWrap.selectAll('.nv-regLine') - .data(function (d) { - return [d] - }); - - regLine.enter() - .append('line').attr('class', 'nv-regLine') - .style('stroke-opacity', 0); - - // don't add lines unless we have slope and intercept to use - regLine.filter(function(d) { - return d.intercept && d.slope; - }) - .watchTransition(renderWatch, 'scatterPlusLineChart: regline') - .attr('x1', x.range()[0]) - .attr('x2', x.range()[1]) - .attr('y1', function (d, i) { - return y(x.domain()[0] * d.slope + d.intercept) - }) - .attr('y2', function (d, i) { - return y(x.domain()[1] * d.slope + d.intercept) - }) - .style('stroke', function (d, i, j) { - return color(d, j) - }) - .style('stroke-opacity', function (d, i) { - return (d.disabled || typeof d.slope === 'undefined' || typeof d.intercept === 'undefined') ? 0 : 1 - }); - - // Setup Axes - if (showXAxis) { - xAxis - .scale(x) - ._ticks( nv.utils.calcTicksX(availableWidth/100, data) ) - .tickSize( -availableHeight , 0); - - g.select('.nv-x.nv-axis') - .attr('transform', 'translate(0,' + y.range()[0] + ')') - .call(xAxis); - } - - if (showYAxis) { - yAxis - .scale(y) - ._ticks( nv.utils.calcTicksY(availableHeight/36, data) ) - .tickSize( -availableWidth, 0); - - g.select('.nv-y.nv-axis') - .call(yAxis); - } - - - if (showDistX) { - distX - .getData(scatter.x()) - .scale(x) - .width(availableWidth) - .color(data.map(function(d,i) { - return d.color || color(d, i); - }).filter(function(d,i) { return !data[i].disabled })); - gEnter.select('.nv-distWrap').append('g') - .attr('class', 'nv-distributionX'); - g.select('.nv-distributionX') - .attr('transform', 'translate(0,' + y.range()[0] + ')') - .datum(data.filter(function(d) { return !d.disabled })) - .call(distX); - } - - if (showDistY) { - distY - .getData(scatter.y()) - .scale(y) - .width(availableHeight) - .color(data.map(function(d,i) { - return d.color || color(d, i); - }).filter(function(d,i) { return !data[i].disabled })); - gEnter.select('.nv-distWrap').append('g') - .attr('class', 'nv-distributionY'); - g.select('.nv-distributionY') - .attr('transform', 'translate(' + (rightAlignYAxis ? availableWidth : -distY.size() ) + ',0)') - .datum(data.filter(function(d) { return !d.disabled })) - .call(distY); - } - - //============================================================ - // Event Handling/Dispatching (in chart's scope) - //------------------------------------------------------------ - - legend.dispatch.on('stateChange', function(newState) { - for (var key in newState) - state[key] = newState[key]; - dispatch.stateChange(state); - chart.update(); - }); - - // Update chart from a state object passed to event handler - dispatch.on('changeState', function(e) { - if (typeof e.disabled !== 'undefined') { - data.forEach(function(series,i) { - series.disabled = e.disabled[i]; - }); - state.disabled = e.disabled; - } - chart.update(); - }); - - // mouseover needs availableHeight so we just keep scatter mouse events inside the chart block - scatter.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true); - container.select('.nv-chart-' + scatter.id() + ' .nv-series-' + evt.seriesIndex + ' .nv-distx-' + evt.pointIndex) - .attr('y1', 0); - container.select('.nv-chart-' + scatter.id() + ' .nv-series-' + evt.seriesIndex + ' .nv-disty-' + evt.pointIndex) - .attr('x2', distY.size()); - }); - - scatter.dispatch.on('elementMouseover.tooltip', function(evt) { - container.select('.nv-series-' + evt.seriesIndex + ' .nv-distx-' + evt.pointIndex) - .attr('y1', evt.pos.top - availableHeight - margin.top); - container.select('.nv-series-' + evt.seriesIndex + ' .nv-disty-' + evt.pointIndex) - .attr('x2', evt.pos.left + distX.size() - margin.left); - tooltip.position(evt.pos).data(evt).hidden(false); - }); - - //store old scales for use in transitions on update - x0 = x.copy(); - y0 = y.copy(); - - }); - - renderWatch.renderEnd('scatter with line immediate'); - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - // expose chart's sub-components - chart.dispatch = dispatch; - chart.scatter = scatter; - chart.legend = legend; - chart.xAxis = xAxis; - chart.yAxis = yAxis; - chart.distX = distX; - chart.distY = distY; - chart.tooltip = tooltip; - - chart.options = nv.utils.optionsFunc.bind(chart); - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - container: {get: function(){return container;}, set: function(_){container=_;}}, - showDistX: {get: function(){return showDistX;}, set: function(_){showDistX=_;}}, - showDistY: {get: function(){return showDistY;}, set: function(_){showDistY=_;}}, - showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}}, - showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}}, - showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}}, - defaultState: {get: function(){return defaultState;}, set: function(_){defaultState=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - duration: {get: function(){return duration;}, set: function(_){duration=_;}}, - - // deprecated options - tooltips: {get: function(){return tooltip.enabled();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltips', 'use chart.tooltip.enabled() instead'); - tooltip.enabled(!!_); - }}, - tooltipContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'use chart.tooltip.contentGenerator() instead'); - tooltip.contentGenerator(_); - }}, - tooltipXContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'This option is removed, put values into main tooltip.'); - }}, - tooltipYContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'This option is removed, put values into main tooltip.'); - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){ - rightAlignYAxis = _; - yAxis.orient( (_) ? 'right' : 'left'); - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - legend.color(color); - distX.color(color); - distY.color(color); - }} - }); - - nv.utils.inheritOptions(chart, scatter); - nv.utils.initOptions(chart); - return chart; - }; - - nv.models.sparkline = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 2, right: 0, bottom: 2, left: 0} - , width = 400 - , height = 32 - , container = null - , animate = true - , x = d3.scale.linear() - , y = d3.scale.linear() - , getX = function(d) { return d.x } - , getY = function(d) { return d.y } - , color = nv.utils.getColor(['#000']) - , xDomain - , yDomain - , xRange - , yRange - ; - - function chart(selection) { - selection.each(function(data) { - var availableWidth = width - margin.left - margin.right, - availableHeight = height - margin.top - margin.bottom; - - container = d3.select(this); - nv.utils.initSVG(container); - - // Setup Scales - x .domain(xDomain || d3.extent(data, getX )) - .range(xRange || [0, availableWidth]); - - y .domain(yDomain || d3.extent(data, getY )) - .range(yRange || [availableHeight, 0]); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-sparkline').data([data]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-sparkline'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')') - - var paths = wrap.selectAll('path') - .data(function(d) { return [d] }); - paths.enter().append('path'); - paths.exit().remove(); - paths - .style('stroke', function(d,i) { return d.color || color(d, i) }) - .attr('d', d3.svg.line() - .x(function(d,i) { return x(getX(d,i)) }) - .y(function(d,i) { return y(getY(d,i)) }) - ); - - // TODO: Add CURRENT data point (Need Min, Mac, Current / Most recent) - var points = wrap.selectAll('circle.nv-point') - .data(function(data) { - var yValues = data.map(function(d, i) { return getY(d,i); }); - function pointIndex(index) { - if (index != -1) { - var result = data[index]; - result.pointIndex = index; - return result; - } else { - return null; - } - } - var maxPoint = pointIndex(yValues.lastIndexOf(y.domain()[1])), - minPoint = pointIndex(yValues.indexOf(y.domain()[0])), - currentPoint = pointIndex(yValues.length - 1); - return [minPoint, maxPoint, currentPoint].filter(function (d) {return d != null;}); - }); - points.enter().append('circle'); - points.exit().remove(); - points - .attr('cx', function(d,i) { return x(getX(d,d.pointIndex)) }) - .attr('cy', function(d,i) { return y(getY(d,d.pointIndex)) }) - .attr('r', 2) - .attr('class', function(d,i) { - return getX(d, d.pointIndex) == x.domain()[1] ? 'nv-point nv-currentValue' : - getY(d, d.pointIndex) == y.domain()[0] ? 'nv-point nv-minValue' : 'nv-point nv-maxValue' - }); - }); - - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}}, - yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}}, - xRange: {get: function(){return xRange;}, set: function(_){xRange=_;}}, - yRange: {get: function(){return yRange;}, set: function(_){yRange=_;}}, - xScale: {get: function(){return x;}, set: function(_){x=_;}}, - yScale: {get: function(){return y;}, set: function(_){y=_;}}, - animate: {get: function(){return animate;}, set: function(_){animate=_;}}, - - //functor options - x: {get: function(){return getX;}, set: function(_){getX=d3.functor(_);}}, - y: {get: function(){return getY;}, set: function(_){getY=d3.functor(_);}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }} - }); - - nv.utils.initOptions(chart); - return chart; - }; - - nv.models.sparklinePlus = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var sparkline = nv.models.sparkline(); - - var margin = {top: 15, right: 100, bottom: 10, left: 50} - , width = null - , height = null - , x - , y - , index = [] - , paused = false - , xTickFormat = d3.format(',r') - , yTickFormat = d3.format(',.2f') - , showLastValue = true - , alignValue = true - , rightAlignValue = false - , noData = null - ; - - function chart(selection) { - selection.each(function(data) { - var container = d3.select(this); - nv.utils.initSVG(container); - - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - chart.update = function() { container.call(chart); }; - chart.container = this; - - // Display No Data message if there's nothing to show. - if (!data || !data.length) { - nv.utils.noData(chart, container) - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - var currentValue = sparkline.y()(data[data.length-1], data.length-1); - - // Setup Scales - x = sparkline.xScale(); - y = sparkline.yScale(); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-sparklineplus').data([data]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-sparklineplus'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-sparklineWrap'); - gEnter.append('g').attr('class', 'nv-valueWrap'); - gEnter.append('g').attr('class', 'nv-hoverArea'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - // Main Chart Component(s) - var sparklineWrap = g.select('.nv-sparklineWrap'); - - sparkline.width(availableWidth).height(availableHeight); - sparklineWrap.call(sparkline); - - if (showLastValue) { - var valueWrap = g.select('.nv-valueWrap'); - var value = valueWrap.selectAll('.nv-currentValue') - .data([currentValue]); - - value.enter().append('text').attr('class', 'nv-currentValue') - .attr('dx', rightAlignValue ? -8 : 8) - .attr('dy', '.9em') - .style('text-anchor', rightAlignValue ? 'end' : 'start'); - - value - .attr('x', availableWidth + (rightAlignValue ? margin.right : 0)) - .attr('y', alignValue ? function (d) { - return y(d) - } : 0) - .style('fill', sparkline.color()(data[data.length - 1], data.length - 1)) - .text(yTickFormat(currentValue)); - } - - gEnter.select('.nv-hoverArea').append('rect') - .on('mousemove', sparklineHover) - .on('click', function() { paused = !paused }) - .on('mouseout', function() { index = []; updateValueLine(); }); - - g.select('.nv-hoverArea rect') - .attr('transform', function(d) { return 'translate(' + -margin.left + ',' + -margin.top + ')' }) - .attr('width', availableWidth + margin.left + margin.right) - .attr('height', availableHeight + margin.top); - - //index is currently global (within the chart), may or may not keep it that way - function updateValueLine() { - if (paused) return; - - var hoverValue = g.selectAll('.nv-hoverValue').data(index); - - var hoverEnter = hoverValue.enter() - .append('g').attr('class', 'nv-hoverValue') - .style('stroke-opacity', 0) - .style('fill-opacity', 0); - - hoverValue.exit() - .transition().duration(250) - .style('stroke-opacity', 0) - .style('fill-opacity', 0) - .remove(); - - hoverValue - .attr('transform', function(d) { return 'translate(' + x(sparkline.x()(data[d],d)) + ',0)' }) - .transition().duration(250) - .style('stroke-opacity', 1) - .style('fill-opacity', 1); - - if (!index.length) return; - - hoverEnter.append('line') - .attr('x1', 0) - .attr('y1', -margin.top) - .attr('x2', 0) - .attr('y2', availableHeight); - - hoverEnter.append('text').attr('class', 'nv-xValue') - .attr('x', -6) - .attr('y', -margin.top) - .attr('text-anchor', 'end') - .attr('dy', '.9em'); - - g.select('.nv-hoverValue .nv-xValue') - .text(xTickFormat(sparkline.x()(data[index[0]], index[0]))); - - hoverEnter.append('text').attr('class', 'nv-yValue') - .attr('x', 6) - .attr('y', -margin.top) - .attr('text-anchor', 'start') - .attr('dy', '.9em'); - - g.select('.nv-hoverValue .nv-yValue') - .text(yTickFormat(sparkline.y()(data[index[0]], index[0]))); - } - - function sparklineHover() { - if (paused) return; - - var pos = d3.mouse(this)[0] - margin.left; - - function getClosestIndex(data, x) { - var distance = Math.abs(sparkline.x()(data[0], 0) - x); - var closestIndex = 0; - for (var i = 0; i < data.length; i++){ - if (Math.abs(sparkline.x()(data[i], i) - x) < distance) { - distance = Math.abs(sparkline.x()(data[i], i) - x); - closestIndex = i; - } - } - return closestIndex; - } - - index = [getClosestIndex(data, Math.round(x.invert(pos)))]; - updateValueLine(); - } - - }); - - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - // expose chart's sub-components - chart.sparkline = sparkline; - - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - xTickFormat: {get: function(){return xTickFormat;}, set: function(_){xTickFormat=_;}}, - yTickFormat: {get: function(){return yTickFormat;}, set: function(_){yTickFormat=_;}}, - showLastValue: {get: function(){return showLastValue;}, set: function(_){showLastValue=_;}}, - alignValue: {get: function(){return alignValue;}, set: function(_){alignValue=_;}}, - rightAlignValue: {get: function(){return rightAlignValue;}, set: function(_){rightAlignValue=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }} - }); - - nv.utils.inheritOptions(chart, sparkline); - nv.utils.initOptions(chart); - - return chart; - }; - - nv.models.stackedArea = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = 960 - , height = 500 - , color = nv.utils.defaultColor() // a function that computes the color - , id = Math.floor(Math.random() * 100000) //Create semi-unique ID incase user doesn't selet one - , container = null - , getX = function(d) { return d.x } // accessor to get the x value from a data point - , getY = function(d) { return d.y } // accessor to get the y value from a data point - , style = 'stack' - , offset = 'zero' - , order = 'default' - , interpolate = 'linear' // controls the line interpolation - , clipEdge = false // if true, masks lines within x and y scale - , x //can be accessed via chart.xScale() - , y //can be accessed via chart.yScale() - , scatter = nv.models.scatter() - , duration = 250 - , dispatch = d3.dispatch('areaClick', 'areaMouseover', 'areaMouseout','renderEnd', 'elementClick', 'elementMouseover', 'elementMouseout') - ; - - scatter - .pointSize(2.2) // default size - .pointDomain([2.2, 2.2]) // all the same size by default - ; - - /************************************ - * offset: - * 'wiggle' (stream) - * 'zero' (stacked) - * 'expand' (normalize to 100%) - * 'silhouette' (simple centered) - * - * order: - * 'inside-out' (stream) - * 'default' (input order) - ************************************/ - - var renderWatch = nv.utils.renderWatch(dispatch, duration); - - function chart(selection) { - renderWatch.reset(); - renderWatch.models(scatter); - selection.each(function(data) { - var availableWidth = width - margin.left - margin.right, - availableHeight = height - margin.top - margin.bottom; - - container = d3.select(this); - nv.utils.initSVG(container); - - // Setup Scales - x = scatter.xScale(); - y = scatter.yScale(); - - var dataRaw = data; - // Injecting point index into each point because d3.layout.stack().out does not give index - data.forEach(function(aseries, i) { - aseries.seriesIndex = i; - aseries.values = aseries.values.map(function(d, j) { - d.index = j; - d.seriesIndex = i; - return d; - }); - }); - - var dataFiltered = data.filter(function(series) { - return !series.disabled; - }); - - data = d3.layout.stack() - .order(order) - .offset(offset) - .values(function(d) { return d.values }) //TODO: make values customizeable in EVERY model in this fashion - .x(getX) - .y(getY) - .out(function(d, y0, y) { - d.display = { - y: y, - y0: y0 - }; - }) - (dataFiltered); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-stackedarea').data([data]); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-stackedarea'); - var defsEnter = wrapEnter.append('defs'); - var gEnter = wrapEnter.append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-areaWrap'); - gEnter.append('g').attr('class', 'nv-scatterWrap'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - // If the user has not specified forceY, make sure 0 is included in the domain - // Otherwise, use user-specified values for forceY - if (scatter.forceY().length == 0) { - scatter.forceY().push(0); - } - - scatter - .width(availableWidth) - .height(availableHeight) - .x(getX) - .y(function(d) { return d.display.y + d.display.y0 }) - .forceY([0]) - .color(data.map(function(d,i) { - return d.color || color(d, d.seriesIndex); - })); - - var scatterWrap = g.select('.nv-scatterWrap') - .datum(data); - - scatterWrap.call(scatter); - - defsEnter.append('clipPath') - .attr('id', 'nv-edge-clip-' + id) - .append('rect'); - - wrap.select('#nv-edge-clip-' + id + ' rect') - .attr('width', availableWidth) - .attr('height', availableHeight); - - g.attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id + ')' : ''); - - var area = d3.svg.area() - .x(function(d,i) { return x(getX(d,i)) }) - .y0(function(d) { - return y(d.display.y0) - }) - .y1(function(d) { - return y(d.display.y + d.display.y0) - }) - .interpolate(interpolate); - - var zeroArea = d3.svg.area() - .x(function(d,i) { return x(getX(d,i)) }) - .y0(function(d) { return y(d.display.y0) }) - .y1(function(d) { return y(d.display.y0) }); - - var path = g.select('.nv-areaWrap').selectAll('path.nv-area') - .data(function(d) { return d }); - - path.enter().append('path').attr('class', function(d,i) { return 'nv-area nv-area-' + i }) - .attr('d', function(d,i){ - return zeroArea(d.values, d.seriesIndex); - }) - .on('mouseover', function(d,i) { - d3.select(this).classed('hover', true); - dispatch.areaMouseover({ - point: d, - series: d.key, - pos: [d3.event.pageX, d3.event.pageY], - seriesIndex: d.seriesIndex - }); - }) - .on('mouseout', function(d,i) { - d3.select(this).classed('hover', false); - dispatch.areaMouseout({ - point: d, - series: d.key, - pos: [d3.event.pageX, d3.event.pageY], - seriesIndex: d.seriesIndex - }); - }) - .on('click', function(d,i) { - d3.select(this).classed('hover', false); - dispatch.areaClick({ - point: d, - series: d.key, - pos: [d3.event.pageX, d3.event.pageY], - seriesIndex: d.seriesIndex - }); - }); - - path.exit().remove(); - path.style('fill', function(d,i){ - return d.color || color(d, d.seriesIndex) - }) - .style('stroke', function(d,i){ return d.color || color(d, d.seriesIndex) }); - path.watchTransition(renderWatch,'stackedArea path') - .attr('d', function(d,i) { - return area(d.values,i) - }); - - //============================================================ - // Event Handling/Dispatching (in chart's scope) - //------------------------------------------------------------ - - scatter.dispatch.on('elementMouseover.area', function(e) { - g.select('.nv-chart-' + id + ' .nv-area-' + e.seriesIndex).classed('hover', true); - }); - scatter.dispatch.on('elementMouseout.area', function(e) { - g.select('.nv-chart-' + id + ' .nv-area-' + e.seriesIndex).classed('hover', false); - }); - - //Special offset functions - chart.d3_stackedOffset_stackPercent = function(stackData) { - var n = stackData.length, //How many series - m = stackData[0].length, //how many points per series - i, - j, - o, - y0 = []; - - for (j = 0; j < m; ++j) { //Looping through all points - for (i = 0, o = 0; i < dataRaw.length; i++) { //looping through all series - o += getY(dataRaw[i].values[j]); //total y value of all series at a certian point in time. - } - - if (o) for (i = 0; i < n; i++) { //(total y value of all series at point in time i) != 0 - stackData[i][j][1] /= o; - } else { //(total y value of all series at point in time i) == 0 - for (i = 0; i < n; i++) { - stackData[i][j][1] = 0; - } - } - } - for (j = 0; j < m; ++j) y0[j] = 0; - return y0; - }; - - }); - - renderWatch.renderEnd('stackedArea immediate'); - return chart; - } - - //============================================================ - // Global getters and setters - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.scatter = scatter; - - scatter.dispatch.on('elementClick', function(){ dispatch.elementClick.apply(this, arguments); }); - scatter.dispatch.on('elementMouseover', function(){ dispatch.elementMouseover.apply(this, arguments); }); - scatter.dispatch.on('elementMouseout', function(){ dispatch.elementMouseout.apply(this, arguments); }); - - chart.interpolate = function(_) { - if (!arguments.length) return interpolate; - interpolate = _; - return chart; - }; - - chart.duration = function(_) { - if (!arguments.length) return duration; - duration = _; - renderWatch.reset(duration); - scatter.duration(duration); - return chart; - }; - - chart.dispatch = dispatch; - chart.scatter = scatter; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - clipEdge: {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}}, - offset: {get: function(){return offset;}, set: function(_){offset=_;}}, - order: {get: function(){return order;}, set: function(_){order=_;}}, - interpolate: {get: function(){return interpolate;}, set: function(_){interpolate=_;}}, - - // simple functor options - x: {get: function(){return getX;}, set: function(_){getX = d3.functor(_);}}, - y: {get: function(){return getY;}, set: function(_){getY = d3.functor(_);}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - }}, - style: {get: function(){return style;}, set: function(_){ - style = _; - switch (style) { - case 'stack': - chart.offset('zero'); - chart.order('default'); - break; - case 'stream': - chart.offset('wiggle'); - chart.order('inside-out'); - break; - case 'stream-center': - chart.offset('silhouette'); - chart.order('inside-out'); - break; - case 'expand': - chart.offset('expand'); - chart.order('default'); - break; - case 'stack_percent': - chart.offset(chart.d3_stackedOffset_stackPercent); - chart.order('default'); - break; - } - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - scatter.duration(duration); - }} - }); - - nv.utils.inheritOptions(chart, scatter); - nv.utils.initOptions(chart); - - return chart; - }; - - nv.models.stackedAreaChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var stacked = nv.models.stackedArea() - , xAxis = nv.models.axis() - , yAxis = nv.models.axis() - , legend = nv.models.legend() - , controls = nv.models.legend() - , interactiveLayer = nv.interactiveGuideline() - , tooltip = nv.models.tooltip() - ; - - var margin = {top: 30, right: 25, bottom: 50, left: 60} - , width = null - , height = null - , color = nv.utils.defaultColor() - , showControls = true - , showLegend = true - , showXAxis = true - , showYAxis = true - , rightAlignYAxis = false - , useInteractiveGuideline = false - , x //can be accessed via chart.xScale() - , y //can be accessed via chart.yScale() - , state = nv.utils.state() - , defaultState = null - , noData = null - , dispatch = d3.dispatch('stateChange', 'changeState','renderEnd') - , controlWidth = 250 - , controlOptions = ['Stacked','Stream','Expanded'] - , controlLabels = {} - , duration = 250 - ; - - state.style = stacked.style(); - xAxis.orient('bottom').tickPadding(7); - yAxis.orient((rightAlignYAxis) ? 'right' : 'left'); - - tooltip - .headerFormatter(function(d, i) { - return xAxis.tickFormat()(d, i); - }) - .valueFormatter(function(d, i) { - return yAxis.tickFormat()(d, i); - }); - - interactiveLayer.tooltip - .headerFormatter(function(d, i) { - return xAxis.tickFormat()(d, i); - }) - .valueFormatter(function(d, i) { - return yAxis.tickFormat()(d, i); - }); - - var oldYTickFormat = null, - oldValueFormatter = null; - - controls.updateState(false); - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var renderWatch = nv.utils.renderWatch(dispatch); - var style = stacked.style(); - - var stateGetter = function(data) { - return function(){ - return { - active: data.map(function(d) { return !d.disabled }), - style: stacked.style() - }; - } - }; - - var stateSetter = function(data) { - return function(state) { - if (state.style !== undefined) - style = state.style; - if (state.active !== undefined) - data.forEach(function(series,i) { - series.disabled = !state.active[i]; - }); - } - }; - - var percentFormatter = d3.format('%'); - - function chart(selection) { - renderWatch.reset(); - renderWatch.models(stacked); - if (showXAxis) renderWatch.models(xAxis); - if (showYAxis) renderWatch.models(yAxis); - - selection.each(function(data) { - var container = d3.select(this), - that = this; - nv.utils.initSVG(container); - - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - chart.update = function() { container.transition().duration(duration).call(chart); }; - chart.container = this; - - state - .setter(stateSetter(data), chart.update) - .getter(stateGetter(data)) - .update(); - - // DEPRECATED set state.disabled - state.disabled = data.map(function(d) { return !!d.disabled }); - - if (!defaultState) { - var key; - defaultState = {}; - for (key in state) { - if (state[key] instanceof Array) - defaultState[key] = state[key].slice(0); - else - defaultState[key] = state[key]; - } - } - - // Display No Data message if there's nothing to show. - if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) { - nv.utils.noData(chart, container) - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - // Setup Scales - x = stacked.xScale(); - y = stacked.yScale(); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-stackedAreaChart').data([data]); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-stackedAreaChart').append('g'); - var g = wrap.select('g'); - - gEnter.append("rect").style("opacity",0); - gEnter.append('g').attr('class', 'nv-x nv-axis'); - gEnter.append('g').attr('class', 'nv-y nv-axis'); - gEnter.append('g').attr('class', 'nv-stackedWrap'); - gEnter.append('g').attr('class', 'nv-legendWrap'); - gEnter.append('g').attr('class', 'nv-controlsWrap'); - gEnter.append('g').attr('class', 'nv-interactive'); - - g.select("rect").attr("width",availableWidth).attr("height",availableHeight); - - // Legend - if (showLegend) { - var legendWidth = (showControls) ? availableWidth - controlWidth : availableWidth; - - legend.width(legendWidth); - g.select('.nv-legendWrap').datum(data).call(legend); - - if ( margin.top != legend.height()) { - margin.top = legend.height(); - availableHeight = nv.utils.availableHeight(height, container, margin); - } - - g.select('.nv-legendWrap') - .attr('transform', 'translate(' + (availableWidth-legendWidth) + ',' + (-margin.top) +')'); - } - - // Controls - if (showControls) { - var controlsData = [ - { - key: controlLabels.stacked || 'Stacked', - metaKey: 'Stacked', - disabled: stacked.style() != 'stack', - style: 'stack' - }, - { - key: controlLabels.stream || 'Stream', - metaKey: 'Stream', - disabled: stacked.style() != 'stream', - style: 'stream' - }, - { - key: controlLabels.expanded || 'Expanded', - metaKey: 'Expanded', - disabled: stacked.style() != 'expand', - style: 'expand' - }, - { - key: controlLabels.stack_percent || 'Stack %', - metaKey: 'Stack_Percent', - disabled: stacked.style() != 'stack_percent', - style: 'stack_percent' - } - ]; - - controlWidth = (controlOptions.length/3) * 260; - controlsData = controlsData.filter(function(d) { - return controlOptions.indexOf(d.metaKey) !== -1; - }); - - controls - .width( controlWidth ) - .color(['#444', '#444', '#444']); - - g.select('.nv-controlsWrap') - .datum(controlsData) - .call(controls); - - if ( margin.top != Math.max(controls.height(), legend.height()) ) { - margin.top = Math.max(controls.height(), legend.height()); - availableHeight = nv.utils.availableHeight(height, container, margin); - } - - g.select('.nv-controlsWrap') - .attr('transform', 'translate(0,' + (-margin.top) +')'); - } - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - if (rightAlignYAxis) { - g.select(".nv-y.nv-axis") - .attr("transform", "translate(" + availableWidth + ",0)"); - } - - //Set up interactive layer - if (useInteractiveGuideline) { - interactiveLayer - .width(availableWidth) - .height(availableHeight) - .margin({left: margin.left, top: margin.top}) - .svgContainer(container) - .xScale(x); - wrap.select(".nv-interactive").call(interactiveLayer); - } - - stacked - .width(availableWidth) - .height(availableHeight); - - var stackedWrap = g.select('.nv-stackedWrap') - .datum(data); - - stackedWrap.transition().call(stacked); - - // Setup Axes - if (showXAxis) { - xAxis.scale(x) - ._ticks( nv.utils.calcTicksX(availableWidth/100, data) ) - .tickSize( -availableHeight, 0); - - g.select('.nv-x.nv-axis') - .attr('transform', 'translate(0,' + availableHeight + ')'); - - g.select('.nv-x.nv-axis') - .transition().duration(0) - .call(xAxis); - } - - if (showYAxis) { - var ticks; - if (stacked.offset() === 'wiggle') { - ticks = 0; - } - else { - ticks = nv.utils.calcTicksY(availableHeight/36, data); - } - yAxis.scale(y) - ._ticks(ticks) - .tickSize(-availableWidth, 0); - - if (stacked.style() === 'expand' || stacked.style() === 'stack_percent') { - var currentFormat = yAxis.tickFormat(); - - if ( !oldYTickFormat || currentFormat !== percentFormatter ) - oldYTickFormat = currentFormat; - - //Forces the yAxis to use percentage in 'expand' mode. - yAxis.tickFormat(percentFormatter); - } - else { - if (oldYTickFormat) { - yAxis.tickFormat(oldYTickFormat); - oldYTickFormat = null; - } - } - - g.select('.nv-y.nv-axis') - .transition().duration(0) - .call(yAxis); - } - - //============================================================ - // Event Handling/Dispatching (in chart's scope) - //------------------------------------------------------------ - - stacked.dispatch.on('areaClick.toggle', function(e) { - if (data.filter(function(d) { return !d.disabled }).length === 1) - data.forEach(function(d) { - d.disabled = false; - }); - else - data.forEach(function(d,i) { - d.disabled = (i != e.seriesIndex); - }); - - state.disabled = data.map(function(d) { return !!d.disabled }); - dispatch.stateChange(state); - - chart.update(); - }); - - legend.dispatch.on('stateChange', function(newState) { - for (var key in newState) - state[key] = newState[key]; - dispatch.stateChange(state); - chart.update(); - }); - - controls.dispatch.on('legendClick', function(d,i) { - if (!d.disabled) return; - - controlsData = controlsData.map(function(s) { - s.disabled = true; - return s; - }); - d.disabled = false; - - stacked.style(d.style); - - - state.style = stacked.style(); - dispatch.stateChange(state); - - chart.update(); - }); - - interactiveLayer.dispatch.on('elementMousemove', function(e) { - stacked.clearHighlights(); - var singlePoint, pointIndex, pointXLocation, allData = []; - data - .filter(function(series, i) { - series.seriesIndex = i; - return !series.disabled; - }) - .forEach(function(series,i) { - pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x()); - var point = series.values[pointIndex]; - var pointYValue = chart.y()(point, pointIndex); - if (pointYValue != null) { - stacked.highlightPoint(i, pointIndex, true); - } - if (typeof point === 'undefined') return; - if (typeof singlePoint === 'undefined') singlePoint = point; - if (typeof pointXLocation === 'undefined') pointXLocation = chart.xScale()(chart.x()(point,pointIndex)); - - //If we are in 'expand' mode, use the stacked percent value instead of raw value. - var tooltipValue = (stacked.style() == 'expand') ? point.display.y : chart.y()(point,pointIndex); - allData.push({ - key: series.key, - value: tooltipValue, - color: color(series,series.seriesIndex), - stackedValue: point.display - }); - }); - - allData.reverse(); - - //Highlight the tooltip entry based on which stack the mouse is closest to. - if (allData.length > 2) { - var yValue = chart.yScale().invert(e.mouseY); - var yDistMax = Infinity, indexToHighlight = null; - allData.forEach(function(series,i) { - - //To handle situation where the stacked area chart is negative, we need to use absolute values - //when checking if the mouse Y value is within the stack area. - yValue = Math.abs(yValue); - var stackedY0 = Math.abs(series.stackedValue.y0); - var stackedY = Math.abs(series.stackedValue.y); - if ( yValue >= stackedY0 && yValue <= (stackedY + stackedY0)) - { - indexToHighlight = i; - return; - } - }); - if (indexToHighlight != null) - allData[indexToHighlight].highlight = true; - } - - var xValue = xAxis.tickFormat()(chart.x()(singlePoint,pointIndex)); - - var valueFormatter = interactiveLayer.tooltip.valueFormatter(); - // Keeps track of the tooltip valueFormatter if the chart changes to expanded view - if (stacked.style() === 'expand' || stacked.style() === 'stack_percent') { - if ( !oldValueFormatter ) { - oldValueFormatter = valueFormatter; - } - //Forces the tooltip to use percentage in 'expand' mode. - valueFormatter = d3.format(".1%"); - } - else { - if (oldValueFormatter) { - valueFormatter = oldValueFormatter; - oldValueFormatter = null; - } - } - - interactiveLayer.tooltip - .position({left: pointXLocation + margin.left, top: e.mouseY + margin.top}) - .chartContainer(that.parentNode) - .valueFormatter(valueFormatter) - .data( - { - value: xValue, - series: allData - } - )(); - - interactiveLayer.renderGuideLine(pointXLocation); - - }); - - interactiveLayer.dispatch.on("elementMouseout",function(e) { - stacked.clearHighlights(); - }); - - // Update chart from a state object passed to event handler - dispatch.on('changeState', function(e) { - - if (typeof e.disabled !== 'undefined' && data.length === e.disabled.length) { - data.forEach(function(series,i) { - series.disabled = e.disabled[i]; - }); - - state.disabled = e.disabled; - } - - if (typeof e.style !== 'undefined') { - stacked.style(e.style); - style = e.style; - } - - chart.update(); - }); - - }); - - renderWatch.renderEnd('stacked Area chart immediate'); - return chart; - } - - //============================================================ - // Event Handling/Dispatching (out of chart's scope) - //------------------------------------------------------------ - - stacked.dispatch.on('elementMouseover.tooltip', function(evt) { - evt.point['x'] = stacked.x()(evt.point); - evt.point['y'] = stacked.y()(evt.point); - tooltip.data(evt).position(evt.pos).hidden(false); - }); - - stacked.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true) - }); - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - // expose chart's sub-components - chart.dispatch = dispatch; - chart.stacked = stacked; - chart.legend = legend; - chart.controls = controls; - chart.xAxis = xAxis; - chart.yAxis = yAxis; - chart.interactiveLayer = interactiveLayer; - chart.tooltip = tooltip; - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}}, - showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}}, - showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}}, - defaultState: {get: function(){return defaultState;}, set: function(_){defaultState=_;}}, - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - showControls: {get: function(){return showControls;}, set: function(_){showControls=_;}}, - controlLabels: {get: function(){return controlLabels;}, set: function(_){controlLabels=_;}}, - controlOptions: {get: function(){return controlOptions;}, set: function(_){controlOptions=_;}}, - - // deprecated options - tooltips: {get: function(){return tooltip.enabled();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltips', 'use chart.tooltip.enabled() instead'); - tooltip.enabled(!!_); - }}, - tooltipContent: {get: function(){return tooltip.contentGenerator();}, set: function(_){ - // deprecated after 1.7.1 - nv.deprecated('tooltipContent', 'use chart.tooltip.contentGenerator() instead'); - tooltip.contentGenerator(_); - }}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - stacked.duration(duration); - xAxis.duration(duration); - yAxis.duration(duration); - }}, - color: {get: function(){return color;}, set: function(_){ - color = nv.utils.getColor(_); - legend.color(color); - stacked.color(color); - }}, - rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){ - rightAlignYAxis = _; - yAxis.orient( rightAlignYAxis ? 'right' : 'left'); - }}, - useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){ - useInteractiveGuideline = !!_; - chart.interactive(!_); - chart.useVoronoi(!_); - stacked.scatter.interactive(!_); - }} - }); - - nv.utils.inheritOptions(chart, stacked); - nv.utils.initOptions(chart); - - return chart; - }; -// based on http://bl.ocks.org/kerryrodden/477c1bfb081b783f80ad - nv.models.sunburst = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = null - , height = null - , mode = "count" - , modes = {count: function(d) { return 1; }, size: function(d) { return d.size }} - , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one - , container = null - , color = nv.utils.defaultColor() - , duration = 500 - , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMousemove', 'elementMouseover', 'elementMouseout', 'renderEnd') - ; - - var x = d3.scale.linear().range([0, 2 * Math.PI]); - var y = d3.scale.sqrt(); - - var partition = d3.layout.partition() - .sort(null) - .value(function(d) { return 1; }); - - var arc = d3.svg.arc() - .startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); }) - .endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); }) - .innerRadius(function(d) { return Math.max(0, y(d.y)); }) - .outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); }); - - // Keep track of the current and previous node being displayed as the root. - var node, prevNode; - // Keep track of the root node - var rootNode; - - //============================================================ - // chart function - //------------------------------------------------------------ - - var renderWatch = nv.utils.renderWatch(dispatch); - - function chart(selection) { - renderWatch.reset(); - selection.each(function(data) { - container = d3.select(this); - var availableWidth = nv.utils.availableWidth(width, container, margin); - var availableHeight = nv.utils.availableHeight(height, container, margin); - var radius = Math.min(availableWidth, availableHeight) / 2; - var path; - - nv.utils.initSVG(container); - - // Setup containers and skeleton of chart - var wrap = container.selectAll('.nv-wrap.nv-sunburst').data(data); - var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-sunburst nv-chart-' + id); - - var g = wrapEnter.selectAll('nv-sunburst'); - - wrap.attr('transform', 'translate(' + availableWidth / 2 + ',' + availableHeight / 2 + ')'); - - container.on('click', function (d, i) { - dispatch.chartClick({ - data: d, - index: i, - pos: d3.event, - id: id - }); - }); - - y.range([0, radius]); - - node = node || data; - rootNode = data[0]; - partition.value(modes[mode] || modes["count"]); - path = g.data(partition.nodes).enter() - .append("path") - .attr("d", arc) - .style("fill", function (d) { - return color((d.children ? d : d.parent).name); - }) - .style("stroke", "#FFF") - .on("click", function(d) { - if (prevNode !== node && node !== d) prevNode = node; - node = d; - path.transition() - .duration(duration) - .attrTween("d", arcTweenZoom(d)); - }) - .each(stash) - .on("dblclick", function(d) { - if (prevNode.parent == d) { - path.transition() - .duration(duration) - .attrTween("d", arcTweenZoom(rootNode)); - } - }) - .each(stash) - .on('mouseover', function(d,i){ - d3.select(this).classed('hover', true).style('opacity', 0.8); - dispatch.elementMouseover({ - data: d, - color: d3.select(this).style("fill") - }); - }) - .on('mouseout', function(d,i){ - d3.select(this).classed('hover', false).style('opacity', 1); - dispatch.elementMouseout({ - data: d - }); - }) - .on('mousemove', function(d,i){ - dispatch.elementMousemove({ - data: d - }); - }); - - - - // Setup for switching data: stash the old values for transition. - function stash(d) { - d.x0 = d.x; - d.dx0 = d.dx; - } - - // When switching data: interpolate the arcs in data space. - function arcTweenData(a, i) { - var oi = d3.interpolate({x: a.x0, dx: a.dx0}, a); - - function tween(t) { - var b = oi(t); - a.x0 = b.x; - a.dx0 = b.dx; - return arc(b); - } - - if (i == 0) { - // If we are on the first arc, adjust the x domain to match the root node - // at the current zoom level. (We only need to do this once.) - var xd = d3.interpolate(x.domain(), [node.x, node.x + node.dx]); - return function (t) { - x.domain(xd(t)); - return tween(t); - }; - } else { - return tween; - } - } - - // When zooming: interpolate the scales. - function arcTweenZoom(d) { - var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]), - yd = d3.interpolate(y.domain(), [d.y, 1]), - yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]); - return function (d, i) { - return i - ? function (t) { - return arc(d); - } - : function (t) { - x.domain(xd(t)); - y.domain(yd(t)).range(yr(t)); - return arc(d); - }; - }; - } - - }); - - renderWatch.renderEnd('sunburst immediate'); - return chart; - } - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - chart.dispatch = dispatch; - chart.options = nv.utils.optionsFunc.bind(chart); - - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - width: {get: function(){return width;}, set: function(_){width=_;}}, - height: {get: function(){return height;}, set: function(_){height=_;}}, - mode: {get: function(){return mode;}, set: function(_){mode=_;}}, - id: {get: function(){return id;}, set: function(_){id=_;}}, - duration: {get: function(){return duration;}, set: function(_){duration=_;}}, - - // options that require extra logic in the setter - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top != undefined ? _.top : margin.top; - margin.right = _.right != undefined ? _.right : margin.right; - margin.bottom = _.bottom != undefined ? _.bottom : margin.bottom; - margin.left = _.left != undefined ? _.left : margin.left; - }}, - color: {get: function(){return color;}, set: function(_){ - color=nv.utils.getColor(_); - }} - }); - - nv.utils.initOptions(chart); - return chart; - }; - nv.models.sunburstChart = function() { - "use strict"; - - //============================================================ - // Public Variables with Default Settings - //------------------------------------------------------------ - - var sunburst = nv.models.sunburst(); - var tooltip = nv.models.tooltip(); - - var margin = {top: 30, right: 20, bottom: 20, left: 20} - , width = null - , height = null - , color = nv.utils.defaultColor() - , id = Math.round(Math.random() * 100000) - , defaultState = null - , noData = null - , duration = 250 - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState','renderEnd') - ; - - //============================================================ - // Private Variables - //------------------------------------------------------------ - - var renderWatch = nv.utils.renderWatch(dispatch); - tooltip.headerEnabled(false).duration(0).valueFormatter(function(d, i) { - return d; - }); - - //============================================================ - // Chart function - //------------------------------------------------------------ - - function chart(selection) { - renderWatch.reset(); - renderWatch.models(sunburst); - - selection.each(function(data) { - var container = d3.select(this); - nv.utils.initSVG(container); - - var that = this; - var availableWidth = nv.utils.availableWidth(width, container, margin), - availableHeight = nv.utils.availableHeight(height, container, margin); - - chart.update = function() { - if (duration === 0) - container.call(chart); - else - container.transition().duration(duration).call(chart) - }; - chart.container = this; - - // Display No Data message if there's nothing to show. - if (!data || !data.length) { - nv.utils.noData(chart, container); - return chart; - } else { - container.selectAll('.nv-noData').remove(); - } - - // Setup containers and skeleton of chart - var wrap = container.selectAll('g.nv-wrap.nv-sunburstChart').data(data); - var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-sunburstChart').append('g'); - var g = wrap.select('g'); - - gEnter.append('g').attr('class', 'nv-sunburstWrap'); - - wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - - // Main Chart Component(s) - sunburst.width(availableWidth).height(availableHeight); - var sunWrap = g.select('.nv-sunburstWrap').datum(data); - d3.transition(sunWrap).call(sunburst); - - }); - - renderWatch.renderEnd('sunburstChart immediate'); - return chart; - } - - //============================================================ - // Event Handling/Dispatching (out of chart's scope) - //------------------------------------------------------------ - - sunburst.dispatch.on('elementMouseover.tooltip', function(evt) { - evt['series'] = { - key: evt.data.name, - value: evt.data.size, - color: evt.color - }; - tooltip.data(evt).hidden(false); - }); - - sunburst.dispatch.on('elementMouseout.tooltip', function(evt) { - tooltip.hidden(true); - }); - - sunburst.dispatch.on('elementMousemove.tooltip', function(evt) { - tooltip.position({top: d3.event.pageY, left: d3.event.pageX})(); - }); - - //============================================================ - // Expose Public Variables - //------------------------------------------------------------ - - // expose chart's sub-components - chart.dispatch = dispatch; - chart.sunburst = sunburst; - chart.tooltip = tooltip; - chart.options = nv.utils.optionsFunc.bind(chart); - - // use Object get/set functionality to map between vars and chart functions - chart._options = Object.create({}, { - // simple options, just get/set the necessary values - noData: {get: function(){return noData;}, set: function(_){noData=_;}}, - defaultState: {get: function(){return defaultState;}, set: function(_){defaultState=_;}}, - - // options that require extra logic in the setter - color: {get: function(){return color;}, set: function(_){ - color = _; - sunburst.color(color); - }}, - duration: {get: function(){return duration;}, set: function(_){ - duration = _; - renderWatch.reset(duration); - sunburst.duration(duration); - }}, - margin: {get: function(){return margin;}, set: function(_){ - margin.top = _.top !== undefined ? _.top : margin.top; - margin.right = _.right !== undefined ? _.right : margin.right; - margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; - margin.left = _.left !== undefined ? _.left : margin.left; - }} - }); - nv.utils.inheritOptions(chart, sunburst); - nv.utils.initOptions(chart); - return chart; - }; - - nv.version = "1.8.1"; -})(); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/rickshaw.min.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/rickshaw.min.js deleted file mode 100644 index bd576991..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/rickshaw.min.js +++ /dev/null @@ -1,3 +0,0 @@ -(function(root,factory){if(typeof define==="function"&&define.amd){define(["d3"],function(d3){return root.Rickshaw=factory(d3)})}else if(typeof exports==="object"){module.exports=factory(require("d3"))}else{root.Rickshaw=factory(d3)}})(this,function(d3){var Rickshaw={namespace:function(namespace,obj){var parts=namespace.split(".");var parent=Rickshaw;for(var i=1,length=parts.length;i0){var x=s.data[0].x;var y=s.data[0].y;if(typeof x!="number"||typeof y!="number"&&y!==null){throw"x and y properties of points should be numbers instead of "+typeof x+" and "+typeof y}}if(s.data.length>=3){if(s.data[2].xthis.window.xMax)isInRange=false;return isInRange}return true};this.onUpdate=function(callback){this.updateCallbacks.push(callback)};this.onConfigure=function(callback){this.configureCallbacks.push(callback)};this.registerRenderer=function(renderer){this._renderers=this._renderers||{};this._renderers[renderer.name]=renderer};this.configure=function(args){this.config=this.config||{};if(args.width||args.height){this.setSize(args)}Rickshaw.keys(this.defaults).forEach(function(k){this.config[k]=k in args?args[k]:k in this?this[k]:this.defaults[k]},this);Rickshaw.keys(this.config).forEach(function(k){this[k]=this.config[k]},this);if("stack"in args)args.unstack=!args.stack;var renderer=args.renderer||this.renderer&&this.renderer.name||"stack";this.setRenderer(renderer,args);this.configureCallbacks.forEach(function(callback){callback(args)})};this.setRenderer=function(r,args){if(typeof r=="function"){this.renderer=new r({graph:self});this.registerRenderer(this.renderer)}else{if(!this._renderers[r]){throw"couldn't find renderer "+r}this.renderer=this._renderers[r]}if(typeof args=="object"){this.renderer.configure(args)}};this.setSize=function(args){args=args||{};if(typeof window!==undefined){var style=window.getComputedStyle(this.element,null);var elementWidth=parseInt(style.getPropertyValue("width"),10);var elementHeight=parseInt(style.getPropertyValue("height"),10)}this.width=args.width||elementWidth||400;this.height=args.height||elementHeight||250;this.vis&&this.vis.attr("width",this.width).attr("height",this.height)};this.initialize(args)};Rickshaw.namespace("Rickshaw.Fixtures.Color");Rickshaw.Fixtures.Color=function(){this.schemes={};this.schemes.spectrum14=["#ecb796","#dc8f70","#b2a470","#92875a","#716c49","#d2ed82","#bbe468","#a1d05d","#e7cbe6","#d8aad6","#a888c2","#9dc2d3","#649eb9","#387aa3"].reverse();this.schemes.spectrum2000=["#57306f","#514c76","#646583","#738394","#6b9c7d","#84b665","#a7ca50","#bfe746","#e2f528","#fff726","#ecdd00","#d4b11d","#de8800","#de4800","#c91515","#9a0000","#7b0429","#580839","#31082b"];this.schemes.spectrum2001=["#2f243f","#3c2c55","#4a3768","#565270","#6b6b7c","#72957f","#86ad6e","#a1bc5e","#b8d954","#d3e04e","#ccad2a","#cc8412","#c1521d","#ad3821","#8a1010","#681717","#531e1e","#3d1818","#320a1b"];this.schemes.classic9=["#423d4f","#4a6860","#848f39","#a2b73c","#ddcb53","#c5a32f","#7d5836","#963b20","#7c2626","#491d37","#2f254a"].reverse();this.schemes.httpStatus={503:"#ea5029",502:"#d23f14",500:"#bf3613",410:"#efacea",409:"#e291dc",403:"#f457e8",408:"#e121d2",401:"#b92dae",405:"#f47ceb",404:"#a82a9f",400:"#b263c6",301:"#6fa024",302:"#87c32b",307:"#a0d84c",304:"#28b55c",200:"#1a4f74",206:"#27839f",201:"#52adc9",202:"#7c979f",203:"#a5b8bd",204:"#c1cdd1"};this.schemes.colorwheel=["#b5b6a9","#858772","#785f43","#96557e","#4682b4","#65b9ac","#73c03a","#cb513a"].reverse();this.schemes.cool=["#5e9d2f","#73c03a","#4682b4","#7bc3b8","#a9884e","#c1b266","#a47493","#c09fb5"];this.schemes.munin=["#00cc00","#0066b3","#ff8000","#ffcc00","#330099","#990099","#ccff00","#ff0000","#808080","#008f00","#00487d","#b35a00","#b38f00","#6b006b","#8fb300","#b30000","#bebebe","#80ff80","#80c9ff","#ffc080","#ffe680","#aa80ff","#ee00cc","#ff8080","#666600","#ffbfff","#00ffcc","#cc6699","#999900"]};Rickshaw.namespace("Rickshaw.Fixtures.RandomData");Rickshaw.Fixtures.RandomData=function(timeInterval){var addData;timeInterval=timeInterval||1;var lastRandomValue=200;var timeBase=Math.floor((new Date).getTime()/1e3);this.addData=function(data){var randomValue=Math.random()*100+15+lastRandomValue;var index=data[0].length;var counter=1;data.forEach(function(series){var randomVariance=Math.random()*20;var v=randomValue/25+counter++ +(Math.cos(index*counter*11/960)+2)*15+(Math.cos(index/7)+2)*7+(Math.cos(index/17)+2)*1;series.push({x:index*timeInterval+timeBase,y:v+randomVariance})});lastRandomValue=randomValue*.85};this.removeData=function(data){data.forEach(function(series){series.shift()});timeBase+=timeInterval}};Rickshaw.namespace("Rickshaw.Fixtures.Time");Rickshaw.Fixtures.Time=function(){var self=this;this.months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];this.units=[{name:"decade",seconds:86400*365.25*10,formatter:function(d){return parseInt(d.getUTCFullYear()/10,10)*10}},{name:"year",seconds:86400*365.25,formatter:function(d){return d.getUTCFullYear()}},{name:"month",seconds:86400*30.5,formatter:function(d){return self.months[d.getUTCMonth()]}},{name:"week",seconds:86400*7,formatter:function(d){return self.formatDate(d)}},{name:"day",seconds:86400,formatter:function(d){return d.getUTCDate()}},{name:"6 hour",seconds:3600*6,formatter:function(d){return self.formatTime(d)}},{name:"hour",seconds:3600,formatter:function(d){return self.formatTime(d)}},{name:"15 minute",seconds:60*15,formatter:function(d){return self.formatTime(d)}},{name:"minute",seconds:60,formatter:function(d){return d.getUTCMinutes()}},{name:"15 second",seconds:15,formatter:function(d){return d.getUTCSeconds()+"s"}},{name:"second",seconds:1,formatter:function(d){return d.getUTCSeconds()+"s"}},{name:"decisecond",seconds:1/10,formatter:function(d){return d.getUTCMilliseconds()+"ms"}},{name:"centisecond",seconds:1/100,formatter:function(d){return d.getUTCMilliseconds()+"ms"}}];this.unit=function(unitName){return this.units.filter(function(unit){return unitName==unit.name}).shift()};this.formatDate=function(d){return d3.time.format("%b %e")(d)};this.formatTime=function(d){return d.toUTCString().match(/(\d+:\d+):/)[1]};this.ceil=function(time,unit){var date,floor,year;if(unit.name=="month"){date=new Date(time*1e3);floor=Date.UTC(date.getUTCFullYear(),date.getUTCMonth())/1e3;if(floor==time)return time;year=date.getUTCFullYear();var month=date.getUTCMonth();if(month==11){month=0;year=year+1}else{month+=1}return Date.UTC(year,month)/1e3}if(unit.name=="year"){date=new Date(time*1e3);floor=Date.UTC(date.getUTCFullYear(),0)/1e3;if(floor==time)return time;year=date.getUTCFullYear()+1;return Date.UTC(year,0)/1e3}return Math.ceil(time/unit.seconds)*unit.seconds}};Rickshaw.namespace("Rickshaw.Fixtures.Time.Local");Rickshaw.Fixtures.Time.Local=function(){var self=this;this.months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];this.units=[{name:"decade",seconds:86400*365.25*10,formatter:function(d){return parseInt(d.getFullYear()/10,10)*10}},{name:"year",seconds:86400*365.25,formatter:function(d){return d.getFullYear()}},{name:"month",seconds:86400*30.5,formatter:function(d){return self.months[d.getMonth()]}},{name:"week",seconds:86400*7,formatter:function(d){return self.formatDate(d)}},{name:"day",seconds:86400,formatter:function(d){return d.getDate()}},{name:"6 hour",seconds:3600*6,formatter:function(d){return self.formatTime(d)}},{name:"hour",seconds:3600,formatter:function(d){return self.formatTime(d)}},{name:"15 minute",seconds:60*15,formatter:function(d){return self.formatTime(d)}},{name:"minute",seconds:60,formatter:function(d){return d.getMinutes()}},{name:"15 second",seconds:15,formatter:function(d){return d.getSeconds()+"s"}},{name:"second",seconds:1,formatter:function(d){return d.getSeconds()+"s"}},{name:"decisecond",seconds:1/10,formatter:function(d){return d.getMilliseconds()+"ms"}},{name:"centisecond",seconds:1/100,formatter:function(d){return d.getMilliseconds()+"ms"}}];this.unit=function(unitName){return this.units.filter(function(unit){return unitName==unit.name}).shift()};this.formatDate=function(d){return d3.time.format("%b %e")(d)};this.formatTime=function(d){return d.toString().match(/(\d+:\d+):/)[1]};this.ceil=function(time,unit){var date,floor,year;if(unit.name=="day"){var nearFuture=new Date((time+unit.seconds-1)*1e3);var rounded=new Date(0);rounded.setMilliseconds(0);rounded.setSeconds(0);rounded.setMinutes(0);rounded.setHours(0);rounded.setDate(nearFuture.getDate());rounded.setMonth(nearFuture.getMonth());rounded.setFullYear(nearFuture.getFullYear());return rounded.getTime()/1e3}if(unit.name=="month"){date=new Date(time*1e3);floor=new Date(date.getFullYear(),date.getMonth()).getTime()/1e3;if(floor==time)return time;year=date.getFullYear();var month=date.getMonth();if(month==11){month=0;year=year+1}else{month+=1}return new Date(year,month).getTime()/1e3}if(unit.name=="year"){date=new Date(time*1e3);floor=new Date(date.getUTCFullYear(),0).getTime()/1e3;if(floor==time)return time;year=date.getFullYear()+1;return new Date(year,0).getTime()/1e3}return Math.ceil(time/unit.seconds)*unit.seconds}};Rickshaw.namespace("Rickshaw.Fixtures.Number");Rickshaw.Fixtures.Number.formatKMBT=function(y){var abs_y=Math.abs(y);if(abs_y>=1e12){return y/1e12+"T"}else if(abs_y>=1e9){return y/1e9+"B"}else if(abs_y>=1e6){return y/1e6+"M"}else if(abs_y>=1e3){return y/1e3+"K"}else if(abs_y<1&&y>0){return y.toFixed(2)}else if(abs_y===0){return""}else{return y}};Rickshaw.Fixtures.Number.formatBase1024KMGTP=function(y){var abs_y=Math.abs(y);if(abs_y>=0x4000000000000){return y/0x4000000000000+"P"}else if(abs_y>=1099511627776){return y/1099511627776+"T"}else if(abs_y>=1073741824){return y/1073741824+"G"}else if(abs_y>=1048576){return y/1048576+"M"}else if(abs_y>=1024){return y/1024+"K"}else if(abs_y<1&&y>0){return y.toFixed(2)}else if(abs_y===0){return""}else{return y}};Rickshaw.namespace("Rickshaw.Color.Palette");Rickshaw.Color.Palette=function(args){var color=new Rickshaw.Fixtures.Color;args=args||{};this.schemes={};this.scheme=color.schemes[args.scheme]||args.scheme||color.schemes.colorwheel;this.runningIndex=0;this.generatorIndex=0;if(args.interpolatedStopCount){var schemeCount=this.scheme.length-1;var i,j,scheme=[];for(i=0;iself.graph.x.range()[1]){if(annotation.element){annotation.line.classList.add("offscreen");annotation.element.style.display="none"}annotation.boxes.forEach(function(box){if(box.rangeElement)box.rangeElement.classList.add("offscreen")});return}if(!annotation.element){var element=annotation.element=document.createElement("div");element.classList.add("annotation");this.elements.timeline.appendChild(element);element.addEventListener("click",function(e){element.classList.toggle("active");annotation.line.classList.toggle("active");annotation.boxes.forEach(function(box){if(box.rangeElement)box.rangeElement.classList.toggle("active")})},false)}annotation.element.style.left=left+"px";annotation.element.style.display="block";annotation.boxes.forEach(function(box){var element=box.element;if(!element){element=box.element=document.createElement("div");element.classList.add("content");element.innerHTML=box.content;annotation.element.appendChild(element);annotation.line=document.createElement("div");annotation.line.classList.add("annotation_line");self.graph.element.appendChild(annotation.line);if(box.end){box.rangeElement=document.createElement("div");box.rangeElement.classList.add("annotation_range");self.graph.element.appendChild(box.rangeElement)}}if(box.end){var annotationRangeStart=left;var annotationRangeEnd=Math.min(self.graph.x(box.end),self.graph.x.range()[1]);if(annotationRangeStart>annotationRangeEnd){annotationRangeEnd=left;annotationRangeStart=Math.max(self.graph.x(box.end),self.graph.x.range()[0])}var annotationRangeWidth=annotationRangeEnd-annotationRangeStart;box.rangeElement.style.left=annotationRangeStart+"px";box.rangeElement.style.width=annotationRangeWidth+"px";box.rangeElement.classList.remove("offscreen")}annotation.line.classList.remove("offscreen");annotation.line.style.left=left+"px"})},this)};this.graph.onUpdate(function(){self.update()})};Rickshaw.namespace("Rickshaw.Graph.Axis.Time");Rickshaw.Graph.Axis.Time=function(args){var self=this;this.graph=args.graph;this.elements=[];this.ticksTreatment=args.ticksTreatment||"plain";this.fixedTimeUnit=args.timeUnit;var time=args.timeFixture||new Rickshaw.Fixtures.Time;this.appropriateTimeUnit=function(){var unit;var units=time.units;var domain=this.graph.x.domain();var rangeSeconds=domain[1]-domain[0];units.forEach(function(u){if(Math.floor(rangeSeconds/u.seconds)>=2){unit=unit||u}});return unit||time.units[time.units.length-1]};this.tickOffsets=function(){var domain=this.graph.x.domain();var unit=this.fixedTimeUnit||this.appropriateTimeUnit();var count=Math.ceil((domain[1]-domain[0])/unit.seconds);var runningTick=domain[0];var offsets=[];for(var i=0;iself.graph.x.range()[1])return;var element=document.createElement("div");element.style.left=self.graph.x(o.value)+"px";element.classList.add("x_tick");element.classList.add(self.ticksTreatment);var title=document.createElement("div");title.classList.add("title");title.innerHTML=o.unit.formatter(new Date(o.value*1e3));element.appendChild(title);self.graph.element.appendChild(element);self.elements.push(element)})};this.graph.onUpdate(function(){self.render()})};Rickshaw.namespace("Rickshaw.Graph.Axis.X");Rickshaw.Graph.Axis.X=function(args){var self=this;var berthRate=.1;this.initialize=function(args){this.graph=args.graph;this.orientation=args.orientation||"top";this.pixelsPerTick=args.pixelsPerTick||75;if(args.ticks)this.staticTicks=args.ticks;if(args.tickValues)this.tickValues=args.tickValues;this.tickSize=args.tickSize||4;this.ticksTreatment=args.ticksTreatment||"plain";if(args.element){this.element=args.element;this._discoverSize(args.element,args);this.vis=d3.select(args.element).append("svg:svg").attr("height",this.height).attr("width",this.width).attr("class","rickshaw_graph x_axis_d3");this.element=this.vis[0][0];this.element.style.position="relative";this.setSize({width:args.width,height:args.height})}else{this.vis=this.graph.vis}this.graph.onUpdate(function(){self.render()})};this.setSize=function(args){args=args||{};if(!this.element)return;this._discoverSize(this.element.parentNode,args);this.vis.attr("height",this.height).attr("width",this.width*(1+berthRate));var berth=Math.floor(this.width*berthRate/2);this.element.style.left=-1*berth+"px"};this.render=function(){if(this._renderWidth!==undefined&&this.graph.width!==this._renderWidth)this.setSize({auto:true});var axis=d3.svg.axis().scale(this.graph.x).orient(this.orientation);axis.tickFormat(args.tickFormat||function(x){return x});if(this.tickValues)axis.tickValues(this.tickValues);this.ticks=this.staticTicks||Math.floor(this.graph.width/this.pixelsPerTick);var berth=Math.floor(this.width*berthRate/2)||0;var transform;if(this.orientation=="top"){var yOffset=this.height||this.graph.height;transform="translate("+berth+","+yOffset+")"}else{transform="translate("+berth+", 0)"}if(this.element){this.vis.selectAll("*").remove()}this.vis.append("svg:g").attr("class",["x_ticks_d3",this.ticksTreatment].join(" ")).attr("transform",transform).call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));var gridSize=(this.orientation=="bottom"?1:-1)*this.graph.height;this.graph.vis.append("svg:g").attr("class","x_grid_d3").call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(gridSize)).selectAll("text").each(function(){this.parentNode.setAttribute("data-x-value",this.textContent)});this._renderHeight=this.graph.height};this._discoverSize=function(element,args){if(typeof window!=="undefined"){var style=window.getComputedStyle(element,null);var elementHeight=parseInt(style.getPropertyValue("height"),10);if(!args.auto){var elementWidth=parseInt(style.getPropertyValue("width"),10)}}this.width=(args.width||elementWidth||this.graph.width)*(1+berthRate);this.height=args.height||elementHeight||40};this.initialize(args)};Rickshaw.namespace("Rickshaw.Graph.Axis.Y");Rickshaw.Graph.Axis.Y=Rickshaw.Class.create({initialize:function(args){this.graph=args.graph;this.orientation=args.orientation||"right";this.pixelsPerTick=args.pixelsPerTick||75;if(args.ticks)this.staticTicks=args.ticks;if(args.tickValues)this.tickValues=args.tickValues;this.tickSize=args.tickSize||4;this.ticksTreatment=args.ticksTreatment||"plain";this.tickFormat=args.tickFormat||function(y){return y};this.berthRate=.1;if(args.element){this.element=args.element;this.vis=d3.select(args.element).append("svg:svg").attr("class","rickshaw_graph y_axis");this.element=this.vis[0][0];this.element.style.position="relative";this.setSize({width:args.width,height:args.height})}else{this.vis=this.graph.vis}var self=this;this.graph.onUpdate(function(){self.render()})},setSize:function(args){args=args||{};if(!this.element)return;if(typeof window!=="undefined"){var style=window.getComputedStyle(this.element.parentNode,null);var elementWidth=parseInt(style.getPropertyValue("width"),10);if(!args.auto){var elementHeight=parseInt(style.getPropertyValue("height"),10)}}this.width=args.width||elementWidth||this.graph.width*this.berthRate;this.height=args.height||elementHeight||this.graph.height;this.vis.attr("width",this.width).attr("height",this.height*(1+this.berthRate));var berth=this.height*this.berthRate;if(this.orientation=="left"){this.element.style.top=-1*berth+"px"}},render:function(){if(this._renderHeight!==undefined&&this.graph.height!==this._renderHeight)this.setSize({auto:true});this.ticks=this.staticTicks||Math.floor(this.graph.height/this.pixelsPerTick);var axis=this._drawAxis(this.graph.y);this._drawGrid(axis);this._renderHeight=this.graph.height},_drawAxis:function(scale){var axis=d3.svg.axis().scale(scale).orient(this.orientation);axis.tickFormat(this.tickFormat);if(this.tickValues)axis.tickValues(this.tickValues);if(this.orientation=="left"){var berth=this.height*this.berthRate;var transform="translate("+this.width+", "+berth+")"}if(this.element){this.vis.selectAll("*").remove()}this.vis.append("svg:g").attr("class",["y_ticks",this.ticksTreatment].join(" ")).attr("transform",transform).call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));return axis},_drawGrid:function(axis){var gridSize=(this.orientation=="right"?1:-1)*this.graph.width;this.graph.vis.append("svg:g").attr("class","y_grid").call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(gridSize)).selectAll("text").each(function(){this.parentNode.setAttribute("data-y-value",this.textContent) -})}});Rickshaw.namespace("Rickshaw.Graph.Axis.Y.Scaled");Rickshaw.Graph.Axis.Y.Scaled=Rickshaw.Class.create(Rickshaw.Graph.Axis.Y,{initialize:function($super,args){if(typeof args.scale==="undefined"){throw new Error("Scaled requires scale")}this.scale=args.scale;if(typeof args.grid==="undefined"){this.grid=true}else{this.grid=args.grid}$super(args)},_drawAxis:function($super,scale){var domain=this.scale.domain();var renderDomain=this.graph.renderer.domain().y;var extents=[Math.min.apply(Math,domain),Math.max.apply(Math,domain)];var extentMap=d3.scale.linear().domain([0,1]).range(extents);var adjExtents=[extentMap(renderDomain[0]),extentMap(renderDomain[1])];var adjustment=d3.scale.linear().domain(extents).range(adjExtents);var adjustedScale=this.scale.copy().domain(domain.map(adjustment)).range(scale.range());return $super(adjustedScale)},_drawGrid:function($super,axis){if(this.grid){$super(axis)}}});Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Highlight");Rickshaw.Graph.Behavior.Series.Highlight=function(args){this.graph=args.graph;this.legend=args.legend;var self=this;var colorSafe={};var activeLine=null;var disabledColor=args.disabledColor||function(seriesColor){return d3.interpolateRgb(seriesColor,d3.rgb("#d8d8d8"))(.8).toString()};this.addHighlightEvents=function(l){l.element.addEventListener("mouseover",function(e){if(activeLine)return;else activeLine=l;self.legend.lines.forEach(function(line){if(l===line){if(self.graph.renderer.unstack&&(line.series.renderer?line.series.renderer.unstack:true)){var seriesIndex=self.graph.series.indexOf(line.series);line.originalIndex=seriesIndex;var series=self.graph.series.splice(seriesIndex,1)[0];self.graph.series.push(series)}return}colorSafe[line.series.name]=colorSafe[line.series.name]||line.series.color;line.series.color=disabledColor(line.series.color)});self.graph.update()},false);l.element.addEventListener("mouseout",function(e){if(!activeLine)return;else activeLine=null;self.legend.lines.forEach(function(line){if(l===line&&line.hasOwnProperty("originalIndex")){var series=self.graph.series.pop();self.graph.series.splice(line.originalIndex,0,series);delete line.originalIndex}if(colorSafe[line.series.name]){line.series.color=colorSafe[line.series.name]}});self.graph.update()},false)};if(this.legend){this.legend.lines.forEach(function(l){self.addHighlightEvents(l)})}};Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Order");Rickshaw.Graph.Behavior.Series.Order=function(args){this.graph=args.graph;this.legend=args.legend;var self=this;if(typeof window.jQuery=="undefined"){throw"couldn't find jQuery at window.jQuery"}if(typeof window.jQuery.ui=="undefined"){throw"couldn't find jQuery UI at window.jQuery.ui"}jQuery(function(){jQuery(self.legend.list).sortable({containment:"parent",tolerance:"pointer",update:function(event,ui){var series=[];jQuery(self.legend.list).find("li").each(function(index,item){if(!item.series)return;series.push(item.series)});for(var i=self.graph.series.length-1;i>=0;i--){self.graph.series[i]=series.shift()}self.graph.update()}});jQuery(self.legend.list).disableSelection()});this.graph.onUpdate(function(){var h=window.getComputedStyle(self.legend.element).height;self.legend.element.style.height=h})};Rickshaw.namespace("Rickshaw.Graph.Behavior.Series.Toggle");Rickshaw.Graph.Behavior.Series.Toggle=function(args){this.graph=args.graph;this.legend=args.legend;var self=this;this.addAnchor=function(line){var anchor=document.createElement("a");anchor.innerHTML="✔";anchor.classList.add("action");line.element.insertBefore(anchor,line.element.firstChild);anchor.onclick=function(e){if(line.series.disabled){line.series.enable();line.element.classList.remove("disabled")}else{if(this.graph.series.filter(function(s){return!s.disabled}).length<=1)return;line.series.disable();line.element.classList.add("disabled")}self.graph.update()}.bind(this);var label=line.element.getElementsByTagName("span")[0];label.onclick=function(e){var disableAllOtherLines=line.series.disabled;if(!disableAllOtherLines){for(var i=0;idomainX){dataIndex=Math.abs(domainX-data[i].x)0){alignables.forEach(function(el){el.classList.remove("left");el.classList.add("right")});var rightAlignError=this._calcLayoutError(alignables);if(rightAlignError>leftAlignError){alignables.forEach(function(el){el.classList.remove("right");el.classList.add("left")})}}if(typeof this.onRender=="function"){this.onRender(args)}},_calcLayoutError:function(alignables){var parentRect=this.element.parentNode.getBoundingClientRect();var error=0;var alignRight=alignables.forEach(function(el){var rect=el.getBoundingClientRect();if(!rect.width){return}if(rect.right>parentRect.right){error+=rect.right-parentRect.right}if(rect.left=self.previewWidth){frameAfterDrag[0]-=frameAfterDrag[1]-self.previewWidth;frameAfterDrag[1]=self.previewWidth}}self.graphs.forEach(function(graph){var domainScale=d3.scale.linear().interpolate(d3.interpolateNumber).domain([0,self.previewWidth]).range(graph.dataDomain());var windowAfterDrag=[domainScale(frameAfterDrag[0]),domainScale(frameAfterDrag[1])];self.slideCallbacks.forEach(function(callback){callback(graph,windowAfterDrag[0],windowAfterDrag[1])});if(frameAfterDrag[0]===0){windowAfterDrag[0]=undefined}if(frameAfterDrag[1]===self.previewWidth){windowAfterDrag[1]=undefined}graph.window.xMin=windowAfterDrag[0];graph.window.xMax=windowAfterDrag[1];graph.update()})}function onMousedown(){drag.target=d3.event.target;drag.start=self._getClientXFromEvent(d3.event,drag);self.frameBeforeDrag=self.currentFrame.slice();d3.event.preventDefault?d3.event.preventDefault():d3.event.returnValue=false;d3.select(document).on("mousemove.rickshaw_range_slider_preview",onMousemove);d3.select(document).on("mouseup.rickshaw_range_slider_preview",onMouseup);d3.select(document).on("touchmove.rickshaw_range_slider_preview",onMousemove);d3.select(document).on("touchend.rickshaw_range_slider_preview",onMouseup);d3.select(document).on("touchcancel.rickshaw_range_slider_preview",onMouseup)}function onMousedownLeftHandle(datum,index){drag.left=true;onMousedown()}function onMousedownRightHandle(datum,index){drag.right=true;onMousedown()}function onMousedownMiddleHandle(datum,index){drag.left=true;drag.right=true;drag.rigid=true;onMousedown()}function onMouseup(datum,index){d3.select(document).on("mousemove.rickshaw_range_slider_preview",null);d3.select(document).on("mouseup.rickshaw_range_slider_preview",null);d3.select(document).on("touchmove.rickshaw_range_slider_preview",null);d3.select(document).on("touchend.rickshaw_range_slider_preview",null);d3.select(document).on("touchcancel.rickshaw_range_slider_preview",null);delete self.frameBeforeDrag;drag.left=false;drag.right=false;drag.rigid=false}element.select("rect.left_handle").on("mousedown",onMousedownLeftHandle);element.select("rect.right_handle").on("mousedown",onMousedownRightHandle);element.select("rect.middle_handle").on("mousedown",onMousedownMiddleHandle);element.select("rect.left_handle").on("touchstart",onMousedownLeftHandle);element.select("rect.right_handle").on("touchstart",onMousedownRightHandle);element.select("rect.middle_handle").on("touchstart",onMousedownMiddleHandle)},_getClientXFromEvent:function(event,drag){switch(event.type){case"touchstart":case"touchmove":var touchList=event.changedTouches;var touch=null;for(var touchIndex=0;touchIndexyMax)yMax=y});if(!series.length)return;if(series[0].xxMax)xMax=series[series.length-1].x});xMin-=(xMax-xMin)*this.padding.left;xMax+=(xMax-xMin)*this.padding.right;yMin=this.graph.min==="auto"?yMin:this.graph.min||0;yMax=this.graph.max===undefined?yMax:this.graph.max;if(this.graph.min==="auto"||yMin<0){yMin-=(yMax-yMin)*this.padding.bottom}if(this.graph.max===undefined){yMax+=(yMax-yMin)*this.padding.top}return{x:[xMin,xMax],y:[yMin,yMax]}},render:function(args){args=args||{};var graph=this.graph;var series=args.series||graph.series;var vis=args.vis||graph.vis;vis.selectAll("*").remove();var data=series.filter(function(s){return!s.disabled}).map(function(s){return s.stack});var pathNodes=vis.selectAll("path.path").data(data).enter().append("svg:path").classed("path",true).attr("d",this.seriesPathFactory());if(this.stroke){var strokeNodes=vis.selectAll("path.stroke").data(data).enter().append("svg:path").classed("stroke",true).attr("d",this.seriesStrokeFactory())}var i=0;series.forEach(function(series){if(series.disabled)return;series.path=pathNodes[0][i];if(this.stroke)series.stroke=strokeNodes[0][i];this._styleSeries(series);i++},this)},_styleSeries:function(series){var fill=this.fill?series.color:"none";var stroke=this.stroke?series.color:"none";series.path.setAttribute("fill",fill);series.path.setAttribute("stroke",stroke);series.path.setAttribute("stroke-width",this.strokeWidth);if(series.className){d3.select(series.path).classed(series.className,true)}if(series.className&&this.stroke){d3.select(series.stroke).classed(series.className,true)}},configure:function(args){args=args||{};Rickshaw.keys(this.defaults()).forEach(function(key){if(!args.hasOwnProperty(key)){this[key]=this[key]||this.graph[key]||this.defaults()[key];return}if(typeof this.defaults()[key]=="object"){Rickshaw.keys(this.defaults()[key]).forEach(function(k){this[key][k]=args[key][k]!==undefined?args[key][k]:this[key][k]!==undefined?this[key][k]:this.defaults()[key][k]},this)}else{this[key]=args[key]!==undefined?args[key]:this[key]!==undefined?this[key]:this.graph[key]!==undefined?this.graph[key]:this.defaults()[key]}},this)},setStrokeWidth:function(strokeWidth){if(strokeWidth!==undefined){this.strokeWidth=strokeWidth}},setTension:function(tension){if(tension!==undefined){this.tension=tension}}});Rickshaw.namespace("Rickshaw.Graph.Renderer.Line");Rickshaw.Graph.Renderer.Line=Rickshaw.Class.create(Rickshaw.Graph.Renderer,{name:"line",defaults:function($super){return Rickshaw.extend($super(),{unstack:true,fill:false,stroke:true})},seriesPathFactory:function(){var graph=this.graph;var factory=d3.svg.line().x(function(d){return graph.x(d.x)}).y(function(d){return graph.y(d.y)}).interpolate(this.graph.interpolation).tension(this.tension);factory.defined&&factory.defined(function(d){return d.y!==null});return factory}});Rickshaw.namespace("Rickshaw.Graph.Renderer.Stack");Rickshaw.Graph.Renderer.Stack=Rickshaw.Class.create(Rickshaw.Graph.Renderer,{name:"stack",defaults:function($super){return Rickshaw.extend($super(),{fill:true,stroke:false,unstack:false})},seriesPathFactory:function(){var graph=this.graph;var factory=d3.svg.area().x(function(d){return graph.x(d.x)}).y0(function(d){return graph.y(d.y0)}).y1(function(d){return graph.y(d.y+d.y0)}).interpolate(this.graph.interpolation).tension(this.tension);factory.defined&&factory.defined(function(d){return d.y!==null});return factory}});Rickshaw.namespace("Rickshaw.Graph.Renderer.Bar");Rickshaw.Graph.Renderer.Bar=Rickshaw.Class.create(Rickshaw.Graph.Renderer,{name:"bar",defaults:function($super){var defaults=Rickshaw.extend($super(),{gapSize:.05,unstack:false});delete defaults.tension;return defaults},initialize:function($super,args){args=args||{};this.gapSize=args.gapSize||this.gapSize;$super(args)},domain:function($super){var domain=$super();var frequentInterval=this._frequentInterval(this.graph.stackedData.slice(-1).shift());domain.x[1]+=Number(frequentInterval.magnitude);return domain},barWidth:function(series){var frequentInterval=this._frequentInterval(series.stack);var barWidth=this.graph.x.magnitude(frequentInterval.magnitude)*(1-this.gapSize);return barWidth},render:function(args){args=args||{};var graph=this.graph;var series=args.series||graph.series;var vis=args.vis||graph.vis;vis.selectAll("*").remove();var barWidth=this.barWidth(series.active()[0]);var barXOffset=0;var activeSeriesCount=series.filter(function(s){return!s.disabled}).length;var seriesBarWidth=this.unstack?barWidth/activeSeriesCount:barWidth;var transform=function(d){var matrix=[1,0,0,d.y<0?-1:1,0,d.y<0?graph.y.magnitude(Math.abs(d.y))*2:0];return"matrix("+matrix.join(",")+")"};series.forEach(function(series){if(series.disabled)return;var barWidth=this.barWidth(series);var nodes=vis.selectAll("path").data(series.stack.filter(function(d){return d.y!==null})).enter().append("svg:rect").attr("x",function(d){return graph.x(d.x)+barXOffset}).attr("y",function(d){return graph.y(d.y0+Math.abs(d.y))*(d.y<0?-1:1)}).attr("width",seriesBarWidth).attr("height",function(d){return graph.y.magnitude(Math.abs(d.y))}).attr("transform",transform);Array.prototype.forEach.call(nodes[0],function(n){n.setAttribute("fill",series.color)});if(this.unstack)barXOffset+=seriesBarWidth},this)},_frequentInterval:function(data){var intervalCounts={};for(var i=0;i0){this[0].data.forEach(function(plot){item.data.push({x:plot.x,y:0})})}else if(item.data.length===0){item.data.push({x:this.timeBase-(this.timeInterval||0),y:0})}this.push(item);if(this.legend){this.legend.addLine(this.itemByName(item.name))}},addData:function(data,x){var index=this.getIndex();Rickshaw.keys(data).forEach(function(name){if(!this.itemByName(name)){this.addItem({name:name})}},this);this.forEach(function(item){item.data.push({x:x||(index*this.timeInterval||1)+this.timeBase,y:data[item.name]||0})},this)},getIndex:function(){return this[0]&&this[0].data&&this[0].data.length?this[0].data.length:0},itemByName:function(name){for(var i=0;i1;i--){this.currentSize+=1;this.currentIndex+=1;this.forEach(function(item){item.data.unshift({x:((i-1)*this.timeInterval||1)+this.timeBase,y:0,i:i})},this)}}},addData:function($super,data,x){$super(data,x);this.currentSize+=1;this.currentIndex+=1;if(this.maxDataPoints!==undefined){while(this.currentSize>this.maxDataPoints){this.dropData()}}},dropData:function(){this.forEach(function(item){item.data.splice(0,1)});this.currentSize-=1},getIndex:function(){return this.currentIndex}});return Rickshaw}); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/stream_layers.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/stream_layers.js deleted file mode 100644 index 43d7cfe0..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/stream_layers.js +++ /dev/null @@ -1,35 +0,0 @@ - -/* Inspired by Lee Byron's test data generator. */ -function stream_layers(n, m, o) { - if (arguments.length < 3) o = 0; - function bump(a) { - var x = 1 / (.1 + Math.random()), - y = 2 * Math.random() - .5, - z = 10 / (.1 + Math.random()); - for (var i = 0; i < m; i++) { - var w = (i / m - y) * z; - a[i] += x * Math.exp(-w * w); - } - } - return d3.range(n).map(function() { - var a = [], i; - for (i = 0; i < m; i++) a[i] = o + o * Math.random(); - for (i = 0; i < 5; i++) bump(a); - return a.map(stream_index); - }); -} - -/* Another layer generator using gamma distributions. */ -function stream_waves(n, m) { - return d3.range(n).map(function(i) { - return d3.range(m).map(function(j) { - var x = 20 * j / m - i / 3; - return 2 * x * Math.exp(-.5 * x); - }).map(stream_index); - }); -} - -function stream_index(d, i) { - return {x: i, y: Math.max(0, d)}; -} - diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/RaspberryPi.png b/modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/RaspberryPi.png deleted file mode 100644 index eb0e28cb26fd12e71a6645a8f35be731e2e268a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8006 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 diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/banner-img-3.png b/modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/banner-img-3.png deleted file mode 100644 index ce6d43d3b5a604e8df6ecfa24d4c90d5861a076a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17519 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 Iol`;+0G@z{cK`qY diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/beagleBone.png b/modules/distribution/src/repository/jaggeryapps/iot/units/showcase/public/images/beagleBone.png deleted file mode 100644 index 8bb45023fe81f46240cbd2531b4995a95ba42006..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10433 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

-
-
-
-

Fire Alarm

-
-

Connect your Fire Alarm device - to the WSO2 device cloud.

-
-
-
-
- -
-
-

Ingredients

-
-

Hardware Requirements

-

- - - - Arduino Uno

- - - - Arduino Ethernet / WiFi Shield -

-
- - - -
- - -
-
-

Prepare


-

Get your device ready

-
- 01 Mount the Ethernet / Wifi shield on the Arduino Uno device. -
-
- 02 Mount the Ethernet / Wifi shield on the Arduino Uno device. -
-
- 03 Mount the Ethernet / Wifi shield on the Arduino Uno device. -
-
-
-
-
-

Connect (Quickstart)

-
-

Internet of Things Foundation Quickstart connection

-
- 01 Use the following command to download the installer from GitHub:
-
-
- 02 Download the Sketch installer from the Arduino website http://arduino.cc/en/Main/Software
-
-
- 03 Install the Sketch program
-
-
- 04 Use the Sketch program to open the samples code samples/quickstart/quickstart.ino
-
-
- 05 View the lower part of the Sketch pad window to check that the COM connection is shown as active
-
-
-
-
-{{/zone}} -{{#zone "topCss"}} - - -{{/zone}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/firealarm.js b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/firealarm.js deleted file mode 100644 index dae1a137..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/firealarm.js +++ /dev/null @@ -1,4 +0,0 @@ -function onRequest(context){ - context.sketchPath = "api/device/sketch/download"; - return context; -} diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/firealarm.json b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/firealarm.json deleted file mode 100644 index 3dbff381..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/firealarm.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "predicate": "false" -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/public/images/firealarm-thumb.png b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/public/images/firealarm-thumb.png deleted file mode 100644 index aaf16925fd6c0cb486fb0101cf4117969de7ddb6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10339 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 DKFpV% diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/public/images/firealarm.png b/modules/distribution/src/repository/jaggeryapps/iot/units/devices/firealarm/public/images/firealarm.png deleted file mode 100644 index a735a75ab637df7c487a640e9ba20c07339a076f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141980 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±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 z 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'};i.Type.extend({name:"Doughnut",defaults:s,initialize:function(t){this.segments=[],this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,this.SegmentArc=i.Arc.extend({ctx:this.chart.ctx,x:this.chart.width/2,y:this.chart.height/2}),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.calculateTotal(t),e.each(t,function(t,i){this.addData(t,i,!0)},this),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,i,e){var s=i||this.segments.length;this.segments.splice(s,0,new this.SegmentArc({value:t.value,outerRadius:this.options.animateScale?0:this.outerRadius,innerRadius:this.options.animateScale?0:this.outerRadius/100*this.options.percentageInnerCutout,fillColor:t.color,highlightColor:t.highlight||t.color,showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,startAngle:1.5*Math.PI,circumference:this.options.animateRotate?0:this.calculateCircumference(t.value),label:t.label})),e||(this.reflow(),this.update())},calculateCircumference:function(t){return 2*Math.PI*(Math.abs(t)/this.total)},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=Math.abs(t.value)},this)},update:function(){this.calculateTotal(this.segments),e.each(this.activeElements,function(t){t.restore(["fillColor"])}),e.each(this.segments,function(t){t.save()}),this.render()},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,e.each(this.segments,function(t){t.update({outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout})},this)},draw:function(t){var i=t?t:1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.calculateCircumference(t.value),outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout},i),t.endAngle=t.startAngle+t.circumference,t.draw(),0===e&&(t.startAngle=1.5*Math.PI),e<% for (var i=0; i
  • <%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>'};i.Type.extend({name:"Line",defaults:s,initialize:function(t){this.PointClass=i.Point.extend({strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx,inRange:function(t){return Math.pow(t-this.x,2)0&&ithis.scale.endPoint?t.controlPoints.outer.y=this.scale.endPoint:t.controlPoints.outer.ythis.scale.endPoint?t.controlPoints.inner.y=this.scale.endPoint:t.controlPoints.inner.y0&&(s.lineTo(h[h.length-1].x,this.scale.endPoint),s.lineTo(h[0].x,this.scale.endPoint),s.fillStyle=t.fillColor,s.closePath(),s.fill()),e.each(h,function(t){t.draw()})},this)}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleShowLabelBackdrop:!0,scaleBackdropColor:"rgba(255,255,255,0.75)",scaleBeginAtZero:!0,scaleBackdropPaddingY:2,scaleBackdropPaddingX:2,scaleShowLine:!0,segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,legendTemplate:'
      <% for (var i=0; i
    • <%if(segments[i].label){%><%=segments[i].label%><%}%>
    • <%}%>
    '};i.Type.extend({name:"PolarArea",defaults:s,initialize:function(t){this.segments=[],this.SegmentArc=i.Arc.extend({showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,ctx:this.chart.ctx,innerRadius:0,x:this.chart.width/2,y:this.chart.height/2}),this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,lineArc:!0,width:this.chart.width,height:this.chart.height,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,valuesCount:t.length}),this.updateScaleRange(t),this.scale.update(),e.each(t,function(t,i){this.addData(t,i,!0)},this),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,i,e){var s=i||this.segments.length;this.segments.splice(s,0,new this.SegmentArc({fillColor:t.color,highlightColor:t.highlight||t.color,label:t.label,value:t.value,outerRadius:this.options.animateScale?0:this.scale.calculateCenterOffset(t.value),circumference:this.options.animateRotate?0:this.scale.getCircumference(),startAngle:1.5*Math.PI})),e||(this.reflow(),this.update())},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=t.value},this),this.scale.valuesCount=this.segments.length},updateScaleRange:function(t){var i=[];e.each(t,function(t){i.push(t.value)});var s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s,{size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2})},update:function(){this.calculateTotal(this.segments),e.each(this.segments,function(t){t.save()}),this.reflow(),this.render()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.updateScaleRange(this.segments),this.scale.update(),e.extend(this.scale,{xCenter:this.chart.width/2,yCenter:this.chart.height/2}),e.each(this.segments,function(t){t.update({outerRadius:this.scale.calculateCenterOffset(t.value)})},this)},draw:function(t){var i=t||1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.scale.getCircumference(),outerRadius:this.scale.calculateCenterOffset(t.value)},i),t.endAngle=t.startAngle+t.circumference,0===e&&(t.startAngle=1.5*Math.PI),e<% for (var i=0; i
  • <%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>'},initialize:function(t){this.PointClass=i.Point.extend({strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx}),this.datasets=[],this.buildScale(t),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getPointsAtEvent(t):[];this.eachPoints(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,pointColor:i.pointColor,pointStrokeColor:i.pointStrokeColor,points:[]};this.datasets.push(s),e.each(i.data,function(e,n){var o;this.scale.animation||(o=this.scale.getPointPosition(n,this.scale.calculateCenterOffset(e))),s.points.push(new this.PointClass({value:e,label:t.labels[n],datasetLabel:i.label,x:this.options.animation?this.scale.xCenter:o.x,y:this.options.animation?this.scale.yCenter:o.y,strokeColor:i.pointStrokeColor,fillColor:i.pointColor,highlightFill:i.pointHighlightFill||i.pointColor,highlightStroke:i.pointHighlightStroke||i.pointStrokeColor}))},this)},this),this.render()},eachPoints:function(t){e.each(this.datasets,function(i){e.each(i.points,t,this)},this)},getPointsAtEvent:function(t){var i=e.getRelativePosition(t),s=e.getAngleFromPoint({x:this.scale.xCenter,y:this.scale.yCenter},i),n=2*Math.PI/this.scale.valuesCount,o=Math.round((s.angle-1.5*Math.PI)/n),a=[];return(o>=this.scale.valuesCount||0>o)&&(o=0),s.distance<=this.scale.drawingArea&&e.each(this.datasets,function(t){a.push(t.points[o])}),a},buildScale:function(t){this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,angleLineColor:this.options.angleLineColor,angleLineWidth:this.options.angleShowLineOut?this.options.angleLineWidth:0,pointLabelFontColor:this.options.pointLabelFontColor,pointLabelFontSize:this.options.pointLabelFontSize,pointLabelFontFamily:this.options.pointLabelFontFamily,pointLabelFontStyle:this.options.pointLabelFontStyle,height:this.chart.height,width:this.chart.width,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,labels:t.labels,valuesCount:t.datasets[0].data.length}),this.scale.setScaleSize(),this.updateScaleRange(t.datasets),this.scale.buildYLabels()},updateScaleRange:function(t){var i=function(){var i=[];return e.each(t,function(t){t.data?i=i.concat(t.data):e.each(t.points,function(t){i.push(t.value)})}),i}(),s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s)},addData:function(t,i){this.scale.valuesCount++,e.each(t,function(t,e){var s=this.scale.getPointPosition(this.scale.valuesCount,this.scale.calculateCenterOffset(t));this.datasets[e].points.push(new this.PointClass({value:t,label:i,x:s.x,y:s.y,strokeColor:this.datasets[e].pointStrokeColor,fillColor:this.datasets[e].pointColor}))},this),this.scale.labels.push(i),this.reflow(),this.update()},removeData:function(){this.scale.valuesCount--,this.scale.labels.shift(),e.each(this.datasets,function(t){t.points.shift()},this),this.reflow(),this.update()},update:function(){this.eachPoints(function(t){t.save()}),this.reflow(),this.render()},reflow:function(){e.extend(this.scale,{width:this.chart.width,height:this.chart.height,size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2}),this.updateScaleRange(this.datasets),this.scale.setScaleSize(),this.scale.buildYLabels()},draw:function(t){var i=t||1,s=this.chart.ctx;this.clear(),this.scale.draw(),e.each(this.datasets,function(t){e.each(t.points,function(t,e){t.hasValue()&&t.transition(this.scale.getPointPosition(e,this.scale.calculateCenterOffset(t.value)),i)},this),s.lineWidth=this.options.datasetStrokeWidth,s.strokeStyle=t.strokeColor,s.beginPath(),e.each(t.points,function(t,i){0===i?s.moveTo(t.x,t.y):s.lineTo(t.x,t.y)},this),s.closePath(),s.stroke(),s.fillStyle=t.fillColor,s.fill(),e.each(t.points,function(t){t.hasValue()&&t.draw()})},this)}})}.call(this); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/bulb.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/bulb.js deleted file mode 100644 index 72c40fd7..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/bulb.js +++ /dev/null @@ -1,10 +0,0 @@ -function changeImage() { - var image = document.getElementById('myImage'); - if (image.src.match("bulb-on")) { - - image.src = "/iot/public/mydevice/images/bulb-off.png"; - } else { - - image.src = "/iot/public/mydevice/images/bulb-on.png"; - } -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/d3.min.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/d3.min.js deleted file mode 100644 index 43a29e23..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/d3.min.js +++ /dev/null @@ -1,9470 +0,0 @@ -!function() { - var d3 = { - version: "3.5.2" - }; - if (!Date.now) Date.now = function() { - return +new Date(); - }; - var d3_arraySlice = [].slice, d3_array = function(list) { - return d3_arraySlice.call(list); - }; - var d3_document = document, d3_documentElement = d3_document.documentElement, d3_window = window; - try { - d3_array(d3_documentElement.childNodes)[0].nodeType; - } catch (e) { - d3_array = function(list) { - var i = list.length, array = new Array(i); - while (i--) array[i] = list[i]; - return array; - }; - } - try { - d3_document.createElement("div").style.setProperty("opacity", 0, ""); - } catch (error) { - var d3_element_prototype = d3_window.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty; - d3_element_prototype.setAttribute = function(name, value) { - d3_element_setAttribute.call(this, name, value + ""); - }; - d3_element_prototype.setAttributeNS = function(space, local, value) { - d3_element_setAttributeNS.call(this, space, local, value + ""); - }; - d3_style_prototype.setProperty = function(name, value, priority) { - d3_style_setProperty.call(this, name, value + "", priority); - }; - } - d3.ascending = d3_ascending; - function d3_ascending(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; - } - d3.descending = function(a, b) { - return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; - }; - d3.min = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n) if ((b = array[i]) != null && b >= b) { - a = b; - break; - } - while (++i < n) if ((b = array[i]) != null && a > b) a = b; - } else { - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { - a = b; - break; - } - while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; - } - return a; - }; - d3.max = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n) if ((b = array[i]) != null && b >= b) { - a = b; - break; - } - while (++i < n) if ((b = array[i]) != null && b > a) a = b; - } else { - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { - a = b; - break; - } - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; - } - return a; - }; - d3.extent = function(array, f) { - var i = -1, n = array.length, a, b, c; - if (arguments.length === 1) { - while (++i < n) if ((b = array[i]) != null && b >= b) { - a = c = b; - break; - } - while (++i < n) if ((b = array[i]) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } else { - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { - a = c = b; - break; - } - while (++i < n) if ((b = f.call(array, array[i], i)) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } - return [ a, c ]; - }; - function d3_number(x) { - return x === null ? NaN : +x; - } - function d3_numeric(x) { - return !isNaN(x); - } - d3.sum = function(array, f) { - var s = 0, n = array.length, a, i = -1; - if (arguments.length === 1) { - while (++i < n) if (d3_numeric(a = +array[i])) s += a; - } else { - while (++i < n) if (d3_numeric(a = +f.call(array, array[i], i))) s += a; - } - return s; - }; - d3.mean = function(array, f) { - var s = 0, n = array.length, a, i = -1, j = n; - if (arguments.length === 1) { - while (++i < n) if (d3_numeric(a = d3_number(array[i]))) s += a; else --j; - } else { - while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) s += a; else --j; - } - if (j) return s / j; - }; - d3.quantile = function(values, p) { - var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; - return e ? v + e * (values[h] - v) : v; - }; - d3.median = function(array, f) { - var numbers = [], n = array.length, a, i = -1; - if (arguments.length === 1) { - while (++i < n) if (d3_numeric(a = d3_number(array[i]))) numbers.push(a); - } else { - while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) numbers.push(a); - } - if (numbers.length) return d3.quantile(numbers.sort(d3_ascending), .5); - }; - d3.variance = function(array, f) { - var n = array.length, m = 0, a, d, s = 0, i = -1, j = 0; - if (arguments.length === 1) { - while (++i < n) { - if (d3_numeric(a = d3_number(array[i]))) { - d = a - m; - m += d / ++j; - s += d * (a - m); - } - } - } else { - while (++i < n) { - if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) { - d = a - m; - m += d / ++j; - s += d * (a - m); - } - } - } - if (j > 1) return s / (j - 1); - }; - d3.deviation = function() { - var v = d3.variance.apply(this, arguments); - return v ? Math.sqrt(v) : v; - }; - function d3_bisector(compare) { - return { - left: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid; - } - return lo; - }, - right: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1; - } - return lo; - } - }; - } - var d3_bisect = d3_bisector(d3_ascending); - d3.bisectLeft = d3_bisect.left; - d3.bisect = d3.bisectRight = d3_bisect.right; - d3.bisector = function(f) { - return d3_bisector(f.length === 1 ? function(d, x) { - return d3_ascending(f(d), x); - } : f); - }; - d3.shuffle = function(array, i0, i1) { - if ((m = arguments.length) < 3) { - i1 = array.length; - if (m < 2) i0 = 0; - } - var m = i1 - i0, t, i; - while (m) { - i = Math.random() * m-- | 0; - t = array[m + i0], array[m + i0] = array[i + i0], array[i + i0] = t; - } - return array; - }; - d3.permute = function(array, indexes) { - var i = indexes.length, permutes = new Array(i); - while (i--) permutes[i] = array[indexes[i]]; - return permutes; - }; - d3.pairs = function(array) { - var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n); - while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ]; - return pairs; - }; - d3.zip = function() { - if (!(n = arguments.length)) return []; - for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { - for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { - zip[j] = arguments[j][i]; - } - } - return zips; - }; - function d3_zipLength(d) { - return d.length; - } - d3.transpose = function(matrix) { - return d3.zip.apply(d3, matrix); - }; - d3.keys = function(map) { - var keys = []; - for (var key in map) keys.push(key); - return keys; - }; - d3.values = function(map) { - var values = []; - for (var key in map) values.push(map[key]); - return values; - }; - d3.entries = function(map) { - var entries = []; - for (var key in map) entries.push({ - key: key, - value: map[key] - }); - return entries; - }; - d3.merge = function(arrays) { - var n = arrays.length, m, i = -1, j = 0, merged, array; - while (++i < n) j += arrays[i].length; - merged = new Array(j); - while (--n >= 0) { - array = arrays[n]; - m = array.length; - while (--m >= 0) { - merged[--j] = array[m]; - } - } - return merged; - }; - var abs = Math.abs; - d3.range = function(start, stop, step) { - if (arguments.length < 3) { - step = 1; - if (arguments.length < 2) { - stop = start; - start = 0; - } - } - if ((stop - start) / step === Infinity) throw new Error("infinite range"); - var range = [], k = d3_range_integerScale(abs(step)), i = -1, j; - start *= k, stop *= k, step *= k; - if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); - return range; - }; - function d3_range_integerScale(x) { - var k = 1; - while (x * k % 1) k *= 10; - return k; - } - function d3_class(ctor, properties) { - for (var key in properties) { - Object.defineProperty(ctor.prototype, key, { - value: properties[key], - enumerable: false - }); - } - } - d3.map = function(object, f) { - var map = new d3_Map(); - if (object instanceof d3_Map) { - object.forEach(function(key, value) { - map.set(key, value); - }); - } else if (Array.isArray(object)) { - var i = -1, n = object.length, o; - if (arguments.length === 1) while (++i < n) map.set(i, object[i]); else while (++i < n) map.set(f.call(object, o = object[i], i), o); - } else { - for (var key in object) map.set(key, object[key]); - } - return map; - }; - function d3_Map() { - this._ = Object.create(null); - } - var d3_map_proto = "__proto__", d3_map_zero = "\x00"; - d3_class(d3_Map, { - has: d3_map_has, - get: function(key) { - return this._[d3_map_escape(key)]; - }, - set: function(key, value) { - return this._[d3_map_escape(key)] = value; - }, - remove: d3_map_remove, - keys: d3_map_keys, - values: function() { - var values = []; - for (var key in this._) values.push(this._[key]); - return values; - }, - entries: function() { - var entries = []; - for (var key in this._) entries.push({ - key: d3_map_unescape(key), - value: this._[key] - }); - return entries; - }, - size: d3_map_size, - empty: d3_map_empty, - forEach: function(f) { - for (var key in this._) f.call(this, d3_map_unescape(key), this._[key]); - } - }); - function d3_map_escape(key) { - return (key += "") === d3_map_proto || key[0] === d3_map_zero ? d3_map_zero + key : key; - } - function d3_map_unescape(key) { - return (key += "")[0] === d3_map_zero ? key.slice(1) : key; - } - function d3_map_has(key) { - return d3_map_escape(key) in this._; - } - function d3_map_remove(key) { - return (key = d3_map_escape(key)) in this._ && delete this._[key]; - } - function d3_map_keys() { - var keys = []; - for (var key in this._) keys.push(d3_map_unescape(key)); - return keys; - } - function d3_map_size() { - var size = 0; - for (var key in this._) ++size; - return size; - } - function d3_map_empty() { - for (var key in this._) return false; - return true; - } - d3.nest = function() { - var nest = {}, keys = [], sortKeys = [], sortValues, rollup; - function map(mapType, array, depth) { - if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; - var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values; - while (++i < n) { - if (values = valuesByKey.get(keyValue = key(object = array[i]))) { - values.push(object); - } else { - valuesByKey.set(keyValue, [ object ]); - } - } - if (mapType) { - object = mapType(); - setter = function(keyValue, values) { - object.set(keyValue, map(mapType, values, depth)); - }; - } else { - object = {}; - setter = function(keyValue, values) { - object[keyValue] = map(mapType, values, depth); - }; - } - valuesByKey.forEach(setter); - return object; - } - function entries(map, depth) { - if (depth >= keys.length) return map; - var array = [], sortKey = sortKeys[depth++]; - map.forEach(function(key, keyMap) { - array.push({ - key: key, - values: entries(keyMap, depth) - }); - }); - return sortKey ? array.sort(function(a, b) { - return sortKey(a.key, b.key); - }) : array; - } - nest.map = function(array, mapType) { - return map(mapType, array, 0); - }; - nest.entries = function(array) { - return entries(map(d3.map, array, 0), 0); - }; - nest.key = function(d) { - keys.push(d); - return nest; - }; - nest.sortKeys = function(order) { - sortKeys[keys.length - 1] = order; - return nest; - }; - nest.sortValues = function(order) { - sortValues = order; - return nest; - }; - nest.rollup = function(f) { - rollup = f; - return nest; - }; - return nest; - }; - d3.set = function(array) { - var set = new d3_Set(); - if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]); - return set; - }; - function d3_Set() { - this._ = Object.create(null); - } - d3_class(d3_Set, { - has: d3_map_has, - add: function(key) { - this._[d3_map_escape(key += "")] = true; - return key; - }, - remove: d3_map_remove, - values: d3_map_keys, - size: d3_map_size, - empty: d3_map_empty, - forEach: function(f) { - for (var key in this._) f.call(this, d3_map_unescape(key)); - } - }); - d3.behavior = {}; - d3.rebind = function(target, source) { - var i = 1, n = arguments.length, method; - while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); - return target; - }; - function d3_rebind(target, source, method) { - return function() { - var value = method.apply(source, arguments); - return value === source ? target : value; - }; - } - function d3_vendorSymbol(object, name) { - if (name in object) return name; - name = name.charAt(0).toUpperCase() + name.slice(1); - for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) { - var prefixName = d3_vendorPrefixes[i] + name; - if (prefixName in object) return prefixName; - } - } - var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ]; - function d3_noop() {} - d3.dispatch = function() { - var dispatch = new d3_dispatch(), i = -1, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - return dispatch; - }; - function d3_dispatch() {} - d3_dispatch.prototype.on = function(type, listener) { - var i = type.indexOf("."), name = ""; - if (i >= 0) { - name = type.slice(i + 1); - type = type.slice(0, i); - } - if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); - if (arguments.length === 2) { - if (listener == null) for (type in this) { - if (this.hasOwnProperty(type)) this[type].on(name, null); - } - return this; - } - }; - function d3_dispatch_event(dispatch) { - var listeners = [], listenerByName = new d3_Map(); - function event() { - var z = listeners, i = -1, n = z.length, l; - while (++i < n) if (l = z[i].on) l.apply(this, arguments); - return dispatch; - } - event.on = function(name, listener) { - var l = listenerByName.get(name), i; - if (arguments.length < 2) return l && l.on; - if (l) { - l.on = null; - listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); - listenerByName.remove(name); - } - if (listener) listeners.push(listenerByName.set(name, { - on: listener - })); - return dispatch; - }; - return event; - } - d3.event = null; - function d3_eventPreventDefault() { - d3.event.preventDefault(); - } - function d3_eventSource() { - var e = d3.event, s; - while (s = e.sourceEvent) e = s; - return e; - } - function d3_eventDispatch(target) { - var dispatch = new d3_dispatch(), i = 0, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - dispatch.of = function(thiz, argumentz) { - return function(e1) { - try { - var e0 = e1.sourceEvent = d3.event; - e1.target = target; - d3.event = e1; - dispatch[e1.type].apply(thiz, argumentz); - } finally { - d3.event = e0; - } - }; - }; - return dispatch; - } - d3.requote = function(s) { - return s.replace(d3_requote_re, "\\$&"); - }; - var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; - var d3_subclass = {}.__proto__ ? function(object, prototype) { - object.__proto__ = prototype; - } : function(object, prototype) { - for (var property in prototype) object[property] = prototype[property]; - }; - function d3_selection(groups) { - d3_subclass(groups, d3_selectionPrototype); - return groups; - } - var d3_select = function(s, n) { - return n.querySelector(s); - }, d3_selectAll = function(s, n) { - return n.querySelectorAll(s); - }, d3_selectMatcher = d3_documentElement.matches || d3_documentElement[d3_vendorSymbol(d3_documentElement, "matchesSelector")], d3_selectMatches = function(n, s) { - return d3_selectMatcher.call(n, s); - }; - if (typeof Sizzle === "function") { - d3_select = function(s, n) { - return Sizzle(s, n)[0] || null; - }; - d3_selectAll = Sizzle; - d3_selectMatches = Sizzle.matchesSelector; - } - d3.selection = function() { - return d3_selectionRoot; - }; - var d3_selectionPrototype = d3.selection.prototype = []; - d3_selectionPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, group, node; - selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(subnode = selector.call(node, node.__data__, i, j)); - if (subnode && "__data__" in node) subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selector(selector) { - return typeof selector === "function" ? selector : function() { - return d3_select(selector, this); - }; - } - d3_selectionPrototype.selectAll = function(selector) { - var subgroups = [], subgroup, node; - selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j))); - subgroup.parentNode = node; - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selectorAll(selector) { - return typeof selector === "function" ? selector : function() { - return d3_selectAll(selector, this); - }; - } - var d3_nsPrefix = { - svg: "http://www.w3.org/2000/svg", - xhtml: "http://www.w3.org/1999/xhtml", - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace", - xmlns: "http://www.w3.org/2000/xmlns/" - }; - d3.ns = { - prefix: d3_nsPrefix, - qualify: function(name) { - var i = name.indexOf(":"), prefix = name; - if (i >= 0) { - prefix = name.slice(0, i); - name = name.slice(i + 1); - } - return d3_nsPrefix.hasOwnProperty(prefix) ? { - space: d3_nsPrefix[prefix], - local: name - } : name; - } - }; - d3_selectionPrototype.attr = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(); - name = d3.ns.qualify(name); - return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name); - } - for (value in name) this.each(d3_selection_attr(value, name[value])); - return this; - } - return this.each(d3_selection_attr(name, value)); - }; - function d3_selection_attr(name, value) { - name = d3.ns.qualify(name); - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - function attrConstant() { - this.setAttribute(name, value); - } - function attrConstantNS() { - this.setAttributeNS(name.space, name.local, value); - } - function attrFunction() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttribute(name); else this.setAttribute(name, x); - } - function attrFunctionNS() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x); - } - return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant; - } - function d3_collapse(s) { - return s.trim().replace(/\s+/g, " "); - } - d3_selectionPrototype.classed = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1; - if (value = node.classList) { - while (++i < n) if (!value.contains(name[i])) return false; - } else { - value = node.getAttribute("class"); - while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; - } - return true; - } - for (value in name) this.each(d3_selection_classed(value, name[value])); - return this; - } - return this.each(d3_selection_classed(name, value)); - }; - function d3_selection_classedRe(name) { - return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); - } - function d3_selection_classes(name) { - return (name + "").trim().split(/^|\s+/); - } - function d3_selection_classed(name, value) { - name = d3_selection_classes(name).map(d3_selection_classedName); - var n = name.length; - function classedConstant() { - var i = -1; - while (++i < n) name[i](this, value); - } - function classedFunction() { - var i = -1, x = value.apply(this, arguments); - while (++i < n) name[i](this, x); - } - return typeof value === "function" ? classedFunction : classedConstant; - } - function d3_selection_classedName(name) { - var re = d3_selection_classedRe(name); - return function(node, value) { - if (c = node.classList) return value ? c.add(name) : c.remove(name); - var c = node.getAttribute("class") || ""; - if (value) { - re.lastIndex = 0; - if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name)); - } else { - node.setAttribute("class", d3_collapse(c.replace(re, " "))); - } - }; - } - d3_selectionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); - return this; - } - if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name); - priority = ""; - } - return this.each(d3_selection_style(name, value, priority)); - }; - function d3_selection_style(name, value, priority) { - function styleNull() { - this.style.removeProperty(name); - } - function styleConstant() { - this.style.setProperty(name, value, priority); - } - function styleFunction() { - var x = value.apply(this, arguments); - if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority); - } - return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant; - } - d3_selectionPrototype.property = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") return this.node()[name]; - for (value in name) this.each(d3_selection_property(value, name[value])); - return this; - } - return this.each(d3_selection_property(name, value)); - }; - function d3_selection_property(name, value) { - function propertyNull() { - delete this[name]; - } - function propertyConstant() { - this[name] = value; - } - function propertyFunction() { - var x = value.apply(this, arguments); - if (x == null) delete this[name]; else this[name] = x; - } - return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant; - } - d3_selectionPrototype.text = function(value) { - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.textContent = v == null ? "" : v; - } : value == null ? function() { - this.textContent = ""; - } : function() { - this.textContent = value; - }) : this.node().textContent; - }; - d3_selectionPrototype.html = function(value) { - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.innerHTML = v == null ? "" : v; - } : value == null ? function() { - this.innerHTML = ""; - } : function() { - this.innerHTML = value; - }) : this.node().innerHTML; - }; - d3_selectionPrototype.append = function(name) { - name = d3_selection_creator(name); - return this.select(function() { - return this.appendChild(name.apply(this, arguments)); - }); - }; - function d3_selection_creator(name) { - return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? function() { - return this.ownerDocument.createElementNS(name.space, name.local); - } : function() { - return this.ownerDocument.createElementNS(this.namespaceURI, name); - }; - } - d3_selectionPrototype.insert = function(name, before) { - name = d3_selection_creator(name); - before = d3_selection_selector(before); - return this.select(function() { - return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null); - }); - }; - d3_selectionPrototype.remove = function() { - return this.each(d3_selectionRemove); - }; - function d3_selectionRemove() { - var parent = this.parentNode; - if (parent) parent.removeChild(this); - } - d3_selectionPrototype.data = function(value, key) { - var i = -1, n = this.length, group, node; - if (!arguments.length) { - value = new Array(n = (group = this[0]).length); - while (++i < n) { - if (node = group[i]) { - value[i] = node.__data__; - } - } - return value; - } - function bind(group, groupData) { - var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData; - if (key) { - var nodeByKeyValue = new d3_Map(), keyValues = new Array(n), keyValue; - for (i = -1; ++i < n; ) { - if (nodeByKeyValue.has(keyValue = key.call(node = group[i], node.__data__, i))) { - exitNodes[i] = node; - } else { - nodeByKeyValue.set(keyValue, node); - } - keyValues[i] = keyValue; - } - for (i = -1; ++i < m; ) { - if (!(node = nodeByKeyValue.get(keyValue = key.call(groupData, nodeData = groupData[i], i)))) { - enterNodes[i] = d3_selection_dataNode(nodeData); - } else if (node !== true) { - updateNodes[i] = node; - node.__data__ = nodeData; - } - nodeByKeyValue.set(keyValue, true); - } - for (i = -1; ++i < n; ) { - if (nodeByKeyValue.get(keyValues[i]) !== true) { - exitNodes[i] = group[i]; - } - } - } else { - for (i = -1; ++i < n0; ) { - node = group[i]; - nodeData = groupData[i]; - if (node) { - node.__data__ = nodeData; - updateNodes[i] = node; - } else { - enterNodes[i] = d3_selection_dataNode(nodeData); - } - } - for (;i < m; ++i) { - enterNodes[i] = d3_selection_dataNode(groupData[i]); - } - for (;i < n; ++i) { - exitNodes[i] = group[i]; - } - } - enterNodes.update = updateNodes; - enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode; - enter.push(enterNodes); - update.push(updateNodes); - exit.push(exitNodes); - } - var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); - if (typeof value === "function") { - while (++i < n) { - bind(group = this[i], value.call(group, group.parentNode.__data__, i)); - } - } else { - while (++i < n) { - bind(group = this[i], value); - } - } - update.enter = function() { - return enter; - }; - update.exit = function() { - return exit; - }; - return update; - }; - function d3_selection_dataNode(data) { - return { - __data__: data - }; - } - d3_selectionPrototype.datum = function(value) { - return arguments.length ? this.property("__data__", value) : this.property("__data__"); - }; - d3_selectionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { - subgroup.push(node); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_filter(selector) { - return function() { - return d3_selectMatches(this, selector); - }; - } - d3_selectionPrototype.order = function() { - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) { - if (node = group[i]) { - if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); - next = node; - } - } - } - return this; - }; - d3_selectionPrototype.sort = function(comparator) { - comparator = d3_selection_sortComparator.apply(this, arguments); - for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator); - return this.order(); - }; - function d3_selection_sortComparator(comparator) { - if (!arguments.length) comparator = d3_ascending; - return function(a, b) { - return a && b ? comparator(a.__data__, b.__data__) : !a - !b; - }; - } - d3_selectionPrototype.each = function(callback) { - return d3_selection_each(this, function(node, i, j) { - callback.call(node, node.__data__, i, j); - }); - }; - function d3_selection_each(groups, callback) { - for (var j = 0, m = groups.length; j < m; j++) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) { - if (node = group[i]) callback(node, i, j); - } - } - return groups; - } - d3_selectionPrototype.call = function(callback) { - var args = d3_array(arguments); - callback.apply(args[0] = this, args); - return this; - }; - d3_selectionPrototype.empty = function() { - return !this.node(); - }; - d3_selectionPrototype.node = function() { - for (var j = 0, m = this.length; j < m; j++) { - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - var node = group[i]; - if (node) return node; - } - } - return null; - }; - d3_selectionPrototype.size = function() { - var n = 0; - d3_selection_each(this, function() { - ++n; - }); - return n; - }; - function d3_selection_enter(selection) { - d3_subclass(selection, d3_selection_enterPrototype); - return selection; - } - var d3_selection_enterPrototype = []; - d3.selection.enter = d3_selection_enter; - d3.selection.enter.prototype = d3_selection_enterPrototype; - d3_selection_enterPrototype.append = d3_selectionPrototype.append; - d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; - d3_selection_enterPrototype.node = d3_selectionPrototype.node; - d3_selection_enterPrototype.call = d3_selectionPrototype.call; - d3_selection_enterPrototype.size = d3_selectionPrototype.size; - d3_selection_enterPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, upgroup, group, node; - for (var j = -1, m = this.length; ++j < m; ) { - upgroup = (group = this[j]).update; - subgroups.push(subgroup = []); - subgroup.parentNode = group.parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j)); - subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - d3_selection_enterPrototype.insert = function(name, before) { - if (arguments.length < 2) before = d3_selection_enterInsertBefore(this); - return d3_selectionPrototype.insert.call(this, name, before); - }; - function d3_selection_enterInsertBefore(enter) { - var i0, j0; - return function(d, i, j) { - var group = enter[j].update, n = group.length, node; - if (j != j0) j0 = j, i0 = 0; - if (i >= i0) i0 = i + 1; - while (!(node = group[i0]) && ++i0 < n) ; - return node; - }; - } - d3.select = function(node) { - var group = [ typeof node === "string" ? d3_select(node, d3_document) : node ]; - group.parentNode = d3_documentElement; - return d3_selection([ group ]); - }; - d3.selectAll = function(nodes) { - var group = d3_array(typeof nodes === "string" ? d3_selectAll(nodes, d3_document) : nodes); - group.parentNode = d3_documentElement; - return d3_selection([ group ]); - }; - var d3_selectionRoot = d3.select(d3_documentElement); - d3_selectionPrototype.on = function(type, listener, capture) { - var n = arguments.length; - if (n < 3) { - if (typeof type !== "string") { - if (n < 2) listener = false; - for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); - return this; - } - if (n < 2) return (n = this.node()["__on" + type]) && n._; - capture = false; - } - return this.each(d3_selection_on(type, listener, capture)); - }; - function d3_selection_on(type, listener, capture) { - var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener; - if (i > 0) type = type.slice(0, i); - var filter = d3_selection_onFilters.get(type); - if (filter) type = filter, wrap = d3_selection_onFilter; - function onRemove() { - var l = this[name]; - if (l) { - this.removeEventListener(type, l, l.$); - delete this[name]; - } - } - function onAdd() { - var l = wrap(listener, d3_array(arguments)); - onRemove.call(this); - this.addEventListener(type, this[name] = l, l.$ = capture); - l._ = listener; - } - function removeAll() { - var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match; - for (var name in this) { - if (match = name.match(re)) { - var l = this[name]; - this.removeEventListener(match[1], l, l.$); - delete this[name]; - } - } - } - return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll; - } - var d3_selection_onFilters = d3.map({ - mouseenter: "mouseover", - mouseleave: "mouseout" - }); - d3_selection_onFilters.forEach(function(k) { - if ("on" + k in d3_document) d3_selection_onFilters.remove(k); - }); - function d3_selection_onListener(listener, argumentz) { - return function(e) { - var o = d3.event; - d3.event = e; - argumentz[0] = this.__data__; - try { - listener.apply(this, argumentz); - } finally { - d3.event = o; - } - }; - } - function d3_selection_onFilter(listener, argumentz) { - var l = d3_selection_onListener(listener, argumentz); - return function(e) { - var target = this, related = e.relatedTarget; - if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) { - l.call(target, e); - } - }; - } - var d3_event_dragSelect = "onselectstart" in d3_document ? null : d3_vendorSymbol(d3_documentElement.style, "userSelect"), d3_event_dragId = 0; - function d3_event_dragSuppress() { - var name = ".dragsuppress-" + ++d3_event_dragId, click = "click" + name, w = d3.select(d3_window).on("touchmove" + name, d3_eventPreventDefault).on("dragstart" + name, d3_eventPreventDefault).on("selectstart" + name, d3_eventPreventDefault); - if (d3_event_dragSelect) { - var style = d3_documentElement.style, select = style[d3_event_dragSelect]; - style[d3_event_dragSelect] = "none"; - } - return function(suppressClick) { - w.on(name, null); - if (d3_event_dragSelect) style[d3_event_dragSelect] = select; - if (suppressClick) { - var off = function() { - w.on(click, null); - }; - w.on(click, function() { - d3_eventPreventDefault(); - off(); - }, true); - setTimeout(off, 0); - } - }; - } - d3.mouse = function(container) { - return d3_mousePoint(container, d3_eventSource()); - }; - var d3_mouse_bug44083 = /WebKit/.test(d3_window.navigator.userAgent) ? -1 : 0; - function d3_mousePoint(container, e) { - if (e.changedTouches) e = e.changedTouches[0]; - var svg = container.ownerSVGElement || container; - if (svg.createSVGPoint) { - var point = svg.createSVGPoint(); - if (d3_mouse_bug44083 < 0 && (d3_window.scrollX || d3_window.scrollY)) { - svg = d3.select("body").append("svg").style({ - position: "absolute", - top: 0, - left: 0, - margin: 0, - padding: 0, - border: "none" - }, "important"); - var ctm = svg[0][0].getScreenCTM(); - d3_mouse_bug44083 = !(ctm.f || ctm.e); - svg.remove(); - } - if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX, - point.y = e.clientY; - point = point.matrixTransform(container.getScreenCTM().inverse()); - return [ point.x, point.y ]; - } - var rect = container.getBoundingClientRect(); - return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ]; - } - d3.touch = function(container, touches, identifier) { - if (arguments.length < 3) identifier = touches, touches = d3_eventSource().changedTouches; - if (touches) for (var i = 0, n = touches.length, touch; i < n; ++i) { - if ((touch = touches[i]).identifier === identifier) { - return d3_mousePoint(container, touch); - } - } - }; - d3.behavior.drag = function() { - var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, d3_behavior_dragMouseSubject, "mousemove", "mouseup"), touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_behavior_dragTouchSubject, "touchmove", "touchend"); - function drag() { - this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart); - } - function dragstart(id, position, subject, move, end) { - return function() { - var that = this, target = d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragSubject = d3.select(subject()).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(), position0 = position(parent, dragId); - if (origin) { - dragOffset = origin.apply(that, arguments); - dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ]; - } else { - dragOffset = [ 0, 0 ]; - } - dispatch({ - type: "dragstart" - }); - function moved() { - var position1 = position(parent, dragId), dx, dy; - if (!position1) return; - dx = position1[0] - position0[0]; - dy = position1[1] - position0[1]; - dragged |= dx | dy; - position0 = position1; - dispatch({ - type: "drag", - x: position1[0] + dragOffset[0], - y: position1[1] + dragOffset[1], - dx: dx, - dy: dy - }); - } - function ended() { - if (!position(parent, dragId)) return; - dragSubject.on(move + dragName, null).on(end + dragName, null); - dragRestore(dragged && d3.event.target === target); - dispatch({ - type: "dragend" - }); - } - }; - } - drag.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return drag; - }; - return d3.rebind(drag, event, "on"); - }; - function d3_behavior_dragTouchId() { - return d3.event.changedTouches[0].identifier; - } - function d3_behavior_dragTouchSubject() { - return d3.event.target; - } - function d3_behavior_dragMouseSubject() { - return d3_window; - } - d3.touches = function(container, touches) { - if (arguments.length < 2) touches = d3_eventSource().touches; - return touches ? d3_array(touches).map(function(touch) { - var point = d3_mousePoint(container, touch); - point.identifier = touch.identifier; - return point; - }) : []; - }; - var ε = 1e-6, ε2 = ε * ε, π = Math.PI, τ = 2 * π, τε = τ - ε, halfπ = π / 2, d3_radians = π / 180, d3_degrees = 180 / π; - function d3_sgn(x) { - return x > 0 ? 1 : x < 0 ? -1 : 0; - } - function d3_cross2d(a, b, c) { - return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]); - } - function d3_acos(x) { - return x > 1 ? 0 : x < -1 ? π : Math.acos(x); - } - function d3_asin(x) { - return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x); - } - function d3_sinh(x) { - return ((x = Math.exp(x)) - 1 / x) / 2; - } - function d3_cosh(x) { - return ((x = Math.exp(x)) + 1 / x) / 2; - } - function d3_tanh(x) { - return ((x = Math.exp(2 * x)) - 1) / (x + 1); - } - function d3_haversin(x) { - return (x = Math.sin(x / 2)) * x; - } - var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4; - d3.interpolateZoom = function(p0, p1) { - var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2]; - var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / ρ; - function interpolate(t) { - var s = t * S; - if (dr) { - var coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0)); - return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ]; - } - return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * s) ]; - } - interpolate.duration = S * 1e3; - return interpolate; - }; - d3.behavior.zoom = function() { - var view = { - x: 0, - y: 0, - k: 1 - }, translate0, center0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, duration = 250, zooming = 0, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1; - function zoom(g) { - g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted); - } - zoom.event = function(g) { - g.each(function() { - var dispatch = event.of(this, arguments), view1 = view; - if (d3_transitionInheritId) { - d3.select(this).transition().each("start.zoom", function() { - view = this.__chart__ || { - x: 0, - y: 0, - k: 1 - }; - zoomstarted(dispatch); - }).tween("zoom:zoom", function() { - var dx = size[0], dy = size[1], cx = center0 ? center0[0] : dx / 2, cy = center0 ? center0[1] : dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]); - return function(t) { - var l = i(t), k = dx / l[2]; - this.__chart__ = view = { - x: cx - l[0] * k, - y: cy - l[1] * k, - k: k - }; - zoomed(dispatch); - }; - }).each("interrupt.zoom", function() { - zoomended(dispatch); - }).each("end.zoom", function() { - zoomended(dispatch); - }); - } else { - this.__chart__ = view; - zoomstarted(dispatch); - zoomed(dispatch); - zoomended(dispatch); - } - }); - }; - zoom.translate = function(_) { - if (!arguments.length) return [ view.x, view.y ]; - view = { - x: +_[0], - y: +_[1], - k: view.k - }; - rescale(); - return zoom; - }; - zoom.scale = function(_) { - if (!arguments.length) return view.k; - view = { - x: view.x, - y: view.y, - k: +_ - }; - rescale(); - return zoom; - }; - zoom.scaleExtent = function(_) { - if (!arguments.length) return scaleExtent; - scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ]; - return zoom; - }; - zoom.center = function(_) { - if (!arguments.length) return center; - center = _ && [ +_[0], +_[1] ]; - return zoom; - }; - zoom.size = function(_) { - if (!arguments.length) return size; - size = _ && [ +_[0], +_[1] ]; - return zoom; - }; - zoom.duration = function(_) { - if (!arguments.length) return duration; - duration = +_; - return zoom; - }; - zoom.x = function(z) { - if (!arguments.length) return x1; - x1 = z; - x0 = z.copy(); - view = { - x: 0, - y: 0, - k: 1 - }; - return zoom; - }; - zoom.y = function(z) { - if (!arguments.length) return y1; - y1 = z; - y0 = z.copy(); - view = { - x: 0, - y: 0, - k: 1 - }; - return zoom; - }; - function location(p) { - return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ]; - } - function point(l) { - return [ l[0] * view.k + view.x, l[1] * view.k + view.y ]; - } - function scaleTo(s) { - view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); - } - function translateTo(p, l) { - l = point(l); - view.x += p[0] - l[0]; - view.y += p[1] - l[1]; - } - function zoomTo(that, p, l, k) { - that.__chart__ = { - x: view.x, - y: view.y, - k: view.k - }; - scaleTo(Math.pow(2, k)); - translateTo(center0 = p, l); - that = d3.select(that); - if (duration > 0) that = that.transition().duration(duration); - that.call(zoom.event); - } - function rescale() { - if (x1) x1.domain(x0.range().map(function(x) { - return (x - view.x) / view.k; - }).map(x0.invert)); - if (y1) y1.domain(y0.range().map(function(y) { - return (y - view.y) / view.k; - }).map(y0.invert)); - } - function zoomstarted(dispatch) { - if (!zooming++) dispatch({ - type: "zoomstart" - }); - } - function zoomed(dispatch) { - rescale(); - dispatch({ - type: "zoom", - scale: view.k, - translate: [ view.x, view.y ] - }); - } - function zoomended(dispatch) { - if (!--zooming) dispatch({ - type: "zoomend" - }); - center0 = null; - } - function mousedowned() { - var that = this, target = d3.event.target, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress(); - d3_selection_interrupt.call(that); - zoomstarted(dispatch); - function moved() { - dragged = 1; - translateTo(d3.mouse(that), location0); - zoomed(dispatch); - } - function ended() { - subject.on(mousemove, null).on(mouseup, null); - dragRestore(dragged && d3.event.target === target); - zoomended(dispatch); - } - } - function touchstarted() { - var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = ".zoom-" + d3.event.changedTouches[0].identifier, touchmove = "touchmove" + zoomName, touchend = "touchend" + zoomName, targets = [], subject = d3.select(that), dragRestore = d3_event_dragSuppress(); - started(); - zoomstarted(dispatch); - subject.on(mousedown, null).on(touchstart, started); - function relocate() { - var touches = d3.touches(that); - scale0 = view.k; - touches.forEach(function(t) { - if (t.identifier in locations0) locations0[t.identifier] = location(t); - }); - return touches; - } - function started() { - var target = d3.event.target; - d3.select(target).on(touchmove, moved).on(touchend, ended); - targets.push(target); - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - locations0[changed[i].identifier] = null; - } - var touches = relocate(), now = Date.now(); - if (touches.length === 1) { - if (now - touchtime < 500) { - var p = touches[0]; - zoomTo(that, p, locations0[p.identifier], Math.floor(Math.log(view.k) / Math.LN2) + 1); - d3_eventPreventDefault(); - } - touchtime = now; - } else if (touches.length > 1) { - var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1]; - distance0 = dx * dx + dy * dy; - } - } - function moved() { - var touches = d3.touches(that), p0, l0, p1, l1; - d3_selection_interrupt.call(that); - for (var i = 0, n = touches.length; i < n; ++i, l1 = null) { - p1 = touches[i]; - if (l1 = locations0[p1.identifier]) { - if (l0) break; - p0 = p1, l0 = l1; - } - } - if (l1) { - var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0); - p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ]; - l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ]; - scaleTo(scale1 * scale0); - } - touchtime = null; - translateTo(p0, l0); - zoomed(dispatch); - } - function ended() { - if (d3.event.touches.length) { - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - delete locations0[changed[i].identifier]; - } - for (var identifier in locations0) { - return void relocate(); - } - } - d3.selectAll(targets).on(zoomName, null); - subject.on(mousedown, mousedowned).on(touchstart, touchstarted); - dragRestore(); - zoomended(dispatch); - } - } - function mousewheeled() { - var dispatch = event.of(this, arguments); - if (mousewheelTimer) clearTimeout(mousewheelTimer); else translate0 = location(center0 = center || d3.mouse(this)), - d3_selection_interrupt.call(this), zoomstarted(dispatch); - mousewheelTimer = setTimeout(function() { - mousewheelTimer = null; - zoomended(dispatch); - }, 50); - d3_eventPreventDefault(); - scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k); - translateTo(center0, translate0); - zoomed(dispatch); - } - function dblclicked() { - var p = d3.mouse(this), k = Math.log(view.k) / Math.LN2; - zoomTo(this, p, location(p), d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1); - } - return d3.rebind(zoom, event, "on"); - }; - var d3_behavior_zoomInfinity = [ 0, Infinity ]; - var d3_behavior_zoomDelta, d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { - return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); - }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { - return d3.event.wheelDelta; - }, "mousewheel") : (d3_behavior_zoomDelta = function() { - return -d3.event.detail; - }, "MozMousePixelScroll"); - d3.color = d3_color; - function d3_color() {} - d3_color.prototype.toString = function() { - return this.rgb() + ""; - }; - d3.hsl = d3_hsl; - function d3_hsl(h, s, l) { - return this instanceof d3_hsl ? void (this.h = +h, this.s = +s, this.l = +l) : arguments.length < 2 ? h instanceof d3_hsl ? new d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : new d3_hsl(h, s, l); - } - var d3_hslPrototype = d3_hsl.prototype = new d3_color(); - d3_hslPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return new d3_hsl(this.h, this.s, this.l / k); - }; - d3_hslPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return new d3_hsl(this.h, this.s, k * this.l); - }; - d3_hslPrototype.rgb = function() { - return d3_hsl_rgb(this.h, this.s, this.l); - }; - function d3_hsl_rgb(h, s, l) { - var m1, m2; - h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h; - s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s; - l = l < 0 ? 0 : l > 1 ? 1 : l; - m2 = l <= .5 ? l * (1 + s) : l + s - l * s; - m1 = 2 * l - m2; - function v(h) { - if (h > 360) h -= 360; else if (h < 0) h += 360; - if (h < 60) return m1 + (m2 - m1) * h / 60; - if (h < 180) return m2; - if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; - return m1; - } - function vv(h) { - return Math.round(v(h) * 255); - } - return new d3_rgb(vv(h + 120), vv(h), vv(h - 120)); - } - d3.hcl = d3_hcl; - function d3_hcl(h, c, l) { - return this instanceof d3_hcl ? void (this.h = +h, this.c = +c, this.l = +l) : arguments.length < 2 ? h instanceof d3_hcl ? new d3_hcl(h.h, h.c, h.l) : h instanceof d3_lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : new d3_hcl(h, c, l); - } - var d3_hclPrototype = d3_hcl.prototype = new d3_color(); - d3_hclPrototype.brighter = function(k) { - return new d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.darker = function(k) { - return new d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.rgb = function() { - return d3_hcl_lab(this.h, this.c, this.l).rgb(); - }; - function d3_hcl_lab(h, c, l) { - if (isNaN(h)) h = 0; - if (isNaN(c)) c = 0; - return new d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); - } - d3.lab = d3_lab; - function d3_lab(l, a, b) { - return this instanceof d3_lab ? void (this.l = +l, this.a = +a, this.b = +b) : arguments.length < 2 ? l instanceof d3_lab ? new d3_lab(l.l, l.a, l.b) : l instanceof d3_hcl ? d3_hcl_lab(l.h, l.c, l.l) : d3_rgb_lab((l = d3_rgb(l)).r, l.g, l.b) : new d3_lab(l, a, b); - } - var d3_lab_K = 18; - var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883; - var d3_labPrototype = d3_lab.prototype = new d3_color(); - d3_labPrototype.brighter = function(k) { - return new d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.darker = function(k) { - return new d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.rgb = function() { - return d3_lab_rgb(this.l, this.a, this.b); - }; - function d3_lab_rgb(l, a, b) { - var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200; - x = d3_lab_xyz(x) * d3_lab_X; - y = d3_lab_xyz(y) * d3_lab_Y; - z = d3_lab_xyz(z) * d3_lab_Z; - return new d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z)); - } - function d3_lab_hcl(l, a, b) { - return l > 0 ? new d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : new d3_hcl(NaN, NaN, l); - } - function d3_lab_xyz(x) { - return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037; - } - function d3_xyz_lab(x) { - return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; - } - function d3_xyz_rgb(r) { - return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055)); - } - d3.rgb = d3_rgb; - function d3_rgb(r, g, b) { - return this instanceof d3_rgb ? void (this.r = ~~r, this.g = ~~g, this.b = ~~b) : arguments.length < 2 ? r instanceof d3_rgb ? new d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : new d3_rgb(r, g, b); - } - function d3_rgbNumber(value) { - return new d3_rgb(value >> 16, value >> 8 & 255, value & 255); - } - function d3_rgbString(value) { - return d3_rgbNumber(value) + ""; - } - var d3_rgbPrototype = d3_rgb.prototype = new d3_color(); - d3_rgbPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - var r = this.r, g = this.g, b = this.b, i = 30; - if (!r && !g && !b) return new d3_rgb(i, i, i); - if (r && r < i) r = i; - if (g && g < i) g = i; - if (b && b < i) b = i; - return new d3_rgb(Math.min(255, r / k), Math.min(255, g / k), Math.min(255, b / k)); - }; - d3_rgbPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return new d3_rgb(k * this.r, k * this.g, k * this.b); - }; - d3_rgbPrototype.hsl = function() { - return d3_rgb_hsl(this.r, this.g, this.b); - }; - d3_rgbPrototype.toString = function() { - return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); - }; - function d3_rgb_hex(v) { - return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16); - } - function d3_rgb_parse(format, rgb, hsl) { - var r = 0, g = 0, b = 0, m1, m2, color; - m1 = /([a-z]+)\((.*)\)/i.exec(format); - if (m1) { - m2 = m1[2].split(","); - switch (m1[1]) { - case "hsl": - { - return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100); - } - - case "rgb": - { - return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2])); - } - } - } - if (color = d3_rgb_names.get(format)) return rgb(color.r, color.g, color.b); - if (format != null && format.charAt(0) === "#" && !isNaN(color = parseInt(format.slice(1), 16))) { - if (format.length === 4) { - r = (color & 3840) >> 4; - r = r >> 4 | r; - g = color & 240; - g = g >> 4 | g; - b = color & 15; - b = b << 4 | b; - } else if (format.length === 7) { - r = (color & 16711680) >> 16; - g = (color & 65280) >> 8; - b = color & 255; - } - } - return rgb(r, g, b); - } - function d3_rgb_hsl(r, g, b) { - var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2; - if (d) { - s = l < .5 ? d / (max + min) : d / (2 - max - min); - if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4; - h *= 60; - } else { - h = NaN; - s = l > 0 && l < 1 ? 0 : h; - } - return new d3_hsl(h, s, l); - } - function d3_rgb_lab(r, g, b) { - r = d3_rgb_xyz(r); - g = d3_rgb_xyz(g); - b = d3_rgb_xyz(b); - var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z); - return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); - } - function d3_rgb_xyz(r) { - return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4); - } - function d3_rgb_parseNumber(c) { - var f = parseFloat(c); - return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; - } - var d3_rgb_names = d3.map({ - aliceblue: 15792383, - antiquewhite: 16444375, - aqua: 65535, - aquamarine: 8388564, - azure: 15794175, - beige: 16119260, - bisque: 16770244, - black: 0, - blanchedalmond: 16772045, - blue: 255, - blueviolet: 9055202, - brown: 10824234, - burlywood: 14596231, - cadetblue: 6266528, - chartreuse: 8388352, - chocolate: 13789470, - coral: 16744272, - cornflowerblue: 6591981, - cornsilk: 16775388, - crimson: 14423100, - cyan: 65535, - darkblue: 139, - darkcyan: 35723, - darkgoldenrod: 12092939, - darkgray: 11119017, - darkgreen: 25600, - darkgrey: 11119017, - darkkhaki: 12433259, - darkmagenta: 9109643, - darkolivegreen: 5597999, - darkorange: 16747520, - darkorchid: 10040012, - darkred: 9109504, - darksalmon: 15308410, - darkseagreen: 9419919, - darkslateblue: 4734347, - darkslategray: 3100495, - darkslategrey: 3100495, - darkturquoise: 52945, - darkviolet: 9699539, - deeppink: 16716947, - deepskyblue: 49151, - dimgray: 6908265, - dimgrey: 6908265, - dodgerblue: 2003199, - firebrick: 11674146, - floralwhite: 16775920, - forestgreen: 2263842, - fuchsia: 16711935, - gainsboro: 14474460, - ghostwhite: 16316671, - gold: 16766720, - goldenrod: 14329120, - gray: 8421504, - green: 32768, - greenyellow: 11403055, - grey: 8421504, - honeydew: 15794160, - hotpink: 16738740, - indianred: 13458524, - indigo: 4915330, - ivory: 16777200, - khaki: 15787660, - lavender: 15132410, - lavenderblush: 16773365, - lawngreen: 8190976, - lemonchiffon: 16775885, - lightblue: 11393254, - lightcoral: 15761536, - lightcyan: 14745599, - lightgoldenrodyellow: 16448210, - lightgray: 13882323, - lightgreen: 9498256, - lightgrey: 13882323, - lightpink: 16758465, - lightsalmon: 16752762, - lightseagreen: 2142890, - lightskyblue: 8900346, - lightslategray: 7833753, - lightslategrey: 7833753, - lightsteelblue: 11584734, - lightyellow: 16777184, - lime: 65280, - limegreen: 3329330, - linen: 16445670, - magenta: 16711935, - maroon: 8388608, - mediumaquamarine: 6737322, - mediumblue: 205, - mediumorchid: 12211667, - mediumpurple: 9662683, - mediumseagreen: 3978097, - mediumslateblue: 8087790, - mediumspringgreen: 64154, - mediumturquoise: 4772300, - mediumvioletred: 13047173, - midnightblue: 1644912, - mintcream: 16121850, - mistyrose: 16770273, - moccasin: 16770229, - navajowhite: 16768685, - navy: 128, - oldlace: 16643558, - olive: 8421376, - olivedrab: 7048739, - orange: 16753920, - orangered: 16729344, - orchid: 14315734, - palegoldenrod: 15657130, - palegreen: 10025880, - paleturquoise: 11529966, - palevioletred: 14381203, - papayawhip: 16773077, - peachpuff: 16767673, - peru: 13468991, - pink: 16761035, - plum: 14524637, - powderblue: 11591910, - purple: 8388736, - red: 16711680, - rosybrown: 12357519, - royalblue: 4286945, - saddlebrown: 9127187, - salmon: 16416882, - sandybrown: 16032864, - seagreen: 3050327, - seashell: 16774638, - sienna: 10506797, - silver: 12632256, - skyblue: 8900331, - slateblue: 6970061, - slategray: 7372944, - slategrey: 7372944, - snow: 16775930, - springgreen: 65407, - steelblue: 4620980, - tan: 13808780, - teal: 32896, - thistle: 14204888, - tomato: 16737095, - turquoise: 4251856, - violet: 15631086, - wheat: 16113331, - white: 16777215, - whitesmoke: 16119285, - yellow: 16776960, - yellowgreen: 10145074 - }); - d3_rgb_names.forEach(function(key, value) { - d3_rgb_names.set(key, d3_rgbNumber(value)); - }); - function d3_functor(v) { - return typeof v === "function" ? v : function() { - return v; - }; - } - d3.functor = d3_functor; - function d3_identity(d) { - return d; - } - d3.xhr = d3_xhrType(d3_identity); - function d3_xhrType(response) { - return function(url, mimeType, callback) { - if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, - mimeType = null; - return d3_xhr(url, mimeType, response, callback); - }; - } - function d3_xhr(url, mimeType, response, callback) { - var xhr = {}, dispatch = d3.dispatch("beforesend", "progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null; - if (d3_window.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); - "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() { - request.readyState > 3 && respond(); - }; - function respond() { - var status = request.status, result; - if (!status && d3_xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) { - try { - result = response.call(xhr, request); - } catch (e) { - dispatch.error.call(xhr, e); - return; - } - dispatch.load.call(xhr, result); - } else { - dispatch.error.call(xhr, request); - } - } - request.onprogress = function(event) { - var o = d3.event; - d3.event = event; - try { - dispatch.progress.call(xhr, request); - } finally { - d3.event = o; - } - }; - xhr.header = function(name, value) { - name = (name + "").toLowerCase(); - if (arguments.length < 2) return headers[name]; - if (value == null) delete headers[name]; else headers[name] = value + ""; - return xhr; - }; - xhr.mimeType = function(value) { - if (!arguments.length) return mimeType; - mimeType = value == null ? null : value + ""; - return xhr; - }; - xhr.responseType = function(value) { - if (!arguments.length) return responseType; - responseType = value; - return xhr; - }; - xhr.response = function(value) { - response = value; - return xhr; - }; - [ "get", "post" ].forEach(function(method) { - xhr[method] = function() { - return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments))); - }; - }); - xhr.send = function(method, data, callback) { - if (arguments.length === 2 && typeof data === "function") callback = data, data = null; - request.open(method, url, true); - if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; - if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); - if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); - if (responseType != null) request.responseType = responseType; - if (callback != null) xhr.on("error", callback).on("load", function(request) { - callback(null, request); - }); - dispatch.beforesend.call(xhr, request); - request.send(data == null ? null : data); - return xhr; - }; - xhr.abort = function() { - request.abort(); - return xhr; - }; - d3.rebind(xhr, dispatch, "on"); - return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); - } - function d3_xhr_fixCallback(callback) { - return callback.length === 1 ? function(error, request) { - callback(error == null ? request : null); - } : callback; - } - function d3_xhrHasResponse(request) { - var type = request.responseType; - return type && type !== "text" ? request.response : request.responseText; - } - d3.dsv = function(delimiter, mimeType) { - var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0); - function dsv(url, row, callback) { - if (arguments.length < 3) callback = row, row = null; - var xhr = d3_xhr(url, mimeType, row == null ? response : typedResponse(row), callback); - xhr.row = function(_) { - return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row; - }; - return xhr; - } - function response(request) { - return dsv.parse(request.responseText); - } - function typedResponse(f) { - return function(request) { - return dsv.parse(request.responseText, f); - }; - } - dsv.parse = function(text, f) { - var o; - return dsv.parseRows(text, function(row, i) { - if (o) return o(row, i - 1); - var a = new Function("d", "return {" + row.map(function(name, i) { - return JSON.stringify(name) + ": d[" + i + "]"; - }).join(",") + "}"); - o = f ? function(row, i) { - return f(a(row), i); - } : a; - }); - }; - dsv.parseRows = function(text, f) { - var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol; - function token() { - if (I >= N) return EOF; - if (eol) return eol = false, EOL; - var j = I; - if (text.charCodeAt(j) === 34) { - var i = j; - while (i++ < N) { - if (text.charCodeAt(i) === 34) { - if (text.charCodeAt(i + 1) !== 34) break; - ++i; - } - } - I = i + 2; - var c = text.charCodeAt(i + 1); - if (c === 13) { - eol = true; - if (text.charCodeAt(i + 2) === 10) ++I; - } else if (c === 10) { - eol = true; - } - return text.slice(j + 1, i).replace(/""/g, '"'); - } - while (I < N) { - var c = text.charCodeAt(I++), k = 1; - if (c === 10) eol = true; else if (c === 13) { - eol = true; - if (text.charCodeAt(I) === 10) ++I, ++k; - } else if (c !== delimiterCode) continue; - return text.slice(j, I - k); - } - return text.slice(j); - } - while ((t = token()) !== EOF) { - var a = []; - while (t !== EOL && t !== EOF) { - a.push(t); - t = token(); - } - if (f && (a = f(a, n++)) == null) continue; - rows.push(a); - } - return rows; - }; - dsv.format = function(rows) { - if (Array.isArray(rows[0])) return dsv.formatRows(rows); - var fieldSet = new d3_Set(), fields = []; - rows.forEach(function(row) { - for (var field in row) { - if (!fieldSet.has(field)) { - fields.push(fieldSet.add(field)); - } - } - }); - return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) { - return fields.map(function(field) { - return formatValue(row[field]); - }).join(delimiter); - })).join("\n"); - }; - dsv.formatRows = function(rows) { - return rows.map(formatRow).join("\n"); - }; - function formatRow(row) { - return row.map(formatValue).join(delimiter); - } - function formatValue(text) { - return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text; - } - return dsv; - }; - d3.csv = d3.dsv(",", "text/csv"); - d3.tsv = d3.dsv(" ", "text/tab-separated-values"); - var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_active, d3_timer_frame = d3_window[d3_vendorSymbol(d3_window, "requestAnimationFrame")] || function(callback) { - setTimeout(callback, 17); - }; - d3.timer = function(callback, delay, then) { - var n = arguments.length; - if (n < 2) delay = 0; - if (n < 3) then = Date.now(); - var time = then + delay, timer = { - c: callback, - t: time, - f: false, - n: null - }; - if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer; - d3_timer_queueTail = timer; - if (!d3_timer_interval) { - d3_timer_timeout = clearTimeout(d3_timer_timeout); - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - }; - function d3_timer_step() { - var now = d3_timer_mark(), delay = d3_timer_sweep() - now; - if (delay > 24) { - if (isFinite(delay)) { - clearTimeout(d3_timer_timeout); - d3_timer_timeout = setTimeout(d3_timer_step, delay); - } - d3_timer_interval = 0; - } else { - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - } - d3.timer.flush = function() { - d3_timer_mark(); - d3_timer_sweep(); - }; - function d3_timer_mark() { - var now = Date.now(); - d3_timer_active = d3_timer_queueHead; - while (d3_timer_active) { - if (now >= d3_timer_active.t) d3_timer_active.f = d3_timer_active.c(now - d3_timer_active.t); - d3_timer_active = d3_timer_active.n; - } - return now; - } - function d3_timer_sweep() { - var t0, t1 = d3_timer_queueHead, time = Infinity; - while (t1) { - if (t1.f) { - t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n; - } else { - if (t1.t < time) time = t1.t; - t1 = (t0 = t1).n; - } - } - d3_timer_queueTail = t0; - return time; - } - function d3_format_precision(x, p) { - return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1); - } - d3.round = function(x, n) { - return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x); - }; - var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix); - d3.formatPrefix = function(value, precision) { - var i = 0; - if (value) { - if (value < 0) value *= -1; - if (precision) value = d3.round(value, d3_format_precision(value, precision)); - i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); - i = Math.max(-24, Math.min(24, Math.floor((i - 1) / 3) * 3)); - } - return d3_formatPrefixes[8 + i / 3]; - }; - function d3_formatPrefix(d, i) { - var k = Math.pow(10, abs(8 - i) * 3); - return { - scale: i > 8 ? function(d) { - return d / k; - } : function(d) { - return d * k; - }, - symbol: d - }; - } - function d3_locale_numberFormat(locale) { - var locale_decimal = locale.decimal, locale_thousands = locale.thousands, locale_grouping = locale.grouping, locale_currency = locale.currency, formatGroup = locale_grouping && locale_thousands ? function(value, width) { - var i = value.length, t = [], j = 0, g = locale_grouping[0], length = 0; - while (i > 0 && g > 0) { - if (length + g + 1 > width) g = Math.max(1, width - length); - t.push(value.substring(i -= g, i + g)); - if ((length += g + 1) > width) break; - g = locale_grouping[j = (j + 1) % locale_grouping.length]; - } - return t.reverse().join(locale_thousands); - } : d3_identity; - return function(specifier) { - var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "-", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = "", suffix = "", integer = false, exponent = true; - if (precision) precision = +precision.substring(1); - if (zfill || fill === "0" && align === "=") { - zfill = fill = "0"; - align = "="; - } - switch (type) { - case "n": - comma = true; - type = "g"; - break; - - case "%": - scale = 100; - suffix = "%"; - type = "f"; - break; - - case "p": - scale = 100; - suffix = "%"; - type = "r"; - break; - - case "b": - case "o": - case "x": - case "X": - if (symbol === "#") prefix = "0" + type.toLowerCase(); - - case "c": - exponent = false; - - case "d": - integer = true; - precision = 0; - break; - - case "s": - scale = -1; - type = "r"; - break; - } - if (symbol === "$") prefix = locale_currency[0], suffix = locale_currency[1]; - if (type == "r" && !precision) type = "g"; - if (precision != null) { - if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); - } - type = d3_format_types.get(type) || d3_format_typeDefault; - var zcomma = zfill && comma; - return function(value) { - var fullSuffix = suffix; - if (integer && value % 1) return ""; - var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign === "-" ? "" : sign; - if (scale < 0) { - var unit = d3.formatPrefix(value, precision); - value = unit.scale(value); - fullSuffix = unit.symbol + suffix; - } else { - value *= scale; - } - value = type(value, precision); - var i = value.lastIndexOf("."), before, after; - if (i < 0) { - var j = exponent ? value.lastIndexOf("e") : -1; - if (j < 0) before = value, after = ""; else before = value.substring(0, j), after = value.substring(j); - } else { - before = value.substring(0, i); - after = locale_decimal + value.substring(i + 1); - } - if (!zfill && comma) before = formatGroup(before, Infinity); - var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; - if (zcomma) before = formatGroup(padding + before, padding.length ? width - after.length : Infinity); - negative += prefix; - value = before + after; - return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + fullSuffix; - }; - }; - } - var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; - var d3_format_types = d3.map({ - b: function(x) { - return x.toString(2); - }, - c: function(x) { - return String.fromCharCode(x); - }, - o: function(x) { - return x.toString(8); - }, - x: function(x) { - return x.toString(16); - }, - X: function(x) { - return x.toString(16).toUpperCase(); - }, - g: function(x, p) { - return x.toPrecision(p); - }, - e: function(x, p) { - return x.toExponential(p); - }, - f: function(x, p) { - return x.toFixed(p); - }, - r: function(x, p) { - return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); - } - }); - function d3_format_typeDefault(x) { - return x + ""; - } - var d3_time = d3.time = {}, d3_date = Date; - function d3_date_utc() { - this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]); - } - d3_date_utc.prototype = { - getDate: function() { - return this._.getUTCDate(); - }, - getDay: function() { - return this._.getUTCDay(); - }, - getFullYear: function() { - return this._.getUTCFullYear(); - }, - getHours: function() { - return this._.getUTCHours(); - }, - getMilliseconds: function() { - return this._.getUTCMilliseconds(); - }, - getMinutes: function() { - return this._.getUTCMinutes(); - }, - getMonth: function() { - return this._.getUTCMonth(); - }, - getSeconds: function() { - return this._.getUTCSeconds(); - }, - getTime: function() { - return this._.getTime(); - }, - getTimezoneOffset: function() { - return 0; - }, - valueOf: function() { - return this._.valueOf(); - }, - setDate: function() { - d3_time_prototype.setUTCDate.apply(this._, arguments); - }, - setDay: function() { - d3_time_prototype.setUTCDay.apply(this._, arguments); - }, - setFullYear: function() { - d3_time_prototype.setUTCFullYear.apply(this._, arguments); - }, - setHours: function() { - d3_time_prototype.setUTCHours.apply(this._, arguments); - }, - setMilliseconds: function() { - d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); - }, - setMinutes: function() { - d3_time_prototype.setUTCMinutes.apply(this._, arguments); - }, - setMonth: function() { - d3_time_prototype.setUTCMonth.apply(this._, arguments); - }, - setSeconds: function() { - d3_time_prototype.setUTCSeconds.apply(this._, arguments); - }, - setTime: function() { - d3_time_prototype.setTime.apply(this._, arguments); - } - }; - var d3_time_prototype = Date.prototype; - function d3_time_interval(local, step, number) { - function round(date) { - var d0 = local(date), d1 = offset(d0, 1); - return date - d0 < d1 - date ? d0 : d1; - } - function ceil(date) { - step(date = local(new d3_date(date - 1)), 1); - return date; - } - function offset(date, k) { - step(date = new d3_date(+date), k); - return date; - } - function range(t0, t1, dt) { - var time = ceil(t0), times = []; - if (dt > 1) { - while (time < t1) { - if (!(number(time) % dt)) times.push(new Date(+time)); - step(time, 1); - } - } else { - while (time < t1) times.push(new Date(+time)), step(time, 1); - } - return times; - } - function range_utc(t0, t1, dt) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = t0; - return range(utc, t1, dt); - } finally { - d3_date = Date; - } - } - local.floor = local; - local.round = round; - local.ceil = ceil; - local.offset = offset; - local.range = range; - var utc = local.utc = d3_time_interval_utc(local); - utc.floor = utc; - utc.round = d3_time_interval_utc(round); - utc.ceil = d3_time_interval_utc(ceil); - utc.offset = d3_time_interval_utc(offset); - utc.range = range_utc; - return local; - } - function d3_time_interval_utc(method) { - return function(date, k) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = date; - return method(utc, k)._; - } finally { - d3_date = Date; - } - }; - } - d3_time.year = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setMonth(0, 1); - return date; - }, function(date, offset) { - date.setFullYear(date.getFullYear() + offset); - }, function(date) { - return date.getFullYear(); - }); - d3_time.years = d3_time.year.range; - d3_time.years.utc = d3_time.year.utc.range; - d3_time.day = d3_time_interval(function(date) { - var day = new d3_date(2e3, 0); - day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); - return day; - }, function(date, offset) { - date.setDate(date.getDate() + offset); - }, function(date) { - return date.getDate() - 1; - }); - d3_time.days = d3_time.day.range; - d3_time.days.utc = d3_time.day.utc.range; - d3_time.dayOfYear = function(date) { - var year = d3_time.year(date); - return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); - }; - [ "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ].forEach(function(day, i) { - i = 7 - i; - var interval = d3_time[day] = d3_time_interval(function(date) { - (date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); - return date; - }, function(date, offset) { - date.setDate(date.getDate() + Math.floor(offset) * 7); - }, function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); - }); - d3_time[day + "s"] = interval.range; - d3_time[day + "s"].utc = interval.utc.range; - d3_time[day + "OfYear"] = function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7); - }; - }); - d3_time.week = d3_time.sunday; - d3_time.weeks = d3_time.sunday.range; - d3_time.weeks.utc = d3_time.sunday.utc.range; - d3_time.weekOfYear = d3_time.sundayOfYear; - function d3_locale_timeFormat(locale) { - var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_days = locale.days, locale_shortDays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths; - function d3_time_format(template) { - var n = template.length; - function format(date) { - var string = [], i = -1, j = 0, c, p, f; - while (++i < n) { - if (template.charCodeAt(i) === 37) { - string.push(template.slice(j, i)); - if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); - if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p); - string.push(c); - j = i + 1; - } - } - string.push(template.slice(j, i)); - return string.join(""); - } - format.parse = function(string) { - var d = { - y: 1900, - m: 0, - d: 1, - H: 0, - M: 0, - S: 0, - L: 0, - Z: null - }, i = d3_time_parse(d, template, string, 0); - if (i != string.length) return null; - if ("p" in d) d.H = d.H % 12 + d.p * 12; - var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)(); - if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) { - date.setFullYear(d.y, 0, 1); - date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7); - } else date.setFullYear(d.y, d.m, d.d); - date.setHours(d.H + (d.Z / 100 | 0), d.M + d.Z % 100, d.S, d.L); - return localZ ? date._ : date; - }; - format.toString = function() { - return template; - }; - return format; - } - function d3_time_parse(date, template, string, j) { - var c, p, t, i = 0, n = template.length, m = string.length; - while (i < n) { - if (j >= m) return -1; - c = template.charCodeAt(i++); - if (c === 37) { - t = template.charAt(i++); - p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t]; - if (!p || (j = p(date, string, j)) < 0) return -1; - } else if (c != string.charCodeAt(j++)) { - return -1; - } - } - return j; - } - d3_time_format.utc = function(template) { - var local = d3_time_format(template); - function format(date) { - try { - d3_date = d3_date_utc; - var utc = new d3_date(); - utc._ = date; - return local(utc); - } finally { - d3_date = Date; - } - } - format.parse = function(string) { - try { - d3_date = d3_date_utc; - var date = local.parse(string); - return date && date._; - } finally { - d3_date = Date; - } - }; - format.toString = local.toString; - return format; - }; - d3_time_format.multi = d3_time_format.utc.multi = d3_time_formatMulti; - var d3_time_periodLookup = d3.map(), d3_time_dayRe = d3_time_formatRe(locale_days), d3_time_dayLookup = d3_time_formatLookup(locale_days), d3_time_dayAbbrevRe = d3_time_formatRe(locale_shortDays), d3_time_dayAbbrevLookup = d3_time_formatLookup(locale_shortDays), d3_time_monthRe = d3_time_formatRe(locale_months), d3_time_monthLookup = d3_time_formatLookup(locale_months), d3_time_monthAbbrevRe = d3_time_formatRe(locale_shortMonths), d3_time_monthAbbrevLookup = d3_time_formatLookup(locale_shortMonths); - locale_periods.forEach(function(p, i) { - d3_time_periodLookup.set(p.toLowerCase(), i); - }); - var d3_time_formats = { - a: function(d) { - return locale_shortDays[d.getDay()]; - }, - A: function(d) { - return locale_days[d.getDay()]; - }, - b: function(d) { - return locale_shortMonths[d.getMonth()]; - }, - B: function(d) { - return locale_months[d.getMonth()]; - }, - c: d3_time_format(locale_dateTime), - d: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - e: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - H: function(d, p) { - return d3_time_formatPad(d.getHours(), p, 2); - }, - I: function(d, p) { - return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); - }, - j: function(d, p) { - return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3); - }, - L: function(d, p) { - return d3_time_formatPad(d.getMilliseconds(), p, 3); - }, - m: function(d, p) { - return d3_time_formatPad(d.getMonth() + 1, p, 2); - }, - M: function(d, p) { - return d3_time_formatPad(d.getMinutes(), p, 2); - }, - p: function(d) { - return locale_periods[+(d.getHours() >= 12)]; - }, - S: function(d, p) { - return d3_time_formatPad(d.getSeconds(), p, 2); - }, - U: function(d, p) { - return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2); - }, - w: function(d) { - return d.getDay(); - }, - W: function(d, p) { - return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2); - }, - x: d3_time_format(locale_date), - X: d3_time_format(locale_time), - y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 100, p, 2); - }, - Y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 1e4, p, 4); - }, - Z: d3_time_zone, - "%": function() { - return "%"; - } - }; - var d3_time_parsers = { - a: d3_time_parseWeekdayAbbrev, - A: d3_time_parseWeekday, - b: d3_time_parseMonthAbbrev, - B: d3_time_parseMonth, - c: d3_time_parseLocaleFull, - d: d3_time_parseDay, - e: d3_time_parseDay, - H: d3_time_parseHour24, - I: d3_time_parseHour24, - j: d3_time_parseDayOfYear, - L: d3_time_parseMilliseconds, - m: d3_time_parseMonthNumber, - M: d3_time_parseMinutes, - p: d3_time_parseAmPm, - S: d3_time_parseSeconds, - U: d3_time_parseWeekNumberSunday, - w: d3_time_parseWeekdayNumber, - W: d3_time_parseWeekNumberMonday, - x: d3_time_parseLocaleDate, - X: d3_time_parseLocaleTime, - y: d3_time_parseYear, - Y: d3_time_parseFullYear, - Z: d3_time_parseZone, - "%": d3_time_parseLiteralPercent - }; - function d3_time_parseWeekdayAbbrev(date, string, i) { - d3_time_dayAbbrevRe.lastIndex = 0; - var n = d3_time_dayAbbrevRe.exec(string.slice(i)); - return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseWeekday(date, string, i) { - d3_time_dayRe.lastIndex = 0; - var n = d3_time_dayRe.exec(string.slice(i)); - return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseMonthAbbrev(date, string, i) { - d3_time_monthAbbrevRe.lastIndex = 0; - var n = d3_time_monthAbbrevRe.exec(string.slice(i)); - return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseMonth(date, string, i) { - d3_time_monthRe.lastIndex = 0; - var n = d3_time_monthRe.exec(string.slice(i)); - return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseLocaleFull(date, string, i) { - return d3_time_parse(date, d3_time_formats.c.toString(), string, i); - } - function d3_time_parseLocaleDate(date, string, i) { - return d3_time_parse(date, d3_time_formats.x.toString(), string, i); - } - function d3_time_parseLocaleTime(date, string, i) { - return d3_time_parse(date, d3_time_formats.X.toString(), string, i); - } - function d3_time_parseAmPm(date, string, i) { - var n = d3_time_periodLookup.get(string.slice(i, i += 2).toLowerCase()); - return n == null ? -1 : (date.p = n, i); - } - return d3_time_format; - } - var d3_time_formatPads = { - "-": "", - _: " ", - "0": "0" - }, d3_time_numberRe = /^\s*\d+/, d3_time_percentRe = /^%/; - function d3_time_formatPad(value, fill, width) { - var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length; - return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); - } - function d3_time_formatRe(names) { - return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); - } - function d3_time_formatLookup(names) { - var map = new d3_Map(), i = -1, n = names.length; - while (++i < n) map.set(names[i].toLowerCase(), i); - return map; - } - function d3_time_parseWeekdayNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 1)); - return n ? (date.w = +n[0], i + n[0].length) : -1; - } - function d3_time_parseWeekNumberSunday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i)); - return n ? (date.U = +n[0], i + n[0].length) : -1; - } - function d3_time_parseWeekNumberMonday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i)); - return n ? (date.W = +n[0], i + n[0].length) : -1; - } - function d3_time_parseFullYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 4)); - return n ? (date.y = +n[0], i + n[0].length) : -1; - } - function d3_time_parseYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1; - } - function d3_time_parseZone(date, string, i) { - return /^[+-]\d{4}$/.test(string = string.slice(i, i + 5)) ? (date.Z = -string, - i + 5) : -1; - } - function d3_time_expandYear(d) { - return d + (d > 68 ? 1900 : 2e3); - } - function d3_time_parseMonthNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.m = n[0] - 1, i + n[0].length) : -1; - } - function d3_time_parseDay(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.d = +n[0], i + n[0].length) : -1; - } - function d3_time_parseDayOfYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 3)); - return n ? (date.j = +n[0], i + n[0].length) : -1; - } - function d3_time_parseHour24(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.H = +n[0], i + n[0].length) : -1; - } - function d3_time_parseMinutes(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.M = +n[0], i + n[0].length) : -1; - } - function d3_time_parseSeconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.S = +n[0], i + n[0].length) : -1; - } - function d3_time_parseMilliseconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 3)); - return n ? (date.L = +n[0], i + n[0].length) : -1; - } - function d3_time_zone(d) { - var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = abs(z) / 60 | 0, zm = abs(z) % 60; - return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); - } - function d3_time_parseLiteralPercent(date, string, i) { - d3_time_percentRe.lastIndex = 0; - var n = d3_time_percentRe.exec(string.slice(i, i + 1)); - return n ? i + n[0].length : -1; - } - function d3_time_formatMulti(formats) { - var n = formats.length, i = -1; - while (++i < n) formats[i][0] = this(formats[i][0]); - return function(date) { - var i = 0, f = formats[i]; - while (!f[1](date)) f = formats[++i]; - return f[0](date); - }; - } - d3.locale = function(locale) { - return { - numberFormat: d3_locale_numberFormat(locale), - timeFormat: d3_locale_timeFormat(locale) - }; - }; - var d3_locale_enUS = d3.locale({ - decimal: ".", - thousands: ",", - grouping: [ 3 ], - currency: [ "$", "" ], - dateTime: "%a %b %e %X %Y", - date: "%m/%d/%Y", - time: "%H:%M:%S", - periods: [ "AM", "PM" ], - days: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], - shortDays: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], - months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], - shortMonths: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] - }); - d3.format = d3_locale_enUS.numberFormat; - d3.geo = {}; - function d3_adder() {} - d3_adder.prototype = { - s: 0, - t: 0, - add: function(y) { - d3_adderSum(y, this.t, d3_adderTemp); - d3_adderSum(d3_adderTemp.s, this.s, this); - if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t; - }, - reset: function() { - this.s = this.t = 0; - }, - valueOf: function() { - return this.s; - } - }; - var d3_adderTemp = new d3_adder(); - function d3_adderSum(a, b, o) { - var x = o.s = a + b, bv = x - a, av = x - bv; - o.t = a - av + (b - bv); - } - d3.geo.stream = function(object, listener) { - if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) { - d3_geo_streamObjectType[object.type](object, listener); - } else { - d3_geo_streamGeometry(object, listener); - } - }; - function d3_geo_streamGeometry(geometry, listener) { - if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { - d3_geo_streamGeometryType[geometry.type](geometry, listener); - } - } - var d3_geo_streamObjectType = { - Feature: function(feature, listener) { - d3_geo_streamGeometry(feature.geometry, listener); - }, - FeatureCollection: function(object, listener) { - var features = object.features, i = -1, n = features.length; - while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); - } - }; - var d3_geo_streamGeometryType = { - Sphere: function(object, listener) { - listener.sphere(); - }, - Point: function(object, listener) { - object = object.coordinates; - listener.point(object[0], object[1], object[2]); - }, - MultiPoint: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]); - }, - LineString: function(object, listener) { - d3_geo_streamLine(object.coordinates, listener, 0); - }, - MultiLineString: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); - }, - Polygon: function(object, listener) { - d3_geo_streamPolygon(object.coordinates, listener); - }, - MultiPolygon: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); - }, - GeometryCollection: function(object, listener) { - var geometries = object.geometries, i = -1, n = geometries.length; - while (++i < n) d3_geo_streamGeometry(geometries[i], listener); - } - }; - function d3_geo_streamLine(coordinates, listener, closed) { - var i = -1, n = coordinates.length - closed, coordinate; - listener.lineStart(); - while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]); - listener.lineEnd(); - } - function d3_geo_streamPolygon(coordinates, listener) { - var i = -1, n = coordinates.length; - listener.polygonStart(); - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); - listener.polygonEnd(); - } - d3.geo.area = function(object) { - d3_geo_areaSum = 0; - d3.geo.stream(object, d3_geo_area); - return d3_geo_areaSum; - }; - var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder(); - var d3_geo_area = { - sphere: function() { - d3_geo_areaSum += 4 * π; - }, - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_areaRingSum.reset(); - d3_geo_area.lineStart = d3_geo_areaRingStart; - }, - polygonEnd: function() { - var area = 2 * d3_geo_areaRingSum; - d3_geo_areaSum += area < 0 ? 4 * π + area : area; - d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; - } - }; - function d3_geo_areaRingStart() { - var λ00, φ00, λ0, cosφ0, sinφ0; - d3_geo_area.point = function(λ, φ) { - d3_geo_area.point = nextPoint; - λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4), - sinφ0 = Math.sin(φ); - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - φ = φ * d3_radians / 2 + π / 4; - var dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(adλ), v = k * sdλ * Math.sin(adλ); - d3_geo_areaRingSum.add(Math.atan2(v, u)); - λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ; - } - d3_geo_area.lineEnd = function() { - nextPoint(λ00, φ00); - }; - } - function d3_geo_cartesian(spherical) { - var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ); - return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ]; - } - function d3_geo_cartesianDot(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; - } - function d3_geo_cartesianCross(a, b) { - return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; - } - function d3_geo_cartesianAdd(a, b) { - a[0] += b[0]; - a[1] += b[1]; - a[2] += b[2]; - } - function d3_geo_cartesianScale(vector, k) { - return [ vector[0] * k, vector[1] * k, vector[2] * k ]; - } - function d3_geo_cartesianNormalize(d) { - var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); - d[0] /= l; - d[1] /= l; - d[2] /= l; - } - function d3_geo_spherical(cartesian) { - return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ]; - } - function d3_geo_sphericalEqual(a, b) { - return abs(a[0] - b[0]) < ε && abs(a[1] - b[1]) < ε; - } - d3.geo.bounds = function() { - var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range; - var bound = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - bound.point = ringPoint; - bound.lineStart = ringStart; - bound.lineEnd = ringEnd; - dλSum = 0; - d3_geo_area.polygonStart(); - }, - polygonEnd: function() { - d3_geo_area.polygonEnd(); - bound.point = point; - bound.lineStart = lineStart; - bound.lineEnd = lineEnd; - if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90; - range[0] = λ0, range[1] = λ1; - } - }; - function point(λ, φ) { - ranges.push(range = [ λ0 = λ, λ1 = λ ]); - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - function linePoint(λ, φ) { - var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]); - if (p0) { - var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal); - d3_geo_cartesianNormalize(inflection); - inflection = d3_geo_spherical(inflection); - var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = abs(dλ) > 180; - if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = inflection[1] * d3_degrees; - if (φi > φ1) φ1 = φi; - } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = -inflection[1] * d3_degrees; - if (φi < φ0) φ0 = φi; - } else { - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - if (antimeridian) { - if (λ < λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } else { - if (λ1 >= λ0) { - if (λ < λ0) λ0 = λ; - if (λ > λ1) λ1 = λ; - } else { - if (λ > λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } - } - } else { - point(λ, φ); - } - p0 = p, λ_ = λ; - } - function lineStart() { - bound.point = linePoint; - } - function lineEnd() { - range[0] = λ0, range[1] = λ1; - bound.point = point; - p0 = null; - } - function ringPoint(λ, φ) { - if (p0) { - var dλ = λ - λ_; - dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ; - } else λ__ = λ, φ__ = φ; - d3_geo_area.point(λ, φ); - linePoint(λ, φ); - } - function ringStart() { - d3_geo_area.lineStart(); - } - function ringEnd() { - ringPoint(λ__, φ__); - d3_geo_area.lineEnd(); - if (abs(dλSum) > ε) λ0 = -(λ1 = 180); - range[0] = λ0, range[1] = λ1; - p0 = null; - } - function angle(λ0, λ1) { - return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; - } - function compareRanges(a, b) { - return a[0] - b[0]; - } - function withinRange(x, range) { - return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; - } - return function(feature) { - φ1 = λ1 = -(λ0 = φ0 = Infinity); - ranges = []; - d3.geo.stream(feature, bound); - var n = ranges.length; - if (n) { - ranges.sort(compareRanges); - for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) { - b = ranges[i]; - if (withinRange(b[0], a) || withinRange(b[1], a)) { - if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; - if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; - } else { - merged.push(a = b); - } - } - var best = -Infinity, dλ; - for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) { - b = merged[i]; - if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1]; - } - } - ranges = range = null; - return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ]; - }; - }(); - d3.geo.centroid = function(object) { - d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, d3_geo_centroid); - var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z; - if (m < ε2) { - x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1; - if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0; - m = x * x + y * y + z * z; - if (m < ε2) return [ NaN, NaN ]; - } - return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ]; - }; - var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2; - var d3_geo_centroid = { - sphere: d3_noop, - point: d3_geo_centroidPoint, - lineStart: d3_geo_centroidLineStart, - lineEnd: d3_geo_centroidLineEnd, - polygonStart: function() { - d3_geo_centroid.lineStart = d3_geo_centroidRingStart; - }, - polygonEnd: function() { - d3_geo_centroid.lineStart = d3_geo_centroidLineStart; - } - }; - function d3_geo_centroidPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ)); - } - function d3_geo_centroidPointXYZ(x, y, z) { - ++d3_geo_centroidW0; - d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0; - d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0; - d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0; - } - function d3_geo_centroidLineStart() { - var x0, y0, z0; - d3_geo_centroid.point = function(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroid.point = nextPoint; - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } - } - function d3_geo_centroidLineEnd() { - d3_geo_centroid.point = d3_geo_centroidPoint; - } - function d3_geo_centroidRingStart() { - var λ00, φ00, x0, y0, z0; - d3_geo_centroid.point = function(λ, φ) { - λ00 = λ, φ00 = φ; - d3_geo_centroid.point = nextPoint; - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - d3_geo_centroid.lineEnd = function() { - nextPoint(λ00, φ00); - d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; - d3_geo_centroid.point = d3_geo_centroidPoint; - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u); - d3_geo_centroidX2 += v * cx; - d3_geo_centroidY2 += v * cy; - d3_geo_centroidZ2 += v * cz; - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } - } - function d3_geo_compose(a, b) { - function compose(x, y) { - return x = a(x, y), b(x[0], x[1]); - } - if (a.invert && b.invert) compose.invert = function(x, y) { - return x = b.invert(x, y), x && a.invert(x[0], x[1]); - }; - return compose; - } - function d3_true() { - return true; - } - function d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener) { - var subject = [], clip = []; - segments.forEach(function(segment) { - if ((n = segment.length - 1) <= 0) return; - var n, p0 = segment[0], p1 = segment[n]; - if (d3_geo_sphericalEqual(p0, p1)) { - listener.lineStart(); - for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]); - listener.lineEnd(); - return; - } - var a = new d3_geo_clipPolygonIntersection(p0, segment, null, true), b = new d3_geo_clipPolygonIntersection(p0, null, a, false); - a.o = b; - subject.push(a); - clip.push(b); - a = new d3_geo_clipPolygonIntersection(p1, segment, null, false); - b = new d3_geo_clipPolygonIntersection(p1, null, a, true); - a.o = b; - subject.push(a); - clip.push(b); - }); - clip.sort(compare); - d3_geo_clipPolygonLinkCircular(subject); - d3_geo_clipPolygonLinkCircular(clip); - if (!subject.length) return; - for (var i = 0, entry = clipStartInside, n = clip.length; i < n; ++i) { - clip[i].e = entry = !entry; - } - var start = subject[0], points, point; - while (1) { - var current = start, isSubject = true; - while (current.v) if ((current = current.n) === start) return; - points = current.z; - listener.lineStart(); - do { - current.v = current.o.v = true; - if (current.e) { - if (isSubject) { - for (var i = 0, n = points.length; i < n; ++i) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.x, current.n.x, 1, listener); - } - current = current.n; - } else { - if (isSubject) { - points = current.p.z; - for (var i = points.length - 1; i >= 0; --i) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.x, current.p.x, -1, listener); - } - current = current.p; - } - current = current.o; - points = current.z; - isSubject = !isSubject; - } while (!current.v); - listener.lineEnd(); - } - } - function d3_geo_clipPolygonLinkCircular(array) { - if (!(n = array.length)) return; - var n, i = 0, a = array[0], b; - while (++i < n) { - a.n = b = array[i]; - b.p = a; - a = b; - } - a.n = b = array[0]; - b.p = a; - } - function d3_geo_clipPolygonIntersection(point, points, other, entry) { - this.x = point; - this.z = points; - this.o = other; - this.e = entry; - this.v = false; - this.n = this.p = null; - } - function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) { - return function(rotate, listener) { - var line = clipLine(listener), rotatedClipStart = rotate.invert(clipStart[0], clipStart[1]); - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - clip.point = pointRing; - clip.lineStart = ringStart; - clip.lineEnd = ringEnd; - segments = []; - polygon = []; - }, - polygonEnd: function() { - clip.point = point; - clip.lineStart = lineStart; - clip.lineEnd = lineEnd; - segments = d3.merge(segments); - var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon); - if (segments.length) { - if (!polygonStarted) listener.polygonStart(), polygonStarted = true; - d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener); - } else if (clipStartInside) { - if (!polygonStarted) listener.polygonStart(), polygonStarted = true; - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - } - if (polygonStarted) listener.polygonEnd(), polygonStarted = false; - segments = polygon = null; - }, - sphere: function() { - listener.polygonStart(); - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - listener.polygonEnd(); - } - }; - function point(λ, φ) { - var point = rotate(λ, φ); - if (pointVisible(λ = point[0], φ = point[1])) listener.point(λ, φ); - } - function pointLine(λ, φ) { - var point = rotate(λ, φ); - line.point(point[0], point[1]); - } - function lineStart() { - clip.point = pointLine; - line.lineStart(); - } - function lineEnd() { - clip.point = point; - line.lineEnd(); - } - var segments; - var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygonStarted = false, polygon, ring; - function pointRing(λ, φ) { - ring.push([ λ, φ ]); - var point = rotate(λ, φ); - ringListener.point(point[0], point[1]); - } - function ringStart() { - ringListener.lineStart(); - ring = []; - } - function ringEnd() { - pointRing(ring[0][0], ring[0][1]); - ringListener.lineEnd(); - var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length; - ring.pop(); - polygon.push(ring); - ring = null; - if (!n) return; - if (clean & 1) { - segment = ringSegments[0]; - var n = segment.length - 1, i = -1, point; - if (n > 0) { - if (!polygonStarted) listener.polygonStart(), polygonStarted = true; - listener.lineStart(); - while (++i < n) listener.point((point = segment[i])[0], point[1]); - listener.lineEnd(); - } - return; - } - if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); - segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); - } - return clip; - }; - } - function d3_geo_clipSegmentLength1(segment) { - return segment.length > 1; - } - function d3_geo_clipBufferListener() { - var lines = [], line; - return { - lineStart: function() { - lines.push(line = []); - }, - point: function(λ, φ) { - line.push([ λ, φ ]); - }, - lineEnd: d3_noop, - buffer: function() { - var buffer = lines; - lines = []; - line = null; - return buffer; - }, - rejoin: function() { - if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); - } - }; - } - function d3_geo_clipSort(a, b) { - return ((a = a.x)[0] < 0 ? a[1] - halfπ - ε : halfπ - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfπ - ε : halfπ - b[1]); - } - var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, [ -π, -π / 2 ]); - function d3_geo_clipAntimeridianLine(listener) { - var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; - return { - lineStart: function() { - listener.lineStart(); - clean = 1; - }, - point: function(λ1, φ1) { - var sλ1 = λ1 > 0 ? π : -π, dλ = abs(λ1 - λ0); - if (abs(dλ - π) < ε) { - listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? halfπ : -halfπ); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - listener.point(λ1, φ0); - clean = 0; - } else if (sλ0 !== sλ1 && dλ >= π) { - if (abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; - if (abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; - φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - clean = 0; - } - listener.point(λ0 = λ1, φ0 = φ1); - sλ0 = sλ1; - }, - lineEnd: function() { - listener.lineEnd(); - λ0 = φ0 = NaN; - }, - clean: function() { - return 2 - clean; - } - }; - } - function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { - var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); - return abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2; - } - function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { - var φ; - if (from == null) { - φ = direction * halfπ; - listener.point(-π, φ); - listener.point(0, φ); - listener.point(π, φ); - listener.point(π, 0); - listener.point(π, -φ); - listener.point(0, -φ); - listener.point(-π, -φ); - listener.point(-π, 0); - listener.point(-π, φ); - } else if (abs(from[0] - to[0]) > ε) { - var s = from[0] < to[0] ? π : -π; - φ = direction * s / 2; - listener.point(-s, φ); - listener.point(0, φ); - listener.point(s, φ); - } else { - listener.point(to[0], to[1]); - } - } - function d3_geo_pointInPolygon(point, polygon) { - var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0; - d3_geo_areaRingSum.reset(); - for (var i = 0, n = polygon.length; i < n; ++i) { - var ring = polygon[i], m = ring.length; - if (!m) continue; - var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + π / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1; - while (true) { - if (j === m) j = 0; - point = ring[j]; - var λ = point[0], φ = point[1] / 2 + π / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, antimeridian = adλ > π, k = sinφ0 * sinφ; - d3_geo_areaRingSum.add(Math.atan2(k * sdλ * Math.sin(adλ), cosφ0 * cosφ + k * Math.cos(adλ))); - polarAngle += antimeridian ? dλ + sdλ * τ : dλ; - if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) { - var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point)); - d3_geo_cartesianNormalize(arc); - var intersection = d3_geo_cartesianCross(meridianNormal, arc); - d3_geo_cartesianNormalize(intersection); - var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]); - if (parallel > φarc || parallel === φarc && (arc[0] || arc[1])) { - winding += antimeridian ^ dλ >= 0 ? 1 : -1; - } - } - if (!j++) break; - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point; - } - } - return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1; - } - function d3_geo_clipCircle(radius) { - var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians); - return d3_geo_clip(visible, clipLine, interpolate, smallRadius ? [ 0, -radius ] : [ -π, radius - π ]); - function visible(λ, φ) { - return Math.cos(λ) * Math.cos(φ) > cr; - } - function clipLine(listener) { - var point0, c0, v0, v00, clean; - return { - lineStart: function() { - v00 = v0 = false; - clean = 1; - }, - point: function(λ, φ) { - var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? π : -π), φ) : 0; - if (!point0 && (v00 = v0 = v)) listener.lineStart(); - if (v !== v0) { - point2 = intersect(point0, point1); - if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { - point1[0] += ε; - point1[1] += ε; - v = visible(point1[0], point1[1]); - } - } - if (v !== v0) { - clean = 0; - if (v) { - listener.lineStart(); - point2 = intersect(point1, point0); - listener.point(point2[0], point2[1]); - } else { - point2 = intersect(point0, point1); - listener.point(point2[0], point2[1]); - listener.lineEnd(); - } - point0 = point2; - } else if (notHemisphere && point0 && smallRadius ^ v) { - var t; - if (!(c & c0) && (t = intersect(point1, point0, true))) { - clean = 0; - if (smallRadius) { - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - } else { - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - } - } - } - if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) { - listener.point(point1[0], point1[1]); - } - point0 = point1, v0 = v, c0 = c; - }, - lineEnd: function() { - if (v0) listener.lineEnd(); - point0 = null; - }, - clean: function() { - return clean | (v00 && v0) << 1; - } - }; - } - function intersect(a, b, two) { - var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b); - var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2; - if (!determinant) return !two && a; - var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2); - d3_geo_cartesianAdd(A, B); - var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1); - if (t2 < 0) return; - var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu); - d3_geo_cartesianAdd(q, A); - q = d3_geo_spherical(q); - if (!two) return q; - var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z; - if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z; - var δλ = λ1 - λ0, polar = abs(δλ - π) < ε, meridian = polar || δλ < ε; - if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z; - if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) { - var q1 = d3_geo_cartesianScale(u, (-w + t) / uu); - d3_geo_cartesianAdd(q1, A); - return [ q, d3_geo_spherical(q1) ]; - } - } - function code(λ, φ) { - var r = smallRadius ? radius : π - radius, code = 0; - if (λ < -r) code |= 1; else if (λ > r) code |= 2; - if (φ < -r) code |= 4; else if (φ > r) code |= 8; - return code; - } - } - function d3_geom_clipLine(x0, y0, x1, y1) { - return function(line) { - var a = line.a, b = line.b, ax = a.x, ay = a.y, bx = b.x, by = b.y, t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r; - r = x0 - ax; - if (!dx && r > 0) return; - r /= dx; - if (dx < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dx > 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } - r = x1 - ax; - if (!dx && r < 0) return; - r /= dx; - if (dx < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dx > 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } - r = y0 - ay; - if (!dy && r > 0) return; - r /= dy; - if (dy < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dy > 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } - r = y1 - ay; - if (!dy && r < 0) return; - r /= dy; - if (dy < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dy > 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } - if (t0 > 0) line.a = { - x: ax + t0 * dx, - y: ay + t0 * dy - }; - if (t1 < 1) line.b = { - x: ax + t1 * dx, - y: ay + t1 * dy - }; - return line; - }; - } - var d3_geo_clipExtentMAX = 1e9; - d3.geo.clipExtent = function() { - var x0, y0, x1, y1, stream, clip, clipExtent = { - stream: function(output) { - if (stream) stream.valid = false; - stream = clip(output); - stream.valid = true; - return stream; - }, - extent: function(_) { - if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; - clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]); - if (stream) stream.valid = false, stream = null; - return clipExtent; - } - }; - return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]); - }; - function d3_geo_clipExtent(x0, y0, x1, y1) { - return function(listener) { - var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), clipLine = d3_geom_clipLine(x0, y0, x1, y1), segments, polygon, ring; - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - listener = bufferListener; - segments = []; - polygon = []; - clean = true; - }, - polygonEnd: function() { - listener = listener_; - segments = d3.merge(segments); - var clipStartInside = insidePolygon([ x0, y1 ]), inside = clean && clipStartInside, visible = segments.length; - if (inside || visible) { - listener.polygonStart(); - if (inside) { - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - } - if (visible) { - d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener); - } - listener.polygonEnd(); - } - segments = polygon = ring = null; - } - }; - function insidePolygon(p) { - var wn = 0, n = polygon.length, y = p[1]; - for (var i = 0; i < n; ++i) { - for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { - b = v[j]; - if (a[1] <= y) { - if (b[1] > y && d3_cross2d(a, b, p) > 0) ++wn; - } else { - if (b[1] <= y && d3_cross2d(a, b, p) < 0) --wn; - } - a = b; - } - } - return wn !== 0; - } - function interpolate(from, to, direction, listener) { - var a = 0, a1 = 0; - if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) { - do { - listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); - } while ((a = (a + direction + 4) % 4) !== a1); - } else { - listener.point(to[0], to[1]); - } - } - function pointVisible(x, y) { - return x0 <= x && x <= x1 && y0 <= y && y <= y1; - } - function point(x, y) { - if (pointVisible(x, y)) listener.point(x, y); - } - var x__, y__, v__, x_, y_, v_, first, clean; - function lineStart() { - clip.point = linePoint; - if (polygon) polygon.push(ring = []); - first = true; - v_ = false; - x_ = y_ = NaN; - } - function lineEnd() { - if (segments) { - linePoint(x__, y__); - if (v__ && v_) bufferListener.rejoin(); - segments.push(bufferListener.buffer()); - } - clip.point = point; - if (v_) listener.lineEnd(); - } - function linePoint(x, y) { - x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x)); - y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y)); - var v = pointVisible(x, y); - if (polygon) ring.push([ x, y ]); - if (first) { - x__ = x, y__ = y, v__ = v; - first = false; - if (v) { - listener.lineStart(); - listener.point(x, y); - } - } else { - if (v && v_) listener.point(x, y); else { - var l = { - a: { - x: x_, - y: y_ - }, - b: { - x: x, - y: y - } - }; - if (clipLine(l)) { - if (!v_) { - listener.lineStart(); - listener.point(l.a.x, l.a.y); - } - listener.point(l.b.x, l.b.y); - if (!v) listener.lineEnd(); - clean = false; - } else if (v) { - listener.lineStart(); - listener.point(x, y); - clean = false; - } - } - } - x_ = x, y_ = y, v_ = v; - } - return clip; - }; - function corner(p, direction) { - return abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; - } - function compare(a, b) { - return comparePoints(a.x, b.x); - } - function comparePoints(a, b) { - var ca = corner(a, 1), cb = corner(b, 1); - return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0]; - } - } - function d3_geo_conic(projectAt) { - var φ0 = 0, φ1 = π / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1); - p.parallels = function(_) { - if (!arguments.length) return [ φ0 / π * 180, φ1 / π * 180 ]; - return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180); - }; - return p; - } - function d3_geo_conicEqualArea(φ0, φ1) { - var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n; - function forward(λ, φ) { - var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; - return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = ρ0 - y; - return [ Math.atan2(x, ρ0_y) / n, d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ]; - }; - return forward; - } - (d3.geo.conicEqualArea = function() { - return d3_geo_conic(d3_geo_conicEqualArea); - }).raw = d3_geo_conicEqualArea; - d3.geo.albers = function() { - return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070); - }; - d3.geo.albersUsa = function() { - var lower48 = d3.geo.albers(); - var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]); - var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]); - var point, pointStream = { - point: function(x, y) { - point = [ x, y ]; - } - }, lower48Point, alaskaPoint, hawaiiPoint; - function albersUsa(coordinates) { - var x = coordinates[0], y = coordinates[1]; - point = null; - (lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y); - return point; - } - albersUsa.invert = function(coordinates) { - var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k; - return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates); - }; - albersUsa.stream = function(stream) { - var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream); - return { - point: function(x, y) { - lower48Stream.point(x, y); - alaskaStream.point(x, y); - hawaiiStream.point(x, y); - }, - sphere: function() { - lower48Stream.sphere(); - alaskaStream.sphere(); - hawaiiStream.sphere(); - }, - lineStart: function() { - lower48Stream.lineStart(); - alaskaStream.lineStart(); - hawaiiStream.lineStart(); - }, - lineEnd: function() { - lower48Stream.lineEnd(); - alaskaStream.lineEnd(); - hawaiiStream.lineEnd(); - }, - polygonStart: function() { - lower48Stream.polygonStart(); - alaskaStream.polygonStart(); - hawaiiStream.polygonStart(); - }, - polygonEnd: function() { - lower48Stream.polygonEnd(); - alaskaStream.polygonEnd(); - hawaiiStream.polygonEnd(); - } - }; - }; - albersUsa.precision = function(_) { - if (!arguments.length) return lower48.precision(); - lower48.precision(_); - alaska.precision(_); - hawaii.precision(_); - return albersUsa; - }; - albersUsa.scale = function(_) { - if (!arguments.length) return lower48.scale(); - lower48.scale(_); - alaska.scale(_ * .35); - hawaii.scale(_); - return albersUsa.translate(lower48.translate()); - }; - albersUsa.translate = function(_) { - if (!arguments.length) return lower48.translate(); - var k = lower48.scale(), x = +_[0], y = +_[1]; - lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point; - alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; - hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; - return albersUsa; - }; - return albersUsa.scale(1070); - }; - var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_pathAreaPolygon = 0; - d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; - }, - polygonEnd: function() { - d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; - d3_geo_pathAreaSum += abs(d3_geo_pathAreaPolygon / 2); - } - }; - function d3_geo_pathAreaRingStart() { - var x00, y00, x0, y0; - d3_geo_pathArea.point = function(x, y) { - d3_geo_pathArea.point = nextPoint; - x00 = x0 = x, y00 = y0 = y; - }; - function nextPoint(x, y) { - d3_geo_pathAreaPolygon += y0 * x - x0 * y; - x0 = x, y0 = y; - } - d3_geo_pathArea.lineEnd = function() { - nextPoint(x00, y00); - }; - } - var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1; - var d3_geo_pathBounds = { - point: d3_geo_pathBoundsPoint, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop - }; - function d3_geo_pathBoundsPoint(x, y) { - if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x; - if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x; - if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y; - if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y; - } - function d3_geo_pathBuffer() { - var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = []; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointCircle = d3_geo_pathBufferCircle(_); - return stream; - }, - result: function() { - if (buffer.length) { - var result = buffer.join(""); - buffer = []; - return result; - } - } - }; - function point(x, y) { - buffer.push("M", x, ",", y, pointCircle); - } - function pointLineStart(x, y) { - buffer.push("M", x, ",", y); - stream.point = pointLine; - } - function pointLine(x, y) { - buffer.push("L", x, ",", y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - buffer.push("Z"); - } - return stream; - } - function d3_geo_pathBufferCircle(radius) { - return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z"; - } - var d3_geo_pathCentroid = { - point: d3_geo_pathCentroidPoint, - lineStart: d3_geo_pathCentroidLineStart, - lineEnd: d3_geo_pathCentroidLineEnd, - polygonStart: function() { - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; - }, - polygonEnd: function() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; - d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; - } - }; - function d3_geo_pathCentroidPoint(x, y) { - d3_geo_centroidX0 += x; - d3_geo_centroidY0 += y; - ++d3_geo_centroidZ0; - } - function d3_geo_pathCentroidLineStart() { - var x0, y0; - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - }; - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } - } - function d3_geo_pathCentroidLineEnd() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - } - function d3_geo_pathCentroidRingStart() { - var x00, y00, x0, y0; - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y); - }; - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - z = y0 * x - x0 * y; - d3_geo_centroidX2 += z * (x0 + x); - d3_geo_centroidY2 += z * (y0 + y); - d3_geo_centroidZ2 += z * 3; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } - d3_geo_pathCentroid.lineEnd = function() { - nextPoint(x00, y00); - }; - } - function d3_geo_pathContext(context) { - var pointRadius = 4.5; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointRadius = _; - return stream; - }, - result: d3_noop - }; - function point(x, y) { - context.moveTo(x + pointRadius, y); - context.arc(x, y, pointRadius, 0, τ); - } - function pointLineStart(x, y) { - context.moveTo(x, y); - stream.point = pointLine; - } - function pointLine(x, y) { - context.lineTo(x, y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - context.closePath(); - } - return stream; - } - function d3_geo_resample(project) { - var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16; - function resample(stream) { - return (maxDepth ? resampleRecursive : resampleNone)(stream); - } - function resampleNone(stream) { - return d3_geo_transformPoint(stream, function(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - }); - } - function resampleRecursive(stream) { - var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0; - var resample = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - stream.polygonStart(); - resample.lineStart = ringStart; - }, - polygonEnd: function() { - stream.polygonEnd(); - resample.lineStart = lineStart; - } - }; - function point(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - } - function lineStart() { - x0 = NaN; - resample.point = linePoint; - stream.lineStart(); - } - function linePoint(λ, φ) { - var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ); - resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); - stream.point(x0, y0); - } - function lineEnd() { - resample.point = point; - stream.lineEnd(); - } - function ringStart() { - lineStart(); - resample.point = ringPoint; - resample.lineEnd = ringEnd; - } - function ringPoint(λ, φ) { - linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; - resample.point = linePoint; - } - function ringEnd() { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); - resample.lineEnd = lineEnd; - lineEnd(); - } - return resample; - } - function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { - var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; - if (d2 > 4 * δ2 && depth--) { - var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = abs(abs(c) - 1) < ε || abs(λ0 - λ1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; - if (dz * dz / d2 > δ2 || abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); - stream.point(x2, y2); - resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); - } - } - } - resample.precision = function(_) { - if (!arguments.length) return Math.sqrt(δ2); - maxDepth = (δ2 = _ * _) > 0 && 16; - return resample; - }; - return resample; - } - d3.geo.path = function() { - var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream; - function path(object) { - if (object) { - if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); - if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream); - d3.geo.stream(object, cacheStream); - } - return contextStream.result(); - } - path.area = function(object) { - d3_geo_pathAreaSum = 0; - d3.geo.stream(object, projectStream(d3_geo_pathArea)); - return d3_geo_pathAreaSum; - }; - path.centroid = function(object) { - d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); - return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ]; - }; - path.bounds = function(object) { - d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity); - d3.geo.stream(object, projectStream(d3_geo_pathBounds)); - return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ]; - }; - path.projection = function(_) { - if (!arguments.length) return projection; - projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; - return reset(); - }; - path.context = function(_) { - if (!arguments.length) return context; - contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_); - if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); - return reset(); - }; - path.pointRadius = function(_) { - if (!arguments.length) return pointRadius; - pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); - return path; - }; - function reset() { - cacheStream = null; - return path; - } - return path.projection(d3.geo.albersUsa()).context(null); - }; - function d3_geo_pathProjectStream(project) { - var resample = d3_geo_resample(function(x, y) { - return project([ x * d3_degrees, y * d3_degrees ]); - }); - return function(stream) { - return d3_geo_projectionRadians(resample(stream)); - }; - } - d3.geo.transform = function(methods) { - return { - stream: function(stream) { - var transform = new d3_geo_transform(stream); - for (var k in methods) transform[k] = methods[k]; - return transform; - } - }; - }; - function d3_geo_transform(stream) { - this.stream = stream; - } - d3_geo_transform.prototype = { - point: function(x, y) { - this.stream.point(x, y); - }, - sphere: function() { - this.stream.sphere(); - }, - lineStart: function() { - this.stream.lineStart(); - }, - lineEnd: function() { - this.stream.lineEnd(); - }, - polygonStart: function() { - this.stream.polygonStart(); - }, - polygonEnd: function() { - this.stream.polygonEnd(); - } - }; - function d3_geo_transformPoint(stream, point) { - return { - point: point, - sphere: function() { - stream.sphere(); - }, - lineStart: function() { - stream.lineStart(); - }, - lineEnd: function() { - stream.lineEnd(); - }, - polygonStart: function() { - stream.polygonStart(); - }, - polygonEnd: function() { - stream.polygonEnd(); - } - }; - } - d3.geo.projection = d3_geo_projection; - d3.geo.projectionMutator = d3_geo_projectionMutator; - function d3_geo_projection(project) { - return d3_geo_projectionMutator(function() { - return project; - })(); - } - function d3_geo_projectionMutator(projectAt) { - var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) { - x = project(x, y); - return [ x[0] * k + δx, δy - x[1] * k ]; - }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream; - function projection(point) { - point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); - return [ point[0] * k + δx, δy - point[1] * k ]; - } - function invert(point) { - point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); - return point && [ point[0] * d3_degrees, point[1] * d3_degrees ]; - } - projection.stream = function(output) { - if (stream) stream.valid = false; - stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output)))); - stream.valid = true; - return stream; - }; - projection.clipAngle = function(_) { - if (!arguments.length) return clipAngle; - preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians); - return invalidate(); - }; - projection.clipExtent = function(_) { - if (!arguments.length) return clipExtent; - clipExtent = _; - postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity; - return invalidate(); - }; - projection.scale = function(_) { - if (!arguments.length) return k; - k = +_; - return reset(); - }; - projection.translate = function(_) { - if (!arguments.length) return [ x, y ]; - x = +_[0]; - y = +_[1]; - return reset(); - }; - projection.center = function(_) { - if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ]; - λ = _[0] % 360 * d3_radians; - φ = _[1] % 360 * d3_radians; - return reset(); - }; - projection.rotate = function(_) { - if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ]; - δλ = _[0] % 360 * d3_radians; - δφ = _[1] % 360 * d3_radians; - δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; - return reset(); - }; - d3.rebind(projection, projectResample, "precision"); - function reset() { - projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); - var center = project(λ, φ); - δx = x - center[0] * k; - δy = y + center[1] * k; - return invalidate(); - } - function invalidate() { - if (stream) stream.valid = false, stream = null; - return projection; - } - return function() { - project = projectAt.apply(this, arguments); - projection.invert = project.invert && invert; - return reset(); - }; - } - function d3_geo_projectionRadians(stream) { - return d3_geo_transformPoint(stream, function(x, y) { - stream.point(x * d3_radians, y * d3_radians); - }); - } - function d3_geo_equirectangular(λ, φ) { - return [ λ, φ ]; - } - (d3.geo.equirectangular = function() { - return d3_geo_projection(d3_geo_equirectangular); - }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; - d3.geo.rotation = function(rotate) { - rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0); - function forward(coordinates) { - coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - } - forward.invert = function(coordinates) { - coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - }; - return forward; - }; - function d3_geo_identityRotation(λ, φ) { - return [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ]; - } - d3_geo_identityRotation.invert = d3_geo_equirectangular; - function d3_geo_rotation(δλ, δφ, δγ) { - return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation; - } - function d3_geo_forwardRotationλ(δλ) { - return function(λ, φ) { - return λ += δλ, [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ]; - }; - } - function d3_geo_rotationλ(δλ) { - var rotation = d3_geo_forwardRotationλ(δλ); - rotation.invert = d3_geo_forwardRotationλ(-δλ); - return rotation; - } - function d3_geo_rotationφγ(δφ, δγ) { - var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ); - function rotation(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ; - return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ]; - } - rotation.invert = function(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ; - return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ]; - }; - return rotation; - } - d3.geo.circle = function() { - var origin = [ 0, 0 ], angle, precision = 6, interpolate; - function circle() { - var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = []; - interpolate(null, null, 1, { - point: function(x, y) { - ring.push(x = rotate(x, y)); - x[0] *= d3_degrees, x[1] *= d3_degrees; - } - }); - return { - type: "Polygon", - coordinates: [ ring ] - }; - } - circle.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return circle; - }; - circle.angle = function(x) { - if (!arguments.length) return angle; - interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); - return circle; - }; - circle.precision = function(_) { - if (!arguments.length) return precision; - interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); - return circle; - }; - return circle.angle(90); - }; - function d3_geo_circleInterpolate(radius, precision) { - var cr = Math.cos(radius), sr = Math.sin(radius); - return function(from, to, direction, listener) { - var step = direction * precision; - if (from != null) { - from = d3_geo_circleAngle(cr, from); - to = d3_geo_circleAngle(cr, to); - if (direction > 0 ? from < to : from > to) from += direction * τ; - } else { - from = radius + direction * τ; - to = radius - .5 * step; - } - for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) { - listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]); - } - }; - } - function d3_geo_circleAngle(cr, point) { - var a = d3_geo_cartesian(point); - a[0] -= cr; - d3_geo_cartesianNormalize(a); - var angle = d3_acos(-a[1]); - return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); - } - d3.geo.distance = function(a, b) { - var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t; - return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ); - }; - d3.geo.graticule = function() { - var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5; - function graticule() { - return { - type: "MultiLineString", - coordinates: lines() - }; - } - function lines() { - return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { - return abs(x % DX) > ε; - }).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) { - return abs(y % DY) > ε; - }).map(y)); - } - graticule.lines = function() { - return lines().map(function(coordinates) { - return { - type: "LineString", - coordinates: coordinates - }; - }); - }; - graticule.outline = function() { - return { - type: "Polygon", - coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ] - }; - }; - graticule.extent = function(_) { - if (!arguments.length) return graticule.minorExtent(); - return graticule.majorExtent(_).minorExtent(_); - }; - graticule.majorExtent = function(_) { - if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ]; - X0 = +_[0][0], X1 = +_[1][0]; - Y0 = +_[0][1], Y1 = +_[1][1]; - if (X0 > X1) _ = X0, X0 = X1, X1 = _; - if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; - return graticule.precision(precision); - }; - graticule.minorExtent = function(_) { - if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; - x0 = +_[0][0], x1 = +_[1][0]; - y0 = +_[0][1], y1 = +_[1][1]; - if (x0 > x1) _ = x0, x0 = x1, x1 = _; - if (y0 > y1) _ = y0, y0 = y1, y1 = _; - return graticule.precision(precision); - }; - graticule.step = function(_) { - if (!arguments.length) return graticule.minorStep(); - return graticule.majorStep(_).minorStep(_); - }; - graticule.majorStep = function(_) { - if (!arguments.length) return [ DX, DY ]; - DX = +_[0], DY = +_[1]; - return graticule; - }; - graticule.minorStep = function(_) { - if (!arguments.length) return [ dx, dy ]; - dx = +_[0], dy = +_[1]; - return graticule; - }; - graticule.precision = function(_) { - if (!arguments.length) return precision; - precision = +_; - x = d3_geo_graticuleX(y0, y1, 90); - y = d3_geo_graticuleY(x0, x1, precision); - X = d3_geo_graticuleX(Y0, Y1, 90); - Y = d3_geo_graticuleY(X0, X1, precision); - return graticule; - }; - return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]); - }; - function d3_geo_graticuleX(y0, y1, dy) { - var y = d3.range(y0, y1 - ε, dy).concat(y1); - return function(x) { - return y.map(function(y) { - return [ x, y ]; - }); - }; - } - function d3_geo_graticuleY(x0, x1, dx) { - var x = d3.range(x0, x1 - ε, dx).concat(x1); - return function(y) { - return x.map(function(x) { - return [ x, y ]; - }); - }; - } - function d3_source(d) { - return d.source; - } - function d3_target(d) { - return d.target; - } - d3.geo.greatArc = function() { - var source = d3_source, source_, target = d3_target, target_; - function greatArc() { - return { - type: "LineString", - coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ] - }; - } - greatArc.distance = function() { - return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments)); - }; - greatArc.source = function(_) { - if (!arguments.length) return source; - source = _, source_ = typeof _ === "function" ? null : _; - return greatArc; - }; - greatArc.target = function(_) { - if (!arguments.length) return target; - target = _, target_ = typeof _ === "function" ? null : _; - return greatArc; - }; - greatArc.precision = function() { - return arguments.length ? greatArc : 0; - }; - return greatArc; - }; - d3.geo.interpolate = function(source, target) { - return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians); - }; - function d3_geo_interpolate(x0, y0, x1, y1) { - var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d); - var interpolate = d ? function(t) { - var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; - return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ]; - } : function() { - return [ x0 * d3_degrees, y0 * d3_degrees ]; - }; - interpolate.distance = d; - return interpolate; - } - d3.geo.length = function(object) { - d3_geo_lengthSum = 0; - d3.geo.stream(object, d3_geo_length); - return d3_geo_lengthSum; - }; - var d3_geo_lengthSum; - var d3_geo_length = { - sphere: d3_noop, - point: d3_noop, - lineStart: d3_geo_lengthLineStart, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop - }; - function d3_geo_lengthLineStart() { - var λ0, sinφ0, cosφ0; - d3_geo_length.point = function(λ, φ) { - λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ); - d3_geo_length.point = nextPoint; - }; - d3_geo_length.lineEnd = function() { - d3_geo_length.point = d3_geo_length.lineEnd = d3_noop; - }; - function nextPoint(λ, φ) { - var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t); - d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ); - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ; - } - } - function d3_geo_azimuthal(scale, angle) { - function azimuthal(λ, φ) { - var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ); - return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ]; - } - azimuthal.invert = function(x, y) { - var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c); - return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ]; - }; - return azimuthal; - } - var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) { - return Math.sqrt(2 / (1 + cosλcosφ)); - }, function(ρ) { - return 2 * Math.asin(ρ / 2); - }); - (d3.geo.azimuthalEqualArea = function() { - return d3_geo_projection(d3_geo_azimuthalEqualArea); - }).raw = d3_geo_azimuthalEqualArea; - var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) { - var c = Math.acos(cosλcosφ); - return c && c / Math.sin(c); - }, d3_identity); - (d3.geo.azimuthalEquidistant = function() { - return d3_geo_projection(d3_geo_azimuthalEquidistant); - }).raw = d3_geo_azimuthalEquidistant; - function d3_geo_conicConformal(φ0, φ1) { - var cosφ0 = Math.cos(φ0), t = function(φ) { - return Math.tan(π / 4 + φ / 2); - }, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n; - if (!n) return d3_geo_mercator; - function forward(λ, φ) { - if (F > 0) { - if (φ < -halfπ + ε) φ = -halfπ + ε; - } else { - if (φ > halfπ - ε) φ = halfπ - ε; - } - var ρ = F / Math.pow(t(φ), n); - return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y); - return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - halfπ ]; - }; - return forward; - } - (d3.geo.conicConformal = function() { - return d3_geo_conic(d3_geo_conicConformal); - }).raw = d3_geo_conicConformal; - function d3_geo_conicEquidistant(φ0, φ1) { - var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0; - if (abs(n) < ε) return d3_geo_equirectangular; - function forward(λ, φ) { - var ρ = G - φ; - return [ ρ * Math.sin(n * λ), G - ρ * Math.cos(n * λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = G - y; - return [ Math.atan2(x, ρ0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) ]; - }; - return forward; - } - (d3.geo.conicEquidistant = function() { - return d3_geo_conic(d3_geo_conicEquidistant); - }).raw = d3_geo_conicEquidistant; - var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / cosλcosφ; - }, Math.atan); - (d3.geo.gnomonic = function() { - return d3_geo_projection(d3_geo_gnomonic); - }).raw = d3_geo_gnomonic; - function d3_geo_mercator(λ, φ) { - return [ λ, Math.log(Math.tan(π / 4 + φ / 2)) ]; - } - d3_geo_mercator.invert = function(x, y) { - return [ x, 2 * Math.atan(Math.exp(y)) - halfπ ]; - }; - function d3_geo_mercatorProjection(project) { - var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto; - m.scale = function() { - var v = scale.apply(m, arguments); - return v === m ? clipAuto ? m.clipExtent(null) : m : v; - }; - m.translate = function() { - var v = translate.apply(m, arguments); - return v === m ? clipAuto ? m.clipExtent(null) : m : v; - }; - m.clipExtent = function(_) { - var v = clipExtent.apply(m, arguments); - if (v === m) { - if (clipAuto = _ == null) { - var k = π * scale(), t = translate(); - clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]); - } - } else if (clipAuto) { - v = null; - } - return v; - }; - return m.clipExtent(null); - } - (d3.geo.mercator = function() { - return d3_geo_mercatorProjection(d3_geo_mercator); - }).raw = d3_geo_mercator; - var d3_geo_orthographic = d3_geo_azimuthal(function() { - return 1; - }, Math.asin); - (d3.geo.orthographic = function() { - return d3_geo_projection(d3_geo_orthographic); - }).raw = d3_geo_orthographic; - var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / (1 + cosλcosφ); - }, function(ρ) { - return 2 * Math.atan(ρ); - }); - (d3.geo.stereographic = function() { - return d3_geo_projection(d3_geo_stereographic); - }).raw = d3_geo_stereographic; - function d3_geo_transverseMercator(λ, φ) { - return [ Math.log(Math.tan(π / 4 + φ / 2)), -λ ]; - } - d3_geo_transverseMercator.invert = function(x, y) { - return [ -y, 2 * Math.atan(Math.exp(x)) - halfπ ]; - }; - (d3.geo.transverseMercator = function() { - var projection = d3_geo_mercatorProjection(d3_geo_transverseMercator), center = projection.center, rotate = projection.rotate; - projection.center = function(_) { - return _ ? center([ -_[1], _[0] ]) : (_ = center(), [ _[1], -_[0] ]); - }; - projection.rotate = function(_) { - return _ ? rotate([ _[0], _[1], _.length > 2 ? _[2] + 90 : 90 ]) : (_ = rotate(), - [ _[0], _[1], _[2] - 90 ]); - }; - return rotate([ 0, 0, 90 ]); - }).raw = d3_geo_transverseMercator; - d3.geom = {}; - function d3_geom_pointX(d) { - return d[0]; - } - function d3_geom_pointY(d) { - return d[1]; - } - d3.geom.hull = function(vertices) { - var x = d3_geom_pointX, y = d3_geom_pointY; - if (arguments.length) return hull(vertices); - function hull(data) { - if (data.length < 3) return []; - var fx = d3_functor(x), fy = d3_functor(y), i, n = data.length, points = [], flippedPoints = []; - for (i = 0; i < n; i++) { - points.push([ +fx.call(this, data[i], i), +fy.call(this, data[i], i), i ]); - } - points.sort(d3_geom_hullOrder); - for (i = 0; i < n; i++) flippedPoints.push([ points[i][0], -points[i][1] ]); - var upper = d3_geom_hullUpper(points), lower = d3_geom_hullUpper(flippedPoints); - var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1], polygon = []; - for (i = upper.length - 1; i >= 0; --i) polygon.push(data[points[upper[i]][2]]); - for (i = +skipLeft; i < lower.length - skipRight; ++i) polygon.push(data[points[lower[i]][2]]); - return polygon; - } - hull.x = function(_) { - return arguments.length ? (x = _, hull) : x; - }; - hull.y = function(_) { - return arguments.length ? (y = _, hull) : y; - }; - return hull; - }; - function d3_geom_hullUpper(points) { - var n = points.length, hull = [ 0, 1 ], hs = 2; - for (var i = 2; i < n; i++) { - while (hs > 1 && d3_cross2d(points[hull[hs - 2]], points[hull[hs - 1]], points[i]) <= 0) --hs; - hull[hs++] = i; - } - return hull.slice(0, hs); - } - function d3_geom_hullOrder(a, b) { - return a[0] - b[0] || a[1] - b[1]; - } - d3.geom.polygon = function(coordinates) { - d3_subclass(coordinates, d3_geom_polygonPrototype); - return coordinates; - }; - var d3_geom_polygonPrototype = d3.geom.polygon.prototype = []; - d3_geom_polygonPrototype.area = function() { - var i = -1, n = this.length, a, b = this[n - 1], area = 0; - while (++i < n) { - a = b; - b = this[i]; - area += a[1] * b[0] - a[0] * b[1]; - } - return area * .5; - }; - d3_geom_polygonPrototype.centroid = function(k) { - var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c; - if (!arguments.length) k = -1 / (6 * this.area()); - while (++i < n) { - a = b; - b = this[i]; - c = a[0] * b[1] - b[0] * a[1]; - x += (a[0] + b[0]) * c; - y += (a[1] + b[1]) * c; - } - return [ x * k, y * k ]; - }; - d3_geom_polygonPrototype.clip = function(subject) { - var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d; - while (++i < n) { - input = subject.slice(); - subject.length = 0; - b = this[i]; - c = input[(m = input.length - closed) - 1]; - j = -1; - while (++j < m) { - d = input[j]; - if (d3_geom_polygonInside(d, a, b)) { - if (!d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - subject.push(d); - } else if (d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - c = d; - } - if (closed) subject.push(subject[0]); - a = b; - } - return subject; - }; - function d3_geom_polygonInside(p, a, b) { - return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); - } - function d3_geom_polygonIntersect(c, d, a, b) { - var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); - return [ x1 + ua * x21, y1 + ua * y21 ]; - } - function d3_geom_polygonClosed(coordinates) { - var a = coordinates[0], b = coordinates[coordinates.length - 1]; - return !(a[0] - b[0] || a[1] - b[1]); - } - var d3_geom_voronoiEdges, d3_geom_voronoiCells, d3_geom_voronoiBeaches, d3_geom_voronoiBeachPool = [], d3_geom_voronoiFirstCircle, d3_geom_voronoiCircles, d3_geom_voronoiCirclePool = []; - function d3_geom_voronoiBeach() { - d3_geom_voronoiRedBlackNode(this); - this.edge = this.site = this.circle = null; - } - function d3_geom_voronoiCreateBeach(site) { - var beach = d3_geom_voronoiBeachPool.pop() || new d3_geom_voronoiBeach(); - beach.site = site; - return beach; - } - function d3_geom_voronoiDetachBeach(beach) { - d3_geom_voronoiDetachCircle(beach); - d3_geom_voronoiBeaches.remove(beach); - d3_geom_voronoiBeachPool.push(beach); - d3_geom_voronoiRedBlackNode(beach); - } - function d3_geom_voronoiRemoveBeach(beach) { - var circle = beach.circle, x = circle.x, y = circle.cy, vertex = { - x: x, - y: y - }, previous = beach.P, next = beach.N, disappearing = [ beach ]; - d3_geom_voronoiDetachBeach(beach); - var lArc = previous; - while (lArc.circle && abs(x - lArc.circle.x) < ε && abs(y - lArc.circle.cy) < ε) { - previous = lArc.P; - disappearing.unshift(lArc); - d3_geom_voronoiDetachBeach(lArc); - lArc = previous; - } - disappearing.unshift(lArc); - d3_geom_voronoiDetachCircle(lArc); - var rArc = next; - while (rArc.circle && abs(x - rArc.circle.x) < ε && abs(y - rArc.circle.cy) < ε) { - next = rArc.N; - disappearing.push(rArc); - d3_geom_voronoiDetachBeach(rArc); - rArc = next; - } - disappearing.push(rArc); - d3_geom_voronoiDetachCircle(rArc); - var nArcs = disappearing.length, iArc; - for (iArc = 1; iArc < nArcs; ++iArc) { - rArc = disappearing[iArc]; - lArc = disappearing[iArc - 1]; - d3_geom_voronoiSetEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex); - } - lArc = disappearing[0]; - rArc = disappearing[nArcs - 1]; - rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, rArc.site, null, vertex); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - } - function d3_geom_voronoiAddBeach(site) { - var x = site.x, directrix = site.y, lArc, rArc, dxl, dxr, node = d3_geom_voronoiBeaches._; - while (node) { - dxl = d3_geom_voronoiLeftBreakPoint(node, directrix) - x; - if (dxl > ε) node = node.L; else { - dxr = x - d3_geom_voronoiRightBreakPoint(node, directrix); - if (dxr > ε) { - if (!node.R) { - lArc = node; - break; - } - node = node.R; - } else { - if (dxl > -ε) { - lArc = node.P; - rArc = node; - } else if (dxr > -ε) { - lArc = node; - rArc = node.N; - } else { - lArc = rArc = node; - } - break; - } - } - } - var newArc = d3_geom_voronoiCreateBeach(site); - d3_geom_voronoiBeaches.insert(lArc, newArc); - if (!lArc && !rArc) return; - if (lArc === rArc) { - d3_geom_voronoiDetachCircle(lArc); - rArc = d3_geom_voronoiCreateBeach(lArc.site); - d3_geom_voronoiBeaches.insert(newArc, rArc); - newArc.edge = rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - return; - } - if (!rArc) { - newArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); - return; - } - d3_geom_voronoiDetachCircle(lArc); - d3_geom_voronoiDetachCircle(rArc); - var lSite = lArc.site, ax = lSite.x, ay = lSite.y, bx = site.x - ax, by = site.y - ay, rSite = rArc.site, cx = rSite.x - ax, cy = rSite.y - ay, d = 2 * (bx * cy - by * cx), hb = bx * bx + by * by, hc = cx * cx + cy * cy, vertex = { - x: (cy * hb - by * hc) / d + ax, - y: (bx * hc - cx * hb) / d + ay - }; - d3_geom_voronoiSetEdgeEnd(rArc.edge, lSite, rSite, vertex); - newArc.edge = d3_geom_voronoiCreateEdge(lSite, site, null, vertex); - rArc.edge = d3_geom_voronoiCreateEdge(site, rSite, null, vertex); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - } - function d3_geom_voronoiLeftBreakPoint(arc, directrix) { - var site = arc.site, rfocx = site.x, rfocy = site.y, pby2 = rfocy - directrix; - if (!pby2) return rfocx; - var lArc = arc.P; - if (!lArc) return -Infinity; - site = lArc.site; - var lfocx = site.x, lfocy = site.y, plby2 = lfocy - directrix; - if (!plby2) return lfocx; - var hl = lfocx - rfocx, aby2 = 1 / pby2 - 1 / plby2, b = hl / plby2; - if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx; - return (rfocx + lfocx) / 2; - } - function d3_geom_voronoiRightBreakPoint(arc, directrix) { - var rArc = arc.N; - if (rArc) return d3_geom_voronoiLeftBreakPoint(rArc, directrix); - var site = arc.site; - return site.y === directrix ? site.x : Infinity; - } - function d3_geom_voronoiCell(site) { - this.site = site; - this.edges = []; - } - d3_geom_voronoiCell.prototype.prepare = function() { - var halfEdges = this.edges, iHalfEdge = halfEdges.length, edge; - while (iHalfEdge--) { - edge = halfEdges[iHalfEdge].edge; - if (!edge.b || !edge.a) halfEdges.splice(iHalfEdge, 1); - } - halfEdges.sort(d3_geom_voronoiHalfEdgeOrder); - return halfEdges.length; - }; - function d3_geom_voronoiCloseCells(extent) { - var x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], x2, y2, x3, y3, cells = d3_geom_voronoiCells, iCell = cells.length, cell, iHalfEdge, halfEdges, nHalfEdges, start, end; - while (iCell--) { - cell = cells[iCell]; - if (!cell || !cell.prepare()) continue; - halfEdges = cell.edges; - nHalfEdges = halfEdges.length; - iHalfEdge = 0; - while (iHalfEdge < nHalfEdges) { - end = halfEdges[iHalfEdge].end(), x3 = end.x, y3 = end.y; - start = halfEdges[++iHalfEdge % nHalfEdges].start(), x2 = start.x, y2 = start.y; - if (abs(x3 - x2) > ε || abs(y3 - y2) > ε) { - halfEdges.splice(iHalfEdge, 0, new d3_geom_voronoiHalfEdge(d3_geom_voronoiCreateBorderEdge(cell.site, end, abs(x3 - x0) < ε && y1 - y3 > ε ? { - x: x0, - y: abs(x2 - x0) < ε ? y2 : y1 - } : abs(y3 - y1) < ε && x1 - x3 > ε ? { - x: abs(y2 - y1) < ε ? x2 : x1, - y: y1 - } : abs(x3 - x1) < ε && y3 - y0 > ε ? { - x: x1, - y: abs(x2 - x1) < ε ? y2 : y0 - } : abs(y3 - y0) < ε && x3 - x0 > ε ? { - x: abs(y2 - y0) < ε ? x2 : x0, - y: y0 - } : null), cell.site, null)); - ++nHalfEdges; - } - } - } - } - function d3_geom_voronoiHalfEdgeOrder(a, b) { - return b.angle - a.angle; - } - function d3_geom_voronoiCircle() { - d3_geom_voronoiRedBlackNode(this); - this.x = this.y = this.arc = this.site = this.cy = null; - } - function d3_geom_voronoiAttachCircle(arc) { - var lArc = arc.P, rArc = arc.N; - if (!lArc || !rArc) return; - var lSite = lArc.site, cSite = arc.site, rSite = rArc.site; - if (lSite === rSite) return; - var bx = cSite.x, by = cSite.y, ax = lSite.x - bx, ay = lSite.y - by, cx = rSite.x - bx, cy = rSite.y - by; - var d = 2 * (ax * cy - ay * cx); - if (d >= -ε2) return; - var ha = ax * ax + ay * ay, hc = cx * cx + cy * cy, x = (cy * ha - ay * hc) / d, y = (ax * hc - cx * ha) / d, cy = y + by; - var circle = d3_geom_voronoiCirclePool.pop() || new d3_geom_voronoiCircle(); - circle.arc = arc; - circle.site = cSite; - circle.x = x + bx; - circle.y = cy + Math.sqrt(x * x + y * y); - circle.cy = cy; - arc.circle = circle; - var before = null, node = d3_geom_voronoiCircles._; - while (node) { - if (circle.y < node.y || circle.y === node.y && circle.x <= node.x) { - if (node.L) node = node.L; else { - before = node.P; - break; - } - } else { - if (node.R) node = node.R; else { - before = node; - break; - } - } - } - d3_geom_voronoiCircles.insert(before, circle); - if (!before) d3_geom_voronoiFirstCircle = circle; - } - function d3_geom_voronoiDetachCircle(arc) { - var circle = arc.circle; - if (circle) { - if (!circle.P) d3_geom_voronoiFirstCircle = circle.N; - d3_geom_voronoiCircles.remove(circle); - d3_geom_voronoiCirclePool.push(circle); - d3_geom_voronoiRedBlackNode(circle); - arc.circle = null; - } - } - function d3_geom_voronoiClipEdges(extent) { - var edges = d3_geom_voronoiEdges, clip = d3_geom_clipLine(extent[0][0], extent[0][1], extent[1][0], extent[1][1]), i = edges.length, e; - while (i--) { - e = edges[i]; - if (!d3_geom_voronoiConnectEdge(e, extent) || !clip(e) || abs(e.a.x - e.b.x) < ε && abs(e.a.y - e.b.y) < ε) { - e.a = e.b = null; - edges.splice(i, 1); - } - } - } - function d3_geom_voronoiConnectEdge(edge, extent) { - var vb = edge.b; - if (vb) return true; - var va = edge.a, x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], lSite = edge.l, rSite = edge.r, lx = lSite.x, ly = lSite.y, rx = rSite.x, ry = rSite.y, fx = (lx + rx) / 2, fy = (ly + ry) / 2, fm, fb; - if (ry === ly) { - if (fx < x0 || fx >= x1) return; - if (lx > rx) { - if (!va) va = { - x: fx, - y: y0 - }; else if (va.y >= y1) return; - vb = { - x: fx, - y: y1 - }; - } else { - if (!va) va = { - x: fx, - y: y1 - }; else if (va.y < y0) return; - vb = { - x: fx, - y: y0 - }; - } - } else { - fm = (lx - rx) / (ry - ly); - fb = fy - fm * fx; - if (fm < -1 || fm > 1) { - if (lx > rx) { - if (!va) va = { - x: (y0 - fb) / fm, - y: y0 - }; else if (va.y >= y1) return; - vb = { - x: (y1 - fb) / fm, - y: y1 - }; - } else { - if (!va) va = { - x: (y1 - fb) / fm, - y: y1 - }; else if (va.y < y0) return; - vb = { - x: (y0 - fb) / fm, - y: y0 - }; - } - } else { - if (ly < ry) { - if (!va) va = { - x: x0, - y: fm * x0 + fb - }; else if (va.x >= x1) return; - vb = { - x: x1, - y: fm * x1 + fb - }; - } else { - if (!va) va = { - x: x1, - y: fm * x1 + fb - }; else if (va.x < x0) return; - vb = { - x: x0, - y: fm * x0 + fb - }; - } - } - } - edge.a = va; - edge.b = vb; - return true; - } - function d3_geom_voronoiEdge(lSite, rSite) { - this.l = lSite; - this.r = rSite; - this.a = this.b = null; - } - function d3_geom_voronoiCreateEdge(lSite, rSite, va, vb) { - var edge = new d3_geom_voronoiEdge(lSite, rSite); - d3_geom_voronoiEdges.push(edge); - if (va) d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, va); - if (vb) d3_geom_voronoiSetEdgeEnd(edge, rSite, lSite, vb); - d3_geom_voronoiCells[lSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, lSite, rSite)); - d3_geom_voronoiCells[rSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, rSite, lSite)); - return edge; - } - function d3_geom_voronoiCreateBorderEdge(lSite, va, vb) { - var edge = new d3_geom_voronoiEdge(lSite, null); - edge.a = va; - edge.b = vb; - d3_geom_voronoiEdges.push(edge); - return edge; - } - function d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, vertex) { - if (!edge.a && !edge.b) { - edge.a = vertex; - edge.l = lSite; - edge.r = rSite; - } else if (edge.l === rSite) { - edge.b = vertex; - } else { - edge.a = vertex; - } - } - function d3_geom_voronoiHalfEdge(edge, lSite, rSite) { - var va = edge.a, vb = edge.b; - this.edge = edge; - this.site = lSite; - this.angle = rSite ? Math.atan2(rSite.y - lSite.y, rSite.x - lSite.x) : edge.l === lSite ? Math.atan2(vb.x - va.x, va.y - vb.y) : Math.atan2(va.x - vb.x, vb.y - va.y); - } - d3_geom_voronoiHalfEdge.prototype = { - start: function() { - return this.edge.l === this.site ? this.edge.a : this.edge.b; - }, - end: function() { - return this.edge.l === this.site ? this.edge.b : this.edge.a; - } - }; - function d3_geom_voronoiRedBlackTree() { - this._ = null; - } - function d3_geom_voronoiRedBlackNode(node) { - node.U = node.C = node.L = node.R = node.P = node.N = null; - } - d3_geom_voronoiRedBlackTree.prototype = { - insert: function(after, node) { - var parent, grandpa, uncle; - if (after) { - node.P = after; - node.N = after.N; - if (after.N) after.N.P = node; - after.N = node; - if (after.R) { - after = after.R; - while (after.L) after = after.L; - after.L = node; - } else { - after.R = node; - } - parent = after; - } else if (this._) { - after = d3_geom_voronoiRedBlackFirst(this._); - node.P = null; - node.N = after; - after.P = after.L = node; - parent = after; - } else { - node.P = node.N = null; - this._ = node; - parent = null; - } - node.L = node.R = null; - node.U = parent; - node.C = true; - after = node; - while (parent && parent.C) { - grandpa = parent.U; - if (parent === grandpa.L) { - uncle = grandpa.R; - if (uncle && uncle.C) { - parent.C = uncle.C = false; - grandpa.C = true; - after = grandpa; - } else { - if (after === parent.R) { - d3_geom_voronoiRedBlackRotateLeft(this, parent); - after = parent; - parent = after.U; - } - parent.C = false; - grandpa.C = true; - d3_geom_voronoiRedBlackRotateRight(this, grandpa); - } - } else { - uncle = grandpa.L; - if (uncle && uncle.C) { - parent.C = uncle.C = false; - grandpa.C = true; - after = grandpa; - } else { - if (after === parent.L) { - d3_geom_voronoiRedBlackRotateRight(this, parent); - after = parent; - parent = after.U; - } - parent.C = false; - grandpa.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, grandpa); - } - } - parent = after.U; - } - this._.C = false; - }, - remove: function(node) { - if (node.N) node.N.P = node.P; - if (node.P) node.P.N = node.N; - node.N = node.P = null; - var parent = node.U, sibling, left = node.L, right = node.R, next, red; - if (!left) next = right; else if (!right) next = left; else next = d3_geom_voronoiRedBlackFirst(right); - if (parent) { - if (parent.L === node) parent.L = next; else parent.R = next; - } else { - this._ = next; - } - if (left && right) { - red = next.C; - next.C = node.C; - next.L = left; - left.U = next; - if (next !== right) { - parent = next.U; - next.U = node.U; - node = next.R; - parent.L = node; - next.R = right; - right.U = next; - } else { - next.U = parent; - parent = next; - node = next.R; - } - } else { - red = node.C; - node = next; - } - if (node) node.U = parent; - if (red) return; - if (node && node.C) { - node.C = false; - return; - } - do { - if (node === this._) break; - if (node === parent.L) { - sibling = parent.R; - if (sibling.C) { - sibling.C = false; - parent.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, parent); - sibling = parent.R; - } - if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { - if (!sibling.R || !sibling.R.C) { - sibling.L.C = false; - sibling.C = true; - d3_geom_voronoiRedBlackRotateRight(this, sibling); - sibling = parent.R; - } - sibling.C = parent.C; - parent.C = sibling.R.C = false; - d3_geom_voronoiRedBlackRotateLeft(this, parent); - node = this._; - break; - } - } else { - sibling = parent.L; - if (sibling.C) { - sibling.C = false; - parent.C = true; - d3_geom_voronoiRedBlackRotateRight(this, parent); - sibling = parent.L; - } - if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { - if (!sibling.L || !sibling.L.C) { - sibling.R.C = false; - sibling.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, sibling); - sibling = parent.L; - } - sibling.C = parent.C; - parent.C = sibling.L.C = false; - d3_geom_voronoiRedBlackRotateRight(this, parent); - node = this._; - break; - } - } - sibling.C = true; - node = parent; - parent = parent.U; - } while (!node.C); - if (node) node.C = false; - } - }; - function d3_geom_voronoiRedBlackRotateLeft(tree, node) { - var p = node, q = node.R, parent = p.U; - if (parent) { - if (parent.L === p) parent.L = q; else parent.R = q; - } else { - tree._ = q; - } - q.U = parent; - p.U = q; - p.R = q.L; - if (p.R) p.R.U = p; - q.L = p; - } - function d3_geom_voronoiRedBlackRotateRight(tree, node) { - var p = node, q = node.L, parent = p.U; - if (parent) { - if (parent.L === p) parent.L = q; else parent.R = q; - } else { - tree._ = q; - } - q.U = parent; - p.U = q; - p.L = q.R; - if (p.L) p.L.U = p; - q.R = p; - } - function d3_geom_voronoiRedBlackFirst(node) { - while (node.L) node = node.L; - return node; - } - function d3_geom_voronoi(sites, bbox) { - var site = sites.sort(d3_geom_voronoiVertexOrder).pop(), x0, y0, circle; - d3_geom_voronoiEdges = []; - d3_geom_voronoiCells = new Array(sites.length); - d3_geom_voronoiBeaches = new d3_geom_voronoiRedBlackTree(); - d3_geom_voronoiCircles = new d3_geom_voronoiRedBlackTree(); - while (true) { - circle = d3_geom_voronoiFirstCircle; - if (site && (!circle || site.y < circle.y || site.y === circle.y && site.x < circle.x)) { - if (site.x !== x0 || site.y !== y0) { - d3_geom_voronoiCells[site.i] = new d3_geom_voronoiCell(site); - d3_geom_voronoiAddBeach(site); - x0 = site.x, y0 = site.y; - } - site = sites.pop(); - } else if (circle) { - d3_geom_voronoiRemoveBeach(circle.arc); - } else { - break; - } - } - if (bbox) d3_geom_voronoiClipEdges(bbox), d3_geom_voronoiCloseCells(bbox); - var diagram = { - cells: d3_geom_voronoiCells, - edges: d3_geom_voronoiEdges - }; - d3_geom_voronoiBeaches = d3_geom_voronoiCircles = d3_geom_voronoiEdges = d3_geom_voronoiCells = null; - return diagram; - } - function d3_geom_voronoiVertexOrder(a, b) { - return b.y - a.y || b.x - a.x; - } - d3.geom.voronoi = function(points) { - var x = d3_geom_pointX, y = d3_geom_pointY, fx = x, fy = y, clipExtent = d3_geom_voronoiClipExtent; - if (points) return voronoi(points); - function voronoi(data) { - var polygons = new Array(data.length), x0 = clipExtent[0][0], y0 = clipExtent[0][1], x1 = clipExtent[1][0], y1 = clipExtent[1][1]; - d3_geom_voronoi(sites(data), clipExtent).cells.forEach(function(cell, i) { - var edges = cell.edges, site = cell.site, polygon = polygons[i] = edges.length ? edges.map(function(e) { - var s = e.start(); - return [ s.x, s.y ]; - }) : site.x >= x0 && site.x <= x1 && site.y >= y0 && site.y <= y1 ? [ [ x0, y1 ], [ x1, y1 ], [ x1, y0 ], [ x0, y0 ] ] : []; - polygon.point = data[i]; - }); - return polygons; - } - function sites(data) { - return data.map(function(d, i) { - return { - x: Math.round(fx(d, i) / ε) * ε, - y: Math.round(fy(d, i) / ε) * ε, - i: i - }; - }); - } - voronoi.links = function(data) { - return d3_geom_voronoi(sites(data)).edges.filter(function(edge) { - return edge.l && edge.r; - }).map(function(edge) { - return { - source: data[edge.l.i], - target: data[edge.r.i] - }; - }); - }; - voronoi.triangles = function(data) { - var triangles = []; - d3_geom_voronoi(sites(data)).cells.forEach(function(cell, i) { - var site = cell.site, edges = cell.edges.sort(d3_geom_voronoiHalfEdgeOrder), j = -1, m = edges.length, e0, s0, e1 = edges[m - 1].edge, s1 = e1.l === site ? e1.r : e1.l; - while (++j < m) { - e0 = e1; - s0 = s1; - e1 = edges[j].edge; - s1 = e1.l === site ? e1.r : e1.l; - if (i < s0.i && i < s1.i && d3_geom_voronoiTriangleArea(site, s0, s1) < 0) { - triangles.push([ data[i], data[s0.i], data[s1.i] ]); - } - } - }); - return triangles; - }; - voronoi.x = function(_) { - return arguments.length ? (fx = d3_functor(x = _), voronoi) : x; - }; - voronoi.y = function(_) { - return arguments.length ? (fy = d3_functor(y = _), voronoi) : y; - }; - voronoi.clipExtent = function(_) { - if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent; - clipExtent = _ == null ? d3_geom_voronoiClipExtent : _; - return voronoi; - }; - voronoi.size = function(_) { - if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent && clipExtent[1]; - return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]); - }; - return voronoi; - }; - var d3_geom_voronoiClipExtent = [ [ -1e6, -1e6 ], [ 1e6, 1e6 ] ]; - function d3_geom_voronoiTriangleArea(a, b, c) { - return (a.x - c.x) * (b.y - a.y) - (a.x - b.x) * (c.y - a.y); - } - d3.geom.delaunay = function(vertices) { - return d3.geom.voronoi().triangles(vertices); - }; - d3.geom.quadtree = function(points, x1, y1, x2, y2) { - var x = d3_geom_pointX, y = d3_geom_pointY, compat; - if (compat = arguments.length) { - x = d3_geom_quadtreeCompatX; - y = d3_geom_quadtreeCompatY; - if (compat === 3) { - y2 = y1; - x2 = x1; - y1 = x1 = 0; - } - return quadtree(points); - } - function quadtree(data) { - var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_; - if (x1 != null) { - x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2; - } else { - x2_ = y2_ = -(x1_ = y1_ = Infinity); - xs = [], ys = []; - n = data.length; - if (compat) for (i = 0; i < n; ++i) { - d = data[i]; - if (d.x < x1_) x1_ = d.x; - if (d.y < y1_) y1_ = d.y; - if (d.x > x2_) x2_ = d.x; - if (d.y > y2_) y2_ = d.y; - xs.push(d.x); - ys.push(d.y); - } else for (i = 0; i < n; ++i) { - var x_ = +fx(d = data[i], i), y_ = +fy(d, i); - if (x_ < x1_) x1_ = x_; - if (y_ < y1_) y1_ = y_; - if (x_ > x2_) x2_ = x_; - if (y_ > y2_) y2_ = y_; - xs.push(x_); - ys.push(y_); - } - } - var dx = x2_ - x1_, dy = y2_ - y1_; - if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy; - function insert(n, d, x, y, x1, y1, x2, y2) { - if (isNaN(x) || isNaN(y)) return; - if (n.leaf) { - var nx = n.x, ny = n.y; - if (nx != null) { - if (abs(nx - x) + abs(ny - y) < .01) { - insertChild(n, d, x, y, x1, y1, x2, y2); - } else { - var nPoint = n.point; - n.x = n.y = n.point = null; - insertChild(n, nPoint, nx, ny, x1, y1, x2, y2); - insertChild(n, d, x, y, x1, y1, x2, y2); - } - } else { - n.x = x, n.y = y, n.point = d; - } - } else { - insertChild(n, d, x, y, x1, y1, x2, y2); - } - } - function insertChild(n, d, x, y, x1, y1, x2, y2) { - var xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym, i = below << 1 | right; - n.leaf = false; - n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); - if (right) x1 = xm; else x2 = xm; - if (below) y1 = ym; else y2 = ym; - insert(n, d, x, y, x1, y1, x2, y2); - } - var root = d3_geom_quadtreeNode(); - root.add = function(d) { - insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_); - }; - root.visit = function(f) { - d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_); - }; - root.find = function(point) { - return d3_geom_quadtreeFind(root, point[0], point[1], x1_, y1_, x2_, y2_); - }; - i = -1; - if (x1 == null) { - while (++i < n) { - insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_); - } - --i; - } else data.forEach(root.add); - xs = ys = data = d = null; - return root; - } - quadtree.x = function(_) { - return arguments.length ? (x = _, quadtree) : x; - }; - quadtree.y = function(_) { - return arguments.length ? (y = _, quadtree) : y; - }; - quadtree.extent = function(_) { - if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ]; - if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], - y2 = +_[1][1]; - return quadtree; - }; - quadtree.size = function(_) { - if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ]; - if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1]; - return quadtree; - }; - return quadtree; - }; - function d3_geom_quadtreeCompatX(d) { - return d.x; - } - function d3_geom_quadtreeCompatY(d) { - return d.y; - } - function d3_geom_quadtreeNode() { - return { - leaf: true, - nodes: [], - point: null, - x: null, - y: null - }; - } - function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { - if (!f(node, x1, y1, x2, y2)) { - var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes; - if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); - if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); - if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); - if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); - } - } - function d3_geom_quadtreeFind(root, x, y, x0, y0, x3, y3) { - var minDistance2 = Infinity, closestPoint; - (function find(node, x1, y1, x2, y2) { - if (x1 > x3 || y1 > y3 || x2 < x0 || y2 < y0) return; - if (point = node.point) { - var point, dx = x - point[0], dy = y - point[1], distance2 = dx * dx + dy * dy; - if (distance2 < minDistance2) { - var distance = Math.sqrt(minDistance2 = distance2); - x0 = x - distance, y0 = y - distance; - x3 = x + distance, y3 = y + distance; - closestPoint = point; - } - } - var children = node.nodes, xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym; - for (var i = below << 1 | right, j = i + 4; i < j; ++i) { - if (node = children[i & 3]) switch (i & 3) { - case 0: - find(node, x1, y1, xm, ym); - break; - - case 1: - find(node, xm, y1, x2, ym); - break; - - case 2: - find(node, x1, ym, xm, y2); - break; - - case 3: - find(node, xm, ym, x2, y2); - break; - } - } - })(root, x0, y0, x3, y3); - return closestPoint; - } - d3.interpolateRgb = d3_interpolateRgb; - function d3_interpolateRgb(a, b) { - a = d3.rgb(a); - b = d3.rgb(b); - var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab; - return function(t) { - return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t)); - }; - } - d3.interpolateObject = d3_interpolateObject; - function d3_interpolateObject(a, b) { - var i = {}, c = {}, k; - for (k in a) { - if (k in b) { - i[k] = d3_interpolate(a[k], b[k]); - } else { - c[k] = a[k]; - } - } - for (k in b) { - if (!(k in a)) { - c[k] = b[k]; - } - } - return function(t) { - for (k in i) c[k] = i[k](t); - return c; - }; - } - d3.interpolateNumber = d3_interpolateNumber; - function d3_interpolateNumber(a, b) { - a = +a, b = +b; - return function(t) { - return a * (1 - t) + b * t; - }; - } - d3.interpolateString = d3_interpolateString; - function d3_interpolateString(a, b) { - var bi = d3_interpolate_numberA.lastIndex = d3_interpolate_numberB.lastIndex = 0, am, bm, bs, i = -1, s = [], q = []; - a = a + "", b = b + ""; - while ((am = d3_interpolate_numberA.exec(a)) && (bm = d3_interpolate_numberB.exec(b))) { - if ((bs = bm.index) > bi) { - bs = b.slice(bi, bs); - if (s[i]) s[i] += bs; else s[++i] = bs; - } - if ((am = am[0]) === (bm = bm[0])) { - if (s[i]) s[i] += bm; else s[++i] = bm; - } else { - s[++i] = null; - q.push({ - i: i, - x: d3_interpolateNumber(am, bm) - }); - } - bi = d3_interpolate_numberB.lastIndex; - } - if (bi < b.length) { - bs = b.slice(bi); - if (s[i]) s[i] += bs; else s[++i] = bs; - } - return s.length < 2 ? q[0] ? (b = q[0].x, function(t) { - return b(t) + ""; - }) : function() { - return b; - } : (b = q.length, function(t) { - for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }); - } - var d3_interpolate_numberA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, d3_interpolate_numberB = new RegExp(d3_interpolate_numberA.source, "g"); - d3.interpolate = d3_interpolate; - function d3_interpolate(a, b) { - var i = d3.interpolators.length, f; - while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ; - return f; - } - d3.interpolators = [ function(a, b) { - var t = typeof b; - return (t === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_color ? d3_interpolateRgb : Array.isArray(b) ? d3_interpolateArray : t === "object" && isNaN(b) ? d3_interpolateObject : d3_interpolateNumber)(a, b); - } ]; - d3.interpolateArray = d3_interpolateArray; - function d3_interpolateArray(a, b) { - var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i; - for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i])); - for (;i < na; ++i) c[i] = a[i]; - for (;i < nb; ++i) c[i] = b[i]; - return function(t) { - for (i = 0; i < n0; ++i) c[i] = x[i](t); - return c; - }; - } - var d3_ease_default = function() { - return d3_identity; - }; - var d3_ease = d3.map({ - linear: d3_ease_default, - poly: d3_ease_poly, - quad: function() { - return d3_ease_quad; - }, - cubic: function() { - return d3_ease_cubic; - }, - sin: function() { - return d3_ease_sin; - }, - exp: function() { - return d3_ease_exp; - }, - circle: function() { - return d3_ease_circle; - }, - elastic: d3_ease_elastic, - back: d3_ease_back, - bounce: function() { - return d3_ease_bounce; - } - }); - var d3_ease_mode = d3.map({ - "in": d3_identity, - out: d3_ease_reverse, - "in-out": d3_ease_reflect, - "out-in": function(f) { - return d3_ease_reflect(d3_ease_reverse(f)); - } - }); - d3.ease = function(name) { - var i = name.indexOf("-"), t = i >= 0 ? name.slice(0, i) : name, m = i >= 0 ? name.slice(i + 1) : "in"; - t = d3_ease.get(t) || d3_ease_default; - m = d3_ease_mode.get(m) || d3_identity; - return d3_ease_clamp(m(t.apply(null, d3_arraySlice.call(arguments, 1)))); - }; - function d3_ease_clamp(f) { - return function(t) { - return t <= 0 ? 0 : t >= 1 ? 1 : f(t); - }; - } - function d3_ease_reverse(f) { - return function(t) { - return 1 - f(1 - t); - }; - } - function d3_ease_reflect(f) { - return function(t) { - return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t)); - }; - } - function d3_ease_quad(t) { - return t * t; - } - function d3_ease_cubic(t) { - return t * t * t; - } - function d3_ease_cubicInOut(t) { - if (t <= 0) return 0; - if (t >= 1) return 1; - var t2 = t * t, t3 = t2 * t; - return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); - } - function d3_ease_poly(e) { - return function(t) { - return Math.pow(t, e); - }; - } - function d3_ease_sin(t) { - return 1 - Math.cos(t * halfπ); - } - function d3_ease_exp(t) { - return Math.pow(2, 10 * (t - 1)); - } - function d3_ease_circle(t) { - return 1 - Math.sqrt(1 - t * t); - } - function d3_ease_elastic(a, p) { - var s; - if (arguments.length < 2) p = .45; - if (arguments.length) s = p / τ * Math.asin(1 / a); else a = 1, s = p / 4; - return function(t) { - return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * τ / p); - }; - } - function d3_ease_back(s) { - if (!s) s = 1.70158; - return function(t) { - return t * t * ((s + 1) * t - s); - }; - } - function d3_ease_bounce(t) { - return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; - } - d3.interpolateHcl = d3_interpolateHcl; - function d3_interpolateHcl(a, b) { - a = d3.hcl(a); - b = d3.hcl(b); - var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al; - if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; - return function(t) { - return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; - }; - } - d3.interpolateHsl = d3_interpolateHsl; - function d3_interpolateHsl(a, b) { - a = d3.hsl(a); - b = d3.hsl(b); - var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al; - if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; - return function(t) { - return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + ""; - }; - } - d3.interpolateLab = d3_interpolateLab; - function d3_interpolateLab(a, b) { - a = d3.lab(a); - b = d3.lab(b); - var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab; - return function(t) { - return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; - }; - } - d3.interpolateRound = d3_interpolateRound; - function d3_interpolateRound(a, b) { - b -= a; - return function(t) { - return Math.round(a + b * t); - }; - } - d3.transform = function(string) { - var g = d3_document.createElementNS(d3.ns.prefix.svg, "g"); - return (d3.transform = function(string) { - if (string != null) { - g.setAttribute("transform", string); - var t = g.transform.baseVal.consolidate(); - } - return new d3_transform(t ? t.matrix : d3_transformIdentity); - })(string); - }; - function d3_transform(m) { - var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; - if (r0[0] * r1[1] < r1[0] * r0[1]) { - r0[0] *= -1; - r0[1] *= -1; - kx *= -1; - kz *= -1; - } - this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; - this.translate = [ m.e, m.f ]; - this.scale = [ kx, ky ]; - this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; - } - d3_transform.prototype.toString = function() { - return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")"; - }; - function d3_transformDot(a, b) { - return a[0] * b[0] + a[1] * b[1]; - } - function d3_transformNormalize(a) { - var k = Math.sqrt(d3_transformDot(a, a)); - if (k) { - a[0] /= k; - a[1] /= k; - } - return k; - } - function d3_transformCombine(a, b, k) { - a[0] += k * b[0]; - a[1] += k * b[1]; - return a; - } - var d3_transformIdentity = { - a: 1, - b: 0, - c: 0, - d: 1, - e: 0, - f: 0 - }; - d3.interpolateTransform = d3_interpolateTransform; - function d3_interpolateTransform(a, b) { - var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale; - if (ta[0] != tb[0] || ta[1] != tb[1]) { - s.push("translate(", null, ",", null, ")"); - q.push({ - i: 1, - x: d3_interpolateNumber(ta[0], tb[0]) - }, { - i: 3, - x: d3_interpolateNumber(ta[1], tb[1]) - }); - } else if (tb[0] || tb[1]) { - s.push("translate(" + tb + ")"); - } else { - s.push(""); - } - if (ra != rb) { - if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; - q.push({ - i: s.push(s.pop() + "rotate(", null, ")") - 2, - x: d3_interpolateNumber(ra, rb) - }); - } else if (rb) { - s.push(s.pop() + "rotate(" + rb + ")"); - } - if (wa != wb) { - q.push({ - i: s.push(s.pop() + "skewX(", null, ")") - 2, - x: d3_interpolateNumber(wa, wb) - }); - } else if (wb) { - s.push(s.pop() + "skewX(" + wb + ")"); - } - if (ka[0] != kb[0] || ka[1] != kb[1]) { - n = s.push(s.pop() + "scale(", null, ",", null, ")"); - q.push({ - i: n - 4, - x: d3_interpolateNumber(ka[0], kb[0]) - }, { - i: n - 2, - x: d3_interpolateNumber(ka[1], kb[1]) - }); - } else if (kb[0] != 1 || kb[1] != 1) { - s.push(s.pop() + "scale(" + kb + ")"); - } - n = q.length; - return function(t) { - var i = -1, o; - while (++i < n) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - } - function d3_uninterpolateNumber(a, b) { - b = (b -= a = +a) || 1 / b; - return function(x) { - return (x - a) / b; - }; - } - function d3_uninterpolateClamp(a, b) { - b = (b -= a = +a) || 1 / b; - return function(x) { - return Math.max(0, Math.min(1, (x - a) / b)); - }; - } - d3.layout = {}; - d3.layout.bundle = function() { - return function(links) { - var paths = [], i = -1, n = links.length; - while (++i < n) paths.push(d3_layout_bundlePath(links[i])); - return paths; - }; - }; - function d3_layout_bundlePath(link) { - var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ]; - while (start !== lca) { - start = start.parent; - points.push(start); - } - var k = points.length; - while (end !== lca) { - points.splice(k, 0, end); - end = end.parent; - } - return points; - } - function d3_layout_bundleAncestors(node) { - var ancestors = [], parent = node.parent; - while (parent != null) { - ancestors.push(node); - node = parent; - parent = parent.parent; - } - ancestors.push(node); - return ancestors; - } - function d3_layout_bundleLeastCommonAncestor(a, b) { - if (a === b) return a; - var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null; - while (aNode === bNode) { - sharedNode = aNode; - aNode = aNodes.pop(); - bNode = bNodes.pop(); - } - return sharedNode; - } - d3.layout.chord = function() { - var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; - function relayout() { - var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; - chords = []; - groups = []; - k = 0, i = -1; - while (++i < n) { - x = 0, j = -1; - while (++j < n) { - x += matrix[i][j]; - } - groupSums.push(x); - subgroupIndex.push(d3.range(n)); - k += x; - } - if (sortGroups) { - groupIndex.sort(function(a, b) { - return sortGroups(groupSums[a], groupSums[b]); - }); - } - if (sortSubgroups) { - subgroupIndex.forEach(function(d, i) { - d.sort(function(a, b) { - return sortSubgroups(matrix[i][a], matrix[i][b]); - }); - }); - } - k = (τ - padding * n) / k; - x = 0, i = -1; - while (++i < n) { - x0 = x, j = -1; - while (++j < n) { - var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; - subgroups[di + "-" + dj] = { - index: di, - subindex: dj, - startAngle: a0, - endAngle: a1, - value: v - }; - } - groups[di] = { - index: di, - startAngle: x0, - endAngle: x, - value: (x - x0) / k - }; - x += padding; - } - i = -1; - while (++i < n) { - j = i - 1; - while (++j < n) { - var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; - if (source.value || target.value) { - chords.push(source.value < target.value ? { - source: target, - target: source - } : { - source: source, - target: target - }); - } - } - } - if (sortChords) resort(); - } - function resort() { - chords.sort(function(a, b) { - return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); - }); - } - chord.matrix = function(x) { - if (!arguments.length) return matrix; - n = (matrix = x) && matrix.length; - chords = groups = null; - return chord; - }; - chord.padding = function(x) { - if (!arguments.length) return padding; - padding = x; - chords = groups = null; - return chord; - }; - chord.sortGroups = function(x) { - if (!arguments.length) return sortGroups; - sortGroups = x; - chords = groups = null; - return chord; - }; - chord.sortSubgroups = function(x) { - if (!arguments.length) return sortSubgroups; - sortSubgroups = x; - chords = null; - return chord; - }; - chord.sortChords = function(x) { - if (!arguments.length) return sortChords; - sortChords = x; - if (chords) resort(); - return chord; - }; - chord.chords = function() { - if (!chords) relayout(); - return chords; - }; - chord.groups = function() { - if (!groups) relayout(); - return groups; - }; - return chord; - }; - d3.layout.force = function() { - var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges; - function repulse(node) { - return function(quad, x1, _, x2) { - if (quad.point !== node) { - var dx = quad.cx - node.x, dy = quad.cy - node.y, dw = x2 - x1, dn = dx * dx + dy * dy; - if (dw * dw / theta2 < dn) { - if (dn < chargeDistance2) { - var k = quad.charge / dn; - node.px -= dx * k; - node.py -= dy * k; - } - return true; - } - if (quad.point && dn && dn < chargeDistance2) { - var k = quad.pointCharge / dn; - node.px -= dx * k; - node.py -= dy * k; - } - } - return !quad.charge; - }; - } - force.tick = function() { - if ((alpha *= .99) < .005) { - event.end({ - type: "end", - alpha: alpha = 0 - }); - return true; - } - var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y; - for (i = 0; i < m; ++i) { - o = links[i]; - s = o.source; - t = o.target; - x = t.x - s.x; - y = t.y - s.y; - if (l = x * x + y * y) { - l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; - x *= l; - y *= l; - t.x -= x * (k = s.weight / (t.weight + s.weight)); - t.y -= y * k; - s.x += x * (k = 1 - k); - s.y += y * k; - } - } - if (k = alpha * gravity) { - x = size[0] / 2; - y = size[1] / 2; - i = -1; - if (k) while (++i < n) { - o = nodes[i]; - o.x += (x - o.x) * k; - o.y += (y - o.y) * k; - } - } - if (charge) { - d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); - i = -1; - while (++i < n) { - if (!(o = nodes[i]).fixed) { - q.visit(repulse(o)); - } - } - } - i = -1; - while (++i < n) { - o = nodes[i]; - if (o.fixed) { - o.x = o.px; - o.y = o.py; - } else { - o.x -= (o.px - (o.px = o.x)) * friction; - o.y -= (o.py - (o.py = o.y)) * friction; - } - } - event.tick({ - type: "tick", - alpha: alpha - }); - }; - force.nodes = function(x) { - if (!arguments.length) return nodes; - nodes = x; - return force; - }; - force.links = function(x) { - if (!arguments.length) return links; - links = x; - return force; - }; - force.size = function(x) { - if (!arguments.length) return size; - size = x; - return force; - }; - force.linkDistance = function(x) { - if (!arguments.length) return linkDistance; - linkDistance = typeof x === "function" ? x : +x; - return force; - }; - force.distance = force.linkDistance; - force.linkStrength = function(x) { - if (!arguments.length) return linkStrength; - linkStrength = typeof x === "function" ? x : +x; - return force; - }; - force.friction = function(x) { - if (!arguments.length) return friction; - friction = +x; - return force; - }; - force.charge = function(x) { - if (!arguments.length) return charge; - charge = typeof x === "function" ? x : +x; - return force; - }; - force.chargeDistance = function(x) { - if (!arguments.length) return Math.sqrt(chargeDistance2); - chargeDistance2 = x * x; - return force; - }; - force.gravity = function(x) { - if (!arguments.length) return gravity; - gravity = +x; - return force; - }; - force.theta = function(x) { - if (!arguments.length) return Math.sqrt(theta2); - theta2 = x * x; - return force; - }; - force.alpha = function(x) { - if (!arguments.length) return alpha; - x = +x; - if (alpha) { - if (x > 0) alpha = x; else alpha = 0; - } else if (x > 0) { - event.start({ - type: "start", - alpha: alpha = x - }); - d3.timer(force.tick); - } - return force; - }; - force.start = function() { - var i, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o; - for (i = 0; i < n; ++i) { - (o = nodes[i]).index = i; - o.weight = 0; - } - for (i = 0; i < m; ++i) { - o = links[i]; - if (typeof o.source == "number") o.source = nodes[o.source]; - if (typeof o.target == "number") o.target = nodes[o.target]; - ++o.source.weight; - ++o.target.weight; - } - for (i = 0; i < n; ++i) { - o = nodes[i]; - if (isNaN(o.x)) o.x = position("x", w); - if (isNaN(o.y)) o.y = position("y", h); - if (isNaN(o.px)) o.px = o.x; - if (isNaN(o.py)) o.py = o.y; - } - distances = []; - if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance; - strengths = []; - if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength; - charges = []; - if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge; - function position(dimension, size) { - if (!neighbors) { - neighbors = new Array(n); - for (j = 0; j < n; ++j) { - neighbors[j] = []; - } - for (j = 0; j < m; ++j) { - var o = links[j]; - neighbors[o.source.index].push(o.target); - neighbors[o.target.index].push(o.source); - } - } - var candidates = neighbors[i], j = -1, m = candidates.length, x; - while (++j < m) if (!isNaN(x = candidates[j][dimension])) return x; - return Math.random() * size; - } - return force.resume(); - }; - force.resume = function() { - return force.alpha(.1); - }; - force.stop = function() { - return force.alpha(0); - }; - force.drag = function() { - if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend); - if (!arguments.length) return drag; - this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag); - }; - function dragmove(d) { - d.px = d3.event.x, d.py = d3.event.y; - force.resume(); - } - return d3.rebind(force, event, "on"); - }; - function d3_layout_forceDragstart(d) { - d.fixed |= 2; - } - function d3_layout_forceDragend(d) { - d.fixed &= ~6; - } - function d3_layout_forceMouseover(d) { - d.fixed |= 4; - d.px = d.x, d.py = d.y; - } - function d3_layout_forceMouseout(d) { - d.fixed &= ~4; - } - function d3_layout_forceAccumulate(quad, alpha, charges) { - var cx = 0, cy = 0; - quad.charge = 0; - if (!quad.leaf) { - var nodes = quad.nodes, n = nodes.length, i = -1, c; - while (++i < n) { - c = nodes[i]; - if (c == null) continue; - d3_layout_forceAccumulate(c, alpha, charges); - quad.charge += c.charge; - cx += c.charge * c.cx; - cy += c.charge * c.cy; - } - } - if (quad.point) { - if (!quad.leaf) { - quad.point.x += Math.random() - .5; - quad.point.y += Math.random() - .5; - } - var k = alpha * charges[quad.point.index]; - quad.charge += quad.pointCharge = k; - cx += k * quad.point.x; - cy += k * quad.point.y; - } - quad.cx = cx / quad.charge; - quad.cy = cy / quad.charge; - } - var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1, d3_layout_forceChargeDistance2 = Infinity; - d3.layout.hierarchy = function() { - var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue; - function hierarchy(root) { - var stack = [ root ], nodes = [], node; - root.depth = 0; - while ((node = stack.pop()) != null) { - nodes.push(node); - if ((childs = children.call(hierarchy, node, node.depth)) && (n = childs.length)) { - var n, childs, child; - while (--n >= 0) { - stack.push(child = childs[n]); - child.parent = node; - child.depth = node.depth + 1; - } - if (value) node.value = 0; - node.children = childs; - } else { - if (value) node.value = +value.call(hierarchy, node, node.depth) || 0; - delete node.children; - } - } - d3_layout_hierarchyVisitAfter(root, function(node) { - var childs, parent; - if (sort && (childs = node.children)) childs.sort(sort); - if (value && (parent = node.parent)) parent.value += node.value; - }); - return nodes; - } - hierarchy.sort = function(x) { - if (!arguments.length) return sort; - sort = x; - return hierarchy; - }; - hierarchy.children = function(x) { - if (!arguments.length) return children; - children = x; - return hierarchy; - }; - hierarchy.value = function(x) { - if (!arguments.length) return value; - value = x; - return hierarchy; - }; - hierarchy.revalue = function(root) { - if (value) { - d3_layout_hierarchyVisitBefore(root, function(node) { - if (node.children) node.value = 0; - }); - d3_layout_hierarchyVisitAfter(root, function(node) { - var parent; - if (!node.children) node.value = +value.call(hierarchy, node, node.depth) || 0; - if (parent = node.parent) parent.value += node.value; - }); - } - return root; - }; - return hierarchy; - }; - function d3_layout_hierarchyRebind(object, hierarchy) { - d3.rebind(object, hierarchy, "sort", "children", "value"); - object.nodes = object; - object.links = d3_layout_hierarchyLinks; - return object; - } - function d3_layout_hierarchyVisitBefore(node, callback) { - var nodes = [ node ]; - while ((node = nodes.pop()) != null) { - callback(node); - if ((children = node.children) && (n = children.length)) { - var n, children; - while (--n >= 0) nodes.push(children[n]); - } - } - } - function d3_layout_hierarchyVisitAfter(node, callback) { - var nodes = [ node ], nodes2 = []; - while ((node = nodes.pop()) != null) { - nodes2.push(node); - if ((children = node.children) && (n = children.length)) { - var i = -1, n, children; - while (++i < n) nodes.push(children[i]); - } - } - while ((node = nodes2.pop()) != null) { - callback(node); - } - } - function d3_layout_hierarchyChildren(d) { - return d.children; - } - function d3_layout_hierarchyValue(d) { - return d.value; - } - function d3_layout_hierarchySort(a, b) { - return b.value - a.value; - } - function d3_layout_hierarchyLinks(nodes) { - return d3.merge(nodes.map(function(parent) { - return (parent.children || []).map(function(child) { - return { - source: parent, - target: child - }; - }); - })); - } - d3.layout.partition = function() { - var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ]; - function position(node, x, dx, dy) { - var children = node.children; - node.x = x; - node.y = node.depth * dy; - node.dx = dx; - node.dy = dy; - if (children && (n = children.length)) { - var i = -1, n, c, d; - dx = node.value ? dx / node.value : 0; - while (++i < n) { - position(c = children[i], x, d = c.value * dx, dy); - x += d; - } - } - } - function depth(node) { - var children = node.children, d = 0; - if (children && (n = children.length)) { - var i = -1, n; - while (++i < n) d = Math.max(d, depth(children[i])); - } - return 1 + d; - } - function partition(d, i) { - var nodes = hierarchy.call(this, d, i); - position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); - return nodes; - } - partition.size = function(x) { - if (!arguments.length) return size; - size = x; - return partition; - }; - return d3_layout_hierarchyRebind(partition, hierarchy); - }; - d3.layout.pie = function() { - var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = τ, padAngle = 0; - function pie(data) { - var n = data.length, values = data.map(function(d, i) { - return +value.call(pie, d, i); - }), a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle), da = (typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a, p = Math.min(Math.abs(da) / n, +(typeof padAngle === "function" ? padAngle.apply(this, arguments) : padAngle)), pa = p * (da < 0 ? -1 : 1), k = (da - n * pa) / d3.sum(values), index = d3.range(n), arcs = [], v; - if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) { - return values[j] - values[i]; - } : function(i, j) { - return sort(data[i], data[j]); - }); - index.forEach(function(i) { - arcs[i] = { - data: data[i], - value: v = values[i], - startAngle: a, - endAngle: a += v * k + pa, - padAngle: p - }; - }); - return arcs; - } - pie.value = function(_) { - if (!arguments.length) return value; - value = _; - return pie; - }; - pie.sort = function(_) { - if (!arguments.length) return sort; - sort = _; - return pie; - }; - pie.startAngle = function(_) { - if (!arguments.length) return startAngle; - startAngle = _; - return pie; - }; - pie.endAngle = function(_) { - if (!arguments.length) return endAngle; - endAngle = _; - return pie; - }; - pie.padAngle = function(_) { - if (!arguments.length) return padAngle; - padAngle = _; - return pie; - }; - return pie; - }; - var d3_layout_pieSortByValue = {}; - d3.layout.stack = function() { - var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY; - function stack(data, index) { - if (!(n = data.length)) return data; - var series = data.map(function(d, i) { - return values.call(stack, d, i); - }); - var points = series.map(function(d) { - return d.map(function(v, i) { - return [ x.call(stack, v, i), y.call(stack, v, i) ]; - }); - }); - var orders = order.call(stack, points, index); - series = d3.permute(series, orders); - points = d3.permute(points, orders); - var offsets = offset.call(stack, points, index); - var m = series[0].length, n, i, j, o; - for (j = 0; j < m; ++j) { - out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); - for (i = 1; i < n; ++i) { - out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); - } - } - return data; - } - stack.values = function(x) { - if (!arguments.length) return values; - values = x; - return stack; - }; - stack.order = function(x) { - if (!arguments.length) return order; - order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; - return stack; - }; - stack.offset = function(x) { - if (!arguments.length) return offset; - offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; - return stack; - }; - stack.x = function(z) { - if (!arguments.length) return x; - x = z; - return stack; - }; - stack.y = function(z) { - if (!arguments.length) return y; - y = z; - return stack; - }; - stack.out = function(z) { - if (!arguments.length) return out; - out = z; - return stack; - }; - return stack; - }; - function d3_layout_stackX(d) { - return d.x; - } - function d3_layout_stackY(d) { - return d.y; - } - function d3_layout_stackOut(d, y0, y) { - d.y0 = y0; - d.y = y; - } - var d3_layout_stackOrders = d3.map({ - "inside-out": function(data) { - var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) { - return max[a] - max[b]; - }), top = 0, bottom = 0, tops = [], bottoms = []; - for (i = 0; i < n; ++i) { - j = index[i]; - if (top < bottom) { - top += sums[j]; - tops.push(j); - } else { - bottom += sums[j]; - bottoms.push(j); - } - } - return bottoms.reverse().concat(tops); - }, - reverse: function(data) { - return d3.range(data.length).reverse(); - }, - "default": d3_layout_stackOrderDefault - }); - var d3_layout_stackOffsets = d3.map({ - silhouette: function(data) { - var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o > max) max = o; - sums.push(o); - } - for (j = 0; j < m; ++j) { - y0[j] = (max - sums[j]) / 2; - } - return y0; - }, - wiggle: function(data) { - var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = []; - y0[0] = o = o0 = 0; - for (j = 1; j < m; ++j) { - for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; - for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { - for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { - s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; - } - s2 += s3 * data[i][j][1]; - } - y0[j] = o -= s1 ? s2 / s1 * dx : 0; - if (o < o0) o0 = o; - } - for (j = 0; j < m; ++j) y0[j] -= o0; - return y0; - }, - expand: function(data) { - var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k; - } - for (j = 0; j < m; ++j) y0[j] = 0; - return y0; - }, - zero: d3_layout_stackOffsetZero - }); - function d3_layout_stackOrderDefault(data) { - return d3.range(data.length); - } - function d3_layout_stackOffsetZero(data) { - var j = -1, m = data[0].length, y0 = []; - while (++j < m) y0[j] = 0; - return y0; - } - function d3_layout_stackMaxIndex(array) { - var i = 1, j = 0, v = array[0][1], k, n = array.length; - for (;i < n; ++i) { - if ((k = array[i][1]) > v) { - j = i; - v = k; - } - } - return j; - } - function d3_layout_stackReduceSum(d) { - return d.reduce(d3_layout_stackSum, 0); - } - function d3_layout_stackSum(p, d) { - return p + d[1]; - } - d3.layout.histogram = function() { - var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges; - function histogram(data, i) { - var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x; - while (++i < m) { - bin = bins[i] = []; - bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); - bin.y = 0; - } - if (m > 0) { - i = -1; - while (++i < n) { - x = values[i]; - if (x >= range[0] && x <= range[1]) { - bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; - bin.y += k; - bin.push(data[i]); - } - } - } - return bins; - } - histogram.value = function(x) { - if (!arguments.length) return valuer; - valuer = x; - return histogram; - }; - histogram.range = function(x) { - if (!arguments.length) return ranger; - ranger = d3_functor(x); - return histogram; - }; - histogram.bins = function(x) { - if (!arguments.length) return binner; - binner = typeof x === "number" ? function(range) { - return d3_layout_histogramBinFixed(range, x); - } : d3_functor(x); - return histogram; - }; - histogram.frequency = function(x) { - if (!arguments.length) return frequency; - frequency = !!x; - return histogram; - }; - return histogram; - }; - function d3_layout_histogramBinSturges(range, values) { - return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); - } - function d3_layout_histogramBinFixed(range, n) { - var x = -1, b = +range[0], m = (range[1] - b) / n, f = []; - while (++x <= n) f[x] = m * x + b; - return f; - } - function d3_layout_histogramRange(values) { - return [ d3.min(values), d3.max(values) ]; - } - d3.layout.pack = function() { - var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius; - function pack(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() { - return radius; - }; - root.x = root.y = 0; - d3_layout_hierarchyVisitAfter(root, function(d) { - d.r = +r(d.value); - }); - d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings); - if (padding) { - var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2; - d3_layout_hierarchyVisitAfter(root, function(d) { - d.r += dr; - }); - d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings); - d3_layout_hierarchyVisitAfter(root, function(d) { - d.r -= dr; - }); - } - d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h)); - return nodes; - } - pack.size = function(_) { - if (!arguments.length) return size; - size = _; - return pack; - }; - pack.radius = function(_) { - if (!arguments.length) return radius; - radius = _ == null || typeof _ === "function" ? _ : +_; - return pack; - }; - pack.padding = function(_) { - if (!arguments.length) return padding; - padding = +_; - return pack; - }; - return d3_layout_hierarchyRebind(pack, hierarchy); - }; - function d3_layout_packSort(a, b) { - return a.value - b.value; - } - function d3_layout_packInsert(a, b) { - var c = a._pack_next; - a._pack_next = b; - b._pack_prev = a; - b._pack_next = c; - c._pack_prev = b; - } - function d3_layout_packSplice(a, b) { - a._pack_next = b; - b._pack_prev = a; - } - function d3_layout_packIntersects(a, b) { - var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; - return .999 * dr * dr > dx * dx + dy * dy; - } - function d3_layout_packSiblings(node) { - if (!(nodes = node.children) || !(n = nodes.length)) return; - var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n; - function bound(node) { - xMin = Math.min(node.x - node.r, xMin); - xMax = Math.max(node.x + node.r, xMax); - yMin = Math.min(node.y - node.r, yMin); - yMax = Math.max(node.y + node.r, yMax); - } - nodes.forEach(d3_layout_packLink); - a = nodes[0]; - a.x = -a.r; - a.y = 0; - bound(a); - if (n > 1) { - b = nodes[1]; - b.x = b.r; - b.y = 0; - bound(b); - if (n > 2) { - c = nodes[2]; - d3_layout_packPlace(a, b, c); - bound(c); - d3_layout_packInsert(a, c); - a._pack_prev = c; - d3_layout_packInsert(c, b); - b = a._pack_next; - for (i = 3; i < n; i++) { - d3_layout_packPlace(a, b, c = nodes[i]); - var isect = 0, s1 = 1, s2 = 1; - for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { - if (d3_layout_packIntersects(j, c)) { - isect = 1; - break; - } - } - if (isect == 1) { - for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { - if (d3_layout_packIntersects(k, c)) { - break; - } - } - } - if (isect) { - if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b); - i--; - } else { - d3_layout_packInsert(a, c); - b = c; - bound(c); - } - } - } - } - var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0; - for (i = 0; i < n; i++) { - c = nodes[i]; - c.x -= cx; - c.y -= cy; - cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); - } - node.r = cr; - nodes.forEach(d3_layout_packUnlink); - } - function d3_layout_packLink(node) { - node._pack_next = node._pack_prev = node; - } - function d3_layout_packUnlink(node) { - delete node._pack_next; - delete node._pack_prev; - } - function d3_layout_packTransform(node, x, y, k) { - var children = node.children; - node.x = x += k * node.x; - node.y = y += k * node.y; - node.r *= k; - if (children) { - var i = -1, n = children.length; - while (++i < n) d3_layout_packTransform(children[i], x, y, k); - } - } - function d3_layout_packPlace(a, b, c) { - var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y; - if (db && (dx || dy)) { - var da = b.r + c.r, dc = dx * dx + dy * dy; - da *= da; - db *= db; - var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); - c.x = a.x + x * dx + y * dy; - c.y = a.y + x * dy - y * dx; - } else { - c.x = a.x + db; - c.y = a.y; - } - } - d3.layout.tree = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = null; - function tree(d, i) { - var nodes = hierarchy.call(this, d, i), root0 = nodes[0], root1 = wrapTree(root0); - d3_layout_hierarchyVisitAfter(root1, firstWalk), root1.parent.m = -root1.z; - d3_layout_hierarchyVisitBefore(root1, secondWalk); - if (nodeSize) d3_layout_hierarchyVisitBefore(root0, sizeNode); else { - var left = root0, right = root0, bottom = root0; - d3_layout_hierarchyVisitBefore(root0, function(node) { - if (node.x < left.x) left = node; - if (node.x > right.x) right = node; - if (node.depth > bottom.depth) bottom = node; - }); - var tx = separation(left, right) / 2 - left.x, kx = size[0] / (right.x + separation(right, left) / 2 + tx), ky = size[1] / (bottom.depth || 1); - d3_layout_hierarchyVisitBefore(root0, function(node) { - node.x = (node.x + tx) * kx; - node.y = node.depth * ky; - }); - } - return nodes; - } - function wrapTree(root0) { - var root1 = { - A: null, - children: [ root0 ] - }, queue = [ root1 ], node1; - while ((node1 = queue.pop()) != null) { - for (var children = node1.children, child, i = 0, n = children.length; i < n; ++i) { - queue.push((children[i] = child = { - _: children[i], - parent: node1, - children: (child = children[i].children) && child.slice() || [], - A: null, - a: null, - z: 0, - m: 0, - c: 0, - s: 0, - t: null, - i: i - }).a = child); - } - } - return root1.children[0]; - } - function firstWalk(v) { - var children = v.children, siblings = v.parent.children, w = v.i ? siblings[v.i - 1] : null; - if (children.length) { - d3_layout_treeShift(v); - var midpoint = (children[0].z + children[children.length - 1].z) / 2; - if (w) { - v.z = w.z + separation(v._, w._); - v.m = v.z - midpoint; - } else { - v.z = midpoint; - } - } else if (w) { - v.z = w.z + separation(v._, w._); - } - v.parent.A = apportion(v, w, v.parent.A || siblings[0]); - } - function secondWalk(v) { - v._.x = v.z + v.parent.m; - v.m += v.parent.m; - } - function apportion(v, w, ancestor) { - if (w) { - var vip = v, vop = v, vim = w, vom = vip.parent.children[0], sip = vip.m, sop = vop.m, sim = vim.m, som = vom.m, shift; - while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { - vom = d3_layout_treeLeft(vom); - vop = d3_layout_treeRight(vop); - vop.a = v; - shift = vim.z + sim - vip.z - sip + separation(vim._, vip._); - if (shift > 0) { - d3_layout_treeMove(d3_layout_treeAncestor(vim, v, ancestor), v, shift); - sip += shift; - sop += shift; - } - sim += vim.m; - sip += vip.m; - som += vom.m; - sop += vop.m; - } - if (vim && !d3_layout_treeRight(vop)) { - vop.t = vim; - vop.m += sim - sop; - } - if (vip && !d3_layout_treeLeft(vom)) { - vom.t = vip; - vom.m += sip - som; - ancestor = v; - } - } - return ancestor; - } - function sizeNode(node) { - node.x *= size[0]; - node.y = node.depth * size[1]; - } - tree.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return tree; - }; - tree.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null ? sizeNode : null; - return tree; - }; - tree.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) == null ? null : sizeNode; - return tree; - }; - return d3_layout_hierarchyRebind(tree, hierarchy); - }; - function d3_layout_treeSeparation(a, b) { - return a.parent == b.parent ? 1 : 2; - } - function d3_layout_treeLeft(v) { - var children = v.children; - return children.length ? children[0] : v.t; - } - function d3_layout_treeRight(v) { - var children = v.children, n; - return (n = children.length) ? children[n - 1] : v.t; - } - function d3_layout_treeMove(wm, wp, shift) { - var change = shift / (wp.i - wm.i); - wp.c -= change; - wp.s += shift; - wm.c += change; - wp.z += shift; - wp.m += shift; - } - function d3_layout_treeShift(v) { - var shift = 0, change = 0, children = v.children, i = children.length, w; - while (--i >= 0) { - w = children[i]; - w.z += shift; - w.m += shift; - shift += w.s + (change += w.c); - } - } - function d3_layout_treeAncestor(vim, v, ancestor) { - return vim.a.parent === v.parent ? vim.a : ancestor; - } - d3.layout.cluster = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; - function cluster(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0; - d3_layout_hierarchyVisitAfter(root, function(node) { - var children = node.children; - if (children && children.length) { - node.x = d3_layout_clusterX(children); - node.y = d3_layout_clusterY(children); - } else { - node.x = previousNode ? x += separation(node, previousNode) : 0; - node.y = 0; - previousNode = node; - } - }); - var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; - d3_layout_hierarchyVisitAfter(root, nodeSize ? function(node) { - node.x = (node.x - root.x) * size[0]; - node.y = (root.y - node.y) * size[1]; - } : function(node) { - node.x = (node.x - x0) / (x1 - x0) * size[0]; - node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; - }); - return nodes; - } - cluster.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return cluster; - }; - cluster.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null; - return cluster; - }; - cluster.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) != null; - return cluster; - }; - return d3_layout_hierarchyRebind(cluster, hierarchy); - }; - function d3_layout_clusterY(children) { - return 1 + d3.max(children, function(child) { - return child.y; - }); - } - function d3_layout_clusterX(children) { - return children.reduce(function(x, child) { - return x + child.x; - }, 0) / children.length; - } - function d3_layout_clusterLeft(node) { - var children = node.children; - return children && children.length ? d3_layout_clusterLeft(children[0]) : node; - } - function d3_layout_clusterRight(node) { - var children = node.children, n; - return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; - } - d3.layout.treemap = function() { - var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5)); - function scale(children, k) { - var i = -1, n = children.length, child, area; - while (++i < n) { - area = (child = children[i]).value * (k < 0 ? 0 : k); - child.area = isNaN(area) || area <= 0 ? 0 : area; - } - } - function squarify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while ((n = remaining.length) > 0) { - row.push(child = remaining[n - 1]); - row.area += child.area; - if (mode !== "squarify" || (score = worst(row, u)) <= best) { - remaining.pop(); - best = score; - } else { - row.area -= row.pop().area; - position(row, u, rect, false); - u = Math.min(rect.dx, rect.dy); - row.length = row.area = 0; - best = Infinity; - } - } - if (row.length) { - position(row, u, rect, true); - row.length = row.area = 0; - } - children.forEach(squarify); - } - } - function stickify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), remaining = children.slice(), child, row = []; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while (child = remaining.pop()) { - row.push(child); - row.area += child.area; - if (child.z != null) { - position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); - row.length = row.area = 0; - } - } - children.forEach(stickify); - } - } - function worst(row, u) { - var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length; - while (++i < n) { - if (!(r = row[i].area)) continue; - if (r < rmin) rmin = r; - if (r > rmax) rmax = r; - } - s *= s; - u *= u; - return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity; - } - function position(row, u, rect, flush) { - var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o; - if (u == rect.dx) { - if (flush || v > rect.dy) v = rect.dy; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dy = v; - x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); - } - o.z = true; - o.dx += rect.x + rect.dx - x; - rect.y += v; - rect.dy -= v; - } else { - if (flush || v > rect.dx) v = rect.dx; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dx = v; - y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); - } - o.z = false; - o.dy += rect.y + rect.dy - y; - rect.x += v; - rect.dx -= v; - } - } - function treemap(d) { - var nodes = stickies || hierarchy(d), root = nodes[0]; - root.x = 0; - root.y = 0; - root.dx = size[0]; - root.dy = size[1]; - if (stickies) hierarchy.revalue(root); - scale([ root ], root.dx * root.dy / root.value); - (stickies ? stickify : squarify)(root); - if (sticky) stickies = nodes; - return nodes; - } - treemap.size = function(x) { - if (!arguments.length) return size; - size = x; - return treemap; - }; - treemap.padding = function(x) { - if (!arguments.length) return padding; - function padFunction(node) { - var p = x.call(treemap, node, node.depth); - return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p); - } - function padConstant(node) { - return d3_layout_treemapPad(node, x); - } - var type; - pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], - padConstant) : padConstant; - return treemap; - }; - treemap.round = function(x) { - if (!arguments.length) return round != Number; - round = x ? Math.round : Number; - return treemap; - }; - treemap.sticky = function(x) { - if (!arguments.length) return sticky; - sticky = x; - stickies = null; - return treemap; - }; - treemap.ratio = function(x) { - if (!arguments.length) return ratio; - ratio = x; - return treemap; - }; - treemap.mode = function(x) { - if (!arguments.length) return mode; - mode = x + ""; - return treemap; - }; - return d3_layout_hierarchyRebind(treemap, hierarchy); - }; - function d3_layout_treemapPadNull(node) { - return { - x: node.x, - y: node.y, - dx: node.dx, - dy: node.dy - }; - } - function d3_layout_treemapPad(node, padding) { - var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2]; - if (dx < 0) { - x += dx / 2; - dx = 0; - } - if (dy < 0) { - y += dy / 2; - dy = 0; - } - return { - x: x, - y: y, - dx: dx, - dy: dy - }; - } - d3.random = { - normal: function(µ, σ) { - var n = arguments.length; - if (n < 2) σ = 1; - if (n < 1) µ = 0; - return function() { - var x, y, r; - do { - x = Math.random() * 2 - 1; - y = Math.random() * 2 - 1; - r = x * x + y * y; - } while (!r || r > 1); - return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r); - }; - }, - logNormal: function() { - var random = d3.random.normal.apply(d3, arguments); - return function() { - return Math.exp(random()); - }; - }, - bates: function(m) { - var random = d3.random.irwinHall(m); - return function() { - return random() / m; - }; - }, - irwinHall: function(m) { - return function() { - for (var s = 0, j = 0; j < m; j++) s += Math.random(); - return s; - }; - } - }; - d3.scale = {}; - function d3_scaleExtent(domain) { - var start = domain[0], stop = domain[domain.length - 1]; - return start < stop ? [ start, stop ] : [ stop, start ]; - } - function d3_scaleRange(scale) { - return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); - } - function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { - var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]); - return function(x) { - return i(u(x)); - }; - } - function d3_scale_nice(domain, nice) { - var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx; - if (x1 < x0) { - dx = i0, i0 = i1, i1 = dx; - dx = x0, x0 = x1, x1 = dx; - } - domain[i0] = nice.floor(x0); - domain[i1] = nice.ceil(x1); - return domain; - } - function d3_scale_niceStep(step) { - return step ? { - floor: function(x) { - return Math.floor(x / step) * step; - }, - ceil: function(x) { - return Math.ceil(x / step) * step; - } - } : d3_scale_niceIdentity; - } - var d3_scale_niceIdentity = { - floor: d3_identity, - ceil: d3_identity - }; - function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { - var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1; - if (domain[k] < domain[0]) { - domain = domain.slice().reverse(); - range = range.slice().reverse(); - } - while (++j <= k) { - u.push(uninterpolate(domain[j - 1], domain[j])); - i.push(interpolate(range[j - 1], range[j])); - } - return function(x) { - var j = d3.bisect(domain, x, 1, k) - 1; - return i[j](u[j](x)); - }; - } - d3.scale.linear = function() { - return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false); - }; - function d3_scale_linear(domain, range, interpolate, clamp) { - var output, input; - function rescale() { - var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; - output = linear(domain, range, uninterpolate, interpolate); - input = linear(range, domain, uninterpolate, d3_interpolate); - return scale; - } - function scale(x) { - return output(x); - } - scale.invert = function(y) { - return input(y); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.map(Number); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.rangeRound = function(x) { - return scale.range(x).interpolate(d3_interpolateRound); - }; - scale.clamp = function(x) { - if (!arguments.length) return clamp; - clamp = x; - return rescale(); - }; - scale.interpolate = function(x) { - if (!arguments.length) return interpolate; - interpolate = x; - return rescale(); - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - scale.nice = function(m) { - d3_scale_linearNice(domain, m); - return rescale(); - }; - scale.copy = function() { - return d3_scale_linear(domain, range, interpolate, clamp); - }; - return rescale(); - } - function d3_scale_linearRebind(scale, linear) { - return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); - } - function d3_scale_linearNice(domain, m) { - return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2])); - } - function d3_scale_linearTickRange(domain, m) { - if (m == null) m = 10; - var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; - if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; - extent[0] = Math.ceil(extent[0] / step) * step; - extent[1] = Math.floor(extent[1] / step) * step + step * .5; - extent[2] = step; - return extent; - } - function d3_scale_linearTicks(domain, m) { - return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); - } - function d3_scale_linearTickFormat(domain, m, format) { - var range = d3_scale_linearTickRange(domain, m); - if (format) { - var match = d3_format_re.exec(format); - match.shift(); - if (match[8] === "s") { - var prefix = d3.formatPrefix(Math.max(abs(range[0]), abs(range[1]))); - if (!match[7]) match[7] = "." + d3_scale_linearPrecision(prefix.scale(range[2])); - match[8] = "f"; - format = d3.format(match.join("")); - return function(d) { - return format(prefix.scale(d)) + prefix.symbol; - }; - } - if (!match[7]) match[7] = "." + d3_scale_linearFormatPrecision(match[8], range); - format = match.join(""); - } else { - format = ",." + d3_scale_linearPrecision(range[2]) + "f"; - } - return d3.format(format); - } - var d3_scale_linearFormatSignificant = { - s: 1, - g: 1, - p: 1, - r: 1, - e: 1 - }; - function d3_scale_linearPrecision(value) { - return -Math.floor(Math.log(value) / Math.LN10 + .01); - } - function d3_scale_linearFormatPrecision(type, range) { - var p = d3_scale_linearPrecision(range[2]); - return type in d3_scale_linearFormatSignificant ? Math.abs(p - d3_scale_linearPrecision(Math.max(abs(range[0]), abs(range[1])))) + +(type !== "e") : p - (type === "%") * 2; - } - d3.scale.log = function() { - return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]); - }; - function d3_scale_log(linear, base, positive, domain) { - function log(x) { - return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base); - } - function pow(x) { - return positive ? Math.pow(base, x) : -Math.pow(base, -x); - } - function scale(x) { - return linear(log(x)); - } - scale.invert = function(x) { - return pow(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - positive = x[0] >= 0; - linear.domain((domain = x.map(Number)).map(log)); - return scale; - }; - scale.base = function(_) { - if (!arguments.length) return base; - base = +_; - linear.domain(domain.map(log)); - return scale; - }; - scale.nice = function() { - var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative); - linear.domain(niced); - domain = niced.map(pow); - return scale; - }; - scale.ticks = function() { - var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base; - if (isFinite(j - i)) { - if (positive) { - for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k); - ticks.push(pow(i)); - } else { - ticks.push(pow(i)); - for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k); - } - for (i = 0; ticks[i] < u; i++) {} - for (j = ticks.length; ticks[j - 1] > v; j--) {} - ticks = ticks.slice(i, j); - } - return ticks; - }; - scale.tickFormat = function(n, format) { - if (!arguments.length) return d3_scale_logFormat; - if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format); - var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12, - Math.floor), e; - return function(d) { - return d / pow(f(log(d) + e)) <= k ? format(d) : ""; - }; - }; - scale.copy = function() { - return d3_scale_log(linear.copy(), base, positive, domain); - }; - return d3_scale_linearRebind(scale, linear); - } - var d3_scale_logFormat = d3.format(".0e"), d3_scale_logNiceNegative = { - floor: function(x) { - return -Math.ceil(-x); - }, - ceil: function(x) { - return -Math.floor(-x); - } - }; - d3.scale.pow = function() { - return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]); - }; - function d3_scale_pow(linear, exponent, domain) { - var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent); - function scale(x) { - return linear(powp(x)); - } - scale.invert = function(x) { - return powb(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - linear.domain((domain = x.map(Number)).map(powp)); - return scale; - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - scale.nice = function(m) { - return scale.domain(d3_scale_linearNice(domain, m)); - }; - scale.exponent = function(x) { - if (!arguments.length) return exponent; - powp = d3_scale_powPow(exponent = x); - powb = d3_scale_powPow(1 / exponent); - linear.domain(domain.map(powp)); - return scale; - }; - scale.copy = function() { - return d3_scale_pow(linear.copy(), exponent, domain); - }; - return d3_scale_linearRebind(scale, linear); - } - function d3_scale_powPow(e) { - return function(x) { - return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); - }; - } - d3.scale.sqrt = function() { - return d3.scale.pow().exponent(.5); - }; - d3.scale.ordinal = function() { - return d3_scale_ordinal([], { - t: "range", - a: [ [] ] - }); - }; - function d3_scale_ordinal(domain, ranger) { - var index, range, rangeBand; - function scale(x) { - return range[((index.get(x) || (ranger.t === "range" ? index.set(x, domain.push(x)) : NaN)) - 1) % range.length]; - } - function steps(start, step) { - return d3.range(domain.length).map(function(i) { - return start + step * i; - }); - } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = []; - index = new d3_Map(); - var i = -1, n = x.length, xi; - while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); - return scale[ranger.t].apply(scale, ranger.a); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - rangeBand = 0; - ranger = { - t: "range", - a: arguments - }; - return scale; - }; - scale.rangePoints = function(x, padding) { - if (arguments.length < 2) padding = 0; - var start = x[0], stop = x[1], step = domain.length < 2 ? (start = (start + stop) / 2, - 0) : (stop - start) / (domain.length - 1 + padding); - range = steps(start + step * padding / 2, step); - rangeBand = 0; - ranger = { - t: "rangePoints", - a: arguments - }; - return scale; - }; - scale.rangeRoundPoints = function(x, padding) { - if (arguments.length < 2) padding = 0; - var start = x[0], stop = x[1], step = domain.length < 2 ? (start = stop = Math.round((start + stop) / 2), - 0) : (stop - start) / (domain.length - 1 + padding) | 0; - range = steps(start + Math.round(step * padding / 2 + (stop - start - (domain.length - 1 + padding) * step) / 2), step); - rangeBand = 0; - ranger = { - t: "rangeRoundPoints", - a: arguments - }; - return scale; - }; - scale.rangeBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding); - range = steps(start + step * outerPadding, step); - if (reverse) range.reverse(); - rangeBand = step * (1 - padding); - ranger = { - t: "rangeBands", - a: arguments - }; - return scale; - }; - scale.rangeRoundBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)); - range = steps(start + Math.round((stop - start - (domain.length - padding) * step) / 2), step); - if (reverse) range.reverse(); - rangeBand = Math.round(step * (1 - padding)); - ranger = { - t: "rangeRoundBands", - a: arguments - }; - return scale; - }; - scale.rangeBand = function() { - return rangeBand; - }; - scale.rangeExtent = function() { - return d3_scaleExtent(ranger.a[0]); - }; - scale.copy = function() { - return d3_scale_ordinal(domain, ranger); - }; - return scale.domain(domain); - } - d3.scale.category10 = function() { - return d3.scale.ordinal().range(d3_category10); - }; - d3.scale.category20 = function() { - return d3.scale.ordinal().range(d3_category20); - }; - d3.scale.category20b = function() { - return d3.scale.ordinal().range(d3_category20b); - }; - d3.scale.category20c = function() { - return d3.scale.ordinal().range(d3_category20c); - }; - var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString); - var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString); - var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString); - var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString); - d3.scale.quantile = function() { - return d3_scale_quantile([], []); - }; - function d3_scale_quantile(domain, range) { - var thresholds; - function rescale() { - var k = 0, q = range.length; - thresholds = []; - while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); - return scale; - } - function scale(x) { - if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)]; - } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.map(d3_number).filter(d3_numeric).sort(d3_ascending); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.quantiles = function() { - return thresholds; - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ]; - }; - scale.copy = function() { - return d3_scale_quantile(domain, range); - }; - return rescale(); - } - d3.scale.quantize = function() { - return d3_scale_quantize(0, 1, [ 0, 1 ]); - }; - function d3_scale_quantize(x0, x1, range) { - var kx, i; - function scale(x) { - return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; - } - function rescale() { - kx = range.length / (x1 - x0); - i = range.length - 1; - return scale; - } - scale.domain = function(x) { - if (!arguments.length) return [ x0, x1 ]; - x0 = +x[0]; - x1 = +x[x.length - 1]; - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - y = y < 0 ? NaN : y / kx + x0; - return [ y, y + 1 / kx ]; - }; - scale.copy = function() { - return d3_scale_quantize(x0, x1, range); - }; - return rescale(); - } - d3.scale.threshold = function() { - return d3_scale_threshold([ .5 ], [ 0, 1 ]); - }; - function d3_scale_threshold(domain, range) { - function scale(x) { - if (x <= x) return range[d3.bisect(domain, x)]; - } - scale.domain = function(_) { - if (!arguments.length) return domain; - domain = _; - return scale; - }; - scale.range = function(_) { - if (!arguments.length) return range; - range = _; - return scale; - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - return [ domain[y - 1], domain[y] ]; - }; - scale.copy = function() { - return d3_scale_threshold(domain, range); - }; - return scale; - } - d3.scale.identity = function() { - return d3_scale_identity([ 0, 1 ]); - }; - function d3_scale_identity(domain) { - function identity(x) { - return +x; - } - identity.invert = identity; - identity.domain = identity.range = function(x) { - if (!arguments.length) return domain; - domain = x.map(identity); - return identity; - }; - identity.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - identity.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - identity.copy = function() { - return d3_scale_identity(domain); - }; - return identity; - } - d3.svg = {}; - function d3_zero() { - return 0; - } - d3.svg.arc = function() { - var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, cornerRadius = d3_zero, padRadius = d3_svg_arcAuto, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle, padAngle = d3_svg_arcPadAngle; - function arc() { - var r0 = Math.max(0, +innerRadius.apply(this, arguments)), r1 = Math.max(0, +outerRadius.apply(this, arguments)), a0 = startAngle.apply(this, arguments) - halfπ, a1 = endAngle.apply(this, arguments) - halfπ, da = Math.abs(a1 - a0), cw = a0 > a1 ? 0 : 1; - if (r1 < r0) rc = r1, r1 = r0, r0 = rc; - if (da >= τε) return circleSegment(r1, cw) + (r0 ? circleSegment(r0, 1 - cw) : "") + "Z"; - var rc, cr, rp, ap, p0 = 0, p1 = 0, x0, y0, x1, y1, x2, y2, x3, y3, path = []; - if (ap = (+padAngle.apply(this, arguments) || 0) / 2) { - rp = padRadius === d3_svg_arcAuto ? Math.sqrt(r0 * r0 + r1 * r1) : +padRadius.apply(this, arguments); - if (!cw) p1 *= -1; - if (r1) p1 = d3_asin(rp / r1 * Math.sin(ap)); - if (r0) p0 = d3_asin(rp / r0 * Math.sin(ap)); - } - if (r1) { - x0 = r1 * Math.cos(a0 + p1); - y0 = r1 * Math.sin(a0 + p1); - x1 = r1 * Math.cos(a1 - p1); - y1 = r1 * Math.sin(a1 - p1); - var l1 = Math.abs(a1 - a0 - 2 * p1) <= π ? 0 : 1; - if (p1 && d3_svg_arcSweep(x0, y0, x1, y1) === cw ^ l1) { - var h1 = (a0 + a1) / 2; - x0 = r1 * Math.cos(h1); - y0 = r1 * Math.sin(h1); - x1 = y1 = null; - } - } else { - x0 = y0 = 0; - } - if (r0) { - x2 = r0 * Math.cos(a1 - p0); - y2 = r0 * Math.sin(a1 - p0); - x3 = r0 * Math.cos(a0 + p0); - y3 = r0 * Math.sin(a0 + p0); - var l0 = Math.abs(a0 - a1 + 2 * p0) <= π ? 0 : 1; - if (p0 && d3_svg_arcSweep(x2, y2, x3, y3) === 1 - cw ^ l0) { - var h0 = (a0 + a1) / 2; - x2 = r0 * Math.cos(h0); - y2 = r0 * Math.sin(h0); - x3 = y3 = null; - } - } else { - x2 = y2 = 0; - } - if ((rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments))) > .001) { - cr = r0 < r1 ^ cw ? 0 : 1; - var oc = x3 == null ? [ x2, y2 ] : x1 == null ? [ x0, y0 ] : d3_geom_polygonIntersect([ x0, y0 ], [ x3, y3 ], [ x1, y1 ], [ x2, y2 ]), ax = x0 - oc[0], ay = y0 - oc[1], bx = x1 - oc[0], by = y1 - oc[1], kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2), lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]); - if (x1 != null) { - var rc1 = Math.min(rc, (r1 - lc) / (kc + 1)), t30 = d3_svg_arcCornerTangents(x3 == null ? [ x2, y2 ] : [ x3, y3 ], [ x0, y0 ], r1, rc1, cw), t12 = d3_svg_arcCornerTangents([ x1, y1 ], [ x2, y2 ], r1, rc1, cw); - if (rc === rc1) { - path.push("M", t30[0], "A", rc1, ",", rc1, " 0 0,", cr, " ", t30[1], "A", r1, ",", r1, " 0 ", 1 - cw ^ d3_svg_arcSweep(t30[1][0], t30[1][1], t12[1][0], t12[1][1]), ",", cw, " ", t12[1], "A", rc1, ",", rc1, " 0 0,", cr, " ", t12[0]); - } else { - path.push("M", t30[0], "A", rc1, ",", rc1, " 0 1,", cr, " ", t12[0]); - } - } else { - path.push("M", x0, ",", y0); - } - if (x3 != null) { - var rc0 = Math.min(rc, (r0 - lc) / (kc - 1)), t03 = d3_svg_arcCornerTangents([ x0, y0 ], [ x3, y3 ], r0, -rc0, cw), t21 = d3_svg_arcCornerTangents([ x2, y2 ], x1 == null ? [ x0, y0 ] : [ x1, y1 ], r0, -rc0, cw); - if (rc === rc0) { - path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t21[1], "A", r0, ",", r0, " 0 ", cw ^ d3_svg_arcSweep(t21[1][0], t21[1][1], t03[1][0], t03[1][1]), ",", 1 - cw, " ", t03[1], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]); - } else { - path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]); - } - } else { - path.push("L", x2, ",", y2); - } - } else { - path.push("M", x0, ",", y0); - if (x1 != null) path.push("A", r1, ",", r1, " 0 ", l1, ",", cw, " ", x1, ",", y1); - path.push("L", x2, ",", y2); - if (x3 != null) path.push("A", r0, ",", r0, " 0 ", l0, ",", 1 - cw, " ", x3, ",", y3); - } - path.push("Z"); - return path.join(""); - } - function circleSegment(r1, cw) { - return "M0," + r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + -r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + r1; - } - arc.innerRadius = function(v) { - if (!arguments.length) return innerRadius; - innerRadius = d3_functor(v); - return arc; - }; - arc.outerRadius = function(v) { - if (!arguments.length) return outerRadius; - outerRadius = d3_functor(v); - return arc; - }; - arc.cornerRadius = function(v) { - if (!arguments.length) return cornerRadius; - cornerRadius = d3_functor(v); - return arc; - }; - arc.padRadius = function(v) { - if (!arguments.length) return padRadius; - padRadius = v == d3_svg_arcAuto ? d3_svg_arcAuto : d3_functor(v); - return arc; - }; - arc.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return arc; - }; - arc.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return arc; - }; - arc.padAngle = function(v) { - if (!arguments.length) return padAngle; - padAngle = d3_functor(v); - return arc; - }; - arc.centroid = function() { - var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - halfπ; - return [ Math.cos(a) * r, Math.sin(a) * r ]; - }; - return arc; - }; - var d3_svg_arcAuto = "auto"; - function d3_svg_arcInnerRadius(d) { - return d.innerRadius; - } - function d3_svg_arcOuterRadius(d) { - return d.outerRadius; - } - function d3_svg_arcStartAngle(d) { - return d.startAngle; - } - function d3_svg_arcEndAngle(d) { - return d.endAngle; - } - function d3_svg_arcPadAngle(d) { - return d && d.padAngle; - } - function d3_svg_arcSweep(x0, y0, x1, y1) { - return (x0 - x1) * y0 - (y0 - y1) * x0 > 0 ? 0 : 1; - } - function d3_svg_arcCornerTangents(p0, p1, r1, rc, cw) { - var x01 = p0[0] - p1[0], y01 = p0[1] - p1[1], lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x1 = p0[0] + ox, y1 = p0[1] + oy, x2 = p1[0] + ox, y2 = p1[1] + oy, x3 = (x1 + x2) / 2, y3 = (y1 + y2) / 2, dx = x2 - x1, dy = y2 - y1, d2 = dx * dx + dy * dy, r = r1 - rc, D = x1 * y2 - x2 * y1, d = (dy < 0 ? -1 : 1) * Math.sqrt(r * r * d2 - D * D), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x3, dy0 = cy0 - y3, dx1 = cx1 - x3, dy1 = cy1 - y3; - if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; - return [ [ cx0 - ox, cy0 - oy ], [ cx0 * r1 / r, cy0 * r1 / r ] ]; - } - function d3_svg_line(projection) { - var x = d3_geom_pointX, y = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7; - function line(data) { - var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y); - function segment() { - segments.push("M", interpolate(projection(points), tension)); - } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]); - } else if (points.length) { - segment(); - points = []; - } - } - if (points.length) segment(); - return segments.length ? segments.join("") : null; - } - line.x = function(_) { - if (!arguments.length) return x; - x = _; - return line; - }; - line.y = function(_) { - if (!arguments.length) return y; - y = _; - return line; - }; - line.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return line; - }; - line.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - return line; - }; - line.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return line; - }; - return line; - } - d3.svg.line = function() { - return d3_svg_line(d3_identity); - }; - var d3_svg_lineInterpolators = d3.map({ - linear: d3_svg_lineLinear, - "linear-closed": d3_svg_lineLinearClosed, - step: d3_svg_lineStep, - "step-before": d3_svg_lineStepBefore, - "step-after": d3_svg_lineStepAfter, - basis: d3_svg_lineBasis, - "basis-open": d3_svg_lineBasisOpen, - "basis-closed": d3_svg_lineBasisClosed, - bundle: d3_svg_lineBundle, - cardinal: d3_svg_lineCardinal, - "cardinal-open": d3_svg_lineCardinalOpen, - "cardinal-closed": d3_svg_lineCardinalClosed, - monotone: d3_svg_lineMonotone - }); - d3_svg_lineInterpolators.forEach(function(key, value) { - value.key = key; - value.closed = /-closed$/.test(key); - }); - function d3_svg_lineLinear(points) { - return points.join("L"); - } - function d3_svg_lineLinearClosed(points) { - return d3_svg_lineLinear(points) + "Z"; - } - function d3_svg_lineStep(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]); - if (n > 1) path.push("H", p[0]); - return path.join(""); - } - function d3_svg_lineStepBefore(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); - return path.join(""); - } - function d3_svg_lineStepAfter(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); - return path.join(""); - } - function d3_svg_lineCardinalOpen(points, tension) { - return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, -1), d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineCardinalClosed(points, tension) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), - points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension)); - } - function d3_svg_lineCardinal(points, tension) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineHermite(points, tangents) { - if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) { - return d3_svg_lineLinear(points); - } - var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1; - if (quad) { - path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1]; - p0 = points[1]; - pi = 2; - } - if (tangents.length > 1) { - t = tangents[1]; - p = points[pi]; - pi++; - path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - for (var i = 2; i < tangents.length; i++, pi++) { - p = points[pi]; - t = tangents[i]; - path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - } - } - if (quad) { - var lp = points[pi]; - path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1]; - } - return path; - } - function d3_svg_lineCardinalTangents(points, tension) { - var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length; - while (++i < n) { - p0 = p1; - p1 = p2; - p2 = points[i]; - tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]); - } - return tangents; - } - function d3_svg_lineBasis(points) { - if (points.length < 3) return d3_svg_lineLinear(points); - var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; - points.push(points[n - 1]); - while (++i <= n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - points.pop(); - path.push("L", pi); - return path.join(""); - } - function d3_svg_lineBasisOpen(points) { - if (points.length < 4) return d3_svg_lineLinear(points); - var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ]; - while (++i < 3) { - pi = points[i]; - px.push(pi[0]); - py.push(pi[1]); - } - path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); - --i; - while (++i < n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBasisClosed(points) { - var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = []; - while (++i < 4) { - pi = points[i % n]; - px.push(pi[0]); - py.push(pi[1]); - } - path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; - --i; - while (++i < m) { - pi = points[i % n]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBundle(points, tension) { - var n = points.length - 1; - if (n) { - var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t; - while (++i <= n) { - p = points[i]; - t = i / n; - p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); - p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); - } - } - return d3_svg_lineBasis(points); - } - function d3_svg_lineDot4(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; - } - var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ]; - function d3_svg_lineBasisBezier(path, x, y) { - path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); - } - function d3_svg_lineSlope(p0, p1) { - return (p1[1] - p0[1]) / (p1[0] - p0[0]); - } - function d3_svg_lineFiniteDifferences(points) { - var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1); - while (++i < j) { - m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; - } - m[i] = d; - return m; - } - function d3_svg_lineMonotoneTangents(points) { - var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1; - while (++i < j) { - d = d3_svg_lineSlope(points[i], points[i + 1]); - if (abs(d) < ε) { - m[i] = m[i + 1] = 0; - } else { - a = m[i] / d; - b = m[i + 1] / d; - s = a * a + b * b; - if (s > 9) { - s = d * 3 / Math.sqrt(s); - m[i] = s * a; - m[i + 1] = s * b; - } - } - } - i = -1; - while (++i <= j) { - s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); - tangents.push([ s || 0, m[i] * s || 0 ]); - } - return tangents; - } - function d3_svg_lineMonotone(points) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); - } - d3.svg.line.radial = function() { - var line = d3_svg_line(d3_svg_lineRadial); - line.radius = line.x, delete line.x; - line.angle = line.y, delete line.y; - return line; - }; - function d3_svg_lineRadial(points) { - var point, i = -1, n = points.length, r, a; - while (++i < n) { - point = points[i]; - r = point[0]; - a = point[1] - halfπ; - point[0] = r * Math.cos(a); - point[1] = r * Math.sin(a); - } - return points; - } - function d3_svg_area(projection) { - var x0 = d3_geom_pointX, x1 = d3_geom_pointX, y0 = 0, y1 = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7; - function area(data) { - var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() { - return x; - } : d3_functor(x1), fy1 = y0 === y1 ? function() { - return y; - } : d3_functor(y1), x, y; - function segment() { - segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z"); - } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]); - points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]); - } else if (points0.length) { - segment(); - points0 = []; - points1 = []; - } - } - if (points0.length) segment(); - return segments.length ? segments.join("") : null; - } - area.x = function(_) { - if (!arguments.length) return x1; - x0 = x1 = _; - return area; - }; - area.x0 = function(_) { - if (!arguments.length) return x0; - x0 = _; - return area; - }; - area.x1 = function(_) { - if (!arguments.length) return x1; - x1 = _; - return area; - }; - area.y = function(_) { - if (!arguments.length) return y1; - y0 = y1 = _; - return area; - }; - area.y0 = function(_) { - if (!arguments.length) return y0; - y0 = _; - return area; - }; - area.y1 = function(_) { - if (!arguments.length) return y1; - y1 = _; - return area; - }; - area.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return area; - }; - area.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - interpolateReverse = interpolate.reverse || interpolate; - L = interpolate.closed ? "M" : "L"; - return area; - }; - area.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return area; - }; - return area; - } - d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; - d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; - d3.svg.area = function() { - return d3_svg_area(d3_identity); - }; - d3.svg.area.radial = function() { - var area = d3_svg_area(d3_svg_lineRadial); - area.radius = area.x, delete area.x; - area.innerRadius = area.x0, delete area.x0; - area.outerRadius = area.x1, delete area.x1; - area.angle = area.y, delete area.y; - area.startAngle = area.y0, delete area.y0; - area.endAngle = area.y1, delete area.y1; - return area; - }; - d3.svg.chord = function() { - var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; - function chord(d, i) { - var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i); - return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z"; - } - function subgroup(self, f, d, i) { - var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) - halfπ, a1 = endAngle.call(self, subgroup, i) - halfπ; - return { - r: r, - a0: a0, - a1: a1, - p0: [ r * Math.cos(a0), r * Math.sin(a0) ], - p1: [ r * Math.cos(a1), r * Math.sin(a1) ] - }; - } - function equals(a, b) { - return a.a0 == b.a0 && a.a1 == b.a1; - } - function arc(r, p, a) { - return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p; - } - function curve(r0, p0, r1, p1) { - return "Q 0,0 " + p1; - } - chord.radius = function(v) { - if (!arguments.length) return radius; - radius = d3_functor(v); - return chord; - }; - chord.source = function(v) { - if (!arguments.length) return source; - source = d3_functor(v); - return chord; - }; - chord.target = function(v) { - if (!arguments.length) return target; - target = d3_functor(v); - return chord; - }; - chord.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return chord; - }; - chord.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return chord; - }; - return chord; - }; - function d3_svg_chordRadius(d) { - return d.radius; - } - d3.svg.diagonal = function() { - var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection; - function diagonal(d, i) { - var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { - x: p0.x, - y: m - }, { - x: p3.x, - y: m - }, p3 ]; - p = p.map(projection); - return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; - } - diagonal.source = function(x) { - if (!arguments.length) return source; - source = d3_functor(x); - return diagonal; - }; - diagonal.target = function(x) { - if (!arguments.length) return target; - target = d3_functor(x); - return diagonal; - }; - diagonal.projection = function(x) { - if (!arguments.length) return projection; - projection = x; - return diagonal; - }; - return diagonal; - }; - function d3_svg_diagonalProjection(d) { - return [ d.x, d.y ]; - } - d3.svg.diagonal.radial = function() { - var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection; - diagonal.projection = function(x) { - return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection; - }; - return diagonal; - }; - function d3_svg_diagonalRadialProjection(projection) { - return function() { - var d = projection.apply(this, arguments), r = d[0], a = d[1] - halfπ; - return [ r * Math.cos(a), r * Math.sin(a) ]; - }; - } - d3.svg.symbol = function() { - var type = d3_svg_symbolType, size = d3_svg_symbolSize; - function symbol(d, i) { - return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i)); - } - symbol.type = function(x) { - if (!arguments.length) return type; - type = d3_functor(x); - return symbol; - }; - symbol.size = function(x) { - if (!arguments.length) return size; - size = d3_functor(x); - return symbol; - }; - return symbol; - }; - function d3_svg_symbolSize() { - return 64; - } - function d3_svg_symbolType() { - return "circle"; - } - function d3_svg_symbolCircle(size) { - var r = Math.sqrt(size / π); - return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z"; - } - var d3_svg_symbols = d3.map({ - circle: d3_svg_symbolCircle, - cross: function(size) { - var r = Math.sqrt(size / 5) / 2; - return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z"; - }, - diamond: function(size) { - var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30; - return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z"; - }, - square: function(size) { - var r = Math.sqrt(size) / 2; - return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z"; - }, - "triangle-down": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z"; - }, - "triangle-up": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z"; - } - }); - d3.svg.symbolTypes = d3_svg_symbols.keys(); - var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians); - d3_selectionPrototype.transition = function(name) { - var id = d3_transitionInheritId || ++d3_transitionId, ns = d3_transitionNamespace(name), subgroups = [], subgroup, node, transition = d3_transitionInherit || { - time: Date.now(), - ease: d3_ease_cubicInOut, - delay: 0, - duration: 250 - }; - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) d3_transitionNode(node, i, ns, id, transition); - subgroup.push(node); - } - } - return d3_transition(subgroups, ns, id); - }; - d3_selectionPrototype.interrupt = function(name) { - return this.each(name == null ? d3_selection_interrupt : d3_selection_interruptNS(d3_transitionNamespace(name))); - }; - var d3_selection_interrupt = d3_selection_interruptNS(d3_transitionNamespace()); - function d3_selection_interruptNS(ns) { - return function() { - var lock, active; - if ((lock = this[ns]) && (active = lock[lock.active])) { - if (--lock.count) { - delete lock[lock.active]; - lock.active += .5; - } else { - delete this[ns]; - } - active.event && active.event.interrupt.call(this, this.__data__, active.index); - } - }; - } - function d3_transition(groups, ns, id) { - d3_subclass(groups, d3_transitionPrototype); - groups.namespace = ns; - groups.id = id; - return groups; - } - var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit; - d3_transitionPrototype.call = d3_selectionPrototype.call; - d3_transitionPrototype.empty = d3_selectionPrototype.empty; - d3_transitionPrototype.node = d3_selectionPrototype.node; - d3_transitionPrototype.size = d3_selectionPrototype.size; - d3.transition = function(selection, name) { - return selection && selection.transition ? d3_transitionInheritId ? selection.transition(name) : selection : d3_selectionRoot.transition(selection); - }; - d3.transition.prototype = d3_transitionPrototype; - d3_transitionPrototype.select = function(selector) { - var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnode, node; - selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - d3_transitionNode(subnode, i, ns, id, node[ns][id]); - subgroup.push(subnode); - } else { - subgroup.push(null); - } - } - } - return d3_transition(subgroups, ns, id); - }; - d3_transitionPrototype.selectAll = function(selector) { - var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnodes, node, subnode, transition; - selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - transition = node[ns][id]; - subnodes = selector.call(node, node.__data__, i, j); - subgroups.push(subgroup = []); - for (var k = -1, o = subnodes.length; ++k < o; ) { - if (subnode = subnodes[k]) d3_transitionNode(subnode, k, ns, id, transition); - subgroup.push(subnode); - } - } - } - } - return d3_transition(subgroups, ns, id); - }; - d3_transitionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { - subgroup.push(node); - } - } - } - return d3_transition(subgroups, this.namespace, this.id); - }; - d3_transitionPrototype.tween = function(name, tween) { - var id = this.id, ns = this.namespace; - if (arguments.length < 2) return this.node()[ns][id].tween.get(name); - return d3_selection_each(this, tween == null ? function(node) { - node[ns][id].tween.remove(name); - } : function(node) { - node[ns][id].tween.set(name, tween); - }); - }; - function d3_transition_tween(groups, name, value, tween) { - var id = groups.id, ns = groups.namespace; - return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) { - node[ns][id].tween.set(name, tween(value.call(node, node.__data__, i, j))); - } : (value = tween(value), function(node) { - node[ns][id].tween.set(name, value); - })); - } - d3_transitionPrototype.attr = function(nameNS, value) { - if (arguments.length < 2) { - for (value in nameNS) this.attr(value, nameNS[value]); - return this; - } - var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS); - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - function attrTween(b) { - return b == null ? attrNull : (b += "", function() { - var a = this.getAttribute(name), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttribute(name, i(t)); - }); - }); - } - function attrTweenNS(b) { - return b == null ? attrNullNS : (b += "", function() { - var a = this.getAttributeNS(name.space, name.local), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttributeNS(name.space, name.local, i(t)); - }); - }); - } - return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween); - }; - d3_transitionPrototype.attrTween = function(nameNS, tween) { - var name = d3.ns.qualify(nameNS); - function attrTween(d, i) { - var f = tween.call(this, d, i, this.getAttribute(name)); - return f && function(t) { - this.setAttribute(name, f(t)); - }; - } - function attrTweenNS(d, i) { - var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); - return f && function(t) { - this.setAttributeNS(name.space, name.local, f(t)); - }; - } - return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); - }; - d3_transitionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.style(priority, name[priority], value); - return this; - } - priority = ""; - } - function styleNull() { - this.style.removeProperty(name); - } - function styleString(b) { - return b == null ? styleNull : (b += "", function() { - var a = d3_window.getComputedStyle(this, null).getPropertyValue(name), i; - return a !== b && (i = d3_interpolate(a, b), function(t) { - this.style.setProperty(name, i(t), priority); - }); - }); - } - return d3_transition_tween(this, "style." + name, value, styleString); - }; - d3_transitionPrototype.styleTween = function(name, tween, priority) { - if (arguments.length < 3) priority = ""; - function styleTween(d, i) { - var f = tween.call(this, d, i, d3_window.getComputedStyle(this, null).getPropertyValue(name)); - return f && function(t) { - this.style.setProperty(name, f(t), priority); - }; - } - return this.tween("style." + name, styleTween); - }; - d3_transitionPrototype.text = function(value) { - return d3_transition_tween(this, "text", value, d3_transition_text); - }; - function d3_transition_text(b) { - if (b == null) b = ""; - return function() { - this.textContent = b; - }; - } - d3_transitionPrototype.remove = function() { - var ns = this.namespace; - return this.each("end.transition", function() { - var p; - if (this[ns].count < 2 && (p = this.parentNode)) p.removeChild(this); - }); - }; - d3_transitionPrototype.ease = function(value) { - var id = this.id, ns = this.namespace; - if (arguments.length < 1) return this.node()[ns][id].ease; - if (typeof value !== "function") value = d3.ease.apply(d3, arguments); - return d3_selection_each(this, function(node) { - node[ns][id].ease = value; - }); - }; - d3_transitionPrototype.delay = function(value) { - var id = this.id, ns = this.namespace; - if (arguments.length < 1) return this.node()[ns][id].delay; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node[ns][id].delay = +value.call(node, node.__data__, i, j); - } : (value = +value, function(node) { - node[ns][id].delay = value; - })); - }; - d3_transitionPrototype.duration = function(value) { - var id = this.id, ns = this.namespace; - if (arguments.length < 1) return this.node()[ns][id].duration; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node[ns][id].duration = Math.max(1, value.call(node, node.__data__, i, j)); - } : (value = Math.max(1, value), function(node) { - node[ns][id].duration = value; - })); - }; - d3_transitionPrototype.each = function(type, listener) { - var id = this.id, ns = this.namespace; - if (arguments.length < 2) { - var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId; - try { - d3_transitionInheritId = id; - d3_selection_each(this, function(node, i, j) { - d3_transitionInherit = node[ns][id]; - type.call(node, node.__data__, i, j); - }); - } finally { - d3_transitionInherit = inherit; - d3_transitionInheritId = inheritId; - } - } else { - d3_selection_each(this, function(node) { - var transition = node[ns][id]; - (transition.event || (transition.event = d3.dispatch("start", "end", "interrupt"))).on(type, listener); - }); - } - return this; - }; - d3_transitionPrototype.transition = function() { - var id0 = this.id, id1 = ++d3_transitionId, ns = this.namespace, subgroups = [], subgroup, group, node, transition; - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if (node = group[i]) { - transition = node[ns][id0]; - d3_transitionNode(node, i, ns, id1, { - time: transition.time, - ease: transition.ease, - delay: transition.delay + transition.duration, - duration: transition.duration - }); - } - subgroup.push(node); - } - } - return d3_transition(subgroups, ns, id1); - }; - function d3_transitionNamespace(name) { - return name == null ? "__transition__" : "__transition_" + name + "__"; - } - function d3_transitionNode(node, i, ns, id, inherit) { - var lock = node[ns] || (node[ns] = { - active: 0, - count: 0 - }), transition = lock[id]; - if (!transition) { - var time = inherit.time; - transition = lock[id] = { - tween: new d3_Map(), - time: time, - delay: inherit.delay, - duration: inherit.duration, - ease: inherit.ease, - index: i - }; - inherit = null; - ++lock.count; - d3.timer(function(elapsed) { - var delay = transition.delay, duration, ease, timer = d3_timer_active, tweened = []; - timer.t = delay + time; - if (delay <= elapsed) return start(elapsed - delay); - timer.c = start; - function start(elapsed) { - if (lock.active > id) return stop(); - var active = lock[lock.active]; - if (active) { - --lock.count; - delete lock[lock.active]; - active.event && active.event.interrupt.call(node, node.__data__, active.index); - } - lock.active = id; - transition.event && transition.event.start.call(node, node.__data__, i); - transition.tween.forEach(function(key, value) { - if (value = value.call(node, node.__data__, i)) { - tweened.push(value); - } - }); - ease = transition.ease; - duration = transition.duration; - d3.timer(function() { - timer.c = tick(elapsed || 1) ? d3_true : tick; - return 1; - }, 0, time); - } - function tick(elapsed) { - if (lock.active !== id) return 1; - var t = elapsed / duration, e = ease(t), n = tweened.length; - while (n > 0) { - tweened[--n].call(node, e); - } - if (t >= 1) { - transition.event && transition.event.end.call(node, node.__data__, i); - return stop(); - } - } - function stop() { - if (--lock.count) delete lock[id]; else delete node[ns]; - return 1; - } - }, 0, time); - } - } - d3.svg.axis = function() { - var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_; - function axis(g) { - g.each(function() { - var g = d3.select(this); - var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = scale.copy(); - var ticks = tickValues == null ? scale1.ticks ? scale1.ticks.apply(scale1, tickArguments_) : scale1.domain() : tickValues, tickFormat = tickFormat_ == null ? scale1.tickFormat ? scale1.tickFormat.apply(scale1, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(".tick").data(ticks, scale1), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", ε), tickExit = d3.transition(tick.exit()).style("opacity", ε).remove(), tickUpdate = d3.transition(tick.order()).style("opacity", 1), tickSpacing = Math.max(innerTickSize, 0) + tickPadding, tickTransform; - var range = d3_scaleRange(scale1), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), - d3.transition(path)); - tickEnter.append("line"); - tickEnter.append("text"); - var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"), sign = orient === "top" || orient === "left" ? -1 : 1, x1, x2, y1, y2; - if (orient === "bottom" || orient === "top") { - tickTransform = d3_svg_axisX, x1 = "x", y1 = "y", x2 = "x2", y2 = "y2"; - text.attr("dy", sign < 0 ? "0em" : ".71em").style("text-anchor", "middle"); - pathUpdate.attr("d", "M" + range[0] + "," + sign * outerTickSize + "V0H" + range[1] + "V" + sign * outerTickSize); - } else { - tickTransform = d3_svg_axisY, x1 = "y", y1 = "x", x2 = "y2", y2 = "x2"; - text.attr("dy", ".32em").style("text-anchor", sign < 0 ? "end" : "start"); - pathUpdate.attr("d", "M" + sign * outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + sign * outerTickSize); - } - lineEnter.attr(y2, sign * innerTickSize); - textEnter.attr(y1, sign * tickSpacing); - lineUpdate.attr(x2, 0).attr(y2, sign * innerTickSize); - textUpdate.attr(x1, 0).attr(y1, sign * tickSpacing); - if (scale1.rangeBand) { - var x = scale1, dx = x.rangeBand() / 2; - scale0 = scale1 = function(d) { - return x(d) + dx; - }; - } else if (scale0.rangeBand) { - scale0 = scale1; - } else { - tickExit.call(tickTransform, scale1, scale0); - } - tickEnter.call(tickTransform, scale0, scale1); - tickUpdate.call(tickTransform, scale1, scale1); - }); - } - axis.scale = function(x) { - if (!arguments.length) return scale; - scale = x; - return axis; - }; - axis.orient = function(x) { - if (!arguments.length) return orient; - orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient; - return axis; - }; - axis.ticks = function() { - if (!arguments.length) return tickArguments_; - tickArguments_ = arguments; - return axis; - }; - axis.tickValues = function(x) { - if (!arguments.length) return tickValues; - tickValues = x; - return axis; - }; - axis.tickFormat = function(x) { - if (!arguments.length) return tickFormat_; - tickFormat_ = x; - return axis; - }; - axis.tickSize = function(x) { - var n = arguments.length; - if (!n) return innerTickSize; - innerTickSize = +x; - outerTickSize = +arguments[n - 1]; - return axis; - }; - axis.innerTickSize = function(x) { - if (!arguments.length) return innerTickSize; - innerTickSize = +x; - return axis; - }; - axis.outerTickSize = function(x) { - if (!arguments.length) return outerTickSize; - outerTickSize = +x; - return axis; - }; - axis.tickPadding = function(x) { - if (!arguments.length) return tickPadding; - tickPadding = +x; - return axis; - }; - axis.tickSubdivide = function() { - return arguments.length && axis; - }; - return axis; - }; - var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = { - top: 1, - right: 1, - bottom: 1, - left: 1 - }; - function d3_svg_axisX(selection, x0, x1) { - selection.attr("transform", function(d) { - var v0 = x0(d); - return "translate(" + (isFinite(v0) ? v0 : x1(d)) + ",0)"; - }); - } - function d3_svg_axisY(selection, y0, y1) { - selection.attr("transform", function(d) { - var v0 = y0(d); - return "translate(0," + (isFinite(v0) ? v0 : y1(d)) + ")"; - }); - } - d3.svg.brush = function() { - var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0]; - function brush(g) { - g.each(function() { - var g = d3.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart); - var background = g.selectAll(".background").data([ 0 ]); - background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"); - g.selectAll(".extent").data([ 0 ]).enter().append("rect").attr("class", "extent").style("cursor", "move"); - var resize = g.selectAll(".resize").data(resizes, d3_identity); - resize.exit().remove(); - resize.enter().append("g").attr("class", function(d) { - return "resize " + d; - }).style("cursor", function(d) { - return d3_svg_brushCursor[d]; - }).append("rect").attr("x", function(d) { - return /[ew]$/.test(d) ? -3 : null; - }).attr("y", function(d) { - return /^[ns]/.test(d) ? -3 : null; - }).attr("width", 6).attr("height", 6).style("visibility", "hidden"); - resize.style("display", brush.empty() ? "none" : null); - var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range; - if (x) { - range = d3_scaleRange(x); - backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]); - redrawX(gUpdate); - } - if (y) { - range = d3_scaleRange(y); - backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]); - redrawY(gUpdate); - } - redraw(gUpdate); - }); - } - brush.event = function(g) { - g.each(function() { - var event_ = event.of(this, arguments), extent1 = { - x: xExtent, - y: yExtent, - i: xExtentDomain, - j: yExtentDomain - }, extent0 = this.__chart__ || extent1; - this.__chart__ = extent1; - if (d3_transitionInheritId) { - d3.select(this).transition().each("start.brush", function() { - xExtentDomain = extent0.i; - yExtentDomain = extent0.j; - xExtent = extent0.x; - yExtent = extent0.y; - event_({ - type: "brushstart" - }); - }).tween("brush:brush", function() { - var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y); - xExtentDomain = yExtentDomain = null; - return function(t) { - xExtent = extent1.x = xi(t); - yExtent = extent1.y = yi(t); - event_({ - type: "brush", - mode: "resize" - }); - }; - }).each("end.brush", function() { - xExtentDomain = extent1.i; - yExtentDomain = extent1.j; - event_({ - type: "brush", - mode: "resize" - }); - event_({ - type: "brushend" - }); - }); - } else { - event_({ - type: "brushstart" - }); - event_({ - type: "brush", - mode: "resize" - }); - event_({ - type: "brushend" - }); - } - }); - }; - function redraw(g) { - g.selectAll(".resize").attr("transform", function(d) { - return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")"; - }); - } - function redrawX(g) { - g.select(".extent").attr("x", xExtent[0]); - g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]); - } - function redrawY(g) { - g.select(".extent").attr("y", yExtent[0]); - g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]); - } - function brushstart() { - var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(), center, origin = d3.mouse(target), offset; - var w = d3.select(d3_window).on("keydown.brush", keydown).on("keyup.brush", keyup); - if (d3.event.changedTouches) { - w.on("touchmove.brush", brushmove).on("touchend.brush", brushend); - } else { - w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend); - } - g.interrupt().selectAll("*").interrupt(); - if (dragging) { - origin[0] = xExtent[0] - origin[0]; - origin[1] = yExtent[0] - origin[1]; - } else if (resizing) { - var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing); - offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ]; - origin[0] = xExtent[ex]; - origin[1] = yExtent[ey]; - } else if (d3.event.altKey) center = origin.slice(); - g.style("pointer-events", "none").selectAll(".resize").style("display", null); - d3.select("body").style("cursor", eventTarget.style("cursor")); - event_({ - type: "brushstart" - }); - brushmove(); - function keydown() { - if (d3.event.keyCode == 32) { - if (!dragging) { - center = null; - origin[0] -= xExtent[1]; - origin[1] -= yExtent[1]; - dragging = 2; - } - d3_eventPreventDefault(); - } - } - function keyup() { - if (d3.event.keyCode == 32 && dragging == 2) { - origin[0] += xExtent[1]; - origin[1] += yExtent[1]; - dragging = 0; - d3_eventPreventDefault(); - } - } - function brushmove() { - var point = d3.mouse(target), moved = false; - if (offset) { - point[0] += offset[0]; - point[1] += offset[1]; - } - if (!dragging) { - if (d3.event.altKey) { - if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ]; - origin[0] = xExtent[+(point[0] < center[0])]; - origin[1] = yExtent[+(point[1] < center[1])]; - } else center = null; - } - if (resizingX && move1(point, x, 0)) { - redrawX(g); - moved = true; - } - if (resizingY && move1(point, y, 1)) { - redrawY(g); - moved = true; - } - if (moved) { - redraw(g); - event_({ - type: "brush", - mode: dragging ? "move" : "resize" - }); - } - } - function move1(point, scale, i) { - var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max; - if (dragging) { - r0 -= position; - r1 -= size + position; - } - min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i]; - if (dragging) { - max = (min += position) + size; - } else { - if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); - if (position < min) { - max = min; - min = position; - } else { - max = position; - } - } - if (extent[0] != min || extent[1] != max) { - if (i) yExtentDomain = null; else xExtentDomain = null; - extent[0] = min; - extent[1] = max; - return true; - } - } - function brushend() { - brushmove(); - g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); - d3.select("body").style("cursor", null); - w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null); - dragRestore(); - event_({ - type: "brushend" - }); - } - } - brush.x = function(z) { - if (!arguments.length) return x; - x = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.y = function(z) { - if (!arguments.length) return y; - y = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.clamp = function(z) { - if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null; - if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z; - return brush; - }; - brush.extent = function(z) { - var x0, x1, y0, y1, t; - if (!arguments.length) { - if (x) { - if (xExtentDomain) { - x0 = xExtentDomain[0], x1 = xExtentDomain[1]; - } else { - x0 = xExtent[0], x1 = xExtent[1]; - if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - } - } - if (y) { - if (yExtentDomain) { - y0 = yExtentDomain[0], y1 = yExtentDomain[1]; - } else { - y0 = yExtent[0], y1 = yExtent[1]; - if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - } - } - return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ]; - } - if (x) { - x0 = z[0], x1 = z[1]; - if (y) x0 = x0[0], x1 = x1[0]; - xExtentDomain = [ x0, x1 ]; - if (x.invert) x0 = x(x0), x1 = x(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ]; - } - if (y) { - y0 = z[0], y1 = z[1]; - if (x) y0 = y0[1], y1 = y1[1]; - yExtentDomain = [ y0, y1 ]; - if (y.invert) y0 = y(y0), y1 = y(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ]; - } - return brush; - }; - brush.clear = function() { - if (!brush.empty()) { - xExtent = [ 0, 0 ], yExtent = [ 0, 0 ]; - xExtentDomain = yExtentDomain = null; - } - return brush; - }; - brush.empty = function() { - return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1]; - }; - return d3.rebind(brush, event, "on"); - }; - var d3_svg_brushCursor = { - n: "ns-resize", - e: "ew-resize", - s: "ns-resize", - w: "ew-resize", - nw: "nwse-resize", - ne: "nesw-resize", - se: "nwse-resize", - sw: "nesw-resize" - }; - var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ]; - var d3_time_format = d3_time.format = d3_locale_enUS.timeFormat; - var d3_time_formatUtc = d3_time_format.utc; - var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ"); - d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso; - function d3_time_formatIsoNative(date) { - return date.toISOString(); - } - d3_time_formatIsoNative.parse = function(string) { - var date = new Date(string); - return isNaN(date) ? null : date; - }; - d3_time_formatIsoNative.toString = d3_time_formatIso.toString; - d3_time.second = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 1e3) * 1e3); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 1e3); - }, function(date) { - return date.getSeconds(); - }); - d3_time.seconds = d3_time.second.range; - d3_time.seconds.utc = d3_time.second.utc.range; - d3_time.minute = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 6e4) * 6e4); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 6e4); - }, function(date) { - return date.getMinutes(); - }); - d3_time.minutes = d3_time.minute.range; - d3_time.minutes.utc = d3_time.minute.utc.range; - d3_time.hour = d3_time_interval(function(date) { - var timezone = date.getTimezoneOffset() / 60; - return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 36e5); - }, function(date) { - return date.getHours(); - }); - d3_time.hours = d3_time.hour.range; - d3_time.hours.utc = d3_time.hour.utc.range; - d3_time.month = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setDate(1); - return date; - }, function(date, offset) { - date.setMonth(date.getMonth() + offset); - }, function(date) { - return date.getMonth(); - }); - d3_time.months = d3_time.month.range; - d3_time.months.utc = d3_time.month.utc.range; - function d3_time_scale(linear, methods, format) { - function scale(x) { - return linear(x); - } - scale.invert = function(x) { - return d3_time_scaleDate(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return linear.domain().map(d3_time_scaleDate); - linear.domain(x); - return scale; - }; - function tickMethod(extent, count) { - var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target); - return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) { - return d / 31536e6; - }), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i]; - } - scale.nice = function(interval, skip) { - var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" && tickMethod(extent, interval); - if (method) interval = method[0], skip = method[1]; - function skipped(date) { - return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length; - } - return scale.domain(d3_scale_nice(domain, skip > 1 ? { - floor: function(date) { - while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1); - return date; - }, - ceil: function(date) { - while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1); - return date; - } - } : interval)); - }; - scale.ticks = function(interval, skip) { - var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" ? tickMethod(extent, interval) : !interval.range && [ { - range: interval - }, skip ]; - if (method) interval = method[0], skip = method[1]; - return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip); - }; - scale.tickFormat = function() { - return format; - }; - scale.copy = function() { - return d3_time_scale(linear.copy(), methods, format); - }; - return d3_scale_linearRebind(scale, linear); - } - function d3_time_scaleDate(t) { - return new Date(t); - } - var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ]; - var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ]; - var d3_time_scaleLocalFormat = d3_time_format.multi([ [ ".%L", function(d) { - return d.getMilliseconds(); - } ], [ ":%S", function(d) { - return d.getSeconds(); - } ], [ "%I:%M", function(d) { - return d.getMinutes(); - } ], [ "%I %p", function(d) { - return d.getHours(); - } ], [ "%a %d", function(d) { - return d.getDay() && d.getDate() != 1; - } ], [ "%b %d", function(d) { - return d.getDate() != 1; - } ], [ "%B", function(d) { - return d.getMonth(); - } ], [ "%Y", d3_true ] ]); - var d3_time_scaleMilliseconds = { - range: function(start, stop, step) { - return d3.range(Math.ceil(start / step) * step, +stop, step).map(d3_time_scaleDate); - }, - floor: d3_identity, - ceil: d3_identity - }; - d3_time_scaleLocalMethods.year = d3_time.year; - d3_time.scale = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); - }; - var d3_time_scaleUtcMethods = d3_time_scaleLocalMethods.map(function(m) { - return [ m[0].utc, m[1] ]; - }); - var d3_time_scaleUtcFormat = d3_time_formatUtc.multi([ [ ".%L", function(d) { - return d.getUTCMilliseconds(); - } ], [ ":%S", function(d) { - return d.getUTCSeconds(); - } ], [ "%I:%M", function(d) { - return d.getUTCMinutes(); - } ], [ "%I %p", function(d) { - return d.getUTCHours(); - } ], [ "%a %d", function(d) { - return d.getUTCDay() && d.getUTCDate() != 1; - } ], [ "%b %d", function(d) { - return d.getUTCDate() != 1; - } ], [ "%B", function(d) { - return d.getUTCMonth(); - } ], [ "%Y", d3_true ] ]); - d3_time_scaleUtcMethods.year = d3_time.year.utc; - d3_time.scale.utc = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleUtcMethods, d3_time_scaleUtcFormat); - }; - d3.text = d3_xhrType(function(request) { - return request.responseText; - }); - d3.json = function(url, callback) { - return d3_xhr(url, "application/json", d3_json, callback); - }; - function d3_json(request) { - return JSON.parse(request.responseText); - } - d3.html = function(url, callback) { - return d3_xhr(url, "text/html", d3_html, callback); - }; - function d3_html(request) { - var range = d3_document.createRange(); - range.selectNode(d3_document.body); - return range.createContextualFragment(request.responseText); - } - d3.xml = d3_xhrType(function(request) { - return request.responseXML; - }); - if (typeof define === "function" && define.amd) define(d3); else if (typeof module === "object" && module.exports) module.exports = d3; - this.d3 = d3; -}(); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/d3.v3.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/d3.v3.js deleted file mode 100644 index 77615c0c..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/d3.v3.js +++ /dev/null @@ -1,5 +0,0 @@ -d3=function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(){}function o(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function a(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=Do.length;r>e;++e){var u=Do[e]+t;if(u in n)return u}}function c(){}function l(){}function s(n){function t(){for(var t,r=e,u=-1,i=r.length;++ue;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function T(n){return Lo(n,Io),n}function q(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t0&&(n=n.substring(0,a));var s=Zo.get(n);return s&&(n=s,l=j),a?t?u:r:t?c:i}function D(n,t){return function(e){var r=mo.event;mo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{mo.event=r}}}function j(n,t){var e=D(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function L(){var n=".dragsuppress-"+ ++Xo,t="touchmove"+n,e="selectstart"+n,r="dragstart"+n,u="click"+n,i=mo.select(_o).on(t,f).on(e,f).on(r,f),o=bo.style,a=o[Vo];return o[Vo]="none",function(t){function e(){i.on(u,null)}i.on(n,null),o[Vo]=a,t&&(i.on(u,function(){f(),e()},!0),setTimeout(e,0))}}function H(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>$o&&(_o.scrollX||_o.scrollY)){e=mo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();$o=!(u.f||u.e),e.remove()}return $o?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function F(n){return n>0?1:0>n?-1:0}function P(n){return n>1?0:-1>n?Bo:Math.acos(n)}function O(n){return n>1?Jo:-1>n?-Jo:Math.asin(n)}function R(n){return((n=Math.exp(n))-1/n)/2}function Y(n){return((n=Math.exp(n))+1/n)/2}function I(n){return((n=Math.exp(2*n))-1)/(n+1)}function U(n){return(n=Math.sin(n/2))*n}function Z(){}function V(n,t,e){return new X(n,t,e)}function X(n,t,e){this.h=n,this.s=t,this.l=e}function $(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,ot(u(n+120),u(n),u(n-120))}function B(n,t,e){return new W(n,t,e)}function W(n,t,e){this.h=n,this.c=t,this.l=e}function J(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),G(e,Math.cos(n*=Qo)*t,Math.sin(n)*t)}function G(n,t,e){return new K(n,t,e)}function K(n,t,e){this.l=n,this.a=t,this.b=e}function Q(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=tt(u)*sa,r=tt(r)*fa,i=tt(i)*ha,ot(rt(3.2404542*u-1.5371385*r-.4985314*i),rt(-.969266*u+1.8760108*r+.041556*i),rt(.0556434*u-.2040259*r+1.0572252*i))}function nt(n,t,e){return n>0?B(Math.atan2(e,t)*na,Math.sqrt(t*t+e*e),n):B(0/0,0/0,n)}function tt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function et(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function rt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ut(n){return ot(n>>16,255&n>>8,255&n)}function it(n){return ut(n)+""}function ot(n,t,e){return new at(n,t,e)}function at(n,t,e){this.r=n,this.g=t,this.b=e}function ct(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function lt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(gt(u[0]),gt(u[1]),gt(u[2]))}return(i=da.get(n))?t(i.r,i.g,i.b):(null!=n&&"#"===n.charAt(0)&&(4===n.length?(o=n.charAt(1),o+=o,a=n.charAt(2),a+=a,c=n.charAt(3),c+=c):7===n.length&&(o=n.substring(1,3),a=n.substring(3,5),c=n.substring(5,7)),o=parseInt(o,16),a=parseInt(a,16),c=parseInt(c,16)),t(o,a,c))}function st(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),V(r,u,c)}function ft(n,t,e){n=ht(n),t=ht(t),e=ht(e);var r=et((.4124564*n+.3575761*t+.1804375*e)/sa),u=et((.2126729*n+.7151522*t+.072175*e)/fa),i=et((.0193339*n+.119192*t+.9503041*e)/ha);return G(116*u-16,500*(r-u),200*(u-i))}function ht(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function gt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function pt(n){return"function"==typeof n?n:function(){return n}}function dt(n){return n}function vt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),mt(t,e,n,r)}}function mt(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=mo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!_o.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=mo.event;mo.event=n;try{o.progress.call(i,c)}finally{mo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Mo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},mo.rebind(i,o,"on"),null==r?i:i.get(yt(r))}function yt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Mt(){var n=bt(),t=_t()-n;t>24?(isFinite(t)&&(clearTimeout(Ma),Ma=setTimeout(Mt,t)),ya=0):(ya=1,ba(Mt))}function xt(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now()),xa.callback=n,xa.time=e+t}function bt(){var n=Date.now();for(xa=va;xa;)n>=xa.time&&(xa.flush=xa.callback(n-xa.time)),xa=xa.next;return n}function _t(){for(var n,t=va,e=1/0;t;)t.flush?t=n?n.next=t.next:va=t.next:(t.time8?function(n){return n/e}:function(n){return n*e},symbol:n}}function St(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Et(n){return n+""}function kt(){}function At(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function Nt(n,t){n&&Da.hasOwnProperty(n.type)&&Da[n.type](n,t)}function Tt(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++ua;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c={point:e,points:n,other:null,visited:!1,entry:!0,subject:!0},l={point:e,points:[e],other:c,visited:!1,entry:!1,subject:!1};c.other=l,i.push(c),o.push(l),c={point:r,points:[r],other:null,visited:!1,entry:!1,subject:!0},l={point:r,points:[r],other:c,visited:!1,entry:!0,subject:!1},c.other=l,i.push(c),o.push(l)}}),o.sort(t),$t(i),$t(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].entry=c=!c;for(var s,f,h,g=i[0];;){for(s=g;s.visited;)if((s=s.next)===g)return;f=s.points,u.lineStart();do{if(s.visited=s.other.visited=!0,s.entry){if(s.subject)for(var a=0;a=0;)u.point((h=f[a])[0],h[1])}else r(s.point,s.prev.point,-1,u);s=s.prev}s=s.other,f=s.points}while(!s.visited);u.lineEnd()}}}function $t(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Wt))}}var g,p,d,v=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=mo.merge(g);var n=Kt(m,p);g.length?Xt(g,Gt,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Jt(),x=t(M);return y}}function Wt(n){return n.length>1}function Jt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:c,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Gt(n,t){return((n=n.point)[0]<0?n[1]-Jo-Go:Jo-n[1])-((t=t.point)[0]<0?t[1]-Jo-Go:Jo-t[1])}function Kt(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;La.reset();for(var a=0,c=t.length;c>a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+Bo/4,p=Math.sin(g),d=Math.cos(g),v=1;;){v===s&&(v=0),n=l[v];var m=n[0],y=n[1]/2+Bo/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=Math.abs(b)>Bo,w=p*M;if(La.add(Math.atan2(w*Math.sin(b),d*x+w*Math.cos(b))),i+=_?b+(b>=0?2:-2)*Bo:b,_^h>=e^m>=e){var S=jt(Ct(f),Ct(n));Ft(S);var E=jt(u,S);Ft(E);var k=(_^b>=0?-1:1)*O(E[2]);(r>k||r===k&&(S[0]||S[1]))&&(o+=_^b>=0?1:-1)}if(!v++)break;h=m,p=M,d=x,f=n}}return(-Go>i||Go>i&&0>La)^1&o}function Qt(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Bo:-Bo,c=Math.abs(i-e);Math.abs(c-Bo)0?Jo:-Jo),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Bo&&(Math.abs(e-u)Go?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function te(n,t,e,r){var u;if(null==n)u=e*Jo,r.point(-Bo,u),r.point(0,u),r.point(Bo,u),r.point(Bo,0),r.point(Bo,-u),r.point(0,-u),r.point(-Bo,-u),r.point(-Bo,0),r.point(-Bo,u);else if(Math.abs(n[0]-t[0])>Go){var i=(n[0]i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],d=t(f,h),v=o?d?0:u(f,h):d?u(f+(0>f?Bo:-Bo),h):0;if(!e&&(l=c=d)&&n.lineStart(),d!==c&&(g=r(e,p),(Ot(e,g)||Ot(p,g))&&(p[0]+=Go,p[1]+=Go,d=t(p[0],p[1]))),d!==c)s=0,d?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^d){var m;v&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!d||e&&Ot(e,p)||n.point(p[0],p[1]),e=p,c=d,i=v},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=Ct(n),u=Ct(t),o=[1,0,0],a=jt(r,u),c=Dt(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=jt(o,a),p=Ht(o,f),d=Ht(a,h);Lt(p,d);var v=g,m=Dt(p,v),y=Dt(v,v),M=m*m-y*(Dt(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=Ht(v,(-m-x)/y);if(Lt(b,p),b=Pt(b),!e)return b;var _,w=n[0],S=t[0],E=n[1],k=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=Math.abs(A-Bo)A;if(!N&&E>k&&(_=E,E=k,k=_),T?N?E+k>0^b[1]<(Math.abs(b[0]-w)Bo^(w<=b[0]&&b[0]<=S)){var q=Ht(v,(-m+x)/y);return Lt(q,p),[b,Pt(q)]}}}function u(t,e){var r=o?n:Bo-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=Math.abs(i)>Go,c=Te(n,6*Qo);return Bt(t,e,c,o?[0,-n]:[-Bo,n-Bo])}function re(n,t,e,r){function u(r,u){return Math.abs(r[0]-n)0?0:3:Math.abs(r[0]-e)0?2:1:Math.abs(r[1]-t)0?1:0:u>0?3:2}function i(n,t){return o(n.point,t.point)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}function a(u,i){var o=i[0]-u[0],a=i[1]-u[1],c=[0,1];return Math.abs(o)0&&(u[0]+=c[0]*o,u[1]+=c[0]*a),!0):!1}return function(c){function l(n){for(var t=0,e=y.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=y[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&s(l,i,n)>0&&++t:i[1]<=r&&s(l,i,n)<0&&--t,l=i;return 0!==t}function s(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(e[0]-n[0])*(t[1]-n[1])}function f(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function h(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function g(n,t){h(n,t)&&c.point(n,t)}function p(){q.point=v,y&&y.push(M=[]),k=!0,E=!1,w=S=0/0}function d(){m&&(v(x,b),_&&E&&T.rejoin(),m.push(T.buffer())),q.point=g,E&&c.lineEnd()}function v(n,t){n=Math.max(-Ja,Math.min(Ja,n)),t=Math.max(-Ja,Math.min(Ja,t));var e=h(n,t);if(y&&M.push([n,t]),k)x=n,b=t,_=e,k=!1,e&&(c.lineStart(),c.point(n,t));else if(e&&E)c.point(n,t);else{var r=[w,S],u=[n,t];a(r,u)?(E||(c.lineStart(),c.point(r[0],r[1])),c.point(u[0],u[1]),e||c.lineEnd(),A=!1):e&&(c.lineStart(),c.point(n,t),A=!1)}w=n,S=t,E=e}var m,y,M,x,b,_,w,S,E,k,A,N=c,T=Jt(),q={point:g,lineStart:p,lineEnd:d,polygonStart:function(){c=T,m=[],y=[],A=!0},polygonEnd:function(){c=N,m=mo.merge(m);var t=l([n,r]),e=A&&t,u=m.length;(e||u)&&(c.polygonStart(),e&&(c.lineStart(),f(null,null,1,c),c.lineEnd()),u&&Xt(m,i,t,f,c),c.polygonEnd()),m=y=M=null}};return q}}function ue(n,t,e){if(Math.abs(t)=n;var r=n/t;if(t>0){if(r>e[1])return!1;r>e[0]&&(e[0]=r)}else{if(rn&&(Qa=n),n>tc&&(tc=n),nc>t&&(nc=t),t>ec&&(ec=t)}function se(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=fe(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=fe(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function fe(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function he(n,t){Oa+=n,Ra+=t,++Ya}function ge(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);Ia+=o*(t+n)/2,Ua+=o*(e+r)/2,Za+=o,he(t=n,e=r)}var t,e;ic.point=function(r,u){ic.point=n,he(t=r,e=u)}}function pe(){ic.point=he}function de(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);Ia+=o*(r+n)/2,Ua+=o*(u+t)/2,Za+=o,o=u*n-r*t,Va+=o*(r+n),Xa+=o*(u+t),$a+=3*o,he(r=n,u=t)}var t,e,r,u;ic.point=function(i,o){ic.point=n,he(t=r=i,e=u=o)},ic.lineEnd=function(){n(t,e)}}function ve(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,Wo)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:c};return a}function me(n){function t(t){function r(e,r){e=n(e,r),t.point(e[0],e[1])}function u(){M=0/0,S.point=o,t.lineStart()}function o(r,u){var o=Ct([r,u]),a=n(r,u);e(M,x,y,b,_,w,M=a[0],x=a[1],y=r,b=o[0],_=o[1],w=o[2],i,t),t.point(M,x)}function a(){S.point=r,t.lineEnd()}function c(){u(),S.point=l,S.lineEnd=s}function l(n,t){o(f=n,h=t),g=M,p=x,d=b,v=_,m=w,S.point=o}function s(){e(M,x,y,b,_,w,g,p,f,d,v,m,i,t),S.lineEnd=a,a()}var f,h,g,p,d,v,m,y,M,x,b,_,w,S={point:r,lineStart:u,lineEnd:a,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=u}};return S}function e(t,i,o,a,c,l,s,f,h,g,p,d,v,m){var y=s-t,M=f-i,x=y*y+M*M;if(x>4*r&&v--){var b=a+g,_=c+p,w=l+d,S=Math.sqrt(b*b+_*_+w*w),E=Math.asin(w/=S),k=Math.abs(Math.abs(w)-1)r||Math.abs((y*q+M*z)/x-.5)>.3||u>a*g+c*p+l*d)&&(e(t,i,o,a,c,l,N,T,k,b/=S,_/=S,w,v,m),m.point(N,T),e(N,T,k,b,_,w,s,f,h,g,p,d,v,m))}}var r=.5,u=Math.cos(30*Qo),i=16;return t.precision=function(n){return arguments.length?(i=(r=n*n)>0&&16,t):Math.sqrt(r)},t}function ye(n){this.stream=n}function Me(n){var t=me(function(t,e){return n([t*na,e*na])});return function(n){var e=new ye(n=t(n));return e.point=function(t,e){n.point(t*Qo,e*Qo)},e}}function xe(n){return be(function(){return n})()}function be(n){function t(n){return n=a(n[0]*Qo,n[1]*Qo),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*na,n[1]*na]}function r(){a=ie(o=Ee(m,y,M),i);var n=i(d,v);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=me(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,d=0,v=0,m=0,y=0,M=0,x=Wa,b=dt,_=null,w=null;return t.stream=function(n){return s&&(s.valid=!1),s=_e(x(o,f(b(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(x=null==n?(_=n,Wa):ee((_=+n)*Qo),u()):_},t.clipExtent=function(n){return arguments.length?(w=n,b=n?re(n[0][0],n[0][1],n[1][0],n[1][1]):dt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(d=n[0]%360*Qo,v=n[1]%360*Qo,r()):[d*na,v*na]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Qo,y=n[1]%360*Qo,M=n.length>2?n[2]%360*Qo:0,r()):[m*na,y*na,M*na]},mo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function _e(n){var t=new ye(n);return t.point=function(t,e){n.point(t*Qo,e*Qo)},t}function we(n,t){return[n,t]}function Se(n,t){return[n>Bo?n-Wo:-Bo>n?n+Wo:n,t]}function Ee(n,t,e){return n?t||e?ie(Ae(n),Ne(t,e)):Ae(n):t||e?Ne(t,e):Se}function ke(n){return function(t,e){return t+=n,[t>Bo?t-Wo:-Bo>t?t+Wo:t,e]}}function Ae(n){var t=ke(n);return t.invert=ke(-n),t}function Ne(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),O(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),O(s*r-a*u)]},e}function Te(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=qe(e,u),i=qe(e,i),(o>0?i>u:u>i)&&(u+=o*Wo)):(u=n+o*Wo,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=Pt([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function qe(n,t){var e=Ct(t);e[0]-=n,Ft(e);var r=P(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Go)%(2*Math.PI)}function ze(n,t,e){var r=mo.range(n,t-Go,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function Ce(n,t,e){var r=mo.range(n,t-Go,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function De(n){return n.source}function je(n){return n.target}function Le(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(U(r-t)+u*o*U(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*na,Math.atan2(o,Math.sqrt(r*r+u*u))*na]}:function(){return[n*na,t*na]};return p.distance=h,p}function He(){function n(n,u){var i=Math.sin(u*=Qo),o=Math.cos(u),a=Math.abs((n*=Qo)-t),c=Math.cos(a);oc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;ac.point=function(u,i){t=u*Qo,e=Math.sin(i*=Qo),r=Math.cos(i),ac.point=n},ac.lineEnd=function(){ac.point=ac.lineEnd=c}}function Fe(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function Pe(n,t){function e(n,t){var e=Math.abs(Math.abs(t)-Jo)1&&u.push("H",r[0]),u.join("")}function We(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function fr(n){return n.length<3?Xe(n):n[0]+nr(n,sr(n))}function hr(n,t,e,r){var u,i,o,a,c,l,s;return u=r[n],i=u[0],o=u[1],u=r[t],a=u[0],c=u[1],u=r[e],l=u[0],s=u[1],(s-o)*(a-i)-(c-o)*(l-i)>0}function gr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function pr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function dr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function vr(n,t){var e={list:n.map(function(n,t){return{index:t,x:n[0],y:n[1]}}).sort(function(n,t){return n.yt.y?1:n.xt.x?1:0}),bottomSite:null},r={list:[],leftEnd:null,rightEnd:null,init:function(){r.leftEnd=r.createHalfEdge(null,"l"),r.rightEnd=r.createHalfEdge(null,"l"),r.leftEnd.r=r.rightEnd,r.rightEnd.l=r.leftEnd,r.list.unshift(r.leftEnd,r.rightEnd)},createHalfEdge:function(n,t){return{edge:n,side:t,vertex:null,l:null,r:null}},insert:function(n,t){t.l=n,t.r=n.r,n.r.l=t,n.r=t},leftBound:function(n){var t=r.leftEnd;do t=t.r;while(t!=r.rightEnd&&u.rightOf(t,n));return t=t.l},del:function(n){n.l.r=n.r,n.r.l=n.l,n.edge=null},right:function(n){return n.r},left:function(n){return n.l},leftRegion:function(n){return null==n.edge?e.bottomSite:n.edge.region[n.side]},rightRegion:function(n){return null==n.edge?e.bottomSite:n.edge.region[yc[n.side]]}},u={bisect:function(n,t){var e={region:{l:n,r:t},ep:{l:null,r:null}},r=t.x-n.x,u=t.y-n.y,i=r>0?r:-r,o=u>0?u:-u;return e.c=n.x*r+n.y*u+.5*(r*r+u*u),i>o?(e.a=1,e.b=u/r,e.c/=r):(e.b=1,e.a=r/u,e.c/=u),e},intersect:function(n,t){var e=n.edge,r=t.edge;if(!e||!r||e.region.r==r.region.r)return null;var u=e.a*r.b-e.b*r.a;if(Math.abs(u)<1e-10)return null;var i,o,a=(e.c*r.b-r.c*e.b)/u,c=(r.c*e.a-e.c*r.a)/u,l=e.region.r,s=r.region.r;l.y=o.region.r.x;return f&&"l"===i.side||!f&&"r"===i.side?null:{x:a,y:c}},rightOf:function(n,t){var e=n.edge,r=e.region.r,u=t.x>r.x;if(u&&"l"===n.side)return 1;if(!u&&"r"===n.side)return 0;if(1===e.a){var i=t.y-r.y,o=t.x-r.x,a=0,c=0;if(!u&&e.b<0||u&&e.b>=0?c=a=i>=e.b*o:(c=t.x+t.y*e.b>e.c,e.b<0&&(c=!c),c||(a=1)),!a){var l=r.x-e.region.l.x;c=e.b*(o*o-i*i)h*h+g*g}return"l"===n.side?c:!c},endPoint:function(n,e,r){n.ep[e]=r,n.ep[yc[e]]&&t(n)},distance:function(n,t){var e=n.x-t.x,r=n.y-t.y;return Math.sqrt(e*e+r*r)}},i={list:[],insert:function(n,t,e){n.vertex=t,n.ystar=t.y+e;for(var r=0,u=i.list,o=u.length;o>r;r++){var a=u[r];if(!(n.ystar>a.ystar||n.ystar==a.ystar&&t.x>a.vertex.x))break}u.splice(r,0,n)},del:function(n){for(var t=0,e=i.list,r=e.length;r>t&&e[t]!=n;++t);e.splice(t,1)},empty:function(){return 0===i.list.length},nextEvent:function(n){for(var t=0,e=i.list,r=e.length;r>t;++t)if(e[t]==n)return e[t+1];return null},min:function(){var n=i.list[0];return{x:n.vertex.x,y:n.ystar}},extractMin:function(){return i.list.shift()}};r.init(),e.bottomSite=e.list.shift();for(var o,a,c,l,s,f,h,g,p,d,v,m,y,M=e.list.shift();;)if(i.empty()||(o=i.min()),M&&(i.empty()||M.yg.y&&(p=h,h=g,g=p,y="r"),m=u.bisect(h,g),f=r.createHalfEdge(m,y),r.insert(l,f),u.endPoint(m,yc[y],v),d=u.intersect(l,f),d&&(i.del(l),i.insert(l,d,u.distance(d,h))),d=u.intersect(f,s),d&&i.insert(f,d,u.distance(d,h))}for(a=r.right(r.leftEnd);a!=r.rightEnd;a=r.right(a))t(a.edge)}function mr(n){return n.x}function yr(n){return n.y}function Mr(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function xr(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&xr(n,c[0],e,r,o,a),c[1]&&xr(n,c[1],o,r,u,a),c[2]&&xr(n,c[2],e,a,o,i),c[3]&&xr(n,c[3],o,a,u,i)}}function br(n,t){n=mo.rgb(n),t=mo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+ct(Math.round(e+i*n))+ct(Math.round(r+o*n))+ct(Math.round(u+a*n))}}function _r(n,t){var e,r={},u={};for(e in n)e in t?r[e]=Er(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function wr(n,t){return t-=n=+n,function(e){return n+t*e}}function Sr(n,t){var e,r,u,i,o,a=0,c=0,l=[],s=[];for(n+="",t+="",Mc.lastIndex=0,r=0;e=Mc.exec(t);++r)e.index&&l.push(t.substring(a,c=e.index)),s.push({i:l.length,x:e[0]}),l.push(null),a=Mc.lastIndex;for(ar;++r)if(o=s[r],o.x==e[0]){if(o.i)if(null==l[o.i+1])for(l[o.i-1]+=o.x,l.splice(o.i,1),u=r+1;i>u;++u)s[u].i--;else for(l[o.i-1]+=o.x+l[o.i+1],l.splice(o.i,2),u=r+1;i>u;++u)s[u].i-=2;else if(null==l[o.i+1])l[o.i]=o.x;else for(l[o.i]=o.x+l[o.i+1],l.splice(o.i+1,1),u=r+1;i>u;++u)s[u].i--;s.splice(r,1),i--,r--}else o.x=wr(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=s.pop(),null==l[o.i+1]?l[o.i]=o.x:(l[o.i]=o.x+l[o.i+1],l.splice(o.i+1,1)),i--;return 1===l.length?null==l[0]?(o=s[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)l[(o=s[r]).i]=o.x(n);return l.join("")}}function Er(n,t){for(var e,r=mo.interpolators.length;--r>=0&&!(e=mo.interpolators[r](n,t)););return e}function kr(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Er(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Ar(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function Nr(n){return function(t){return 1-n(1-t)}}function Tr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function qr(n){return n*n}function zr(n){return n*n*n}function Cr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Dr(n){return function(t){return Math.pow(t,n)}}function jr(n){return 1-Math.cos(n*Jo)}function Lr(n){return Math.pow(2,10*(n-1))}function Hr(n){return 1-Math.sqrt(1-n*n)}function Fr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Wo*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Wo/t)}}function Pr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Or(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=mo.hcl(n),t=mo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return J(e+i*n,r+o*n,u+a*n)+""}}function Yr(n,t){n=mo.hsl(n),t=mo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return $(e+i*n,r+o*n,u+a*n)+""}}function Ir(n,t){n=mo.lab(n),t=mo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return Q(e+i*n,r+o*n,u+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Zr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Xr(t),u=Vr(t,e),i=Xr($r(e,t,-u))||0;t[0]*e[1]180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:wr(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:wr(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:wr(g[0],p[0])},{i:e-2,x:wr(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++ie;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function vu(n){return n.reduce(mu,0)}function mu(n,t){return n+t[1]}function yu(n,t){return Mu(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function Mu(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function xu(n){return[mo.min(n),mo.max(n)]}function bu(n,t){return n.parent==t.parent?1:2}function _u(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function wu(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function Su(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i0&&(n=r);return n}function Eu(n,t){return n.x-t.x}function ku(n,t){return t.x-n.x}function Au(n,t){return n.depth-t.depth}function Nu(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function qu(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function zu(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function Cu(n,t){return n.value-t.value}function Du(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function ju(n,t){n._pack_next=t,t._pack_prev=n}function Lu(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Hu(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(Fu),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],Ru(r,u,i),t(i),Du(r,i),r._pack_prev=i,Du(i,u),u=r._pack_next,o=3;l>o;o++){Ru(r,u,i=e[o]);var p=0,d=1,v=1;for(a=u._pack_next;a!==u;a=a._pack_next,d++)if(Lu(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!Lu(c,i);c=c._pack_prev,v++);p?(v>d||d==v&&u.ro;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(Pu)}}function Fu(n){n._pack_next=n._pack_prev=n}function Pu(n){delete n._pack_next,delete n._pack_prev}function Ou(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++iu&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function $u(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Bu(n){return n.rangeExtent?n.rangeExtent():$u(n.range())}function Wu(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Ju(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Gu(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Tc}function Ku(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Ku:Wu,c=r?Jr:Wr;return o=u(n,t,c,e),a=u(t,n,c,Er),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Ur)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return ri(n,t)},i.tickFormat=function(t,e){return ui(n,t,e)},i.nice=function(t){return ti(n,t),u()},i.copy=function(){return Qu(n,t,e,r)},u()}function ni(n,t){return mo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function ti(n,t){return Ju(n,Gu(ei(n,t)[2]))}function ei(n,t){null==t&&(t=10);var e=$u(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function ri(n,t){return mo.range.apply(mo,ei(n,t))}function ui(n,t,e){var r=-Math.floor(Math.log(ei(n,t)[2])/Math.LN10+.01);return mo.format(e?e.replace(Aa,function(n,t,e,u,i,o,a,c,l,s){return[t,e,u,i,o,a,c,l||"."+(r-2*("%"===s)),s].join("")}):",."+r+"f")}function ii(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Ju(r.map(u),e?Math:zc);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=$u(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++0;h--)o.push(i(l)*h);for(l=0;o[l]c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return qc;arguments.length<2?t=qc:"function"!=typeof t&&(t=mo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return ii(n.copy(),t,e,r)},ni(o,n)}function oi(n,t,e){function r(t){return n(u(t))}var u=ai(t),i=ai(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return ri(e,n)},r.tickFormat=function(n,t){return ui(e,n,t)},r.nice=function(n){return r.domain(ti(e,n))},r.exponent=function(o){return arguments.length?(u=ai(t=o),i=ai(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return oi(n.copy(),t,e)},ni(r,n)}function ai(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ci(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return mo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++ae?[0/0,0/0]:[e>0?u[e-1]:n[0],et?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return si(n,t,e)},u()}function fi(n,t){function e(e){return e>=e?t[mo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return fi(n,t)},e}function hi(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return ri(n,t)},t.tickFormat=function(t,e){return ui(n,t,e)},t.copy=function(){return hi(n)},t}function gi(n){return n.innerRadius}function pi(n){return n.outerRadius}function di(n){return n.startAngle}function vi(n){return n.endAngle}function mi(n){for(var t,e,r,u=-1,i=n.length;++ue?l():(i.active=e,o.event&&o.event.start.call(n,s,t),o.tween.forEach(function(e,r){(r=r.call(n,s,t))&&p.push(r)}),c(r||1)?1:(xt(c,h,a),void 0))}function c(r){if(i.active!==e)return l();for(var u=r/g,a=f(u),c=p.length;c>0;)p[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,s,t),l()):void 0}function l(){return--i.count?delete i[e]:delete n.__transition__,1}var s=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=[];return r>=h?u(r-h):(xt(u,h,a),void 0)},0,a)}}function Ti(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function qi(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function zi(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ci(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new Jc(e-1)),1),e}function i(n,e){return t(n=new Jc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{Jc=zi;var r=new zi;return r._=n,o(r,t,e)}finally{Jc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Di(n);return c.floor=c,c.round=Di(r),c.ceil=Di(u),c.offset=Di(i),c.range=a,n}function Di(n){return function(t,e){try{Jc=zi;var r=new zi;return r._=t,n(r,e)._}finally{Jc=Date}}}function ji(n){function t(t){for(var r,u,i,o=[],a=-1,c=0;++aa;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=ml[o in dl?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function Hi(n){return new RegExp("^(?:"+n.map(mo.requote).join("|")+")","i")}function Fi(n){for(var t=new u,e=-1,r=n.length;++en?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Oi(n,t,e){cl.lastIndex=0;var r=cl.exec(t.substring(e));return r?(n.w=ll.get(r[0].toLowerCase()),e+r[0].length):-1}function Ri(n,t,e){ol.lastIndex=0;var r=ol.exec(t.substring(e));return r?(n.w=al.get(r[0].toLowerCase()),e+r[0].length):-1}function Yi(n,t,e){yl.lastIndex=0;var r=yl.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ii(n,t,e){yl.lastIndex=0;var r=yl.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Ui(n,t,e){yl.lastIndex=0;var r=yl.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function Zi(n,t,e){hl.lastIndex=0;var r=hl.exec(t.substring(e));return r?(n.m=gl.get(r[0].toLowerCase()),e+r[0].length):-1}function Vi(n,t,e){sl.lastIndex=0;var r=sl.exec(t.substring(e));return r?(n.m=fl.get(r[0].toLowerCase()),e+r[0].length):-1}function Xi(n,t,e){return Li(n,vl.c.toString(),t,e)}function $i(n,t,e){return Li(n,vl.x.toString(),t,e)}function Bi(n,t,e){return Li(n,vl.X.toString(),t,e)}function Wi(n,t,e){yl.lastIndex=0;var r=yl.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Ji(n,t,e){yl.lastIndex=0;var r=yl.exec(t.substring(e,e+2));return r?(n.y=Ki(+r[0]),e+r[0].length):-1}function Gi(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Ki(n){return n+(n>68?1900:2e3)}function Qi(n,t,e){yl.lastIndex=0;var r=yl.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function no(n,t,e){yl.lastIndex=0;var r=yl.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function to(n,t,e){yl.lastIndex=0;var r=yl.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function eo(n,t,e){yl.lastIndex=0;var r=yl.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ro(n,t,e){yl.lastIndex=0;var r=yl.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function uo(n,t,e){yl.lastIndex=0;var r=yl.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function io(n,t,e){yl.lastIndex=0;var r=yl.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function oo(n,t,e){var r=Ml.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}function ao(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(Math.abs(t)/60),u=Math.abs(t)%60;return e+Pi(r,"0",2)+Pi(u,"0",2)}function co(n,t,e){pl.lastIndex=0;var r=pl.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function lo(n){function t(n){try{Jc=zi;var t=new Jc;return t._=n,e(t)}finally{Jc=Date}}var e=ji(n);return t.parse=function(n){try{Jc=zi;var t=e.parse(n);return t&&t._}finally{Jc=Date}},t.toString=e.toString,t}function so(n){return n.toISOString()}function fo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=mo.bisect(bl,u);return i==bl.length?[t.year,ei(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/bl[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=ho(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=ho(+t+1);return t}}:n))},r.ticks=function(n,t){var e=$u(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],ho(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return fo(n.copy(),t,e)},ni(r,n)}function ho(n){return new Date(n)}function go(n){return function(t){for(var e=n.length-1,r=n[e];!r[1](t);)r=n[--e];return r[0](t)}}function po(n){return JSON.parse(n.responseText)}function vo(n){var t=xo.createRange();return t.selectNode(xo.body),t.createContextualFragment(n.responseText)}var mo={version:"3.3.6"};Date.now||(Date.now=function(){return+new Date});var yo=[].slice,Mo=function(n){return yo.call(n)},xo=document,bo=xo.documentElement,_o=window;try{Mo(bo.childNodes)[0].nodeType}catch(wo){Mo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{xo.createElement("div").style.setProperty("opacity",0,"")}catch(So){var Eo=_o.Element.prototype,ko=Eo.setAttribute,Ao=Eo.setAttributeNS,No=_o.CSSStyleDeclaration.prototype,To=No.setProperty;Eo.setAttribute=function(n,t){ko.call(this,n,t+"")},Eo.setAttributeNS=function(n,t,e){Ao.call(this,n,t,e+"")},No.setProperty=function(n,t,e){To.call(this,n,t+"",e)}}mo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},mo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},mo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ur&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ur&&(e=r)}return e},mo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ue&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ue&&(e=r)}return e},mo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=e);)e=u=void 0;for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=e);)e=void 0;for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},mo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i1&&(t=t.map(e)),t=t.filter(n),t.length?mo.quantile(t.sort(mo.ascending),.5):void 0},mo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)r;){var i=r+u>>>1;er?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},mo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=mo.min(arguments,t),r=new Array(e);++nr)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var l,s,f,h,g=-1,p=a.length,d=o[c++],v=new u;++g=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(mo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},mo.set=function(n){var t=new i;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(i,{has:function(n){return zo+n in this},add:function(n){return this[zo+n]=!0,n},remove:function(n){return n=zo+n,n in this&&delete this[n]},values:function(){var n=[];return this.forEach(function(t){n.push(t)}),n},forEach:function(n){for(var t in this)t.charCodeAt(0)===Co&&n.call(this,t.substring(1))}}),mo.behavior={},mo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},mo.event=null,mo.requote=function(n){return n.replace(jo,"\\$&")};var jo=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,Lo={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ho=function(n,t){return t.querySelector(n)},Fo=function(n,t){return t.querySelectorAll(n)},Po=bo[a(bo,"matchesSelector")],Oo=function(n,t){return Po.call(n,t)};"function"==typeof Sizzle&&(Ho=function(n,t){return Sizzle(n,t)[0]||null},Fo=function(n,t){return Sizzle.uniqueSort(Sizzle(n,t))},Oo=Sizzle.matchesSelector),mo.selection=function(){return Uo};var Ro=mo.selection.prototype=[];Ro.select=function(n){var t,e,r,u,i=[];n=d(n);for(var o=-1,a=this.length;++o=0&&(e=n.substring(0,t),n=n.substring(t+1)),Yo.hasOwnProperty(e)?{space:Yo[e],local:n}:n}},Ro.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=mo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(m(t,n[t]));return this}return this.each(m(n,t))},Ro.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=n.trim().split(/^|\s+/g)).length,u=-1;if(t=e.classList){for(;++ur){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(_(e,n[e],t));return this}if(2>r)return _o.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(_(n,t,e))},Ro.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(w(t,n[t]));return this}return this.each(w(n,t))},Ro.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Ro.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Ro.append=function(n){return n=S(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Ro.insert=function(n,t){return n=S(n),t=d(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments))})},Ro.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},Ro.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),d=new Array(a);if(t){var v,m=new u,y=new u,M=[];for(r=-1;++rr;++r)p[r]=E(e[r]);for(;a>r;++r)d[r]=n[r]}p.update=g,p.parentNode=g.parentNode=d.parentNode=n.parentNode,c.push(p),l.push(g),s.push(d)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++oi;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a)&&t.push(r)}return p(u)},Ro.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},Ro.sort=function(n){n=A.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},Ro.size=function(){var n=0;return this.each(function(){++n}),n};var Io=[];mo.selection.enter=T,mo.selection.enter.prototype=Io,Io.append=Ro.append,Io.empty=Ro.empty,Io.node=Ro.node,Io.call=Ro.call,Io.size=Ro.size,Io.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(C(n,t,e))};var Zo=mo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Zo.forEach(function(n){"on"+n in xo&&Zo.remove(n)});var Vo=a(bo.style,"userSelect"),Xo=0;mo.mouse=function(n){return H(n,h())};var $o=/WebKit/.test(_o.navigator.userAgent)?-1:0;mo.touches=function(n,t){return arguments.length<2&&(t=h().touches),t?Mo(t).map(function(t){var e=H(n,t);return e.identifier=t.identifier,e}):[]},mo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return mo.event.changedTouches[0].identifier}function e(n,t){return mo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(s,g),e=n[0]-d[0],r=n[1]-d[1];v|=e|r,d=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(v&&mo.event.target===h),f({type:"dragend"})}var c,l=this,s=l.parentNode,f=u.of(l,arguments),h=mo.event.target,g=n(),p=null==g?"drag":"drag-"+g,d=t(s,g),v=0,m=mo.select(_o).on(e+"."+p,o).on(r+"."+p,a),y=L();i?(c=i.apply(l,arguments),c=[c.x-d[0],c.y-d[1]]):c=[0,0],f({type:"dragstart"})}}var u=g(n,"drag","dragstart","dragend"),i=null,o=r(c,mo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},mo.rebind(n,u,"on")};var Bo=Math.PI,Wo=2*Bo,Jo=Bo/2,Go=1e-6,Ko=Go*Go,Qo=Bo/180,na=180/Bo,ta=Math.SQRT2,ea=2,ra=4;mo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=Y(d),o=i/(ea*h)*(e*I(ta*t+d)-R(d));return[r+o*l,u+o*s,i*e/Y(ta*t+d)]}return[r+n*l,u+n*s,i*Math.exp(ta*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+ra*f)/(2*i*ea*h),p=(c*c-i*i-ra*f)/(2*c*ea*h),d=Math.log(Math.sqrt(g*g+1)-g),v=Math.log(Math.sqrt(p*p+1)-p),m=v-d,y=(m||Math.log(c/i))/ta;return e.duration=1e3*y,e},mo.behavior.zoom=function(){function n(n){n.on(A,l).on(oa+".zoom",h).on(N,p).on("dblclick.zoom",d).on(q,s)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(k[0],Math.min(k[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){b&&b.domain(x.range().map(function(n){return(n-S.x)/S.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-S.y)/S.k}).map(_.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function l(){function n(){s=1,u(mo.mouse(r),h),a(i)}function e(){f.on(N,_o===r?p:null).on(T,null),g(s&&mo.event.target===l),c(i)}var r=this,i=C.of(r,arguments),l=mo.event.target,s=0,f=mo.select(_o).on(N,n).on(T,e),h=t(mo.mouse(r)),g=L();z.call(r),o(i)}function s(){function n(){var n=mo.touches(p);return g=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=mo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-M){var l=o[0],s=v[l.identifier];r(2*S.k),u(l,s),f(),a(d)}M=c}else if(o.length>1){var l=o[0],h=o[1],g=l[0]-h[0],p=l[1]-h[1];m=g*g+p*p}}function i(){for(var n,t,e,i,o=mo.touches(p),c=0,l=o.length;l>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*g)}M=null,u(n,t),a(d)}function h(){if(mo.event.touches.length){for(var t=mo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}_.on(x,null).on(b,null),w.on(A,l).on(q,s),E(),c(d)}var g,p=this,d=C.of(p,arguments),v={},m=0,y=mo.event.changedTouches[0].identifier,x="touchmove.zoom-"+y,b="touchend.zoom-"+y,_=mo.select(_o).on(x,i).on(b,h),w=mo.select(p).on(A,null).on(q,e),E=L();z.call(p),e(),o(d)}function h(){var n=C.of(this,arguments);y?clearTimeout(y):(z.call(this),o(n)),y=setTimeout(function(){y=null,c(n)},50),f();var e=m||mo.mouse(this);v||(v=t(e)),r(Math.pow(2,.002*ua())*S.k),u(e,v),a(n)}function p(){v=null}function d(){var n=C.of(this,arguments),e=mo.mouse(this),i=t(e),l=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,mo.event.shiftKey?Math.ceil(l)-1:Math.floor(l)+1)),u(e,i),a(n),c(n)}var v,m,y,M,x,b,_,w,S={x:0,y:0,k:1},E=[960,500],k=ia,A="mousedown.zoom",N="mousemove.zoom",T="mouseup.zoom",q="touchstart.zoom",C=g(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=C.of(this,arguments),t=S;Oc?mo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],u=e/2,i=r/2,o=mo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(k=null==t?ia:[+t[0],+t[1]],n):k},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.x=function(t){return arguments.length?(b=t,x=t.copy(),S={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),S={x:0,y:0,k:1},n):w},mo.rebind(n,C,"on")};var ua,ia=[0,1/0],oa="onwheel"in xo?(ua=function(){return-mo.event.deltaY*(mo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in xo?(ua=function(){return mo.event.wheelDelta},"mousewheel"):(ua=function(){return-mo.event.detail},"MozMousePixelScroll");Z.prototype.toString=function(){return this.rgb()+""},mo.hsl=function(n,t,e){return 1===arguments.length?n instanceof X?V(n.h,n.s,n.l):lt(""+n,st,V):V(+n,+t,+e)};var aa=X.prototype=new Z;aa.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),V(this.h,this.s,this.l/n)},aa.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),V(this.h,this.s,n*this.l)},aa.rgb=function(){return $(this.h,this.s,this.l)},mo.hcl=function(n,t,e){return 1===arguments.length?n instanceof W?B(n.h,n.c,n.l):n instanceof K?nt(n.l,n.a,n.b):nt((n=ft((n=mo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):B(+n,+t,+e)};var ca=W.prototype=new Z;ca.brighter=function(n){return B(this.h,this.c,Math.min(100,this.l+la*(arguments.length?n:1)))},ca.darker=function(n){return B(this.h,this.c,Math.max(0,this.l-la*(arguments.length?n:1)))},ca.rgb=function(){return J(this.h,this.c,this.l).rgb()},mo.lab=function(n,t,e){return 1===arguments.length?n instanceof K?G(n.l,n.a,n.b):n instanceof W?J(n.l,n.c,n.h):ft((n=mo.rgb(n)).r,n.g,n.b):G(+n,+t,+e)};var la=18,sa=.95047,fa=1,ha=1.08883,ga=K.prototype=new Z;ga.brighter=function(n){return G(Math.min(100,this.l+la*(arguments.length?n:1)),this.a,this.b)},ga.darker=function(n){return G(Math.max(0,this.l-la*(arguments.length?n:1)),this.a,this.b)},ga.rgb=function(){return Q(this.l,this.a,this.b)},mo.rgb=function(n,t,e){return 1===arguments.length?n instanceof at?ot(n.r,n.g,n.b):lt(""+n,ot,$):ot(~~n,~~t,~~e)};var pa=at.prototype=new Z;pa.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),ot(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):ot(u,u,u)},pa.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),ot(~~(n*this.r),~~(n*this.g),~~(n*this.b))},pa.hsl=function(){return st(this.r,this.g,this.b)},pa.toString=function(){return"#"+ct(this.r)+ct(this.g)+ct(this.b)};var da=mo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});da.forEach(function(n,t){da.set(n,ut(t))}),mo.functor=pt,mo.xhr=vt(dt),mo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=mo.xhr(n,t,i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o.row(e)}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function o(t){return t.map(a).join(n)}function a(n){return c.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var c=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=c)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==l)continue;return n.substring(t,s-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],c=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new i,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(a).join(n)].concat(t.map(function(t){return u.map(function(n){return a(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(o).join("\n")},e},mo.csv=mo.dsv(",","text/csv"),mo.tsv=mo.dsv(" ","text/tab-separated-values");var va,ma,ya,Ma,xa,ba=_o[a(_o,"requestAnimationFrame")]||function(n){setTimeout(n,17)};mo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={callback:n,time:u,next:null};ma?ma.next=i:va=i,ma=i,ya||(Ma=clearTimeout(Ma),ya=1,ba(Mt))},mo.timer.flush=function(){bt(),_t()};var _a=".",wa=",",Sa=[3,3],Ea="$",ka=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(wt);mo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=mo.round(n,St(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),ka[8+e/3]},mo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)},mo.format=function(n){var t=Aa.exec(n),e=t[1]||" ",r=t[2]||">",u=t[3]||"",i=t[4]||"",o=t[5],a=+t[6],c=t[7],l=t[8],s=t[9],f=1,h="",g=!1;switch(l&&(l=+l.substring(1)),(o||"0"===e&&"="===r)&&(o=e="0",r="=",c&&(a-=Math.floor((a-1)/4))),s){case"n":c=!0,s="g";break;case"%":f=100,h="%",s="f";break;case"p":f=100,h="%",s="r";break;case"b":case"o":case"x":case"X":"#"===i&&(i="0"+s.toLowerCase());case"c":case"d":g=!0,l=0;break;case"s":f=-1,s="r"}"#"===i?i="":"$"===i&&(i=Ea),"r"!=s||l||(s="g"),null!=l&&("g"==s?l=Math.max(1,Math.min(21,l)):("e"==s||"f"==s)&&(l=Math.max(0,Math.min(20,l)))),s=Na.get(s)||Et;var p=o&&c;return function(n){if(g&&n%1)return"";var t=0>n||0===n&&0>1/n?(n=-n,"-"):u;if(0>f){var d=mo.formatPrefix(n,l);n=d.scale(n),h=d.symbol}else n*=f;n=s(n,l);var v=n.lastIndexOf("."),m=0>v?n:n.substring(0,v),y=0>v?"":_a+n.substring(v+1);!o&&c&&(m=Ta(m));var M=i.length+m.length+y.length+(p?0:t.length),x=a>M?new Array(M=a-M+1).join(e):"";return p&&(m=Ta(x+m)),t+=i,n=m+y,("<"===r?t+n+x:">"===r?x+t+n:"^"===r?x.substring(0,M>>=1)+t+n+x.substring(M):t+(p?n:x+n))+h}};var Aa=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,Na=mo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=mo.round(n,St(n,t))).toFixed(Math.max(0,Math.min(20,St(n*(1+1e-15),t))))}}),Ta=dt;if(Sa){var qa=Sa.length;Ta=function(n){for(var t=n.length,e=[],r=0,u=Sa[0];t>0&&u>0;)e.push(n.substring(t-=u,t+u)),u=Sa[r=(r+1)%qa];return e.reverse().join(wa)}}mo.geo={},kt.prototype={s:0,t:0,add:function(n){At(n,this.t,za),At(za.s,this.s,this),this.s?this.t+=za.t:this.s=za.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var za=new kt;mo.geo.stream=function(n,t){n&&Ca.hasOwnProperty(n.type)?Ca[n.type](n,t):Nt(n,t)};var Ca={Feature:function(n,t){Nt(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*Bo+n:n,Ha.lineStart=Ha.lineEnd=Ha.point=c}};mo.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=Ct([t*Qo,e*Qo]);if(m){var u=jt(m,r),i=[u[1],-u[0],0],o=jt(i,u);Ft(o),o=Pt(o);var c=t-p,l=c>0?1:-1,d=o[0]*na*l,v=Math.abs(c)>180;if(v^(d>l*p&&l*t>d)){var y=o[1]*na;y>g&&(g=y)}else if(d=(d+360)%360-180,v^(d>l*p&&l*t>d)){var y=-o[1]*na;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);v?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=Math.abs(r)>180?r+(r>0?360:-360):r}else d=n,v=e;Ha.point(n,e),t(n,e)}function i(){Ha.lineStart()}function o(){u(d,v),Ha.lineEnd(),Math.abs(y)>Go&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nLa?(s=-(h=180),f=-(g=90)):y>Go?g=90:-Go>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],mo.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),mo.geo.centroid=function(n){Fa=Pa=Oa=Ra=Ya=Ia=Ua=Za=Va=Xa=$a=0,mo.geo.stream(n,Ba);var t=Va,e=Xa,r=$a,u=t*t+e*e+r*r;return Ko>u&&(t=Ia,e=Ua,r=Za,Go>Pa&&(t=Oa,e=Ra,r=Ya),u=t*t+e*e+r*r,Ko>u)?[0/0,0/0]:[Math.atan2(e,t)*na,O(r/Math.sqrt(u))*na]};var Fa,Pa,Oa,Ra,Ya,Ia,Ua,Za,Va,Xa,$a,Ba={sphere:c,point:Rt,lineStart:It,lineEnd:Ut,polygonStart:function(){Ba.lineStart=Zt},polygonEnd:function(){Ba.lineStart=It}},Wa=Bt(Vt,Qt,te,[-Bo,-Bo/2]),Ja=1e9;mo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=re(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(mo.geo.conicEqualArea=function(){return oe(ae)}).raw=ae,mo.geo.albers=function(){return mo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},mo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=mo.geo.albers(),o=mo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=mo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Go,f+.12*l+Go],[s-.214*l-Go,f+.234*l-Go]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Go,f+.166*l+Go],[s-.115*l-Go,f+.234*l-Go]]).stream(c).point,n},n.scale(1070)};var Ga,Ka,Qa,nc,tc,ec,rc={point:c,lineStart:c,lineEnd:c,polygonStart:function(){Ka=0,rc.lineStart=ce},polygonEnd:function(){rc.lineStart=rc.lineEnd=rc.point=c,Ga+=Math.abs(Ka/2)}},uc={point:le,lineStart:c,lineEnd:c,polygonStart:c,polygonEnd:c},ic={point:he,lineStart:ge,lineEnd:pe,polygonStart:function(){ic.lineStart=de},polygonEnd:function(){ic.point=he,ic.lineStart=ge,ic.lineEnd=pe}};mo.geo.transform=function(n){return{stream:function(t){var e=new ye(t);for(var r in n)e[r]=n[r];return e}}},ye.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},mo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),mo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Ga=0,mo.geo.stream(n,u(rc)),Ga},n.centroid=function(n){return Oa=Ra=Ya=Ia=Ua=Za=Va=Xa=$a=0,mo.geo.stream(n,u(ic)),$a?[Va/$a,Xa/$a]:Za?[Ia/Za,Ua/Za]:Ya?[Oa/Ya,Ra/Ya]:[0/0,0/0]},n.bounds=function(n){return tc=ec=-(Qa=nc=1/0),mo.geo.stream(n,u(uc)),[[Qa,nc],[tc,ec]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Me(n):dt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new se:new ve(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(mo.geo.albersUsa()).context(null)},mo.geo.projection=xe,mo.geo.projectionMutator=be,(mo.geo.equirectangular=function(){return xe(we)}).raw=we.invert=we,mo.geo.rotation=function(n){function t(t){return t=n(t[0]*Qo,t[1]*Qo),t[0]*=na,t[1]*=na,t}return n=Ee(n[0]%360*Qo,n[1]*Qo,n.length>2?n[2]*Qo:0),t.invert=function(t){return t=n.invert(t[0]*Qo,t[1]*Qo),t[0]*=na,t[1]*=na,t},t},Se.invert=we,mo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=Ee(-n[0]*Qo,-n[1]*Qo,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=na,n[1]*=na}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=Te((t=+r)*Qo,u*Qo),n):t},n.precision=function(r){return arguments.length?(e=Te(t*Qo,(u=+r)*Qo),n):u},n.angle(90)},mo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Qo,u=n[1]*Qo,i=t[1]*Qo,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},mo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return mo.range(Math.ceil(i/v)*v,u,v).map(h).concat(mo.range(Math.ceil(l/m)*m,c,m).map(g)).concat(mo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return Math.abs(n%v)>Go -}).map(s)).concat(mo.range(Math.ceil(a/d)*d,o,d).filter(function(n){return Math.abs(n%m)>Go}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,d=p,v=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(v=+t[0],m=+t[1],n):[v,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],d=+t[1],n):[p,d]},n.precision=function(t){return arguments.length?(y=+t,s=ze(a,o,90),f=Ce(r,e,y),h=ze(l,c,90),g=Ce(i,u,y),n):y},n.majorExtent([[-180,-90+Go],[180,90-Go]]).minorExtent([[-180,-80-Go],[180,80+Go]])},mo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=De,u=je;return n.distance=function(){return mo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},mo.geo.interpolate=function(n,t){return Le(n[0]*Qo,n[1]*Qo,t[0]*Qo,t[1]*Qo)},mo.geo.length=function(n){return oc=0,mo.geo.stream(n,ac),oc};var oc,ac={sphere:c,point:c,lineStart:He,lineEnd:c,polygonStart:c,polygonEnd:c},cc=Fe(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(mo.geo.azimuthalEqualArea=function(){return xe(cc)}).raw=cc;var lc=Fe(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},dt);(mo.geo.azimuthalEquidistant=function(){return xe(lc)}).raw=lc,(mo.geo.conicConformal=function(){return oe(Pe)}).raw=Pe,(mo.geo.conicEquidistant=function(){return oe(Oe)}).raw=Oe;var sc=Fe(function(n){return 1/n},Math.atan);(mo.geo.gnomonic=function(){return xe(sc)}).raw=sc,Re.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Jo]},(mo.geo.mercator=function(){return Ye(Re)}).raw=Re;var fc=Fe(function(){return 1},Math.asin);(mo.geo.orthographic=function(){return xe(fc)}).raw=fc;var hc=Fe(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(mo.geo.stereographic=function(){return xe(hc)}).raw=hc,Ie.invert=function(n,t){return[Math.atan2(R(n),Math.cos(t)),O(Math.sin(t)/Y(n))]},(mo.geo.transverseMercator=function(){return Ye(Ie)}).raw=Ie,mo.geom={},mo.svg={},mo.svg.line=function(){return Ue(dt)};var gc=mo.map({linear:Xe,"linear-closed":$e,step:Be,"step-before":We,"step-after":Je,basis:er,"basis-open":rr,"basis-closed":ur,bundle:ir,cardinal:Qe,"cardinal-open":Ge,"cardinal-closed":Ke,monotone:fr});gc.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var pc=[0,2/3,1/3,0],dc=[0,1/3,2/3,0],vc=[0,1/6,2/3,1/6];mo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u,i,o,a,c,l,s,f,h,g,p,d=pt(e),v=pt(r),m=n.length,y=m-1,M=[],x=[],b=0;if(d===Ze&&r===Ve)t=n;else for(i=0,t=[];m>i;++i)t.push([+d.call(this,u=n[i],i),+v.call(this,u,i)]);for(i=1;m>i;++i)(t[i][1]i;++i)i!==b&&(c=t[i][1]-t[b][1],a=t[i][0]-t[b][0],M.push({angle:Math.atan2(c,a),index:i}));for(M.sort(function(n,t){return n.angle-t.angle}),g=M[0].angle,h=M[0].index,f=0,i=1;y>i;++i){if(o=M[i].index,g==M[i].angle){if(a=t[h][0]-t[b][0],c=t[h][1]-t[b][1],l=t[o][0]-t[b][0],s=t[o][1]-t[b][1],a*a+c*c>=l*l+s*s){M[i].index=-1;continue}M[f].index=-1}g=M[i].angle,f=i,h=o}for(x.push(b),i=0,o=0;2>i;++o)M[o].index>-1&&(x.push(M[o].index),i++);for(p=x.length;y>o;++o)if(!(M[o].index<0)){for(;!hr(x[p-2],x[p-1],M[o].index,t);)--p;x[p++]=M[o].index}var _=[];for(i=p-1;i>=0;--i)_.push(n[x[i]]);return _}var e=Ze,r=Ve;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},mo.geom.polygon=function(n){return Lo(n,mc),n};var mc=mo.geom.polygon.prototype=[];mc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++ta;a++)e.push([u,t[a],t[a+1]])}),e},mo.geom.voronoi=function(n){function t(n){var t,i,o,a=n.map(function(){return[]}),c=pt(e),l=pt(r),s=n.length,f=1e6;if(c===Ze&&l===Ve)t=n;else for(t=new Array(s),o=0;s>o;++o)t[o]=[+c.call(this,i=n[o],o),+l.call(this,i,o)];if(vr(t,function(n){var t,e,r,u,i,o;1===n.a&&n.b>=0?(t=n.ep.r,e=n.ep.l):(t=n.ep.l,e=n.ep.r),1===n.a?(i=t?t.y:-f,r=n.c-n.b*i,o=e?e.y:f,u=n.c-n.b*o):(r=t?t.x:-f,i=n.c-n.a*r,u=e?e.x:f,o=n.c-n.a*u);var c=[r,i],l=[u,o];a[n.region.l.index].push(c,l),a[n.region.r.index].push(c,l)}),a=a.map(function(n,e){var r=t[e][0],u=t[e][1],i=n.map(function(n){return Math.atan2(n[0]-r,n[1]-u)}),o=mo.range(n.length).sort(function(n,t){return i[n]-i[t]});return o.filter(function(n,t){return!t||i[n]-i[o[t-1]]>Go}).map(function(t){return n[t]})}),a.forEach(function(n,e){var r=n.length;if(!r)return n.push([-f,-f],[-f,f],[f,f],[f,-f]);if(!(r>2)){var u=t[e],i=n[0],o=n[1],a=u[0],c=u[1],l=i[0],s=i[1],h=o[0],g=o[1],p=Math.abs(h-l),d=g-s;if(Math.abs(d)c?-f:f;n.push([-f,v],[f,v])}else if(Go>p){var m=l>a?-f:f;n.push([m,-f],[m,f])}else{var v=(l-a)*(g-s)>(h-l)*(s-c)?f:-f,y=Math.abs(d)-p;Math.abs(y)d?v:-v,v]):(y>0&&(v*=-1),n.push([-f,v],[f,v]))}}}),u)for(o=0;s>o;++o)u.clip(a[o]);for(o=0;s>o;++o)a[o].point=n[o];return a}var e=Ze,r=Ve,u=null;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.clipExtent=function(n){if(!arguments.length)return u&&[u[0],u[2]];if(null==n)u=null;else{var e=+n[0][0],r=+n[0][1],i=+n[1][0],o=+n[1][1];u=mo.geom.polygon([[e,r],[e,o],[i,o],[i,r]])}return t},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):u&&u[2]},t.links=function(n){var t,u,i,o=n.map(function(){return[]}),a=[],c=pt(e),l=pt(r),s=n.length;if(c===Ze&&l===Ve)t=n;else for(t=new Array(s),i=0;s>i;++i)t[i]=[+c.call(this,u=n[i],i),+l.call(this,u,i)];return vr(t,function(t){var e=t.region.l.index,r=t.region.r.index;o[e][r]||(o[e][r]=o[r][e]=!0,a.push({source:n[e],target:n[r]}))}),a},t.triangles=function(n){if(e===Ze&&r===Ve)return mo.geom.delaunay(n);for(var t,u=new Array(c),i=pt(e),o=pt(r),a=-1,c=n.length;++a=l,h=r>=s,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=Mr()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,d,v,m,y,M=pt(a),x=pt(c);if(null!=t)d=t,v=e,m=r,y=u;else if(m=y=-(d=v=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.xm&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);d>b&&(d=b),v>_&&(v=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-d,S=y-v;w>S?y=v+w:m=d+S;var E=Mr();if(E.add=function(n){i(E,n,+M(n,++g),+x(n,g),d,v,m,y)},E.visit=function(n){xr(n,E,d,v,m,y)},g=-1,null==t){for(;++g=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=bc.get(e)||xc,r=_c.get(r)||dt,Ar(r(e.apply(null,Array.prototype.slice.call(arguments,1))))},mo.interpolateHcl=Rr,mo.interpolateHsl=Yr,mo.interpolateLab=Ir,mo.interpolateRound=Ur,mo.transform=function(n){var t=xo.createElementNS(mo.ns.prefix.svg,"g");return(mo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Zr(e?e.matrix:wc)})(n)},Zr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var wc={a:1,b:0,c:0,d:1,e:0,f:0};mo.interpolateTransform=Br,mo.layout={},mo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e(u-e)*a){var c=t.charge*a*a;return n.px-=i*c,n.py-=o*c,!0}if(t.point&&isFinite(a)){var c=t.pointCharge*a*a;n.px-=i*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=mo.event.x,n.py=mo.event.y,a.resume()}var e,r,u,i,o,a={},c=mo.dispatch("start","tick","end"),l=[1,1],s=.9,f=Sc,h=Ec,g=-30,p=.1,d=.8,v=[],m=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,d,y,M,x,b=v.length,_=m.length;for(e=0;_>e;++e)a=m[e],f=a.source,h=a.target,M=h.x-f.x,x=h.y-f.y,(d=M*M+x*x)&&(d=r*i[e]*((d=Math.sqrt(d))-u[e])/d,M*=d,x*=d,h.x-=M*(y=f.weight/(h.weight+f.weight)),h.y-=x*y,f.x+=M*(y=1-y),f.y+=x*y);if((y=r*p)&&(M=l[0]/2,x=l[1]/2,e=-1,y))for(;++e0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),mo.timer(a.tick)),a):r},a.start=function(){function n(n,r){for(var u,i=t(e),o=-1,a=i.length;++or;++r)c[r]=[];for(r=0;d>r;++r){var n=m[r];c[n.source.index].push(n.target),c[n.target.index].push(n.source)}}return c[e]}var e,r,c,s,p=v.length,d=m.length,y=l[0],M=l[1];for(e=0;p>e;++e)(s=v[e]).index=e,s.weight=0;for(e=0;d>e;++e)s=m[e],"number"==typeof s.source&&(s.source=v[s.source]),"number"==typeof s.target&&(s.target=v[s.target]),++s.source.weight,++s.target.weight;for(e=0;p>e;++e)s=v[e],isNaN(s.x)&&(s.x=n("x",y)),isNaN(s.y)&&(s.y=n("y",M)),isNaN(s.px)&&(s.px=s.x),isNaN(s.py)&&(s.py=s.y);if(u=[],"function"==typeof f)for(e=0;d>e;++e)u[e]=+f.call(this,m[e],e);else for(e=0;d>e;++e)u[e]=f;if(i=[],"function"==typeof h)for(e=0;d>e;++e)i[e]=+h.call(this,m[e],e);else for(e=0;d>e;++e)i[e]=h;if(o=[],"function"==typeof g)for(e=0;p>e;++e)o[e]=+g.call(this,v[e],e);else for(e=0;p>e;++e)o[e]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=mo.behavior.drag().origin(dt).on("dragstart.force",nu).on("drag.force",t).on("dragend.force",tu)),arguments.length?(this.on("mouseover.force",eu).on("mouseout.force",ru).call(e),void 0):e},mo.rebind(a,c,"on")};var Sc=20,Ec=1;mo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(l=c.length)){for(var l,s,f=-1,h=t.children=[],g=0,p=o+1;++fg;++g)for(u.call(n,l[0][g],p=d[g],s[0][g][1]),h=1;v>h;++h)u.call(n,l[h][g],p+=s[h-1][g][1],s[h][g][1]);return a}var t=dt,e=gu,r=pu,u=hu,i=su,o=fu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:Ac.get(t)||gu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:Nc.get(t)||pu,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var Ac=mo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(du),i=n.map(vu),o=mo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return mo.range(n.length).reverse()},"default":gu}),Nc=mo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:pu});mo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=s[0]&&a<=s[1]&&(o=c[mo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=xu,u=yu;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=pt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return Mu(n,t)}:pt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},mo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,l,s=r[0],f=s,h=-1;++h0&&(qu(zu(a,n,r),n,u),l+=u,s+=u),f+=a._tree.mod,l+=i._tree.mod,h+=c._tree.mod,s+=o._tree.mod;a&&!wu(o)&&(o._tree.thread=a,o._tree.mod+=f-s),i&&!_u(c)&&(c._tree.thread=i,c._tree.mod+=l-h,r=n)}return r}var l=t.call(this,n,i),s=l[0];Nu(s,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(s),a(s,-s._tree.prelim);var f=Su(s,ku),h=Su(s,Eu),g=Su(s,Au),p=f.x-e(f,h)/2,d=h.x+e(h,f)/2,v=g.depth||1;return Nu(s,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(d-p)*r[0],n.y=n.depth/v*r[1],delete n._tree}),l}var t=mo.layout.hierarchy().sort(null).value(null),e=bu,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},iu(n,t)},mo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Nu(a,function(n){n.r=+s(n.value)}),Nu(a,Hu),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Nu(a,function(n){n.r+=f}),Nu(a,Hu),Nu(a,function(n){n.r-=f})}return Ou(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=mo.layout.hierarchy().sort(Cu),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},iu(n,e)},mo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Nu(c,function(n){var t=n.children;t&&t.length?(n.x=Iu(t),n.y=Yu(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Uu(c),f=Zu(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Nu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=mo.layout.hierarchy().sort(null).value(null),e=bu,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},iu(n,t)},mo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,d="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,d))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,d,l,!1),d=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,d,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++oe&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++ie.dx)&&(s=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=mo.random.normal.apply(mo,arguments);return function(){return Math.exp(n())}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t/n}}},mo.scale={};var Tc={floor:dt,ceil:dt};mo.scale.linear=function(){return Qu([0,1],[0,1],Er,!1)},mo.scale.log=function(){return ii(mo.scale.linear().domain([0,1]),10,!0,[1,10])};var qc=mo.format(".0e"),zc={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};mo.scale.pow=function(){return oi(mo.scale.linear(),1,[0,1])},mo.scale.sqrt=function(){return mo.scale.pow().exponent(.5)},mo.scale.ordinal=function(){return ci([],{t:"range",a:[[]]})},mo.scale.category10=function(){return mo.scale.ordinal().range(Cc)},mo.scale.category20=function(){return mo.scale.ordinal().range(Dc)},mo.scale.category20b=function(){return mo.scale.ordinal().range(jc)},mo.scale.category20c=function(){return mo.scale.ordinal().range(Lc)};var Cc=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(it),Dc=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(it),jc=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(it),Lc=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(it);mo.scale.quantile=function(){return li([],[])},mo.scale.quantize=function(){return si(0,1,[0,1])},mo.scale.threshold=function(){return fi([.5],[0,1])},mo.scale.identity=function(){return hi([0,1])},mo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+Hc,a=u.apply(this,arguments)+Hc,c=(o>a&&(c=o,o=a,a=c),a-o),l=Bo>c?"0":"1",s=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=Fc?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*s+","+i*f+"A"+i+","+i+" 0 "+l+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+l+",0 "+n*s+","+n*f+"Z":"M"+i*s+","+i*f+"A"+i+","+i+" 0 "+l+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=gi,e=pi,r=di,u=vi;return n.innerRadius=function(e){return arguments.length?(t=pt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=pt(t),n):e},n.startAngle=function(t){return arguments.length?(r=pt(t),n):r},n.endAngle=function(t){return arguments.length?(u=pt(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+Hc;return[Math.cos(i)*n,Math.sin(i)*n]},n};var Hc=-Jo,Fc=Wo-Go;mo.svg.line.radial=function(){var n=Ue(mi);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},We.reverse=Je,Je.reverse=We,mo.svg.area=function(){return yi(dt)},mo.svg.area.radial=function(){var n=yi(mi);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},mo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+Hc,s=l.call(n,u,r)+Hc;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Bo)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=De,o=je,a=Mi,c=di,l=vi;return n.radius=function(t){return arguments.length?(a=pt(t),n):a},n.source=function(t){return arguments.length?(i=pt(t),n):i},n.target=function(t){return arguments.length?(o=pt(t),n):o},n.startAngle=function(t){return arguments.length?(c=pt(t),n):c},n.endAngle=function(t){return arguments.length?(l=pt(t),n):l},n},mo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=De,e=je,r=xi;return n.source=function(e){return arguments.length?(t=pt(e),n):t},n.target=function(t){return arguments.length?(e=pt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},mo.svg.diagonal.radial=function(){var n=mo.svg.diagonal(),t=xi,e=n.projection;return n.projection=function(n){return arguments.length?e(bi(t=n)):t},n},mo.svg.symbol=function(){function n(n,r){return(Pc.get(t.call(this,n,r))||Si)(e.call(this,n,r))}var t=wi,e=_i;return n.type=function(e){return arguments.length?(t=pt(e),n):t},n.size=function(t){return arguments.length?(e=pt(t),n):e},n};var Pc=mo.map({circle:Si,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ic)),e=t*Ic;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/Yc),e=t*Yc/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Yc),e=t*Yc/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});mo.svg.symbolTypes=Pc.keys();var Oc,Rc,Yc=Math.sqrt(3),Ic=Math.tan(30*Qo),Uc=[],Zc=0;Uc.call=Ro.call,Uc.empty=Ro.empty,Uc.node=Ro.node,Uc.size=Ro.size,mo.transition=function(n){return arguments.length?Oc?n.transition():n:Uo.transition()},mo.transition.prototype=Uc,Uc.select=function(n){var t,e,r,u=this.id,i=[];n=d(n);for(var o=-1,a=this.length;++oi;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a)&&t.push(r)}return Ei(u,this.id)},Uc.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):N(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Uc.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n)) -})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Br:Er,a=mo.ns.qualify(n);return ki(this,"attr."+n,t,a.local?i:u)},Uc.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=mo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Uc.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=_o.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=Er(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return ki(this,"style."+n,t,u)},Uc.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,_o.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Uc.text=function(n){return ki(this,"text",n,Ai)},Uc.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Uc.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=mo.ease.apply(mo,arguments)),N(this,function(e){e.__transition__[t].ease=n}))},Uc.delay=function(n){var t=this.id;return N(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Uc.duration=function(n){var t=this.id;return N(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Uc.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Rc,u=Oc;Oc=e,N(this,function(t,r,u){Rc=t.__transition__[e],n.call(t,t.__data__,r,u)}),Rc=r,Oc=u}else N(this,function(r){var u=r.__transition__[e];(u.event||(u.event=mo.dispatch("start","end"))).on(n,t)});return this},Uc.transition=function(){for(var n,t,e,r,u=this.id,i=++Zc,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],l=0,s=t.length;s>l;l++)(e=t[l])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,Ni(e,l,i,r)),n.push(e)}return Ei(o,i)},mo.svg.axis=function(){function n(n){n.each(function(){var n,l=mo.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):dt:t,p=l.selectAll(".tick").data(h,f),d=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Go),v=mo.transition(p.exit()).style("opacity",Go).remove(),m=mo.transition(p).style("opacity",1),y=Bu(f),M=l.selectAll(".domain").data([0]),x=(M.enter().append("path").attr("class","domain"),mo.transition(M));d.append("line"),d.append("text");var b=d.select("line"),_=m.select("line"),w=p.select("text").text(g),S=d.select("text"),E=m.select("text");switch(r){case"bottom":n=Ti,b.attr("y2",u),S.attr("y",Math.max(u,0)+o),_.attr("x2",0).attr("y2",u),E.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),x.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Ti,b.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),_.attr("x2",0).attr("y2",-u),E.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),x.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=qi,b.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),_.attr("x2",-u).attr("y2",0),E.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),x.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=qi,b.attr("x2",u),S.attr("x",Math.max(u,0)+o),_.attr("x2",u).attr("y2",0),E.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),x.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var k=f.rangeBand()/2,A=function(n){return f(n)+k};d.call(n,A),m.call(n,A)}else d.call(n,s),m.call(n,f),v.call(n,f)})}var t,e=mo.scale.linear(),r=Vc,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xc?t+"":Vc,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vc="bottom",Xc={top:1,right:1,bottom:1,left:1};mo.svg.brush=function(){function n(i){i.each(function(){var i=mo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(v,dt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $c[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var s,f=mo.transition(i),h=mo.transition(o);c&&(s=Bu(c),h.attr("x",s[0]).attr("width",s[1]-s[0]),e(f)),l&&(s=Bu(l),h.attr("y",s[0]).attr("height",s[1]-s[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function r(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==mo.event.keyCode&&(N||(M=null,q[0]-=s[1],q[1]-=h[1],N=2),f())}function g(){32==mo.event.keyCode&&2==N&&(q[0]+=s[1],q[1]+=h[1],N=0,f())}function v(){var n=mo.mouse(b),u=!1;x&&(n[0]+=x[0],n[1]+=x[1]),N||(mo.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),q[0]=s[+(n[0]f?(u=r,r=f):u=f),g[0]!=r||g[1]!=u?(e?o=null:i=null,g[0]=r,g[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),mo.select("body").style("cursor",null),z.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),T(),w({type:"brushend"})}var M,x,b=this,_=mo.select(mo.event.target),w=a.of(b,arguments),S=mo.select(b),E=_.datum(),k=!/^(n|s)$/.test(E)&&c,A=!/^(e|w)$/.test(E)&&l,N=_.classed("extent"),T=L(),q=mo.mouse(b),z=mo.select(_o).on("keydown.brush",u).on("keyup.brush",g);if(mo.event.changedTouches?z.on("touchmove.brush",v).on("touchend.brush",y):z.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),N)q[0]=s[0]-q[0],q[1]=h[0]-q[1];else if(E){var C=+/w$/.test(E),D=+/^n/.test(E);x=[s[1-C]-q[0],h[1-D]-q[1]],q[0]=s[C],q[1]=h[D]}else mo.event.altKey&&(M=q.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),mo.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=g(n,"brushstart","brush","brushend"),c=null,l=null,s=[0,0],h=[0,0],p=!0,d=!0,v=Bc[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:s,y:h,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Oc?mo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=kr(s,t.x),r=kr(h,t.y);return i=o=null,function(u){s=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bc[!c<<1|!l],n):c},n.y=function(t){return arguments.length?(l=t,v=Bc[!c<<1|!l],n):l},n.clamp=function(t){return arguments.length?(c&&l?(p=!!t[0],d=!!t[1]):c?p=!!t:l&&(d=!!t),n):c&&l?[p,d]:c?p:l?d:null},n.extent=function(t){var e,r,u,a,f;return arguments.length?(c&&(e=t[0],r=t[1],l&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(f=e,e=r,r=f),(e!=s[0]||r!=s[1])&&(s=[e,r])),l&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],l.invert&&(u=l(u),a=l(a)),u>a&&(f=u,u=a,a=f),(u!=h[0]||a!=h[1])&&(h=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(f=e,e=r,r=f))),l&&(o?(u=o[0],a=o[1]):(u=h[0],a=h[1],l.invert&&(u=l.invert(u),a=l.invert(a)),u>a&&(f=u,u=a,a=f))),c&&l?[[e,u],[r,a]]:c?[e,r]:l&&[u,a])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],i=o=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!l&&h[0]==h[1]},mo.rebind(n,a,"on")};var $c={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bc=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wc=mo.time={},Jc=Date,Gc=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];zi.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){Kc.setUTCDate.apply(this._,arguments)},setDay:function(){Kc.setUTCDay.apply(this._,arguments)},setFullYear:function(){Kc.setUTCFullYear.apply(this._,arguments)},setHours:function(){Kc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){Kc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){Kc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){Kc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){Kc.setUTCSeconds.apply(this._,arguments)},setTime:function(){Kc.setTime.apply(this._,arguments)}};var Kc=Date.prototype,Qc="%a %b %e %X %Y",nl="%m/%d/%Y",tl="%H:%M:%S",el=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],rl=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],ul=["January","February","March","April","May","June","July","August","September","October","November","December"],il=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];Wc.year=Ci(function(n){return n=Wc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),Wc.years=Wc.year.range,Wc.years.utc=Wc.year.utc.range,Wc.day=Ci(function(n){var t=new Jc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),Wc.days=Wc.day.range,Wc.days.utc=Wc.day.utc.range,Wc.dayOfYear=function(n){var t=Wc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},Gc.forEach(function(n,t){n=n.toLowerCase(),t=7-t;var e=Wc[n]=Ci(function(n){return(n=Wc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=Wc.year(n).getDay();return Math.floor((Wc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});Wc[n+"s"]=e.range,Wc[n+"s"].utc=e.utc.range,Wc[n+"OfYear"]=function(n){var e=Wc.year(n).getDay();return Math.floor((Wc.dayOfYear(n)+(e+t)%7)/7)}}),Wc.week=Wc.sunday,Wc.weeks=Wc.sunday.range,Wc.weeks.utc=Wc.sunday.utc.range,Wc.weekOfYear=Wc.sundayOfYear,Wc.format=ji;var ol=Hi(el),al=Fi(el),cl=Hi(rl),ll=Fi(rl),sl=Hi(ul),fl=Fi(ul),hl=Hi(il),gl=Fi(il),pl=/^%/,dl={"-":"",_:" ",0:"0"},vl={a:function(n){return rl[n.getDay()]},A:function(n){return el[n.getDay()]},b:function(n){return il[n.getMonth()]},B:function(n){return ul[n.getMonth()]},c:ji(Qc),d:function(n,t){return Pi(n.getDate(),t,2)},e:function(n,t){return Pi(n.getDate(),t,2)},H:function(n,t){return Pi(n.getHours(),t,2)},I:function(n,t){return Pi(n.getHours()%12||12,t,2)},j:function(n,t){return Pi(1+Wc.dayOfYear(n),t,3)},L:function(n,t){return Pi(n.getMilliseconds(),t,3)},m:function(n,t){return Pi(n.getMonth()+1,t,2)},M:function(n,t){return Pi(n.getMinutes(),t,2)},p:function(n){return n.getHours()>=12?"PM":"AM"},S:function(n,t){return Pi(n.getSeconds(),t,2)},U:function(n,t){return Pi(Wc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Pi(Wc.mondayOfYear(n),t,2)},x:ji(nl),X:ji(tl),y:function(n,t){return Pi(n.getFullYear()%100,t,2)},Y:function(n,t){return Pi(n.getFullYear()%1e4,t,4)},Z:ao,"%":function(){return"%"}},ml={a:Oi,A:Ri,b:Zi,B:Vi,c:Xi,d:no,e:no,H:eo,I:eo,j:to,L:io,m:Qi,M:ro,p:oo,S:uo,U:Ii,w:Yi,W:Ui,x:$i,X:Bi,y:Ji,Y:Wi,Z:Gi,"%":co},yl=/^\s*\d+/,Ml=mo.map({am:0,pm:1});ji.utc=lo;var xl=lo("%Y-%m-%dT%H:%M:%S.%LZ");ji.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?so:xl,so.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},so.toString=xl.toString,Wc.second=Ci(function(n){return new Jc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),Wc.seconds=Wc.second.range,Wc.seconds.utc=Wc.second.utc.range,Wc.minute=Ci(function(n){return new Jc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),Wc.minutes=Wc.minute.range,Wc.minutes.utc=Wc.minute.utc.range,Wc.hour=Ci(function(n){var t=n.getTimezoneOffset()/60;return new Jc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),Wc.hours=Wc.hour.range,Wc.hours.utc=Wc.hour.utc.range,Wc.month=Ci(function(n){return n=Wc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),Wc.months=Wc.month.range,Wc.months.utc=Wc.month.utc.range;var bl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],_l=[[Wc.second,1],[Wc.second,5],[Wc.second,15],[Wc.second,30],[Wc.minute,1],[Wc.minute,5],[Wc.minute,15],[Wc.minute,30],[Wc.hour,1],[Wc.hour,3],[Wc.hour,6],[Wc.hour,12],[Wc.day,1],[Wc.day,2],[Wc.week,1],[Wc.month,1],[Wc.month,3],[Wc.year,1]],wl=[[ji("%Y"),Vt],[ji("%B"),function(n){return n.getMonth()}],[ji("%b %d"),function(n){return 1!=n.getDate()}],[ji("%a %d"),function(n){return n.getDay()&&1!=n.getDate()}],[ji("%I %p"),function(n){return n.getHours()}],[ji("%I:%M"),function(n){return n.getMinutes()}],[ji(":%S"),function(n){return n.getSeconds()}],[ji(".%L"),function(n){return n.getMilliseconds()}]],Sl=go(wl);_l.year=Wc.year,Wc.scale=function(){return fo(mo.scale.linear(),_l,Sl)};var El={range:function(n,t,e){return mo.range(+n,+t,e).map(ho)}},kl=_l.map(function(n){return[n[0].utc,n[1]]}),Al=[[lo("%Y"),Vt],[lo("%B"),function(n){return n.getUTCMonth()}],[lo("%b %d"),function(n){return 1!=n.getUTCDate()}],[lo("%a %d"),function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],[lo("%I %p"),function(n){return n.getUTCHours()}],[lo("%I:%M"),function(n){return n.getUTCMinutes()}],[lo(":%S"),function(n){return n.getUTCSeconds()}],[lo(".%L"),function(n){return n.getUTCMilliseconds()}]],Nl=go(Al);return kl.year=Wc.year.utc,Wc.scale.utc=function(){return fo(mo.scale.linear(),kl,Nl)},mo.text=vt(function(n){return n.responseText}),mo.json=function(n,t){return mt(n,"application/json",po,t)},mo.html=function(n,t){return mt(n,"text/html",vo,t)},mo.xml=vt(function(n){return n.responseXML}),mo}(); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graph_util.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graph_util.js deleted file mode 100644 index 9b20afe4..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graph_util.js +++ /dev/null @@ -1,243 +0,0 @@ -var fromDate; -var toDate; - -// create a custom bar renderer that has no gaps -Rickshaw.Graph.Renderer.BarNoGap = Rickshaw.Class.create(Rickshaw.Graph.Renderer.Bar, { - name: 'bar_no_gap', - barWidth: function (series) { - var frequentInterval = this._frequentInterval(series.stack); - var barWidth = this.graph.x(series.stack[0].x + frequentInterval.magnitude * 1); - return barWidth; - } -}); - - -var currentDay = new Date(); -var startDate = new Date(currentDay.getTime() - (60 * 60 * 24 * 100)); -var endDate = new Date(currentDay.getTime()); - -var configObject = { - startOfWeek: 'monday', - separator: ' to ', - format: 'YYYY-MM-DD HH:mm', - autoClose: false, - time: { - enabled: true - }, - shortcuts: 'hide', - endDate: currentDay, - - getValue: function () { - return this.value; - }, - setValue: function (s) { - this.value = s; - } -}; - -var DateRange = convertDate(startDate) + " " + configObject.separator + " " + convertDate(endDate); - -$('#date-range').dateRangePicker(configObject) - .bind('datepicker-apply', function (event, dateRange) { - $(this).addClass('active'); - $(this).siblings().removeClass('active'); - fromDate = dateRange.date1 != "Invalid Date" ? dateRange.date1.getTime() / 1000 : null; - toDate = dateRange.date2 != "Invalid Date" ? dateRange.date2.getTime() / 1000 : null; - getStats(fromDate, toDate); - } -); - -$(document).ready(function () { - $('#date-range').html(DateRange); - $('#date-range').trigger('datepicker-apply', - { - 'value': DateRange, - 'date1': startDate, - 'date2': endDate - }); -}); - -//day picker -$('#today-btn').on('click', function () { - getDateTime(currentDay.getTime() - 86400000, currentDay.getTime()); -}); - -//hour picker -$('#hour-btn').on('click', function () { - getDateTime(currentDay.getTime() - 3600000, currentDay.getTime()); -}) - -//week picker -$('#week-btn').on('click', function () { - getDateTime(currentDay.getTime() - 604800000, currentDay.getTime()); -}) - -//month picker -$('#month-btn').on('click', function () { - getDateTime(currentDay.getTime() - (604800000 * 4), currentDay.getTime()); -}); - -$('body').on('click', '.btn-group button', function (e) { - $(this).addClass('active'); - $(this).siblings().removeClass('active'); -}); - -function getDateTime(from, to) { - startDate = new Date(from); - endDate = new Date(to); - DateRange = convertDate(startDate) + " " + configObject.separator + " " + convertDate(endDate); - console.log(DateRange); - $('#date-range').html(DateRange); - $('#date-range').trigger('datepicker-apply', - { - 'value': DateRange, - 'date1': startDate, - 'date2': endDate - } - ); - getStats(from / 1000, to / 1000); -} - -function getStats(from, to) { - var deviceId = getUrlParameter('deviceId'); - var deviceType = getUrlParameter('deviceType'); - - var requestData = new Object(); - - requestData['deviceId'] = deviceId; - requestData['deviceType'] = deviceType; - - if (from) { - requestData['from'] = from; - } - - if (to) { - requestData['to'] = to; - } - - var getStatsRequest = $.ajax({ - url: "api/stats", - method: "GET", - data: requestData - }); - - getStatsRequest.done(function (stats) { - updateGraphs(JSON.parse(stats)); - }); - - getStatsRequest.fail(function (jqXHR, textStatus) { - alert("Request failed: " + textStatus); - }); - -} - -function getUrlParameter(paramName) { - var pageURL = window.location.search.substring(1); - var urlVariables = pageURL.split('&'); - for (var i = 0; i < urlVariables.length; i++) { - var parameterName = urlVariables[i].split('='); - if (parameterName[0] == paramName) { - return parameterName[1]; - } - } -} - -function updateGraphs(stats) { - console.log(stats); - - var temperatureData = stats['temperatureData']; - updateTemperatureGraph(convertStatsToGraphData(temperatureData)); - - var lightData = stats['lightData']; - updateLightGraph(convertStatsToGraphData(lightData)); - - var motionData = stats['motionData']; - updateMotionGraph(convertStatsToGraphData(motionData)); - - var sonarData = stats['sonarData']; - updateSonarGraph(convertStatsToGraphData(sonarData)); - - var fanData = stats['fanData']; - updateFanGraph(convertStateStatsToGraphData(fanData)); - - var bulbData = stats['bulbData']; - updateBulbGraph(convertStateStatsToGraphData(bulbData)); - - scaleGraphs(); -} - -function scaleGraphs() { - var sliders = $('.right_handle'); - if (sliders.length == 0) { - return; - } - - var graphWidth = $('#canvas-wrapper1').width() - 50; - //Scale graphs - var sliderX = graphWidth * 60 * 60 / (toDate - fromDate); - if (sliderX < graphWidth) { - // fake handle move - if (sliderX < 100) { - sliderX = 100; - } - var edown = document.createEvent("HTMLEvents"); - edown.initEvent("mousedown", true, true); - edown.clientX = graphWidth; - var emove = document.createEvent("HTMLEvents"); - emove.initEvent("mousemove", true, true); - emove.clientX = sliderX; - var eup = document.createEvent("HTMLEvents"); - eup.initEvent("mouseup", true, true); - for (var slider in sliders) { - sliders[slider].dispatchEvent(edown); - document.dispatchEvent(emove); - document.dispatchEvent(eup); - } - } -} - -function convertStatsToGraphData(stats) { - - var graphData = new Array(); - if (!stats) { - return graphData; - } - for (var i = 0; i < stats.length; i++) { - graphData.push({x: parseInt(stats[i]['time']) * 1000, y: stats[i]['value']}) - } - - return graphData; -} - - -function convertStateStatsToGraphData(stats) { - - var graphData = new Array(); - if (!stats) { - return graphData; - } - var yValue; - for (var i = 0; i < stats.length; i++) { - yValue = -1; - - if (stats[i]['value'].toUpperCase() == 'ON') { - yValue = 1; - } else if (stats[i]['value'].toUpperCase() == 'OFF') { - yValue = 0; - } - - graphData.push({x: parseInt(stats[i]['time']) * 1000, y: yValue}) - } - - return graphData; -} - -function convertDate(date) { - var month = date.getMonth() + 1; - var day = date.getDate(); - var hour=date.getHours(); - var minute=date.getMinutes(); - return date.getFullYear() + '-' + (('' + month).length < 2 ? '0' : '') - + month + '-' + (('' + day).length < 2 ? '0' : '') + day +" "+ (('' + hour).length < 2 ? '0' : '') - + hour +":"+(('' + minute).length < 2 ? '0' : '')+ minute; -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/bulb_graph.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/bulb_graph.js deleted file mode 100644 index f4a1c5a4..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/bulb_graph.js +++ /dev/null @@ -1,85 +0,0 @@ -function updateBulbGraph(bulbData) { - renderBulbChart(bulbData); -} - - -function renderBulbChart(chartDataRaw){ - var chartWrapperElmId = "#canvas-wrapper6"; - var graphWidth = $(chartWrapperElmId).width() - 50; - if (chartDataRaw.length == 0) { - $(chartWrapperElmId).html("No data available..."); - return; - } - - var chartData = [[], []]; - for (var i = 0; i < chartDataRaw.length; i++){ - chartData[0].push({x:parseInt(chartDataRaw[i].x), y:parseInt(chartDataRaw[i].y)}); - chartData[1].push({x:parseInt(chartDataRaw[i].x), y:Math.abs(parseInt(chartDataRaw[i].y) - 1)}); - } - - //var i = parseInt(fromDate); - //while (i < parseInt(toDate)) { - // var rnd = Math.round(Math.random()); - // chartData[0].push({x: i * 1000, y: rnd}); - // chartData[1].push({x: i * 1000, y: Math.abs(rnd - 1)}); - // i += 60 * 5; - //} - - var chartDiv = "chart6"; - var sliderDiv = "slider6"; - var x_axis = "x_axis6"; - var y_axis = "y_axis6"; - $(chartWrapperElmId).html("").html('
    '); - - var graph = new Rickshaw.Graph({ - element: document.getElementById(chartDiv), - width: graphWidth, - height: 150, - strokeWidth: 0.5, - renderer: 'bar_no_gap', - xScale: d3.time.scale(), - padding: {top: 0.2, left: 0.02, right: 0.02, bottom: 0}, - series: [ - {color: '#5E610B', data: chartData[0]}, - {color: 'white', data: chartData[1]} - ] - }); - - graph.registerRenderer(new Rickshaw.Graph.Renderer.BarNoGap({graph: graph})); - - graph.render(); - - var xAxis = new Rickshaw.Graph.Axis.X({ - graph: graph, - orientation: 'bottom', - element: document.getElementById(x_axis), - tickFormat: graph.x.tickFormat() - }); - - xAxis.render(); - - var yAxis = new Rickshaw.Graph.Axis.Y({ - graph: graph, - orientation: 'left', - element: document.getElementById(y_axis), - width: 40, - height: 160, - tickFormat: function (y) { - switch (y) { - case 1: - return 'ON'; - case 0: - return 'OFF'; - default : - return ''; - } - } - }); - - yAxis.render(); - - var slider = new Rickshaw.Graph.RangeSlider.Preview({ - graph: graph, - element: document.getElementById(sliderDiv) - }); -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/fan_graph.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/fan_graph.js deleted file mode 100644 index 991a14d6..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/fan_graph.js +++ /dev/null @@ -1,84 +0,0 @@ -function updateFanGraph(fanData) { - renderFanChart(fanData); -} - -function renderFanChart(chartDataRaw) { - var chartWrapperElmId = "#canvas-wrapper5"; - var graphWidth = $(chartWrapperElmId).width() - 50; - if (chartDataRaw.length == 0) { - $(chartWrapperElmId).html("No data available..."); - return; - } - - var chartData = [[], []]; - for (var i = 0; i < chartDataRaw.length; i++){ - chartData[0].push({x:parseInt(chartDataRaw[i].x), y:parseInt(chartDataRaw[i].y)}); - chartData[1].push({x:parseInt(chartDataRaw[i].x), y:Math.abs(parseInt(chartDataRaw[i].y) - 1)}); - } - - //var i = parseInt(fromDate); - //while (i < parseInt(toDate)) { - // var rnd = Math.round(Math.random()); - // chartData[0].push({x: i * 1000, y: rnd}); - // chartData[1].push({x: i * 1000, y: Math.abs(rnd - 1)}); - // i += 60 * 5; - //} - - var chartDiv = "chart5"; - var sliderDiv = "slider5"; - var x_axis = "x_axis5"; - var y_axis = "y_axis5"; - $(chartWrapperElmId).html("").html('
    '); - - var graph = new Rickshaw.Graph({ - element: document.getElementById(chartDiv), - width: graphWidth, - height: 150, - strokeWidth: 0.5, - renderer: 'bar_no_gap', - xScale: d3.time.scale(), - padding: {top: 0.2, left: 0.02, right: 0.02, bottom: 0}, - series: [ - {color: '#2F0B3A', data: chartData[0]}, - {color: 'white', data: chartData[1]} - ] - }); - - graph.registerRenderer(new Rickshaw.Graph.Renderer.BarNoGap({graph: graph})); - - graph.render(); - - var xAxis = new Rickshaw.Graph.Axis.X({ - graph: graph, - orientation: 'bottom', - element: document.getElementById(x_axis), - tickFormat: graph.x.tickFormat() - }); - - xAxis.render(); - - var yAxis = new Rickshaw.Graph.Axis.Y({ - graph: graph, - orientation: 'left', - element: document.getElementById(y_axis), - width: 40, - height: 160, - tickFormat: function (y) { - switch (y) { - case 1: - return 'ON'; - case 0: - return 'OFF'; - default : - return ''; - } - } - }); - - yAxis.render(); - - var slider = new Rickshaw.Graph.RangeSlider.Preview({ - graph: graph, - element: document.getElementById(sliderDiv) - }); -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/light_graph.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/light_graph.js deleted file mode 100644 index 1e91a758..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/light_graph.js +++ /dev/null @@ -1,85 +0,0 @@ -function updateLightGraph(lightData) { - renderLightChart(lightData); -} - - -function renderLightChart(chartDataRaw){ - var chartWrapperElmId = "#canvas-wrapper2"; - var graphWidth = $(chartWrapperElmId).width() - 50; - if (chartDataRaw.length == 0) { - $(chartWrapperElmId).html("No data available..."); - return; - } - - var chartData = [[], []]; - for (var i = 0; i < chartDataRaw.length; i++){ - chartData[0].push({x:parseInt(chartDataRaw[i].x), y:parseInt(chartDataRaw[i].y)}); - chartData[1].push({x:parseInt(chartDataRaw[i].x), y:Math.abs(parseInt(chartDataRaw[i].y) - 1)}); - } - - //var i = parseInt(fromDate); - //while (i < parseInt(toDate)) { - // var rnd = Math.round(Math.random()); - // chartData[0].push({x: i * 1000, y: rnd}); - // chartData[1].push({x: i * 1000, y: Math.abs(rnd - 1)}); - // i += 60 * 5; - //} - - var chartDiv = "chart2"; - var sliderDiv = "slider2"; - var x_axis = "x_axis2"; - var y_axis = "y_axis2"; - $(chartWrapperElmId).html("").html('
    '); - - var graph = new Rickshaw.Graph({ - element: document.getElementById(chartDiv), - width: graphWidth, - height: 150, - strokeWidth: 0.5, - renderer: 'bar_no_gap', - xScale: d3.time.scale(), - padding: {top: 0.2, left: 0.02, right: 0.02, bottom: 0}, - series: [ - {color: 'steelblue', data: chartData[0]}, - {color: 'white', data: chartData[1]} - ] - }); - - graph.registerRenderer(new Rickshaw.Graph.Renderer.BarNoGap({graph: graph})); - - graph.render(); - - var xAxis = new Rickshaw.Graph.Axis.X({ - graph: graph, - orientation: 'bottom', - element: document.getElementById(x_axis), - tickFormat: graph.x.tickFormat() - }); - - xAxis.render(); - - var yAxis = new Rickshaw.Graph.Axis.Y({ - graph: graph, - orientation: 'left', - element: document.getElementById(y_axis), - width: 40, - height: 160, - tickFormat: function (y) { - switch (y) { - case 1: - return 'ON'; - case 0: - return 'OFF'; - default : - return ''; - } - } - }); - - yAxis.render(); - - var slider = new Rickshaw.Graph.RangeSlider.Preview({ - graph: graph, - element: document.getElementById(sliderDiv) - }); -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/motion_graph.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/motion_graph.js deleted file mode 100644 index 04fe84d6..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/motion_graph.js +++ /dev/null @@ -1,70 +0,0 @@ -function updateMotionGraph(motionData) { - renderMotionChart(motionData); -} - - -function renderMotionChart(chartDataRaw){ - var chartWrapperElmId = "#canvas-wrapper3"; - var graphWidth = $(chartWrapperElmId).width() - 50; - if (chartDataRaw.length == 0) { - $(chartWrapperElmId).html("No data available..."); - return; - } - - var chartData = []; - for (var i = 0; i < chartDataRaw.length; i++){ - chartData.push({x:parseInt(chartDataRaw[i].x), y:parseInt(chartDataRaw[i].y)}); - } - - //var i = parseInt(fromDate); - //while (i < parseInt(toDate)){ - // var rnd = Math.random() * (30 - 20) + 20; - // chartData.push({x:i * 1000, y:rnd}); - // i += 60 * 5; - //} - - var chartDiv = "chart3"; - var sliderDiv = "slider3"; - var x_axis = "x_axis3"; - var y_axis = "y_axis3"; - $(chartWrapperElmId).html("").html('
    '); - - var graph = new Rickshaw.Graph({ - element: document.getElementById(chartDiv), - width: graphWidth, - height: 400, - strokeWidth: 0.5, - renderer: 'line', - xScale: d3.time.scale(), - padding: {top: 0.2, left: 0.02, right: 0.02, bottom: 0}, - series:[ - { color: '#2F0B3A', data: chartData } - ] - }); - - graph.render(); - - var xAxis = new Rickshaw.Graph.Axis.X({ - graph: graph, - orientation: 'bottom', - element: document.getElementById(x_axis), - tickFormat: graph.x.tickFormat() - }); - - xAxis.render(); - - var yAxis = new Rickshaw.Graph.Axis.Y({ - graph: graph, - orientation: 'left', - element: document.getElementById(y_axis), - width: 40, - height: 410 - }); - - yAxis.render(); - - var slider = new Rickshaw.Graph.RangeSlider.Preview({ - graph: graph, - element: document.getElementById(sliderDiv) - }); -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/sonar_graph.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/sonar_graph.js deleted file mode 100644 index c7bdf5c5..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/sonar_graph.js +++ /dev/null @@ -1,69 +0,0 @@ -function updateSonarGraph(sonarData) { - renderSonarChart(sonarData); -} - -function renderSonarChart(chartDataRaw){ - var chartWrapperElmId = "#canvas-wrapper4"; - var graphWidth = $(chartWrapperElmId).width() - 50; - if (chartDataRaw.length == 0) { - $(chartWrapperElmId).html("No data available..."); - return; - } - - var chartData = []; - for (var i = 0; i < chartDataRaw.length; i++){ - chartData.push({x:parseInt(chartDataRaw[i].x), y:parseInt(chartDataRaw[i].y)}); - } - - //var i = parseInt(fromDate); - //while (i < parseInt(toDate)){ - // var rnd = Math.random() * (30 - 20) + 20; - // chartData.push({x:i * 1000, y:rnd}); - // i += 60 * 5; - //} - - var chartDiv = "chart4"; - var sliderDiv = "slider4"; - var x_axis = "x_axis4"; - var y_axis = "y_axis4"; - $(chartWrapperElmId).html("").html('
    '); - - var graph = new Rickshaw.Graph({ - element: document.getElementById(chartDiv), - width: graphWidth, - height: 400, - strokeWidth: 1, - renderer: 'line', - xScale: d3.time.scale(), - padding: {top: 0.2, left: 0.02, right: 0.02, bottom: 0}, - series:[ - { color: '#170B3B', data: chartData } - ] - }); - - graph.render(); - - var xAxis = new Rickshaw.Graph.Axis.X({ - graph: graph, - orientation: 'bottom', - element: document.getElementById(x_axis), - tickFormat: graph.x.tickFormat() - }); - - xAxis.render(); - - var yAxis = new Rickshaw.Graph.Axis.Y({ - graph: graph, - orientation: 'left', - element: document.getElementById(y_axis), - width: 40, - height: 410 - }); - - yAxis.render(); - - var slider = new Rickshaw.Graph.RangeSlider.Preview({ - graph: graph, - element: document.getElementById(sliderDiv) - }); -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/temperature_graph.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/temperature_graph.js deleted file mode 100644 index 3fed9611..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/graphs/temperature_graph.js +++ /dev/null @@ -1,70 +0,0 @@ -function updateTemperatureGraph(temperatureData) { - console.log("temperatureData"); - renderTemperatureChart(temperatureData); -} - -function renderTemperatureChart(chartDataRaw){ - var chartWrapperElmId = "#canvas-wrapper1"; - var graphWidth = $(chartWrapperElmId).width() - 50; - if (chartDataRaw.length == 0) { - $(chartWrapperElmId).html("No data available..."); - return; - } - - var chartData = []; - for (var i = 0; i < chartDataRaw.length; i++){ - chartData.push({x:parseInt(chartDataRaw[i].x), y:parseInt(chartDataRaw[i].y)}); - } - - //var i = parseInt(fromDate); - //while (i < parseInt(toDate)){ - // var rnd = Math.random() * (30 - 20) + 20; - // chartData.push({x:i * 1000, y:rnd}); - // i += 60 * 5; - //} - - var chartDiv = "chart1"; - var sliderDiv = "slider1"; - var x_axis = "x_axis1"; - var y_axis = "y_axis1"; - $(chartWrapperElmId).html("").html('
    '); - - var graph = new Rickshaw.Graph({ - element: document.getElementById(chartDiv), - width: graphWidth, - height: 400, - strokeWidth: 1, - renderer: 'line', - xScale: d3.time.scale(), - padding: {top: 0.2, left: 0.02, right: 0.02, bottom: 0}, - series:[ - { color: '#FF4000', data: chartData } - ] - }); - - graph.render(); - - var xAxis = new Rickshaw.Graph.Axis.X({ - graph: graph, - orientation: 'bottom', - element: document.getElementById(x_axis), - tickFormat: graph.x.tickFormat() - }); - - xAxis.render(); - - var yAxis = new Rickshaw.Graph.Axis.Y({ - graph: graph, - orientation: 'left', - element: document.getElementById(y_axis), - width: 40, - height: 410 - }); - - yAxis.render(); - - var slider = new Rickshaw.Graph.RangeSlider.Preview({ - graph: graph, - element: document.getElementById(sliderDiv) - }); -} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/jquery.daterangepicker.js b/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/jquery.daterangepicker.js deleted file mode 100644 index 872bc597..00000000 --- a/modules/distribution/src/repository/jaggeryapps/iot/units/mydevice/public/js/jquery.daterangepicker.js +++ /dev/null @@ -1,1432 +0,0 @@ -// daterangepicker.js -// version : 0.0.5 -// author : Chunlong Liu -// last updated at: 2014-05-27 -// license : MIT -// www.jszen.com - -(function($) -{ - - $.dateRangePickerLanguages = - { - 'cn': - { - 'selected': '已选择:', - 'day':'天', - 'days': '天', - 'apply': '确定', - 'week-1' : '一', - 'week-2' : '二', - 'week-3' : '三', - 'week-4' : '四', - 'week-5' : '五', - 'week-6' : '六', - 'week-7' : '日', - 'month-name': ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'], - 'shortcuts' : '快捷选择', - 'past': '过去', - 'following':'将来', - 'previous' : '   ', - 'prev-week' : '上周', - 'prev-month' : '上个月', - 'prev-year' : '去年', - 'next': '   ', - 'next-week':'下周', - 'next-month':'下个月', - 'next-year':'明年', - 'less-than' : '所选日期范围不能大于%d天', - 'more-than' : '所选日期范围不能小于%d天', - 'default-more' : '请选择大于%d天的日期范围', - 'default-less' : '请选择小于%d天的日期范围', - 'default-range' : '请选择%d天到%d天的日期范围', - 'default-single':'请选择一个日期', - 'default-default': '请选择一个日期范围' - }, - 'cz': - { - 'selected': 'Vybráno:', - 'day':'Den', - 'days': 'Dny', - 'apply': 'Zavřít', - 'week-1' : 'Po', - 'week-2' : 'Út', - 'week-3' : 'St', - 'week-4' : 'Čt', - 'week-5' : 'Pá', - 'week-6' : 'So', - 'week-7' : 'Ne', - 'month-name': ['Leden','Únor','Březen','Duben','Květen','Červen','Červenec','Srpen','Září','Říjen','Listopad','Prosinec'], - 'shortcuts' : 'Zkratky', - 'past': 'po', - 'following':'následující', - 'previous' : 'předchozí', - 'prev-week' : 'týden', - 'prev-month' : 'měsíc', - 'prev-year' : 'rok', - 'next':'další', - 'next-week':'týden', - 'next-month':'měsíc', - 'next-year':'rok', - 'less-than' : 'Rozsah data by neměl být větší než %d dnů', - 'more-than' : 'Rozsah data by neměl být menší než %d dnů', - 'default-more' : 'Prosím zvolte rozsah data větší než %d dnů', - 'default-single' : 'Prosím zvolte datum', - 'default-less' : 'Prosím zvolte rozsah data menší než %d dnů', - 'default-range' : 'Prosím zvolte rozsah data mezi %d a %d dny', - 'default-default': 'Prosím zvolte rozsah data' - }, - 'en': - { - 'selected': 'Selected:', - 'day':'Day', - 'days': 'Days', - 'apply': 'Apply', - 'week-1' : 'MO', - 'week-2' : 'TU', - 'week-3' : 'WE', - 'week-4' : 'TH', - 'week-5' : 'FR', - 'week-6' : 'SA', - 'week-7' : 'SU', - 'month-name': ['JANUARY','FEBRUARY','MARCH','APRIL','MAY','JUNE','JULY','AUGUST','SEPTEMBER','OCTOBER','NOVEMBER','DECEMBER'], - 'shortcuts' : 'Shortcuts', - 'past': 'Past', - 'following':'Following', - 'previous' : 'Previous', - 'prev-week' : 'Week', - 'prev-month' : 'Month', - 'prev-year' : 'Year', - 'next':'Next', - 'next-week':'Week', - 'next-month':'Month', - 'next-year':'Year', - 'less-than' : 'Date range should not be more than %d days', - 'more-than' : 'Date range should not be less than %d days', - 'default-more' : 'Please select a date range longer than %d days', - 'default-single' : 'Please select a date', - 'default-less' : 'Please select a date range less than %d days', - 'default-range' : 'Please select a date range between %d and %d days', - 'default-default': 'Please select a date range' - }, - 'it': - { - 'selected': 'Selezionati:', - 'day':'Giorno', - 'days': 'Giorni', - 'apply': 'Chiudi', - 'week-1' : 'LU', - 'week-2' : 'MA', - 'week-3' : 'ME', - 'week-4' : 'GI', - 'week-5' : 'VE', - 'week-6' : 'SA', - 'week-7' : 'DO', - 'month-name': ['GENNAIO','FEBBRAIO','MARZO','APRILE','MAGGIO','GIUGNO','LUGLIO','AGOSTO','SETTEMBRE','OTTOBRE','NOVEMBRE','DICEMBRE'], - 'shortcuts' : 'Scorciatoie', - 'past': 'Scorso', - 'following':'Successivo', - 'previous' : 'Precedente', - 'prev-week' : 'Settimana', - 'prev-month' : 'Mese', - 'prev-year' : 'Anno', - 'next':'Prossimo', - 'next-week':'Settimana', - 'next-month':'Mese', - 'next-year':'Anno', - 'less-than' : 'L\'intervallo non dev\'essere maggiore di %d giorni', - 'more-than' : 'L\'intervallo non dev\'essere minore di %d giorni', - 'default-more' : 'Seleziona un intervallo maggiore di %d giorni', - 'default-single' : 'Seleziona una data', - 'default-less' : 'Seleziona un intervallo minore di %d giorni', - 'default-range' : 'Seleziona un intervallo compreso tra i %d e i %d giorni', - 'default-default': 'Seleziona un intervallo di date' - }, - 'es': - { - 'selected': 'Seleccionado:', - 'day':'Dia', - 'days': 'Dias', - 'apply': 'Cerrar', - 'week-1' : 'LU', - 'week-2' : 'MA', - 'week-3' : 'MI', - 'week-4' : 'JU', - 'week-5' : 'VI', - 'week-6' : 'SA', - 'week-7' : 'DO', - 'month-name': ['ENERO','FEBRERO','MARZO','ABRIL','MAYO','JUNIO','JULIO','AGOSTO','SEPTIEMBRE','OCTUBRE','NOVIEMBRE','DICIEMBRE'], - 'shortcuts' : 'Accesos directos', - 'past': 'Pasado', - 'following':'Siguiente', - 'previous' : 'Anterior', - 'prev-week' : 'Semana', - 'prev-month' : 'Mes', - 'prev-year' : 'Año', - 'next':'Siguiente', - 'next-week':'Semana', - 'next-month':'Mes', - 'next-year':'Año', - 'less-than' : 'El rango no deberia ser mayor de %d dias', - 'more-than' : 'El rango no deberia ser menor de %d dias', - 'default-more' : 'Por favor selecciona un rango mayor a %d dias', - 'default-single' : 'Por favor selecciona un dia', - 'default-less' : 'Por favor selecciona un rango menor a %d dias', - 'default-range' : 'Por favor selecciona un rango entre %d y %d dias', - 'default-default': 'Por favor selecciona un rango de fechas.' - }, - 'de': - { - 'selected': 'Auswahl:', - 'day':'Tag', - 'days': 'Tage', - 'apply': 'Schließen', - 'week-1' : 'MO', - 'week-2' : 'DI', - 'week-3' : 'MI', - 'week-4' : 'DO', - 'week-5' : 'FR', - 'week-6' : 'SA', - 'week-7' : 'SO', - 'month-name': ['JANUAR','FEBRUAR','MÄRZ','APRIL','MAI','JUNI','JULI','AUGUST','SEPTEMBER','OKTOBER','NOVEMBER','DEZEMBER'], - 'shortcuts' : 'Schnellwahl', - 'past': 'Vorherige', - 'following':'Folgende', - 'previous' : 'Vorherige', - 'prev-week' : 'Woche', - 'prev-month' : 'Monat', - 'prev-year' : 'Jahr', - 'next':'Nächste', - 'next-week':'Woche', - 'next-month':'Monat', - 'next-year':'Jahr', - 'less-than' : 'Datumsbereich darf nicht größer sein als %d Tage', - 'more-than' : 'Datumsbereich darf nicht kleiner sein als %d Tage', - 'default-more' : 'Bitte mindestens %d Tage auswählen', - 'default-single' : 'Bitte ein Datum auswählen', - 'default-less' : 'Bitte weniger als %d Tage auswählen', - 'default-range' : 'Bitte einen Datumsbereich zwischen %d und %d Tagen auswählen', - 'default-default': 'Bitte ein Start- und Enddatum auswählen' - }, - 'ru': - { - 'selected': 'Выбрано:', - 'day': 'День', - 'days': 'Дней', - 'apply': 'Закрыть', - 'week-1': 'ПН', - 'week-2': 'ВТ', - 'week-3': 'СР', - 'week-4': 'ЧТ', - 'week-5': 'ПТ', - 'week-6': 'СБ', - 'week-7': 'ВС', - 'month-name': ['ЯНВАРЬ','ФЕВРАЛЬ','МАРТ','АПРЕЛЬ','МАЙ','ИЮНЬ','ИЮЛЬ','АВГУСТ','СЕНТЯБРЬ','ОКТЯБРЬ','НОЯБРЬ','ДЕКАБРЬ'], - 'shortcuts': 'Быстрый выбор', - 'past': 'Прошедшие', - 'following': 'Следующие', - 'previous': '   ', - 'prev-week': 'Неделя', - 'prev-month': 'Месяц', - 'prev-year': 'Год', - 'next': '   ', - 'next-week': 'Неделя', - 'next-month': 'Месяц', - 'next-year': 'Год', - 'less-than': 'Диапазон не может быть больше %d дней', - 'more-than': 'Диапазон не может быть меньше %d дней', - 'default-more': 'Пожалуйста выберите диапазон больше %d дней', - 'default-single': 'Пожалуйста выберите дату', - 'default-less': 'Пожалуйста выберите диапазон меньше %d дней', - 'default-range': 'Пожалуйста выберите диапазон между %d и %d днями', - 'default-default': 'Пожалуйста выберите диапазон' - }, - 'fr': - { - 'selected': 'Sélection:', - 'day':'Jour', - 'days': 'Jours', - 'apply': 'Fermer', - 'week-1' : 'LU', - 'week-2' : 'MA', - 'week-3' : 'ME', - 'week-4' : 'JE', - 'week-5' : 'VE', - 'week-6' : 'SA', - 'week-7' : 'DI', - 'month-name': ['JANVIER','FÉVRIER','MARS','AVRIL','MAI','JUIN','JUILLET','AOÛT','SEPTEMBRE','OCTOBRE','NOVEMBRE','DÉCEMBRE'], - 'shortcuts' : 'Raccourcis', - 'past': 'Passé', - 'following':'Suivant', - 'previous' : 'Précédent', - 'prev-week' : 'Semaine', - 'prev-month' : 'Mois', - 'prev-year' : 'Année', - 'next':'Suivant', - 'next-week':'Semaine', - 'next-month':'Mois', - 'next-year':'Année', - 'less-than' : 'L\'intervalle ne doit pas être supérieure à %d jours', - 'more-than' : 'L\'intervalle ne doit pas être inférieure à %d jours', - 'default-more' : 'Merci de choisir une intervalle supérieure à %d jours', - 'default-single' : 'Merci de choisir une date', - 'default-less' : 'Merci de choisir une intervalle inférieure %d jours', - 'default-range' : 'Merci de choisir une intervalle comprise entre %d et %d jours', - 'default-default': 'Merci de choisir une date' - } - }; - - - if (window['moment'] === undefined) - { - if (window['console'] && console['warn']) console.warn('Please import moment.js before daterangepicker.js'); - return; - } - - $.fn.dateRangePicker = function(opt) - { - if (!opt) opt = {}; - opt = $.extend(true, - { - autoClose: false, - format: 'YYYY-MM-DD', - separator: ' to ', - language: 'auto', - startOfWeek: 'sunday',// or monday - getValue: function() - { - return $(this).val(); - }, - setValue: function(s) - { - if(!$(this).attr('readonly') && !$(this).is(':disabled')){ - $(this).val(s); - } - }, - startDate: false, - endDate: false, - time: { - enabled: false - }, - minDays: 0, - maxDays: 0, - showShortcuts: true, - shortcuts: - { - //'prev-days': [1,3,5,7], - 'next-days': [3,5,7], - //'prev' : ['week','month','year'], - 'next' : ['week','month','year'] - }, - customShortcuts : [], - inline:false, - container:'body', - alwaysOpen:false, - singleDate:false, - batchMode: false, - duration: 200 - },opt); - - opt.start = false; - opt.end = false; - - if (opt.startDate && typeof opt.startDate == 'string') opt.startDate = moment(opt.startDate,opt.format).toDate(); - if (opt.endDate && typeof opt.endDate == 'string') opt.endDate = moment(opt.endDate,opt.format).toDate(); - - var langs = getLanguages(); - var box; - var initiated = false; - var self = this; - var selfDom = $(self).get(0); - - $(this).unbind('.datepicker').bind('click.datepicker',function(evt) - { - var isOpen = box.is(':visible'); - $(document).trigger('click.datepicker'); - evt.stopPropagation(); - if(!isOpen) open(opt.duration); - }); - - init_datepicker.call(this); - - if (opt.alwaysOpen) - { - open(0); - } - - // expose some api - $(this).data('dateRangePicker', - { - setDateRange : function(d1,d2) - { - if (typeof d1 == 'string' && typeof d2 == 'string') - { - d1 = moment(d1,opt.format).toDate(); - d2 = moment(d2,opt.format).toDate(); - } - setDateRange(d1,d2); - }, - clear: clearSelection, - close: closeDatePicker, - open: open, - getDatePicker: getDatePicker, - destroy: function() - { - $(self).unbind('.datepicker'); - $(self).data('dateRangePicker',''); - box.remove(); - $(window).unbind('resize.datepicker',calcPosition); - $(document).unbind('click.datepicker',closeDatePicker); - } - }); - - $(window).bind('resize.datepicker',calcPosition); - - return this; - - - - - - - - - - - - function init_datepicker() - { - var self = this; - - if ($(this).data('date-picker-opened')) - { - closeDatePicker(); - return; - } - $(this).data('date-picker-opened',true); - - - - - - box = createDom().hide(); - $(opt.container).append(box); - - if (!opt.inline) - { - calcPosition(); - } - else - { - box.addClass("inline-wrapper").css({position:'static'}); - } - - if (opt.alwaysOpen) - { - box.find('.apply-btn').hide(); - } - - var defaultTime = opt.defaultTime ? opt.defaultTime : new Date(); - if (opt.startDate && compare_month(defaultTime,opt.startDate) < 0 ) defaultTime = moment(opt.startDate).toDate(); - if (opt.endDate && compare_month(nextMonth(defaultTime),opt.endDate) > 0 ) defaultTime = prevMonth(moment(opt.endDate).toDate()); - - - showMonth(defaultTime,'month1'); - showMonth(nextMonth(defaultTime),'month2'); - - if (opt.time.enabled) { - if ((opt.startDate && opt.endDate) || (opt.start && opt.end)) { - showTime(moment(opt.start || opt.startDate).toDate(),'time1'); - showTime(moment(opt.end || opt.endDate).toDate(),'time2'); - } else { - showTime(defaultTime,'time1'); - showTime(defaultTime,'time2'); - } - } - - //showSelectedInfo(); - - - - - var defaultTopText = ''; - if (opt.singleDate) - defaultTopText = lang('default-single'); - else if (opt.minDays && opt.maxDays) - defaultTopText = lang('default-range'); - else if (opt.minDays) - defaultTopText = lang('default-more'); - else if (opt.maxDays) - defaultTopText = lang('default-less'); - else - defaultTopText = lang('default-default'); - - box.find('.default-top').html( defaultTopText.replace(/\%d/,opt.minDays).replace(/\%d/,opt.maxDays)); - - - - - setTimeout(function() - { - initiated = true; - },0); - - box.click(function(evt) - { - evt.stopPropagation(); - }); - - $(document).bind('click.datepicker',closeDatePicker); - - box.find('.next').click(function() - { - var isMonth2 = $(this).parents('table').hasClass('month2'); - var month = isMonth2 ? opt.month2 : opt.month1; - month = nextMonth(month); - if (!opt.singleDate && !isMonth2 && compare_month(month,opt.month2) >= 0 || isMonthOutOfBounds(month)) return; - showMonth(month,isMonth2 ? 'month2' : 'month1'); - showGap(); - }); - - box.find('.prev').click(function() - { - var isMonth2 = $(this).parents('table').hasClass('month2'); - var month = isMonth2 ? opt.month2 : opt.month1; - month = prevMonth(month); - //if (isMonth2 && month.getFullYear()+''+month.getMonth() <= opt.month1.getFullYear()+''+opt.month1.getMonth()) return; - if (isMonth2 && compare_month(month,opt.month1) <= 0 || isMonthOutOfBounds(month)) return; - showMonth(month,isMonth2 ? 'month2' : 'month1'); - showGap(); - }); - - - box.bind('click',function(evt) - { - if ($(evt.target).hasClass('day')) - { - dayClicked($(evt.target)); - } - }); - - box.attr('unselectable', 'on') - .css('user-select', 'none') - .bind('selectstart', function(e) - { - e.preventDefault(); return false; - }); - - box.find('.apply-btn').click(function() - { - closeDatePicker(); - var dateRange = getDateString(new Date(opt.start))+ opt.separator +getDateString(new Date(opt.end)); - $(self).trigger('datepicker-apply', - { - 'value': dateRange, - 'date1' : new Date(opt.start), - 'date2' : new Date(opt.end) - }); - }); - - box.find('[shortcut]').click(function() - { - var shortcut = $(this).attr('shortcut'); - var end = new Date(),start = false; - if (shortcut.indexOf('day') != -1) - { - var day = parseInt(shortcut.split(',',2)[1],10); - start = new Date(new Date().getTime() + 86400000*day); - end = new Date(end.getTime() + 86400000*(day>0?1:-1) ); - } - else if (shortcut.indexOf('week')!= -1) - { - var dir = shortcut.indexOf('prev,') != -1 ? -1 : 1; - - if (dir == 1) - var stopDay = opt.startOfWeek == 'monday' ? 1 : 0; - else - var stopDay = opt.startOfWeek == 'monday' ? 0 : 6; - - end = new Date(end.getTime() - 86400000); - while(end.getDay() != stopDay) end = new Date(end.getTime() + dir*86400000); - start = new Date(end.getTime() + dir*86400000*6); - } - else if (shortcut.indexOf('month') != -1) - { - var dir = shortcut.indexOf('prev,') != -1 ? -1 : 1; - if (dir == 1) - start = nextMonth(end); - else - start = prevMonth(end); - start.setDate(1); - end = nextMonth(start); - end.setDate(1); - end = new Date(end.getTime() - 86400000); - } - else if (shortcut.indexOf('year') != -1) - { - var dir = shortcut.indexOf('prev,') != -1 ? -1 : 1; - start = new Date(); - start.setFullYear(end.getFullYear() + dir); - start.setMonth(0); - start.setDate(1); - end.setFullYear(end.getFullYear() + dir); - end.setMonth(11); - end.setDate(31); - } - else if (shortcut == 'custom') - { - var name = $(this).html(); - if (opt.customShortcuts && opt.customShortcuts.length > 0) - { - for(var i=0;i=2)) - { - var ___format = opt.format; - if (___format.match(/Do/)) - { - - ___format = ___format.replace(/Do/,'D'); - defaults[0] = defaults[0].replace(/(\d+)(th|nd|st)/,'$1'); - if(defaults.length >= 2){ - defaults[1] = defaults[1].replace(/(\d+)(th|nd|st)/,'$1'); - } - } - // set initiated to avoid triggerring datepicker-change event - initiated = false; - if(defaults.length >= 2){ - setDateRange(moment(defaults[0], ___format).toDate(),moment(defaults[1], ___format).toDate()); - } - else if(defaults.length==1 && opt.singleDate){ - setSingleDate(moment(defaults[0], ___format).toDate()); - } - - initiated = true; - } - box.slideDown(animationTime); - } - - - - function renderTime (name, date) { - box.find("." + name + " input[type=range].hour-range").val(moment(date).hours()); - box.find("." + name + " input[type=range].minute-range").val(moment(date).minutes()); - setTime(name, moment(date).format("HH"), moment(date).format("mm")); - } - - function changeTime (name, date) { - opt[name] = parseInt( - moment(parseInt(date)) - .startOf('day') - .add('h', moment(opt[name + "Time"]).format("HH")) - .add('m', moment(opt[name + "Time"]).format("mm")).valueOf() - ); - } - - function swapTime () { - renderTime("time1", opt.start); - renderTime("time2", opt.end); - } - - function setTime (name, hour, minute) { - hour && (box.find("." + name + " .hour-val").text(hour)); - minute && (box.find("." + name + " .minute-val").text(minute)); - switch (name) { - case "time1": - if (opt.start) { - setRange("start", moment(opt.start)); - } - setRange("startTime", moment(opt.startTime || moment().valueOf())); - break; - case "time2": - if (opt.end) { - setRange("end", moment(opt.end)); - } - setRange("endTime", moment(opt.endTime || moment().valueOf())); - break; - } - function setRange(name, timePoint) { - var h = timePoint.format("HH"), - m = timePoint.format("mm"); - opt[name] = timePoint - .startOf('day') - .add("h", hour || h) - .add("m", minute || m) - .valueOf(); - } - checkSelectionValid(); - showSelectedInfo(); - showSelectedDays(); - } - - function clearSelection() - { - opt.start = false; - opt.end = false; - box.find('.day.checked').removeClass('checked'); - opt.setValue.call(selfDom, ''); - checkSelectionValid(); - showSelectedInfo(); - showSelectedDays(); - } - - function handleStart(time) - { - var r = time; - if (opt.batchMode === 'week-range') { - if (opt.startOfWeek === 'monday') { - r = moment(parseInt(time)).startOf('isoweek').valueOf(); - } else { - r = moment(parseInt(time)).startOf('week').valueOf(); - } - } else if (opt.batchMode === 'month-range') { - r = moment(parseInt(time)).startOf('month').valueOf(); - } - - return r; - } - - function handleEnd(time) - { - var r = time; - if (opt.batchMode === 'week-range') { - if (opt.startOfWeek === 'monday') { - r = moment(parseInt(time)).endOf('isoweek').valueOf(); - } else { - r = moment(parseInt(time)).endOf('week').valueOf(); - } - } else if (opt.batchMode === 'month') { - r = moment(parseInt(time)).endOf('month').valueOf(); - } - - return r; - } - - - function dayClicked(day) - { - if (day.hasClass('invalid')) return; - var time = day.attr('time'); - day.addClass('checked'); - if ( opt.singleDate ) - { - opt.start = time; - opt.end = false; - if (opt.time.enabled) { - changeTime("start", opt.start); - } - } - else if (opt.batchMode === 'week') - { - if (opt.startOfWeek === 'monday') { - opt.start = moment(parseInt(time)).startOf('isoweek').valueOf(); - opt.end = moment(parseInt(time)).endOf('isoweek').valueOf(); - } else { - opt.end = moment(parseInt(time)).endOf('week').valueOf(); - opt.start = moment(parseInt(time)).startOf('week').valueOf(); - } - } - else if (opt.batchMode === 'month') - { - opt.start = moment(parseInt(time)).startOf('month').valueOf(); - opt.end = moment(parseInt(time)).endOf('month').valueOf(); - } - else if ((opt.start && opt.end) || (!opt.start && !opt.end) ) - { - opt.start = handleStart(time); - opt.end = false; - if (opt.time.enabled) { - changeTime("start", opt.start); - } - } - else if (opt.start) - { - opt.end = handleEnd(time); - if (opt.time.enabled) { - changeTime("end", opt.end); - } - } - - if (!opt.singleDate && opt.start && opt.end && opt.start > opt.end) - { - var tmp = opt.end; - opt.end = handleEnd(opt.start); - opt.start = handleStart(tmp); - if (opt.time.enabled) { - swapTime(); - } - } - - opt.start = parseInt(opt.start); - opt.end = parseInt(opt.end); - - checkSelectionValid(); - showSelectedInfo(); - showSelectedDays(); - autoclose(); - } - - function autoclose () { - if (opt.singleDate === true) { - if (initiated && opt.start ) - { - if (opt.autoClose) closeDatePicker(); - } - } else { - if (initiated && opt.start && opt.end) - { - if (opt.autoClose) closeDatePicker(); - } - } - } - - function checkSelectionValid() - { - var days = Math.ceil( (opt.end - opt.start) / 86400000 ) + 1; - if (opt.singleDate) { // Validate if only start is there - if (opt.start && !opt.end) - box.find('.drp_top-bar').removeClass('error').addClass('normal'); - else - box.find('.drp_top-bar').removeClass('error').removeClass('normal'); - } - else if ( opt.maxDays && days > opt.maxDays) - { - opt.start = false; - opt.end = false; - box.find('.day').removeClass('checked'); - box.find('.drp_top-bar').removeClass('normal').addClass('error').find('.error-top').html( lang('less-than').replace('%d',opt.maxDays) ); - } - else if ( opt.minDays && days < opt.minDays) - { - opt.start = false; - opt.end = false; - box.find('.day').removeClass('checked'); - box.find('.drp_top-bar').removeClass('normal').addClass('error').find('.error-top').html( lang('more-than').replace('%d',opt.minDays) ); - } - else - { - if (opt.start || opt.end) - box.find('.drp_top-bar').removeClass('error').addClass('normal'); - else - box.find('.drp_top-bar').removeClass('error').removeClass('normal'); - } - - if ( (opt.singleDate && opt.start && !opt.end) || (!opt.singleDate && opt.start && opt.end) ) - { - box.find('.apply-btn').removeClass('disabled'); - } - else - { - box.find('.apply-btn').addClass('disabled'); - } - - if (opt.batchMode) - { - if ( (opt.start && opt.startDate && compare_day(opt.start, opt.startDate) < 0) - || (opt.end && opt.endDate && compare_day(opt.end, opt.endDate) > 0) ) - { - opt.start = false; - opt.end = false; - box.find('.day').removeClass('checked'); - } - } - } - - function showSelectedInfo() - { - box.find('.start-day').html('...'); - box.find('.end-day').html('...'); - box.find('.selected-days').hide(); - if (opt.start) - { - box.find('.start-day').html(getDateString(new Date(parseInt(opt.start)))); - } - if (opt.end) - { - box.find('.end-day').html(getDateString(new Date(parseInt(opt.end)))); - } - - if (opt.start && opt.singleDate) - { - box.find('.apply-btn').removeClass('disabled'); - var dateRange = getDateString(new Date(opt.start)); - opt.setValue.call(selfDom, dateRange, getDateString(new Date(opt.start)), getDateString(new Date(opt.end))); - - if (initiated) - { - $(self).trigger('datepicker-change', - { - 'value': dateRange, - 'date1' : new Date(opt.start) - }); - } - } - else if (opt.start && opt.end) - { - box.find('.selected-days').show().find('.selected-days-num').html(Math.round((opt.end-opt.start)/86400000)+1); - box.find('.apply-btn').removeClass('disabled'); - var dateRange = getDateString(new Date(opt.start))+ opt.separator +getDateString(new Date(opt.end)); - opt.setValue.call(selfDom,dateRange, getDateString(new Date(opt.start)), getDateString(new Date(opt.end))); - if (initiated) - { - $(self).trigger('datepicker-change', - { - 'value': dateRange, - 'date1' : new Date(opt.start), - 'date2' : new Date(opt.end) - }); - } - } - else - { - box.find('.apply-btn').addClass('disabled'); - } - } - - function setDateRange(date1,date2) - { - if (date1.getTime() > date2.getTime()) - { - var tmp = date2; - date2 = date1; - date1 = tmp; - tmp = null; - } - var valid = true; - if (opt.startDate && compare_day(date1,opt.startDate) < 0) valid = false; - if (opt.endDate && compare_day(date2,opt.endDate) > 0) valid = false; - if (!valid) - { - showMonth(opt.startDate,'month1'); - showMonth(nextMonth(opt.startDate),'month2'); - showGap(); - return; - } - - opt.start = date1.getTime(); - opt.end = date2.getTime(); - if (compare_day(date1,date2) > 0 && compare_month(date1,date2) == 0) - { - date2 = nextMonth(date1); - } - if (opt.time.enabled) { - renderTime("time1", date1); - renderTime("time2", date2); - } - showMonth(date1,'month1'); - showMonth(date2,'month2'); - showGap(); - showSelectedInfo(); - autoclose(); - } - - function setSingleDate(date1) - { - - var valid = true; - if (opt.startDate && compare_day(date1,opt.startDate) < 0) valid = false; - if (opt.endDate && compare_day(date1,opt.endDate) > 0) valid = false; - if (!valid) - { - showMonth(opt.startDate,'month1'); - - //showGap(); - return; - } - - opt.start = date1.getTime(); - - - if (opt.time.enabled) { - renderTime("time1", date1); - - } - showMonth(date1,'month1'); - //showMonth(date2,'month2'); - showGap(); - showSelectedInfo(); - autoclose(); - } - - function showSelectedDays() - { - if (!opt.start && !opt.end) return; - box.find('.day').each(function() - { - var time = parseInt($(this).attr('time')), - start = opt.start, - end = opt.end; - if (opt.time.enabled) { - time = moment(time).startOf('day').valueOf(); - start = moment(start || moment().valueOf()).startOf('day').valueOf(); - end = moment(end || moment().valueOf()).startOf('day').valueOf(); - } - if ( - (opt.start && opt.end && end >= time && start <= time ) - || ( opt.start && !opt.end && moment(start).format('YYYY-MM-DD') == moment(time).format('YYYY-MM-DD') ) - ) - { - $(this).addClass('checked'); - } - else - { - $(this).removeClass('checked'); - } - }); - } - - function showMonth(date,month) - { - date = moment(date).toDate(); - var monthName = nameMonth(date.getMonth()); - box.find('.'+month+' .month-name').html(monthName+' '+date.getFullYear()); - box.find('.'+month+' tbody').html(createMonthHTML(date)); - opt[month] = date; - } - - function showTime(date,name) - { - box.find('.' + name).append(getTimeHTML()); - renderTime(name, date); - } - - function nameMonth(m) - { - return lang('month-name')[m]; - } - - function getDateString(d) - { - return moment(d).format(opt.format); - } - - function showGap() - { - showSelectedDays(); - var m1 = parseInt(moment(opt.month1).format('YYYYMM')); - var m2 = parseInt(moment(opt.month2).format('YYYYMM')); - var p = Math.abs(m1 - m2); - var shouldShow = (p > 1 && p !=89); - if (shouldShow) - box.find('.gap').show(); - else - box.find('.gap').hide(); - } - - function closeDatePicker() - { - if (opt.alwaysOpen) return; - $(box).slideUp(opt.duration,function() - { - $(self).data('date-picker-opened',false); - }); - //$(document).unbind('.datepicker'); - $(self).trigger('datepicker-close'); - } - - function compare_month(m1,m2) - { - var p = parseInt(moment(m1).format('YYYYMM')) - parseInt(moment(m2).format('YYYYMM')); - if (p > 0 ) return 1; - if (p == 0) return 0; - return -1; - } - - function compare_day(m1,m2) - { - var p = parseInt(moment(m1).format('YYYYMMDD')) - parseInt(moment(m2).format('YYYYMMDD')); - if (p > 0 ) return 1; - if (p == 0) return 0; - return -1; - } - - function nextMonth(month) - { - month = moment(month).toDate(); - var toMonth = month.getMonth(); - while(month.getMonth() == toMonth) month = new Date(month.getTime()+86400000); - return month; - } - - function prevMonth(month) - { - month = moment(month).toDate(); - var toMonth = month.getMonth(); - while(month.getMonth() == toMonth) month = new Date(month.getTime()-86400000); - return month; - } - - function getTimeHTML() - { - var timeHtml = '
    ' - +'Time: 00:00' - +'
    ' - +'
    ' - +'' - +'
    ' - +'
    ' - +'' - +'
    '; - return timeHtml; - } - - function createDom() - { - var html = '
    ' - +'
    \ -
    \ - '+lang('selected')+' ...' - if ( ! opt.singleDate ) { - html += ' '+opt.separator+' ... (3 '+lang('days')+')' - } - html += '
    \ -
    error
    \ -
    default
    \ - \ -
    ' - +'
    ' - +''+getWeekHead()+'
    <January, 2011>
    ' - if ( ! opt.singleDate ) { - html += '
    '+getGapHTML()+'
    ' - +''+getWeekHead()+'
    <January, 2011>
    ' - } - //+'
    ' - html += '
    ' - +'
    ' - +'
    ' - if ( ! opt.singleDate ) { - html += '
    ' - } - html += '
    ' - +'
    ' - +'
    '; - - if (opt.showShortcuts) - { - html += ''; - } - html += '