.\n\n.list-group {\n // No need to set list-style: none; since .list-group-item is block level\n margin-bottom: 20px;\n padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -1px;\n background-color: @list-group-bg;\n border: 1px solid @list-group-border;\n\n // Round the first and last items\n &:first-child {\n .border-top-radius(@list-group-border-radius);\n }\n &:last-child {\n margin-bottom: 0;\n .border-bottom-radius(@list-group-border-radius);\n }\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item,\nbutton.list-group-item {\n color: @list-group-link-color;\n\n .list-group-item-heading {\n color: @list-group-link-heading-color;\n }\n\n // Hover state\n &:hover,\n &:focus {\n text-decoration: none;\n color: @list-group-link-hover-color;\n background-color: @list-group-hover-bg;\n }\n}\n\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n\n.list-group-item {\n // Disabled state\n &.disabled,\n &.disabled:hover,\n &.disabled:focus {\n background-color: @list-group-disabled-bg;\n color: @list-group-disabled-color;\n cursor: @cursor-disabled;\n\n // Force color to inherit for custom content\n .list-group-item-heading {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-disabled-text-color;\n }\n }\n\n // Active class on item itself, not parent\n &.active,\n &.active:hover,\n &.active:focus {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: @list-group-active-color;\n background-color: @list-group-active-bg;\n border-color: @list-group-active-border;\n\n // Force color to inherit for custom content\n .list-group-item-heading,\n .list-group-item-heading > small,\n .list-group-item-heading > .small {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-active-text-color;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n","// List Groups\n\n.list-group-item-variant(@state; @background; @color) {\n .list-group-item-@{state} {\n color: @color;\n background-color: @background;\n\n a&,\n button& {\n color: @color;\n\n .list-group-item-heading {\n color: inherit;\n }\n\n &:hover,\n &:focus {\n color: @color;\n background-color: darken(@background, 5%);\n }\n &.active,\n &.active:hover,\n &.active:focus {\n color: #fff;\n background-color: @color;\n border-color: @color;\n }\n }\n }\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n margin-bottom: @line-height-computed;\n background-color: @panel-bg;\n border: 1px solid transparent;\n border-radius: @panel-border-radius;\n .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n padding: @panel-body-padding;\n &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n padding: @panel-heading-padding;\n border-bottom: 1px solid transparent;\n .border-top-radius((@panel-border-radius - 1));\n\n > .dropdown .dropdown-toggle {\n color: inherit;\n }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: ceil((@font-size-base * 1.125));\n color: inherit;\n\n > a,\n > small,\n > .small,\n > small > a,\n > .small > a {\n color: inherit;\n }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n padding: @panel-footer-padding;\n background-color: @panel-footer-bg;\n border-top: 1px solid @panel-inner-border;\n .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n > .list-group,\n > .panel-collapse > .list-group {\n margin-bottom: 0;\n\n .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n }\n\n // Add border top radius for first one\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n .border-top-radius((@panel-border-radius - 1));\n }\n }\n\n // Add border bottom radius for last one\n &:last-child {\n .list-group-item:last-child {\n border-bottom: 0;\n .border-bottom-radius((@panel-border-radius - 1));\n }\n }\n }\n > .panel-heading + .panel-collapse > .list-group {\n .list-group-item:first-child {\n .border-top-radius(0);\n }\n }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n .list-group-item:first-child {\n border-top-width: 0;\n }\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n > .table,\n > .table-responsive > .table,\n > .panel-collapse > .table {\n margin-bottom: 0;\n\n caption {\n padding-left: @panel-body-padding;\n padding-right: @panel-body-padding;\n }\n }\n // Add border top radius for first one\n > .table:first-child,\n > .table-responsive:first-child > .table:first-child {\n .border-top-radius((@panel-border-radius - 1));\n\n > thead:first-child,\n > tbody:first-child {\n > tr:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n border-top-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-top-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n // Add border bottom radius for last one\n > .table:last-child,\n > .table-responsive:last-child > .table:last-child {\n .border-bottom-radius((@panel-border-radius - 1));\n\n > tbody:last-child,\n > tfoot:last-child {\n > tr:last-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n border-bottom-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-bottom-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n > .panel-body + .table,\n > .panel-body + .table-responsive,\n > .table + .panel-body,\n > .table-responsive + .panel-body {\n border-top: 1px solid @table-border-color;\n }\n > .table > tbody:first-child > tr:first-child th,\n > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n }\n > .table-bordered,\n > .table-responsive > .table-bordered {\n border: 0;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n > thead,\n > tbody {\n > tr:first-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n > tbody,\n > tfoot {\n > tr:last-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n }\n > .table-responsive {\n border: 0;\n margin-bottom: 0;\n }\n}\n\n\n// Collapsible panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n margin-bottom: @line-height-computed;\n\n // Tighten up margin so it's only between panels\n .panel {\n margin-bottom: 0;\n border-radius: @panel-border-radius;\n\n + .panel {\n margin-top: 5px;\n }\n }\n\n .panel-heading {\n border-bottom: 0;\n\n + .panel-collapse > .panel-body,\n + .panel-collapse > .list-group {\n border-top: 1px solid @panel-inner-border;\n }\n }\n\n .panel-footer {\n border-top: 0;\n + .panel-collapse .panel-body {\n border-bottom: 1px solid @panel-inner-border;\n }\n }\n}\n\n\n// Contextual variations\n.panel-default {\n .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","// Panels\n\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n border-color: @border;\n\n & > .panel-heading {\n color: @heading-text-color;\n background-color: @heading-bg-color;\n border-color: @heading-border;\n\n + .panel-collapse > .panel-body {\n border-top-color: @border;\n }\n .badge {\n color: @heading-bg-color;\n background-color: @heading-text-color;\n }\n }\n & > .panel-footer {\n + .panel-collapse > .panel-body {\n border-bottom-color: @border;\n }\n }\n}\n","// Embeds responsive\n//\n// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n }\n}\n\n// Modifier class for 16:9 aspect ratio\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n\n// Modifier class for 4:3 aspect ratio\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: @well-bg;\n border: 1px solid @well-border;\n border-radius: @border-radius-base;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n blockquote {\n border-color: #ddd;\n border-color: rgba(0,0,0,.15);\n }\n}\n\n// Sizes\n.well-lg {\n padding: 24px;\n border-radius: @border-radius-large;\n}\n.well-sm {\n padding: 9px;\n border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-size-base * 1.5);\n font-weight: @close-font-weight;\n line-height: 1;\n color: @close-color;\n text-shadow: @close-text-shadow;\n .opacity(.2);\n\n &:hover,\n &:focus {\n color: @close-color;\n text-decoration: none;\n cursor: pointer;\n .opacity(.5);\n }\n\n // Additional properties for button version\n // iOS requires the button element instead of an anchor tag.\n // If you want the anchor version, it requires `href=\"#\"`.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n button& {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal;\n -webkit-overflow-scrolling: touch;\n\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n\n // When fading in the modal, animate it to slide down\n &.fade .modal-dialog {\n .translate(0, -25%);\n .transition-transform(~\"0.3s ease-out\");\n }\n &.in .modal-dialog { .translate(0, 0) }\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n background-color: @modal-content-bg;\n border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n border: 1px solid @modal-content-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 3px 9px rgba(0,0,0,.5));\n background-clip: padding-box;\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal-background;\n background-color: @modal-backdrop-bg;\n // Fade for backdrop\n &.fade { .opacity(0); }\n &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n padding: @modal-title-padding;\n border-bottom: 1px solid @modal-header-border-color;\n &:extend(.clearfix all);\n}\n// Close icon\n.modal-header .close {\n margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n margin: 0;\n line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n padding: @modal-inner-padding;\n text-align: right; // right align buttons\n border-top: 1px solid @modal-footer-border-color;\n &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n // Properly space out buttons\n .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n }\n // but override that for button groups\n .btn-group .btn + .btn {\n margin-left: -1px;\n }\n // and override it for block buttons as well\n .btn-block + .btn-block {\n margin-left: 0;\n }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n width: @modal-md;\n margin: 30px auto;\n }\n .modal-content {\n .box-shadow(0 5px 15px rgba(0,0,0,.5));\n }\n\n // Modal sizes\n .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n position: absolute;\n z-index: @zindex-tooltip;\n display: block;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n .reset-text();\n font-size: @font-size-small;\n\n .opacity(0);\n\n &.in { .opacity(@tooltip-opacity); }\n &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }\n &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }\n &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }\n &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: @tooltip-max-width;\n padding: 3px 8px;\n color: @tooltip-color;\n text-align: center;\n background-color: @tooltip-bg;\n border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1\n.tooltip {\n &.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-left .tooltip-arrow {\n bottom: 0;\n right: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-right .tooltip-arrow {\n bottom: 0;\n left: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n border-right-color: @tooltip-arrow-color;\n }\n &.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-left-color: @tooltip-arrow-color;\n }\n &.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-left .tooltip-arrow {\n top: 0;\n right: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-right .tooltip-arrow {\n top: 0;\n left: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n}\n",".reset-text() {\n font-family: @font-family-base;\n // We deliberately do NOT reset font-size.\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: @line-height-base;\n text-align: left; // Fallback for where `start` is not supported\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: @zindex-popover;\n display: none;\n max-width: @popover-max-width;\n padding: 1px;\n // Our parent element can be arbitrary since popovers are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n .reset-text();\n font-size: @font-size-base;\n\n background-color: @popover-bg;\n background-clip: padding-box;\n border: 1px solid @popover-fallback-border-color;\n border: 1px solid @popover-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n // Offset the popover to account for the popover arrow\n &.top { margin-top: -@popover-arrow-width; }\n &.right { margin-left: @popover-arrow-width; }\n &.bottom { margin-top: @popover-arrow-width; }\n &.left { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n margin: 0; // reset heading margin\n padding: 8px 14px;\n font-size: @font-size-base;\n background-color: @popover-title-bg;\n border-bottom: 1px solid darken(@popover-title-bg, 5%);\n border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;\n}\n\n.popover-content {\n padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n &,\n &:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n }\n}\n.popover > .arrow {\n border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n border-width: @popover-arrow-width;\n content: \"\";\n}\n\n.popover {\n &.top > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-top-color: @popover-arrow-outer-color;\n bottom: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n bottom: 1px;\n margin-left: -@popover-arrow-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-color;\n }\n }\n &.right > .arrow {\n top: 50%;\n left: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-right-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n left: 1px;\n bottom: -@popover-arrow-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-color;\n }\n }\n &.bottom > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-bottom-color: @popover-arrow-outer-color;\n top: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n top: 1px;\n margin-left: -@popover-arrow-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-color;\n }\n }\n\n &.left > .arrow {\n top: 50%;\n right: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-right-width: 0;\n border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-left-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: @popover-arrow-color;\n bottom: -@popover-arrow-width;\n }\n }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n\n > .item {\n display: none;\n position: relative;\n .transition(.6s ease-in-out left);\n\n // Account for jankitude on images\n > img,\n > a > img {\n &:extend(.img-responsive);\n line-height: 1;\n }\n\n // WebKit CSS3 transforms for supported devices\n @media all and (transform-3d), (-webkit-transform-3d) {\n .transition-transform(~'0.6s ease-in-out');\n .backface-visibility(~'hidden');\n .perspective(1000px);\n\n &.next,\n &.active.right {\n .translate3d(100%, 0, 0);\n left: 0;\n }\n &.prev,\n &.active.left {\n .translate3d(-100%, 0, 0);\n left: 0;\n }\n &.next.left,\n &.prev.right,\n &.active {\n .translate3d(0, 0, 0);\n left: 0;\n }\n }\n }\n\n > .active,\n > .next,\n > .prev {\n display: block;\n }\n\n > .active {\n left: 0;\n }\n\n > .next,\n > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n }\n\n > .next {\n left: 100%;\n }\n > .prev {\n left: -100%;\n }\n > .next.left,\n > .prev.right {\n left: 0;\n }\n\n > .active.left {\n left: -100%;\n }\n > .active.right {\n left: 100%;\n }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: @carousel-control-width;\n .opacity(@carousel-control-opacity);\n font-size: @carousel-control-font-size;\n color: @carousel-control-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n background-color: rgba(0, 0, 0, 0); // Fix IE9 click-thru bug\n // We can't have this transition here because WebKit cancels the carousel\n // animation if you trip this while in the middle of another animation.\n\n // Set gradients for backgrounds\n &.left {\n #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n }\n &.right {\n left: auto;\n right: 0;\n #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n }\n\n // Hover/focus state\n &:hover,\n &:focus {\n outline: 0;\n color: @carousel-control-color;\n text-decoration: none;\n .opacity(.9);\n }\n\n // Toggles\n .icon-prev,\n .icon-next,\n .glyphicon-chevron-left,\n .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n }\n .icon-prev,\n .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n }\n .icon-next,\n .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n }\n .icon-prev,\n .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n }\n\n\n .icon-prev {\n &:before {\n content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n }\n }\n .icon-next {\n &:before {\n content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n }\n }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n\n li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid @carousel-indicator-border-color;\n border-radius: 10px;\n cursor: pointer;\n\n // IE8-9 hack for event handling\n //\n // Internet Explorer 8-9 does not support clicks on elements without a set\n // `background-color`. We cannot use `filter` since that's not viewed as a\n // background color by the browser. Thus, a hack is needed.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer\n //\n // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n // set alpha transparency for the best results possible.\n background-color: #000 \\9; // IE8\n background-color: rgba(0,0,0,0); // IE9\n }\n .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: @carousel-indicator-active-bg;\n }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: @carousel-caption-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n & .btn {\n text-shadow: none; // No shadow for button elements in carousel-caption\n }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n // Scale up the controls a smidge\n .carousel-control {\n .glyphicon-chevron-left,\n .glyphicon-chevron-right,\n .icon-prev,\n .icon-next {\n width: (@carousel-control-font-size * 1.5);\n height: (@carousel-control-font-size * 1.5);\n margin-top: (@carousel-control-font-size / -2);\n font-size: (@carousel-control-font-size * 1.5);\n }\n .glyphicon-chevron-left,\n .icon-prev {\n margin-left: (@carousel-control-font-size / -2);\n }\n .glyphicon-chevron-right,\n .icon-next {\n margin-right: (@carousel-control-font-size / -2);\n }\n }\n\n // Show and left align the captions\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n\n // Move up the indicators\n .carousel-indicators {\n bottom: 20px;\n }\n}\n","// Clearfix\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n// contenteditable attribute is included anywhere else in the document.\n// Otherwise it causes space to appear at the top and bottom of elements\n// that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n// `:before` to contain the top-margins of child elements.\n//\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n\n.clearfix() {\n &:before,\n &:after {\n content: \" \"; // 1\n display: table; // 2\n }\n &:after {\n clear: both;\n }\n}\n","// Center-align a block level element\n\n.center-block() {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n","// CSS image replacement\n//\n// Heads up! v3 launched with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (has been removed in v4)\n.hide-text() {\n font: ~\"0/0\" a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n// New mixin to use as of v3.0.1\n.text-hide() {\n .hide-text();\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#support-ie10-width\n// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n width: device-width;\n}\n\n\n// Visibility utilities\n// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n .responsive-invisibility();\n}\n\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n\n.visible-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-visibility();\n }\n}\n.visible-xs-block {\n @media (max-width: @screen-xs-max) {\n display: block !important;\n }\n}\n.visible-xs-inline {\n @media (max-width: @screen-xs-max) {\n display: inline !important;\n }\n}\n.visible-xs-inline-block {\n @media (max-width: @screen-xs-max) {\n display: inline-block !important;\n }\n}\n\n.visible-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-visibility();\n }\n}\n.visible-sm-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: block !important;\n }\n}\n.visible-sm-inline {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline !important;\n }\n}\n.visible-sm-inline-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline-block !important;\n }\n}\n\n.visible-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-visibility();\n }\n}\n.visible-md-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: block !important;\n }\n}\n.visible-md-inline {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline !important;\n }\n}\n.visible-md-inline-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline-block !important;\n }\n}\n\n.visible-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-visibility();\n }\n}\n.visible-lg-block {\n @media (min-width: @screen-lg-min) {\n display: block !important;\n }\n}\n.visible-lg-inline {\n @media (min-width: @screen-lg-min) {\n display: inline !important;\n }\n}\n.visible-lg-inline-block {\n @media (min-width: @screen-lg-min) {\n display: inline-block !important;\n }\n}\n\n.hidden-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-invisibility();\n }\n}\n.hidden-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-invisibility();\n }\n}\n.hidden-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-invisibility();\n }\n}\n.hidden-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-invisibility();\n }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n// Note: Deprecated .visible-print as of v3.2.0\n.visible-print {\n .responsive-invisibility();\n\n @media print {\n .responsive-visibility();\n }\n}\n.visible-print-block {\n display: none !important;\n\n @media print {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n\n @media print {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n\n @media print {\n display: inline-block !important;\n }\n}\n\n.hidden-print {\n @media print {\n .responsive-invisibility();\n }\n}\n","// Responsive utilities\n\n//\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n display: block !important;\n table& { display: table !important; }\n tr& { display: table-row !important; }\n th&,\n td& { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n display: none !important;\n}\n"]}
\ No newline at end of file
diff --git a/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map
new file mode 100644
index 0000000..6c7fa40
--- /dev/null
+++ b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map
@@ -0,0 +1 @@
+{"version":3,"sources":["less/normalize.less","less/print.less","bootstrap.css","dist/css/bootstrap.css","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/mixins/reset-text.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":";;;;4EAQA,KACE,YAAA,WACA,yBAAA,KACA,qBAAA,KAOF,KACE,OAAA,EAaF,QAAA,MAAA,QAAA,WAAA,OAAA,OAAA,OAAA,OAAA,KAAA,KAAA,IAAA,QAAA,QAaE,QAAA,MAQF,MAAA,OAAA,SAAA,MAIE,QAAA,aACA,eAAA,SAQF,sBACE,QAAA,KACA,OAAA,EAQF,SAAA,SAEE,QAAA,KAUF,EACE,iBAAA,YAQF,SAAA,QAEE,QAAA,EAUF,YACE,cAAA,IAAA,OAOF,EAAA,OAEE,YAAA,IAOF,IACE,WAAA,OAQF,GACE,OAAA,MAAA,EACA,UAAA,IAOF,KACE,MAAA,KACA,WAAA,KAOF,MACE,UAAA,IAOF,IAAA,IAEE,SAAA,SACA,UAAA,IACA,YAAA,EACA,eAAA,SAGF,IACE,IAAA,MAGF,IACE,OAAA,OAUF,IACE,OAAA,EAOF,eACE,SAAA,OAUF,OACE,OAAA,IAAA,KAOF,GACE,OAAA,EAAA,mBAAA,YAAA,gBAAA,YACA,WAAA,YAOF,IACE,SAAA,KAOF,KAAA,IAAA,IAAA,KAIE,YAAA,UAAA,UACA,UAAA,IAkBF,OAAA,MAAA,SAAA,OAAA,SAKE,OAAA,EACA,KAAA,QACA,MAAA,QAOF,OACE,SAAA,QAUF,OAAA,OAEE,eAAA,KAWF,OAAA,wBAAA,kBAAA,mBAIE,mBAAA,OACA,OAAA,QAOF,iBAAA,qBAEE,OAAA,QAOF,yBAAA,wBAEE,QAAA,EACA,OAAA,EAQF,MACE,YAAA,OAWF,qBAAA,kBAEE,mBAAA,WAAA,gBAAA,WAAA,WAAA,WACA,QAAA,EASF,8CAAA,8CAEE,OAAA,KAQF,mBACE,mBAAA,YACA,gBAAA,YAAA,WAAA,YAAA,mBAAA,UASF,iDAAA,8CAEE,mBAAA,KAOF,SACE,QAAA,MAAA,OAAA,MACA,OAAA,EAAA,IACA,OAAA,IAAA,MAAA,OAQF,OACE,QAAA,EACA,OAAA,EAOF,SACE,SAAA,KAQF,SACE,YAAA,IAUF,MACE,eAAA,EACA,gBAAA,SAGF,GAAA,GAEE,QAAA,uFCjUF,aA7FI,EAAA,OAAA,QAGI,MAAA,eACA,YAAA,eACA,WAAA,cAAA,mBAAA,eACA,WAAA,eAGJ,EAAA,UAEI,gBAAA,UAGJ,cACI,QAAA,KAAA,WAAA,IAGJ,kBACI,QAAA,KAAA,YAAA,IAKJ,6BAAA,mBAEI,QAAA,GAGJ,WAAA,IAEI,OAAA,IAAA,MAAA,KC4KL,kBAAA,MDvKK,MC0KL,QAAA,mBDrKK,IE8KN,GDLC,kBAAA,MDrKK,ICwKL,UAAA,eCUD,GF5KM,GE2KN,EF1KM,QAAA,ECuKL,OAAA,ECSD,GF3KM,GCsKL,iBAAA,MD/JK,QCkKL,QAAA,KCSD,YFtKU,oBCiKT,iBAAA,eD7JK,OCgKL,OAAA,IAAA,MAAA,KD5JK,OC+JL,gBAAA,mBCSD,UFpKU,UC+JT,iBAAA,eDzJS,mBEkKV,mBDLC,OAAA,IAAA,MAAA,gBEjPD,WACA,YAAA,uBFsPD,IAAA,+CE7OC,IAAK,sDAAuD,4BAA6B,iDAAkD,gBAAiB,gDAAiD,eAAgB,+CAAgD,mBAAoB,2EAA4E,cAE7W,WACA,SAAA,SACA,IAAA,IACA,QAAA,aACA,YAAA,uBACA,WAAA,OACA,YAAA,IACA,YAAA,EAIkC,uBAAA,YAAW,wBAAA,UACX,2BAAW,QAAA,QAEX,uBDuPlC,QAAS,QCtPyB,sBFiPnC,uBEjP8C,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,2BAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,6BAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,2BAAW,QAAA,QACX,qBAAW,QAAA,QACX,0BAAW,QAAA,QACX,qBAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,2BAAW,QAAA,QACX,sBAAW,QAAA,QACX,yBAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,+BAAW,QAAA,QACX,2BAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,8BAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,6BAAW,QAAA,QACX,6BAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,sBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,2BAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,yBAAW,QAAA,QACX,8BAAW,QAAA,QACX,6BAAW,QAAA,QACX,6BAAW,QAAA,QACX,+BAAW,QAAA,QACX,8BAAW,QAAA,QACX,gCAAW,QAAA,QACX,uBAAW,QAAA,QACX,8BAAW,QAAA,QACX,+BAAW,QAAA,QACX,iCAAW,QAAA,QACX,0BAAW,QAAA,QACX,6BAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,gCAAW,QAAA,QACX,gCAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,0BAAW,QAAA,QACX,+BAAW,QAAA,QACX,+BAAW,QAAA,QACX,wBAAW,QAAA,QACX,+BAAW,QAAA,QACX,gCAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,8BAAW,QAAA,QACX,0BAAW,QAAA,QACX,gCAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,gCAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,6BAAW,QAAA,QACX,8BAAW,QAAA,QACX,2BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,8BAAW,QAAA,QACX,+BAAW,QAAA,QACX,mCAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,2BAAW,QAAA,QACX,4BAAW,QAAA,QACX,+BAAW,QAAA,QACX,wBAAW,QAAA,QACX,2BAAW,QAAA,QACX,yBAAW,QAAA,QACX,0BAAW,QAAA,QACX,yBAAW,QAAA,QACX,6BAAW,QAAA,QACX,+BAAW,QAAA,QACX,0BAAW,QAAA,QACX,gCAAW,QAAA,QACX,+BAAW,QAAA,QACX,8BAAW,QAAA,QACX,kCAAW,QAAA,QACX,oCAAW,QAAA,QACX,sBAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,8BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,0BAAW,QAAA,QACX,4BAAW,QAAA,QACX,qCAAW,QAAA,QACX,oCAAW,QAAA,QACX,kCAAW,QAAA,QACX,oCAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,8BAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,0BAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,uBAAW,QAAA,QACX,mCAAW,QAAA,QACX,uCAAW,QAAA,QACX,gCAAW,QAAA,QACX,oCAAW,QAAA,QACX,qCAAW,QAAA,QACX,yCAAW,QAAA,QACX,4BAAW,QAAA,QACX,yBAAW,QAAA,QACX,gCAAW,QAAA,QACX,8BAAW,QAAA,QACX,yBAAW,QAAA,QACX,wBAAW,QAAA,QACX,0BAAW,QAAA,QACX,6BAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,yBAAW,QAAA,QACX,yBAAW,QAAA,QACX,uBAAW,QAAA,QACX,8BAAW,QAAA,QACX,+BAAW,QAAA,QACX,gCAAW,QAAA,QACX,8BAAW,QAAA,QACX,8BAAW,QAAA,QACX,8BAAW,QAAA,QACX,2BAAW,QAAA,QACX,0BAAW,QAAA,QACX,yBAAW,QAAA,QACX,6BAAW,QAAA,QACX,2BAAW,QAAA,QACX,4BAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,2BAAW,QAAA,QACX,2BAAW,QAAA,QACX,4BAAW,QAAA,QACX,+BAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,iCAAW,QAAA,QACX,oCAAW,QAAA,QACX,iCAAW,QAAA,QACX,+BAAW,QAAA,QACX,+BAAW,QAAA,QACX,iCAAW,QAAA,QACX,qBAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,2BAAW,QAAA,QACX,uBAAW,QAAA,QASX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,4BAAW,QAAA,QACX,uBAAW,QAAA,QACX,wBAAW,QAAA,QACX,uBAAW,QAAA,QACX,yBAAW,QAAA,QACX,yBAAW,QAAA,QACX,+BAAW,QAAA,QACX,uBAAW,QAAA,QACX,6BAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,wBAAW,QAAA,QACX,4BAAW,QAAA,QACX,uBAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,2BAAW,QAAA,QACX,0BAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,4BAAW,QAAA,QACX,mCAAW,QAAA,QACX,4BAAW,QAAA,QACX,oCAAW,QAAA,QACX,kCAAW,QAAA,QACX,iCAAW,QAAA,QACX,+BAAW,QAAA,QACX,sBAAW,QAAA,QACX,wBAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,kCAAW,QAAA,QACX,mCAAW,QAAA,QACX,sCAAW,QAAA,QACX,0CAAW,QAAA,QACX,oCAAW,QAAA,QACX,wCAAW,QAAA,QACX,qCAAW,QAAA,QACX,iCAAW,QAAA,QACX,gCAAW,QAAA,QACX,kCAAW,QAAA,QACX,+BAAW,QAAA,QACX,0BAAW,QAAA,QACX,8BAAW,QAAA,QACX,4BAAW,QAAA,QACX,4BAAW,QAAA,QACX,6BAAW,QAAA,QACX,4BAAW,QAAA,QCtS/C,0BCgEE,QAAA,QHi+BF,EDNC,mBAAA,WGxhCI,gBAAiB,WFiiCZ,WAAY,WGl+BZ,OADL,QJg+BJ,mBAAA,WGthCI,gBAAiB,WACpB,WAAA,WHyhCD,KGrhCC,UAAW,KAEX,4BAAA,cAEA,KACA,YAAA,iBAAA,UAAA,MAAA,WHuhCD,UAAA,KGnhCC,YAAa,WF4hCb,MAAO,KACP,iBAAkB,KExhClB,OADA,MAEA,OHqhCD,SG/gCC,YAAa,QACb,UAAA,QACA,YAAA,QAEA,EFwhCA,MAAO,QEthCL,gBAAA,KAIF,QH8gCD,QKjkCC,MAAA,QACA,gBAAA,UF6DF,QACE,QAAA,IAAA,KAAA,yBHygCD,eAAA,KGlgCC,OHqgCD,OAAA,ECSD,IACE,eAAgB,ODDjB,4BM/kCC,0BLklCF,gBKnlCE,iBADA,eH4EA,QAAS,MACT,UAAA,KHugCD,OAAA,KGhgCC,aACA,cAAA,IAEA,eACA,QAAA,aC6FA,UAAA,KACK,OAAA,KACG,QAAA,IEvLR,YAAA,WACA,iBAAA,KACA,OAAA,IAAA,MAAA,KN+lCD,cAAA,IGjgCC,mBAAoB,IAAI,IAAI,YAC5B,cAAA,IAAA,IAAA,YHmgCD,WAAA,IAAA,IAAA,YG5/BC,YACA,cAAA,IAEA,GH+/BD,WAAA,KGv/BC,cAAe,KACf,OAAA,EACA,WAAA,IAAA,MAAA,KAEA,SACA,SAAA,SACA,MAAA,IACA,OAAA,IACA,QAAA,EHy/BD,OAAA,KGj/BC,SAAA,OF0/BA,KAAM,cEx/BJ,OAAA,EAEA,0BACA,yBACA,SAAA,OACA,MAAA,KHm/BH,OAAA,KGx+BC,OAAQ,EACR,SAAA,QH0+BD,KAAA,KCSD,cACE,OAAQ,QAQV,IACA,IMlpCE,IACA,IACA,IACA,INwoCF,GACA,GACA,GACA,GACA,GACA,GDAC,YAAA,QOlpCC,YAAa,IN2pCb,YAAa,IACb,MAAO,QAoBT,WAZA,UAaA,WAZA,UM5pCI,WN6pCJ,UM5pCI,WN6pCJ,UM5pCI,WN6pCJ,UDMC,WCLD,UACA,UAZA,SAaA,UAZA,SAaA,UAZA,SAaA,UAZA,SAaA,UAZA,SAaA,UAZA,SMppCE,YAAa,INwqCb,YAAa,EACb,MAAO,KAGT,IMxqCE,IAJF,IN2qCA,GAEA,GDLC,GCSC,WAAY,KACZ,cAAe,KASjB,WANA,UDCC,WCCD,UM5qCA,WN8qCA,UACA,UANA,SM5qCI,UN8qCJ,SM3qCA,UN6qCA,SAQE,UAAW,IAGb,IMprCE,IAJF,INurCA,GAEA,GDLC,GCSC,WAAY,KACZ,cAAe,KASjB,WANA,UDCC,WCCD,UMvrCA,WNyrCA,UACA,UANA,SMxrCI,UN0rCJ,SMtrCA,UNwrCA,SMxrCU,UAAA,IACV,IAAA,GAAU,UAAA,KACV,IAAA,GAAU,UAAA,KACV,IAAA,GAAU,UAAA,KACV,IAAA,GAAU,UAAA,KACV,IAAA,GAAU,UAAA,KAOR,IADF,GPssCC,UAAA,KCSD,EMzsCE,OAAA,EAAA,EAAA,KAEA,MPosCD,cAAA,KO/rCC,UAAW,KAwOX,YAAa,IA1OX,YAAA,IPssCH,yBO7rCC,MNssCE,UAAW,MMjsCf,OAAA,MAEE,UAAA,IAKF,MP0rCC,KO1rCsB,QAAA,KP6rCtB,iBAAA,QO5rCsB,WP+rCtB,WAAA,KO9rCsB,YPisCtB,WAAA,MOhsCsB,aPmsCtB,WAAA,OOlsCsB,cPqsCtB,WAAA,QOlsCsB,aPqsCtB,YAAA,OOpsCsB,gBPusCtB,eAAA,UOtsCsB,gBPysCtB,eAAA,UOrsCC,iBPwsCD,eAAA,WQ3yCC,YR8yCD,MAAA,KCSD,cOpzCI,MAAA,QAHF,qBDwGF,qBP6sCC,MAAA,QCSD,cO3zCI,MAAA,QAHF,qBD2GF,qBPitCC,MAAA,QCSD,WOl0CI,MAAA,QAHF,kBD8GF,kBPqtCC,MAAA,QCSD,cOz0CI,MAAA,QAHF,qBDiHF,qBPytCC,MAAA,QCSD,aOh1CI,MAAA,QDwHF,oBAHF,oBExHE,MAAA,QACA,YR01CA,MAAO,KQx1CL,iBAAA,QAHF,mBF8HF,mBP2tCC,iBAAA,QCSD,YQ/1CI,iBAAA,QAHF,mBFiIF,mBP+tCC,iBAAA,QCSD,SQt2CI,iBAAA,QAHF,gBFoIF,gBPmuCC,iBAAA,QCSD,YQ72CI,iBAAA,QAHF,mBFuIF,mBPuuCC,iBAAA,QCSD,WQp3CI,iBAAA,QF6IF,kBADF,kBAEE,iBAAA,QPsuCD,aO7tCC,eAAgB,INsuChB,OAAQ,KAAK,EAAE,KMpuCf,cAAA,IAAA,MAAA,KAFF,GPkuCC,GCSC,WAAY,EACZ,cAAe,KM9tCf,MP0tCD,MO3tCD,MAPI,MASF,cAAA,EAIF,eALE,aAAA,EACA,WAAA,KPkuCD,aO9tCC,aAAc,EAKZ,YAAA,KACA,WAAA,KP6tCH,gBOvtCC,QAAS,aACT,cAAA,IACA,aAAA,IAEF,GNguCE,WAAY,EM9tCZ,cAAA,KAGA,GADF,GP0tCC,YAAA,WOttCC,GPytCD,YAAA,IOnnCD,GAvFM,YAAA,EAEA,yBACA,kBGtNJ,MAAA,KACA,MAAA,MACA,SAAA,OVq6CC,MAAA,KO7nCC,WAAY,MAhFV,cAAA,SPgtCH,YAAA,OOtsCD,kBNgtCE,YAAa,OM1sCjB,0BPssCC,YOrsCC,OAAA,KA9IqB,cAAA,IAAA,OAAA,KAmJvB,YACE,UAAA,IACA,eAAA,UAEA,WPssCD,QAAA,KAAA,KOjsCG,OAAA,EAAA,EAAA,KN0sCF,UAAW,OACX,YAAa,IAAI,MAAM,KMptCzB,yBP+sCC,wBO/sCD,yBNytCE,cAAe,EMnsCb,kBAFA,kBACA,iBPksCH,QAAA,MO/rCG,UAAA,INwsCF,YAAa,WACb,MAAO,KMhsCT,yBP2rCC,yBO3rCD,wBAEE,QAAA,cAEA,oBACA,sBACA,cAAA,KP6rCD,aAAA,EOvrCG,WAAA,MNgsCF,aAAc,IAAI,MAAM,KACxB,YAAa,EMhsCX,kCNksCJ,kCMnsCe,iCACX,oCNmsCJ,oCDLC,mCCUC,QAAS,GMjsCX,iCNmsCA,iCMzsCM,gCAOJ,mCNmsCF,mCDLC,kCO7rCC,QAAA,cPksCD,QWv+CC,cAAe,KVg/Cf,WAAY,OACZ,YAAa,WU7+Cb,KXy+CD,IWr+CD,IACE,KACA,YAAA,MAAA,OAAA,SAAA,cAAA,UAEA,KACA,QAAA,IAAA,IXu+CD,UAAA,IWn+CC,MAAO,QACP,iBAAA,QACA,cAAA,IAEA,IACA,QAAA,IAAA,IACA,UAAA,IV4+CA,MU5+CA,KXq+CD,iBAAA,KW3+CC,cAAe,IASb,mBAAA,MAAA,EAAA,KAAA,EAAA,gBACA,WAAA,MAAA,EAAA,KAAA,EAAA,gBAEA,QV6+CF,QU7+CE,EXq+CH,UAAA,KWh+CC,YAAa,IACb,mBAAA,KACA,WAAA,KAEA,IACA,QAAA,MACA,QAAA,MACA,OAAA,EAAA,EAAA,KACA,UAAA,KACA,YAAA,WACA,MAAA,KACA,WAAA,UXk+CD,UAAA,WW7+CC,iBAAkB,QAehB,OAAA,IAAA,MAAA,KACA,cAAA,IAEA,SACA,QAAA,EACA,UAAA,QXi+CH,MAAA,QW59CC,YAAa,SACb,iBAAA,YACA,cAAA,EC1DF,gBCHE,WAAA,MACA,WAAA,OAEA,Wb8hDD,cAAA,KYxhDC,aAAA,KAqEA,aAAc,KAvEZ,YAAA,KZ+hDH,yBY1hDC,WAkEE,MAAO,OZ69CV,yBY5hDC,WA+DE,MAAO,OZk+CV,0BYzhDC,WCvBA,MAAA,QAGA,iBbmjDD,cAAA,KYthDC,aAAc,KCvBd,aAAA,KACA,YAAA,KCAE,KACE,aAAA,MAEA,YAAA,MAGA,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UdgjDL,SAAA,SchiDG,WAAA,IACE,cAAA,KdkiDL,aAAA,Kc1hDG,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Ud6hDH,MAAA,Kc7hDG,WdgiDH,MAAA,KchiDG,WdmiDH,MAAA,acniDG,WdsiDH,MAAA,actiDG,UdyiDH,MAAA,IcziDG,Ud4iDH,MAAA,ac5iDG,Ud+iDH,MAAA,ac/iDG,UdkjDH,MAAA,IcljDG,UdqjDH,MAAA,acrjDG,UdwjDH,MAAA,acxjDG,Ud2jDH,MAAA,Ic3jDG,Ud8jDH,MAAA,ac/iDG,UdkjDH,MAAA,YcljDG,gBdqjDH,MAAA,KcrjDG,gBdwjDH,MAAA,acxjDG,gBd2jDH,MAAA,ac3jDG,ed8jDH,MAAA,Ic9jDG,edikDH,MAAA,acjkDG,edokDH,MAAA,acpkDG,edukDH,MAAA,IcvkDG,ed0kDH,MAAA,ac1kDG,ed6kDH,MAAA,ac7kDG,edglDH,MAAA,IchlDG,edmlDH,MAAA,ac9kDG,edilDH,MAAA,YchmDG,edmmDH,MAAA,KcnmDG,gBdsmDH,KAAA,KctmDG,gBdymDH,KAAA,aczmDG,gBd4mDH,KAAA,ac5mDG,ed+mDH,KAAA,Ic/mDG,edknDH,KAAA,aclnDG,edqnDH,KAAA,acrnDG,edwnDH,KAAA,IcxnDG,ed2nDH,KAAA,ac3nDG,ed8nDH,KAAA,ac9nDG,edioDH,KAAA,IcjoDG,edooDH,KAAA,ac/nDG,edkoDH,KAAA,YcnnDG,edsnDH,KAAA,KctnDG,kBdynDH,YAAA,KcznDG,kBd4nDH,YAAA,ac5nDG,kBd+nDH,YAAA,ac/nDG,iBdkoDH,YAAA,IcloDG,iBdqoDH,YAAA,acroDG,iBdwoDH,YAAA,acxoDG,iBd2oDH,YAAA,Ic3oDG,iBd8oDH,YAAA,ac9oDG,iBdipDH,YAAA,acjpDG,iBdopDH,YAAA,IcppDG,iBdupDH,YAAA,acvpDG,iBd0pDH,YAAA,Yc5rDG,iBACE,YAAA,EAOJ,yBACE,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Ud0rDD,MAAA,Kc1rDC,Wd6rDD,MAAA,Kc7rDC,WdgsDD,MAAA,achsDC,WdmsDD,MAAA,acnsDC,UdssDD,MAAA,IctsDC,UdysDD,MAAA,aczsDC,Ud4sDD,MAAA,ac5sDC,Ud+sDD,MAAA,Ic/sDC,UdktDD,MAAA,acltDC,UdqtDD,MAAA,acrtDC,UdwtDD,MAAA,IcxtDC,Ud2tDD,MAAA,ac5sDC,Ud+sDD,MAAA,Yc/sDC,gBdktDD,MAAA,KcltDC,gBdqtDD,MAAA,acrtDC,gBdwtDD,MAAA,acxtDC,ed2tDD,MAAA,Ic3tDC,ed8tDD,MAAA,ac9tDC,ediuDD,MAAA,acjuDC,edouDD,MAAA,IcpuDC,eduuDD,MAAA,acvuDC,ed0uDD,MAAA,ac1uDC,ed6uDD,MAAA,Ic7uDC,edgvDD,MAAA,ac3uDC,ed8uDD,MAAA,Yc7vDC,edgwDD,MAAA,KchwDC,gBdmwDD,KAAA,KcnwDC,gBdswDD,KAAA,actwDC,gBdywDD,KAAA,aczwDC,ed4wDD,KAAA,Ic5wDC,ed+wDD,KAAA,ac/wDC,edkxDD,KAAA,aclxDC,edqxDD,KAAA,IcrxDC,edwxDD,KAAA,acxxDC,ed2xDD,KAAA,ac3xDC,ed8xDD,KAAA,Ic9xDC,ediyDD,KAAA,ac5xDC,ed+xDD,KAAA,YchxDC,edmxDD,KAAA,KcnxDC,kBdsxDD,YAAA,KctxDC,kBdyxDD,YAAA,aczxDC,kBd4xDD,YAAA,ac5xDC,iBd+xDD,YAAA,Ic/xDC,iBdkyDD,YAAA,aclyDC,iBdqyDD,YAAA,acryDC,iBdwyDD,YAAA,IcxyDC,iBd2yDD,YAAA,ac3yDC,iBd8yDD,YAAA,ac9yDC,iBdizDD,YAAA,IcjzDC,iBdozDD,YAAA,acpzDC,iBduzDD,YAAA,YY9yDD,iBE3CE,YAAA,GAQF,yBACE,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Udw1DD,MAAA,Kcx1DC,Wd21DD,MAAA,Kc31DC,Wd81DD,MAAA,ac91DC,Wdi2DD,MAAA,acj2DC,Udo2DD,MAAA,Icp2DC,Udu2DD,MAAA,acv2DC,Ud02DD,MAAA,ac12DC,Ud62DD,MAAA,Ic72DC,Udg3DD,MAAA,ach3DC,Udm3DD,MAAA,acn3DC,Uds3DD,MAAA,Ict3DC,Udy3DD,MAAA,ac12DC,Ud62DD,MAAA,Yc72DC,gBdg3DD,MAAA,Kch3DC,gBdm3DD,MAAA,acn3DC,gBds3DD,MAAA,act3DC,edy3DD,MAAA,Icz3DC,ed43DD,MAAA,ac53DC,ed+3DD,MAAA,ac/3DC,edk4DD,MAAA,Icl4DC,edq4DD,MAAA,acr4DC,edw4DD,MAAA,acx4DC,ed24DD,MAAA,Ic34DC,ed84DD,MAAA,acz4DC,ed44DD,MAAA,Yc35DC,ed85DD,MAAA,Kc95DC,gBdi6DD,KAAA,Kcj6DC,gBdo6DD,KAAA,acp6DC,gBdu6DD,KAAA,acv6DC,ed06DD,KAAA,Ic16DC,ed66DD,KAAA,ac76DC,edg7DD,KAAA,ach7DC,edm7DD,KAAA,Icn7DC,eds7DD,KAAA,act7DC,edy7DD,KAAA,acz7DC,ed47DD,KAAA,Ic57DC,ed+7DD,KAAA,ac17DC,ed67DD,KAAA,Yc96DC,edi7DD,KAAA,Kcj7DC,kBdo7DD,YAAA,Kcp7DC,kBdu7DD,YAAA,acv7DC,kBd07DD,YAAA,ac17DC,iBd67DD,YAAA,Ic77DC,iBdg8DD,YAAA,ach8DC,iBdm8DD,YAAA,acn8DC,iBds8DD,YAAA,Ict8DC,iBdy8DD,YAAA,acz8DC,iBd48DD,YAAA,ac58DC,iBd+8DD,YAAA,Ic/8DC,iBdk9DD,YAAA,acl9DC,iBdq9DD,YAAA,YYz8DD,iBE9CE,YAAA,GAQF,0BACE,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Uds/DD,MAAA,Kct/DC,Wdy/DD,MAAA,Kcz/DC,Wd4/DD,MAAA,ac5/DC,Wd+/DD,MAAA,ac//DC,UdkgED,MAAA,IclgEC,UdqgED,MAAA,acrgEC,UdwgED,MAAA,acxgEC,Ud2gED,MAAA,Ic3gEC,Ud8gED,MAAA,ac9gEC,UdihED,MAAA,acjhEC,UdohED,MAAA,IcphEC,UduhED,MAAA,acxgEC,Ud2gED,MAAA,Yc3gEC,gBd8gED,MAAA,Kc9gEC,gBdihED,MAAA,acjhEC,gBdohED,MAAA,acphEC,eduhED,MAAA,IcvhEC,ed0hED,MAAA,ac1hEC,ed6hED,MAAA,ac7hEC,edgiED,MAAA,IchiEC,edmiED,MAAA,acniEC,edsiED,MAAA,actiEC,edyiED,MAAA,IcziEC,ed4iED,MAAA,acviEC,ed0iED,MAAA,YczjEC,ed4jED,MAAA,Kc5jEC,gBd+jED,KAAA,Kc/jEC,gBdkkED,KAAA,aclkEC,gBdqkED,KAAA,acrkEC,edwkED,KAAA,IcxkEC,ed2kED,KAAA,ac3kEC,ed8kED,KAAA,ac9kEC,edilED,KAAA,IcjlEC,edolED,KAAA,acplEC,edulED,KAAA,acvlEC,ed0lED,KAAA,Ic1lEC,ed6lED,KAAA,acxlEC,ed2lED,KAAA,Yc5kEC,ed+kED,KAAA,Kc/kEC,kBdklED,YAAA,KcllEC,kBdqlED,YAAA,acrlEC,kBdwlED,YAAA,acxlEC,iBd2lED,YAAA,Ic3lEC,iBd8lED,YAAA,ac9lEC,iBdimED,YAAA,acjmEC,iBdomED,YAAA,IcpmEC,iBdumED,YAAA,acvmEC,iBd0mED,YAAA,ac1mEC,iBd6mED,YAAA,Ic7mEC,iBdgnED,YAAA,achnEC,iBdmnED,YAAA,YetrED,iBACA,YAAA,GAGA,MACA,iBAAA,YAEA,QfyrED,YAAA,IevrEC,eAAgB,IAChB,MAAA,KfyrED,WAAA,KelrEC,GACA,WAAA,KfsrED,OexrEC,MAAO,KdmsEP,UAAW,KACX,cAAe,KcvrET,mBd0rER,mBczrEQ,mBAHA,mBACA,mBd0rER,mBDHC,QAAA,IensEC,YAAa,WAoBX,eAAA,IACA,WAAA,IAAA,MAAA,KArBJ,mBdktEE,eAAgB,OAChB,cAAe,IAAI,MAAM,KDJ1B,uCCMD,uCcrtEA,wCdstEA,wCclrEI,2CANI,2CforEP,WAAA,EezqEG,mBf4qEH,WAAA,IAAA,MAAA,KCWD,cACE,iBAAkB,Kc/pEpB,6BdkqEA,6BcjqEE,6BAZM,6BfsqEP,6BCMD,6BDHC,QAAA,ICWD,gBACE,OAAQ,IAAI,MAAM,Kc1qEpB,4Bd6qEA,4Bc7qEA,4BAQQ,4Bf8pEP,4BCMD,4Bc7pEM,OAAA,IAAA,MAAA,KAYF,4BAFJ,4BfopEC,oBAAA,IevoEG,yCf0oEH,iBAAA,QehoEC,4BACA,iBAAA,QfooED,uBe9nEG,SAAA,OdyoEF,QAAS,acxoEL,MAAA,KAEA,sBfioEL,sBgB7wEC,SAAA,OfwxEA,QAAS,WACT,MAAO,KAST,0BerxEE,0Bf+wEF,0BAGA,0BexxEM,0BAMJ,0BfgxEF,0BAGA,0BACA,0BDNC,0BCAD,0BAGA,0BASE,iBAAkB,QDLnB,sCgBlyEC,sCAAA,oCfyyEF,sCetxEM,sCf2xEJ,iBAAkB,QASpB,2Be1yEE,2BfoyEF,2BAGA,2Be7yEM,2BAMJ,2BfqyEF,2BAGA,2BACA,2BDNC,2BCAD,2BAGA,2BASE,iBAAkB,QDLnB,uCgBvzEC,uCAAA,qCf8zEF,uCe3yEM,uCfgzEJ,iBAAkB,QASpB,wBe/zEE,wBfyzEF,wBAGA,wBel0EM,wBAMJ,wBf0zEF,wBAGA,wBACA,wBDNC,wBCAD,wBAGA,wBASE,iBAAkB,QDLnB,oCgB50EC,oCAAA,kCfm1EF,oCeh0EM,oCfq0EJ,iBAAkB,QASpB,2Bep1EE,2Bf80EF,2BAGA,2Bev1EM,2BAMJ,2Bf+0EF,2BAGA,2BACA,2BDNC,2BCAD,2BAGA,2BASE,iBAAkB,QDLnB,uCgBj2EC,uCAAA,qCfw2EF,uCer1EM,uCf01EJ,iBAAkB,QASpB,0Bez2EE,0Bfm2EF,0BAGA,0Be52EM,0BAMJ,0Bfo2EF,0BAGA,0BACA,0BDNC,0BCAD,0BAGA,0BASE,iBAAkB,QDLnB,sCehtEC,sCADF,oCdwtEA,sCe12EM,sCDoJJ,iBAAA,QA6DF,kBACE,WAAY,KA3DV,WAAA,KAEA,oCACA,kBACA,MAAA,KfotED,cAAA,Ke7pEC,WAAY,OAnDV,mBAAA,yBfmtEH,OAAA,IAAA,MAAA,KCWD,yBACE,cAAe,Ec5qEjB,qCd+qEA,qCcjtEI,qCARM,qCfktET,qCCMD,qCDHC,YAAA,OCWD,kCACE,OAAQ,EcvrEV,0Dd0rEA,0Dc1rEA,0DAzBU,0Df4sET,0DCMD,0DAME,YAAa,Ec/rEf,yDdksEA,yDclsEA,yDArBU,yDfgtET,yDCMD,yDAME,aAAc,EDLjB,yDe1sEW,yDEzNV,yDjBk6EC,yDiBj6ED,cAAA,GAMA,SjBk6ED,UAAA,EiB/5EC,QAAS,EACT,OAAA,EACA,OAAA,EAEA,OACA,QAAA,MACA,MAAA,KACA,QAAA,EACA,cAAA,KACA,UAAA,KjBi6ED,YAAA,QiB95EC,MAAO,KACP,OAAA,EACA,cAAA,IAAA,MAAA,QAEA,MjBg6ED,QAAA,aiBr5EC,UAAW,Kb4BX,cAAA,IACG,YAAA,IJ63EJ,mBiBr5EC,mBAAoB,WhBg6EjB,gBAAiB,WgB95EpB,WAAA,WjBy5ED,qBiBv5EC,kBAGA,OAAQ,IAAI,EAAE,EACd,WAAA,MjBs5ED,YAAA,OiBj5EC,iBACA,QAAA,MAIF,kBhB25EE,QAAS,MgBz5ET,MAAA,KAIF,iBAAA,ahB05EE,OAAQ,KI99ER,uBY2EF,2BjB64EC,wBiB54EC,QAAA,IAAA,KAAA,yBACA,eAAA,KAEA,OACA,QAAA,MjB+4ED,YAAA,IiBr3EC,UAAW,KACX,YAAA,WACA,MAAA,KAEA,cACA,QAAA,MACA,MAAA,KACA,OAAA,KACA,QAAA,IAAA,KACA,UAAA,KACA,YAAA,WACA,MAAA,KbxDA,iBAAA,KACQ,iBAAA,KAyHR,OAAA,IAAA,MAAA,KACK,cAAA,IACG,mBAAA,MAAA,EAAA,IAAA,IAAA,iBJwzET,WAAA,MAAA,EAAA,IAAA,IAAA,iBkBh8EC,mBAAA,aAAA,YAAA,KAAA,mBAAA,YAAA,KACE,cAAA,aAAA,YAAA,KAAA,WAAA,YAAA,KACA,WAAA,aAAA,YAAA,KAAA,WAAA,YAAA,KdWM,oBJy7ET,aAAA,QIx5EC,QAAA,EACE,mBAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,qBACA,WAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,qBAEF,gCAA0B,MAAA,KJ25E3B,QAAA,EI15EiC,oCJ65EjC,MAAA,KiBh4EG,yCACA,MAAA,KAQF,0BhBs4EA,iBAAkB,YAClB,OAAQ,EgBn4EN,wBjB63EH,wBiB13EC,iChBq4EA,iBAAkB,KgBn4EhB,QAAA,EAIF,wBACE,iCjB03EH,OAAA,YiB72EC,sBjBg3ED,OAAA,KiB91EG,mBhB02EF,mBAAoB,KAEtB,qDgB32EM,8BjBo2EH,8BiBj2EC,wCAAA,+BhB62EA,YAAa,KgB32EX,iCjBy2EH,iCiBt2EC,2CAAA,kChB02EF,0BACA,0BACA,oCACA,2BAKE,YAAa,KgBh3EX,iCjB82EH,iCACF,2CiBp2EC,kChBu2EA,0BACA,0BACA,oCACA,2BgBz2EA,YAAA,MhBi3EF,YgBv2EE,cAAA,KAGA,UADA,OjBi2ED,SAAA,SiBr2EC,QAAS,MhBg3ET,WAAY,KgBx2EV,cAAA,KAGA,gBADA,aAEA,WAAA,KjBi2EH,aAAA,KiB91EC,cAAe,EhBy2Ef,YAAa,IACb,OAAQ,QgBp2ER,+BjBg2ED,sCiBl2EC,yBACA,gCAIA,SAAU,ShBw2EV,WAAY,MgBt2EZ,YAAA,MAIF,oBAAA,cAEE,WAAA,KAGA,iBADA,cAEA,SAAA,SACA,QAAA,aACA,aAAA,KjB61ED,cAAA,EiB31EC,YAAa,IhBs2Eb,eAAgB,OgBp2EhB,OAAA,QAUA,kCjBo1ED,4BCWC,WAAY,EACZ,YAAa,KgBv1Eb,wCAAA,qCjBm1ED,8BCOD,+BgBh2EI,2BhB+1EJ,4BAME,OAAQ,YDNT,0BiBv1EG,uBAMF,oCAAA,iChB61EA,OAAQ,YDNT,yBiBp1EK,sBAaJ,mCAFF,gCAGE,OAAA,YAGA,qBjBy0ED,WAAA,KiBv0EC,YAAA,IhBk1EA,eAAgB,IgBh1Ed,cAAA,EjB00EH,8BiB5zED,8BCnQE,cAAA,EACA,aAAA,EAEA,UACA,OAAA,KlBkkFD,QAAA,IAAA,KkBhkFC,UAAA,KACE,YAAA,IACA,cAAA,IAGF,gBjB0kFA,OAAQ,KiBxkFN,YAAA,KD2PA,0BAFJ,kBAGI,OAAA,KAEA,6BACA,OAAA,KjBy0EH,QAAA,IAAA,KiB/0EC,UAAW,KAST,YAAA,IACA,cAAA,IAVJ,mChB81EE,OAAQ,KgBh1EN,YAAA,KAGA,6CAjBJ,qCAkBI,OAAA,KAEA,oCACA,OAAA,KjBy0EH,WAAA,KiBr0EC,QAAS,IAAI,KC/Rb,UAAA,KACA,YAAA,IAEA,UACA,OAAA,KlBumFD,QAAA,KAAA,KkBrmFC,UAAA,KACE,YAAA,UACA,cAAA,IAGF,gBjB+mFA,OAAQ,KiB7mFN,YAAA,KDuRA,0BAFJ,kBAGI,OAAA,KAEA,6BACA,OAAA,KjBk1EH,QAAA,KAAA,KiBx1EC,UAAW,KAST,YAAA,UACA,cAAA,IAVJ,mChBu2EE,OAAQ,KgBz1EN,YAAA,KAGA,6CAjBJ,qCAkBI,OAAA,KAEA,oCACA,OAAA,KjBk1EH,WAAA,KiBz0EC,QAAS,KAAK,KAEd,UAAA,KjB00ED,YAAA,UiBt0EG,cjBy0EH,SAAA,SiBp0EC,4BACA,cAAA,OAEA,uBACA,SAAA,SACA,IAAA,EACA,MAAA,EACA,QAAA,EACA,QAAA,MACA,MAAA,KjBu0ED,OAAA,KiBr0EC,YAAa,KhBg1Eb,WAAY,OACZ,eAAgB,KDLjB,oDiBv0EC,uCADA,iCAGA,MAAO,KhBg1EP,OAAQ,KACR,YAAa,KDLd,oDiBv0EC,uCADA,iCAKA,MAAO,KhB80EP,OAAQ,KACR,YAAa,KAKf,uBAEA,8BAJA,4BADA,yBAEA,oBAEA,2BDNC,4BkBruFG,mCAJA,yBD0ZJ,gCbvWE,MAAA,QJ2rFD,2BkBxuFG,aAAA,QACE,mBAAA,MAAA,EAAA,IAAA,IAAA,iBd4CJ,WAAA,MAAA,EAAA,IAAA,IAAA,iBJgsFD,iCiBz1EC,aAAc,QC5YZ,mBAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QACA,WAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QlByuFH,gCiB91EC,MAAO,QCtYL,iBAAA,QlBuuFH,aAAA,QCWD,oCACE,MAAO,QAKT,uBAEA,8BAJA,4BADA,yBAEA,oBAEA,2BDNC,4BkBnwFG,mCAJA,yBD6ZJ,gCb1WE,MAAA,QJytFD,2BkBtwFG,aAAA,QACE,mBAAA,MAAA,EAAA,IAAA,IAAA,iBd4CJ,WAAA,MAAA,EAAA,IAAA,IAAA,iBJ8tFD,iCiBp3EC,aAAc,QC/YZ,mBAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QACA,WAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QlBuwFH,gCiBz3EC,MAAO,QCzYL,iBAAA,QlBqwFH,aAAA,QCWD,oCACE,MAAO,QAKT,qBAEA,4BAJA,0BADA,uBAEA,kBAEA,yBDNC,0BkBjyFG,iCAJA,uBDgaJ,8Bb7WE,MAAA,QJuvFD,yBkBpyFG,aAAA,QACE,mBAAA,MAAA,EAAA,IAAA,IAAA,iBd4CJ,WAAA,MAAA,EAAA,IAAA,IAAA,iBJ4vFD,+BiB/4EC,aAAc,QClZZ,mBAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QACA,WAAA,MAAA,EAAA,IAAA,IAAA,iBAAA,EAAA,EAAA,IAAA,QlBqyFH,8BiBp5EC,MAAO,QC5YL,iBAAA,QlBmyFH,aAAA,QiB/4EG,kCjBk5EH,MAAA,QiB/4EG,2CjBk5EH,IAAA,KiBv4EC,mDACA,IAAA,EAEA,YjB04ED,QAAA,MiBvzEC,WAAY,IAwEZ,cAAe,KAtIX,MAAA,QAEA,yBjBy3EH,yBiBrvEC,QAAS,aA/HP,cAAA,EACA,eAAA,OjBw3EH,2BiB1vEC,QAAS,aAxHP,MAAA,KjBq3EH,eAAA,OiBj3EG,kCACA,QAAA,aAmHJ,0BhB4wEE,QAAS,aACT,eAAgB,OgBr3Ed,wCjB82EH,6CiBtwED,2CjBywEC,MAAA,KiB72EG,wCACA,MAAA,KAmGJ,4BhBwxEE,cAAe,EgBp3Eb,eAAA,OAGA,uBADA,oBjB82EH,QAAA,aiBpxEC,WAAY,EhB+xEZ,cAAe,EgBr3EX,eAAA,OAsFN,6BAAA,0BAjFI,aAAA,EAiFJ,4CjB6xEC,sCiBx2EG,SAAA,SjB22EH,YAAA,EiBh2ED,kDhB42EE,IAAK,GgBl2EL,2BjB+1EH,kCiBh2EG,wBAEA,+BAXF,YAAa,IhBo3Eb,WAAY,EgBn2EV,cAAA,EJviBF,2BIshBF,wBJrhBE,WAAA,KI4jBA,6BAyBA,aAAc,MAnCV,YAAA,MAEA,yBjBw1EH,gCACF,YAAA,IiBx3EG,cAAe,EAwCf,WAAA,OAwBJ,sDAdQ,MAAA,KjB80EL,yBACF,+CiBn0EC,YAAA,KAEE,UAAW,MjBs0EZ,yBACF,+CmBp6FG,YAAa,IACf,UAAA,MAGA,KACA,QAAA,aACA,QAAA,IAAA,KAAA,cAAA,EACA,UAAA,KACA,YAAA,IACA,YAAA,WACA,WAAA,OC0CA,YAAA,OACA,eAAA,OACA,iBAAA,aACA,aAAA,ahB+JA,OAAA,QACG,oBAAA,KACC,iBAAA,KACI,gBAAA,KJ+tFT,YAAA,KmBv6FG,iBAAA,KlBm7FF,OAAQ,IAAI,MAAM,YAClB,cAAe,IkB96Ff,kBdzBA,kBACA,WLk8FD,kBCOD,kBADA,WAME,QAAS,IAAI,KAAK,yBAClB,eAAgB,KkBh7FhB,WnBy6FD,WmB56FG,WlBw7FF,MAAO,KkBn7FL,gBAAA,Kf6BM,YADR,YJk5FD,iBAAA,KmBz6FC,QAAA,ElBq7FA,mBAAoB,MAAM,EAAE,IAAI,IAAI,iBAC5B,WAAY,MAAM,EAAE,IAAI,IAAI,iBoBh+FpC,cAGA,ejB8DA,wBACQ,OAAA,YJ05FT,OAAA,kBmBz6FG,mBAAA,KlBq7FM,WAAY,KkBn7FhB,QAAA,IASN,eC3DE,yBACA,eAAA,KpBi+FD,aoB99FC,MAAA,KnB0+FA,iBAAkB,KmBx+FhB,aAAA,KpBk+FH,mBoBh+FO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpBi+FH,mBoB99FC,MAAA,KnB0+FA,iBAAkB,QAClB,aAAc,QmBt+FR,oBADJ,oBpBi+FH,mCoB99FG,MAAA,KnB0+FF,iBAAkB,QAClB,aAAc,QmBt+FN,0BnB4+FV,0BAHA,0BmB1+FM,0BnB4+FN,0BAHA,0BDFC,yCoBx+FK,yCnB4+FN,yCmBv+FE,MAAA,KnB++FA,iBAAkB,QAClB,aAAc,QmBx+FZ,oBpBg+FH,oBoBh+FG,mCnB6+FF,iBAAkB,KmBz+FV,4BnB8+FV,4BAHA,4BDHC,6BCOD,6BAHA,6BkB39FA,sCClBM,sCnB8+FN,sCmBx+FI,iBAAA,KACA,aAAA,KDcJ,oBC9DE,MAAA,KACA,iBAAA,KpB0hGD,aoBvhGC,MAAA,KnBmiGA,iBAAkB,QmBjiGhB,aAAA,QpB2hGH,mBoBzhGO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpB0hGH,mBoBvhGC,MAAA,KnBmiGA,iBAAkB,QAClB,aAAc,QmB/hGR,oBADJ,oBpB0hGH,mCoBvhGG,MAAA,KnBmiGF,iBAAkB,QAClB,aAAc,QmB/hGN,0BnBqiGV,0BAHA,0BmBniGM,0BnBqiGN,0BAHA,0BDFC,yCoBjiGK,yCnBqiGN,yCmBhiGE,MAAA,KnBwiGA,iBAAkB,QAClB,aAAc,QmBjiGZ,oBpByhGH,oBoBzhGG,mCnBsiGF,iBAAkB,KmBliGV,4BnBuiGV,4BAHA,4BDHC,6BCOD,6BAHA,6BkBjhGA,sCCrBM,sCnBuiGN,sCmBjiGI,iBAAA,QACA,aAAA,QDkBJ,oBClEE,MAAA,QACA,iBAAA,KpBmlGD,aoBhlGC,MAAA,KnB4lGA,iBAAkB,QmB1lGhB,aAAA,QpBolGH,mBoBllGO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpBmlGH,mBoBhlGC,MAAA,KnB4lGA,iBAAkB,QAClB,aAAc,QmBxlGR,oBADJ,oBpBmlGH,mCoBhlGG,MAAA,KnB4lGF,iBAAkB,QAClB,aAAc,QmBxlGN,0BnB8lGV,0BAHA,0BmB5lGM,0BnB8lGN,0BAHA,0BDFC,yCoB1lGK,yCnB8lGN,yCmBzlGE,MAAA,KnBimGA,iBAAkB,QAClB,aAAc,QmB1lGZ,oBpBklGH,oBoBllGG,mCnB+lGF,iBAAkB,KmB3lGV,4BnBgmGV,4BAHA,4BDHC,6BCOD,6BAHA,6BkBtkGA,sCCzBM,sCnBgmGN,sCmB1lGI,iBAAA,QACA,aAAA,QDsBJ,oBCtEE,MAAA,QACA,iBAAA,KpB4oGD,UoBzoGC,MAAA,KnBqpGA,iBAAkB,QmBnpGhB,aAAA,QpB6oGH,gBoB3oGO,gBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpB4oGH,gBoBzoGC,MAAA,KnBqpGA,iBAAkB,QAClB,aAAc,QmBjpGR,iBADJ,iBpB4oGH,gCoBzoGG,MAAA,KnBqpGF,iBAAkB,QAClB,aAAc,QmBjpGN,uBnBupGV,uBAHA,uBmBrpGM,uBnBupGN,uBAHA,uBDFC,sCoBnpGK,sCnBupGN,sCmBlpGE,MAAA,KnB0pGA,iBAAkB,QAClB,aAAc,QmBnpGZ,iBpB2oGH,iBoB3oGG,gCnBwpGF,iBAAkB,KmBppGV,yBnBypGV,yBAHA,yBDHC,0BCOD,0BAHA,0BkB3nGA,mCC7BM,mCnBypGN,mCmBnpGI,iBAAA,QACA,aAAA,QD0BJ,iBC1EE,MAAA,QACA,iBAAA,KpBqsGD,aoBlsGC,MAAA,KnB8sGA,iBAAkB,QmB5sGhB,aAAA,QpBssGH,mBoBpsGO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpBqsGH,mBoBlsGC,MAAA,KnB8sGA,iBAAkB,QAClB,aAAc,QmB1sGR,oBADJ,oBpBqsGH,mCoBlsGG,MAAA,KnB8sGF,iBAAkB,QAClB,aAAc,QmB1sGN,0BnBgtGV,0BAHA,0BmB9sGM,0BnBgtGN,0BAHA,0BDFC,yCoB5sGK,yCnBgtGN,yCmB3sGE,MAAA,KnBmtGA,iBAAkB,QAClB,aAAc,QmB5sGZ,oBpBosGH,oBoBpsGG,mCnBitGF,iBAAkB,KmB7sGV,4BnBktGV,4BAHA,4BDHC,6BCOD,6BAHA,6BkBhrGA,sCCjCM,sCnBktGN,sCmB5sGI,iBAAA,QACA,aAAA,QD8BJ,oBC9EE,MAAA,QACA,iBAAA,KpB8vGD,YoB3vGC,MAAA,KnBuwGA,iBAAkB,QmBrwGhB,aAAA,QpB+vGH,kBoB7vGO,kBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpB8vGH,kBoB3vGC,MAAA,KnBuwGA,iBAAkB,QAClB,aAAc,QmBnwGR,mBADJ,mBpB8vGH,kCoB3vGG,MAAA,KnBuwGF,iBAAkB,QAClB,aAAc,QmBnwGN,yBnBywGV,yBAHA,yBmBvwGM,yBnBywGN,yBAHA,yBDFC,wCoBrwGK,wCnBywGN,wCmBpwGE,MAAA,KnB4wGA,iBAAkB,QAClB,aAAc,QmBrwGZ,mBpB6vGH,mBoB7vGG,kCnB0wGF,iBAAkB,KmBtwGV,2BnB2wGV,2BAHA,2BDHC,4BCOD,4BAHA,4BkBruGA,qCCrCM,qCnB2wGN,qCmBrwGI,iBAAA,QACA,aAAA,QDuCJ,mBACE,MAAA,QACA,iBAAA,KnB+tGD,UmB5tGC,YAAA,IlBwuGA,MAAO,QACP,cAAe,EAEjB,UGzwGE,iBemCE,iBflCM,oBJkwGT,6BmB7tGC,iBAAA,YlByuGA,mBAAoB,KACZ,WAAY,KkBtuGlB,UAEF,iBAAA,gBnB6tGD,gBmB3tGG,aAAA,YnBiuGH,gBmB/tGG,gBAIA,MAAA,QlBuuGF,gBAAiB,UACjB,iBAAkB,YDNnB,0BmBhuGK,0BAUN,mCATM,mClB2uGJ,MAAO,KmB1yGP,gBAAA,KAGA,mBADA,QpBmyGD,QAAA,KAAA,KmBztGC,UAAW,KlBquGX,YAAa,UmBjzGb,cAAA,IAGA,mBADA,QpB0yGD,QAAA,IAAA,KmB5tGC,UAAW,KlBwuGX,YAAa,ImBxzGb,cAAA,IAGA,mBADA,QpBizGD,QAAA,IAAA,ImB3tGC,UAAW,KACX,YAAA,IACA,cAAA,IAIF,WACE,QAAA,MnB2tGD,MAAA,KCYD,sBACE,WAAY,IqBz3GZ,6BADF,4BtBk3GC,6BI7rGC,MAAA,KAEQ,MJisGT,QAAA,EsBr3GC,mBAAA,QAAA,KAAA,OACE,cAAA,QAAA,KAAA,OtBu3GH,WAAA,QAAA,KAAA,OsBl3GC,StBq3GD,QAAA,EsBn3Ga,UtBs3Gb,QAAA,KsBr3Ga,atBw3Gb,QAAA,MsBv3Ga,etB03Gb,QAAA,UsBt3GC,kBACA,QAAA,gBlBwKA,YACQ,SAAA,SAAA,OAAA,EAOR,SAAA,OACQ,mCAAA,KAAA,8BAAA,KAGR,2BAAA,KACQ,4BAAA,KAAA,uBAAA,KJ2sGT,oBAAA,KuBr5GC,4BAA6B,OAAQ,WACrC,uBAAA,OAAA,WACA,oBAAA,OAAA,WAEA,OACA,QAAA,aACA,MAAA,EACA,OAAA,EACA,YAAA,IACA,eAAA,OvBu5GD,WAAA,IAAA,OuBn5GC,WAAY,IAAI,QtBk6GhB,aAAc,IAAI,MAAM,YsBh6GxB,YAAA,IAAA,MAAA,YAKA,UADF,QvBo5GC,SAAA,SuB94GC,uBACA,QAAA,EAEA,eACA,SAAA,SACA,IAAA,KACA,KAAA,EACA,QAAA,KACA,QAAA,KACA,MAAA,KACA,UAAA,MACA,QAAA,IAAA,EACA,OAAA,IAAA,EAAA,EACA,UAAA,KACA,WAAA,KACA,WAAA,KnBsBA,iBAAA,KACQ,wBAAA,YmBrBR,gBAAA,YtB+5GA,OsB/5GA,IAAA,MAAA,KvBk5GD,OAAA,IAAA,MAAA,gBuB74GC,cAAA,IACE,mBAAA,EAAA,IAAA,KAAA,iBACA,WAAA,EAAA,IAAA,KAAA,iBAzBJ,0BCzBE,MAAA,EACA,KAAA,KAEA,wBxBo8GD,OAAA,IuB96GC,OAAQ,IAAI,EAmCV,SAAA,OACA,iBAAA,QAEA,oBACA,QAAA,MACA,QAAA,IAAA,KACA,MAAA,KvB84GH,YAAA,IuBx4GC,YAAA,WtBw5GA,MAAO,KsBt5GL,YAAA,OvB44GH,0BuB14GG,0BAMF,MAAA,QtBo5GA,gBAAiB,KACjB,iBAAkB,QsBj5GhB,yBAEA,+BADA,+BvBu4GH,MAAA,KuB73GC,gBAAA,KtB64GA,iBAAkB,QAClB,QAAS,EDZV,2BuB33GC,iCAAA,iCAEE,MAAA,KEzGF,iCF2GE,iCAEA,gBAAA,KvB63GH,OAAA,YuBx3GC,iBAAkB,YAGhB,iBAAA,KvBw3GH,OAAA,0DuBn3GG,qBvBs3GH,QAAA,MuB72GC,QACA,QAAA,EAQF,qBACE,MAAA,EACA,KAAA,KAIF,oBACE,MAAA,KACA,KAAA,EAEA,iBACA,QAAA,MACA,QAAA,IAAA,KvBw2GD,UAAA,KuBp2GC,YAAa,WACb,MAAA,KACA,YAAA,OAEA,mBACA,SAAA,MACA,IAAA,EvBs2GD,MAAA,EuBl2GC,OAAQ,EACR,KAAA,EACA,QAAA,IAQF,2BtB42GE,MAAO,EsBx2GL,KAAA,KAEA,eACA,sCvB41GH,QAAA,GuBn2GC,WAAY,EtBm3GZ,cAAe,IAAI,OsBx2GjB,cAAA,IAAA,QAEA,uBvB41GH,8CuBv0GC,IAAK,KAXL,OAAA,KApEA,cAAA,IvB25GC,yBuBv1GD,6BA1DA,MAAA,EACA,KAAA,KvBq5GD,kC0BpiHG,MAAO,KzBojHP,KAAM,GyBhjHR,W1BsiHD,oB0B1iHC,SAAU,SzB0jHV,QAAS,ayBpjHP,eAAA,OAGA,yB1BsiHH,gBCgBC,SAAU,SACV,MAAO,KyB7iHT,gC1BsiHC,gCCYD,+BAFA,+ByBhjHA,uBANM,uBzBujHN,sBAFA,sBAQE,QAAS,EyBljHP,qB1BuiHH,2B0BliHD,2BACE,iC1BoiHD,YAAA,KCgBD,aACE,YAAa,KDZd,kB0B1iHD,wBAAA,0BzB2jHE,MAAO,KDZR,kB0B/hHD,wBACE,0B1BiiHD,YAAA,I0B5hHC,yE1B+hHD,cAAA,E2BhlHC,4BACG,YAAA,EDsDL,mEzB6iHE,wBAAyB,E0B5lHzB,2BAAA,E3BilHD,6C0B5hHD,8CACE,uBAAA,E1B8hHD,0BAAA,E0B3hHC,sB1B8hHD,MAAA,KCgBD,8D0B/mHE,cAAA,E3BomHD,mE0B3hHD,oECjEE,wBAAA,EACG,2BAAA,EDqEL,oEzB0iHE,uBAAwB,EyBxiHxB,0BAAA,EAiBF,mCACE,iCACA,QAAA,EAEF,iCACE,cAAA,IACA,aAAA,IAKF,oCtB/CE,cAAA,KACQ,aAAA,KsBkDR,iCtBnDA,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBsByDV,0CACE,mBAAA,K1BugHD,WAAA,K0BngHC,YACA,YAAA,EAGF,eACE,aAAA,IAAA,IAAA,E1BqgHD,oBAAA,ECgBD,uBACE,aAAc,EAAE,IAAI,IyB1gHlB,yBACA,+BACA,oC1B+/GH,QAAA,M0BtgHC,MAAO,KAcH,MAAA,K1B2/GL,UAAA,KCgBD,oCACE,MAAO,KyBpgHL,8BACA,oC1By/GH,oC0Bp/GC,0CACE,WAAA,K1Bs/GH,YAAA,E2B/pHC,4DACC,cAAA,EAQA,sD3B4pHF,uBAAA,I0Bt/GC,wBAAA,IC/KA,2BAAA,EACC,0BAAA,EAQA,sD3BkqHF,uBAAA,E0Bv/GC,wBAAyB,EACzB,2BAAA,I1By/GD,0BAAA,ICgBD,uE0BtrHE,cAAA,E3B2qHD,4E0Bt/GD,6EC7LE,2BAAA,EACC,0BAAA,EDoMH,6EACE,uBAAA,EACA,wBAAA,EAEA,qB1Bo/GD,QAAA,M0Bx/GC,MAAO,KzBwgHP,aAAc,MyBjgHZ,gBAAA,SAEA,0B1Bq/GH,gC0B9/GC,QAAS,WAYP,MAAA,K1Bq/GH,MAAA,G0Bj/GG,qC1Bo/GH,MAAA,KCgBD,+CACE,KAAM,KyB7+GF,gDAFA,6C1Bs+GL,2D0Br+GK,wDEzOJ,SAAU,SACV,KAAA,cACA,eAAA,K5BitHD,a4B7sHC,SAAA,SACE,QAAA,MACA,gBAAA,S5BgtHH,0B4BxtHC,MAAO,KAeL,cAAA,EACA,aAAA,EAOA,2BACA,SAAA,S5BusHH,QAAA,E4BrsHG,MAAA,KACE,MAAA,K5BusHL,cAAA,ECgBD,iCACE,QAAS,EiBnrHT,8BACA,mCACA,sCACA,OAAA,KlBwqHD,QAAA,KAAA,KkBtqHC,UAAA,KjBsrHA,YAAa,UACb,cAAe,IiBrrHb,oClB0qHH,yCkBvqHC,4CjBurHA,OAAQ,KACR,YAAa,KDTd,8C4B/sHD,mDAAA,sD3B0tHA,sCACA,2CiBzrHI,8CjB8rHF,OAAQ,KiB1sHR,8BACA,mCACA,sCACA,OAAA,KlB+rHD,QAAA,IAAA,KkB7rHC,UAAA,KjB6sHA,YAAa,IACb,cAAe,IiB5sHb,oClBisHH,yCkB9rHC,4CjB8sHA,OAAQ,KACR,YAAa,KDTd,8C4B7tHD,mDAAA,sD3BwuHA,sCACA,2CiBhtHI,8CjBqtHF,OAAQ,K2BzuHR,2B5B6tHD,mB4B7tHC,iB3B8uHA,QAAS,W2BzuHX,8D5B6tHC,sD4B7tHD,oDAEE,cAAA,EAEA,mB5B+tHD,iB4B1tHC,MAAO,GACP,YAAA,OACA,eAAA,OAEA,mBACA,QAAA,IAAA,KACA,UAAA,KACA,YAAA,IACA,YAAA,EACA,MAAA,K5B4tHD,WAAA,O4BztHC,iBAAA,KACE,OAAA,IAAA,MAAA,KACA,cAAA,I5B4tHH,4B4BztHC,QAAA,IAAA,KACE,UAAA,KACA,cAAA,I5B4tHH,4B4B/uHC,QAAS,KAAK,K3B+vHd,UAAW,K2BruHT,cAAA,IAKJ,wCAAA,qC3BquHE,WAAY,EAEd,uCACA,+BACA,kC0B70HE,6CACG,8CC4GL,6D5BqtHC,wE4BptHC,wBAAA,E5ButHD,2BAAA,ECgBD,+BACE,aAAc,EAEhB,sCACA,8B2BhuHA,+D5BstHC,oDCWD,iC0Bl1HE,4CACG,6CCiHH,uBAAA,E5BwtHD,0BAAA,E4BltHC,8BAGA,YAAA,E5BotHD,iB4BxtHC,SAAU,SAUR,UAAA,E5BitHH,YAAA,O4B/sHK,sB5BktHL,SAAA,SCgBD,2BACE,YAAa,K2BxtHb,6BAAA,4B5B4sHD,4B4BzsHK,QAAA,EAGJ,kCAAA,wCAGI,aAAA,K5B4sHL,iC6B12HD,uCACE,QAAA,EACA,YAAA,K7B62HD,K6B/2HC,aAAc,EAOZ,cAAA,EACA,WAAA,KARJ,QAWM,SAAA,SACA,QAAA,M7B42HL,U6B12HK,SAAA,S5B03HJ,QAAS,M4Bx3HH,QAAA,KAAA,KAMJ,gB7Bu2HH,gB6Bt2HK,gBAAA,K7By2HL,iBAAA,KCgBD,mB4Br3HQ,MAAA,KAGA,yBADA,yB7B02HP,MAAA,K6Bl2HG,gBAAA,K5Bk3HF,OAAQ,YACR,iBAAkB,Y4B/2Hd,aAzCN,mB7B64HC,mBwBh5HC,iBAAA,KACA,aAAA,QAEA,kBxBm5HD,OAAA,I6Bn5HC,OAAQ,IAAI,EA0DV,SAAA,O7B41HH,iBAAA,Q6Bl1HC,c7Bq1HD,UAAA,K6Bn1HG,UAEA,cAAA,IAAA,MAAA,KALJ,aASM,MAAA,KACA,cAAA,KAEA,e7Bo1HL,aAAA,I6Bn1HK,YAAA,WACE,OAAA,IAAA,MAAA,Y7Bq1HP,cAAA,IAAA,IAAA,EAAA,ECgBD,qBACE,aAAc,KAAK,KAAK,K4B51HlB,sBAEA,4BADA,4BAEA,MAAA,K7Bi1HP,OAAA,Q6B50HC,iBAAA,KAqDA,OAAA,IAAA,MAAA,KA8BA,oBAAA,YAnFA,wBAwDE,MAAA,K7B2xHH,cAAA,E6BzxHK,2BACA,MAAA,KA3DJ,6BAgEE,cAAA,IACA,WAAA,OAYJ,iDA0DE,IAAK,KAjED,KAAA,K7B0xHH,yB6BztHD,2BA9DM,QAAA,W7B0xHL,MAAA,G6Bn2HD,6BAuFE,cAAA,GAvFF,6B5Bw3HA,aAAc,EACd,cAAe,IDZhB,kC6BtuHD,wCA3BA,wCATM,OAAA,IAAA,MAAA,K7B+wHH,yB6B3uHD,6B5B2vHE,cAAe,IAAI,MAAM,KACzB,cAAe,IAAI,IAAI,EAAE,EDZ1B,kC6B92HD,wC7B+2HD,wC6B72HG,oBAAA,MAIE,c7B+2HL,MAAA,K6B52HK,gB7B+2HL,cAAA,ICgBD,iBACE,YAAa,I4Bv3HP,uBAQR,6B7Bo2HC,6B6Bl2HG,MAAA,K7Bq2HH,iBAAA,Q6Bn2HK,gBACA,MAAA,KAYN,mBACE,WAAA,I7B41HD,YAAA,E6Bz1HG,e7B41HH,MAAA,K6B11HK,kBACA,MAAA,KAPN,oBAYI,cAAA,IACA,WAAA,OAYJ,wCA0DE,IAAK,KAjED,KAAA,K7B21HH,yB6B1xHD,kBA9DM,QAAA,W7B21HL,MAAA,G6Bl1HD,oBACA,cAAA,GAIE,oBACA,cAAA,EANJ,yB5B02HE,aAAc,EACd,cAAe,IDZhB,8B6B1yHD,oCA3BA,oCATM,OAAA,IAAA,MAAA,K7Bm1HH,yB6B/yHD,yB5B+zHE,cAAe,IAAI,MAAM,KACzB,cAAe,IAAI,IAAI,EAAE,EDZ1B,8B6Bx0HD,oC7By0HD,oC6Bv0HG,oBAAA,MAGA,uB7B00HH,QAAA,K6B/zHC,qBF3OA,QAAA,M3B+iID,yB8BxiIC,WAAY,KACZ,uBAAA,EACA,wBAAA,EAEA,Q9B0iID,SAAA,S8BliIC,WAAY,KA8nBZ,cAAe,KAhoBb,OAAA,IAAA,MAAA,Y9ByiIH,yB8BzhIC,QAgnBE,cAAe,K9B86GlB,yB8BjhIC,eACA,MAAA,MAGA,iBACA,cAAA,KAAA,aAAA,KAEA,WAAA,Q9BkhID,2BAAA,M8BhhIC,WAAA,IAAA,MAAA,YACE,mBAAA,MAAA,EAAA,IAAA,EAAA,qB9BkhIH,WAAA,MAAA,EAAA,IAAA,EAAA,qB8Bz7GD,oBArlBI,WAAA,KAEA,yBAAA,iB9BkhID,MAAA,K8BhhIC,WAAA,EACE,mBAAA,KACA,WAAA,KAEA,0B9BkhIH,QAAA,gB8B/gIC,OAAA,eACE,eAAA,E9BihIH,SAAA,kBCkBD,oBACE,WAAY,QDZf,sC8B/gIK,mC9B8gIH,oC8BzgIC,cAAe,E7B4hIf,aAAc,G6Bj+GlB,sCAnjBE,mC7ByhIA,WAAY,MDdX,4D8BngID,sC9BogID,mCCkBG,WAAY,O6B3gId,kCANE,gC9BsgIH,4B8BvgIG,0BAuiBF,aAAc,M7Bm/Gd,YAAa,MAEf,yBDZC,kC8B3gIK,gC9B0gIH,4B8B3gIG,0BAcF,aAAc,EAChB,YAAA,GAMF,mBA8gBE,QAAS,KAhhBP,aAAA,EAAA,EAAA,I9BkgIH,yB8B7/HC,mB7B+gIE,cAAe,G6B1gIjB,qBADA,kB9BggID,SAAA,M8Bz/HC,MAAO,EAggBP,KAAM,E7B4gHN,QAAS,KDdR,yB8B7/HD,qB9B8/HD,kB8B7/HC,cAAA,GAGF,kBACE,IAAA,EACA,aAAA,EAAA,EAAA,I9BigID,qB8B1/HC,OAAQ,EACR,cAAA,EACA,aAAA,IAAA,EAAA,EAEA,cACA,MAAA,K9B4/HD,OAAA,K8B1/HC,QAAA,KAAA,K7B4gIA,UAAW,K6B1gIT,YAAA,KAIA,oBAbJ,oB9BwgIC,gBAAA,K8Bv/HG,kB7B0gIF,QAAS,MDdR,yBACF,iC8Bh/HC,uCACA,YAAA,OAGA,eC9LA,SAAA,SACA,MAAA,MD+LA,QAAA,IAAA,KACA,WAAA,IACA,aAAA,KACA,cAAA,I9Bm/HD,iBAAA,Y8B/+HC,iBAAA,KACE,OAAA,IAAA,MAAA,Y9Bi/HH,cAAA,I8B5+HG,qBACA,QAAA,EAEA,yB9B++HH,QAAA,M8BrgIC,MAAO,KAyBL,OAAA,I9B++HH,cAAA,I8BpjHD,mCAvbI,WAAA,I9Bg/HH,yB8Bt+HC,eACA,QAAA,MAGE,YACA,OAAA,MAAA,M9By+HH,iB8B58HC,YAAA,KA2YA,eAAgB,KAjaZ,YAAA,KAEA,yBACA,iCACA,SAAA,OACA,MAAA,KACA,MAAA,KAAA,WAAA,E9Bs+HH,iBAAA,Y8B3kHC,OAAQ,E7B8lHR,mBAAoB,K6Bt/HhB,WAAA,KAGA,kDAqZN,sC9BklHC,QAAA,IAAA,KAAA,IAAA,KCmBD,sC6Bv/HQ,YAAA,KAmBR,4C9Bs9HD,4C8BvlHG,iBAAkB,M9B4lHnB,yB8B5lHD,YAtYI,MAAA,K9Bq+HH,OAAA,E8Bn+HK,eACA,MAAA,K9Bu+HP,iB8B39HG,YAAa,KACf,eAAA,MAGA,aACA,QAAA,KAAA,K1B9NA,WAAA,IACQ,aAAA,M2B/DR,cAAA,IACA,YAAA,M/B4vID,WAAA,IAAA,MAAA,YiBtuHC,cAAe,IAAI,MAAM,YAwEzB,mBAAoB,MAAM,EAAE,IAAI,EAAE,qBAAyB,EAAE,IAAI,EAAE,qBAtI/D,WAAA,MAAA,EAAA,IAAA,EAAA,qBAAA,EAAA,IAAA,EAAA,qBAEA,yBjBwyHH,yBiBpqHC,QAAS,aA/HP,cAAA,EACA,eAAA,OjBuyHH,2BiBzqHC,QAAS,aAxHP,MAAA,KjBoyHH,eAAA,OiBhyHG,kCACA,QAAA,aAmHJ,0BhBmsHE,QAAS,aACT,eAAgB,OgB5yHd,wCjB6xHH,6CiBrrHD,2CjBwrHC,MAAA,KiB5xHG,wCACA,MAAA,KAmGJ,4BhB+sHE,cAAe,EgB3yHb,eAAA,OAGA,uBADA,oBjB6xHH,QAAA,aiBnsHC,WAAY,EhBstHZ,cAAe,EgB5yHX,eAAA,OAsFN,6BAAA,0BAjFI,aAAA,EAiFJ,4CjB4sHC,sCiBvxHG,SAAA,SjB0xHH,YAAA,E8BngID,kDAmWE,IAAK,GAvWH,yBACE,yB9B8gIL,cAAA,I8B5/HD,oCAoVE,cAAe,GA1Vf,yBACA,aACA,MAAA,KACA,YAAA,E1BzPF,eAAA,EACQ,aAAA,EJmwIP,YAAA,EACF,OAAA,E8BngIG,mBAAoB,KACtB,WAAA,M9BugID,8B8BngIC,WAAY,EACZ,uBAAA,EHzUA,wBAAA,EAQA,mDACC,cAAA,E3By0IF,uBAAA,I8B//HC,wBAAyB,IChVzB,2BAAA,EACA,0BAAA,EDkVA,YCnVA,WAAA,IACA,cAAA,IDqVA,mBCtVA,WAAA,KACA,cAAA,KD+VF,mBChWE,WAAA,KACA,cAAA,KDuWF,aAsSE,WAAY,KA1SV,cAAA,KAEA,yB9B+/HD,aACF,MAAA,K8Bl+HG,aAAc,KAhBhB,YAAA,MACA,yBE5WA,aF8WE,MAAA,eAFF,cAKI,MAAA,gB9Bu/HH,aAAA,M8B7+HD,4BACA,aAAA,GADF,gBAKI,iBAAA,Q9Bg/HH,aAAA,QCmBD,8B6BhgIM,MAAA,KARN,oC9B0/HC,oC8B5+HG,MAAA,Q9B++HH,iBAAA,Y8B1+HK,6B9B6+HL,MAAA,KCmBD,iC6B5/HQ,MAAA,KAKF,uC9By+HL,uCCmBC,MAAO,KACP,iBAAkB,Y6Bz/HZ,sCAIF,4C9Bu+HL,4CCmBC,MAAO,KACP,iBAAkB,Q6Bv/HZ,wCAxCR,8C9BihIC,8C8Bn+HG,MAAA,K9Bs+HH,iBAAA,YCmBD,+B6Bt/HM,aAAA,KAGA,qCApDN,qC9B2hIC,iBAAA,KCmBD,yC6Bp/HI,iBAAA,KAOE,iCAAA,6B7Bk/HJ,aAAc,Q6B9+HR,oCAiCN,0C9B+7HD,0C8B3xHC,MAAO,KA7LC,iBAAA,QACA,yB7B8+HR,sD6B5+HU,MAAA,KAKF,4D9By9HP,4DCmBC,MAAO,KACP,iBAAkB,Y6Bz+HV,2DAIF,iE9Bu9HP,iECmBC,MAAO,KACP,iBAAkB,Q6Bv+HV,6D9B09HX,mEADE,mE8B1jIC,MAAO,KA8GP,iBAAA,aAEE,6B9Bi9HL,MAAA,K8B58HG,mC9B+8HH,MAAA,KCmBD,0B6B/9HM,MAAA,KAIA,gCAAA,gC7Bg+HJ,MAAO,K6Bt9HT,0CARQ,0CASN,mD9Bu8HD,mD8Bt8HC,MAAA,KAFF,gBAKI,iBAAA,K9B08HH,aAAA,QCmBD,8B6B19HM,MAAA,QARN,oC9Bo9HC,oC8Bt8HG,MAAA,K9By8HH,iBAAA,Y8Bp8HK,6B9Bu8HL,MAAA,QCmBD,iC6Bt9HQ,MAAA,QAKF,uC9Bm8HL,uCCmBC,MAAO,KACP,iBAAkB,Y6Bn9HZ,sCAIF,4C9Bi8HL,4CCmBC,MAAO,KACP,iBAAkB,Q6Bj9HZ,wCAxCR,8C9B2+HC,8C8B57HG,MAAA,K9B+7HH,iBAAA,YCmBD,+B6B/8HM,aAAA,KAGA,qCArDN,qC9Bq/HC,iBAAA,KCmBD,yC6B78HI,iBAAA,KAME,iCAAA,6B7B48HJ,aAAc,Q6Bx8HR,oCAuCN,0C9Bm5HD,0C8B33HC,MAAO,KAvDC,iBAAA,QAuDV,yBApDU,kE9Bs7HP,aAAA,Q8Bn7HO,0D9Bs7HP,iBAAA,QCmBD,sD6Bt8HU,MAAA,QAKF,4D9Bm7HP,4DCmBC,MAAO,KACP,iBAAkB,Y6Bn8HV,2DAIF,iE9Bi7HP,iECmBC,MAAO,KACP,iBAAkB,Q6Bj8HV,6D9Bo7HX,mEADE,mE8B1hIC,MAAO,KA+GP,iBAAA,aAEE,6B9Bg7HL,MAAA,Q8B36HG,mC9B86HH,MAAA,KCmBD,0B6B97HM,MAAA,QAIA,gCAAA,gC7B+7HJ,MAAO,KgCvkJT,0CH0oBQ,0CGzoBN,mDjCwjJD,mDiCvjJC,MAAA,KAEA,YACA,QAAA,IAAA,KjC2jJD,cAAA,KiChkJC,WAAY,KAQV,iBAAA,QjC2jJH,cAAA,IiCxjJK,eACA,QAAA,ajC4jJL,yBiCxkJC,QAAS,EAAE,IAkBT,MAAA,KjCyjJH,QAAA,SkC5kJC,oBACA,MAAA,KAEA,YlC+kJD,QAAA,akCnlJC,aAAc,EAOZ,OAAA,KAAA,ElC+kJH,cAAA,ICmBD,eiC/lJM,QAAA,OAEA,iBACA,oBACA,SAAA,SACA,MAAA,KACA,QAAA,IAAA,KACA,YAAA,KACA,YAAA,WlCglJL,MAAA,QkC9kJG,gBAAA,KjCimJF,iBAAkB,KiC9lJZ,OAAA,IAAA,MAAA,KPVH,6B3B2lJJ,gCkC7kJG,YAAA,EjCgmJF,uBAAwB,I0BvnJxB,0BAAA,I3BymJD,4BkCxkJG,+BjC2lJF,wBAAyB,IACzB,2BAA4B,IiCxlJxB,uBAFA,uBAGA,0BAFA,0BlC8kJL,QAAA,EkCtkJG,MAAA,QjCylJF,iBAAkB,KAClB,aAAc,KAEhB,sBiCvlJM,4BAFA,4BjC0lJN,yBiCvlJM,+BAFA,+BAGA,QAAA,ElC2kJL,MAAA,KkCloJC,OAAQ,QjCqpJR,iBAAkB,QAClB,aAAc,QiCnlJV,wBAEA,8BADA,8BjColJN,2BiCtlJM,iCjCulJN,iCDZC,MAAA,KkC/jJC,OAAQ,YjCklJR,iBAAkB,KkC7pJd,aAAA,KAEA,oBnC8oJL,uBmC5oJG,QAAA,KAAA,KlC+pJF,UAAW,K0B1pJX,YAAA,U3B4oJD,gCmC3oJG,mClC8pJF,uBAAwB,I0BvqJxB,0BAAA,I3BypJD,+BkC1kJD,kCjC6lJE,wBAAyB,IkC7qJrB,2BAAA,IAEA,oBnC8pJL,uBmC5pJG,QAAA,IAAA,KlC+qJF,UAAW,K0B1qJX,YAAA,I3B4pJD,gCmC3pJG,mClC8qJF,uBAAwB,I0BvrJxB,0BAAA,I3ByqJD,+BoC3qJD,kCACE,wBAAA,IACA,2BAAA,IAEA,OpC6qJD,aAAA,EoCjrJC,OAAQ,KAAK,EAOX,WAAA,OpC6qJH,WAAA,KCmBD,UmC7rJM,QAAA,OAEA,YACA,eACA,QAAA,apC8qJL,QAAA,IAAA,KoC5rJC,iBAAkB,KnC+sJlB,OAAQ,IAAI,MAAM,KmC5rJd,cAAA,KAnBN,kBpCisJC,kBCmBC,gBAAiB,KmCzrJb,iBAAA,KA3BN,eAAA,kBAkCM,MAAA,MAlCN,mBAAA,sBnC6tJE,MAAO,KmClrJH,mBAEA,yBADA,yBpCqqJL,sBqCltJC,MAAO,KACP,OAAA,YACA,iBAAA,KAEA,OACA,QAAA,OACA,QAAA,KAAA,KAAA,KACA,UAAA,IACA,YAAA,IACA,YAAA,EACA,MAAA,KrCotJD,WAAA,OqChtJG,YAAA,OpCmuJF,eAAgB,SoCjuJZ,cAAA,MrCotJL,cqCltJK,cAKJ,MAAA,KACE,gBAAA,KrC+sJH,OAAA,QqC1sJG,aACA,QAAA,KAOJ,YCtCE,SAAA,StC+uJD,IAAA,KCmBD,eqC7vJM,iBAAA,KALJ,2BD0CF,2BrC4sJC,iBAAA,QCmBD,eqCpwJM,iBAAA,QALJ,2BD8CF,2BrC+sJC,iBAAA,QCmBD,eqC3wJM,iBAAA,QALJ,2BDkDF,2BrCktJC,iBAAA,QCmBD,YqClxJM,iBAAA,QALJ,wBDsDF,wBrCqtJC,iBAAA,QCmBD,eqCzxJM,iBAAA,QALJ,2BD0DF,2BrCwtJC,iBAAA,QCmBD,cqChyJM,iBAAA,QCDJ,0BADF,0BAEE,iBAAA,QAEA,OACA,QAAA,aACA,UAAA,KACA,QAAA,IAAA,IACA,UAAA,KACA,YAAA,IACA,YAAA,EACA,MAAA,KACA,WAAA,OvCqxJD,YAAA,OuClxJC,eAAA,OACE,iBAAA,KvCoxJH,cAAA,KuC/wJG,aACA,QAAA,KAGF,YtCkyJA,SAAU,SsChyJR,IAAA,KAMA,0BvC4wJH,eCmBC,IAAK,EsC7xJD,QAAA,IAAA,IvCgxJL,cuC9wJK,cAKJ,MAAA,KtC4xJA,gBAAiB,KsC1xJf,OAAA,QvC4wJH,+BuCxwJC,4BACE,MAAA,QvC0wJH,iBAAA,KuCtwJG,wBvCywJH,MAAA,MuCrwJG,+BvCwwJH,aAAA,IwCj0JC,uBACA,YAAA,IAEA,WACA,YAAA,KxCo0JD,eAAA,KwCz0JC,cAAe,KvC41Jf,MAAO,QuCn1JL,iBAAA,KAIA,eAbJ,cAcI,MAAA,QxCo0JH,awCl1JC,cAAe,KAmBb,UAAA,KxCk0JH,YAAA,ICmBD,cuCh1JI,iBAAA,QAEA,sBxCi0JH,4BwC31JC,cAAe,KA8Bb,aAAA,KxCg0JH,cAAA,IwC7yJD,sBAfI,UAAA,KxCi0JD,oCwC9zJC,WvCi1JA,YAAa,KuC/0JX,eAAA,KxCi0JH,sBwCvzJD,4BvC00JE,cAAe,KuC90Jb,aAAA,KC5CJ,ezC42JD,cyC32JC,UAAA,MAGA,WACA,QAAA,MACA,QAAA,IACA,cAAA,KrCiLA,YAAA,WACK,iBAAA,KACG,OAAA,IAAA,MAAA,KJ8rJT,cAAA,IyCx3JC,mBAAoB,OAAO,IAAI,YxC24J1B,cAAe,OAAO,IAAI,YwC93J7B,WAAA,OAAA,IAAA,YAKF,iBzC22JD,eCmBC,aAAc,KACd,YAAa,KwCv3JX,mBA1BJ,kBzCk4JC,kByCv2JG,aAAA,QCzBJ,oBACE,QAAA,IACA,MAAA,KAEA,O1Cs4JD,QAAA,K0C14JC,cAAe,KAQb,OAAA,IAAA,MAAA,YAEA,cAAA,IAVJ,UAeI,WAAA,E1Ck4JH,MAAA,QCmBD,mByC/4JI,YAAA,IArBJ,SAyBI,U1C+3JH,cAAA,ECmBD,WyCx4JE,WAAA,IAFF,mBAAA,mBAMI,cAAA,KAEA,0BACA,0B1Cy3JH,SAAA,S0Cj3JC,IAAK,KCvDL,MAAA,MACA,MAAA,Q3C46JD,e0Ct3JC,MAAO,QClDL,iBAAA,Q3C26JH,aAAA,Q2Cx6JG,kB3C26JH,iBAAA,Q2Cn7JC,2BACA,MAAA,Q3Cu7JD,Y0C73JC,MAAO,QCtDL,iBAAA,Q3Cs7JH,aAAA,Q2Cn7JG,e3Cs7JH,iBAAA,Q2C97JC,wBACA,MAAA,Q3Ck8JD,e0Cp4JC,MAAO,QC1DL,iBAAA,Q3Ci8JH,aAAA,Q2C97JG,kB3Ci8JH,iBAAA,Q2Cz8JC,2BACA,MAAA,Q3C68JD,c0C34JC,MAAO,QC9DL,iBAAA,Q3C48JH,aAAA,Q2Cz8JG,iB3C48JH,iBAAA,Q4C78JC,0BAAQ,MAAA,QACR,wCAAQ,K5Cm9JP,oBAAA,KAAA,E4C/8JD,GACA,oBAAA,EAAA,GACA,mCAAQ,K5Cq9JP,oBAAA,KAAA,E4Cv9JD,GACA,oBAAA,EAAA,GACA,gCAAQ,K5Cq9JP,oBAAA,KAAA,E4C78JD,GACA,oBAAA,EAAA,GAGA,UACA,OAAA,KxCsCA,cAAA,KACQ,SAAA,OJ26JT,iBAAA,Q4C78JC,cAAe,IACf,mBAAA,MAAA,EAAA,IAAA,IAAA,eACA,WAAA,MAAA,EAAA,IAAA,IAAA,eAEA,cACA,MAAA,KACA,MAAA,EACA,OAAA,KACA,UAAA,KxCyBA,YAAA,KACQ,MAAA,KAyHR,WAAA,OACK,iBAAA,QACG,mBAAA,MAAA,EAAA,KAAA,EAAA,gBJ+zJT,WAAA,MAAA,EAAA,KAAA,EAAA,gB4C18JC,mBAAoB,MAAM,IAAI,K3Cq+JzB,cAAe,MAAM,IAAI,K4Cp+J5B,WAAA,MAAA,IAAA,KDEF,sBCAE,gCDAF,iBAAA,yK5C88JD,iBAAA,oK4Cv8JC,iBAAiB,iK3Cm+JjB,wBAAyB,KAAK,KG/gK9B,gBAAA,KAAA,KJy/JD,qBIv/JS,+BwCmDR,kBAAmB,qBAAqB,GAAG,OAAO,SErElD,aAAA,qBAAA,GAAA,OAAA,S9C4gKD,UAAA,qBAAA,GAAA,OAAA,S6Cz9JG,sBACA,iBAAA,Q7C69JH,wC4Cx8JC,iBAAkB,yKEzElB,iBAAA,oK9CohKD,iBAAA,iK6Cj+JG,mBACA,iBAAA,Q7Cq+JH,qC4C58JC,iBAAkB,yKE7ElB,iBAAA,oK9C4hKD,iBAAA,iK6Cz+JG,sBACA,iBAAA,Q7C6+JH,wC4Ch9JC,iBAAkB,yKEjFlB,iBAAA,oK9CoiKD,iBAAA,iK6Cj/JG,qBACA,iBAAA,Q7Cq/JH,uC+C5iKC,iBAAkB,yKAElB,iBAAA,oK/C6iKD,iBAAA,iK+C1iKG,O/C6iKH,WAAA,KC4BD,mB8CnkKE,WAAA,E/C4iKD,O+CxiKD,YACE,SAAA,O/C0iKD,KAAA,E+CtiKC,Y/CyiKD,MAAA,Q+CriKG,c/CwiKH,QAAA,MC4BD,4B8C9jKE,UAAA,KAGF,aAAA,mBAEE,aAAA,KAGF,YAAA,kB9C+jKE,cAAe,K8CxjKjB,YAHE,Y/CoiKD,a+ChiKC,QAAA,W/CmiKD,eAAA,I+C/hKC,c/CkiKD,eAAA,O+C7hKC,cACA,eAAA,OAMF,eACE,WAAA,EACA,cAAA,ICvDF,YAEE,aAAA,EACA,WAAA,KAQF,YACE,aAAA,EACA,cAAA,KAGA,iBACA,SAAA,SACA,QAAA,MhD6kKD,QAAA,KAAA,KgD1kKC,cAAA,KrB3BA,iBAAA,KACC,OAAA,IAAA,MAAA,KqB6BD,6BACE,uBAAA,IrBvBF,wBAAA,I3BsmKD,4BgDpkKC,cAAe,E/CgmKf,2BAA4B,I+C9lK5B,0BAAA,IAFF,kBAAA,uBAKI,MAAA,KAIF,2CAAA,gD/CgmKA,MAAO,K+C5lKL,wBAFA,wBhDykKH,6BgDxkKG,6BAKF,MAAO,KACP,gBAAA,KACA,iBAAA,QAKA,uB/C4lKA,MAAO,KACP,WAAY,K+CzlKV,0BhDmkKH,gCgDlkKG,gCALF,MAAA,K/CmmKA,OAAQ,YACR,iBAAkB,KDxBnB,mDgD5kKC,yDAAA,yD/CymKA,MAAO,QDxBR,gDgDhkKC,sDAAA,sD/C6lKA,MAAO,K+CzlKL,wBAEA,8BADA,8BhDmkKH,QAAA,EgDxkKC,MAAA,K/ComKA,iBAAkB,QAClB,aAAc,QAEhB,iDDpBC,wDCuBD,uDADA,uD+CzmKE,8DAYI,6D/C4lKN,uD+CxmKE,8D/C2mKF,6DAKE,MAAO,QDxBR,8CiD1qKG,oDADF,oDAEE,MAAA,QAEA,yBhDusKF,MAAO,QgDrsKH,iBAAA,QAFF,0BAAA,+BAKI,MAAA,QAGF,mDAAA,wDhDwsKJ,MAAO,QDtBR,gCiDhrKO,gCAGF,qCAFE,qChD2sKN,MAAO,QACP,iBAAkB,QAEpB,iCgDvsKQ,uCAFA,uChD0sKR,sCDtBC,4CiDnrKO,4CArBN,MAAA,KACE,iBAAA,QACA,aAAA,QAEA,sBhDouKF,MAAO,QgDluKH,iBAAA,QAFF,uBAAA,4BAKI,MAAA,QAGF,gDAAA,qDhDquKJ,MAAO,QDtBR,6BiD7sKO,6BAGF,kCAFE,kChDwuKN,MAAO,QACP,iBAAkB,QAEpB,8BgDpuKQ,oCAFA,oChDuuKR,mCDtBC,yCiDhtKO,yCArBN,MAAA,KACE,iBAAA,QACA,aAAA,QAEA,yBhDiwKF,MAAO,QgD/vKH,iBAAA,QAFF,0BAAA,+BAKI,MAAA,QAGF,mDAAA,wDhDkwKJ,MAAO,QDtBR,gCiD1uKO,gCAGF,qCAFE,qChDqwKN,MAAO,QACP,iBAAkB,QAEpB,iCgDjwKQ,uCAFA,uChDowKR,sCDtBC,4CiD7uKO,4CArBN,MAAA,KACE,iBAAA,QACA,aAAA,QAEA,wBhD8xKF,MAAO,QgD5xKH,iBAAA,QAFF,yBAAA,8BAKI,MAAA,QAGF,kDAAA,uDhD+xKJ,MAAO,QDtBR,+BiDvwKO,+BAGF,oCAFE,oChDkyKN,MAAO,QACP,iBAAkB,QAEpB,gCgD9xKQ,sCAFA,sChDiyKR,qCDtBC,2CiD1wKO,2CDkGN,MAAO,KACP,iBAAA,QACA,aAAA,QAEF,yBACE,WAAA,EACA,cAAA,IE1HF,sBACE,cAAA,EACA,YAAA,IAEA,O9C0DA,cAAA,KACQ,iBAAA,KJ6uKT,OAAA,IAAA,MAAA,YkDnyKC,cAAe,IACf,mBAAA,EAAA,IAAA,IAAA,gBlDqyKD,WAAA,EAAA,IAAA,IAAA,gBkD/xKC,YACA,QAAA,KvBnBC,e3BuzKF,QAAA,KAAA,KkDtyKC,cAAe,IAAI,MAAM,YAMvB,uBAAA,IlDmyKH,wBAAA,IkD7xKC,0CACA,MAAA,QAEA,alDgyKD,WAAA,EkDpyKC,cAAe,EjDg0Kf,UAAW,KACX,MAAO,QDtBR,oBkD1xKC,sBjDkzKF,eiDxzKI,mBAKJ,qBAEE,MAAA,QvBvCA,cACC,QAAA,KAAA,K3Bs0KF,iBAAA,QkDrxKC,WAAY,IAAI,MAAM,KjDizKtB,2BAA4B,IiD9yK1B,0BAAA,IAHJ,mBAAA,mCAMM,cAAA,ElDwxKL,oCkDnxKG,oDjD+yKF,aAAc,IAAI,EiD7yKZ,cAAA,EvBtEL,4D3B61KF,4EkDjxKG,WAAA,EjD6yKF,uBAAwB,IiD3yKlB,wBAAA,IvBtEL,0D3B21KF,0EkD1yKC,cAAe,EvB1Df,2BAAA,IACC,0BAAA,IuB0FH,+EAEI,uBAAA,ElD8wKH,wBAAA,EkD1wKC,wDlD6wKD,iBAAA,EC4BD,0BACE,iBAAkB,EiDlyKpB,8BlD0wKC,ckD1wKD,gCjDuyKE,cAAe,EiDvyKjB,sCAQM,sBlDwwKL,wCC4BC,cAAe,K0Br5Kf,aAAA,KuByGF,wDlDqxKC,0BC4BC,uBAAwB,IACxB,wBAAyB,IiDlzK3B,yFAoBQ,yFlDwwKP,2DkDzwKO,2DjDqyKN,uBAAwB,IACxB,wBAAyB,IAK3B,wGiD9zKA,wGjD4zKA,wGDtBC,wGCuBD,0EiD7zKA,0EjD2zKA,0EiDnyKU,0EjD2yKR,uBAAwB,IAK1B,uGiDx0KA,uGjDs0KA,uGDtBC,uGCuBD,yEiDv0KA,yEjDq0KA,yEiDzyKU,yEvB7HR,wBAAA,IuBiGF,sDlDqzKC,yBC4BC,2BAA4B,IAC5B,0BAA2B,IiDxyKrB,qFA1CR,qFAyCQ,wDlDmxKP,wDC4BC,2BAA4B,IAC5B,0BAA2B,IAG7B,oGDtBC,oGCwBD,oGiD91KA,oGjD21KA,uEiD7yKU,uEjD+yKV,uEiD71KA,uEjDm2KE,0BAA2B,IAG7B,mGDtBC,mGCwBD,mGiDx2KA,mGjDq2KA,sEiDnzKU,sEjDqzKV,sEiDv2KA,sEjD62KE,2BAA4B,IiDlzK1B,0BlD2xKH,qCkDt1KD,0BAAA,qCA+DI,WAAA,IAAA,MAAA,KA/DJ,kDAAA,kDAmEI,WAAA,EAnEJ,uBAAA,yCjD23KE,OAAQ,EiDjzKA,+CjDqzKV,+CiD/3KA,+CjDi4KA,+CAEA,+CANA,+CDjBC,iECoBD,iEiDh4KA,iEjDk4KA,iEAEA,iEANA,iEAWE,YAAa,EiD3zKL,8CjD+zKV,8CiD74KA,8CjD+4KA,8CAEA,8CANA,8CDjBC,gECoBD,gEiD94KA,gEjDg5KA,gEAEA,gEANA,gEAWE,aAAc,EAIhB,+CiD35KA,+CjDy5KA,+CiDl0KU,+CjDq0KV,iEiD55KA,iEjD05KA,iEDtBC,iEC6BC,cAAe,EAEjB,8CiDn0KU,8CjDq0KV,8CiDr6KA,8CjDo6KA,gEDtBC,gECwBD,gEiDh0KI,gEACA,cAAA,EAUJ,yBACE,cAAA,ElDmyKD,OAAA,EkD/xKG,aACA,cAAA,KANJ,oBASM,cAAA,ElDkyKL,cAAA,IkD7xKG,2BlDgyKH,WAAA,IC4BD,4BiDxzKM,cAAA,EAKF,wDAvBJ,wDlDqzKC,WAAA,IAAA,MAAA,KkD5xKK,2BlD+xKL,WAAA,EmDlhLC,uDnDqhLD,cAAA,IAAA,MAAA,KmDlhLG,eACA,aAAA,KnDshLH,8BmDxhLC,MAAA,KAMI,iBAAA,QnDqhLL,aAAA,KmDlhLK,0DACA,iBAAA,KAGJ,qCAEI,MAAA,QnDmhLL,iBAAA,KmDpiLC,yDnDuiLD,oBAAA,KmDpiLG,eACA,aAAA,QnDwiLH,8BmD1iLC,MAAA,KAMI,iBAAA,QnDuiLL,aAAA,QmDpiLK,0DACA,iBAAA,QAGJ,qCAEI,MAAA,QnDqiLL,iBAAA,KmDtjLC,yDnDyjLD,oBAAA,QmDtjLG,eACA,aAAA,QnD0jLH,8BmD5jLC,MAAA,QAMI,iBAAA,QnDyjLL,aAAA,QmDtjLK,0DACA,iBAAA,QAGJ,qCAEI,MAAA,QnDujLL,iBAAA,QmDxkLC,yDnD2kLD,oBAAA,QmDxkLG,YACA,aAAA,QnD4kLH,2BmD9kLC,MAAA,QAMI,iBAAA,QnD2kLL,aAAA,QmDxkLK,uDACA,iBAAA,QAGJ,kCAEI,MAAA,QnDykLL,iBAAA,QmD1lLC,sDnD6lLD,oBAAA,QmD1lLG,eACA,aAAA,QnD8lLH,8BmDhmLC,MAAA,QAMI,iBAAA,QnD6lLL,aAAA,QmD1lLK,0DACA,iBAAA,QAGJ,qCAEI,MAAA,QnD2lLL,iBAAA,QmD5mLC,yDnD+mLD,oBAAA,QmD5mLG,cACA,aAAA,QnDgnLH,6BmDlnLC,MAAA,QAMI,iBAAA,QnD+mLL,aAAA,QmD5mLK,yDACA,iBAAA,QAGJ,oCAEI,MAAA,QnD6mLL,iBAAA,QoD5nLC,wDACA,oBAAA,QAEA,kBACA,SAAA,SpD+nLD,QAAA,MoDpoLC,OAAQ,EnDgqLR,QAAS,EACT,SAAU,OAEZ,yCmDtpLI,wBADA,yBAEA,yBACA,wBACA,SAAA,SACA,IAAA,EACA,OAAA,EpD+nLH,KAAA,EoD1nLC,MAAO,KACP,OAAA,KpD4nLD,OAAA,EoDvnLC,wBpD0nLD,eAAA,OqDppLC,uBACA,eAAA,IAEA,MACA,WAAA,KACA,QAAA,KjDwDA,cAAA,KACQ,iBAAA,QJgmLT,OAAA,IAAA,MAAA,QqD/pLC,cAAe,IASb,mBAAA,MAAA,EAAA,IAAA,IAAA,gBACA,WAAA,MAAA,EAAA,IAAA,IAAA,gBAKJ,iBACE,aAAA,KACA,aAAA,gBAEF,SACE,QAAA,KACA,cAAA,ICtBF,SACE,QAAA,IACA,cAAA,IAEA,OACA,MAAA,MACA,UAAA,KjCRA,YAAA,IAGA,YAAA,ErBqrLD,MAAA,KsD7qLC,YAAA,EAAA,IAAA,EAAA,KrDysLA,OAAQ,kBqDvsLN,QAAA,GjCbF,aiCeE,ajCZF,MAAA,KrB6rLD,gBAAA,KsDzqLC,OAAA,QACE,OAAA,kBACA,QAAA,GAEA,aACA,mBAAA,KtD2qLH,QAAA,EuDhsLC,OAAQ,QACR,WAAA,IvDksLD,OAAA,EuD7rLC,YACA,SAAA,OAEA,OACA,SAAA,MACA,IAAA,EACA,MAAA,EACA,OAAA,EACA,KAAA,EAIA,QAAA,KvD6rLD,QAAA,KuD1rLC,SAAA,OnD+GA,2BAAA,MACI,QAAA,EAEI,0BAkER,mBAAA,kBAAA,IAAA,SAEK,cAAA,aAAA,IAAA,SACG,WAAA,UAAA,IAAA,SJ6gLT,kBAAA,kBuDhsLC,cAAA,kBnD2GA,aAAA,kBACI,UAAA,kBAEI,wBJwlLT,kBAAA,euDpsLK,cAAe,eACnB,aAAA,eACA,UAAA,eAIF,mBACE,WAAA,OACA,WAAA,KvDqsLD,cuDhsLC,SAAU,SACV,MAAA,KACA,OAAA,KAEA,eACA,SAAA,SnDaA,iBAAA,KACQ,wBAAA,YmDZR,gBAAA,YtD4tLA,OsD5tLA,IAAA,MAAA,KAEA,OAAA,IAAA,MAAA,evDksLD,cAAA,IuD9rLC,QAAS,EACT,mBAAA,EAAA,IAAA,IAAA,eACA,WAAA,EAAA,IAAA,IAAA,eAEA,gBACA,SAAA,MACA,IAAA,EACA,MAAA,EvDgsLD,OAAA,EuD9rLC,KAAA,ElCrEA,QAAA,KAGA,iBAAA,KkCmEA,qBlCtEA,OAAA,iBAGA,QAAA,EkCwEF,mBACE,OAAA,kBACA,QAAA,GAIF,cACE,QAAA,KvDgsLD,cAAA,IAAA,MAAA,QuD3rLC,qBACA,WAAA,KAKF,aACE,OAAA,EACA,YAAA,WAIF,YACE,SAAA,SACA,QAAA,KvD0rLD,cuD5rLC,QAAS,KAQP,WAAA,MACA,WAAA,IAAA,MAAA,QATJ,wBAaI,cAAA,EvDsrLH,YAAA,IuDlrLG,mCvDqrLH,YAAA,KuD/qLC,oCACA,YAAA,EAEA,yBACA,SAAA,SvDkrLD,IAAA,QuDhqLC,MAAO,KAZP,OAAA,KACE,SAAA,OvDgrLD,yBuD7qLD,cnDvEA,MAAA,MACQ,OAAA,KAAA,KmD2ER,eAAY,mBAAA,EAAA,IAAA,KAAA,evD+qLX,WAAA,EAAA,IAAA,KAAA,euDzqLD,UAFA,MAAA,OvDirLD,yBwD/zLC,UACA,MAAA,OCNA,SAEA,SAAA,SACA,QAAA,KACA,QAAA,MACA,YAAA,iBAAA,UAAA,MAAA,WACA,UAAA,KACA,WAAA,OACA,YAAA,IACA,YAAA,WACA,WAAA,KACA,WAAA,MACA,gBAAA,KACA,YAAA,KACA,eAAA,KACA,eAAA,ODHA,WAAA,OnCVA,aAAA,OAGA,UAAA,OrBs1LD,YAAA,OwD30LC,OAAA,iBnCdA,QAAA,ErB61LD,WAAA,KwD90LY,YAAmB,OAAA,kBxDk1L/B,QAAA,GwDj1LY,aAAmB,QAAA,IAAA,ExDq1L/B,WAAA,KwDp1LY,eAAmB,QAAA,EAAA,IxDw1L/B,YAAA,IwDv1LY,gBAAmB,QAAA,IAAA,ExD21L/B,WAAA,IwDt1LC,cACA,QAAA,EAAA,IACA,YAAA,KAEA,eACA,UAAA,MxDy1LD,QAAA,IAAA,IwDr1LC,MAAO,KACP,WAAA,OACA,iBAAA,KACA,cAAA,IAEA,exDu1LD,SAAA,SwDn1LC,MAAA,EACE,OAAA,EACA,aAAA,YACA,aAAA,MAEA,4BxDq1LH,OAAA,EwDn1LC,KAAA,IACE,YAAA,KACA,aAAA,IAAA,IAAA,EACA,iBAAA,KAEA,iCxDq1LH,MAAA,IwDn1LC,OAAA,EACE,cAAA,KACA,aAAA,IAAA,IAAA,EACA,iBAAA,KAEA,kCxDq1LH,OAAA,EwDn1LC,KAAA,IACE,cAAA,KACA,aAAA,IAAA,IAAA,EACA,iBAAA,KAEA,8BxDq1LH,IAAA,IwDn1LC,KAAA,EACE,WAAA,KACA,aAAA,IAAA,IAAA,IAAA,EACA,mBAAA,KAEA,6BxDq1LH,IAAA,IwDn1LC,MAAA,EACE,WAAA,KACA,aAAA,IAAA,EAAA,IAAA,IACA,kBAAA,KAEA,+BxDq1LH,IAAA,EwDn1LC,KAAA,IACE,YAAA,KACA,aAAA,EAAA,IAAA,IACA,oBAAA,KAEA,oCxDq1LH,IAAA,EwDn1LC,MAAA,IACE,WAAA,KACA,aAAA,EAAA,IAAA,IACA,oBAAA,KAEA,qCxDq1LH,IAAA,E0Dl7LC,KAAM,IACN,WAAA,KACA,aAAA,EAAA,IAAA,IACA,oBAAA,KAEA,SACA,SAAA,SACA,IAAA,EDXA,KAAA,EAEA,QAAA,KACA,QAAA,KACA,UAAA,MACA,QAAA,IACA,YAAA,iBAAA,UAAA,MAAA,WACA,UAAA,KACA,WAAA,OACA,YAAA,IACA,YAAA,WACA,WAAA,KACA,WAAA,MACA,gBAAA,KACA,YAAA,KACA,eAAA,KCAA,eAAA,OAEA,WAAA,OACA,aAAA,OAAA,UAAA,OACA,YAAA,OACA,iBAAA,KACA,wBAAA,YtD8CA,gBAAA,YACQ,OAAA,IAAA,MAAA,KJk5LT,OAAA,IAAA,MAAA,e0D77LC,cAAA,IAAY,mBAAA,EAAA,IAAA,KAAA,e1Dg8Lb,WAAA,EAAA,IAAA,KAAA,e0D/7La,WAAA,KACZ,aAAY,WAAA,MACZ,eAAY,YAAA,KAGd,gBACE,WAAA,KAEA,cACA,YAAA,MAEA,e1Dq8LD,QAAA,IAAA,K0Dl8LC,OAAQ,EACR,UAAA,K1Do8LD,iBAAA,Q0D57LC,cAAA,IAAA,MAAA,QzDy9LA,cAAe,IAAI,IAAI,EAAE,EyDt9LvB,iBACA,QAAA,IAAA,KAEA,gBACA,sB1D87LH,SAAA,S0D37LC,QAAS,MACT,MAAA,E1D67LD,OAAA,E0D37LC,aAAc,YACd,aAAA,M1D87LD,gB0Dz7LC,aAAA,KAEE,sBACA,QAAA,GACA,aAAA,KAEA,oB1D27LH,OAAA,M0D17LG,KAAA,IACE,YAAA,MACA,iBAAA,KACA,iBAAA,gBACA,oBAAA,E1D67LL,0B0Dz7LC,OAAA,IACE,YAAA,MACA,QAAA,IACA,iBAAA,KACA,oBAAA,EAEA,sB1D27LH,IAAA,I0D17LG,KAAA,MACE,WAAA,MACA,mBAAA,KACA,mBAAA,gBACA,kBAAA,E1D67LL,4B0Dz7LC,OAAA,MACE,KAAA,IACA,QAAA,IACA,mBAAA,KACA,kBAAA,EAEA,uB1D27LH,IAAA,M0D17LG,KAAA,IACE,YAAA,MACA,iBAAA,EACA,oBAAA,KACA,oBAAA,gB1D67LL,6B0Dx7LC,IAAA,IACE,YAAA,MACA,QAAA,IACA,iBAAA,EACA,oBAAA,KAEA,qB1D07LH,IAAA,I0Dz7LG,MAAA,MACE,WAAA,MACA,mBAAA,EACA,kBAAA,KACA,kBAAA,gB1D47LL,2B2DpjMC,MAAO,IACP,OAAA,M3DsjMD,QAAA,I2DnjMC,mBAAoB,EACpB,kBAAA,KAEA,U3DqjMD,SAAA,S2DljMG,gBACA,SAAA,SvD6KF,MAAA,KACK,SAAA,OJ04LN,sB2D/jMC,SAAU,S1D4lMV,QAAS,K0D9kML,mBAAA,IAAA,YAAA,K3DqjML,cAAA,IAAA,YAAA,K2D3hMC,WAAA,IAAA,YAAA,KvDmKK,4BAFL,0BAGQ,YAAA,EA3JA,qDA+GR,sBAEQ,mBAAA,kBAAA,IAAA,YJ86LP,cAAA,aAAA,IAAA,Y2DzjMG,WAAA,UAAA,IAAA,YvDmHJ,4BAAA,OACQ,oBAAA,OuDjHF,oBAAA,O3D4jML,YAAA,OI58LD,mCHs+LA,2BGr+LQ,KAAA,EuD5GF,kBAAA,sB3D6jML,UAAA,sBC2BD,kCADA,2BG5+LA,KAAA,EACQ,kBAAA,uBuDtGF,UAAA,uBArCN,6B3DomMD,gC2DpmMC,iC1D+nME,KAAM,E0DllMN,kBAAA,mB3D4jMH,UAAA,oBAGA,wB2D5mMD,sBAAA,sBAsDI,QAAA,MAEA,wB3D0jMH,KAAA,E2DtjMG,sB3DyjMH,sB2DrnMC,SAAU,SA+DR,IAAA,E3DyjMH,MAAA,KC0BD,sB0D/kMI,KAAA,KAnEJ,sBAuEI,KAAA,MAvEJ,2BA0EI,4B3DwjMH,KAAA,E2D/iMC,6BACA,KAAA,MAEA,8BACA,KAAA,KtC3FA,kBsC6FA,SAAA,SACA,IAAA,EACA,OAAA,EACA,KAAA,EACA,MAAA,I3DmjMD,UAAA,K2D9iMC,MAAA,KdnGE,WAAA,OACA,YAAA,EAAA,IAAA,IAAA,eACA,iBAAA,cAAA,OAAA,kBACA,QAAA,G7CqpMH,uB2DljMC,iBAAA,sEACE,iBAAA,iEACA,iBAAA,uFdxGA,iBAAA,kEACA,OAAA,+GACA,kBAAA,SACA,wBACA,MAAA,E7C6pMH,KAAA,K2DpjMC,iBAAA,sE1DglMA,iBAAiB,iE0D9kMf,iBAAA,uFACA,iBAAA,kEACA,OAAA,+GtCvHF,kBAAA,SsCyFF,wB3DslMC,wBC4BC,MAAO,KACP,gBAAiB,KACjB,OAAQ,kB0D7kMN,QAAA,EACA,QAAA,G3DwjMH,0C2DhmMD,2CA2CI,6BADA,6B1DklMF,SAAU,S0D7kMR,IAAA,IACA,QAAA,E3DqjMH,QAAA,a2DrmMC,WAAY,MAqDV,0CADA,6B3DsjMH,KAAA,I2D1mMC,YAAa,MA0DX,2CADA,6BAEA,MAAA,IACA,aAAA,MAME,6BADF,6B3DmjMH,MAAA,K2D9iMG,OAAA,KACE,YAAA,M3DgjML,YAAA,E2DriMC,oCACA,QAAA,QAEA,oCACA,QAAA,QAEA,qBACA,SAAA,SACA,OAAA,K3DwiMD,KAAA,I2DjjMC,QAAS,GAYP,MAAA,IACA,aAAA,EACA,YAAA,KACA,WAAA,OACA,WAAA,KAEA,wBACA,QAAA,aAWA,MAAA,KACA,OAAA,K3D8hMH,OAAA,I2D7jMC,YAAa,OAkCX,OAAA,QACA,iBAAA,OACA,iBAAA,cACA,OAAA,IAAA,MAAA,K3D8hMH,cAAA,K2DthMC,6BACA,MAAA,KACA,OAAA,KACA,OAAA,EACA,iBAAA,KAEA,kBACA,SAAA,SACA,MAAA,IACA,OAAA,K3DyhMD,KAAA,I2DxhMC,QAAA,GACE,YAAA,K3D0hMH,eAAA,K2Dj/LC,MAAO,KAhCP,WAAA,O1D8iMA,YAAa,EAAE,IAAI,IAAI,eAEzB,uB0D3iMM,YAAA,KAEA,oCACA,0C3DmhMH,2C2D3hMD,6BAAA,6BAYI,MAAA,K3DmhMH,OAAA,K2D/hMD,WAAA,M1D2jME,UAAW,KDxBZ,0C2D9gMD,6BACE,YAAA,MAEA,2C3DghMD,6B2D5gMD,aAAA,M3D+gMC,kBACF,MAAA,I4D7wMC,KAAA,I3DyyME,eAAgB,KAElB,qBACE,OAAQ,MAkBZ,qCADA,sCADA,mBADA,oBAXA,gBADA,iBAOA,uBADA,wBADA,iBADA,kBADA,wBADA,yBASA,mCADA,oC2DpzME,oBAAA,qBAAA,oBAAA,qB3D2zMF,WADA,YAOA,uBADA,wBADA,qBADA,sBADA,cADA,e2D/zMI,a3Dq0MJ,cDvBC,kB4D7yMG,mB3DqzMJ,WADA,YAwBE,QAAS,MACT,QAAS,IASX,qCADA,mBANA,gBAGA,uBADA,iBADA,wBAIA,mCDhBC,oB6D/0MC,oB5Dk2MF,W+B51MA,uBhCo0MC,qB4D5zMG,cChBF,aACA,kB5D+1MF,W+Br1ME,MAAO,KhCy0MR,cgCt0MC,QAAS,MACT,aAAA,KhCw0MD,YAAA,KgC/zMC,YhCk0MD,MAAA,gBgC/zMC,WhCk0MD,MAAA,egC/zMC,MhCk0MD,QAAA,e8Dz1MC,MACA,QAAA,gBAEA,WACA,WAAA,O9B8BF,WACE,KAAA,EAAA,EAAA,EhCg0MD,MAAA,YgCzzMC,YAAa,KACb,iBAAA,YhC2zMD,OAAA,E+D31MC,Q/D81MD,QAAA,eC4BD,OACE,SAAU,M+Dn4MV,chE42MD,MAAA,aC+BD,YADA,YADA,YADA,YAIE,QAAS,e+Dp5MT,kBhEs4MC,mBgEr4MD,yBhEi4MD,kB+Dl1MD,mBA6IA,yB9D4tMA,kBACA,mB8Dj3ME,yB9D62MF,kBACA,mBACA,yB+Dv5MY,QAAA,eACV,yBAAU,YhE04MT,QAAA,gBC4BD,iB+Dp6MU,QAAA,gBhE64MX,c+D51MG,QAAS,oB/Dg2MV,c+Dl2MC,c/Dm2MH,QAAA,sB+D91MG,yB/Dk2MD,kBACF,QAAA,iB+D91MG,yB/Dk2MD,mBACF,QAAA,kBgEh6MC,yBhEo6MC,yBgEn6MD,QAAA,wBACA,+CAAU,YhEw6MT,QAAA,gBC4BD,iB+Dl8MU,QAAA,gBhE26MX,c+Dr2MG,QAAS,oB/Dy2MV,c+D32MC,c/D42MH,QAAA,sB+Dv2MG,+C/D22MD,kBACF,QAAA,iB+Dv2MG,+C/D22MD,mBACF,QAAA,kBgE97MC,+ChEk8MC,yBgEj8MD,QAAA,wBACA,gDAAU,YhEs8MT,QAAA,gBC4BD,iB+Dh+MU,QAAA,gBhEy8MX,c+D92MG,QAAS,oB/Dk3MV,c+Dp3MC,c/Dq3MH,QAAA,sB+Dh3MG,gD/Do3MD,kBACF,QAAA,iB+Dh3MG,gD/Do3MD,mBACF,QAAA,kBgE59MC,gDhEg+MC,yBgE/9MD,QAAA,wBACA,0BAAU,YhEo+MT,QAAA,gBC4BD,iB+D9/MU,QAAA,gBhEu+MX,c+Dv3MG,QAAS,oB/D23MV,c+D73MC,c/D83MH,QAAA,sB+Dz3MG,0B/D63MD,kBACF,QAAA,iB+Dz3MG,0B/D63MD,mBACF,QAAA,kBgEl/MC,0BhEs/MC,yBACF,QAAA,wBgEv/MC,yBhE2/MC,WACF,QAAA,gBgE5/MC,+ChEggNC,WACF,QAAA,gBgEjgNC,gDhEqgNC,WACF,QAAA,gBAGA,0B+Dh3MC,WA4BE,QAAS,gBC5LX,eAAU,QAAA,eACV,aAAU,ehEyhNT,QAAA,gBC4BD,oB+DnjNU,QAAA,gBhE4hNX,iB+D93MG,QAAS,oBAMX,iB/D23MD,iB+Dt2MG,QAAS,sB/D22MZ,qB+D/3MC,QAAS,e/Dk4MV,a+D53MC,qBAcE,QAAS,iB/Dm3MZ,sB+Dh4MC,QAAS,e/Dm4MV,a+D73MC,sBAOE,QAAS,kB/D23MZ,4B+D53MC,QAAS,eCpLT,ahEojNC,4BACF,QAAA,wBC6BD,aACE,cACE,QAAS","sourcesContent":["/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n// without disabling user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n box-shadow: none !important;\n text-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n}\n","/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), 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');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n background-color: #fcf8e3;\n padding: .2em;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333333;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n.row {\n margin-left: -15px;\n margin-right: -15px;\n}\n.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 {\n position: relative;\n min-height: 1px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.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 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .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 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .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 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .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 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n min-width: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n border: 0;\n background-color: transparent;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n min-height: 34px;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-left: 0;\n padding-right: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n border-color: #3c763d;\n background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n border-color: #8a6d3b;\n background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n border-color: #a94442;\n background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-left: -15px;\n margin-right: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: 7px;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n white-space: nowrap;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n outline: 0;\n background-image: none;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n opacity: 0.65;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n color: #337ab7;\n font-weight: normal;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n text-align: left;\n background-color: #fff;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n left: auto;\n right: 0;\n}\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n left: auto;\n right: 0;\n }\n .navbar-right .dropdown-menu-left {\n left: 0;\n right: auto;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n margin-bottom: 0;\n padding-left: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n cursor: default;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n overflow-x: visible;\n padding-right: 15px;\n padding-left: 15px;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-left: 0;\n padding-right: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: 15px;\n padding: 9px 10px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n margin-left: -15px;\n margin-right: -15px;\n padding: 10px 15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-left: 15px;\n margin-right: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n background-color: #e7e7e7;\n color: #555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n background-color: #080808;\n color: #fff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n content: \"/\\00a0\";\n padding: 0 5px;\n color: #ccc;\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n line-height: 1.42857143;\n text-decoration: none;\n color: #337ab7;\n background-color: #fff;\n border: 1px solid #ddd;\n margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-bottom-left-radius: 4px;\n border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-bottom-right-radius: 4px;\n border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n background-color: #fff;\n border-color: #ddd;\n cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-bottom-left-radius: 3px;\n border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n list-style: none;\n text-align: center;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n background-color: #fff;\n cursor: not-allowed;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n color: #fff;\n line-height: 1;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-left: 60px;\n padding-right: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-left: auto;\n margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n background-color: #dff0d8;\n border-color: #d6e9c6;\n color: #3c763d;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n background-color: #d9edf7;\n border-color: #bce8f1;\n color: #31708f;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n background-color: #fcf8e3;\n border-color: #faebcc;\n color: #8a6d3b;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n background-color: #f2dede;\n border-color: #ebccd1;\n color: #a94442;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n overflow: hidden;\n height: 20px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n 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);\n 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);\n 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);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n 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);\n 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);\n 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);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n 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);\n 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);\n 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);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n 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);\n 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);\n 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);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n 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);\n 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);\n 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);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n margin-bottom: 20px;\n padding-left: 0;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n text-decoration: none;\n color: #555;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n background-color: #eeeeee;\n color: #777777;\n cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-left: 15px;\n padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n border: 0;\n margin-bottom: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 12px;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.tooltip.in {\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.tooltip.top {\n margin-top: -3px;\n padding: 5px 0;\n}\n.tooltip.right {\n margin-left: 3px;\n padding: 0 5px;\n}\n.tooltip.bottom {\n margin-top: 3px;\n padding: 5px 0;\n}\n.tooltip.left {\n margin-left: -3px;\n padding: 0 5px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n bottom: 0;\n right: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 14px;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n margin: 0;\n padding: 8px 14px;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n border-width: 10px;\n content: \"\";\n}\n.popover.top > .arrow {\n left: 50%;\n margin-left: -11px;\n border-bottom-width: 0;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n bottom: -11px;\n}\n.popover.top > .arrow:after {\n content: \" \";\n bottom: 1px;\n margin-left: -10px;\n border-bottom-width: 0;\n border-top-color: #fff;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-left-width: 0;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n content: \" \";\n left: 1px;\n bottom: -10px;\n border-left-width: 0;\n border-right-color: #fff;\n}\n.popover.bottom > .arrow {\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n top: -11px;\n}\n.popover.bottom > .arrow:after {\n content: \" \";\n top: 1px;\n margin-left: -10px;\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: #fff;\n bottom: -10px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n}\n.carousel-inner > .item {\n display: none;\n position: relative;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n -moz-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 15%;\n opacity: 0.5;\n filter: alpha(opacity=50);\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n left: auto;\n right: 0;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n outline: 0;\n color: #fff;\n text-decoration: none;\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid #fff;\n border-radius: 10px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n content: \" \";\n display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n margin: .67em 0;\n font-size: 2em;\n}\nmark {\n color: #000;\n background: #ff0;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\nsup {\n top: -.5em;\n}\nsub {\n bottom: -.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n height: 0;\n -webkit-box-sizing: content-box;\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n margin: 0;\n font: inherit;\n color: inherit;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n padding: 0;\n border: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: content-box;\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n -webkit-appearance: textfield;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n padding: .35em .625em .75em;\n margin: 0 2px;\n border: 1px solid #c0c0c0;\n}\nlegend {\n padding: 0;\n border: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-spacing: 0;\n border-collapse: collapse;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n color: #000 !important;\n text-shadow: none !important;\n background: transparent !important;\n -webkit-box-shadow: none !important;\n box-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), 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');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n display: inline-block;\n max-width: 100%;\n height: auto;\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all .2s ease-in-out;\n -o-transition: all .2s ease-in-out;\n transition: all .2s ease-in-out;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n padding: .2em;\n background-color: #fcf8e3;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n margin-left: -5px;\n list-style: none;\n}\n.list-inline > li {\n display: inline-block;\n padding-right: 5px;\n padding-left: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n overflow: hidden;\n clear: left;\n text-align: right;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n text-align: right;\n border-right: 5px solid #eee;\n border-left: 0;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n color: #333;\n word-break: break-all;\n word-wrap: break-word;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n.row {\n margin-right: -15px;\n margin-left: -15px;\n}\n.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 {\n position: relative;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n.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 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .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 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0;\n }\n}\n@media (min-width: 992px) {\n .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 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0;\n }\n}\n@media (min-width: 1200px) {\n .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 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n display: table-column;\n float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n display: table-cell;\n float: none;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n min-height: .01%;\n overflow-x: auto;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-top: 4px \\9;\n margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n vertical-align: middle;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n min-height: 34px;\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-right: 0;\n padding-left: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #3c763d;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #8a6d3b;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n background-color: #f2dede;\n border-color: #a94442;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n padding-top: 7px;\n margin-top: 0;\n margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n padding-top: 7px;\n margin-bottom: 0;\n text-align: right;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n padding: 6px 12px;\n margin-bottom: 0;\n font-size: 14px;\n font-weight: normal;\n line-height: 1.42857143;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n -ms-touch-action: manipulation;\n touch-action: manipulation;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n outline: 0;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n opacity: .65;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n font-weight: normal;\n color: #337ab7;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity .15s linear;\n -o-transition: opacity .15s linear;\n transition: opacity .15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-timing-function: ease;\n -o-transition-timing-function: ease;\n transition-timing-function: ease;\n -webkit-transition-duration: .35s;\n -o-transition-duration: .35s;\n transition-duration: .35s;\n -webkit-transition-property: height, visibility;\n -o-transition-property: height, visibility;\n transition-property: height, visibility;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n font-size: 14px;\n text-align: left;\n list-style: none;\n background-color: #fff;\n -webkit-background-clip: padding-box;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, .15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n color: #262626;\n text-decoration: none;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n background-color: #337ab7;\n outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n content: \"\";\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n right: 0;\n left: auto;\n }\n .navbar-right .dropdown-menu-left {\n right: auto;\n left: 0;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-right: 8px;\n padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-right: 12px;\n padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n display: table-cell;\n float: none;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-right: 0;\n padding-left: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555;\n text-align: center;\n background-color: #eee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eee;\n}\n.nav > li.disabled > a {\n color: #777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777;\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eee #eee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555;\n cursor: default;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n padding-right: 15px;\n padding-left: 15px;\n overflow-x: visible;\n -webkit-overflow-scrolling: touch;\n border-top: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-right: 0;\n padding-left: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n height: 50px;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n padding: 9px 10px;\n margin-top: 8px;\n margin-right: 15px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n padding: 10px 15px;\n margin-top: 8px;\n margin-right: -15px;\n margin-bottom: 8px;\n margin-left: -15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n padding-top: 0;\n padding-bottom: 0;\n margin-right: 0;\n margin-left: 0;\n border: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-right: 15px;\n margin-left: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n color: #fff;\n background-color: #080808;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n padding: 0 5px;\n color: #ccc;\n content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n color: #777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n margin-left: -1px;\n line-height: 1.42857143;\n color: #337ab7;\n text-decoration: none;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-top-left-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-top-right-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eee;\n border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n cursor: default;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777;\n cursor: not-allowed;\n background-color: #fff;\n border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-top-left-radius: 6px;\n border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n text-align: center;\n list-style: none;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777;\n cursor: not-allowed;\n background-color: #fff;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n background-color: #777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n padding-right: 15px;\n padding-left: 15px;\n border-radius: 6px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-right: 60px;\n padding-left: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border .2s ease-in-out;\n -o-transition: border .2s ease-in-out;\n transition: border .2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-right: auto;\n margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@-o-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n height: 20px;\n margin-bottom: 20px;\n overflow: hidden;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n}\n.progress-bar {\n float: left;\n width: 0;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n -webkit-transition: width .6s ease;\n -o-transition: width .6s ease;\n transition: width .6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n -webkit-background-size: 40px 40px;\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n overflow: hidden;\n zoom: 1;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n padding-left: 0;\n margin-bottom: 20px;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n color: #555;\n text-decoration: none;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n color: #777;\n cursor: not-allowed;\n background-color: #eee;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-right: 15px;\n padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n margin-bottom: 0;\n border: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, .15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n filter: alpha(opacity=20);\n opacity: .2;\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n filter: alpha(opacity=50);\n opacity: .5;\n}\nbutton.close {\n -webkit-appearance: none;\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n display: none;\n overflow: hidden;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transition: -webkit-transform .3s ease-out;\n -o-transition: -o-transform .3s ease-out;\n transition: transform .3s ease-out;\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n -webkit-background-clip: padding-box;\n background-clip: padding-box;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, .2);\n border-radius: 6px;\n outline: 0;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n filter: alpha(opacity=0);\n opacity: 0;\n}\n.modal-backdrop.in {\n filter: alpha(opacity=50);\n opacity: .5;\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-bottom: 0;\n margin-left: 5px;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 12px;\n font-style: normal;\n font-weight: normal;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n white-space: normal;\n filter: alpha(opacity=0);\n opacity: 0;\n\n line-break: auto;\n}\n.tooltip.in {\n filter: alpha(opacity=90);\n opacity: .9;\n}\n.tooltip.top {\n padding: 5px 0;\n margin-top: -3px;\n}\n.tooltip.right {\n padding: 0 5px;\n margin-left: 3px;\n}\n.tooltip.bottom {\n padding: 5px 0;\n margin-top: 3px;\n}\n.tooltip.left {\n padding: 0 5px;\n margin-left: -3px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n right: 5px;\n bottom: 0;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n font-style: normal;\n font-weight: normal;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n white-space: normal;\n background-color: #fff;\n -webkit-background-clip: padding-box;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, .2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n\n line-break: auto;\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n padding: 8px 14px;\n margin: 0;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n content: \"\";\n border-width: 10px;\n}\n.popover.top > .arrow {\n bottom: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-color: #999;\n border-top-color: rgba(0, 0, 0, .25);\n border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n bottom: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-color: #fff;\n border-bottom-width: 0;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-right-color: #999;\n border-right-color: rgba(0, 0, 0, .25);\n border-left-width: 0;\n}\n.popover.right > .arrow:after {\n bottom: -10px;\n left: 1px;\n content: \" \";\n border-right-color: #fff;\n border-left-width: 0;\n}\n.popover.bottom > .arrow {\n top: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999;\n border-bottom-color: rgba(0, 0, 0, .25);\n}\n.popover.bottom > .arrow:after {\n top: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999;\n border-left-color: rgba(0, 0, 0, .25);\n}\n.popover.left > .arrow:after {\n right: 1px;\n bottom: -10px;\n content: \" \";\n border-right-width: 0;\n border-left-color: #fff;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n.carousel-inner > .item {\n position: relative;\n display: none;\n -webkit-transition: .6s ease-in-out left;\n -o-transition: .6s ease-in-out left;\n transition: .6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform .6s ease-in-out;\n -o-transition: -o-transform .6s ease-in-out;\n transition: transform .6s ease-in-out;\n\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n left: 0;\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n left: 0;\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n left: 0;\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 15%;\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n background-color: rgba(0, 0, 0, 0);\n filter: alpha(opacity=50);\n opacity: .5;\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));\n background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control.right {\n right: 0;\n left: auto;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));\n background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n color: #fff;\n text-decoration: none;\n filter: alpha(opacity=90);\n outline: 0;\n opacity: .9;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n margin-top: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n font-family: serif;\n line-height: 1;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n padding-left: 0;\n margin-left: -30%;\n text-align: center;\n list-style: none;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n border: 1px solid #fff;\n border-radius: 10px;\n}\n.carousel-indicators .active {\n width: 12px;\n height: 12px;\n margin: 0;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n right: 20%;\n left: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n display: table;\n content: \" \";\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-right: auto;\n margin-left: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n//
Star\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\002a\"; } }\n.glyphicon-plus { &:before { content: \"\\002b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-btc { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n cursor: pointer;\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // WebKit-specific. Other browsers will keep their default outline style.\n // (Initially tried to also force default via `outline: initial`,\n // but that seems to erroneously remove the outline in Firefox altogether.)\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @dl-horizontal-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover,\n a&:focus {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover,\n a&:focus {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: floor((@gutter / 2));\n padding-right: ceil((@gutter / 2));\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: ceil((@gutter / -2));\n margin-right: floor((@gutter / -2));\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: ceil((@grid-gutter-width / 2));\n padding-right: floor((@grid-gutter-width / 2));\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius; // Note: This has no effect on
s in some browsers, due to the limited stylability of s in CSS.\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Unstyle the caret on ``s in IE10+.\n &::-ms-expand {\n border: 0;\n background-color: transparent;\n }\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &[disabled],\n &[readonly],\n fieldset[disabled] & {\n background-color: @input-bg-disabled;\n opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655\n }\n\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n\n // Reset height for `textarea`s\n textarea& {\n height: auto;\n }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n\n\n// Special styles for iOS temporal inputs\n//\n// In Mobile Safari, setting `display: block` on temporal inputs causes the\n// text within the input to become vertically misaligned. As a workaround, we\n// set a pixel line-height that matches the given height of the input, but only\n// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848\n//\n// Note that as of 9.3, iOS doesn't support `week`.\n\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"],\n input[type=\"time\"],\n input[type=\"datetime-local\"],\n input[type=\"month\"] {\n &.form-control {\n line-height: @input-height-base;\n }\n\n &.input-sm,\n .input-group-sm & {\n line-height: @input-height-small;\n }\n\n &.input-lg,\n .input-group-lg & {\n line-height: @input-height-large;\n }\n }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: @form-group-margin-bottom;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n\n label {\n min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n// Some special care is needed because s don't inherit their parent's `cursor`.\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n &[disabled],\n &.disabled,\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n}\n// These classes are used directly on s\n.radio-inline,\n.checkbox-inline {\n &.disabled,\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n}\n// These classes are used on elements with descendants\n.radio,\n.checkbox {\n &.disabled,\n fieldset[disabled] & {\n label {\n cursor: @cursor-disabled;\n }\n }\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n // Size it appropriately next to real form controls\n padding-top: (@padding-base-vertical + 1);\n padding-bottom: (@padding-base-vertical + 1);\n // Remove default margin from `p`\n margin-bottom: 0;\n min-height: (@line-height-computed + @font-size-base);\n\n &.input-lg,\n &.input-sm {\n padding-left: 0;\n padding-right: 0;\n }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// The `.form-group-* form-control` variations are sadly duplicated to avoid the\n// issue documented in https://github.com/twbs/bootstrap/issues/15074.\n\n.input-sm {\n .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small);\n}\n.form-group-sm {\n .form-control {\n height: @input-height-small;\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n line-height: @line-height-small;\n border-radius: @input-border-radius-small;\n }\n select.form-control {\n height: @input-height-small;\n line-height: @input-height-small;\n }\n textarea.form-control,\n select[multiple].form-control {\n height: auto;\n }\n .form-control-static {\n height: @input-height-small;\n min-height: (@line-height-computed + @font-size-small);\n padding: (@padding-small-vertical + 1) @padding-small-horizontal;\n font-size: @font-size-small;\n line-height: @line-height-small;\n }\n}\n\n.input-lg {\n .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large);\n}\n.form-group-lg {\n .form-control {\n height: @input-height-large;\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-large;\n border-radius: @input-border-radius-large;\n }\n select.form-control {\n height: @input-height-large;\n line-height: @input-height-large;\n }\n textarea.form-control,\n select[multiple].form-control {\n height: auto;\n }\n .form-control-static {\n height: @input-height-large;\n min-height: (@line-height-computed + @font-size-large);\n padding: (@padding-large-vertical + 1) @padding-large-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-large;\n }\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n.has-feedback {\n // Enable absolute positioning\n position: relative;\n\n // Ensure icons don't overlap text\n .form-control {\n padding-right: (@input-height-base * 1.25);\n }\n}\n// Feedback icon (requires .glyphicon classes)\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2; // Ensure icon is above input groups\n display: block;\n width: @input-height-base;\n height: @input-height-base;\n line-height: @input-height-base;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: @input-height-large;\n height: @input-height-large;\n line-height: @input-height-large;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: @input-height-small;\n height: @input-height-small;\n line-height: @input-height-small;\n}\n\n// Feedback states\n.has-success {\n .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n.has-warning {\n .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n.has-error {\n .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n\n// Reposition feedback icon if input has visible label above\n.has-feedback label {\n\n & ~ .form-control-feedback {\n top: (@line-height-computed + 5); // Height of the `label` and its margin\n }\n &.sr-only ~ .form-control-feedback {\n top: 0;\n }\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n display: block; // account for any element using help-block\n margin-top: 5px;\n margin-bottom: 10px;\n color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n // Kick in the inline\n @media (min-width: @screen-sm-min) {\n // Inline-block all the things for \"inline\"\n .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n\n // In navbar-form, allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n width: auto; // Prevent labels from stacking above inputs in `.form-group`\n vertical-align: middle;\n }\n\n // Make static controls behave like regular ones\n .form-control-static {\n display: inline-block;\n }\n\n .input-group {\n display: inline-table;\n vertical-align: middle;\n\n .input-group-addon,\n .input-group-btn,\n .form-control {\n width: auto;\n }\n }\n\n // Input groups need that 100% width though\n .input-group > .form-control {\n width: 100%;\n }\n\n .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match.\n .radio,\n .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n\n label {\n padding-left: 0;\n }\n }\n .radio input[type=\"radio\"],\n .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n\n // Re-override the feedback icon.\n .has-feedback .form-control-feedback {\n top: 0;\n }\n }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n // Consistent vertical alignment of radios and checkboxes\n //\n // Labels also get some reset styles, but that is scoped to a media query below.\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n }\n // Account for padding we're adding to ensure the alignment and of help text\n // and other content below items\n .radio,\n .checkbox {\n min-height: (@line-height-computed + (@padding-base-vertical + 1));\n }\n\n // Make form groups behave like rows\n .form-group {\n .make-row();\n }\n\n // Reset spacing and right align labels, but scope to media queries so that\n // labels on narrow viewports stack the same as a default form example.\n @media (min-width: @screen-sm-min) {\n .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n }\n }\n\n // Validation states\n //\n // Reposition the icon because it's now within a grid column and columns have\n // `position: relative;` on them. Also accounts for the grid gutter padding.\n .has-feedback .form-control-feedback {\n right: floor((@grid-gutter-width / 2));\n }\n\n // Form group sizes\n //\n // Quick utility class for applying `.input-lg` and `.input-sm` styles to the\n // inputs and labels within a `.form-group`.\n .form-group-lg {\n @media (min-width: @screen-sm-min) {\n .control-label {\n padding-top: (@padding-large-vertical + 1);\n font-size: @font-size-large;\n }\n }\n }\n .form-group-sm {\n @media (min-width: @screen-sm-min) {\n .control-label {\n padding-top: (@padding-small-vertical + 1);\n font-size: @font-size-small;\n }\n }\n }\n}\n","// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n // Color the label and help text\n .help-block,\n .control-label,\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline,\n &.radio label,\n &.checkbox label,\n &.radio-inline label,\n &.checkbox-inline label {\n color: @text-color;\n }\n // Set the border and box shadow on specific inputs to match\n .form-control {\n border-color: @border-color;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n &:focus {\n border-color: darken(@border-color, 10%);\n @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n .box-shadow(@shadow);\n }\n }\n // Set validation states also for addons\n .input-group-addon {\n color: @text-color;\n border-color: @border-color;\n background-color: @background-color;\n }\n // Optional feedback icon\n .form-control-feedback {\n color: @text-color;\n }\n}\n\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-border-focus` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n.form-control-focus(@color: @input-border-focus) {\n @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n &:focus {\n border-color: @color;\n outline: 0;\n .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. ``\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n height: @input-height;\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n\n select& {\n height: @input-height;\n line-height: @input-height;\n }\n\n textarea&,\n select[multiple]& {\n height: auto;\n }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n display: inline-block;\n margin-bottom: 0; // For input.btn\n font-weight: @btn-font-weight;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n white-space: nowrap;\n .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base);\n .user-select(none);\n\n &,\n &:active,\n &.active {\n &:focus,\n &.focus {\n .tab-focus();\n }\n }\n\n &:hover,\n &:focus,\n &.focus {\n color: @btn-default-color;\n text-decoration: none;\n }\n\n &:active,\n &.active {\n outline: 0;\n background-image: none;\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n .opacity(.65);\n .box-shadow(none);\n }\n\n a& {\n &.disabled,\n fieldset[disabled] & {\n pointer-events: none; // Future-proof disabling of clicks on `` elements\n }\n }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n color: @link-color;\n font-weight: normal;\n border-radius: 0;\n\n &,\n &:active,\n &.active,\n &[disabled],\n fieldset[disabled] & {\n background-color: transparent;\n .box-shadow(none);\n }\n &,\n &:hover,\n &:focus,\n &:active {\n border-color: transparent;\n }\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n background-color: transparent;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @btn-link-disabled-color;\n text-decoration: none;\n }\n }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n // line-height: ensure even-numbered height of button next to large input\n .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large);\n}\n.btn-sm {\n // line-height: ensure proper height of button next to small input\n .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n.btn-xs {\n .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 25%);\n }\n &:hover {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n\n &:hover,\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 17%);\n border-color: darken(@border, 25%);\n }\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus,\n &.focus {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n opacity: 0;\n .transition(opacity .15s linear);\n &.in {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n\n &.in { display: block; }\n tr&.in { display: table-row; }\n tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n .transition-property(~\"height, visibility\");\n .transition-duration(.35s);\n .transition-timing-function(ease);\n}\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: @caret-width-base dashed;\n border-top: @caret-width-base solid ~\"\\9\"; // IE8\n border-right: @caret-width-base solid transparent;\n border-left: @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropup,\n.dropdown {\n position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: @zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0; // override default ul\n list-style: none;\n font-size: @font-size-base;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n background-color: @dropdown-bg;\n border: 1px solid @dropdown-fallback-border; // IE8 fallback\n border: 1px solid @dropdown-border;\n border-radius: @border-radius-base;\n .box-shadow(0 6px 12px rgba(0,0,0,.175));\n background-clip: padding-box;\n\n // Aligns the dropdown menu to right\n //\n // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n &.pull-right {\n right: 0;\n left: auto;\n }\n\n // Dividers (basically an hr) within the dropdown\n .divider {\n .nav-divider(@dropdown-divider-bg);\n }\n\n // Links within the dropdown menu\n > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n color: @dropdown-link-color;\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n &:hover,\n &:focus {\n text-decoration: none;\n color: @dropdown-link-hover-color;\n background-color: @dropdown-link-hover-bg;\n }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-active-color;\n text-decoration: none;\n outline: 0;\n background-color: @dropdown-link-active-bg;\n }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-disabled-color;\n }\n\n // Nuke hover/focus effects\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none; // Remove CSS gradient\n .reset-filter();\n cursor: @cursor-disabled;\n }\n}\n\n// Open state for the dropdown\n.open {\n // Show the menu\n > .dropdown-menu {\n display: block;\n }\n\n // Remove the outline when :focus is triggered\n > a {\n outline: 0;\n }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n left: auto; // Reset the default from `.dropdown-menu`\n right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: @font-size-small;\n line-height: @line-height-base;\n color: @dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n // Reverse the caret\n .caret {\n border-top: 0;\n border-bottom: @caret-width-base dashed;\n border-bottom: @caret-width-base solid ~\"\\9\"; // IE8\n content: \"\";\n }\n // Different positioning for bottom up menu\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-right {\n .dropdown-menu {\n .dropdown-menu-right();\n }\n // Necessary for overrides of the default right aligned menu.\n // Will remove come v4 in all likelihood.\n .dropdown-menu-left {\n .dropdown-menu-left();\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle; // match .btn alignment given font-size hack above\n > .btn {\n position: relative;\n float: left;\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active,\n &.active {\n z-index: 2;\n }\n }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -1px;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n margin-left: -5px; // Offset the first child's margin\n &:extend(.clearfix all);\n\n .btn,\n .btn-group,\n .input-group {\n float: left;\n }\n > .btn,\n > .btn-group,\n > .input-group {\n margin-left: 5px;\n }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n margin-left: 0;\n &:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n }\n}\n// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-right-radius(0);\n }\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n .box-shadow(none);\n }\n}\n\n\n// Reposition the caret\n.btn .caret {\n margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n border-width: @caret-width-large @caret-width-large 0;\n border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n > .btn,\n > .btn-group,\n > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n }\n\n // Clear floats so dropdown menus can be properly placed\n > .btn-group {\n &:extend(.clearfix all);\n > .btn {\n float: none;\n }\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n }\n}\n\n.btn-group-vertical > .btn {\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n &:first-child:not(:last-child) {\n .border-top-radius(@btn-border-radius-base);\n .border-bottom-radius(0);\n }\n &:last-child:not(:first-child) {\n .border-top-radius(0);\n .border-bottom-radius(@btn-border-radius-base);\n }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-bottom-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n > .btn,\n > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n }\n > .btn-group .btn {\n width: 100%;\n }\n\n > .btn-group .dropdown-menu {\n left: auto;\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n > .btn,\n > .btn-group > .btn {\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0,0,0,0);\n pointer-events: none;\n }\n }\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n position: relative; // For dropdowns\n display: table;\n border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n // Undo padding and float of grid classes\n &[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n }\n\n .form-control {\n // Ensure that the input is always above the *appended* addon button for\n // proper border colors.\n position: relative;\n z-index: 2;\n\n // IE9 fubars the placeholder attribute in text inputs and the arrows on\n // select elements in input groups. To fix it, we float the input. Details:\n // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n float: left;\n\n width: 100%;\n margin-bottom: 0;\n\n &:focus {\n z-index: 3;\n }\n }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 1;\n color: @input-color;\n text-align: center;\n background-color: @input-group-addon-bg;\n border: 1px solid @input-group-addon-border-color;\n border-radius: @input-border-radius;\n\n // Sizing\n &.input-sm {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n border-radius: @input-border-radius-small;\n }\n &.input-lg {\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n border-radius: @input-border-radius-large;\n }\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n .border-right-radius(0);\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n .border-left-radius(0);\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n position: relative;\n // Jankily prevent input button groups from wrapping with `white-space` and\n // `font-size` in combination with `inline-block` on buttons.\n font-size: 0;\n white-space: nowrap;\n\n // Negative margin for spacing, position for bringing hovered/focused/actived\n // element above the siblings.\n > .btn {\n position: relative;\n + .btn {\n margin-left: -1px;\n }\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active {\n z-index: 2;\n }\n }\n\n // Negative margin to only have a 1px border between the two\n &:first-child {\n > .btn,\n > .btn-group {\n margin-right: -1px;\n }\n }\n &:last-child {\n > .btn,\n > .btn-group {\n z-index: 2;\n margin-left: -1px;\n }\n }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n margin-bottom: 0;\n padding-left: 0; // Override default ul/ol\n list-style: none;\n &:extend(.clearfix all);\n\n > li {\n position: relative;\n display: block;\n\n > a {\n position: relative;\n display: block;\n padding: @nav-link-padding;\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @nav-link-hover-bg;\n }\n }\n\n // Disabled state sets text to gray and nukes hover/tab effects\n &.disabled > a {\n color: @nav-disabled-link-color;\n\n &:hover,\n &:focus {\n color: @nav-disabled-link-hover-color;\n text-decoration: none;\n background-color: transparent;\n cursor: @cursor-disabled;\n }\n }\n }\n\n // Open dropdowns\n .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @nav-link-hover-bg;\n border-color: @link-color;\n }\n }\n\n // Nav dividers (deprecated with v3.0.1)\n //\n // This should have been removed in v3 with the dropping of `.nav-list`, but\n // we missed it. We don't currently support this anywhere, but in the interest\n // of maintaining backward compatibility in case you use it, it's deprecated.\n .nav-divider {\n .nav-divider();\n }\n\n // Prevent IE8 from misplacing imgs\n //\n // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n > li > a > img {\n max-width: none;\n }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n border-bottom: 1px solid @nav-tabs-border-color;\n > li {\n float: left;\n // Make the list-items overlay the bottom border\n margin-bottom: -1px;\n\n // Actual tabs (as links)\n > a {\n margin-right: 2px;\n line-height: @line-height-base;\n border: 1px solid transparent;\n border-radius: @border-radius-base @border-radius-base 0 0;\n &:hover {\n border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n }\n }\n\n // Active state, and its :hover to override normal :hover\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-tabs-active-link-hover-color;\n background-color: @nav-tabs-active-link-hover-bg;\n border: 1px solid @nav-tabs-active-link-hover-border-color;\n border-bottom-color: transparent;\n cursor: default;\n }\n }\n }\n // pulling this in mainly for less shorthand\n &.nav-justified {\n .nav-justified();\n .nav-tabs-justified();\n }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n > li {\n float: left;\n\n // Links rendered as pills\n > a {\n border-radius: @nav-pills-border-radius;\n }\n + li {\n margin-left: 2px;\n }\n\n // Active state\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-pills-active-link-hover-color;\n background-color: @nav-pills-active-link-hover-bg;\n }\n }\n }\n}\n\n\n// Stacked pills\n.nav-stacked {\n > li {\n float: none;\n + li {\n margin-top: 2px;\n margin-left: 0; // no need for this gap between nav items\n }\n }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n width: 100%;\n\n > li {\n float: none;\n > a {\n text-align: center;\n margin-bottom: 5px;\n }\n }\n\n > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n }\n\n @media (min-width: @screen-sm-min) {\n > li {\n display: table-cell;\n width: 1%;\n > a {\n margin-bottom: 0;\n }\n }\n }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n border-bottom: 0;\n\n > li > a {\n // Override margin from .nav-tabs\n margin-right: 0;\n border-radius: @border-radius-base;\n }\n\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border: 1px solid @nav-tabs-justified-link-border-color;\n }\n\n @media (min-width: @screen-sm-min) {\n > li > a {\n border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n border-radius: @border-radius-base @border-radius-base 0 0;\n }\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border-bottom-color: @nav-tabs-justified-active-link-border-color;\n }\n }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n // make dropdown border overlap tab border\n margin-top: -1px;\n // Remove the top rounded corners here since there is a hard edge above the menu\n .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n margin-bottom: @navbar-margin-bottom;\n border: 1px solid transparent;\n\n // Prevent floats from breaking the navbar\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: @navbar-border-radius;\n }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n overflow-x: visible;\n padding-right: @navbar-padding-horizontal;\n padding-left: @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n &:extend(.clearfix all);\n -webkit-overflow-scrolling: touch;\n\n &.in {\n overflow-y: auto;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border-top: 0;\n box-shadow: none;\n\n &.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0; // Override default setting\n overflow: visible !important;\n }\n\n &.in {\n overflow-y: visible;\n }\n\n // Undo the collapse side padding for navbars with containers to ensure\n // alignment of right-aligned contents.\n .navbar-fixed-top &,\n .navbar-static-top &,\n .navbar-fixed-bottom & {\n padding-left: 0;\n padding-right: 0;\n }\n }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n .navbar-collapse {\n max-height: @navbar-collapse-max-height;\n\n @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n max-height: 200px;\n }\n }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n > .navbar-header,\n > .navbar-collapse {\n margin-right: -@navbar-padding-horizontal;\n margin-left: -@navbar-padding-horizontal;\n\n @media (min-width: @grid-float-breakpoint) {\n margin-right: 0;\n margin-left: 0;\n }\n }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n z-index: @zindex-navbar;\n border-width: 0 0 1px;\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: @zindex-navbar-fixed;\n\n // Undo the rounded corners\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0; // override .navbar defaults\n border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n float: left;\n padding: @navbar-padding-vertical @navbar-padding-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-computed;\n height: @navbar-height;\n\n &:hover,\n &:focus {\n text-decoration: none;\n }\n\n > img {\n display: block;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n .navbar > .container &,\n .navbar > .container-fluid & {\n margin-left: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: @navbar-padding-horizontal;\n padding: 9px 10px;\n .navbar-vertical-align(34px);\n background-color: transparent;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n border-radius: @border-radius-base;\n\n // We remove the `outline` here, but later compensate by attaching `:hover`\n // styles to `:focus`.\n &:focus {\n outline: 0;\n }\n\n // Bars\n .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n }\n .icon-bar + .icon-bar {\n margin-top: 4px;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n display: none;\n }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: @line-height-computed;\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n > li > a,\n .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n > li > a {\n line-height: @line-height-computed;\n &:hover,\n &:focus {\n background-image: none;\n }\n }\n }\n }\n\n // Uncollapse the nav\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin: 0;\n\n > li {\n float: left;\n > a {\n padding-top: @navbar-padding-vertical;\n padding-bottom: @navbar-padding-vertical;\n }\n }\n }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n margin-left: -@navbar-padding-horizontal;\n margin-right: -@navbar-padding-horizontal;\n padding: 10px @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n\n // Mixin behavior for optimum display\n .form-inline();\n\n .form-group {\n @media (max-width: @grid-float-breakpoint-max) {\n margin-bottom: 5px;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n }\n\n // Vertically center in expanded, horizontal navbar\n .navbar-vertical-align(@input-height-base);\n\n // Undo 100% width for pull classes\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n .box-shadow(none);\n }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n .border-top-radius(@navbar-border-radius);\n .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n .navbar-vertical-align(@input-height-base);\n\n &.btn-sm {\n .navbar-vertical-align(@input-height-small);\n }\n &.btn-xs {\n .navbar-vertical-align(22);\n }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n .navbar-vertical-align(@line-height-computed);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin-left: @navbar-padding-horizontal;\n margin-right: @navbar-padding-horizontal;\n }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-left { .pull-left(); }\n .navbar-right {\n .pull-right();\n margin-right: -@navbar-padding-horizontal;\n\n ~ .navbar-right {\n margin-right: 0;\n }\n }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n background-color: @navbar-default-bg;\n border-color: @navbar-default-border;\n\n .navbar-brand {\n color: @navbar-default-brand-color;\n &:hover,\n &:focus {\n color: @navbar-default-brand-hover-color;\n background-color: @navbar-default-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-default-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-default-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n\n .navbar-toggle {\n border-color: @navbar-default-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-default-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-default-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: @navbar-default-border;\n }\n\n // Dropdown menu items\n .navbar-nav {\n // Remove background color from open dropdown\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-default-link-active-bg;\n color: @navbar-default-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n > li > a {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n }\n }\n\n\n // Links in navbars\n //\n // Add a class to ensure links outside the navbar nav are colored correctly.\n\n .navbar-link {\n color: @navbar-default-link-color;\n &:hover {\n color: @navbar-default-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n }\n }\n }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n background-color: @navbar-inverse-bg;\n border-color: @navbar-inverse-border;\n\n .navbar-brand {\n color: @navbar-inverse-brand-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-brand-hover-color;\n background-color: @navbar-inverse-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-inverse-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-inverse-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n\n // Darken the responsive nav toggle\n .navbar-toggle {\n border-color: @navbar-inverse-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-inverse-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-inverse-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: darken(@navbar-inverse-bg, 7%);\n }\n\n // Dropdowns\n .navbar-nav {\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-inverse-link-active-bg;\n color: @navbar-inverse-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display\n .open .dropdown-menu {\n > .dropdown-header {\n border-color: @navbar-inverse-border;\n }\n .divider {\n background-color: @navbar-inverse-border;\n }\n > li > a {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n }\n }\n\n .navbar-link {\n color: @navbar-inverse-link-color;\n &:hover {\n color: @navbar-inverse-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n }\n }\n }\n}\n","// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n .clearfix();\n}\n.center-block {\n .center-block();\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n display: none !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n margin-bottom: @line-height-computed;\n list-style: none;\n background-color: @breadcrumb-bg;\n border-radius: @border-radius-base;\n\n > li {\n display: inline-block;\n\n + li:before {\n content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n padding: 0 5px;\n color: @breadcrumb-color;\n }\n }\n\n > .active {\n color: @breadcrumb-active-color;\n }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: @line-height-computed 0;\n border-radius: @border-radius-base;\n\n > li {\n display: inline; // Remove list-style and block-level defaults\n > a,\n > span {\n position: relative;\n float: left; // Collapse white-space\n padding: @padding-base-vertical @padding-base-horizontal;\n line-height: @line-height-base;\n text-decoration: none;\n color: @pagination-color;\n background-color: @pagination-bg;\n border: 1px solid @pagination-border;\n margin-left: -1px;\n }\n &:first-child {\n > a,\n > span {\n margin-left: 0;\n .border-left-radius(@border-radius-base);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius-base);\n }\n }\n }\n\n > li > a,\n > li > span {\n &:hover,\n &:focus {\n z-index: 2;\n color: @pagination-hover-color;\n background-color: @pagination-hover-bg;\n border-color: @pagination-hover-border;\n }\n }\n\n > .active > a,\n > .active > span {\n &,\n &:hover,\n &:focus {\n z-index: 3;\n color: @pagination-active-color;\n background-color: @pagination-active-bg;\n border-color: @pagination-active-border;\n cursor: default;\n }\n }\n\n > .disabled {\n > span,\n > span:hover,\n > span:focus,\n > a,\n > a:hover,\n > a:focus {\n color: @pagination-disabled-color;\n background-color: @pagination-disabled-bg;\n border-color: @pagination-disabled-border;\n cursor: @cursor-disabled;\n }\n }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n","// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n padding-left: 0;\n margin: @line-height-computed 0;\n list-style: none;\n text-align: center;\n &:extend(.clearfix all);\n li {\n display: inline;\n > a,\n > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: @pager-bg;\n border: 1px solid @pager-border;\n border-radius: @pager-border-radius;\n }\n\n > a:hover,\n > a:focus {\n text-decoration: none;\n background-color: @pager-hover-bg;\n }\n }\n\n .next {\n > a,\n > span {\n float: right;\n }\n }\n\n .previous {\n > a,\n > span {\n float: left;\n }\n }\n\n .disabled {\n > a,\n > a:hover,\n > a:focus,\n > span {\n color: @pager-disabled-color;\n background-color: @pager-bg;\n cursor: @cursor-disabled;\n }\n }\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: @label-color;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n\n // Add hover effects, but only for links\n a& {\n &:hover,\n &:focus {\n color: @label-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Empty labels collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for labels in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n .label-variant(@label-default-bg);\n}\n\n.label-primary {\n .label-variant(@label-primary-bg);\n}\n\n.label-success {\n .label-variant(@label-success-bg);\n}\n\n.label-info {\n .label-variant(@label-info-bg);\n}\n\n.label-warning {\n .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n .label-variant(@label-danger-bg);\n}\n","// Labels\n\n.label-variant(@color) {\n background-color: @color;\n\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: @font-size-small;\n font-weight: @badge-font-weight;\n color: @badge-color;\n line-height: @badge-line-height;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: @badge-bg;\n border-radius: @badge-border-radius;\n\n // Empty badges collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for badges in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n\n .btn-xs &,\n .btn-group-xs > .btn & {\n top: 0;\n padding: 1px 5px;\n }\n\n // Hover state, but only for links\n a& {\n &:hover,\n &:focus {\n color: @badge-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Account for badges in navs\n .list-group-item.active > &,\n .nav-pills > .active > a > & {\n color: @badge-active-color;\n background-color: @badge-active-bg;\n }\n\n .list-group-item > & {\n float: right;\n }\n\n .list-group-item > & + & {\n margin-right: 5px;\n }\n\n .nav-pills > li > a > & {\n margin-left: 3px;\n }\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding-top: @jumbotron-padding;\n padding-bottom: @jumbotron-padding;\n margin-bottom: @jumbotron-padding;\n color: @jumbotron-color;\n background-color: @jumbotron-bg;\n\n h1,\n .h1 {\n color: @jumbotron-heading-color;\n }\n\n p {\n margin-bottom: (@jumbotron-padding / 2);\n font-size: @jumbotron-font-size;\n font-weight: 200;\n }\n\n > hr {\n border-top-color: darken(@jumbotron-bg, 10%);\n }\n\n .container &,\n .container-fluid & {\n border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n\n .container {\n max-width: 100%;\n }\n\n @media screen and (min-width: @screen-sm-min) {\n padding-top: (@jumbotron-padding * 1.6);\n padding-bottom: (@jumbotron-padding * 1.6);\n\n .container &,\n .container-fluid & {\n padding-left: (@jumbotron-padding * 2);\n padding-right: (@jumbotron-padding * 2);\n }\n\n h1,\n .h1 {\n font-size: @jumbotron-heading-font-size;\n }\n }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n display: block;\n padding: @thumbnail-padding;\n margin-bottom: @line-height-computed;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(border .2s ease-in-out);\n\n > img,\n a > img {\n &:extend(.img-responsive);\n margin-left: auto;\n margin-right: auto;\n }\n\n // Add a hover state for linked versions only\n a&:hover,\n a&:focus,\n a&.active {\n border-color: @link-color;\n }\n\n // Image captions\n .caption {\n padding: @thumbnail-caption-padding;\n color: @thumbnail-caption-color;\n }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n padding: @alert-padding;\n margin-bottom: @line-height-computed;\n border: 1px solid transparent;\n border-radius: @alert-border-radius;\n\n // Headings for larger alerts\n h4 {\n margin-top: 0;\n // Specified for the h4 to prevent conflicts of changing @headings-color\n color: inherit;\n }\n\n // Provide class for links that match alerts\n .alert-link {\n font-weight: @alert-link-font-weight;\n }\n\n // Improve alignment and spacing of inner content\n > p,\n > ul {\n margin-bottom: 0;\n }\n\n > p + p {\n margin-top: 5px;\n }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n padding-right: (@alert-padding + 20);\n\n // Adjust close link position\n .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n\n.alert-info {\n .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n\n.alert-warning {\n .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n\n.alert-danger {\n .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n overflow: hidden;\n height: @line-height-computed;\n margin-bottom: @line-height-computed;\n background-color: @progress-bg;\n border-radius: @progress-border-radius;\n .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: @font-size-small;\n line-height: @line-height-computed;\n color: @progress-bar-color;\n text-align: center;\n background-color: @progress-bar-bg;\n .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n #gradient > .striped();\n background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Progress bars\n\n.progress-bar-variant(@color) {\n background-color: @color;\n\n // Deprecated parent class requirement as of v3.2.0\n .progress-striped & {\n #gradient > .striped();\n }\n}\n",".media {\n // Proper spacing between instances of .media\n margin-top: 15px;\n\n &:first-child {\n margin-top: 0;\n }\n}\n\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n\n.media-body {\n width: 10000px;\n}\n\n.media-object {\n display: block;\n\n // Fix collapse in webkit from max-width: 100% and display: table-cell.\n &.img-thumbnail {\n max-width: none;\n }\n}\n\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n\n.media-middle {\n vertical-align: middle;\n}\n\n.media-bottom {\n vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on , , or .\n\n.list-group {\n // No need to set list-style: none; since .list-group-item is block level\n margin-bottom: 20px;\n padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -1px;\n background-color: @list-group-bg;\n border: 1px solid @list-group-border;\n\n // Round the first and last items\n &:first-child {\n .border-top-radius(@list-group-border-radius);\n }\n &:last-child {\n margin-bottom: 0;\n .border-bottom-radius(@list-group-border-radius);\n }\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item,\nbutton.list-group-item {\n color: @list-group-link-color;\n\n .list-group-item-heading {\n color: @list-group-link-heading-color;\n }\n\n // Hover state\n &:hover,\n &:focus {\n text-decoration: none;\n color: @list-group-link-hover-color;\n background-color: @list-group-hover-bg;\n }\n}\n\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n\n.list-group-item {\n // Disabled state\n &.disabled,\n &.disabled:hover,\n &.disabled:focus {\n background-color: @list-group-disabled-bg;\n color: @list-group-disabled-color;\n cursor: @cursor-disabled;\n\n // Force color to inherit for custom content\n .list-group-item-heading {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-disabled-text-color;\n }\n }\n\n // Active class on item itself, not parent\n &.active,\n &.active:hover,\n &.active:focus {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: @list-group-active-color;\n background-color: @list-group-active-bg;\n border-color: @list-group-active-border;\n\n // Force color to inherit for custom content\n .list-group-item-heading,\n .list-group-item-heading > small,\n .list-group-item-heading > .small {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-active-text-color;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n","// List Groups\n\n.list-group-item-variant(@state; @background; @color) {\n .list-group-item-@{state} {\n color: @color;\n background-color: @background;\n\n a&,\n button& {\n color: @color;\n\n .list-group-item-heading {\n color: inherit;\n }\n\n &:hover,\n &:focus {\n color: @color;\n background-color: darken(@background, 5%);\n }\n &.active,\n &.active:hover,\n &.active:focus {\n color: #fff;\n background-color: @color;\n border-color: @color;\n }\n }\n }\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n margin-bottom: @line-height-computed;\n background-color: @panel-bg;\n border: 1px solid transparent;\n border-radius: @panel-border-radius;\n .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n padding: @panel-body-padding;\n &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n padding: @panel-heading-padding;\n border-bottom: 1px solid transparent;\n .border-top-radius((@panel-border-radius - 1));\n\n > .dropdown .dropdown-toggle {\n color: inherit;\n }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: ceil((@font-size-base * 1.125));\n color: inherit;\n\n > a,\n > small,\n > .small,\n > small > a,\n > .small > a {\n color: inherit;\n }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n padding: @panel-footer-padding;\n background-color: @panel-footer-bg;\n border-top: 1px solid @panel-inner-border;\n .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n > .list-group,\n > .panel-collapse > .list-group {\n margin-bottom: 0;\n\n .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n }\n\n // Add border top radius for first one\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n .border-top-radius((@panel-border-radius - 1));\n }\n }\n\n // Add border bottom radius for last one\n &:last-child {\n .list-group-item:last-child {\n border-bottom: 0;\n .border-bottom-radius((@panel-border-radius - 1));\n }\n }\n }\n > .panel-heading + .panel-collapse > .list-group {\n .list-group-item:first-child {\n .border-top-radius(0);\n }\n }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n .list-group-item:first-child {\n border-top-width: 0;\n }\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n > .table,\n > .table-responsive > .table,\n > .panel-collapse > .table {\n margin-bottom: 0;\n\n caption {\n padding-left: @panel-body-padding;\n padding-right: @panel-body-padding;\n }\n }\n // Add border top radius for first one\n > .table:first-child,\n > .table-responsive:first-child > .table:first-child {\n .border-top-radius((@panel-border-radius - 1));\n\n > thead:first-child,\n > tbody:first-child {\n > tr:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n border-top-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-top-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n // Add border bottom radius for last one\n > .table:last-child,\n > .table-responsive:last-child > .table:last-child {\n .border-bottom-radius((@panel-border-radius - 1));\n\n > tbody:last-child,\n > tfoot:last-child {\n > tr:last-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n border-bottom-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-bottom-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n > .panel-body + .table,\n > .panel-body + .table-responsive,\n > .table + .panel-body,\n > .table-responsive + .panel-body {\n border-top: 1px solid @table-border-color;\n }\n > .table > tbody:first-child > tr:first-child th,\n > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n }\n > .table-bordered,\n > .table-responsive > .table-bordered {\n border: 0;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n > thead,\n > tbody {\n > tr:first-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n > tbody,\n > tfoot {\n > tr:last-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n }\n > .table-responsive {\n border: 0;\n margin-bottom: 0;\n }\n}\n\n\n// Collapsible panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n margin-bottom: @line-height-computed;\n\n // Tighten up margin so it's only between panels\n .panel {\n margin-bottom: 0;\n border-radius: @panel-border-radius;\n\n + .panel {\n margin-top: 5px;\n }\n }\n\n .panel-heading {\n border-bottom: 0;\n\n + .panel-collapse > .panel-body,\n + .panel-collapse > .list-group {\n border-top: 1px solid @panel-inner-border;\n }\n }\n\n .panel-footer {\n border-top: 0;\n + .panel-collapse .panel-body {\n border-bottom: 1px solid @panel-inner-border;\n }\n }\n}\n\n\n// Contextual variations\n.panel-default {\n .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","// Panels\n\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n border-color: @border;\n\n & > .panel-heading {\n color: @heading-text-color;\n background-color: @heading-bg-color;\n border-color: @heading-border;\n\n + .panel-collapse > .panel-body {\n border-top-color: @border;\n }\n .badge {\n color: @heading-bg-color;\n background-color: @heading-text-color;\n }\n }\n & > .panel-footer {\n + .panel-collapse > .panel-body {\n border-bottom-color: @border;\n }\n }\n}\n","// Embeds responsive\n//\n// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n }\n}\n\n// Modifier class for 16:9 aspect ratio\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n\n// Modifier class for 4:3 aspect ratio\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: @well-bg;\n border: 1px solid @well-border;\n border-radius: @border-radius-base;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n blockquote {\n border-color: #ddd;\n border-color: rgba(0,0,0,.15);\n }\n}\n\n// Sizes\n.well-lg {\n padding: 24px;\n border-radius: @border-radius-large;\n}\n.well-sm {\n padding: 9px;\n border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-size-base * 1.5);\n font-weight: @close-font-weight;\n line-height: 1;\n color: @close-color;\n text-shadow: @close-text-shadow;\n .opacity(.2);\n\n &:hover,\n &:focus {\n color: @close-color;\n text-decoration: none;\n cursor: pointer;\n .opacity(.5);\n }\n\n // Additional properties for button version\n // iOS requires the button element instead of an anchor tag.\n // If you want the anchor version, it requires `href=\"#\"`.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n button& {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal;\n -webkit-overflow-scrolling: touch;\n\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n\n // When fading in the modal, animate it to slide down\n &.fade .modal-dialog {\n .translate(0, -25%);\n .transition-transform(~\"0.3s ease-out\");\n }\n &.in .modal-dialog { .translate(0, 0) }\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n background-color: @modal-content-bg;\n border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n border: 1px solid @modal-content-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 3px 9px rgba(0,0,0,.5));\n background-clip: padding-box;\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal-background;\n background-color: @modal-backdrop-bg;\n // Fade for backdrop\n &.fade { .opacity(0); }\n &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n padding: @modal-title-padding;\n border-bottom: 1px solid @modal-header-border-color;\n &:extend(.clearfix all);\n}\n// Close icon\n.modal-header .close {\n margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n margin: 0;\n line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n padding: @modal-inner-padding;\n text-align: right; // right align buttons\n border-top: 1px solid @modal-footer-border-color;\n &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n // Properly space out buttons\n .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n }\n // but override that for button groups\n .btn-group .btn + .btn {\n margin-left: -1px;\n }\n // and override it for block buttons as well\n .btn-block + .btn-block {\n margin-left: 0;\n }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n width: @modal-md;\n margin: 30px auto;\n }\n .modal-content {\n .box-shadow(0 5px 15px rgba(0,0,0,.5));\n }\n\n // Modal sizes\n .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n position: absolute;\n z-index: @zindex-tooltip;\n display: block;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n .reset-text();\n font-size: @font-size-small;\n\n .opacity(0);\n\n &.in { .opacity(@tooltip-opacity); }\n &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }\n &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }\n &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }\n &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: @tooltip-max-width;\n padding: 3px 8px;\n color: @tooltip-color;\n text-align: center;\n background-color: @tooltip-bg;\n border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1\n.tooltip {\n &.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-left .tooltip-arrow {\n bottom: 0;\n right: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-right .tooltip-arrow {\n bottom: 0;\n left: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n border-right-color: @tooltip-arrow-color;\n }\n &.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-left-color: @tooltip-arrow-color;\n }\n &.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-left .tooltip-arrow {\n top: 0;\n right: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-right .tooltip-arrow {\n top: 0;\n left: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n}\n",".reset-text() {\n font-family: @font-family-base;\n // We deliberately do NOT reset font-size.\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: @line-height-base;\n text-align: left; // Fallback for where `start` is not supported\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: @zindex-popover;\n display: none;\n max-width: @popover-max-width;\n padding: 1px;\n // Our parent element can be arbitrary since popovers are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n .reset-text();\n font-size: @font-size-base;\n\n background-color: @popover-bg;\n background-clip: padding-box;\n border: 1px solid @popover-fallback-border-color;\n border: 1px solid @popover-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n // Offset the popover to account for the popover arrow\n &.top { margin-top: -@popover-arrow-width; }\n &.right { margin-left: @popover-arrow-width; }\n &.bottom { margin-top: @popover-arrow-width; }\n &.left { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n margin: 0; // reset heading margin\n padding: 8px 14px;\n font-size: @font-size-base;\n background-color: @popover-title-bg;\n border-bottom: 1px solid darken(@popover-title-bg, 5%);\n border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;\n}\n\n.popover-content {\n padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n &,\n &:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n }\n}\n.popover > .arrow {\n border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n border-width: @popover-arrow-width;\n content: \"\";\n}\n\n.popover {\n &.top > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-top-color: @popover-arrow-outer-color;\n bottom: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n bottom: 1px;\n margin-left: -@popover-arrow-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-color;\n }\n }\n &.right > .arrow {\n top: 50%;\n left: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-right-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n left: 1px;\n bottom: -@popover-arrow-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-color;\n }\n }\n &.bottom > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-bottom-color: @popover-arrow-outer-color;\n top: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n top: 1px;\n margin-left: -@popover-arrow-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-color;\n }\n }\n\n &.left > .arrow {\n top: 50%;\n right: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-right-width: 0;\n border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-left-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: @popover-arrow-color;\n bottom: -@popover-arrow-width;\n }\n }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n\n > .item {\n display: none;\n position: relative;\n .transition(.6s ease-in-out left);\n\n // Account for jankitude on images\n > img,\n > a > img {\n &:extend(.img-responsive);\n line-height: 1;\n }\n\n // WebKit CSS3 transforms for supported devices\n @media all and (transform-3d), (-webkit-transform-3d) {\n .transition-transform(~'0.6s ease-in-out');\n .backface-visibility(~'hidden');\n .perspective(1000px);\n\n &.next,\n &.active.right {\n .translate3d(100%, 0, 0);\n left: 0;\n }\n &.prev,\n &.active.left {\n .translate3d(-100%, 0, 0);\n left: 0;\n }\n &.next.left,\n &.prev.right,\n &.active {\n .translate3d(0, 0, 0);\n left: 0;\n }\n }\n }\n\n > .active,\n > .next,\n > .prev {\n display: block;\n }\n\n > .active {\n left: 0;\n }\n\n > .next,\n > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n }\n\n > .next {\n left: 100%;\n }\n > .prev {\n left: -100%;\n }\n > .next.left,\n > .prev.right {\n left: 0;\n }\n\n > .active.left {\n left: -100%;\n }\n > .active.right {\n left: 100%;\n }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: @carousel-control-width;\n .opacity(@carousel-control-opacity);\n font-size: @carousel-control-font-size;\n color: @carousel-control-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n background-color: rgba(0, 0, 0, 0); // Fix IE9 click-thru bug\n // We can't have this transition here because WebKit cancels the carousel\n // animation if you trip this while in the middle of another animation.\n\n // Set gradients for backgrounds\n &.left {\n #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n }\n &.right {\n left: auto;\n right: 0;\n #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n }\n\n // Hover/focus state\n &:hover,\n &:focus {\n outline: 0;\n color: @carousel-control-color;\n text-decoration: none;\n .opacity(.9);\n }\n\n // Toggles\n .icon-prev,\n .icon-next,\n .glyphicon-chevron-left,\n .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n }\n .icon-prev,\n .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n }\n .icon-next,\n .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n }\n .icon-prev,\n .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n }\n\n\n .icon-prev {\n &:before {\n content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n }\n }\n .icon-next {\n &:before {\n content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n }\n }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n\n li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid @carousel-indicator-border-color;\n border-radius: 10px;\n cursor: pointer;\n\n // IE8-9 hack for event handling\n //\n // Internet Explorer 8-9 does not support clicks on elements without a set\n // `background-color`. We cannot use `filter` since that's not viewed as a\n // background color by the browser. Thus, a hack is needed.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer\n //\n // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n // set alpha transparency for the best results possible.\n background-color: #000 \\9; // IE8\n background-color: rgba(0,0,0,0); // IE9\n }\n .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: @carousel-indicator-active-bg;\n }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: @carousel-caption-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n & .btn {\n text-shadow: none; // No shadow for button elements in carousel-caption\n }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n // Scale up the controls a smidge\n .carousel-control {\n .glyphicon-chevron-left,\n .glyphicon-chevron-right,\n .icon-prev,\n .icon-next {\n width: (@carousel-control-font-size * 1.5);\n height: (@carousel-control-font-size * 1.5);\n margin-top: (@carousel-control-font-size / -2);\n font-size: (@carousel-control-font-size * 1.5);\n }\n .glyphicon-chevron-left,\n .icon-prev {\n margin-left: (@carousel-control-font-size / -2);\n }\n .glyphicon-chevron-right,\n .icon-next {\n margin-right: (@carousel-control-font-size / -2);\n }\n }\n\n // Show and left align the captions\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n\n // Move up the indicators\n .carousel-indicators {\n bottom: 20px;\n }\n}\n","// Clearfix\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n// contenteditable attribute is included anywhere else in the document.\n// Otherwise it causes space to appear at the top and bottom of elements\n// that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n// `:before` to contain the top-margins of child elements.\n//\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n\n.clearfix() {\n &:before,\n &:after {\n content: \" \"; // 1\n display: table; // 2\n }\n &:after {\n clear: both;\n }\n}\n","// Center-align a block level element\n\n.center-block() {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n","// CSS image replacement\n//\n// Heads up! v3 launched with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (has been removed in v4)\n.hide-text() {\n font: ~\"0/0\" a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n// New mixin to use as of v3.0.1\n.text-hide() {\n .hide-text();\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#support-ie10-width\n// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n width: device-width;\n}\n\n\n// Visibility utilities\n// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n .responsive-invisibility();\n}\n\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n\n.visible-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-visibility();\n }\n}\n.visible-xs-block {\n @media (max-width: @screen-xs-max) {\n display: block !important;\n }\n}\n.visible-xs-inline {\n @media (max-width: @screen-xs-max) {\n display: inline !important;\n }\n}\n.visible-xs-inline-block {\n @media (max-width: @screen-xs-max) {\n display: inline-block !important;\n }\n}\n\n.visible-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-visibility();\n }\n}\n.visible-sm-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: block !important;\n }\n}\n.visible-sm-inline {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline !important;\n }\n}\n.visible-sm-inline-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline-block !important;\n }\n}\n\n.visible-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-visibility();\n }\n}\n.visible-md-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: block !important;\n }\n}\n.visible-md-inline {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline !important;\n }\n}\n.visible-md-inline-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline-block !important;\n }\n}\n\n.visible-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-visibility();\n }\n}\n.visible-lg-block {\n @media (min-width: @screen-lg-min) {\n display: block !important;\n }\n}\n.visible-lg-inline {\n @media (min-width: @screen-lg-min) {\n display: inline !important;\n }\n}\n.visible-lg-inline-block {\n @media (min-width: @screen-lg-min) {\n display: inline-block !important;\n }\n}\n\n.hidden-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-invisibility();\n }\n}\n.hidden-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-invisibility();\n }\n}\n.hidden-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-invisibility();\n }\n}\n.hidden-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-invisibility();\n }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n// Note: Deprecated .visible-print as of v3.2.0\n.visible-print {\n .responsive-invisibility();\n\n @media print {\n .responsive-visibility();\n }\n}\n.visible-print-block {\n display: none !important;\n\n @media print {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n\n @media print {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n\n @media print {\n display: inline-block !important;\n }\n}\n\n.hidden-print {\n @media print {\n .responsive-invisibility();\n }\n}\n","// Responsive utilities\n\n//\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n display: block !important;\n table& { display: table !important; }\n tr& { display: table-row !important; }\n th&,\n td& { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n display: none !important;\n}\n"]}
\ No newline at end of file
diff --git a/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot
new file mode 100644
index 0000000..b93a495
Binary files /dev/null and b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot differ
diff --git a/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.svg b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.svg
new file mode 100644
index 0000000..94fb549
--- /dev/null
+++ b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.svg
@@ -0,0 +1,288 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf
new file mode 100644
index 0000000..1413fc6
Binary files /dev/null and b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf differ
diff --git a/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff
new file mode 100644
index 0000000..9e61285
Binary files /dev/null and b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff differ
diff --git a/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2
new file mode 100644
index 0000000..64539b5
Binary files /dev/null and b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 differ
diff --git a/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js
new file mode 100644
index 0000000..8a2e99a
--- /dev/null
+++ b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js
@@ -0,0 +1,2377 @@
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under the MIT license
+ */
+
+if (typeof jQuery === 'undefined') {
+ throw new Error('Bootstrap\'s JavaScript requires jQuery')
+}
+
++function ($) {
+ 'use strict';
+ var version = $.fn.jquery.split(' ')[0].split('.')
+ if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {
+ throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')
+ }
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: transition.js v3.3.7
+ * http://getbootstrap.com/javascript/#transitions
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
+ // ============================================================
+
+ function transitionEnd() {
+ var el = document.createElement('bootstrap')
+
+ var transEndEventNames = {
+ WebkitTransition : 'webkitTransitionEnd',
+ MozTransition : 'transitionend',
+ OTransition : 'oTransitionEnd otransitionend',
+ transition : 'transitionend'
+ }
+
+ for (var name in transEndEventNames) {
+ if (el.style[name] !== undefined) {
+ return { end: transEndEventNames[name] }
+ }
+ }
+
+ return false // explicit for ie8 ( ._.)
+ }
+
+ // http://blog.alexmaccaw.com/css-transitions
+ $.fn.emulateTransitionEnd = function (duration) {
+ var called = false
+ var $el = this
+ $(this).one('bsTransitionEnd', function () { called = true })
+ var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
+ setTimeout(callback, duration)
+ return this
+ }
+
+ $(function () {
+ $.support.transition = transitionEnd()
+
+ if (!$.support.transition) return
+
+ $.event.special.bsTransitionEnd = {
+ bindType: $.support.transition.end,
+ delegateType: $.support.transition.end,
+ handle: function (e) {
+ if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
+ }
+ }
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: alert.js v3.3.7
+ * http://getbootstrap.com/javascript/#alerts
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // ALERT CLASS DEFINITION
+ // ======================
+
+ var dismiss = '[data-dismiss="alert"]'
+ var Alert = function (el) {
+ $(el).on('click', dismiss, this.close)
+ }
+
+ Alert.VERSION = '3.3.7'
+
+ Alert.TRANSITION_DURATION = 150
+
+ Alert.prototype.close = function (e) {
+ var $this = $(this)
+ var selector = $this.attr('data-target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+ }
+
+ var $parent = $(selector === '#' ? [] : selector)
+
+ if (e) e.preventDefault()
+
+ if (!$parent.length) {
+ $parent = $this.closest('.alert')
+ }
+
+ $parent.trigger(e = $.Event('close.bs.alert'))
+
+ if (e.isDefaultPrevented()) return
+
+ $parent.removeClass('in')
+
+ function removeElement() {
+ // detach from parent, fire event then clean up data
+ $parent.detach().trigger('closed.bs.alert').remove()
+ }
+
+ $.support.transition && $parent.hasClass('fade') ?
+ $parent
+ .one('bsTransitionEnd', removeElement)
+ .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
+ removeElement()
+ }
+
+
+ // ALERT PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.alert')
+
+ if (!data) $this.data('bs.alert', (data = new Alert(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ var old = $.fn.alert
+
+ $.fn.alert = Plugin
+ $.fn.alert.Constructor = Alert
+
+
+ // ALERT NO CONFLICT
+ // =================
+
+ $.fn.alert.noConflict = function () {
+ $.fn.alert = old
+ return this
+ }
+
+
+ // ALERT DATA-API
+ // ==============
+
+ $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: button.js v3.3.7
+ * http://getbootstrap.com/javascript/#buttons
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // BUTTON PUBLIC CLASS DEFINITION
+ // ==============================
+
+ var Button = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, Button.DEFAULTS, options)
+ this.isLoading = false
+ }
+
+ Button.VERSION = '3.3.7'
+
+ Button.DEFAULTS = {
+ loadingText: 'loading...'
+ }
+
+ Button.prototype.setState = function (state) {
+ var d = 'disabled'
+ var $el = this.$element
+ var val = $el.is('input') ? 'val' : 'html'
+ var data = $el.data()
+
+ state += 'Text'
+
+ if (data.resetText == null) $el.data('resetText', $el[val]())
+
+ // push to event loop to allow forms to submit
+ setTimeout($.proxy(function () {
+ $el[val](data[state] == null ? this.options[state] : data[state])
+
+ if (state == 'loadingText') {
+ this.isLoading = true
+ $el.addClass(d).attr(d, d).prop(d, true)
+ } else if (this.isLoading) {
+ this.isLoading = false
+ $el.removeClass(d).removeAttr(d).prop(d, false)
+ }
+ }, this), 0)
+ }
+
+ Button.prototype.toggle = function () {
+ var changed = true
+ var $parent = this.$element.closest('[data-toggle="buttons"]')
+
+ if ($parent.length) {
+ var $input = this.$element.find('input')
+ if ($input.prop('type') == 'radio') {
+ if ($input.prop('checked')) changed = false
+ $parent.find('.active').removeClass('active')
+ this.$element.addClass('active')
+ } else if ($input.prop('type') == 'checkbox') {
+ if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
+ this.$element.toggleClass('active')
+ }
+ $input.prop('checked', this.$element.hasClass('active'))
+ if (changed) $input.trigger('change')
+ } else {
+ this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
+ this.$element.toggleClass('active')
+ }
+ }
+
+
+ // BUTTON PLUGIN DEFINITION
+ // ========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.button')
+ var options = typeof option == 'object' && option
+
+ if (!data) $this.data('bs.button', (data = new Button(this, options)))
+
+ if (option == 'toggle') data.toggle()
+ else if (option) data.setState(option)
+ })
+ }
+
+ var old = $.fn.button
+
+ $.fn.button = Plugin
+ $.fn.button.Constructor = Button
+
+
+ // BUTTON NO CONFLICT
+ // ==================
+
+ $.fn.button.noConflict = function () {
+ $.fn.button = old
+ return this
+ }
+
+
+ // BUTTON DATA-API
+ // ===============
+
+ $(document)
+ .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+ var $btn = $(e.target).closest('.btn')
+ Plugin.call($btn, 'toggle')
+ if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
+ // Prevent double click on radios, and the double selections (so cancellation) on checkboxes
+ e.preventDefault()
+ // The target component still receive the focus
+ if ($btn.is('input,button')) $btn.trigger('focus')
+ else $btn.find('input:visible,button:visible').first().trigger('focus')
+ }
+ })
+ .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+ $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: carousel.js v3.3.7
+ * http://getbootstrap.com/javascript/#carousel
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // CAROUSEL CLASS DEFINITION
+ // =========================
+
+ var Carousel = function (element, options) {
+ this.$element = $(element)
+ this.$indicators = this.$element.find('.carousel-indicators')
+ this.options = options
+ this.paused = null
+ this.sliding = null
+ this.interval = null
+ this.$active = null
+ this.$items = null
+
+ this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
+
+ this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
+ .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
+ .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
+ }
+
+ Carousel.VERSION = '3.3.7'
+
+ Carousel.TRANSITION_DURATION = 600
+
+ Carousel.DEFAULTS = {
+ interval: 5000,
+ pause: 'hover',
+ wrap: true,
+ keyboard: true
+ }
+
+ Carousel.prototype.keydown = function (e) {
+ if (/input|textarea/i.test(e.target.tagName)) return
+ switch (e.which) {
+ case 37: this.prev(); break
+ case 39: this.next(); break
+ default: return
+ }
+
+ e.preventDefault()
+ }
+
+ Carousel.prototype.cycle = function (e) {
+ e || (this.paused = false)
+
+ this.interval && clearInterval(this.interval)
+
+ this.options.interval
+ && !this.paused
+ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
+
+ return this
+ }
+
+ Carousel.prototype.getItemIndex = function (item) {
+ this.$items = item.parent().children('.item')
+ return this.$items.index(item || this.$active)
+ }
+
+ Carousel.prototype.getItemForDirection = function (direction, active) {
+ var activeIndex = this.getItemIndex(active)
+ var willWrap = (direction == 'prev' && activeIndex === 0)
+ || (direction == 'next' && activeIndex == (this.$items.length - 1))
+ if (willWrap && !this.options.wrap) return active
+ var delta = direction == 'prev' ? -1 : 1
+ var itemIndex = (activeIndex + delta) % this.$items.length
+ return this.$items.eq(itemIndex)
+ }
+
+ Carousel.prototype.to = function (pos) {
+ var that = this
+ var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
+
+ if (pos > (this.$items.length - 1) || pos < 0) return
+
+ if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
+ if (activeIndex == pos) return this.pause().cycle()
+
+ return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
+ }
+
+ Carousel.prototype.pause = function (e) {
+ e || (this.paused = true)
+
+ if (this.$element.find('.next, .prev').length && $.support.transition) {
+ this.$element.trigger($.support.transition.end)
+ this.cycle(true)
+ }
+
+ this.interval = clearInterval(this.interval)
+
+ return this
+ }
+
+ Carousel.prototype.next = function () {
+ if (this.sliding) return
+ return this.slide('next')
+ }
+
+ Carousel.prototype.prev = function () {
+ if (this.sliding) return
+ return this.slide('prev')
+ }
+
+ Carousel.prototype.slide = function (type, next) {
+ var $active = this.$element.find('.item.active')
+ var $next = next || this.getItemForDirection(type, $active)
+ var isCycling = this.interval
+ var direction = type == 'next' ? 'left' : 'right'
+ var that = this
+
+ if ($next.hasClass('active')) return (this.sliding = false)
+
+ var relatedTarget = $next[0]
+ var slideEvent = $.Event('slide.bs.carousel', {
+ relatedTarget: relatedTarget,
+ direction: direction
+ })
+ this.$element.trigger(slideEvent)
+ if (slideEvent.isDefaultPrevented()) return
+
+ this.sliding = true
+
+ isCycling && this.pause()
+
+ if (this.$indicators.length) {
+ this.$indicators.find('.active').removeClass('active')
+ var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
+ $nextIndicator && $nextIndicator.addClass('active')
+ }
+
+ var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
+ if ($.support.transition && this.$element.hasClass('slide')) {
+ $next.addClass(type)
+ $next[0].offsetWidth // force reflow
+ $active.addClass(direction)
+ $next.addClass(direction)
+ $active
+ .one('bsTransitionEnd', function () {
+ $next.removeClass([type, direction].join(' ')).addClass('active')
+ $active.removeClass(['active', direction].join(' '))
+ that.sliding = false
+ setTimeout(function () {
+ that.$element.trigger(slidEvent)
+ }, 0)
+ })
+ .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
+ } else {
+ $active.removeClass('active')
+ $next.addClass('active')
+ this.sliding = false
+ this.$element.trigger(slidEvent)
+ }
+
+ isCycling && this.cycle()
+
+ return this
+ }
+
+
+ // CAROUSEL PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.carousel')
+ var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
+ var action = typeof option == 'string' ? option : options.slide
+
+ if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
+ if (typeof option == 'number') data.to(option)
+ else if (action) data[action]()
+ else if (options.interval) data.pause().cycle()
+ })
+ }
+
+ var old = $.fn.carousel
+
+ $.fn.carousel = Plugin
+ $.fn.carousel.Constructor = Carousel
+
+
+ // CAROUSEL NO CONFLICT
+ // ====================
+
+ $.fn.carousel.noConflict = function () {
+ $.fn.carousel = old
+ return this
+ }
+
+
+ // CAROUSEL DATA-API
+ // =================
+
+ var clickHandler = function (e) {
+ var href
+ var $this = $(this)
+ var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
+ if (!$target.hasClass('carousel')) return
+ var options = $.extend({}, $target.data(), $this.data())
+ var slideIndex = $this.attr('data-slide-to')
+ if (slideIndex) options.interval = false
+
+ Plugin.call($target, options)
+
+ if (slideIndex) {
+ $target.data('bs.carousel').to(slideIndex)
+ }
+
+ e.preventDefault()
+ }
+
+ $(document)
+ .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
+ .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
+
+ $(window).on('load', function () {
+ $('[data-ride="carousel"]').each(function () {
+ var $carousel = $(this)
+ Plugin.call($carousel, $carousel.data())
+ })
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: collapse.js v3.3.7
+ * http://getbootstrap.com/javascript/#collapse
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+/* jshint latedef: false */
+
++function ($) {
+ 'use strict';
+
+ // COLLAPSE PUBLIC CLASS DEFINITION
+ // ================================
+
+ var Collapse = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, Collapse.DEFAULTS, options)
+ this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
+ '[data-toggle="collapse"][data-target="#' + element.id + '"]')
+ this.transitioning = null
+
+ if (this.options.parent) {
+ this.$parent = this.getParent()
+ } else {
+ this.addAriaAndCollapsedClass(this.$element, this.$trigger)
+ }
+
+ if (this.options.toggle) this.toggle()
+ }
+
+ Collapse.VERSION = '3.3.7'
+
+ Collapse.TRANSITION_DURATION = 350
+
+ Collapse.DEFAULTS = {
+ toggle: true
+ }
+
+ Collapse.prototype.dimension = function () {
+ var hasWidth = this.$element.hasClass('width')
+ return hasWidth ? 'width' : 'height'
+ }
+
+ Collapse.prototype.show = function () {
+ if (this.transitioning || this.$element.hasClass('in')) return
+
+ var activesData
+ var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
+
+ if (actives && actives.length) {
+ activesData = actives.data('bs.collapse')
+ if (activesData && activesData.transitioning) return
+ }
+
+ var startEvent = $.Event('show.bs.collapse')
+ this.$element.trigger(startEvent)
+ if (startEvent.isDefaultPrevented()) return
+
+ if (actives && actives.length) {
+ Plugin.call(actives, 'hide')
+ activesData || actives.data('bs.collapse', null)
+ }
+
+ var dimension = this.dimension()
+
+ this.$element
+ .removeClass('collapse')
+ .addClass('collapsing')[dimension](0)
+ .attr('aria-expanded', true)
+
+ this.$trigger
+ .removeClass('collapsed')
+ .attr('aria-expanded', true)
+
+ this.transitioning = 1
+
+ var complete = function () {
+ this.$element
+ .removeClass('collapsing')
+ .addClass('collapse in')[dimension]('')
+ this.transitioning = 0
+ this.$element
+ .trigger('shown.bs.collapse')
+ }
+
+ if (!$.support.transition) return complete.call(this)
+
+ var scrollSize = $.camelCase(['scroll', dimension].join('-'))
+
+ this.$element
+ .one('bsTransitionEnd', $.proxy(complete, this))
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
+ }
+
+ Collapse.prototype.hide = function () {
+ if (this.transitioning || !this.$element.hasClass('in')) return
+
+ var startEvent = $.Event('hide.bs.collapse')
+ this.$element.trigger(startEvent)
+ if (startEvent.isDefaultPrevented()) return
+
+ var dimension = this.dimension()
+
+ this.$element[dimension](this.$element[dimension]())[0].offsetHeight
+
+ this.$element
+ .addClass('collapsing')
+ .removeClass('collapse in')
+ .attr('aria-expanded', false)
+
+ this.$trigger
+ .addClass('collapsed')
+ .attr('aria-expanded', false)
+
+ this.transitioning = 1
+
+ var complete = function () {
+ this.transitioning = 0
+ this.$element
+ .removeClass('collapsing')
+ .addClass('collapse')
+ .trigger('hidden.bs.collapse')
+ }
+
+ if (!$.support.transition) return complete.call(this)
+
+ this.$element
+ [dimension](0)
+ .one('bsTransitionEnd', $.proxy(complete, this))
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
+ }
+
+ Collapse.prototype.toggle = function () {
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
+ }
+
+ Collapse.prototype.getParent = function () {
+ return $(this.options.parent)
+ .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
+ .each($.proxy(function (i, element) {
+ var $element = $(element)
+ this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
+ }, this))
+ .end()
+ }
+
+ Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
+ var isOpen = $element.hasClass('in')
+
+ $element.attr('aria-expanded', isOpen)
+ $trigger
+ .toggleClass('collapsed', !isOpen)
+ .attr('aria-expanded', isOpen)
+ }
+
+ function getTargetFromTrigger($trigger) {
+ var href
+ var target = $trigger.attr('data-target')
+ || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
+
+ return $(target)
+ }
+
+
+ // COLLAPSE PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.collapse')
+ var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
+
+ if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
+ if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.collapse
+
+ $.fn.collapse = Plugin
+ $.fn.collapse.Constructor = Collapse
+
+
+ // COLLAPSE NO CONFLICT
+ // ====================
+
+ $.fn.collapse.noConflict = function () {
+ $.fn.collapse = old
+ return this
+ }
+
+
+ // COLLAPSE DATA-API
+ // =================
+
+ $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
+ var $this = $(this)
+
+ if (!$this.attr('data-target')) e.preventDefault()
+
+ var $target = getTargetFromTrigger($this)
+ var data = $target.data('bs.collapse')
+ var option = data ? 'toggle' : $this.data()
+
+ Plugin.call($target, option)
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: dropdown.js v3.3.7
+ * http://getbootstrap.com/javascript/#dropdowns
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // DROPDOWN CLASS DEFINITION
+ // =========================
+
+ var backdrop = '.dropdown-backdrop'
+ var toggle = '[data-toggle="dropdown"]'
+ var Dropdown = function (element) {
+ $(element).on('click.bs.dropdown', this.toggle)
+ }
+
+ Dropdown.VERSION = '3.3.7'
+
+ function getParent($this) {
+ var selector = $this.attr('data-target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+ }
+
+ var $parent = selector && $(selector)
+
+ return $parent && $parent.length ? $parent : $this.parent()
+ }
+
+ function clearMenus(e) {
+ if (e && e.which === 3) return
+ $(backdrop).remove()
+ $(toggle).each(function () {
+ var $this = $(this)
+ var $parent = getParent($this)
+ var relatedTarget = { relatedTarget: this }
+
+ if (!$parent.hasClass('open')) return
+
+ if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
+
+ $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
+
+ if (e.isDefaultPrevented()) return
+
+ $this.attr('aria-expanded', 'false')
+ $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
+ })
+ }
+
+ Dropdown.prototype.toggle = function (e) {
+ var $this = $(this)
+
+ if ($this.is('.disabled, :disabled')) return
+
+ var $parent = getParent($this)
+ var isActive = $parent.hasClass('open')
+
+ clearMenus()
+
+ if (!isActive) {
+ if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
+ // if mobile we use a backdrop because click events don't delegate
+ $(document.createElement('div'))
+ .addClass('dropdown-backdrop')
+ .insertAfter($(this))
+ .on('click', clearMenus)
+ }
+
+ var relatedTarget = { relatedTarget: this }
+ $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
+
+ if (e.isDefaultPrevented()) return
+
+ $this
+ .trigger('focus')
+ .attr('aria-expanded', 'true')
+
+ $parent
+ .toggleClass('open')
+ .trigger($.Event('shown.bs.dropdown', relatedTarget))
+ }
+
+ return false
+ }
+
+ Dropdown.prototype.keydown = function (e) {
+ if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
+
+ var $this = $(this)
+
+ e.preventDefault()
+ e.stopPropagation()
+
+ if ($this.is('.disabled, :disabled')) return
+
+ var $parent = getParent($this)
+ var isActive = $parent.hasClass('open')
+
+ if (!isActive && e.which != 27 || isActive && e.which == 27) {
+ if (e.which == 27) $parent.find(toggle).trigger('focus')
+ return $this.trigger('click')
+ }
+
+ var desc = ' li:not(.disabled):visible a'
+ var $items = $parent.find('.dropdown-menu' + desc)
+
+ if (!$items.length) return
+
+ var index = $items.index(e.target)
+
+ if (e.which == 38 && index > 0) index-- // up
+ if (e.which == 40 && index < $items.length - 1) index++ // down
+ if (!~index) index = 0
+
+ $items.eq(index).trigger('focus')
+ }
+
+
+ // DROPDOWN PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.dropdown')
+
+ if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ var old = $.fn.dropdown
+
+ $.fn.dropdown = Plugin
+ $.fn.dropdown.Constructor = Dropdown
+
+
+ // DROPDOWN NO CONFLICT
+ // ====================
+
+ $.fn.dropdown.noConflict = function () {
+ $.fn.dropdown = old
+ return this
+ }
+
+
+ // APPLY TO STANDARD DROPDOWN ELEMENTS
+ // ===================================
+
+ $(document)
+ .on('click.bs.dropdown.data-api', clearMenus)
+ .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
+ .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
+ .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
+ .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: modal.js v3.3.7
+ * http://getbootstrap.com/javascript/#modals
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // MODAL CLASS DEFINITION
+ // ======================
+
+ var Modal = function (element, options) {
+ this.options = options
+ this.$body = $(document.body)
+ this.$element = $(element)
+ this.$dialog = this.$element.find('.modal-dialog')
+ this.$backdrop = null
+ this.isShown = null
+ this.originalBodyPad = null
+ this.scrollbarWidth = 0
+ this.ignoreBackdropClick = false
+
+ if (this.options.remote) {
+ this.$element
+ .find('.modal-content')
+ .load(this.options.remote, $.proxy(function () {
+ this.$element.trigger('loaded.bs.modal')
+ }, this))
+ }
+ }
+
+ Modal.VERSION = '3.3.7'
+
+ Modal.TRANSITION_DURATION = 300
+ Modal.BACKDROP_TRANSITION_DURATION = 150
+
+ Modal.DEFAULTS = {
+ backdrop: true,
+ keyboard: true,
+ show: true
+ }
+
+ Modal.prototype.toggle = function (_relatedTarget) {
+ return this.isShown ? this.hide() : this.show(_relatedTarget)
+ }
+
+ Modal.prototype.show = function (_relatedTarget) {
+ var that = this
+ var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
+
+ this.$element.trigger(e)
+
+ if (this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = true
+
+ this.checkScrollbar()
+ this.setScrollbar()
+ this.$body.addClass('modal-open')
+
+ this.escape()
+ this.resize()
+
+ this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
+
+ this.$dialog.on('mousedown.dismiss.bs.modal', function () {
+ that.$element.one('mouseup.dismiss.bs.modal', function (e) {
+ if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
+ })
+ })
+
+ this.backdrop(function () {
+ var transition = $.support.transition && that.$element.hasClass('fade')
+
+ if (!that.$element.parent().length) {
+ that.$element.appendTo(that.$body) // don't move modals dom position
+ }
+
+ that.$element
+ .show()
+ .scrollTop(0)
+
+ that.adjustDialog()
+
+ if (transition) {
+ that.$element[0].offsetWidth // force reflow
+ }
+
+ that.$element.addClass('in')
+
+ that.enforceFocus()
+
+ var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
+
+ transition ?
+ that.$dialog // wait for modal to slide in
+ .one('bsTransitionEnd', function () {
+ that.$element.trigger('focus').trigger(e)
+ })
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ that.$element.trigger('focus').trigger(e)
+ })
+ }
+
+ Modal.prototype.hide = function (e) {
+ if (e) e.preventDefault()
+
+ e = $.Event('hide.bs.modal')
+
+ this.$element.trigger(e)
+
+ if (!this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = false
+
+ this.escape()
+ this.resize()
+
+ $(document).off('focusin.bs.modal')
+
+ this.$element
+ .removeClass('in')
+ .off('click.dismiss.bs.modal')
+ .off('mouseup.dismiss.bs.modal')
+
+ this.$dialog.off('mousedown.dismiss.bs.modal')
+
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$element
+ .one('bsTransitionEnd', $.proxy(this.hideModal, this))
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ this.hideModal()
+ }
+
+ Modal.prototype.enforceFocus = function () {
+ $(document)
+ .off('focusin.bs.modal') // guard against infinite focus loop
+ .on('focusin.bs.modal', $.proxy(function (e) {
+ if (document !== e.target &&
+ this.$element[0] !== e.target &&
+ !this.$element.has(e.target).length) {
+ this.$element.trigger('focus')
+ }
+ }, this))
+ }
+
+ Modal.prototype.escape = function () {
+ if (this.isShown && this.options.keyboard) {
+ this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
+ e.which == 27 && this.hide()
+ }, this))
+ } else if (!this.isShown) {
+ this.$element.off('keydown.dismiss.bs.modal')
+ }
+ }
+
+ Modal.prototype.resize = function () {
+ if (this.isShown) {
+ $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
+ } else {
+ $(window).off('resize.bs.modal')
+ }
+ }
+
+ Modal.prototype.hideModal = function () {
+ var that = this
+ this.$element.hide()
+ this.backdrop(function () {
+ that.$body.removeClass('modal-open')
+ that.resetAdjustments()
+ that.resetScrollbar()
+ that.$element.trigger('hidden.bs.modal')
+ })
+ }
+
+ Modal.prototype.removeBackdrop = function () {
+ this.$backdrop && this.$backdrop.remove()
+ this.$backdrop = null
+ }
+
+ Modal.prototype.backdrop = function (callback) {
+ var that = this
+ var animate = this.$element.hasClass('fade') ? 'fade' : ''
+
+ if (this.isShown && this.options.backdrop) {
+ var doAnimate = $.support.transition && animate
+
+ this.$backdrop = $(document.createElement('div'))
+ .addClass('modal-backdrop ' + animate)
+ .appendTo(this.$body)
+
+ this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
+ if (this.ignoreBackdropClick) {
+ this.ignoreBackdropClick = false
+ return
+ }
+ if (e.target !== e.currentTarget) return
+ this.options.backdrop == 'static'
+ ? this.$element[0].focus()
+ : this.hide()
+ }, this))
+
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
+
+ this.$backdrop.addClass('in')
+
+ if (!callback) return
+
+ doAnimate ?
+ this.$backdrop
+ .one('bsTransitionEnd', callback)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callback()
+
+ } else if (!this.isShown && this.$backdrop) {
+ this.$backdrop.removeClass('in')
+
+ var callbackRemove = function () {
+ that.removeBackdrop()
+ callback && callback()
+ }
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$backdrop
+ .one('bsTransitionEnd', callbackRemove)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callbackRemove()
+
+ } else if (callback) {
+ callback()
+ }
+ }
+
+ // these following methods are used to handle overflowing modals
+
+ Modal.prototype.handleUpdate = function () {
+ this.adjustDialog()
+ }
+
+ Modal.prototype.adjustDialog = function () {
+ var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
+
+ this.$element.css({
+ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
+ paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
+ })
+ }
+
+ Modal.prototype.resetAdjustments = function () {
+ this.$element.css({
+ paddingLeft: '',
+ paddingRight: ''
+ })
+ }
+
+ Modal.prototype.checkScrollbar = function () {
+ var fullWindowWidth = window.innerWidth
+ if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
+ var documentElementRect = document.documentElement.getBoundingClientRect()
+ fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
+ }
+ this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
+ this.scrollbarWidth = this.measureScrollbar()
+ }
+
+ Modal.prototype.setScrollbar = function () {
+ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
+ this.originalBodyPad = document.body.style.paddingRight || ''
+ if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
+ }
+
+ Modal.prototype.resetScrollbar = function () {
+ this.$body.css('padding-right', this.originalBodyPad)
+ }
+
+ Modal.prototype.measureScrollbar = function () { // thx walsh
+ var scrollDiv = document.createElement('div')
+ scrollDiv.className = 'modal-scrollbar-measure'
+ this.$body.append(scrollDiv)
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
+ this.$body[0].removeChild(scrollDiv)
+ return scrollbarWidth
+ }
+
+
+ // MODAL PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option, _relatedTarget) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.modal')
+ var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
+
+ if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
+ if (typeof option == 'string') data[option](_relatedTarget)
+ else if (options.show) data.show(_relatedTarget)
+ })
+ }
+
+ var old = $.fn.modal
+
+ $.fn.modal = Plugin
+ $.fn.modal.Constructor = Modal
+
+
+ // MODAL NO CONFLICT
+ // =================
+
+ $.fn.modal.noConflict = function () {
+ $.fn.modal = old
+ return this
+ }
+
+
+ // MODAL DATA-API
+ // ==============
+
+ $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
+ var $this = $(this)
+ var href = $this.attr('href')
+ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
+ var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
+
+ if ($this.is('a')) e.preventDefault()
+
+ $target.one('show.bs.modal', function (showEvent) {
+ if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
+ $target.one('hidden.bs.modal', function () {
+ $this.is(':visible') && $this.trigger('focus')
+ })
+ })
+ Plugin.call($target, option, this)
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: tooltip.js v3.3.7
+ * http://getbootstrap.com/javascript/#tooltip
+ * Inspired by the original jQuery.tipsy by Jason Frame
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // TOOLTIP PUBLIC CLASS DEFINITION
+ // ===============================
+
+ var Tooltip = function (element, options) {
+ this.type = null
+ this.options = null
+ this.enabled = null
+ this.timeout = null
+ this.hoverState = null
+ this.$element = null
+ this.inState = null
+
+ this.init('tooltip', element, options)
+ }
+
+ Tooltip.VERSION = '3.3.7'
+
+ Tooltip.TRANSITION_DURATION = 150
+
+ Tooltip.DEFAULTS = {
+ animation: true,
+ placement: 'top',
+ selector: false,
+ template: '
',
+ trigger: 'hover focus',
+ title: '',
+ delay: 0,
+ html: false,
+ container: false,
+ viewport: {
+ selector: 'body',
+ padding: 0
+ }
+ }
+
+ Tooltip.prototype.init = function (type, element, options) {
+ this.enabled = true
+ this.type = type
+ this.$element = $(element)
+ this.options = this.getOptions(options)
+ this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
+ this.inState = { click: false, hover: false, focus: false }
+
+ if (this.$element[0] instanceof document.constructor && !this.options.selector) {
+ throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
+ }
+
+ var triggers = this.options.trigger.split(' ')
+
+ for (var i = triggers.length; i--;) {
+ var trigger = triggers[i]
+
+ if (trigger == 'click') {
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
+ } else if (trigger != 'manual') {
+ var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
+ var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
+
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
+ }
+ }
+
+ this.options.selector ?
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
+ this.fixTitle()
+ }
+
+ Tooltip.prototype.getDefaults = function () {
+ return Tooltip.DEFAULTS
+ }
+
+ Tooltip.prototype.getOptions = function (options) {
+ options = $.extend({}, this.getDefaults(), this.$element.data(), options)
+
+ if (options.delay && typeof options.delay == 'number') {
+ options.delay = {
+ show: options.delay,
+ hide: options.delay
+ }
+ }
+
+ return options
+ }
+
+ Tooltip.prototype.getDelegateOptions = function () {
+ var options = {}
+ var defaults = this.getDefaults()
+
+ this._options && $.each(this._options, function (key, value) {
+ if (defaults[key] != value) options[key] = value
+ })
+
+ return options
+ }
+
+ Tooltip.prototype.enter = function (obj) {
+ var self = obj instanceof this.constructor ?
+ obj : $(obj.currentTarget).data('bs.' + this.type)
+
+ if (!self) {
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+ $(obj.currentTarget).data('bs.' + this.type, self)
+ }
+
+ if (obj instanceof $.Event) {
+ self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
+ }
+
+ if (self.tip().hasClass('in') || self.hoverState == 'in') {
+ self.hoverState = 'in'
+ return
+ }
+
+ clearTimeout(self.timeout)
+
+ self.hoverState = 'in'
+
+ if (!self.options.delay || !self.options.delay.show) return self.show()
+
+ self.timeout = setTimeout(function () {
+ if (self.hoverState == 'in') self.show()
+ }, self.options.delay.show)
+ }
+
+ Tooltip.prototype.isInStateTrue = function () {
+ for (var key in this.inState) {
+ if (this.inState[key]) return true
+ }
+
+ return false
+ }
+
+ Tooltip.prototype.leave = function (obj) {
+ var self = obj instanceof this.constructor ?
+ obj : $(obj.currentTarget).data('bs.' + this.type)
+
+ if (!self) {
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+ $(obj.currentTarget).data('bs.' + this.type, self)
+ }
+
+ if (obj instanceof $.Event) {
+ self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
+ }
+
+ if (self.isInStateTrue()) return
+
+ clearTimeout(self.timeout)
+
+ self.hoverState = 'out'
+
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
+
+ self.timeout = setTimeout(function () {
+ if (self.hoverState == 'out') self.hide()
+ }, self.options.delay.hide)
+ }
+
+ Tooltip.prototype.show = function () {
+ var e = $.Event('show.bs.' + this.type)
+
+ if (this.hasContent() && this.enabled) {
+ this.$element.trigger(e)
+
+ var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
+ if (e.isDefaultPrevented() || !inDom) return
+ var that = this
+
+ var $tip = this.tip()
+
+ var tipId = this.getUID(this.type)
+
+ this.setContent()
+ $tip.attr('id', tipId)
+ this.$element.attr('aria-describedby', tipId)
+
+ if (this.options.animation) $tip.addClass('fade')
+
+ var placement = typeof this.options.placement == 'function' ?
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
+ this.options.placement
+
+ var autoToken = /\s?auto?\s?/i
+ var autoPlace = autoToken.test(placement)
+ if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
+
+ $tip
+ .detach()
+ .css({ top: 0, left: 0, display: 'block' })
+ .addClass(placement)
+ .data('bs.' + this.type, this)
+
+ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
+ this.$element.trigger('inserted.bs.' + this.type)
+
+ var pos = this.getPosition()
+ var actualWidth = $tip[0].offsetWidth
+ var actualHeight = $tip[0].offsetHeight
+
+ if (autoPlace) {
+ var orgPlacement = placement
+ var viewportDim = this.getPosition(this.$viewport)
+
+ placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
+ placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
+ placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
+ placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
+ placement
+
+ $tip
+ .removeClass(orgPlacement)
+ .addClass(placement)
+ }
+
+ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
+
+ this.applyPlacement(calculatedOffset, placement)
+
+ var complete = function () {
+ var prevHoverState = that.hoverState
+ that.$element.trigger('shown.bs.' + that.type)
+ that.hoverState = null
+
+ if (prevHoverState == 'out') that.leave(that)
+ }
+
+ $.support.transition && this.$tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ complete()
+ }
+ }
+
+ Tooltip.prototype.applyPlacement = function (offset, placement) {
+ var $tip = this.tip()
+ var width = $tip[0].offsetWidth
+ var height = $tip[0].offsetHeight
+
+ // manually read margins because getBoundingClientRect includes difference
+ var marginTop = parseInt($tip.css('margin-top'), 10)
+ var marginLeft = parseInt($tip.css('margin-left'), 10)
+
+ // we must check for NaN for ie 8/9
+ if (isNaN(marginTop)) marginTop = 0
+ if (isNaN(marginLeft)) marginLeft = 0
+
+ offset.top += marginTop
+ offset.left += marginLeft
+
+ // $.fn.offset doesn't round pixel values
+ // so we use setOffset directly with our own function B-0
+ $.offset.setOffset($tip[0], $.extend({
+ using: function (props) {
+ $tip.css({
+ top: Math.round(props.top),
+ left: Math.round(props.left)
+ })
+ }
+ }, offset), 0)
+
+ $tip.addClass('in')
+
+ // check to see if placing tip in new offset caused the tip to resize itself
+ var actualWidth = $tip[0].offsetWidth
+ var actualHeight = $tip[0].offsetHeight
+
+ if (placement == 'top' && actualHeight != height) {
+ offset.top = offset.top + height - actualHeight
+ }
+
+ var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
+
+ if (delta.left) offset.left += delta.left
+ else offset.top += delta.top
+
+ var isVertical = /top|bottom/.test(placement)
+ var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
+ var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
+
+ $tip.offset(offset)
+ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
+ }
+
+ Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
+ this.arrow()
+ .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
+ .css(isVertical ? 'top' : 'left', '')
+ }
+
+ Tooltip.prototype.setContent = function () {
+ var $tip = this.tip()
+ var title = this.getTitle()
+
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
+ $tip.removeClass('fade in top bottom left right')
+ }
+
+ Tooltip.prototype.hide = function (callback) {
+ var that = this
+ var $tip = $(this.$tip)
+ var e = $.Event('hide.bs.' + this.type)
+
+ function complete() {
+ if (that.hoverState != 'in') $tip.detach()
+ if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
+ that.$element
+ .removeAttr('aria-describedby')
+ .trigger('hidden.bs.' + that.type)
+ }
+ callback && callback()
+ }
+
+ this.$element.trigger(e)
+
+ if (e.isDefaultPrevented()) return
+
+ $tip.removeClass('in')
+
+ $.support.transition && $tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ complete()
+
+ this.hoverState = null
+
+ return this
+ }
+
+ Tooltip.prototype.fixTitle = function () {
+ var $e = this.$element
+ if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
+ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
+ }
+ }
+
+ Tooltip.prototype.hasContent = function () {
+ return this.getTitle()
+ }
+
+ Tooltip.prototype.getPosition = function ($element) {
+ $element = $element || this.$element
+
+ var el = $element[0]
+ var isBody = el.tagName == 'BODY'
+
+ var elRect = el.getBoundingClientRect()
+ if (elRect.width == null) {
+ // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
+ elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
+ }
+ var isSvg = window.SVGElement && el instanceof window.SVGElement
+ // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
+ // See https://github.com/twbs/bootstrap/issues/20280
+ var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
+ var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
+ var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
+
+ return $.extend({}, elRect, scroll, outerDims, elOffset)
+ }
+
+ Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
+ return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
+ placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
+ placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
+ /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
+
+ }
+
+ Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
+ var delta = { top: 0, left: 0 }
+ if (!this.$viewport) return delta
+
+ var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
+ var viewportDimensions = this.getPosition(this.$viewport)
+
+ if (/right|left/.test(placement)) {
+ var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
+ var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
+ if (topEdgeOffset < viewportDimensions.top) { // top overflow
+ delta.top = viewportDimensions.top - topEdgeOffset
+ } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
+ delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
+ }
+ } else {
+ var leftEdgeOffset = pos.left - viewportPadding
+ var rightEdgeOffset = pos.left + viewportPadding + actualWidth
+ if (leftEdgeOffset < viewportDimensions.left) { // left overflow
+ delta.left = viewportDimensions.left - leftEdgeOffset
+ } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
+ delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
+ }
+ }
+
+ return delta
+ }
+
+ Tooltip.prototype.getTitle = function () {
+ var title
+ var $e = this.$element
+ var o = this.options
+
+ title = $e.attr('data-original-title')
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
+
+ return title
+ }
+
+ Tooltip.prototype.getUID = function (prefix) {
+ do prefix += ~~(Math.random() * 1000000)
+ while (document.getElementById(prefix))
+ return prefix
+ }
+
+ Tooltip.prototype.tip = function () {
+ if (!this.$tip) {
+ this.$tip = $(this.options.template)
+ if (this.$tip.length != 1) {
+ throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
+ }
+ }
+ return this.$tip
+ }
+
+ Tooltip.prototype.arrow = function () {
+ return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
+ }
+
+ Tooltip.prototype.enable = function () {
+ this.enabled = true
+ }
+
+ Tooltip.prototype.disable = function () {
+ this.enabled = false
+ }
+
+ Tooltip.prototype.toggleEnabled = function () {
+ this.enabled = !this.enabled
+ }
+
+ Tooltip.prototype.toggle = function (e) {
+ var self = this
+ if (e) {
+ self = $(e.currentTarget).data('bs.' + this.type)
+ if (!self) {
+ self = new this.constructor(e.currentTarget, this.getDelegateOptions())
+ $(e.currentTarget).data('bs.' + this.type, self)
+ }
+ }
+
+ if (e) {
+ self.inState.click = !self.inState.click
+ if (self.isInStateTrue()) self.enter(self)
+ else self.leave(self)
+ } else {
+ self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
+ }
+ }
+
+ Tooltip.prototype.destroy = function () {
+ var that = this
+ clearTimeout(this.timeout)
+ this.hide(function () {
+ that.$element.off('.' + that.type).removeData('bs.' + that.type)
+ if (that.$tip) {
+ that.$tip.detach()
+ }
+ that.$tip = null
+ that.$arrow = null
+ that.$viewport = null
+ that.$element = null
+ })
+ }
+
+
+ // TOOLTIP PLUGIN DEFINITION
+ // =========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.tooltip')
+ var options = typeof option == 'object' && option
+
+ if (!data && /destroy|hide/.test(option)) return
+ if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.tooltip
+
+ $.fn.tooltip = Plugin
+ $.fn.tooltip.Constructor = Tooltip
+
+
+ // TOOLTIP NO CONFLICT
+ // ===================
+
+ $.fn.tooltip.noConflict = function () {
+ $.fn.tooltip = old
+ return this
+ }
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: popover.js v3.3.7
+ * http://getbootstrap.com/javascript/#popovers
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // POPOVER PUBLIC CLASS DEFINITION
+ // ===============================
+
+ var Popover = function (element, options) {
+ this.init('popover', element, options)
+ }
+
+ if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
+
+ Popover.VERSION = '3.3.7'
+
+ Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
+ placement: 'right',
+ trigger: 'click',
+ content: '',
+ template: '
'
+ })
+
+
+ // NOTE: POPOVER EXTENDS tooltip.js
+ // ================================
+
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
+
+ Popover.prototype.constructor = Popover
+
+ Popover.prototype.getDefaults = function () {
+ return Popover.DEFAULTS
+ }
+
+ Popover.prototype.setContent = function () {
+ var $tip = this.tip()
+ var title = this.getTitle()
+ var content = this.getContent()
+
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
+ $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
+ this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
+ ](content)
+
+ $tip.removeClass('fade top bottom left right in')
+
+ // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
+ // this manually by checking the contents.
+ if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
+ }
+
+ Popover.prototype.hasContent = function () {
+ return this.getTitle() || this.getContent()
+ }
+
+ Popover.prototype.getContent = function () {
+ var $e = this.$element
+ var o = this.options
+
+ return $e.attr('data-content')
+ || (typeof o.content == 'function' ?
+ o.content.call($e[0]) :
+ o.content)
+ }
+
+ Popover.prototype.arrow = function () {
+ return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
+ }
+
+
+ // POPOVER PLUGIN DEFINITION
+ // =========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.popover')
+ var options = typeof option == 'object' && option
+
+ if (!data && /destroy|hide/.test(option)) return
+ if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.popover
+
+ $.fn.popover = Plugin
+ $.fn.popover.Constructor = Popover
+
+
+ // POPOVER NO CONFLICT
+ // ===================
+
+ $.fn.popover.noConflict = function () {
+ $.fn.popover = old
+ return this
+ }
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: scrollspy.js v3.3.7
+ * http://getbootstrap.com/javascript/#scrollspy
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // SCROLLSPY CLASS DEFINITION
+ // ==========================
+
+ function ScrollSpy(element, options) {
+ this.$body = $(document.body)
+ this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
+ this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
+ this.selector = (this.options.target || '') + ' .nav li > a'
+ this.offsets = []
+ this.targets = []
+ this.activeTarget = null
+ this.scrollHeight = 0
+
+ this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
+ this.refresh()
+ this.process()
+ }
+
+ ScrollSpy.VERSION = '3.3.7'
+
+ ScrollSpy.DEFAULTS = {
+ offset: 10
+ }
+
+ ScrollSpy.prototype.getScrollHeight = function () {
+ return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
+ }
+
+ ScrollSpy.prototype.refresh = function () {
+ var that = this
+ var offsetMethod = 'offset'
+ var offsetBase = 0
+
+ this.offsets = []
+ this.targets = []
+ this.scrollHeight = this.getScrollHeight()
+
+ if (!$.isWindow(this.$scrollElement[0])) {
+ offsetMethod = 'position'
+ offsetBase = this.$scrollElement.scrollTop()
+ }
+
+ this.$body
+ .find(this.selector)
+ .map(function () {
+ var $el = $(this)
+ var href = $el.data('target') || $el.attr('href')
+ var $href = /^#./.test(href) && $(href)
+
+ return ($href
+ && $href.length
+ && $href.is(':visible')
+ && [[$href[offsetMethod]().top + offsetBase, href]]) || null
+ })
+ .sort(function (a, b) { return a[0] - b[0] })
+ .each(function () {
+ that.offsets.push(this[0])
+ that.targets.push(this[1])
+ })
+ }
+
+ ScrollSpy.prototype.process = function () {
+ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
+ var scrollHeight = this.getScrollHeight()
+ var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
+ var offsets = this.offsets
+ var targets = this.targets
+ var activeTarget = this.activeTarget
+ var i
+
+ if (this.scrollHeight != scrollHeight) {
+ this.refresh()
+ }
+
+ if (scrollTop >= maxScroll) {
+ return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
+ }
+
+ if (activeTarget && scrollTop < offsets[0]) {
+ this.activeTarget = null
+ return this.clear()
+ }
+
+ for (i = offsets.length; i--;) {
+ activeTarget != targets[i]
+ && scrollTop >= offsets[i]
+ && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
+ && this.activate(targets[i])
+ }
+ }
+
+ ScrollSpy.prototype.activate = function (target) {
+ this.activeTarget = target
+
+ this.clear()
+
+ var selector = this.selector +
+ '[data-target="' + target + '"],' +
+ this.selector + '[href="' + target + '"]'
+
+ var active = $(selector)
+ .parents('li')
+ .addClass('active')
+
+ if (active.parent('.dropdown-menu').length) {
+ active = active
+ .closest('li.dropdown')
+ .addClass('active')
+ }
+
+ active.trigger('activate.bs.scrollspy')
+ }
+
+ ScrollSpy.prototype.clear = function () {
+ $(this.selector)
+ .parentsUntil(this.options.target, '.active')
+ .removeClass('active')
+ }
+
+
+ // SCROLLSPY PLUGIN DEFINITION
+ // ===========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.scrollspy')
+ var options = typeof option == 'object' && option
+
+ if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.scrollspy
+
+ $.fn.scrollspy = Plugin
+ $.fn.scrollspy.Constructor = ScrollSpy
+
+
+ // SCROLLSPY NO CONFLICT
+ // =====================
+
+ $.fn.scrollspy.noConflict = function () {
+ $.fn.scrollspy = old
+ return this
+ }
+
+
+ // SCROLLSPY DATA-API
+ // ==================
+
+ $(window).on('load.bs.scrollspy.data-api', function () {
+ $('[data-spy="scroll"]').each(function () {
+ var $spy = $(this)
+ Plugin.call($spy, $spy.data())
+ })
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: tab.js v3.3.7
+ * http://getbootstrap.com/javascript/#tabs
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // TAB CLASS DEFINITION
+ // ====================
+
+ var Tab = function (element) {
+ // jscs:disable requireDollarBeforejQueryAssignment
+ this.element = $(element)
+ // jscs:enable requireDollarBeforejQueryAssignment
+ }
+
+ Tab.VERSION = '3.3.7'
+
+ Tab.TRANSITION_DURATION = 150
+
+ Tab.prototype.show = function () {
+ var $this = this.element
+ var $ul = $this.closest('ul:not(.dropdown-menu)')
+ var selector = $this.data('target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+ }
+
+ if ($this.parent('li').hasClass('active')) return
+
+ var $previous = $ul.find('.active:last a')
+ var hideEvent = $.Event('hide.bs.tab', {
+ relatedTarget: $this[0]
+ })
+ var showEvent = $.Event('show.bs.tab', {
+ relatedTarget: $previous[0]
+ })
+
+ $previous.trigger(hideEvent)
+ $this.trigger(showEvent)
+
+ if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
+
+ var $target = $(selector)
+
+ this.activate($this.closest('li'), $ul)
+ this.activate($target, $target.parent(), function () {
+ $previous.trigger({
+ type: 'hidden.bs.tab',
+ relatedTarget: $this[0]
+ })
+ $this.trigger({
+ type: 'shown.bs.tab',
+ relatedTarget: $previous[0]
+ })
+ })
+ }
+
+ Tab.prototype.activate = function (element, container, callback) {
+ var $active = container.find('> .active')
+ var transition = callback
+ && $.support.transition
+ && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
+
+ function next() {
+ $active
+ .removeClass('active')
+ .find('> .dropdown-menu > .active')
+ .removeClass('active')
+ .end()
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', false)
+
+ element
+ .addClass('active')
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', true)
+
+ if (transition) {
+ element[0].offsetWidth // reflow for transition
+ element.addClass('in')
+ } else {
+ element.removeClass('fade')
+ }
+
+ if (element.parent('.dropdown-menu').length) {
+ element
+ .closest('li.dropdown')
+ .addClass('active')
+ .end()
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', true)
+ }
+
+ callback && callback()
+ }
+
+ $active.length && transition ?
+ $active
+ .one('bsTransitionEnd', next)
+ .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
+ next()
+
+ $active.removeClass('in')
+ }
+
+
+ // TAB PLUGIN DEFINITION
+ // =====================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.tab')
+
+ if (!data) $this.data('bs.tab', (data = new Tab(this)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.tab
+
+ $.fn.tab = Plugin
+ $.fn.tab.Constructor = Tab
+
+
+ // TAB NO CONFLICT
+ // ===============
+
+ $.fn.tab.noConflict = function () {
+ $.fn.tab = old
+ return this
+ }
+
+
+ // TAB DATA-API
+ // ============
+
+ var clickHandler = function (e) {
+ e.preventDefault()
+ Plugin.call($(this), 'show')
+ }
+
+ $(document)
+ .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
+ .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: affix.js v3.3.7
+ * http://getbootstrap.com/javascript/#affix
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // AFFIX CLASS DEFINITION
+ // ======================
+
+ var Affix = function (element, options) {
+ this.options = $.extend({}, Affix.DEFAULTS, options)
+
+ this.$target = $(this.options.target)
+ .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
+ .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
+
+ this.$element = $(element)
+ this.affixed = null
+ this.unpin = null
+ this.pinnedOffset = null
+
+ this.checkPosition()
+ }
+
+ Affix.VERSION = '3.3.7'
+
+ Affix.RESET = 'affix affix-top affix-bottom'
+
+ Affix.DEFAULTS = {
+ offset: 0,
+ target: window
+ }
+
+ Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
+ var scrollTop = this.$target.scrollTop()
+ var position = this.$element.offset()
+ var targetHeight = this.$target.height()
+
+ if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
+
+ if (this.affixed == 'bottom') {
+ if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
+ return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
+ }
+
+ var initializing = this.affixed == null
+ var colliderTop = initializing ? scrollTop : position.top
+ var colliderHeight = initializing ? targetHeight : height
+
+ if (offsetTop != null && scrollTop <= offsetTop) return 'top'
+ if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
+
+ return false
+ }
+
+ Affix.prototype.getPinnedOffset = function () {
+ if (this.pinnedOffset) return this.pinnedOffset
+ this.$element.removeClass(Affix.RESET).addClass('affix')
+ var scrollTop = this.$target.scrollTop()
+ var position = this.$element.offset()
+ return (this.pinnedOffset = position.top - scrollTop)
+ }
+
+ Affix.prototype.checkPositionWithEventLoop = function () {
+ setTimeout($.proxy(this.checkPosition, this), 1)
+ }
+
+ Affix.prototype.checkPosition = function () {
+ if (!this.$element.is(':visible')) return
+
+ var height = this.$element.height()
+ var offset = this.options.offset
+ var offsetTop = offset.top
+ var offsetBottom = offset.bottom
+ var scrollHeight = Math.max($(document).height(), $(document.body).height())
+
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
+ if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
+
+ var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
+
+ if (this.affixed != affix) {
+ if (this.unpin != null) this.$element.css('top', '')
+
+ var affixType = 'affix' + (affix ? '-' + affix : '')
+ var e = $.Event(affixType + '.bs.affix')
+
+ this.$element.trigger(e)
+
+ if (e.isDefaultPrevented()) return
+
+ this.affixed = affix
+ this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
+
+ this.$element
+ .removeClass(Affix.RESET)
+ .addClass(affixType)
+ .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
+ }
+
+ if (affix == 'bottom') {
+ this.$element.offset({
+ top: scrollHeight - height - offsetBottom
+ })
+ }
+ }
+
+
+ // AFFIX PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.affix')
+ var options = typeof option == 'object' && option
+
+ if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.affix
+
+ $.fn.affix = Plugin
+ $.fn.affix.Constructor = Affix
+
+
+ // AFFIX NO CONFLICT
+ // =================
+
+ $.fn.affix.noConflict = function () {
+ $.fn.affix = old
+ return this
+ }
+
+
+ // AFFIX DATA-API
+ // ==============
+
+ $(window).on('load', function () {
+ $('[data-spy="affix"]').each(function () {
+ var $spy = $(this)
+ var data = $spy.data()
+
+ data.offset = data.offset || {}
+
+ if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
+ if (data.offsetTop != null) data.offset.top = data.offsetTop
+
+ Plugin.call($spy, data)
+ })
+ })
+
+}(jQuery);
diff --git a/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/js/npm.js b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/js/npm.js
new file mode 100644
index 0000000..bf6aa80
--- /dev/null
+++ b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/bootstrap/dist/js/npm.js
@@ -0,0 +1,13 @@
+// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
+require('../../js/transition.js')
+require('../../js/alert.js')
+require('../../js/button.js')
+require('../../js/carousel.js')
+require('../../js/collapse.js')
+require('../../js/dropdown.js')
+require('../../js/modal.js')
+require('../../js/tooltip.js')
+require('../../js/popover.js')
+require('../../js/scrollspy.js')
+require('../../js/tab.js')
+require('../../js/affix.js')
\ No newline at end of file
diff --git a/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/chart/Chart.bundle.js b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/chart/Chart.bundle.js
new file mode 100644
index 0000000..db74e2f
--- /dev/null
+++ b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/chart/Chart.bundle.js
@@ -0,0 +1,18919 @@
+/*!
+ * Chart.js
+ * http://chartjs.org/
+ * Version: 2.7.2
+ *
+ * Copyright 2018 Chart.js Contributors
+ * Released under the MIT license
+ * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
+ */
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chart = f()}})(function(){var define,module,exports;return (function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o
lum2) {
+ return (lum1 + 0.05) / (lum2 + 0.05);
+ }
+ return (lum2 + 0.05) / (lum1 + 0.05);
+ },
+
+ level: function (color2) {
+ var contrastRatio = this.contrast(color2);
+ if (contrastRatio >= 7.1) {
+ return 'AAA';
+ }
+
+ return (contrastRatio >= 4.5) ? 'AA' : '';
+ },
+
+ dark: function () {
+ // YIQ equation from http://24ways.org/2010/calculating-color-contrast
+ var rgb = this.values.rgb;
+ var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;
+ return yiq < 128;
+ },
+
+ light: function () {
+ return !this.dark();
+ },
+
+ negate: function () {
+ var rgb = [];
+ for (var i = 0; i < 3; i++) {
+ rgb[i] = 255 - this.values.rgb[i];
+ }
+ this.setValues('rgb', rgb);
+ return this;
+ },
+
+ lighten: function (ratio) {
+ var hsl = this.values.hsl;
+ hsl[2] += hsl[2] * ratio;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ darken: function (ratio) {
+ var hsl = this.values.hsl;
+ hsl[2] -= hsl[2] * ratio;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ saturate: function (ratio) {
+ var hsl = this.values.hsl;
+ hsl[1] += hsl[1] * ratio;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ desaturate: function (ratio) {
+ var hsl = this.values.hsl;
+ hsl[1] -= hsl[1] * ratio;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ whiten: function (ratio) {
+ var hwb = this.values.hwb;
+ hwb[1] += hwb[1] * ratio;
+ this.setValues('hwb', hwb);
+ return this;
+ },
+
+ blacken: function (ratio) {
+ var hwb = this.values.hwb;
+ hwb[2] += hwb[2] * ratio;
+ this.setValues('hwb', hwb);
+ return this;
+ },
+
+ greyscale: function () {
+ var rgb = this.values.rgb;
+ // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
+ var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;
+ this.setValues('rgb', [val, val, val]);
+ return this;
+ },
+
+ clearer: function (ratio) {
+ var alpha = this.values.alpha;
+ this.setValues('alpha', alpha - (alpha * ratio));
+ return this;
+ },
+
+ opaquer: function (ratio) {
+ var alpha = this.values.alpha;
+ this.setValues('alpha', alpha + (alpha * ratio));
+ return this;
+ },
+
+ rotate: function (degrees) {
+ var hsl = this.values.hsl;
+ var hue = (hsl[0] + degrees) % 360;
+ hsl[0] = hue < 0 ? 360 + hue : hue;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ /**
+ * Ported from sass implementation in C
+ * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209
+ */
+ mix: function (mixinColor, weight) {
+ var color1 = this;
+ var color2 = mixinColor;
+ var p = weight === undefined ? 0.5 : weight;
+
+ var w = 2 * p - 1;
+ var a = color1.alpha() - color2.alpha();
+
+ var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ return this
+ .rgb(
+ w1 * color1.red() + w2 * color2.red(),
+ w1 * color1.green() + w2 * color2.green(),
+ w1 * color1.blue() + w2 * color2.blue()
+ )
+ .alpha(color1.alpha() * p + color2.alpha() * (1 - p));
+ },
+
+ toJSON: function () {
+ return this.rgb();
+ },
+
+ clone: function () {
+ // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,
+ // making the final build way to big to embed in Chart.js. So let's do it manually,
+ // assuming that values to clone are 1 dimension arrays containing only numbers,
+ // except 'alpha' which is a number.
+ var result = new Color();
+ var source = this.values;
+ var target = result.values;
+ var value, type;
+
+ for (var prop in source) {
+ if (source.hasOwnProperty(prop)) {
+ value = source[prop];
+ type = ({}).toString.call(value);
+ if (type === '[object Array]') {
+ target[prop] = value.slice(0);
+ } else if (type === '[object Number]') {
+ target[prop] = value;
+ } else {
+ console.error('unexpected color value:', value);
+ }
+ }
+ }
+
+ return result;
+ }
+};
+
+Color.prototype.spaces = {
+ rgb: ['red', 'green', 'blue'],
+ hsl: ['hue', 'saturation', 'lightness'],
+ hsv: ['hue', 'saturation', 'value'],
+ hwb: ['hue', 'whiteness', 'blackness'],
+ cmyk: ['cyan', 'magenta', 'yellow', 'black']
+};
+
+Color.prototype.maxes = {
+ rgb: [255, 255, 255],
+ hsl: [360, 100, 100],
+ hsv: [360, 100, 100],
+ hwb: [360, 100, 100],
+ cmyk: [100, 100, 100, 100]
+};
+
+Color.prototype.getValues = function (space) {
+ var values = this.values;
+ var vals = {};
+
+ for (var i = 0; i < space.length; i++) {
+ vals[space.charAt(i)] = values[space][i];
+ }
+
+ if (values.alpha !== 1) {
+ vals.a = values.alpha;
+ }
+
+ // {r: 255, g: 255, b: 255, a: 0.4}
+ return vals;
+};
+
+Color.prototype.setValues = function (space, vals) {
+ var values = this.values;
+ var spaces = this.spaces;
+ var maxes = this.maxes;
+ var alpha = 1;
+ var i;
+
+ this.valid = true;
+
+ if (space === 'alpha') {
+ alpha = vals;
+ } else if (vals.length) {
+ // [10, 10, 10]
+ values[space] = vals.slice(0, space.length);
+ alpha = vals[space.length];
+ } else if (vals[space.charAt(0)] !== undefined) {
+ // {r: 10, g: 10, b: 10}
+ for (i = 0; i < space.length; i++) {
+ values[space][i] = vals[space.charAt(i)];
+ }
+
+ alpha = vals.a;
+ } else if (vals[spaces[space][0]] !== undefined) {
+ // {red: 10, green: 10, blue: 10}
+ var chans = spaces[space];
+
+ for (i = 0; i < space.length; i++) {
+ values[space][i] = vals[chans[i]];
+ }
+
+ alpha = vals.alpha;
+ }
+
+ values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));
+
+ if (space === 'alpha') {
+ return false;
+ }
+
+ var capped;
+
+ // cap values of the space prior converting all values
+ for (i = 0; i < space.length; i++) {
+ capped = Math.max(0, Math.min(maxes[space][i], values[space][i]));
+ values[space][i] = Math.round(capped);
+ }
+
+ // convert to all the other color spaces
+ for (var sname in spaces) {
+ if (sname !== space) {
+ values[sname] = convert[space][sname](values[space]);
+ }
+ }
+
+ return true;
+};
+
+Color.prototype.setSpace = function (space, args) {
+ var vals = args[0];
+
+ if (vals === undefined) {
+ // color.rgb()
+ return this.getValues(space);
+ }
+
+ // color.rgb(10, 10, 10)
+ if (typeof vals === 'number') {
+ vals = Array.prototype.slice.call(args);
+ }
+
+ this.setValues(space, vals);
+ return this;
+};
+
+Color.prototype.setChannel = function (space, index, val) {
+ var svalues = this.values[space];
+ if (val === undefined) {
+ // color.red()
+ return svalues[index];
+ } else if (val === svalues[index]) {
+ // color.red(color.red())
+ return this;
+ }
+
+ // color.red(100)
+ svalues[index] = val;
+ this.setValues(space, svalues);
+
+ return this;
+};
+
+if (typeof window !== 'undefined') {
+ window.Color = Color;
+}
+
+module.exports = Color;
+
+},{"1":1,"4":4}],3:[function(require,module,exports){
+/* MIT license */
+
+module.exports = {
+ rgb2hsl: rgb2hsl,
+ rgb2hsv: rgb2hsv,
+ rgb2hwb: rgb2hwb,
+ rgb2cmyk: rgb2cmyk,
+ rgb2keyword: rgb2keyword,
+ rgb2xyz: rgb2xyz,
+ rgb2lab: rgb2lab,
+ rgb2lch: rgb2lch,
+
+ hsl2rgb: hsl2rgb,
+ hsl2hsv: hsl2hsv,
+ hsl2hwb: hsl2hwb,
+ hsl2cmyk: hsl2cmyk,
+ hsl2keyword: hsl2keyword,
+
+ hsv2rgb: hsv2rgb,
+ hsv2hsl: hsv2hsl,
+ hsv2hwb: hsv2hwb,
+ hsv2cmyk: hsv2cmyk,
+ hsv2keyword: hsv2keyword,
+
+ hwb2rgb: hwb2rgb,
+ hwb2hsl: hwb2hsl,
+ hwb2hsv: hwb2hsv,
+ hwb2cmyk: hwb2cmyk,
+ hwb2keyword: hwb2keyword,
+
+ cmyk2rgb: cmyk2rgb,
+ cmyk2hsl: cmyk2hsl,
+ cmyk2hsv: cmyk2hsv,
+ cmyk2hwb: cmyk2hwb,
+ cmyk2keyword: cmyk2keyword,
+
+ keyword2rgb: keyword2rgb,
+ keyword2hsl: keyword2hsl,
+ keyword2hsv: keyword2hsv,
+ keyword2hwb: keyword2hwb,
+ keyword2cmyk: keyword2cmyk,
+ keyword2lab: keyword2lab,
+ keyword2xyz: keyword2xyz,
+
+ xyz2rgb: xyz2rgb,
+ xyz2lab: xyz2lab,
+ xyz2lch: xyz2lch,
+
+ lab2xyz: lab2xyz,
+ lab2rgb: lab2rgb,
+ lab2lch: lab2lch,
+
+ lch2lab: lch2lab,
+ lch2xyz: lch2xyz,
+ lch2rgb: lch2rgb
+}
+
+
+function rgb2hsl(rgb) {
+ var r = rgb[0]/255,
+ g = rgb[1]/255,
+ b = rgb[2]/255,
+ min = Math.min(r, g, b),
+ max = Math.max(r, g, b),
+ delta = max - min,
+ h, s, l;
+
+ if (max == min)
+ h = 0;
+ else if (r == max)
+ h = (g - b) / delta;
+ else if (g == max)
+ h = 2 + (b - r) / delta;
+ else if (b == max)
+ h = 4 + (r - g)/ delta;
+
+ h = Math.min(h * 60, 360);
+
+ if (h < 0)
+ h += 360;
+
+ l = (min + max) / 2;
+
+ if (max == min)
+ s = 0;
+ else if (l <= 0.5)
+ s = delta / (max + min);
+ else
+ s = delta / (2 - max - min);
+
+ return [h, s * 100, l * 100];
+}
+
+function rgb2hsv(rgb) {
+ var r = rgb[0],
+ g = rgb[1],
+ b = rgb[2],
+ min = Math.min(r, g, b),
+ max = Math.max(r, g, b),
+ delta = max - min,
+ h, s, v;
+
+ if (max == 0)
+ s = 0;
+ else
+ s = (delta/max * 1000)/10;
+
+ if (max == min)
+ h = 0;
+ else if (r == max)
+ h = (g - b) / delta;
+ else if (g == max)
+ h = 2 + (b - r) / delta;
+ else if (b == max)
+ h = 4 + (r - g) / delta;
+
+ h = Math.min(h * 60, 360);
+
+ if (h < 0)
+ h += 360;
+
+ v = ((max / 255) * 1000) / 10;
+
+ return [h, s, v];
+}
+
+function rgb2hwb(rgb) {
+ var r = rgb[0],
+ g = rgb[1],
+ b = rgb[2],
+ h = rgb2hsl(rgb)[0],
+ w = 1/255 * Math.min(r, Math.min(g, b)),
+ b = 1 - 1/255 * Math.max(r, Math.max(g, b));
+
+ return [h, w * 100, b * 100];
+}
+
+function rgb2cmyk(rgb) {
+ var r = rgb[0] / 255,
+ g = rgb[1] / 255,
+ b = rgb[2] / 255,
+ c, m, y, k;
+
+ k = Math.min(1 - r, 1 - g, 1 - b);
+ c = (1 - r - k) / (1 - k) || 0;
+ m = (1 - g - k) / (1 - k) || 0;
+ y = (1 - b - k) / (1 - k) || 0;
+ return [c * 100, m * 100, y * 100, k * 100];
+}
+
+function rgb2keyword(rgb) {
+ return reverseKeywords[JSON.stringify(rgb)];
+}
+
+function rgb2xyz(rgb) {
+ var r = rgb[0] / 255,
+ g = rgb[1] / 255,
+ b = rgb[2] / 255;
+
+ // assume sRGB
+ r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
+ g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
+ b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
+
+ var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
+ var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
+ var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
+
+ return [x * 100, y *100, z * 100];
+}
+
+function rgb2lab(rgb) {
+ var xyz = rgb2xyz(rgb),
+ x = xyz[0],
+ y = xyz[1],
+ z = xyz[2],
+ l, a, b;
+
+ x /= 95.047;
+ y /= 100;
+ z /= 108.883;
+
+ x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
+ y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
+ z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
+
+ l = (116 * y) - 16;
+ a = 500 * (x - y);
+ b = 200 * (y - z);
+
+ return [l, a, b];
+}
+
+function rgb2lch(args) {
+ return lab2lch(rgb2lab(args));
+}
+
+function hsl2rgb(hsl) {
+ var h = hsl[0] / 360,
+ s = hsl[1] / 100,
+ l = hsl[2] / 100,
+ t1, t2, t3, rgb, val;
+
+ if (s == 0) {
+ val = l * 255;
+ return [val, val, val];
+ }
+
+ if (l < 0.5)
+ t2 = l * (1 + s);
+ else
+ t2 = l + s - l * s;
+ t1 = 2 * l - t2;
+
+ rgb = [0, 0, 0];
+ for (var i = 0; i < 3; i++) {
+ t3 = h + 1 / 3 * - (i - 1);
+ t3 < 0 && t3++;
+ t3 > 1 && t3--;
+
+ if (6 * t3 < 1)
+ val = t1 + (t2 - t1) * 6 * t3;
+ else if (2 * t3 < 1)
+ val = t2;
+ else if (3 * t3 < 2)
+ val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
+ else
+ val = t1;
+
+ rgb[i] = val * 255;
+ }
+
+ return rgb;
+}
+
+function hsl2hsv(hsl) {
+ var h = hsl[0],
+ s = hsl[1] / 100,
+ l = hsl[2] / 100,
+ sv, v;
+
+ if(l === 0) {
+ // no need to do calc on black
+ // also avoids divide by 0 error
+ return [0, 0, 0];
+ }
+
+ l *= 2;
+ s *= (l <= 1) ? l : 2 - l;
+ v = (l + s) / 2;
+ sv = (2 * s) / (l + s);
+ return [h, sv * 100, v * 100];
+}
+
+function hsl2hwb(args) {
+ return rgb2hwb(hsl2rgb(args));
+}
+
+function hsl2cmyk(args) {
+ return rgb2cmyk(hsl2rgb(args));
+}
+
+function hsl2keyword(args) {
+ return rgb2keyword(hsl2rgb(args));
+}
+
+
+function hsv2rgb(hsv) {
+ var h = hsv[0] / 60,
+ s = hsv[1] / 100,
+ v = hsv[2] / 100,
+ hi = Math.floor(h) % 6;
+
+ var f = h - Math.floor(h),
+ p = 255 * v * (1 - s),
+ q = 255 * v * (1 - (s * f)),
+ t = 255 * v * (1 - (s * (1 - f))),
+ v = 255 * v;
+
+ switch(hi) {
+ case 0:
+ return [v, t, p];
+ case 1:
+ return [q, v, p];
+ case 2:
+ return [p, v, t];
+ case 3:
+ return [p, q, v];
+ case 4:
+ return [t, p, v];
+ case 5:
+ return [v, p, q];
+ }
+}
+
+function hsv2hsl(hsv) {
+ var h = hsv[0],
+ s = hsv[1] / 100,
+ v = hsv[2] / 100,
+ sl, l;
+
+ l = (2 - s) * v;
+ sl = s * v;
+ sl /= (l <= 1) ? l : 2 - l;
+ sl = sl || 0;
+ l /= 2;
+ return [h, sl * 100, l * 100];
+}
+
+function hsv2hwb(args) {
+ return rgb2hwb(hsv2rgb(args))
+}
+
+function hsv2cmyk(args) {
+ return rgb2cmyk(hsv2rgb(args));
+}
+
+function hsv2keyword(args) {
+ return rgb2keyword(hsv2rgb(args));
+}
+
+// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
+function hwb2rgb(hwb) {
+ var h = hwb[0] / 360,
+ wh = hwb[1] / 100,
+ bl = hwb[2] / 100,
+ ratio = wh + bl,
+ i, v, f, n;
+
+ // wh + bl cant be > 1
+ if (ratio > 1) {
+ wh /= ratio;
+ bl /= ratio;
+ }
+
+ i = Math.floor(6 * h);
+ v = 1 - bl;
+ f = 6 * h - i;
+ if ((i & 0x01) != 0) {
+ f = 1 - f;
+ }
+ n = wh + f * (v - wh); // linear interpolation
+
+ switch (i) {
+ default:
+ case 6:
+ case 0: r = v; g = n; b = wh; break;
+ case 1: r = n; g = v; b = wh; break;
+ case 2: r = wh; g = v; b = n; break;
+ case 3: r = wh; g = n; b = v; break;
+ case 4: r = n; g = wh; b = v; break;
+ case 5: r = v; g = wh; b = n; break;
+ }
+
+ return [r * 255, g * 255, b * 255];
+}
+
+function hwb2hsl(args) {
+ return rgb2hsl(hwb2rgb(args));
+}
+
+function hwb2hsv(args) {
+ return rgb2hsv(hwb2rgb(args));
+}
+
+function hwb2cmyk(args) {
+ return rgb2cmyk(hwb2rgb(args));
+}
+
+function hwb2keyword(args) {
+ return rgb2keyword(hwb2rgb(args));
+}
+
+function cmyk2rgb(cmyk) {
+ var c = cmyk[0] / 100,
+ m = cmyk[1] / 100,
+ y = cmyk[2] / 100,
+ k = cmyk[3] / 100,
+ r, g, b;
+
+ r = 1 - Math.min(1, c * (1 - k) + k);
+ g = 1 - Math.min(1, m * (1 - k) + k);
+ b = 1 - Math.min(1, y * (1 - k) + k);
+ return [r * 255, g * 255, b * 255];
+}
+
+function cmyk2hsl(args) {
+ return rgb2hsl(cmyk2rgb(args));
+}
+
+function cmyk2hsv(args) {
+ return rgb2hsv(cmyk2rgb(args));
+}
+
+function cmyk2hwb(args) {
+ return rgb2hwb(cmyk2rgb(args));
+}
+
+function cmyk2keyword(args) {
+ return rgb2keyword(cmyk2rgb(args));
+}
+
+
+function xyz2rgb(xyz) {
+ var x = xyz[0] / 100,
+ y = xyz[1] / 100,
+ z = xyz[2] / 100,
+ r, g, b;
+
+ r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
+ g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
+ b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
+
+ // assume sRGB
+ r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
+ : r = (r * 12.92);
+
+ g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
+ : g = (g * 12.92);
+
+ b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
+ : b = (b * 12.92);
+
+ r = Math.min(Math.max(0, r), 1);
+ g = Math.min(Math.max(0, g), 1);
+ b = Math.min(Math.max(0, b), 1);
+
+ return [r * 255, g * 255, b * 255];
+}
+
+function xyz2lab(xyz) {
+ var x = xyz[0],
+ y = xyz[1],
+ z = xyz[2],
+ l, a, b;
+
+ x /= 95.047;
+ y /= 100;
+ z /= 108.883;
+
+ x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
+ y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
+ z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
+
+ l = (116 * y) - 16;
+ a = 500 * (x - y);
+ b = 200 * (y - z);
+
+ return [l, a, b];
+}
+
+function xyz2lch(args) {
+ return lab2lch(xyz2lab(args));
+}
+
+function lab2xyz(lab) {
+ var l = lab[0],
+ a = lab[1],
+ b = lab[2],
+ x, y, z, y2;
+
+ if (l <= 8) {
+ y = (l * 100) / 903.3;
+ y2 = (7.787 * (y / 100)) + (16 / 116);
+ } else {
+ y = 100 * Math.pow((l + 16) / 116, 3);
+ y2 = Math.pow(y / 100, 1/3);
+ }
+
+ x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3);
+
+ z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3);
+
+ return [x, y, z];
+}
+
+function lab2lch(lab) {
+ var l = lab[0],
+ a = lab[1],
+ b = lab[2],
+ hr, h, c;
+
+ hr = Math.atan2(b, a);
+ h = hr * 360 / 2 / Math.PI;
+ if (h < 0) {
+ h += 360;
+ }
+ c = Math.sqrt(a * a + b * b);
+ return [l, c, h];
+}
+
+function lab2rgb(args) {
+ return xyz2rgb(lab2xyz(args));
+}
+
+function lch2lab(lch) {
+ var l = lch[0],
+ c = lch[1],
+ h = lch[2],
+ a, b, hr;
+
+ hr = h / 360 * 2 * Math.PI;
+ a = c * Math.cos(hr);
+ b = c * Math.sin(hr);
+ return [l, a, b];
+}
+
+function lch2xyz(args) {
+ return lab2xyz(lch2lab(args));
+}
+
+function lch2rgb(args) {
+ return lab2rgb(lch2lab(args));
+}
+
+function keyword2rgb(keyword) {
+ return cssKeywords[keyword];
+}
+
+function keyword2hsl(args) {
+ return rgb2hsl(keyword2rgb(args));
+}
+
+function keyword2hsv(args) {
+ return rgb2hsv(keyword2rgb(args));
+}
+
+function keyword2hwb(args) {
+ return rgb2hwb(keyword2rgb(args));
+}
+
+function keyword2cmyk(args) {
+ return rgb2cmyk(keyword2rgb(args));
+}
+
+function keyword2lab(args) {
+ return rgb2lab(keyword2rgb(args));
+}
+
+function keyword2xyz(args) {
+ return rgb2xyz(keyword2rgb(args));
+}
+
+var cssKeywords = {
+ aliceblue: [240,248,255],
+ antiquewhite: [250,235,215],
+ aqua: [0,255,255],
+ aquamarine: [127,255,212],
+ azure: [240,255,255],
+ beige: [245,245,220],
+ bisque: [255,228,196],
+ black: [0,0,0],
+ blanchedalmond: [255,235,205],
+ blue: [0,0,255],
+ blueviolet: [138,43,226],
+ brown: [165,42,42],
+ burlywood: [222,184,135],
+ cadetblue: [95,158,160],
+ chartreuse: [127,255,0],
+ chocolate: [210,105,30],
+ coral: [255,127,80],
+ cornflowerblue: [100,149,237],
+ cornsilk: [255,248,220],
+ crimson: [220,20,60],
+ cyan: [0,255,255],
+ darkblue: [0,0,139],
+ darkcyan: [0,139,139],
+ darkgoldenrod: [184,134,11],
+ darkgray: [169,169,169],
+ darkgreen: [0,100,0],
+ darkgrey: [169,169,169],
+ darkkhaki: [189,183,107],
+ darkmagenta: [139,0,139],
+ darkolivegreen: [85,107,47],
+ darkorange: [255,140,0],
+ darkorchid: [153,50,204],
+ darkred: [139,0,0],
+ darksalmon: [233,150,122],
+ darkseagreen: [143,188,143],
+ darkslateblue: [72,61,139],
+ darkslategray: [47,79,79],
+ darkslategrey: [47,79,79],
+ darkturquoise: [0,206,209],
+ darkviolet: [148,0,211],
+ deeppink: [255,20,147],
+ deepskyblue: [0,191,255],
+ dimgray: [105,105,105],
+ dimgrey: [105,105,105],
+ dodgerblue: [30,144,255],
+ firebrick: [178,34,34],
+ floralwhite: [255,250,240],
+ forestgreen: [34,139,34],
+ fuchsia: [255,0,255],
+ gainsboro: [220,220,220],
+ ghostwhite: [248,248,255],
+ gold: [255,215,0],
+ goldenrod: [218,165,32],
+ gray: [128,128,128],
+ green: [0,128,0],
+ greenyellow: [173,255,47],
+ grey: [128,128,128],
+ honeydew: [240,255,240],
+ hotpink: [255,105,180],
+ indianred: [205,92,92],
+ indigo: [75,0,130],
+ ivory: [255,255,240],
+ khaki: [240,230,140],
+ lavender: [230,230,250],
+ lavenderblush: [255,240,245],
+ lawngreen: [124,252,0],
+ lemonchiffon: [255,250,205],
+ lightblue: [173,216,230],
+ lightcoral: [240,128,128],
+ lightcyan: [224,255,255],
+ lightgoldenrodyellow: [250,250,210],
+ lightgray: [211,211,211],
+ lightgreen: [144,238,144],
+ lightgrey: [211,211,211],
+ lightpink: [255,182,193],
+ lightsalmon: [255,160,122],
+ lightseagreen: [32,178,170],
+ lightskyblue: [135,206,250],
+ lightslategray: [119,136,153],
+ lightslategrey: [119,136,153],
+ lightsteelblue: [176,196,222],
+ lightyellow: [255,255,224],
+ lime: [0,255,0],
+ limegreen: [50,205,50],
+ linen: [250,240,230],
+ magenta: [255,0,255],
+ maroon: [128,0,0],
+ mediumaquamarine: [102,205,170],
+ mediumblue: [0,0,205],
+ mediumorchid: [186,85,211],
+ mediumpurple: [147,112,219],
+ mediumseagreen: [60,179,113],
+ mediumslateblue: [123,104,238],
+ mediumspringgreen: [0,250,154],
+ mediumturquoise: [72,209,204],
+ mediumvioletred: [199,21,133],
+ midnightblue: [25,25,112],
+ mintcream: [245,255,250],
+ mistyrose: [255,228,225],
+ moccasin: [255,228,181],
+ navajowhite: [255,222,173],
+ navy: [0,0,128],
+ oldlace: [253,245,230],
+ olive: [128,128,0],
+ olivedrab: [107,142,35],
+ orange: [255,165,0],
+ orangered: [255,69,0],
+ orchid: [218,112,214],
+ palegoldenrod: [238,232,170],
+ palegreen: [152,251,152],
+ paleturquoise: [175,238,238],
+ palevioletred: [219,112,147],
+ papayawhip: [255,239,213],
+ peachpuff: [255,218,185],
+ peru: [205,133,63],
+ pink: [255,192,203],
+ plum: [221,160,221],
+ powderblue: [176,224,230],
+ purple: [128,0,128],
+ rebeccapurple: [102, 51, 153],
+ red: [255,0,0],
+ rosybrown: [188,143,143],
+ royalblue: [65,105,225],
+ saddlebrown: [139,69,19],
+ salmon: [250,128,114],
+ sandybrown: [244,164,96],
+ seagreen: [46,139,87],
+ seashell: [255,245,238],
+ sienna: [160,82,45],
+ silver: [192,192,192],
+ skyblue: [135,206,235],
+ slateblue: [106,90,205],
+ slategray: [112,128,144],
+ slategrey: [112,128,144],
+ snow: [255,250,250],
+ springgreen: [0,255,127],
+ steelblue: [70,130,180],
+ tan: [210,180,140],
+ teal: [0,128,128],
+ thistle: [216,191,216],
+ tomato: [255,99,71],
+ turquoise: [64,224,208],
+ violet: [238,130,238],
+ wheat: [245,222,179],
+ white: [255,255,255],
+ whitesmoke: [245,245,245],
+ yellow: [255,255,0],
+ yellowgreen: [154,205,50]
+};
+
+var reverseKeywords = {};
+for (var key in cssKeywords) {
+ reverseKeywords[JSON.stringify(cssKeywords[key])] = key;
+}
+
+},{}],4:[function(require,module,exports){
+var conversions = require(3);
+
+var convert = function() {
+ return new Converter();
+}
+
+for (var func in conversions) {
+ // export Raw versions
+ convert[func + "Raw"] = (function(func) {
+ // accept array or plain args
+ return function(arg) {
+ if (typeof arg == "number")
+ arg = Array.prototype.slice.call(arguments);
+ return conversions[func](arg);
+ }
+ })(func);
+
+ var pair = /(\w+)2(\w+)/.exec(func),
+ from = pair[1],
+ to = pair[2];
+
+ // export rgb2hsl and ["rgb"]["hsl"]
+ convert[from] = convert[from] || {};
+
+ convert[from][to] = convert[func] = (function(func) {
+ return function(arg) {
+ if (typeof arg == "number")
+ arg = Array.prototype.slice.call(arguments);
+
+ var val = conversions[func](arg);
+ if (typeof val == "string" || val === undefined)
+ return val; // keyword
+
+ for (var i = 0; i < val.length; i++)
+ val[i] = Math.round(val[i]);
+ return val;
+ }
+ })(func);
+}
+
+
+/* Converter does lazy conversion and caching */
+var Converter = function() {
+ this.convs = {};
+};
+
+/* Either get the values for a space or
+ set the values for a space, depending on args */
+Converter.prototype.routeSpace = function(space, args) {
+ var values = args[0];
+ if (values === undefined) {
+ // color.rgb()
+ return this.getValues(space);
+ }
+ // color.rgb(10, 10, 10)
+ if (typeof values == "number") {
+ values = Array.prototype.slice.call(args);
+ }
+
+ return this.setValues(space, values);
+};
+
+/* Set the values for a space, invalidating cache */
+Converter.prototype.setValues = function(space, values) {
+ this.space = space;
+ this.convs = {};
+ this.convs[space] = values;
+ return this;
+};
+
+/* Get the values for a space. If there's already
+ a conversion for the space, fetch it, otherwise
+ compute it */
+Converter.prototype.getValues = function(space) {
+ var vals = this.convs[space];
+ if (!vals) {
+ var fspace = this.space,
+ from = this.convs[fspace];
+ vals = convert[fspace][space](from);
+
+ this.convs[space] = vals;
+ }
+ return vals;
+};
+
+["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) {
+ Converter.prototype[space] = function(vals) {
+ return this.routeSpace(space, arguments);
+ }
+});
+
+module.exports = convert;
+},{"3":3}],5:[function(require,module,exports){
+'use strict'
+
+module.exports = {
+ "aliceblue": [240, 248, 255],
+ "antiquewhite": [250, 235, 215],
+ "aqua": [0, 255, 255],
+ "aquamarine": [127, 255, 212],
+ "azure": [240, 255, 255],
+ "beige": [245, 245, 220],
+ "bisque": [255, 228, 196],
+ "black": [0, 0, 0],
+ "blanchedalmond": [255, 235, 205],
+ "blue": [0, 0, 255],
+ "blueviolet": [138, 43, 226],
+ "brown": [165, 42, 42],
+ "burlywood": [222, 184, 135],
+ "cadetblue": [95, 158, 160],
+ "chartreuse": [127, 255, 0],
+ "chocolate": [210, 105, 30],
+ "coral": [255, 127, 80],
+ "cornflowerblue": [100, 149, 237],
+ "cornsilk": [255, 248, 220],
+ "crimson": [220, 20, 60],
+ "cyan": [0, 255, 255],
+ "darkblue": [0, 0, 139],
+ "darkcyan": [0, 139, 139],
+ "darkgoldenrod": [184, 134, 11],
+ "darkgray": [169, 169, 169],
+ "darkgreen": [0, 100, 0],
+ "darkgrey": [169, 169, 169],
+ "darkkhaki": [189, 183, 107],
+ "darkmagenta": [139, 0, 139],
+ "darkolivegreen": [85, 107, 47],
+ "darkorange": [255, 140, 0],
+ "darkorchid": [153, 50, 204],
+ "darkred": [139, 0, 0],
+ "darksalmon": [233, 150, 122],
+ "darkseagreen": [143, 188, 143],
+ "darkslateblue": [72, 61, 139],
+ "darkslategray": [47, 79, 79],
+ "darkslategrey": [47, 79, 79],
+ "darkturquoise": [0, 206, 209],
+ "darkviolet": [148, 0, 211],
+ "deeppink": [255, 20, 147],
+ "deepskyblue": [0, 191, 255],
+ "dimgray": [105, 105, 105],
+ "dimgrey": [105, 105, 105],
+ "dodgerblue": [30, 144, 255],
+ "firebrick": [178, 34, 34],
+ "floralwhite": [255, 250, 240],
+ "forestgreen": [34, 139, 34],
+ "fuchsia": [255, 0, 255],
+ "gainsboro": [220, 220, 220],
+ "ghostwhite": [248, 248, 255],
+ "gold": [255, 215, 0],
+ "goldenrod": [218, 165, 32],
+ "gray": [128, 128, 128],
+ "green": [0, 128, 0],
+ "greenyellow": [173, 255, 47],
+ "grey": [128, 128, 128],
+ "honeydew": [240, 255, 240],
+ "hotpink": [255, 105, 180],
+ "indianred": [205, 92, 92],
+ "indigo": [75, 0, 130],
+ "ivory": [255, 255, 240],
+ "khaki": [240, 230, 140],
+ "lavender": [230, 230, 250],
+ "lavenderblush": [255, 240, 245],
+ "lawngreen": [124, 252, 0],
+ "lemonchiffon": [255, 250, 205],
+ "lightblue": [173, 216, 230],
+ "lightcoral": [240, 128, 128],
+ "lightcyan": [224, 255, 255],
+ "lightgoldenrodyellow": [250, 250, 210],
+ "lightgray": [211, 211, 211],
+ "lightgreen": [144, 238, 144],
+ "lightgrey": [211, 211, 211],
+ "lightpink": [255, 182, 193],
+ "lightsalmon": [255, 160, 122],
+ "lightseagreen": [32, 178, 170],
+ "lightskyblue": [135, 206, 250],
+ "lightslategray": [119, 136, 153],
+ "lightslategrey": [119, 136, 153],
+ "lightsteelblue": [176, 196, 222],
+ "lightyellow": [255, 255, 224],
+ "lime": [0, 255, 0],
+ "limegreen": [50, 205, 50],
+ "linen": [250, 240, 230],
+ "magenta": [255, 0, 255],
+ "maroon": [128, 0, 0],
+ "mediumaquamarine": [102, 205, 170],
+ "mediumblue": [0, 0, 205],
+ "mediumorchid": [186, 85, 211],
+ "mediumpurple": [147, 112, 219],
+ "mediumseagreen": [60, 179, 113],
+ "mediumslateblue": [123, 104, 238],
+ "mediumspringgreen": [0, 250, 154],
+ "mediumturquoise": [72, 209, 204],
+ "mediumvioletred": [199, 21, 133],
+ "midnightblue": [25, 25, 112],
+ "mintcream": [245, 255, 250],
+ "mistyrose": [255, 228, 225],
+ "moccasin": [255, 228, 181],
+ "navajowhite": [255, 222, 173],
+ "navy": [0, 0, 128],
+ "oldlace": [253, 245, 230],
+ "olive": [128, 128, 0],
+ "olivedrab": [107, 142, 35],
+ "orange": [255, 165, 0],
+ "orangered": [255, 69, 0],
+ "orchid": [218, 112, 214],
+ "palegoldenrod": [238, 232, 170],
+ "palegreen": [152, 251, 152],
+ "paleturquoise": [175, 238, 238],
+ "palevioletred": [219, 112, 147],
+ "papayawhip": [255, 239, 213],
+ "peachpuff": [255, 218, 185],
+ "peru": [205, 133, 63],
+ "pink": [255, 192, 203],
+ "plum": [221, 160, 221],
+ "powderblue": [176, 224, 230],
+ "purple": [128, 0, 128],
+ "rebeccapurple": [102, 51, 153],
+ "red": [255, 0, 0],
+ "rosybrown": [188, 143, 143],
+ "royalblue": [65, 105, 225],
+ "saddlebrown": [139, 69, 19],
+ "salmon": [250, 128, 114],
+ "sandybrown": [244, 164, 96],
+ "seagreen": [46, 139, 87],
+ "seashell": [255, 245, 238],
+ "sienna": [160, 82, 45],
+ "silver": [192, 192, 192],
+ "skyblue": [135, 206, 235],
+ "slateblue": [106, 90, 205],
+ "slategray": [112, 128, 144],
+ "slategrey": [112, 128, 144],
+ "snow": [255, 250, 250],
+ "springgreen": [0, 255, 127],
+ "steelblue": [70, 130, 180],
+ "tan": [210, 180, 140],
+ "teal": [0, 128, 128],
+ "thistle": [216, 191, 216],
+ "tomato": [255, 99, 71],
+ "turquoise": [64, 224, 208],
+ "violet": [238, 130, 238],
+ "wheat": [245, 222, 179],
+ "white": [255, 255, 255],
+ "whitesmoke": [245, 245, 245],
+ "yellow": [255, 255, 0],
+ "yellowgreen": [154, 205, 50]
+};
+
+},{}],6:[function(require,module,exports){
+//! moment.js
+//! version : 2.20.1
+//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
+//! license : MIT
+//! momentjs.com
+
+;(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ global.moment = factory()
+}(this, (function () { 'use strict';
+
+var hookCallback;
+
+function hooks () {
+ return hookCallback.apply(null, arguments);
+}
+
+// This is done to register the method called with moment()
+// without creating circular dependencies.
+function setHookCallback (callback) {
+ hookCallback = callback;
+}
+
+function isArray(input) {
+ return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
+}
+
+function isObject(input) {
+ // IE8 will treat undefined and null as object if it wasn't for
+ // input != null
+ return input != null && Object.prototype.toString.call(input) === '[object Object]';
+}
+
+function isObjectEmpty(obj) {
+ if (Object.getOwnPropertyNames) {
+ return (Object.getOwnPropertyNames(obj).length === 0);
+ } else {
+ var k;
+ for (k in obj) {
+ if (obj.hasOwnProperty(k)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
+function isUndefined(input) {
+ return input === void 0;
+}
+
+function isNumber(input) {
+ return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
+}
+
+function isDate(input) {
+ return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
+}
+
+function map(arr, fn) {
+ var res = [], i;
+ for (i = 0; i < arr.length; ++i) {
+ res.push(fn(arr[i], i));
+ }
+ return res;
+}
+
+function hasOwnProp(a, b) {
+ return Object.prototype.hasOwnProperty.call(a, b);
+}
+
+function extend(a, b) {
+ for (var i in b) {
+ if (hasOwnProp(b, i)) {
+ a[i] = b[i];
+ }
+ }
+
+ if (hasOwnProp(b, 'toString')) {
+ a.toString = b.toString;
+ }
+
+ if (hasOwnProp(b, 'valueOf')) {
+ a.valueOf = b.valueOf;
+ }
+
+ return a;
+}
+
+function createUTC (input, format, locale, strict) {
+ return createLocalOrUTC(input, format, locale, strict, true).utc();
+}
+
+function defaultParsingFlags() {
+ // We need to deep clone this object.
+ return {
+ empty : false,
+ unusedTokens : [],
+ unusedInput : [],
+ overflow : -2,
+ charsLeftOver : 0,
+ nullInput : false,
+ invalidMonth : null,
+ invalidFormat : false,
+ userInvalidated : false,
+ iso : false,
+ parsedDateParts : [],
+ meridiem : null,
+ rfc2822 : false,
+ weekdayMismatch : false
+ };
+}
+
+function getParsingFlags(m) {
+ if (m._pf == null) {
+ m._pf = defaultParsingFlags();
+ }
+ return m._pf;
+}
+
+var some;
+if (Array.prototype.some) {
+ some = Array.prototype.some;
+} else {
+ some = function (fun) {
+ var t = Object(this);
+ var len = t.length >>> 0;
+
+ for (var i = 0; i < len; i++) {
+ if (i in t && fun.call(this, t[i], i, t)) {
+ return true;
+ }
+ }
+
+ return false;
+ };
+}
+
+function isValid(m) {
+ if (m._isValid == null) {
+ var flags = getParsingFlags(m);
+ var parsedParts = some.call(flags.parsedDateParts, function (i) {
+ return i != null;
+ });
+ var isNowValid = !isNaN(m._d.getTime()) &&
+ flags.overflow < 0 &&
+ !flags.empty &&
+ !flags.invalidMonth &&
+ !flags.invalidWeekday &&
+ !flags.weekdayMismatch &&
+ !flags.nullInput &&
+ !flags.invalidFormat &&
+ !flags.userInvalidated &&
+ (!flags.meridiem || (flags.meridiem && parsedParts));
+
+ if (m._strict) {
+ isNowValid = isNowValid &&
+ flags.charsLeftOver === 0 &&
+ flags.unusedTokens.length === 0 &&
+ flags.bigHour === undefined;
+ }
+
+ if (Object.isFrozen == null || !Object.isFrozen(m)) {
+ m._isValid = isNowValid;
+ }
+ else {
+ return isNowValid;
+ }
+ }
+ return m._isValid;
+}
+
+function createInvalid (flags) {
+ var m = createUTC(NaN);
+ if (flags != null) {
+ extend(getParsingFlags(m), flags);
+ }
+ else {
+ getParsingFlags(m).userInvalidated = true;
+ }
+
+ return m;
+}
+
+// Plugins that add properties should also add the key here (null value),
+// so we can properly clone ourselves.
+var momentProperties = hooks.momentProperties = [];
+
+function copyConfig(to, from) {
+ var i, prop, val;
+
+ if (!isUndefined(from._isAMomentObject)) {
+ to._isAMomentObject = from._isAMomentObject;
+ }
+ if (!isUndefined(from._i)) {
+ to._i = from._i;
+ }
+ if (!isUndefined(from._f)) {
+ to._f = from._f;
+ }
+ if (!isUndefined(from._l)) {
+ to._l = from._l;
+ }
+ if (!isUndefined(from._strict)) {
+ to._strict = from._strict;
+ }
+ if (!isUndefined(from._tzm)) {
+ to._tzm = from._tzm;
+ }
+ if (!isUndefined(from._isUTC)) {
+ to._isUTC = from._isUTC;
+ }
+ if (!isUndefined(from._offset)) {
+ to._offset = from._offset;
+ }
+ if (!isUndefined(from._pf)) {
+ to._pf = getParsingFlags(from);
+ }
+ if (!isUndefined(from._locale)) {
+ to._locale = from._locale;
+ }
+
+ if (momentProperties.length > 0) {
+ for (i = 0; i < momentProperties.length; i++) {
+ prop = momentProperties[i];
+ val = from[prop];
+ if (!isUndefined(val)) {
+ to[prop] = val;
+ }
+ }
+ }
+
+ return to;
+}
+
+var updateInProgress = false;
+
+// Moment prototype object
+function Moment(config) {
+ copyConfig(this, config);
+ this._d = new Date(config._d != null ? config._d.getTime() : NaN);
+ if (!this.isValid()) {
+ this._d = new Date(NaN);
+ }
+ // Prevent infinite loop in case updateOffset creates new moment
+ // objects.
+ if (updateInProgress === false) {
+ updateInProgress = true;
+ hooks.updateOffset(this);
+ updateInProgress = false;
+ }
+}
+
+function isMoment (obj) {
+ return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
+}
+
+function absFloor (number) {
+ if (number < 0) {
+ // -0 -> 0
+ return Math.ceil(number) || 0;
+ } else {
+ return Math.floor(number);
+ }
+}
+
+function toInt(argumentForCoercion) {
+ var coercedNumber = +argumentForCoercion,
+ value = 0;
+
+ if (coercedNumber !== 0 && isFinite(coercedNumber)) {
+ value = absFloor(coercedNumber);
+ }
+
+ return value;
+}
+
+// compare two arrays, return the number of differences
+function compareArrays(array1, array2, dontConvert) {
+ var len = Math.min(array1.length, array2.length),
+ lengthDiff = Math.abs(array1.length - array2.length),
+ diffs = 0,
+ i;
+ for (i = 0; i < len; i++) {
+ if ((dontConvert && array1[i] !== array2[i]) ||
+ (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
+ diffs++;
+ }
+ }
+ return diffs + lengthDiff;
+}
+
+function warn(msg) {
+ if (hooks.suppressDeprecationWarnings === false &&
+ (typeof console !== 'undefined') && console.warn) {
+ console.warn('Deprecation warning: ' + msg);
+ }
+}
+
+function deprecate(msg, fn) {
+ var firstTime = true;
+
+ return extend(function () {
+ if (hooks.deprecationHandler != null) {
+ hooks.deprecationHandler(null, msg);
+ }
+ if (firstTime) {
+ var args = [];
+ var arg;
+ for (var i = 0; i < arguments.length; i++) {
+ arg = '';
+ if (typeof arguments[i] === 'object') {
+ arg += '\n[' + i + '] ';
+ for (var key in arguments[0]) {
+ arg += key + ': ' + arguments[0][key] + ', ';
+ }
+ arg = arg.slice(0, -2); // Remove trailing comma and space
+ } else {
+ arg = arguments[i];
+ }
+ args.push(arg);
+ }
+ warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
+ firstTime = false;
+ }
+ return fn.apply(this, arguments);
+ }, fn);
+}
+
+var deprecations = {};
+
+function deprecateSimple(name, msg) {
+ if (hooks.deprecationHandler != null) {
+ hooks.deprecationHandler(name, msg);
+ }
+ if (!deprecations[name]) {
+ warn(msg);
+ deprecations[name] = true;
+ }
+}
+
+hooks.suppressDeprecationWarnings = false;
+hooks.deprecationHandler = null;
+
+function isFunction(input) {
+ return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
+}
+
+function set (config) {
+ var prop, i;
+ for (i in config) {
+ prop = config[i];
+ if (isFunction(prop)) {
+ this[i] = prop;
+ } else {
+ this['_' + i] = prop;
+ }
+ }
+ this._config = config;
+ // Lenient ordinal parsing accepts just a number in addition to
+ // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
+ // TODO: Remove "ordinalParse" fallback in next major release.
+ this._dayOfMonthOrdinalParseLenient = new RegExp(
+ (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
+ '|' + (/\d{1,2}/).source);
+}
+
+function mergeConfigs(parentConfig, childConfig) {
+ var res = extend({}, parentConfig), prop;
+ for (prop in childConfig) {
+ if (hasOwnProp(childConfig, prop)) {
+ if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
+ res[prop] = {};
+ extend(res[prop], parentConfig[prop]);
+ extend(res[prop], childConfig[prop]);
+ } else if (childConfig[prop] != null) {
+ res[prop] = childConfig[prop];
+ } else {
+ delete res[prop];
+ }
+ }
+ }
+ for (prop in parentConfig) {
+ if (hasOwnProp(parentConfig, prop) &&
+ !hasOwnProp(childConfig, prop) &&
+ isObject(parentConfig[prop])) {
+ // make sure changes to properties don't modify parent config
+ res[prop] = extend({}, res[prop]);
+ }
+ }
+ return res;
+}
+
+function Locale(config) {
+ if (config != null) {
+ this.set(config);
+ }
+}
+
+var keys;
+
+if (Object.keys) {
+ keys = Object.keys;
+} else {
+ keys = function (obj) {
+ var i, res = [];
+ for (i in obj) {
+ if (hasOwnProp(obj, i)) {
+ res.push(i);
+ }
+ }
+ return res;
+ };
+}
+
+var defaultCalendar = {
+ sameDay : '[Today at] LT',
+ nextDay : '[Tomorrow at] LT',
+ nextWeek : 'dddd [at] LT',
+ lastDay : '[Yesterday at] LT',
+ lastWeek : '[Last] dddd [at] LT',
+ sameElse : 'L'
+};
+
+function calendar (key, mom, now) {
+ var output = this._calendar[key] || this._calendar['sameElse'];
+ return isFunction(output) ? output.call(mom, now) : output;
+}
+
+var defaultLongDateFormat = {
+ LTS : 'h:mm:ss A',
+ LT : 'h:mm A',
+ L : 'MM/DD/YYYY',
+ LL : 'MMMM D, YYYY',
+ LLL : 'MMMM D, YYYY h:mm A',
+ LLLL : 'dddd, MMMM D, YYYY h:mm A'
+};
+
+function longDateFormat (key) {
+ var format = this._longDateFormat[key],
+ formatUpper = this._longDateFormat[key.toUpperCase()];
+
+ if (format || !formatUpper) {
+ return format;
+ }
+
+ this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
+ return val.slice(1);
+ });
+
+ return this._longDateFormat[key];
+}
+
+var defaultInvalidDate = 'Invalid date';
+
+function invalidDate () {
+ return this._invalidDate;
+}
+
+var defaultOrdinal = '%d';
+var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
+
+function ordinal (number) {
+ return this._ordinal.replace('%d', number);
+}
+
+var defaultRelativeTime = {
+ future : 'in %s',
+ past : '%s ago',
+ s : 'a few seconds',
+ ss : '%d 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'
+};
+
+function relativeTime (number, withoutSuffix, string, isFuture) {
+ var output = this._relativeTime[string];
+ return (isFunction(output)) ?
+ output(number, withoutSuffix, string, isFuture) :
+ output.replace(/%d/i, number);
+}
+
+function pastFuture (diff, output) {
+ var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
+ return isFunction(format) ? format(output) : format.replace(/%s/i, output);
+}
+
+var aliases = {};
+
+function addUnitAlias (unit, shorthand) {
+ var lowerCase = unit.toLowerCase();
+ aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
+}
+
+function normalizeUnits(units) {
+ return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
+}
+
+function normalizeObjectUnits(inputObject) {
+ var normalizedInput = {},
+ normalizedProp,
+ prop;
+
+ for (prop in inputObject) {
+ if (hasOwnProp(inputObject, prop)) {
+ normalizedProp = normalizeUnits(prop);
+ if (normalizedProp) {
+ normalizedInput[normalizedProp] = inputObject[prop];
+ }
+ }
+ }
+
+ return normalizedInput;
+}
+
+var priorities = {};
+
+function addUnitPriority(unit, priority) {
+ priorities[unit] = priority;
+}
+
+function getPrioritizedUnits(unitsObj) {
+ var units = [];
+ for (var u in unitsObj) {
+ units.push({unit: u, priority: priorities[u]});
+ }
+ units.sort(function (a, b) {
+ return a.priority - b.priority;
+ });
+ return units;
+}
+
+function zeroFill(number, targetLength, forceSign) {
+ var absNumber = '' + Math.abs(number),
+ zerosToFill = targetLength - absNumber.length,
+ sign = number >= 0;
+ return (sign ? (forceSign ? '+' : '') : '-') +
+ Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
+}
+
+var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
+
+var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
+
+var formatFunctions = {};
+
+var formatTokenFunctions = {};
+
+// token: 'M'
+// padded: ['MM', 2]
+// ordinal: 'Mo'
+// callback: function () { this.month() + 1 }
+function addFormatToken (token, padded, ordinal, callback) {
+ var func = callback;
+ if (typeof callback === 'string') {
+ func = function () {
+ return this[callback]();
+ };
+ }
+ if (token) {
+ formatTokenFunctions[token] = func;
+ }
+ if (padded) {
+ formatTokenFunctions[padded[0]] = function () {
+ return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
+ };
+ }
+ if (ordinal) {
+ formatTokenFunctions[ordinal] = function () {
+ return this.localeData().ordinal(func.apply(this, arguments), token);
+ };
+ }
+}
+
+function removeFormattingTokens(input) {
+ if (input.match(/\[[\s\S]/)) {
+ return input.replace(/^\[|\]$/g, '');
+ }
+ return input.replace(/\\/g, '');
+}
+
+function makeFormatFunction(format) {
+ var array = format.match(formattingTokens), i, length;
+
+ for (i = 0, length = array.length; i < length; i++) {
+ if (formatTokenFunctions[array[i]]) {
+ array[i] = formatTokenFunctions[array[i]];
+ } else {
+ array[i] = removeFormattingTokens(array[i]);
+ }
+ }
+
+ return function (mom) {
+ var output = '', i;
+ for (i = 0; i < length; i++) {
+ output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
+ }
+ return output;
+ };
+}
+
+// format date using native date object
+function formatMoment(m, format) {
+ if (!m.isValid()) {
+ return m.localeData().invalidDate();
+ }
+
+ format = expandFormat(format, m.localeData());
+ formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
+
+ return formatFunctions[format](m);
+}
+
+function expandFormat(format, locale) {
+ var i = 5;
+
+ function replaceLongDateFormatTokens(input) {
+ return locale.longDateFormat(input) || input;
+ }
+
+ localFormattingTokens.lastIndex = 0;
+ while (i >= 0 && localFormattingTokens.test(format)) {
+ format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
+ localFormattingTokens.lastIndex = 0;
+ i -= 1;
+ }
+
+ return format;
+}
+
+var match1 = /\d/; // 0 - 9
+var match2 = /\d\d/; // 00 - 99
+var match3 = /\d{3}/; // 000 - 999
+var match4 = /\d{4}/; // 0000 - 9999
+var match6 = /[+-]?\d{6}/; // -999999 - 999999
+var match1to2 = /\d\d?/; // 0 - 99
+var match3to4 = /\d\d\d\d?/; // 999 - 9999
+var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999
+var match1to3 = /\d{1,3}/; // 0 - 999
+var match1to4 = /\d{1,4}/; // 0 - 9999
+var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999
+
+var matchUnsigned = /\d+/; // 0 - inf
+var matchSigned = /[+-]?\d+/; // -inf - inf
+
+var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
+var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
+
+var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
+
+// any word (or two) characters or numbers including two/three word month in arabic.
+// includes scottish gaelic two word and hyphenated months
+var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;
+
+
+var regexes = {};
+
+function addRegexToken (token, regex, strictRegex) {
+ regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
+ return (isStrict && strictRegex) ? strictRegex : regex;
+ };
+}
+
+function getParseRegexForToken (token, config) {
+ if (!hasOwnProp(regexes, token)) {
+ return new RegExp(unescapeFormat(token));
+ }
+
+ return regexes[token](config._strict, config._locale);
+}
+
+// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
+function unescapeFormat(s) {
+ return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
+ return p1 || p2 || p3 || p4;
+ }));
+}
+
+function regexEscape(s) {
+ return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
+}
+
+var tokens = {};
+
+function addParseToken (token, callback) {
+ var i, func = callback;
+ if (typeof token === 'string') {
+ token = [token];
+ }
+ if (isNumber(callback)) {
+ func = function (input, array) {
+ array[callback] = toInt(input);
+ };
+ }
+ for (i = 0; i < token.length; i++) {
+ tokens[token[i]] = func;
+ }
+}
+
+function addWeekParseToken (token, callback) {
+ addParseToken(token, function (input, array, config, token) {
+ config._w = config._w || {};
+ callback(input, config._w, config, token);
+ });
+}
+
+function addTimeToArrayFromToken(token, input, config) {
+ if (input != null && hasOwnProp(tokens, token)) {
+ tokens[token](input, config._a, config, token);
+ }
+}
+
+var YEAR = 0;
+var MONTH = 1;
+var DATE = 2;
+var HOUR = 3;
+var MINUTE = 4;
+var SECOND = 5;
+var MILLISECOND = 6;
+var WEEK = 7;
+var WEEKDAY = 8;
+
+// FORMATTING
+
+addFormatToken('Y', 0, 0, function () {
+ var y = this.year();
+ return y <= 9999 ? '' + y : '+' + y;
+});
+
+addFormatToken(0, ['YY', 2], 0, function () {
+ return this.year() % 100;
+});
+
+addFormatToken(0, ['YYYY', 4], 0, 'year');
+addFormatToken(0, ['YYYYY', 5], 0, 'year');
+addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
+
+// ALIASES
+
+addUnitAlias('year', 'y');
+
+// PRIORITIES
+
+addUnitPriority('year', 1);
+
+// PARSING
+
+addRegexToken('Y', matchSigned);
+addRegexToken('YY', match1to2, match2);
+addRegexToken('YYYY', match1to4, match4);
+addRegexToken('YYYYY', match1to6, match6);
+addRegexToken('YYYYYY', match1to6, match6);
+
+addParseToken(['YYYYY', 'YYYYYY'], YEAR);
+addParseToken('YYYY', function (input, array) {
+ array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
+});
+addParseToken('YY', function (input, array) {
+ array[YEAR] = hooks.parseTwoDigitYear(input);
+});
+addParseToken('Y', function (input, array) {
+ array[YEAR] = parseInt(input, 10);
+});
+
+// HELPERS
+
+function daysInYear(year) {
+ return isLeapYear(year) ? 366 : 365;
+}
+
+function isLeapYear(year) {
+ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
+}
+
+// HOOKS
+
+hooks.parseTwoDigitYear = function (input) {
+ return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
+};
+
+// MOMENTS
+
+var getSetYear = makeGetSet('FullYear', true);
+
+function getIsLeapYear () {
+ return isLeapYear(this.year());
+}
+
+function makeGetSet (unit, keepTime) {
+ return function (value) {
+ if (value != null) {
+ set$1(this, unit, value);
+ hooks.updateOffset(this, keepTime);
+ return this;
+ } else {
+ return get(this, unit);
+ }
+ };
+}
+
+function get (mom, unit) {
+ return mom.isValid() ?
+ mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
+}
+
+function set$1 (mom, unit, value) {
+ if (mom.isValid() && !isNaN(value)) {
+ if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
+ mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
+ }
+ else {
+ mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
+ }
+ }
+}
+
+// MOMENTS
+
+function stringGet (units) {
+ units = normalizeUnits(units);
+ if (isFunction(this[units])) {
+ return this[units]();
+ }
+ return this;
+}
+
+
+function stringSet (units, value) {
+ if (typeof units === 'object') {
+ units = normalizeObjectUnits(units);
+ var prioritized = getPrioritizedUnits(units);
+ for (var i = 0; i < prioritized.length; i++) {
+ this[prioritized[i].unit](units[prioritized[i].unit]);
+ }
+ } else {
+ units = normalizeUnits(units);
+ if (isFunction(this[units])) {
+ return this[units](value);
+ }
+ }
+ return this;
+}
+
+function mod(n, x) {
+ return ((n % x) + x) % x;
+}
+
+var indexOf;
+
+if (Array.prototype.indexOf) {
+ indexOf = Array.prototype.indexOf;
+} else {
+ indexOf = function (o) {
+ // I know
+ var i;
+ for (i = 0; i < this.length; ++i) {
+ if (this[i] === o) {
+ return i;
+ }
+ }
+ return -1;
+ };
+}
+
+function daysInMonth(year, month) {
+ if (isNaN(year) || isNaN(month)) {
+ return NaN;
+ }
+ var modMonth = mod(month, 12);
+ year += (month - modMonth) / 12;
+ return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);
+}
+
+// FORMATTING
+
+addFormatToken('M', ['MM', 2], 'Mo', function () {
+ return this.month() + 1;
+});
+
+addFormatToken('MMM', 0, 0, function (format) {
+ return this.localeData().monthsShort(this, format);
+});
+
+addFormatToken('MMMM', 0, 0, function (format) {
+ return this.localeData().months(this, format);
+});
+
+// ALIASES
+
+addUnitAlias('month', 'M');
+
+// PRIORITY
+
+addUnitPriority('month', 8);
+
+// PARSING
+
+addRegexToken('M', match1to2);
+addRegexToken('MM', match1to2, match2);
+addRegexToken('MMM', function (isStrict, locale) {
+ return locale.monthsShortRegex(isStrict);
+});
+addRegexToken('MMMM', function (isStrict, locale) {
+ return locale.monthsRegex(isStrict);
+});
+
+addParseToken(['M', 'MM'], function (input, array) {
+ array[MONTH] = toInt(input) - 1;
+});
+
+addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
+ var month = config._locale.monthsParse(input, token, config._strict);
+ // if we didn't find a month name, mark the date as invalid.
+ if (month != null) {
+ array[MONTH] = month;
+ } else {
+ getParsingFlags(config).invalidMonth = input;
+ }
+});
+
+// LOCALES
+
+var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
+var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
+function localeMonths (m, format) {
+ if (!m) {
+ return isArray(this._months) ? this._months :
+ this._months['standalone'];
+ }
+ return isArray(this._months) ? this._months[m.month()] :
+ this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
+}
+
+var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
+function localeMonthsShort (m, format) {
+ if (!m) {
+ return isArray(this._monthsShort) ? this._monthsShort :
+ this._monthsShort['standalone'];
+ }
+ return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
+ this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
+}
+
+function handleStrictParse(monthName, format, strict) {
+ var i, ii, mom, llc = monthName.toLocaleLowerCase();
+ if (!this._monthsParse) {
+ // this is not used
+ this._monthsParse = [];
+ this._longMonthsParse = [];
+ this._shortMonthsParse = [];
+ for (i = 0; i < 12; ++i) {
+ mom = createUTC([2000, i]);
+ this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
+ this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
+ }
+ }
+
+ if (strict) {
+ if (format === 'MMM') {
+ ii = indexOf.call(this._shortMonthsParse, llc);
+ return ii !== -1 ? ii : null;
+ } else {
+ ii = indexOf.call(this._longMonthsParse, llc);
+ return ii !== -1 ? ii : null;
+ }
+ } else {
+ if (format === 'MMM') {
+ ii = indexOf.call(this._shortMonthsParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._longMonthsParse, llc);
+ return ii !== -1 ? ii : null;
+ } else {
+ ii = indexOf.call(this._longMonthsParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._shortMonthsParse, llc);
+ return ii !== -1 ? ii : null;
+ }
+ }
+}
+
+function localeMonthsParse (monthName, format, strict) {
+ var i, mom, regex;
+
+ if (this._monthsParseExact) {
+ return handleStrictParse.call(this, monthName, format, strict);
+ }
+
+ if (!this._monthsParse) {
+ this._monthsParse = [];
+ this._longMonthsParse = [];
+ this._shortMonthsParse = [];
+ }
+
+ // TODO: add sorting
+ // Sorting makes sure if one month (or abbr) is a prefix of another
+ // see sorting in computeMonthsParse
+ for (i = 0; i < 12; i++) {
+ // make the regex if we don't have it already
+ mom = createUTC([2000, i]);
+ if (strict && !this._longMonthsParse[i]) {
+ this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
+ this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
+ }
+ if (!strict && !this._monthsParse[i]) {
+ regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
+ this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
+ }
+ // test the regex
+ if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
+ return i;
+ } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
+ return i;
+ } else if (!strict && this._monthsParse[i].test(monthName)) {
+ return i;
+ }
+ }
+}
+
+// MOMENTS
+
+function setMonth (mom, value) {
+ var dayOfMonth;
+
+ if (!mom.isValid()) {
+ // No op
+ return mom;
+ }
+
+ if (typeof value === 'string') {
+ if (/^\d+$/.test(value)) {
+ value = toInt(value);
+ } else {
+ value = mom.localeData().monthsParse(value);
+ // TODO: Another silent failure?
+ if (!isNumber(value)) {
+ return mom;
+ }
+ }
+ }
+
+ dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
+ mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
+ return mom;
+}
+
+function getSetMonth (value) {
+ if (value != null) {
+ setMonth(this, value);
+ hooks.updateOffset(this, true);
+ return this;
+ } else {
+ return get(this, 'Month');
+ }
+}
+
+function getDaysInMonth () {
+ return daysInMonth(this.year(), this.month());
+}
+
+var defaultMonthsShortRegex = matchWord;
+function monthsShortRegex (isStrict) {
+ if (this._monthsParseExact) {
+ if (!hasOwnProp(this, '_monthsRegex')) {
+ computeMonthsParse.call(this);
+ }
+ if (isStrict) {
+ return this._monthsShortStrictRegex;
+ } else {
+ return this._monthsShortRegex;
+ }
+ } else {
+ if (!hasOwnProp(this, '_monthsShortRegex')) {
+ this._monthsShortRegex = defaultMonthsShortRegex;
+ }
+ return this._monthsShortStrictRegex && isStrict ?
+ this._monthsShortStrictRegex : this._monthsShortRegex;
+ }
+}
+
+var defaultMonthsRegex = matchWord;
+function monthsRegex (isStrict) {
+ if (this._monthsParseExact) {
+ if (!hasOwnProp(this, '_monthsRegex')) {
+ computeMonthsParse.call(this);
+ }
+ if (isStrict) {
+ return this._monthsStrictRegex;
+ } else {
+ return this._monthsRegex;
+ }
+ } else {
+ if (!hasOwnProp(this, '_monthsRegex')) {
+ this._monthsRegex = defaultMonthsRegex;
+ }
+ return this._monthsStrictRegex && isStrict ?
+ this._monthsStrictRegex : this._monthsRegex;
+ }
+}
+
+function computeMonthsParse () {
+ function cmpLenRev(a, b) {
+ return b.length - a.length;
+ }
+
+ var shortPieces = [], longPieces = [], mixedPieces = [],
+ i, mom;
+ for (i = 0; i < 12; i++) {
+ // make the regex if we don't have it already
+ mom = createUTC([2000, i]);
+ shortPieces.push(this.monthsShort(mom, ''));
+ longPieces.push(this.months(mom, ''));
+ mixedPieces.push(this.months(mom, ''));
+ mixedPieces.push(this.monthsShort(mom, ''));
+ }
+ // Sorting makes sure if one month (or abbr) is a prefix of another it
+ // will match the longer piece.
+ shortPieces.sort(cmpLenRev);
+ longPieces.sort(cmpLenRev);
+ mixedPieces.sort(cmpLenRev);
+ for (i = 0; i < 12; i++) {
+ shortPieces[i] = regexEscape(shortPieces[i]);
+ longPieces[i] = regexEscape(longPieces[i]);
+ }
+ for (i = 0; i < 24; i++) {
+ mixedPieces[i] = regexEscape(mixedPieces[i]);
+ }
+
+ this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
+ this._monthsShortRegex = this._monthsRegex;
+ this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
+ this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
+}
+
+function createDate (y, m, d, h, M, s, ms) {
+ // can't just apply() to create a date:
+ // https://stackoverflow.com/q/181348
+ var date = new Date(y, m, d, h, M, s, ms);
+
+ // the date constructor remaps years 0-99 to 1900-1999
+ if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
+ date.setFullYear(y);
+ }
+ return date;
+}
+
+function createUTCDate (y) {
+ var date = new Date(Date.UTC.apply(null, arguments));
+
+ // the Date.UTC function remaps years 0-99 to 1900-1999
+ if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
+ date.setUTCFullYear(y);
+ }
+ return date;
+}
+
+// start-of-first-week - start-of-year
+function firstWeekOffset(year, dow, doy) {
+ var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
+ fwd = 7 + dow - doy,
+ // first-week day local weekday -- which local weekday is fwd
+ fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
+
+ return -fwdlw + fwd - 1;
+}
+
+// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
+function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
+ var localWeekday = (7 + weekday - dow) % 7,
+ weekOffset = firstWeekOffset(year, dow, doy),
+ dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
+ resYear, resDayOfYear;
+
+ if (dayOfYear <= 0) {
+ resYear = year - 1;
+ resDayOfYear = daysInYear(resYear) + dayOfYear;
+ } else if (dayOfYear > daysInYear(year)) {
+ resYear = year + 1;
+ resDayOfYear = dayOfYear - daysInYear(year);
+ } else {
+ resYear = year;
+ resDayOfYear = dayOfYear;
+ }
+
+ return {
+ year: resYear,
+ dayOfYear: resDayOfYear
+ };
+}
+
+function weekOfYear(mom, dow, doy) {
+ var weekOffset = firstWeekOffset(mom.year(), dow, doy),
+ week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
+ resWeek, resYear;
+
+ if (week < 1) {
+ resYear = mom.year() - 1;
+ resWeek = week + weeksInYear(resYear, dow, doy);
+ } else if (week > weeksInYear(mom.year(), dow, doy)) {
+ resWeek = week - weeksInYear(mom.year(), dow, doy);
+ resYear = mom.year() + 1;
+ } else {
+ resYear = mom.year();
+ resWeek = week;
+ }
+
+ return {
+ week: resWeek,
+ year: resYear
+ };
+}
+
+function weeksInYear(year, dow, doy) {
+ var weekOffset = firstWeekOffset(year, dow, doy),
+ weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
+ return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
+}
+
+// FORMATTING
+
+addFormatToken('w', ['ww', 2], 'wo', 'week');
+addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
+
+// ALIASES
+
+addUnitAlias('week', 'w');
+addUnitAlias('isoWeek', 'W');
+
+// PRIORITIES
+
+addUnitPriority('week', 5);
+addUnitPriority('isoWeek', 5);
+
+// PARSING
+
+addRegexToken('w', match1to2);
+addRegexToken('ww', match1to2, match2);
+addRegexToken('W', match1to2);
+addRegexToken('WW', match1to2, match2);
+
+addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
+ week[token.substr(0, 1)] = toInt(input);
+});
+
+// HELPERS
+
+// LOCALES
+
+function localeWeek (mom) {
+ return weekOfYear(mom, this._week.dow, this._week.doy).week;
+}
+
+var defaultLocaleWeek = {
+ dow : 0, // Sunday is the first day of the week.
+ doy : 6 // The week that contains Jan 1st is the first week of the year.
+};
+
+function localeFirstDayOfWeek () {
+ return this._week.dow;
+}
+
+function localeFirstDayOfYear () {
+ return this._week.doy;
+}
+
+// MOMENTS
+
+function getSetWeek (input) {
+ var week = this.localeData().week(this);
+ return input == null ? week : this.add((input - week) * 7, 'd');
+}
+
+function getSetISOWeek (input) {
+ var week = weekOfYear(this, 1, 4).week;
+ return input == null ? week : this.add((input - week) * 7, 'd');
+}
+
+// FORMATTING
+
+addFormatToken('d', 0, 'do', 'day');
+
+addFormatToken('dd', 0, 0, function (format) {
+ return this.localeData().weekdaysMin(this, format);
+});
+
+addFormatToken('ddd', 0, 0, function (format) {
+ return this.localeData().weekdaysShort(this, format);
+});
+
+addFormatToken('dddd', 0, 0, function (format) {
+ return this.localeData().weekdays(this, format);
+});
+
+addFormatToken('e', 0, 0, 'weekday');
+addFormatToken('E', 0, 0, 'isoWeekday');
+
+// ALIASES
+
+addUnitAlias('day', 'd');
+addUnitAlias('weekday', 'e');
+addUnitAlias('isoWeekday', 'E');
+
+// PRIORITY
+addUnitPriority('day', 11);
+addUnitPriority('weekday', 11);
+addUnitPriority('isoWeekday', 11);
+
+// PARSING
+
+addRegexToken('d', match1to2);
+addRegexToken('e', match1to2);
+addRegexToken('E', match1to2);
+addRegexToken('dd', function (isStrict, locale) {
+ return locale.weekdaysMinRegex(isStrict);
+});
+addRegexToken('ddd', function (isStrict, locale) {
+ return locale.weekdaysShortRegex(isStrict);
+});
+addRegexToken('dddd', function (isStrict, locale) {
+ return locale.weekdaysRegex(isStrict);
+});
+
+addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
+ var weekday = config._locale.weekdaysParse(input, token, config._strict);
+ // if we didn't get a weekday name, mark the date as invalid
+ if (weekday != null) {
+ week.d = weekday;
+ } else {
+ getParsingFlags(config).invalidWeekday = input;
+ }
+});
+
+addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
+ week[token] = toInt(input);
+});
+
+// HELPERS
+
+function parseWeekday(input, locale) {
+ if (typeof input !== 'string') {
+ return input;
+ }
+
+ if (!isNaN(input)) {
+ return parseInt(input, 10);
+ }
+
+ input = locale.weekdaysParse(input);
+ if (typeof input === 'number') {
+ return input;
+ }
+
+ return null;
+}
+
+function parseIsoWeekday(input, locale) {
+ if (typeof input === 'string') {
+ return locale.weekdaysParse(input) % 7 || 7;
+ }
+ return isNaN(input) ? null : input;
+}
+
+// LOCALES
+
+var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
+function localeWeekdays (m, format) {
+ if (!m) {
+ return isArray(this._weekdays) ? this._weekdays :
+ this._weekdays['standalone'];
+ }
+ return isArray(this._weekdays) ? this._weekdays[m.day()] :
+ this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
+}
+
+var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
+function localeWeekdaysShort (m) {
+ return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
+}
+
+var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
+function localeWeekdaysMin (m) {
+ return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
+}
+
+function handleStrictParse$1(weekdayName, format, strict) {
+ var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
+ if (!this._weekdaysParse) {
+ this._weekdaysParse = [];
+ this._shortWeekdaysParse = [];
+ this._minWeekdaysParse = [];
+
+ for (i = 0; i < 7; ++i) {
+ mom = createUTC([2000, 1]).day(i);
+ this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
+ this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
+ this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
+ }
+ }
+
+ if (strict) {
+ if (format === 'dddd') {
+ ii = indexOf.call(this._weekdaysParse, llc);
+ return ii !== -1 ? ii : null;
+ } else if (format === 'ddd') {
+ ii = indexOf.call(this._shortWeekdaysParse, llc);
+ return ii !== -1 ? ii : null;
+ } else {
+ ii = indexOf.call(this._minWeekdaysParse, llc);
+ return ii !== -1 ? ii : null;
+ }
+ } else {
+ if (format === 'dddd') {
+ ii = indexOf.call(this._weekdaysParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._shortWeekdaysParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._minWeekdaysParse, llc);
+ return ii !== -1 ? ii : null;
+ } else if (format === 'ddd') {
+ ii = indexOf.call(this._shortWeekdaysParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._weekdaysParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._minWeekdaysParse, llc);
+ return ii !== -1 ? ii : null;
+ } else {
+ ii = indexOf.call(this._minWeekdaysParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._weekdaysParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._shortWeekdaysParse, llc);
+ return ii !== -1 ? ii : null;
+ }
+ }
+}
+
+function localeWeekdaysParse (weekdayName, format, strict) {
+ var i, mom, regex;
+
+ if (this._weekdaysParseExact) {
+ return handleStrictParse$1.call(this, weekdayName, format, strict);
+ }
+
+ if (!this._weekdaysParse) {
+ this._weekdaysParse = [];
+ this._minWeekdaysParse = [];
+ this._shortWeekdaysParse = [];
+ this._fullWeekdaysParse = [];
+ }
+
+ for (i = 0; i < 7; i++) {
+ // make the regex if we don't have it already
+
+ mom = createUTC([2000, 1]).day(i);
+ if (strict && !this._fullWeekdaysParse[i]) {
+ this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
+ this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
+ this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i');
+ }
+ if (!this._weekdaysParse[i]) {
+ regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
+ this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
+ }
+ // test the regex
+ if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
+ return i;
+ } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
+ return i;
+ } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
+ return i;
+ } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
+ return i;
+ }
+ }
+}
+
+// MOMENTS
+
+function getSetDayOfWeek (input) {
+ if (!this.isValid()) {
+ return input != null ? this : NaN;
+ }
+ var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
+ if (input != null) {
+ input = parseWeekday(input, this.localeData());
+ return this.add(input - day, 'd');
+ } else {
+ return day;
+ }
+}
+
+function getSetLocaleDayOfWeek (input) {
+ if (!this.isValid()) {
+ return input != null ? this : NaN;
+ }
+ var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
+ return input == null ? weekday : this.add(input - weekday, 'd');
+}
+
+function getSetISODayOfWeek (input) {
+ if (!this.isValid()) {
+ return input != null ? this : NaN;
+ }
+
+ // behaves the same as moment#day except
+ // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
+ // as a setter, sunday should belong to the previous week.
+
+ if (input != null) {
+ var weekday = parseIsoWeekday(input, this.localeData());
+ return this.day(this.day() % 7 ? weekday : weekday - 7);
+ } else {
+ return this.day() || 7;
+ }
+}
+
+var defaultWeekdaysRegex = matchWord;
+function weekdaysRegex (isStrict) {
+ if (this._weekdaysParseExact) {
+ if (!hasOwnProp(this, '_weekdaysRegex')) {
+ computeWeekdaysParse.call(this);
+ }
+ if (isStrict) {
+ return this._weekdaysStrictRegex;
+ } else {
+ return this._weekdaysRegex;
+ }
+ } else {
+ if (!hasOwnProp(this, '_weekdaysRegex')) {
+ this._weekdaysRegex = defaultWeekdaysRegex;
+ }
+ return this._weekdaysStrictRegex && isStrict ?
+ this._weekdaysStrictRegex : this._weekdaysRegex;
+ }
+}
+
+var defaultWeekdaysShortRegex = matchWord;
+function weekdaysShortRegex (isStrict) {
+ if (this._weekdaysParseExact) {
+ if (!hasOwnProp(this, '_weekdaysRegex')) {
+ computeWeekdaysParse.call(this);
+ }
+ if (isStrict) {
+ return this._weekdaysShortStrictRegex;
+ } else {
+ return this._weekdaysShortRegex;
+ }
+ } else {
+ if (!hasOwnProp(this, '_weekdaysShortRegex')) {
+ this._weekdaysShortRegex = defaultWeekdaysShortRegex;
+ }
+ return this._weekdaysShortStrictRegex && isStrict ?
+ this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
+ }
+}
+
+var defaultWeekdaysMinRegex = matchWord;
+function weekdaysMinRegex (isStrict) {
+ if (this._weekdaysParseExact) {
+ if (!hasOwnProp(this, '_weekdaysRegex')) {
+ computeWeekdaysParse.call(this);
+ }
+ if (isStrict) {
+ return this._weekdaysMinStrictRegex;
+ } else {
+ return this._weekdaysMinRegex;
+ }
+ } else {
+ if (!hasOwnProp(this, '_weekdaysMinRegex')) {
+ this._weekdaysMinRegex = defaultWeekdaysMinRegex;
+ }
+ return this._weekdaysMinStrictRegex && isStrict ?
+ this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
+ }
+}
+
+
+function computeWeekdaysParse () {
+ function cmpLenRev(a, b) {
+ return b.length - a.length;
+ }
+
+ var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
+ i, mom, minp, shortp, longp;
+ for (i = 0; i < 7; i++) {
+ // make the regex if we don't have it already
+ mom = createUTC([2000, 1]).day(i);
+ minp = this.weekdaysMin(mom, '');
+ shortp = this.weekdaysShort(mom, '');
+ longp = this.weekdays(mom, '');
+ minPieces.push(minp);
+ shortPieces.push(shortp);
+ longPieces.push(longp);
+ mixedPieces.push(minp);
+ mixedPieces.push(shortp);
+ mixedPieces.push(longp);
+ }
+ // Sorting makes sure if one weekday (or abbr) is a prefix of another it
+ // will match the longer piece.
+ minPieces.sort(cmpLenRev);
+ shortPieces.sort(cmpLenRev);
+ longPieces.sort(cmpLenRev);
+ mixedPieces.sort(cmpLenRev);
+ for (i = 0; i < 7; i++) {
+ shortPieces[i] = regexEscape(shortPieces[i]);
+ longPieces[i] = regexEscape(longPieces[i]);
+ mixedPieces[i] = regexEscape(mixedPieces[i]);
+ }
+
+ this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
+ this._weekdaysShortRegex = this._weekdaysRegex;
+ this._weekdaysMinRegex = this._weekdaysRegex;
+
+ this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
+ this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
+ this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
+}
+
+// FORMATTING
+
+function hFormat() {
+ return this.hours() % 12 || 12;
+}
+
+function kFormat() {
+ return this.hours() || 24;
+}
+
+addFormatToken('H', ['HH', 2], 0, 'hour');
+addFormatToken('h', ['hh', 2], 0, hFormat);
+addFormatToken('k', ['kk', 2], 0, kFormat);
+
+addFormatToken('hmm', 0, 0, function () {
+ return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
+});
+
+addFormatToken('hmmss', 0, 0, function () {
+ return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
+ zeroFill(this.seconds(), 2);
+});
+
+addFormatToken('Hmm', 0, 0, function () {
+ return '' + this.hours() + zeroFill(this.minutes(), 2);
+});
+
+addFormatToken('Hmmss', 0, 0, function () {
+ return '' + this.hours() + zeroFill(this.minutes(), 2) +
+ zeroFill(this.seconds(), 2);
+});
+
+function meridiem (token, lowercase) {
+ addFormatToken(token, 0, 0, function () {
+ return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
+ });
+}
+
+meridiem('a', true);
+meridiem('A', false);
+
+// ALIASES
+
+addUnitAlias('hour', 'h');
+
+// PRIORITY
+addUnitPriority('hour', 13);
+
+// PARSING
+
+function matchMeridiem (isStrict, locale) {
+ return locale._meridiemParse;
+}
+
+addRegexToken('a', matchMeridiem);
+addRegexToken('A', matchMeridiem);
+addRegexToken('H', match1to2);
+addRegexToken('h', match1to2);
+addRegexToken('k', match1to2);
+addRegexToken('HH', match1to2, match2);
+addRegexToken('hh', match1to2, match2);
+addRegexToken('kk', match1to2, match2);
+
+addRegexToken('hmm', match3to4);
+addRegexToken('hmmss', match5to6);
+addRegexToken('Hmm', match3to4);
+addRegexToken('Hmmss', match5to6);
+
+addParseToken(['H', 'HH'], HOUR);
+addParseToken(['k', 'kk'], function (input, array, config) {
+ var kInput = toInt(input);
+ array[HOUR] = kInput === 24 ? 0 : kInput;
+});
+addParseToken(['a', 'A'], function (input, array, config) {
+ config._isPm = config._locale.isPM(input);
+ config._meridiem = input;
+});
+addParseToken(['h', 'hh'], function (input, array, config) {
+ array[HOUR] = toInt(input);
+ getParsingFlags(config).bigHour = true;
+});
+addParseToken('hmm', function (input, array, config) {
+ var pos = input.length - 2;
+ array[HOUR] = toInt(input.substr(0, pos));
+ array[MINUTE] = toInt(input.substr(pos));
+ getParsingFlags(config).bigHour = true;
+});
+addParseToken('hmmss', function (input, array, config) {
+ var pos1 = input.length - 4;
+ var pos2 = input.length - 2;
+ array[HOUR] = toInt(input.substr(0, pos1));
+ array[MINUTE] = toInt(input.substr(pos1, 2));
+ array[SECOND] = toInt(input.substr(pos2));
+ getParsingFlags(config).bigHour = true;
+});
+addParseToken('Hmm', function (input, array, config) {
+ var pos = input.length - 2;
+ array[HOUR] = toInt(input.substr(0, pos));
+ array[MINUTE] = toInt(input.substr(pos));
+});
+addParseToken('Hmmss', function (input, array, config) {
+ var pos1 = input.length - 4;
+ var pos2 = input.length - 2;
+ array[HOUR] = toInt(input.substr(0, pos1));
+ array[MINUTE] = toInt(input.substr(pos1, 2));
+ array[SECOND] = toInt(input.substr(pos2));
+});
+
+// LOCALES
+
+function localeIsPM (input) {
+ // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
+ // Using charAt should be more compatible.
+ return ((input + '').toLowerCase().charAt(0) === 'p');
+}
+
+var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
+function localeMeridiem (hours, minutes, isLower) {
+ if (hours > 11) {
+ return isLower ? 'pm' : 'PM';
+ } else {
+ return isLower ? 'am' : 'AM';
+ }
+}
+
+
+// MOMENTS
+
+// Setting the hour should keep the time, because the user explicitly
+// specified which hour he wants. So trying to maintain the same hour (in
+// a new timezone) makes sense. Adding/subtracting hours does not follow
+// this rule.
+var getSetHour = makeGetSet('Hours', true);
+
+// months
+// week
+// weekdays
+// meridiem
+var baseConfig = {
+ calendar: defaultCalendar,
+ longDateFormat: defaultLongDateFormat,
+ invalidDate: defaultInvalidDate,
+ ordinal: defaultOrdinal,
+ dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
+ relativeTime: defaultRelativeTime,
+
+ months: defaultLocaleMonths,
+ monthsShort: defaultLocaleMonthsShort,
+
+ week: defaultLocaleWeek,
+
+ weekdays: defaultLocaleWeekdays,
+ weekdaysMin: defaultLocaleWeekdaysMin,
+ weekdaysShort: defaultLocaleWeekdaysShort,
+
+ meridiemParse: defaultLocaleMeridiemParse
+};
+
+// internal storage for locale config files
+var locales = {};
+var localeFamilies = {};
+var globalLocale;
+
+function normalizeLocale(key) {
+ return key ? key.toLowerCase().replace('_', '-') : key;
+}
+
+// pick the locale from the array
+// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
+// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
+function chooseLocale(names) {
+ var i = 0, j, next, locale, split;
+
+ while (i < names.length) {
+ split = normalizeLocale(names[i]).split('-');
+ j = split.length;
+ next = normalizeLocale(names[i + 1]);
+ next = next ? next.split('-') : null;
+ while (j > 0) {
+ locale = loadLocale(split.slice(0, j).join('-'));
+ if (locale) {
+ return locale;
+ }
+ if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
+ //the next array item is better than a shallower substring of this one
+ break;
+ }
+ j--;
+ }
+ i++;
+ }
+ return null;
+}
+
+function loadLocale(name) {
+ var oldLocale = null;
+ // TODO: Find a better way to register and load all the locales in Node
+ if (!locales[name] && (typeof module !== 'undefined') &&
+ module && module.exports) {
+ try {
+ oldLocale = globalLocale._abbr;
+ var aliasedRequire = require;
+ aliasedRequire('./locale/' + name);
+ getSetGlobalLocale(oldLocale);
+ } catch (e) {}
+ }
+ return locales[name];
+}
+
+// This function will load locale and then set the global locale. If
+// no arguments are passed in, it will simply return the current global
+// locale key.
+function getSetGlobalLocale (key, values) {
+ var data;
+ if (key) {
+ if (isUndefined(values)) {
+ data = getLocale(key);
+ }
+ else {
+ data = defineLocale(key, values);
+ }
+
+ if (data) {
+ // moment.duration._locale = moment._locale = data;
+ globalLocale = data;
+ }
+ }
+
+ return globalLocale._abbr;
+}
+
+function defineLocale (name, config) {
+ if (config !== null) {
+ var parentConfig = baseConfig;
+ config.abbr = name;
+ if (locales[name] != null) {
+ deprecateSimple('defineLocaleOverride',
+ 'use moment.updateLocale(localeName, config) to change ' +
+ 'an existing locale. moment.defineLocale(localeName, ' +
+ 'config) should only be used for creating a new locale ' +
+ 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
+ parentConfig = locales[name]._config;
+ } else if (config.parentLocale != null) {
+ if (locales[config.parentLocale] != null) {
+ parentConfig = locales[config.parentLocale]._config;
+ } else {
+ if (!localeFamilies[config.parentLocale]) {
+ localeFamilies[config.parentLocale] = [];
+ }
+ localeFamilies[config.parentLocale].push({
+ name: name,
+ config: config
+ });
+ return null;
+ }
+ }
+ locales[name] = new Locale(mergeConfigs(parentConfig, config));
+
+ if (localeFamilies[name]) {
+ localeFamilies[name].forEach(function (x) {
+ defineLocale(x.name, x.config);
+ });
+ }
+
+ // backwards compat for now: also set the locale
+ // make sure we set the locale AFTER all child locales have been
+ // created, so we won't end up with the child locale set.
+ getSetGlobalLocale(name);
+
+
+ return locales[name];
+ } else {
+ // useful for testing
+ delete locales[name];
+ return null;
+ }
+}
+
+function updateLocale(name, config) {
+ if (config != null) {
+ var locale, tmpLocale, parentConfig = baseConfig;
+ // MERGE
+ tmpLocale = loadLocale(name);
+ if (tmpLocale != null) {
+ parentConfig = tmpLocale._config;
+ }
+ config = mergeConfigs(parentConfig, config);
+ locale = new Locale(config);
+ locale.parentLocale = locales[name];
+ locales[name] = locale;
+
+ // backwards compat for now: also set the locale
+ getSetGlobalLocale(name);
+ } else {
+ // pass null for config to unupdate, useful for tests
+ if (locales[name] != null) {
+ if (locales[name].parentLocale != null) {
+ locales[name] = locales[name].parentLocale;
+ } else if (locales[name] != null) {
+ delete locales[name];
+ }
+ }
+ }
+ return locales[name];
+}
+
+// returns locale data
+function getLocale (key) {
+ var locale;
+
+ if (key && key._locale && key._locale._abbr) {
+ key = key._locale._abbr;
+ }
+
+ if (!key) {
+ return globalLocale;
+ }
+
+ if (!isArray(key)) {
+ //short-circuit everything else
+ locale = loadLocale(key);
+ if (locale) {
+ return locale;
+ }
+ key = [key];
+ }
+
+ return chooseLocale(key);
+}
+
+function listLocales() {
+ return keys(locales);
+}
+
+function checkOverflow (m) {
+ var overflow;
+ var a = m._a;
+
+ if (a && getParsingFlags(m).overflow === -2) {
+ overflow =
+ a[MONTH] < 0 || a[MONTH] > 11 ? MONTH :
+ a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
+ a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
+ a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE :
+ a[SECOND] < 0 || a[SECOND] > 59 ? SECOND :
+ a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
+ -1;
+
+ if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
+ overflow = DATE;
+ }
+ if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
+ overflow = WEEK;
+ }
+ if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
+ overflow = WEEKDAY;
+ }
+
+ getParsingFlags(m).overflow = overflow;
+ }
+
+ return m;
+}
+
+// Pick the first defined of two or three arguments.
+function defaults(a, b, c) {
+ if (a != null) {
+ return a;
+ }
+ if (b != null) {
+ return b;
+ }
+ return c;
+}
+
+function currentDateArray(config) {
+ // hooks is actually the exported moment object
+ var nowValue = new Date(hooks.now());
+ if (config._useUTC) {
+ return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
+ }
+ return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
+}
+
+// convert an array to a date.
+// the array should mirror the parameters below
+// note: all values past the year are optional and will default to the lowest possible value.
+// [year, month, day , hour, minute, second, millisecond]
+function configFromArray (config) {
+ var i, date, input = [], currentDate, expectedWeekday, yearToUse;
+
+ if (config._d) {
+ return;
+ }
+
+ currentDate = currentDateArray(config);
+
+ //compute day of the year from weeks and weekdays
+ if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
+ dayOfYearFromWeekInfo(config);
+ }
+
+ //if the day of the year is set, figure out what it is
+ if (config._dayOfYear != null) {
+ yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
+
+ if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
+ getParsingFlags(config)._overflowDayOfYear = true;
+ }
+
+ date = createUTCDate(yearToUse, 0, config._dayOfYear);
+ config._a[MONTH] = date.getUTCMonth();
+ config._a[DATE] = date.getUTCDate();
+ }
+
+ // Default to current date.
+ // * if no year, month, day of month are given, default to today
+ // * if day of month is given, default month and year
+ // * if month is given, default only year
+ // * if year is given, don't default anything
+ for (i = 0; i < 3 && config._a[i] == null; ++i) {
+ config._a[i] = input[i] = currentDate[i];
+ }
+
+ // Zero out whatever was not defaulted, including time
+ for (; i < 7; i++) {
+ config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
+ }
+
+ // Check for 24:00:00.000
+ if (config._a[HOUR] === 24 &&
+ config._a[MINUTE] === 0 &&
+ config._a[SECOND] === 0 &&
+ config._a[MILLISECOND] === 0) {
+ config._nextDay = true;
+ config._a[HOUR] = 0;
+ }
+
+ config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
+ expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();
+
+ // Apply timezone offset from input. The actual utcOffset can be changed
+ // with parseZone.
+ if (config._tzm != null) {
+ config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
+ }
+
+ if (config._nextDay) {
+ config._a[HOUR] = 24;
+ }
+
+ // check for mismatching day of week
+ if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
+ getParsingFlags(config).weekdayMismatch = true;
+ }
+}
+
+function dayOfYearFromWeekInfo(config) {
+ var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
+
+ w = config._w;
+ if (w.GG != null || w.W != null || w.E != null) {
+ dow = 1;
+ doy = 4;
+
+ // TODO: We need to take the current isoWeekYear, but that depends on
+ // how we interpret now (local, utc, fixed offset). So create
+ // a now version of current config (take local/utc/offset flags, and
+ // create now).
+ weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
+ week = defaults(w.W, 1);
+ weekday = defaults(w.E, 1);
+ if (weekday < 1 || weekday > 7) {
+ weekdayOverflow = true;
+ }
+ } else {
+ dow = config._locale._week.dow;
+ doy = config._locale._week.doy;
+
+ var curWeek = weekOfYear(createLocal(), dow, doy);
+
+ weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
+
+ // Default to current week.
+ week = defaults(w.w, curWeek.week);
+
+ if (w.d != null) {
+ // weekday -- low day numbers are considered next week
+ weekday = w.d;
+ if (weekday < 0 || weekday > 6) {
+ weekdayOverflow = true;
+ }
+ } else if (w.e != null) {
+ // local weekday -- counting starts from begining of week
+ weekday = w.e + dow;
+ if (w.e < 0 || w.e > 6) {
+ weekdayOverflow = true;
+ }
+ } else {
+ // default to begining of week
+ weekday = dow;
+ }
+ }
+ if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
+ getParsingFlags(config)._overflowWeeks = true;
+ } else if (weekdayOverflow != null) {
+ getParsingFlags(config)._overflowWeekday = true;
+ } else {
+ temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
+ config._a[YEAR] = temp.year;
+ config._dayOfYear = temp.dayOfYear;
+ }
+}
+
+// iso 8601 regex
+// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
+var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
+var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
+
+var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
+
+var isoDates = [
+ ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
+ ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
+ ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
+ ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
+ ['YYYY-DDD', /\d{4}-\d{3}/],
+ ['YYYY-MM', /\d{4}-\d\d/, false],
+ ['YYYYYYMMDD', /[+-]\d{10}/],
+ ['YYYYMMDD', /\d{8}/],
+ // YYYYMM is NOT allowed by the standard
+ ['GGGG[W]WWE', /\d{4}W\d{3}/],
+ ['GGGG[W]WW', /\d{4}W\d{2}/, false],
+ ['YYYYDDD', /\d{7}/]
+];
+
+// iso time formats and regexes
+var isoTimes = [
+ ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
+ ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
+ ['HH:mm:ss', /\d\d:\d\d:\d\d/],
+ ['HH:mm', /\d\d:\d\d/],
+ ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
+ ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
+ ['HHmmss', /\d\d\d\d\d\d/],
+ ['HHmm', /\d\d\d\d/],
+ ['HH', /\d\d/]
+];
+
+var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
+
+// date from iso format
+function configFromISO(config) {
+ var i, l,
+ string = config._i,
+ match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
+ allowTime, dateFormat, timeFormat, tzFormat;
+
+ if (match) {
+ getParsingFlags(config).iso = true;
+
+ for (i = 0, l = isoDates.length; i < l; i++) {
+ if (isoDates[i][1].exec(match[1])) {
+ dateFormat = isoDates[i][0];
+ allowTime = isoDates[i][2] !== false;
+ break;
+ }
+ }
+ if (dateFormat == null) {
+ config._isValid = false;
+ return;
+ }
+ if (match[3]) {
+ for (i = 0, l = isoTimes.length; i < l; i++) {
+ if (isoTimes[i][1].exec(match[3])) {
+ // match[2] should be 'T' or space
+ timeFormat = (match[2] || ' ') + isoTimes[i][0];
+ break;
+ }
+ }
+ if (timeFormat == null) {
+ config._isValid = false;
+ return;
+ }
+ }
+ if (!allowTime && timeFormat != null) {
+ config._isValid = false;
+ return;
+ }
+ if (match[4]) {
+ if (tzRegex.exec(match[4])) {
+ tzFormat = 'Z';
+ } else {
+ config._isValid = false;
+ return;
+ }
+ }
+ config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
+ configFromStringAndFormat(config);
+ } else {
+ config._isValid = false;
+ }
+}
+
+// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
+var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;
+
+function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
+ var result = [
+ untruncateYear(yearStr),
+ defaultLocaleMonthsShort.indexOf(monthStr),
+ parseInt(dayStr, 10),
+ parseInt(hourStr, 10),
+ parseInt(minuteStr, 10)
+ ];
+
+ if (secondStr) {
+ result.push(parseInt(secondStr, 10));
+ }
+
+ return result;
+}
+
+function untruncateYear(yearStr) {
+ var year = parseInt(yearStr, 10);
+ if (year <= 49) {
+ return 2000 + year;
+ } else if (year <= 999) {
+ return 1900 + year;
+ }
+ return year;
+}
+
+function preprocessRFC2822(s) {
+ // Remove comments and folding whitespace and replace multiple-spaces with a single space
+ return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').trim();
+}
+
+function checkWeekday(weekdayStr, parsedInput, config) {
+ if (weekdayStr) {
+ // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
+ var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
+ weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
+ if (weekdayProvided !== weekdayActual) {
+ getParsingFlags(config).weekdayMismatch = true;
+ config._isValid = false;
+ return false;
+ }
+ }
+ return true;
+}
+
+var obsOffsets = {
+ UT: 0,
+ GMT: 0,
+ EDT: -4 * 60,
+ EST: -5 * 60,
+ CDT: -5 * 60,
+ CST: -6 * 60,
+ MDT: -6 * 60,
+ MST: -7 * 60,
+ PDT: -7 * 60,
+ PST: -8 * 60
+};
+
+function calculateOffset(obsOffset, militaryOffset, numOffset) {
+ if (obsOffset) {
+ return obsOffsets[obsOffset];
+ } else if (militaryOffset) {
+ // the only allowed military tz is Z
+ return 0;
+ } else {
+ var hm = parseInt(numOffset, 10);
+ var m = hm % 100, h = (hm - m) / 100;
+ return h * 60 + m;
+ }
+}
+
+// date and time from ref 2822 format
+function configFromRFC2822(config) {
+ var match = rfc2822.exec(preprocessRFC2822(config._i));
+ if (match) {
+ var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
+ if (!checkWeekday(match[1], parsedArray, config)) {
+ return;
+ }
+
+ config._a = parsedArray;
+ config._tzm = calculateOffset(match[8], match[9], match[10]);
+
+ config._d = createUTCDate.apply(null, config._a);
+ config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
+
+ getParsingFlags(config).rfc2822 = true;
+ } else {
+ config._isValid = false;
+ }
+}
+
+// date from iso format or fallback
+function configFromString(config) {
+ var matched = aspNetJsonRegex.exec(config._i);
+
+ if (matched !== null) {
+ config._d = new Date(+matched[1]);
+ return;
+ }
+
+ configFromISO(config);
+ if (config._isValid === false) {
+ delete config._isValid;
+ } else {
+ return;
+ }
+
+ configFromRFC2822(config);
+ if (config._isValid === false) {
+ delete config._isValid;
+ } else {
+ return;
+ }
+
+ // Final attempt, use Input Fallback
+ hooks.createFromInputFallback(config);
+}
+
+hooks.createFromInputFallback = deprecate(
+ 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
+ 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
+ 'discouraged and will be removed in an upcoming major release. Please refer to ' +
+ 'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
+ function (config) {
+ config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
+ }
+);
+
+// constant that refers to the ISO standard
+hooks.ISO_8601 = function () {};
+
+// constant that refers to the RFC 2822 form
+hooks.RFC_2822 = function () {};
+
+// date from string and format string
+function configFromStringAndFormat(config) {
+ // TODO: Move this to another part of the creation flow to prevent circular deps
+ if (config._f === hooks.ISO_8601) {
+ configFromISO(config);
+ return;
+ }
+ if (config._f === hooks.RFC_2822) {
+ configFromRFC2822(config);
+ return;
+ }
+ config._a = [];
+ getParsingFlags(config).empty = true;
+
+ // This array is used to make a Date, either with `new Date` or `Date.UTC`
+ var string = '' + config._i,
+ i, parsedInput, tokens, token, skipped,
+ stringLength = string.length,
+ totalParsedInputLength = 0;
+
+ tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
+
+ for (i = 0; i < tokens.length; i++) {
+ token = tokens[i];
+ parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
+ // console.log('token', token, 'parsedInput', parsedInput,
+ // 'regex', getParseRegexForToken(token, config));
+ if (parsedInput) {
+ skipped = string.substr(0, string.indexOf(parsedInput));
+ if (skipped.length > 0) {
+ getParsingFlags(config).unusedInput.push(skipped);
+ }
+ string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
+ totalParsedInputLength += parsedInput.length;
+ }
+ // don't parse if it's not a known token
+ if (formatTokenFunctions[token]) {
+ if (parsedInput) {
+ getParsingFlags(config).empty = false;
+ }
+ else {
+ getParsingFlags(config).unusedTokens.push(token);
+ }
+ addTimeToArrayFromToken(token, parsedInput, config);
+ }
+ else if (config._strict && !parsedInput) {
+ getParsingFlags(config).unusedTokens.push(token);
+ }
+ }
+
+ // add remaining unparsed input length to the string
+ getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
+ if (string.length > 0) {
+ getParsingFlags(config).unusedInput.push(string);
+ }
+
+ // clear _12h flag if hour is <= 12
+ if (config._a[HOUR] <= 12 &&
+ getParsingFlags(config).bigHour === true &&
+ config._a[HOUR] > 0) {
+ getParsingFlags(config).bigHour = undefined;
+ }
+
+ getParsingFlags(config).parsedDateParts = config._a.slice(0);
+ getParsingFlags(config).meridiem = config._meridiem;
+ // handle meridiem
+ config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
+
+ configFromArray(config);
+ checkOverflow(config);
+}
+
+
+function meridiemFixWrap (locale, hour, meridiem) {
+ var isPm;
+
+ if (meridiem == null) {
+ // nothing to do
+ return hour;
+ }
+ if (locale.meridiemHour != null) {
+ return locale.meridiemHour(hour, meridiem);
+ } else if (locale.isPM != null) {
+ // Fallback
+ isPm = locale.isPM(meridiem);
+ if (isPm && hour < 12) {
+ hour += 12;
+ }
+ if (!isPm && hour === 12) {
+ hour = 0;
+ }
+ return hour;
+ } else {
+ // this is not supposed to happen
+ return hour;
+ }
+}
+
+// date from string and array of format strings
+function configFromStringAndArray(config) {
+ var tempConfig,
+ bestMoment,
+
+ scoreToBeat,
+ i,
+ currentScore;
+
+ if (config._f.length === 0) {
+ getParsingFlags(config).invalidFormat = true;
+ config._d = new Date(NaN);
+ return;
+ }
+
+ for (i = 0; i < config._f.length; i++) {
+ currentScore = 0;
+ tempConfig = copyConfig({}, config);
+ if (config._useUTC != null) {
+ tempConfig._useUTC = config._useUTC;
+ }
+ tempConfig._f = config._f[i];
+ configFromStringAndFormat(tempConfig);
+
+ if (!isValid(tempConfig)) {
+ continue;
+ }
+
+ // if there is any input that was not parsed add a penalty for that format
+ currentScore += getParsingFlags(tempConfig).charsLeftOver;
+
+ //or tokens
+ currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
+
+ getParsingFlags(tempConfig).score = currentScore;
+
+ if (scoreToBeat == null || currentScore < scoreToBeat) {
+ scoreToBeat = currentScore;
+ bestMoment = tempConfig;
+ }
+ }
+
+ extend(config, bestMoment || tempConfig);
+}
+
+function configFromObject(config) {
+ if (config._d) {
+ return;
+ }
+
+ var i = normalizeObjectUnits(config._i);
+ config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
+ return obj && parseInt(obj, 10);
+ });
+
+ configFromArray(config);
+}
+
+function createFromConfig (config) {
+ var res = new Moment(checkOverflow(prepareConfig(config)));
+ if (res._nextDay) {
+ // Adding is smart enough around DST
+ res.add(1, 'd');
+ res._nextDay = undefined;
+ }
+
+ return res;
+}
+
+function prepareConfig (config) {
+ var input = config._i,
+ format = config._f;
+
+ config._locale = config._locale || getLocale(config._l);
+
+ if (input === null || (format === undefined && input === '')) {
+ return createInvalid({nullInput: true});
+ }
+
+ if (typeof input === 'string') {
+ config._i = input = config._locale.preparse(input);
+ }
+
+ if (isMoment(input)) {
+ return new Moment(checkOverflow(input));
+ } else if (isDate(input)) {
+ config._d = input;
+ } else if (isArray(format)) {
+ configFromStringAndArray(config);
+ } else if (format) {
+ configFromStringAndFormat(config);
+ } else {
+ configFromInput(config);
+ }
+
+ if (!isValid(config)) {
+ config._d = null;
+ }
+
+ return config;
+}
+
+function configFromInput(config) {
+ var input = config._i;
+ if (isUndefined(input)) {
+ config._d = new Date(hooks.now());
+ } else if (isDate(input)) {
+ config._d = new Date(input.valueOf());
+ } else if (typeof input === 'string') {
+ configFromString(config);
+ } else if (isArray(input)) {
+ config._a = map(input.slice(0), function (obj) {
+ return parseInt(obj, 10);
+ });
+ configFromArray(config);
+ } else if (isObject(input)) {
+ configFromObject(config);
+ } else if (isNumber(input)) {
+ // from milliseconds
+ config._d = new Date(input);
+ } else {
+ hooks.createFromInputFallback(config);
+ }
+}
+
+function createLocalOrUTC (input, format, locale, strict, isUTC) {
+ var c = {};
+
+ if (locale === true || locale === false) {
+ strict = locale;
+ locale = undefined;
+ }
+
+ if ((isObject(input) && isObjectEmpty(input)) ||
+ (isArray(input) && input.length === 0)) {
+ input = undefined;
+ }
+ // object construction must be done this way.
+ // https://github.com/moment/moment/issues/1423
+ c._isAMomentObject = true;
+ c._useUTC = c._isUTC = isUTC;
+ c._l = locale;
+ c._i = input;
+ c._f = format;
+ c._strict = strict;
+
+ return createFromConfig(c);
+}
+
+function createLocal (input, format, locale, strict) {
+ return createLocalOrUTC(input, format, locale, strict, false);
+}
+
+var prototypeMin = deprecate(
+ 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
+ function () {
+ var other = createLocal.apply(null, arguments);
+ if (this.isValid() && other.isValid()) {
+ return other < this ? this : other;
+ } else {
+ return createInvalid();
+ }
+ }
+);
+
+var prototypeMax = deprecate(
+ 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
+ function () {
+ var other = createLocal.apply(null, arguments);
+ if (this.isValid() && other.isValid()) {
+ return other > this ? this : other;
+ } else {
+ return createInvalid();
+ }
+ }
+);
+
+// Pick a moment m from moments so that m[fn](other) is true for all
+// other. This relies on the function fn to be transitive.
+//
+// moments should either be an array of moment objects or an array, whose
+// first element is an array of moment objects.
+function pickBy(fn, moments) {
+ var res, i;
+ if (moments.length === 1 && isArray(moments[0])) {
+ moments = moments[0];
+ }
+ if (!moments.length) {
+ return createLocal();
+ }
+ res = moments[0];
+ for (i = 1; i < moments.length; ++i) {
+ if (!moments[i].isValid() || moments[i][fn](res)) {
+ res = moments[i];
+ }
+ }
+ return res;
+}
+
+// TODO: Use [].sort instead?
+function min () {
+ var args = [].slice.call(arguments, 0);
+
+ return pickBy('isBefore', args);
+}
+
+function max () {
+ var args = [].slice.call(arguments, 0);
+
+ return pickBy('isAfter', args);
+}
+
+var now = function () {
+ return Date.now ? Date.now() : +(new Date());
+};
+
+var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
+
+function isDurationValid(m) {
+ for (var key in m) {
+ if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
+ return false;
+ }
+ }
+
+ var unitHasDecimal = false;
+ for (var i = 0; i < ordering.length; ++i) {
+ if (m[ordering[i]]) {
+ if (unitHasDecimal) {
+ return false; // only allow non-integers for smallest unit
+ }
+ if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
+ unitHasDecimal = true;
+ }
+ }
+ }
+
+ return true;
+}
+
+function isValid$1() {
+ return this._isValid;
+}
+
+function createInvalid$1() {
+ return createDuration(NaN);
+}
+
+function Duration (duration) {
+ var normalizedInput = normalizeObjectUnits(duration),
+ years = normalizedInput.year || 0,
+ quarters = normalizedInput.quarter || 0,
+ months = normalizedInput.month || 0,
+ weeks = normalizedInput.week || 0,
+ days = normalizedInput.day || 0,
+ hours = normalizedInput.hour || 0,
+ minutes = normalizedInput.minute || 0,
+ seconds = normalizedInput.second || 0,
+ milliseconds = normalizedInput.millisecond || 0;
+
+ this._isValid = isDurationValid(normalizedInput);
+
+ // representation for dateAddRemove
+ this._milliseconds = +milliseconds +
+ seconds * 1e3 + // 1000
+ minutes * 6e4 + // 1000 * 60
+ hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
+ // Because of dateAddRemove treats 24 hours as different from a
+ // day when working around DST, we need to store them separately
+ this._days = +days +
+ weeks * 7;
+ // It is impossible to translate months into days without knowing
+ // which months you are are talking about, so we have to store
+ // it separately.
+ this._months = +months +
+ quarters * 3 +
+ years * 12;
+
+ this._data = {};
+
+ this._locale = getLocale();
+
+ this._bubble();
+}
+
+function isDuration (obj) {
+ return obj instanceof Duration;
+}
+
+function absRound (number) {
+ if (number < 0) {
+ return Math.round(-1 * number) * -1;
+ } else {
+ return Math.round(number);
+ }
+}
+
+// FORMATTING
+
+function offset (token, separator) {
+ addFormatToken(token, 0, 0, function () {
+ var offset = this.utcOffset();
+ var sign = '+';
+ if (offset < 0) {
+ offset = -offset;
+ sign = '-';
+ }
+ return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
+ });
+}
+
+offset('Z', ':');
+offset('ZZ', '');
+
+// PARSING
+
+addRegexToken('Z', matchShortOffset);
+addRegexToken('ZZ', matchShortOffset);
+addParseToken(['Z', 'ZZ'], function (input, array, config) {
+ config._useUTC = true;
+ config._tzm = offsetFromString(matchShortOffset, input);
+});
+
+// HELPERS
+
+// timezone chunker
+// '+10:00' > ['10', '00']
+// '-1530' > ['-15', '30']
+var chunkOffset = /([\+\-]|\d\d)/gi;
+
+function offsetFromString(matcher, string) {
+ var matches = (string || '').match(matcher);
+
+ if (matches === null) {
+ return null;
+ }
+
+ var chunk = matches[matches.length - 1] || [];
+ var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
+ var minutes = +(parts[1] * 60) + toInt(parts[2]);
+
+ return minutes === 0 ?
+ 0 :
+ parts[0] === '+' ? minutes : -minutes;
+}
+
+// Return a moment from input, that is local/utc/zone equivalent to model.
+function cloneWithOffset(input, model) {
+ var res, diff;
+ if (model._isUTC) {
+ res = model.clone();
+ diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
+ // Use low-level api, because this fn is low-level api.
+ res._d.setTime(res._d.valueOf() + diff);
+ hooks.updateOffset(res, false);
+ return res;
+ } else {
+ return createLocal(input).local();
+ }
+}
+
+function getDateOffset (m) {
+ // On Firefox.24 Date#getTimezoneOffset returns a floating point.
+ // https://github.com/moment/moment/pull/1871
+ return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
+}
+
+// HOOKS
+
+// This function will be called whenever a moment is mutated.
+// It is intended to keep the offset in sync with the timezone.
+hooks.updateOffset = function () {};
+
+// MOMENTS
+
+// keepLocalTime = true means only change the timezone, without
+// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
+// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
+// +0200, so we adjust the time as needed, to be valid.
+//
+// Keeping the time actually adds/subtracts (one hour)
+// from the actual represented time. That is why we call updateOffset
+// a second time. In case it wants us to change the offset again
+// _changeInProgress == true case, then we have to adjust, because
+// there is no such time in the given timezone.
+function getSetOffset (input, keepLocalTime, keepMinutes) {
+ var offset = this._offset || 0,
+ localAdjust;
+ if (!this.isValid()) {
+ return input != null ? this : NaN;
+ }
+ if (input != null) {
+ if (typeof input === 'string') {
+ input = offsetFromString(matchShortOffset, input);
+ if (input === null) {
+ return this;
+ }
+ } else if (Math.abs(input) < 16 && !keepMinutes) {
+ input = input * 60;
+ }
+ if (!this._isUTC && keepLocalTime) {
+ localAdjust = getDateOffset(this);
+ }
+ this._offset = input;
+ this._isUTC = true;
+ if (localAdjust != null) {
+ this.add(localAdjust, 'm');
+ }
+ if (offset !== input) {
+ if (!keepLocalTime || this._changeInProgress) {
+ addSubtract(this, createDuration(input - offset, 'm'), 1, false);
+ } else if (!this._changeInProgress) {
+ this._changeInProgress = true;
+ hooks.updateOffset(this, true);
+ this._changeInProgress = null;
+ }
+ }
+ return this;
+ } else {
+ return this._isUTC ? offset : getDateOffset(this);
+ }
+}
+
+function getSetZone (input, keepLocalTime) {
+ if (input != null) {
+ if (typeof input !== 'string') {
+ input = -input;
+ }
+
+ this.utcOffset(input, keepLocalTime);
+
+ return this;
+ } else {
+ return -this.utcOffset();
+ }
+}
+
+function setOffsetToUTC (keepLocalTime) {
+ return this.utcOffset(0, keepLocalTime);
+}
+
+function setOffsetToLocal (keepLocalTime) {
+ if (this._isUTC) {
+ this.utcOffset(0, keepLocalTime);
+ this._isUTC = false;
+
+ if (keepLocalTime) {
+ this.subtract(getDateOffset(this), 'm');
+ }
+ }
+ return this;
+}
+
+function setOffsetToParsedOffset () {
+ if (this._tzm != null) {
+ this.utcOffset(this._tzm, false, true);
+ } else if (typeof this._i === 'string') {
+ var tZone = offsetFromString(matchOffset, this._i);
+ if (tZone != null) {
+ this.utcOffset(tZone);
+ }
+ else {
+ this.utcOffset(0, true);
+ }
+ }
+ return this;
+}
+
+function hasAlignedHourOffset (input) {
+ if (!this.isValid()) {
+ return false;
+ }
+ input = input ? createLocal(input).utcOffset() : 0;
+
+ return (this.utcOffset() - input) % 60 === 0;
+}
+
+function isDaylightSavingTime () {
+ return (
+ this.utcOffset() > this.clone().month(0).utcOffset() ||
+ this.utcOffset() > this.clone().month(5).utcOffset()
+ );
+}
+
+function isDaylightSavingTimeShifted () {
+ if (!isUndefined(this._isDSTShifted)) {
+ return this._isDSTShifted;
+ }
+
+ var c = {};
+
+ copyConfig(c, this);
+ c = prepareConfig(c);
+
+ if (c._a) {
+ var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
+ this._isDSTShifted = this.isValid() &&
+ compareArrays(c._a, other.toArray()) > 0;
+ } else {
+ this._isDSTShifted = false;
+ }
+
+ return this._isDSTShifted;
+}
+
+function isLocal () {
+ return this.isValid() ? !this._isUTC : false;
+}
+
+function isUtcOffset () {
+ return this.isValid() ? this._isUTC : false;
+}
+
+function isUtc () {
+ return this.isValid() ? this._isUTC && this._offset === 0 : false;
+}
+
+// ASP.NET json date format regex
+var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;
+
+// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
+// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
+// and further modified to allow for strings containing both week and day
+var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
+
+function createDuration (input, key) {
+ var duration = input,
+ // matching against regexp is expensive, do it on demand
+ match = null,
+ sign,
+ ret,
+ diffRes;
+
+ if (isDuration(input)) {
+ duration = {
+ ms : input._milliseconds,
+ d : input._days,
+ M : input._months
+ };
+ } else if (isNumber(input)) {
+ duration = {};
+ if (key) {
+ duration[key] = input;
+ } else {
+ duration.milliseconds = input;
+ }
+ } else if (!!(match = aspNetRegex.exec(input))) {
+ sign = (match[1] === '-') ? -1 : 1;
+ duration = {
+ y : 0,
+ d : toInt(match[DATE]) * sign,
+ h : toInt(match[HOUR]) * sign,
+ m : toInt(match[MINUTE]) * sign,
+ s : toInt(match[SECOND]) * sign,
+ ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
+ };
+ } else if (!!(match = isoRegex.exec(input))) {
+ sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1;
+ duration = {
+ y : parseIso(match[2], sign),
+ M : parseIso(match[3], sign),
+ w : parseIso(match[4], sign),
+ d : parseIso(match[5], sign),
+ h : parseIso(match[6], sign),
+ m : parseIso(match[7], sign),
+ s : parseIso(match[8], sign)
+ };
+ } else if (duration == null) {// checks for null or undefined
+ duration = {};
+ } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
+ diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
+
+ duration = {};
+ duration.ms = diffRes.milliseconds;
+ duration.M = diffRes.months;
+ }
+
+ ret = new Duration(duration);
+
+ if (isDuration(input) && hasOwnProp(input, '_locale')) {
+ ret._locale = input._locale;
+ }
+
+ return ret;
+}
+
+createDuration.fn = Duration.prototype;
+createDuration.invalid = createInvalid$1;
+
+function parseIso (inp, sign) {
+ // We'd normally use ~~inp for this, but unfortunately it also
+ // converts floats to ints.
+ // inp may be undefined, so careful calling replace on it.
+ var res = inp && parseFloat(inp.replace(',', '.'));
+ // apply sign while we're at it
+ return (isNaN(res) ? 0 : res) * sign;
+}
+
+function positiveMomentsDifference(base, other) {
+ var res = {milliseconds: 0, months: 0};
+
+ res.months = other.month() - base.month() +
+ (other.year() - base.year()) * 12;
+ if (base.clone().add(res.months, 'M').isAfter(other)) {
+ --res.months;
+ }
+
+ res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
+
+ return res;
+}
+
+function momentsDifference(base, other) {
+ var res;
+ if (!(base.isValid() && other.isValid())) {
+ return {milliseconds: 0, months: 0};
+ }
+
+ other = cloneWithOffset(other, base);
+ if (base.isBefore(other)) {
+ res = positiveMomentsDifference(base, other);
+ } else {
+ res = positiveMomentsDifference(other, base);
+ res.milliseconds = -res.milliseconds;
+ res.months = -res.months;
+ }
+
+ return res;
+}
+
+// TODO: remove 'name' arg after deprecation is removed
+function createAdder(direction, name) {
+ return function (val, period) {
+ var dur, tmp;
+ //invert the arguments, but complain about it
+ if (period !== null && !isNaN(+period)) {
+ deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
+ 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
+ tmp = val; val = period; period = tmp;
+ }
+
+ val = typeof val === 'string' ? +val : val;
+ dur = createDuration(val, period);
+ addSubtract(this, dur, direction);
+ return this;
+ };
+}
+
+function addSubtract (mom, duration, isAdding, updateOffset) {
+ var milliseconds = duration._milliseconds,
+ days = absRound(duration._days),
+ months = absRound(duration._months);
+
+ if (!mom.isValid()) {
+ // No op
+ return;
+ }
+
+ updateOffset = updateOffset == null ? true : updateOffset;
+
+ if (months) {
+ setMonth(mom, get(mom, 'Month') + months * isAdding);
+ }
+ if (days) {
+ set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
+ }
+ if (milliseconds) {
+ mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
+ }
+ if (updateOffset) {
+ hooks.updateOffset(mom, days || months);
+ }
+}
+
+var add = createAdder(1, 'add');
+var subtract = createAdder(-1, 'subtract');
+
+function getCalendarFormat(myMoment, now) {
+ var diff = myMoment.diff(now, 'days', true);
+ return diff < -6 ? 'sameElse' :
+ diff < -1 ? 'lastWeek' :
+ diff < 0 ? 'lastDay' :
+ diff < 1 ? 'sameDay' :
+ diff < 2 ? 'nextDay' :
+ diff < 7 ? 'nextWeek' : 'sameElse';
+}
+
+function calendar$1 (time, formats) {
+ // We want to compare the start of today, vs this.
+ // Getting start-of-today depends on whether we're local/utc/offset or not.
+ var now = time || createLocal(),
+ sod = cloneWithOffset(now, this).startOf('day'),
+ format = hooks.calendarFormat(this, sod) || 'sameElse';
+
+ var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
+
+ return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
+}
+
+function clone () {
+ return new Moment(this);
+}
+
+function isAfter (input, units) {
+ var localInput = isMoment(input) ? input : createLocal(input);
+ if (!(this.isValid() && localInput.isValid())) {
+ return false;
+ }
+ units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
+ if (units === 'millisecond') {
+ return this.valueOf() > localInput.valueOf();
+ } else {
+ return localInput.valueOf() < this.clone().startOf(units).valueOf();
+ }
+}
+
+function isBefore (input, units) {
+ var localInput = isMoment(input) ? input : createLocal(input);
+ if (!(this.isValid() && localInput.isValid())) {
+ return false;
+ }
+ units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
+ if (units === 'millisecond') {
+ return this.valueOf() < localInput.valueOf();
+ } else {
+ return this.clone().endOf(units).valueOf() < localInput.valueOf();
+ }
+}
+
+function isBetween (from, to, units, inclusivity) {
+ inclusivity = inclusivity || '()';
+ return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
+ (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
+}
+
+function isSame (input, units) {
+ var localInput = isMoment(input) ? input : createLocal(input),
+ inputMs;
+ if (!(this.isValid() && localInput.isValid())) {
+ return false;
+ }
+ units = normalizeUnits(units || 'millisecond');
+ if (units === 'millisecond') {
+ return this.valueOf() === localInput.valueOf();
+ } else {
+ inputMs = localInput.valueOf();
+ return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
+ }
+}
+
+function isSameOrAfter (input, units) {
+ return this.isSame(input, units) || this.isAfter(input,units);
+}
+
+function isSameOrBefore (input, units) {
+ return this.isSame(input, units) || this.isBefore(input,units);
+}
+
+function diff (input, units, asFloat) {
+ var that,
+ zoneDelta,
+ delta, output;
+
+ if (!this.isValid()) {
+ return NaN;
+ }
+
+ that = cloneWithOffset(input, this);
+
+ if (!that.isValid()) {
+ return NaN;
+ }
+
+ zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
+
+ units = normalizeUnits(units);
+
+ switch (units) {
+ case 'year': output = monthDiff(this, that) / 12; break;
+ case 'month': output = monthDiff(this, that); break;
+ case 'quarter': output = monthDiff(this, that) / 3; break;
+ case 'second': output = (this - that) / 1e3; break; // 1000
+ case 'minute': output = (this - that) / 6e4; break; // 1000 * 60
+ case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60
+ case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst
+ case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst
+ default: output = this - that;
+ }
+
+ return asFloat ? output : absFloor(output);
+}
+
+function monthDiff (a, b) {
+ // difference in months
+ var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
+ // b is in (anchor - 1 month, anchor + 1 month)
+ anchor = a.clone().add(wholeMonthDiff, 'months'),
+ anchor2, adjust;
+
+ if (b - anchor < 0) {
+ anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
+ // linear across the month
+ adjust = (b - anchor) / (anchor - anchor2);
+ } else {
+ anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
+ // linear across the month
+ adjust = (b - anchor) / (anchor2 - anchor);
+ }
+
+ //check for negative zero, return zero if negative zero
+ return -(wholeMonthDiff + adjust) || 0;
+}
+
+hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
+hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
+
+function toString () {
+ return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
+}
+
+function toISOString(keepOffset) {
+ if (!this.isValid()) {
+ return null;
+ }
+ var utc = keepOffset !== true;
+ var m = utc ? this.clone().utc() : this;
+ if (m.year() < 0 || m.year() > 9999) {
+ return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
+ }
+ if (isFunction(Date.prototype.toISOString)) {
+ // native implementation is ~50x faster, use it when we can
+ if (utc) {
+ return this.toDate().toISOString();
+ } else {
+ return new Date(this._d.valueOf()).toISOString().replace('Z', formatMoment(m, 'Z'));
+ }
+ }
+ return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
+}
+
+/**
+ * Return a human readable representation of a moment that can
+ * also be evaluated to get a new moment which is the same
+ *
+ * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
+ */
+function inspect () {
+ if (!this.isValid()) {
+ return 'moment.invalid(/* ' + this._i + ' */)';
+ }
+ var func = 'moment';
+ var zone = '';
+ if (!this.isLocal()) {
+ func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
+ zone = 'Z';
+ }
+ var prefix = '[' + func + '("]';
+ var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
+ var datetime = '-MM-DD[T]HH:mm:ss.SSS';
+ var suffix = zone + '[")]';
+
+ return this.format(prefix + year + datetime + suffix);
+}
+
+function format (inputString) {
+ if (!inputString) {
+ inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
+ }
+ var output = formatMoment(this, inputString);
+ return this.localeData().postformat(output);
+}
+
+function from (time, withoutSuffix) {
+ if (this.isValid() &&
+ ((isMoment(time) && time.isValid()) ||
+ createLocal(time).isValid())) {
+ return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
+ } else {
+ return this.localeData().invalidDate();
+ }
+}
+
+function fromNow (withoutSuffix) {
+ return this.from(createLocal(), withoutSuffix);
+}
+
+function to (time, withoutSuffix) {
+ if (this.isValid() &&
+ ((isMoment(time) && time.isValid()) ||
+ createLocal(time).isValid())) {
+ return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
+ } else {
+ return this.localeData().invalidDate();
+ }
+}
+
+function toNow (withoutSuffix) {
+ return this.to(createLocal(), withoutSuffix);
+}
+
+// If passed a locale key, it will set the locale for this
+// instance. Otherwise, it will return the locale configuration
+// variables for this instance.
+function locale (key) {
+ var newLocaleData;
+
+ if (key === undefined) {
+ return this._locale._abbr;
+ } else {
+ newLocaleData = getLocale(key);
+ if (newLocaleData != null) {
+ this._locale = newLocaleData;
+ }
+ return this;
+ }
+}
+
+var lang = deprecate(
+ 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
+ function (key) {
+ if (key === undefined) {
+ return this.localeData();
+ } else {
+ return this.locale(key);
+ }
+ }
+);
+
+function localeData () {
+ return this._locale;
+}
+
+function startOf (units) {
+ units = normalizeUnits(units);
+ // the following switch intentionally omits break keywords
+ // to utilize falling through the cases.
+ switch (units) {
+ case 'year':
+ this.month(0);
+ /* falls through */
+ case 'quarter':
+ case 'month':
+ this.date(1);
+ /* falls through */
+ case 'week':
+ case 'isoWeek':
+ case 'day':
+ case 'date':
+ this.hours(0);
+ /* falls through */
+ case 'hour':
+ this.minutes(0);
+ /* falls through */
+ case 'minute':
+ this.seconds(0);
+ /* falls through */
+ case 'second':
+ this.milliseconds(0);
+ }
+
+ // weeks are a special case
+ if (units === 'week') {
+ this.weekday(0);
+ }
+ if (units === 'isoWeek') {
+ this.isoWeekday(1);
+ }
+
+ // quarters are also special
+ if (units === 'quarter') {
+ this.month(Math.floor(this.month() / 3) * 3);
+ }
+
+ return this;
+}
+
+function endOf (units) {
+ units = normalizeUnits(units);
+ if (units === undefined || units === 'millisecond') {
+ return this;
+ }
+
+ // 'date' is an alias for 'day', so it should be considered as such.
+ if (units === 'date') {
+ units = 'day';
+ }
+
+ return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
+}
+
+function valueOf () {
+ return this._d.valueOf() - ((this._offset || 0) * 60000);
+}
+
+function unix () {
+ return Math.floor(this.valueOf() / 1000);
+}
+
+function toDate () {
+ return new Date(this.valueOf());
+}
+
+function toArray () {
+ var m = this;
+ return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
+}
+
+function toObject () {
+ var m = this;
+ return {
+ years: m.year(),
+ months: m.month(),
+ date: m.date(),
+ hours: m.hours(),
+ minutes: m.minutes(),
+ seconds: m.seconds(),
+ milliseconds: m.milliseconds()
+ };
+}
+
+function toJSON () {
+ // new Date(NaN).toJSON() === null
+ return this.isValid() ? this.toISOString() : null;
+}
+
+function isValid$2 () {
+ return isValid(this);
+}
+
+function parsingFlags () {
+ return extend({}, getParsingFlags(this));
+}
+
+function invalidAt () {
+ return getParsingFlags(this).overflow;
+}
+
+function creationData() {
+ return {
+ input: this._i,
+ format: this._f,
+ locale: this._locale,
+ isUTC: this._isUTC,
+ strict: this._strict
+ };
+}
+
+// FORMATTING
+
+addFormatToken(0, ['gg', 2], 0, function () {
+ return this.weekYear() % 100;
+});
+
+addFormatToken(0, ['GG', 2], 0, function () {
+ return this.isoWeekYear() % 100;
+});
+
+function addWeekYearFormatToken (token, getter) {
+ addFormatToken(0, [token, token.length], 0, getter);
+}
+
+addWeekYearFormatToken('gggg', 'weekYear');
+addWeekYearFormatToken('ggggg', 'weekYear');
+addWeekYearFormatToken('GGGG', 'isoWeekYear');
+addWeekYearFormatToken('GGGGG', 'isoWeekYear');
+
+// ALIASES
+
+addUnitAlias('weekYear', 'gg');
+addUnitAlias('isoWeekYear', 'GG');
+
+// PRIORITY
+
+addUnitPriority('weekYear', 1);
+addUnitPriority('isoWeekYear', 1);
+
+
+// PARSING
+
+addRegexToken('G', matchSigned);
+addRegexToken('g', matchSigned);
+addRegexToken('GG', match1to2, match2);
+addRegexToken('gg', match1to2, match2);
+addRegexToken('GGGG', match1to4, match4);
+addRegexToken('gggg', match1to4, match4);
+addRegexToken('GGGGG', match1to6, match6);
+addRegexToken('ggggg', match1to6, match6);
+
+addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
+ week[token.substr(0, 2)] = toInt(input);
+});
+
+addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
+ week[token] = hooks.parseTwoDigitYear(input);
+});
+
+// MOMENTS
+
+function getSetWeekYear (input) {
+ return getSetWeekYearHelper.call(this,
+ input,
+ this.week(),
+ this.weekday(),
+ this.localeData()._week.dow,
+ this.localeData()._week.doy);
+}
+
+function getSetISOWeekYear (input) {
+ return getSetWeekYearHelper.call(this,
+ input, this.isoWeek(), this.isoWeekday(), 1, 4);
+}
+
+function getISOWeeksInYear () {
+ return weeksInYear(this.year(), 1, 4);
+}
+
+function getWeeksInYear () {
+ var weekInfo = this.localeData()._week;
+ return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
+}
+
+function getSetWeekYearHelper(input, week, weekday, dow, doy) {
+ var weeksTarget;
+ if (input == null) {
+ return weekOfYear(this, dow, doy).year;
+ } else {
+ weeksTarget = weeksInYear(input, dow, doy);
+ if (week > weeksTarget) {
+ week = weeksTarget;
+ }
+ return setWeekAll.call(this, input, week, weekday, dow, doy);
+ }
+}
+
+function setWeekAll(weekYear, week, weekday, dow, doy) {
+ var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
+ date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
+
+ this.year(date.getUTCFullYear());
+ this.month(date.getUTCMonth());
+ this.date(date.getUTCDate());
+ return this;
+}
+
+// FORMATTING
+
+addFormatToken('Q', 0, 'Qo', 'quarter');
+
+// ALIASES
+
+addUnitAlias('quarter', 'Q');
+
+// PRIORITY
+
+addUnitPriority('quarter', 7);
+
+// PARSING
+
+addRegexToken('Q', match1);
+addParseToken('Q', function (input, array) {
+ array[MONTH] = (toInt(input) - 1) * 3;
+});
+
+// MOMENTS
+
+function getSetQuarter (input) {
+ return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
+}
+
+// FORMATTING
+
+addFormatToken('D', ['DD', 2], 'Do', 'date');
+
+// ALIASES
+
+addUnitAlias('date', 'D');
+
+// PRIOROITY
+addUnitPriority('date', 9);
+
+// PARSING
+
+addRegexToken('D', match1to2);
+addRegexToken('DD', match1to2, match2);
+addRegexToken('Do', function (isStrict, locale) {
+ // TODO: Remove "ordinalParse" fallback in next major release.
+ return isStrict ?
+ (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :
+ locale._dayOfMonthOrdinalParseLenient;
+});
+
+addParseToken(['D', 'DD'], DATE);
+addParseToken('Do', function (input, array) {
+ array[DATE] = toInt(input.match(match1to2)[0]);
+});
+
+// MOMENTS
+
+var getSetDayOfMonth = makeGetSet('Date', true);
+
+// FORMATTING
+
+addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
+
+// ALIASES
+
+addUnitAlias('dayOfYear', 'DDD');
+
+// PRIORITY
+addUnitPriority('dayOfYear', 4);
+
+// PARSING
+
+addRegexToken('DDD', match1to3);
+addRegexToken('DDDD', match3);
+addParseToken(['DDD', 'DDDD'], function (input, array, config) {
+ config._dayOfYear = toInt(input);
+});
+
+// HELPERS
+
+// MOMENTS
+
+function getSetDayOfYear (input) {
+ var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
+ return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
+}
+
+// FORMATTING
+
+addFormatToken('m', ['mm', 2], 0, 'minute');
+
+// ALIASES
+
+addUnitAlias('minute', 'm');
+
+// PRIORITY
+
+addUnitPriority('minute', 14);
+
+// PARSING
+
+addRegexToken('m', match1to2);
+addRegexToken('mm', match1to2, match2);
+addParseToken(['m', 'mm'], MINUTE);
+
+// MOMENTS
+
+var getSetMinute = makeGetSet('Minutes', false);
+
+// FORMATTING
+
+addFormatToken('s', ['ss', 2], 0, 'second');
+
+// ALIASES
+
+addUnitAlias('second', 's');
+
+// PRIORITY
+
+addUnitPriority('second', 15);
+
+// PARSING
+
+addRegexToken('s', match1to2);
+addRegexToken('ss', match1to2, match2);
+addParseToken(['s', 'ss'], SECOND);
+
+// MOMENTS
+
+var getSetSecond = makeGetSet('Seconds', false);
+
+// FORMATTING
+
+addFormatToken('S', 0, 0, function () {
+ return ~~(this.millisecond() / 100);
+});
+
+addFormatToken(0, ['SS', 2], 0, function () {
+ return ~~(this.millisecond() / 10);
+});
+
+addFormatToken(0, ['SSS', 3], 0, 'millisecond');
+addFormatToken(0, ['SSSS', 4], 0, function () {
+ return this.millisecond() * 10;
+});
+addFormatToken(0, ['SSSSS', 5], 0, function () {
+ return this.millisecond() * 100;
+});
+addFormatToken(0, ['SSSSSS', 6], 0, function () {
+ return this.millisecond() * 1000;
+});
+addFormatToken(0, ['SSSSSSS', 7], 0, function () {
+ return this.millisecond() * 10000;
+});
+addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
+ return this.millisecond() * 100000;
+});
+addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
+ return this.millisecond() * 1000000;
+});
+
+
+// ALIASES
+
+addUnitAlias('millisecond', 'ms');
+
+// PRIORITY
+
+addUnitPriority('millisecond', 16);
+
+// PARSING
+
+addRegexToken('S', match1to3, match1);
+addRegexToken('SS', match1to3, match2);
+addRegexToken('SSS', match1to3, match3);
+
+var token;
+for (token = 'SSSS'; token.length <= 9; token += 'S') {
+ addRegexToken(token, matchUnsigned);
+}
+
+function parseMs(input, array) {
+ array[MILLISECOND] = toInt(('0.' + input) * 1000);
+}
+
+for (token = 'S'; token.length <= 9; token += 'S') {
+ addParseToken(token, parseMs);
+}
+// MOMENTS
+
+var getSetMillisecond = makeGetSet('Milliseconds', false);
+
+// FORMATTING
+
+addFormatToken('z', 0, 0, 'zoneAbbr');
+addFormatToken('zz', 0, 0, 'zoneName');
+
+// MOMENTS
+
+function getZoneAbbr () {
+ return this._isUTC ? 'UTC' : '';
+}
+
+function getZoneName () {
+ return this._isUTC ? 'Coordinated Universal Time' : '';
+}
+
+var proto = Moment.prototype;
+
+proto.add = add;
+proto.calendar = calendar$1;
+proto.clone = clone;
+proto.diff = diff;
+proto.endOf = endOf;
+proto.format = format;
+proto.from = from;
+proto.fromNow = fromNow;
+proto.to = to;
+proto.toNow = toNow;
+proto.get = stringGet;
+proto.invalidAt = invalidAt;
+proto.isAfter = isAfter;
+proto.isBefore = isBefore;
+proto.isBetween = isBetween;
+proto.isSame = isSame;
+proto.isSameOrAfter = isSameOrAfter;
+proto.isSameOrBefore = isSameOrBefore;
+proto.isValid = isValid$2;
+proto.lang = lang;
+proto.locale = locale;
+proto.localeData = localeData;
+proto.max = prototypeMax;
+proto.min = prototypeMin;
+proto.parsingFlags = parsingFlags;
+proto.set = stringSet;
+proto.startOf = startOf;
+proto.subtract = subtract;
+proto.toArray = toArray;
+proto.toObject = toObject;
+proto.toDate = toDate;
+proto.toISOString = toISOString;
+proto.inspect = inspect;
+proto.toJSON = toJSON;
+proto.toString = toString;
+proto.unix = unix;
+proto.valueOf = valueOf;
+proto.creationData = creationData;
+
+// Year
+proto.year = getSetYear;
+proto.isLeapYear = getIsLeapYear;
+
+// Week Year
+proto.weekYear = getSetWeekYear;
+proto.isoWeekYear = getSetISOWeekYear;
+
+// Quarter
+proto.quarter = proto.quarters = getSetQuarter;
+
+// Month
+proto.month = getSetMonth;
+proto.daysInMonth = getDaysInMonth;
+
+// Week
+proto.week = proto.weeks = getSetWeek;
+proto.isoWeek = proto.isoWeeks = getSetISOWeek;
+proto.weeksInYear = getWeeksInYear;
+proto.isoWeeksInYear = getISOWeeksInYear;
+
+// Day
+proto.date = getSetDayOfMonth;
+proto.day = proto.days = getSetDayOfWeek;
+proto.weekday = getSetLocaleDayOfWeek;
+proto.isoWeekday = getSetISODayOfWeek;
+proto.dayOfYear = getSetDayOfYear;
+
+// Hour
+proto.hour = proto.hours = getSetHour;
+
+// Minute
+proto.minute = proto.minutes = getSetMinute;
+
+// Second
+proto.second = proto.seconds = getSetSecond;
+
+// Millisecond
+proto.millisecond = proto.milliseconds = getSetMillisecond;
+
+// Offset
+proto.utcOffset = getSetOffset;
+proto.utc = setOffsetToUTC;
+proto.local = setOffsetToLocal;
+proto.parseZone = setOffsetToParsedOffset;
+proto.hasAlignedHourOffset = hasAlignedHourOffset;
+proto.isDST = isDaylightSavingTime;
+proto.isLocal = isLocal;
+proto.isUtcOffset = isUtcOffset;
+proto.isUtc = isUtc;
+proto.isUTC = isUtc;
+
+// Timezone
+proto.zoneAbbr = getZoneAbbr;
+proto.zoneName = getZoneName;
+
+// Deprecations
+proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
+proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
+proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
+proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
+proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
+
+function createUnix (input) {
+ return createLocal(input * 1000);
+}
+
+function createInZone () {
+ return createLocal.apply(null, arguments).parseZone();
+}
+
+function preParsePostFormat (string) {
+ return string;
+}
+
+var proto$1 = Locale.prototype;
+
+proto$1.calendar = calendar;
+proto$1.longDateFormat = longDateFormat;
+proto$1.invalidDate = invalidDate;
+proto$1.ordinal = ordinal;
+proto$1.preparse = preParsePostFormat;
+proto$1.postformat = preParsePostFormat;
+proto$1.relativeTime = relativeTime;
+proto$1.pastFuture = pastFuture;
+proto$1.set = set;
+
+// Month
+proto$1.months = localeMonths;
+proto$1.monthsShort = localeMonthsShort;
+proto$1.monthsParse = localeMonthsParse;
+proto$1.monthsRegex = monthsRegex;
+proto$1.monthsShortRegex = monthsShortRegex;
+
+// Week
+proto$1.week = localeWeek;
+proto$1.firstDayOfYear = localeFirstDayOfYear;
+proto$1.firstDayOfWeek = localeFirstDayOfWeek;
+
+// Day of Week
+proto$1.weekdays = localeWeekdays;
+proto$1.weekdaysMin = localeWeekdaysMin;
+proto$1.weekdaysShort = localeWeekdaysShort;
+proto$1.weekdaysParse = localeWeekdaysParse;
+
+proto$1.weekdaysRegex = weekdaysRegex;
+proto$1.weekdaysShortRegex = weekdaysShortRegex;
+proto$1.weekdaysMinRegex = weekdaysMinRegex;
+
+// Hours
+proto$1.isPM = localeIsPM;
+proto$1.meridiem = localeMeridiem;
+
+function get$1 (format, index, field, setter) {
+ var locale = getLocale();
+ var utc = createUTC().set(setter, index);
+ return locale[field](utc, format);
+}
+
+function listMonthsImpl (format, index, field) {
+ if (isNumber(format)) {
+ index = format;
+ format = undefined;
+ }
+
+ format = format || '';
+
+ if (index != null) {
+ return get$1(format, index, field, 'month');
+ }
+
+ var i;
+ var out = [];
+ for (i = 0; i < 12; i++) {
+ out[i] = get$1(format, i, field, 'month');
+ }
+ return out;
+}
+
+// ()
+// (5)
+// (fmt, 5)
+// (fmt)
+// (true)
+// (true, 5)
+// (true, fmt, 5)
+// (true, fmt)
+function listWeekdaysImpl (localeSorted, format, index, field) {
+ if (typeof localeSorted === 'boolean') {
+ if (isNumber(format)) {
+ index = format;
+ format = undefined;
+ }
+
+ format = format || '';
+ } else {
+ format = localeSorted;
+ index = format;
+ localeSorted = false;
+
+ if (isNumber(format)) {
+ index = format;
+ format = undefined;
+ }
+
+ format = format || '';
+ }
+
+ var locale = getLocale(),
+ shift = localeSorted ? locale._week.dow : 0;
+
+ if (index != null) {
+ return get$1(format, (index + shift) % 7, field, 'day');
+ }
+
+ var i;
+ var out = [];
+ for (i = 0; i < 7; i++) {
+ out[i] = get$1(format, (i + shift) % 7, field, 'day');
+ }
+ return out;
+}
+
+function listMonths (format, index) {
+ return listMonthsImpl(format, index, 'months');
+}
+
+function listMonthsShort (format, index) {
+ return listMonthsImpl(format, index, 'monthsShort');
+}
+
+function listWeekdays (localeSorted, format, index) {
+ return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
+}
+
+function listWeekdaysShort (localeSorted, format, index) {
+ return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
+}
+
+function listWeekdaysMin (localeSorted, format, index) {
+ return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
+}
+
+getSetGlobalLocale('en', {
+ dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
+ ordinal : function (number) {
+ var b = number % 10,
+ output = (toInt(number % 100 / 10) === 1) ? 'th' :
+ (b === 1) ? 'st' :
+ (b === 2) ? 'nd' :
+ (b === 3) ? 'rd' : 'th';
+ return number + output;
+ }
+});
+
+// Side effect imports
+hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
+hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
+
+var mathAbs = Math.abs;
+
+function abs () {
+ var data = this._data;
+
+ this._milliseconds = mathAbs(this._milliseconds);
+ this._days = mathAbs(this._days);
+ this._months = mathAbs(this._months);
+
+ data.milliseconds = mathAbs(data.milliseconds);
+ data.seconds = mathAbs(data.seconds);
+ data.minutes = mathAbs(data.minutes);
+ data.hours = mathAbs(data.hours);
+ data.months = mathAbs(data.months);
+ data.years = mathAbs(data.years);
+
+ return this;
+}
+
+function addSubtract$1 (duration, input, value, direction) {
+ var other = createDuration(input, value);
+
+ duration._milliseconds += direction * other._milliseconds;
+ duration._days += direction * other._days;
+ duration._months += direction * other._months;
+
+ return duration._bubble();
+}
+
+// supports only 2.0-style add(1, 's') or add(duration)
+function add$1 (input, value) {
+ return addSubtract$1(this, input, value, 1);
+}
+
+// supports only 2.0-style subtract(1, 's') or subtract(duration)
+function subtract$1 (input, value) {
+ return addSubtract$1(this, input, value, -1);
+}
+
+function absCeil (number) {
+ if (number < 0) {
+ return Math.floor(number);
+ } else {
+ return Math.ceil(number);
+ }
+}
+
+function bubble () {
+ var milliseconds = this._milliseconds;
+ var days = this._days;
+ var months = this._months;
+ var data = this._data;
+ var seconds, minutes, hours, years, monthsFromDays;
+
+ // if we have a mix of positive and negative values, bubble down first
+ // check: https://github.com/moment/moment/issues/2166
+ if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
+ (milliseconds <= 0 && days <= 0 && months <= 0))) {
+ milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
+ days = 0;
+ months = 0;
+ }
+
+ // The following code bubbles up values, see the tests for
+ // examples of what that means.
+ data.milliseconds = milliseconds % 1000;
+
+ seconds = absFloor(milliseconds / 1000);
+ data.seconds = seconds % 60;
+
+ minutes = absFloor(seconds / 60);
+ data.minutes = minutes % 60;
+
+ hours = absFloor(minutes / 60);
+ data.hours = hours % 24;
+
+ days += absFloor(hours / 24);
+
+ // convert days to months
+ monthsFromDays = absFloor(daysToMonths(days));
+ months += monthsFromDays;
+ days -= absCeil(monthsToDays(monthsFromDays));
+
+ // 12 months -> 1 year
+ years = absFloor(months / 12);
+ months %= 12;
+
+ data.days = days;
+ data.months = months;
+ data.years = years;
+
+ return this;
+}
+
+function daysToMonths (days) {
+ // 400 years have 146097 days (taking into account leap year rules)
+ // 400 years have 12 months === 4800
+ return days * 4800 / 146097;
+}
+
+function monthsToDays (months) {
+ // the reverse of daysToMonths
+ return months * 146097 / 4800;
+}
+
+function as (units) {
+ if (!this.isValid()) {
+ return NaN;
+ }
+ var days;
+ var months;
+ var milliseconds = this._milliseconds;
+
+ units = normalizeUnits(units);
+
+ if (units === 'month' || units === 'year') {
+ days = this._days + milliseconds / 864e5;
+ months = this._months + daysToMonths(days);
+ return units === 'month' ? months : months / 12;
+ } else {
+ // handle milliseconds separately because of floating point math errors (issue #1867)
+ days = this._days + Math.round(monthsToDays(this._months));
+ switch (units) {
+ case 'week' : return days / 7 + milliseconds / 6048e5;
+ case 'day' : return days + milliseconds / 864e5;
+ case 'hour' : return days * 24 + milliseconds / 36e5;
+ case 'minute' : return days * 1440 + milliseconds / 6e4;
+ case 'second' : return days * 86400 + milliseconds / 1000;
+ // Math.floor prevents floating point math errors here
+ case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
+ default: throw new Error('Unknown unit ' + units);
+ }
+ }
+}
+
+// TODO: Use this.as('ms')?
+function valueOf$1 () {
+ if (!this.isValid()) {
+ return NaN;
+ }
+ return (
+ this._milliseconds +
+ this._days * 864e5 +
+ (this._months % 12) * 2592e6 +
+ toInt(this._months / 12) * 31536e6
+ );
+}
+
+function makeAs (alias) {
+ return function () {
+ return this.as(alias);
+ };
+}
+
+var asMilliseconds = makeAs('ms');
+var asSeconds = makeAs('s');
+var asMinutes = makeAs('m');
+var asHours = makeAs('h');
+var asDays = makeAs('d');
+var asWeeks = makeAs('w');
+var asMonths = makeAs('M');
+var asYears = makeAs('y');
+
+function clone$1 () {
+ return createDuration(this);
+}
+
+function get$2 (units) {
+ units = normalizeUnits(units);
+ return this.isValid() ? this[units + 's']() : NaN;
+}
+
+function makeGetter(name) {
+ return function () {
+ return this.isValid() ? this._data[name] : NaN;
+ };
+}
+
+var milliseconds = makeGetter('milliseconds');
+var seconds = makeGetter('seconds');
+var minutes = makeGetter('minutes');
+var hours = makeGetter('hours');
+var days = makeGetter('days');
+var months = makeGetter('months');
+var years = makeGetter('years');
+
+function weeks () {
+ return absFloor(this.days() / 7);
+}
+
+var round = Math.round;
+var thresholds = {
+ ss: 44, // a few seconds to seconds
+ s : 45, // seconds to minute
+ m : 45, // minutes to hour
+ h : 22, // hours to day
+ d : 26, // days to month
+ M : 11 // months to year
+};
+
+// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
+function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
+ return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
+}
+
+function relativeTime$1 (posNegDuration, withoutSuffix, locale) {
+ var duration = createDuration(posNegDuration).abs();
+ var seconds = round(duration.as('s'));
+ var minutes = round(duration.as('m'));
+ var hours = round(duration.as('h'));
+ var days = round(duration.as('d'));
+ var months = round(duration.as('M'));
+ var years = round(duration.as('y'));
+
+ var a = seconds <= thresholds.ss && ['s', seconds] ||
+ seconds < thresholds.s && ['ss', seconds] ||
+ minutes <= 1 && ['m'] ||
+ minutes < thresholds.m && ['mm', minutes] ||
+ hours <= 1 && ['h'] ||
+ hours < thresholds.h && ['hh', hours] ||
+ days <= 1 && ['d'] ||
+ days < thresholds.d && ['dd', days] ||
+ months <= 1 && ['M'] ||
+ months < thresholds.M && ['MM', months] ||
+ years <= 1 && ['y'] || ['yy', years];
+
+ a[2] = withoutSuffix;
+ a[3] = +posNegDuration > 0;
+ a[4] = locale;
+ return substituteTimeAgo.apply(null, a);
+}
+
+// This function allows you to set the rounding function for relative time strings
+function getSetRelativeTimeRounding (roundingFunction) {
+ if (roundingFunction === undefined) {
+ return round;
+ }
+ if (typeof(roundingFunction) === 'function') {
+ round = roundingFunction;
+ return true;
+ }
+ return false;
+}
+
+// This function allows you to set a threshold for relative time strings
+function getSetRelativeTimeThreshold (threshold, limit) {
+ if (thresholds[threshold] === undefined) {
+ return false;
+ }
+ if (limit === undefined) {
+ return thresholds[threshold];
+ }
+ thresholds[threshold] = limit;
+ if (threshold === 's') {
+ thresholds.ss = limit - 1;
+ }
+ return true;
+}
+
+function humanize (withSuffix) {
+ if (!this.isValid()) {
+ return this.localeData().invalidDate();
+ }
+
+ var locale = this.localeData();
+ var output = relativeTime$1(this, !withSuffix, locale);
+
+ if (withSuffix) {
+ output = locale.pastFuture(+this, output);
+ }
+
+ return locale.postformat(output);
+}
+
+var abs$1 = Math.abs;
+
+function sign(x) {
+ return ((x > 0) - (x < 0)) || +x;
+}
+
+function toISOString$1() {
+ // for ISO strings we do not use the normal bubbling rules:
+ // * milliseconds bubble up until they become hours
+ // * days do not bubble at all
+ // * months bubble up until they become years
+ // This is because there is no context-free conversion between hours and days
+ // (think of clock changes)
+ // and also not between days and months (28-31 days per month)
+ if (!this.isValid()) {
+ return this.localeData().invalidDate();
+ }
+
+ var seconds = abs$1(this._milliseconds) / 1000;
+ var days = abs$1(this._days);
+ var months = abs$1(this._months);
+ var minutes, hours, years;
+
+ // 3600 seconds -> 60 minutes -> 1 hour
+ minutes = absFloor(seconds / 60);
+ hours = absFloor(minutes / 60);
+ seconds %= 60;
+ minutes %= 60;
+
+ // 12 months -> 1 year
+ years = absFloor(months / 12);
+ months %= 12;
+
+
+ // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
+ var Y = years;
+ var M = months;
+ var D = days;
+ var h = hours;
+ var m = minutes;
+ var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
+ var total = this.asSeconds();
+
+ if (!total) {
+ // this is the same as C#'s (Noda) and python (isodate)...
+ // but not other JS (goog.date)
+ return 'P0D';
+ }
+
+ var totalSign = total < 0 ? '-' : '';
+ var ymSign = sign(this._months) !== sign(total) ? '-' : '';
+ var daysSign = sign(this._days) !== sign(total) ? '-' : '';
+ var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
+
+ return totalSign + 'P' +
+ (Y ? ymSign + Y + 'Y' : '') +
+ (M ? ymSign + M + 'M' : '') +
+ (D ? daysSign + D + 'D' : '') +
+ ((h || m || s) ? 'T' : '') +
+ (h ? hmsSign + h + 'H' : '') +
+ (m ? hmsSign + m + 'M' : '') +
+ (s ? hmsSign + s + 'S' : '');
+}
+
+var proto$2 = Duration.prototype;
+
+proto$2.isValid = isValid$1;
+proto$2.abs = abs;
+proto$2.add = add$1;
+proto$2.subtract = subtract$1;
+proto$2.as = as;
+proto$2.asMilliseconds = asMilliseconds;
+proto$2.asSeconds = asSeconds;
+proto$2.asMinutes = asMinutes;
+proto$2.asHours = asHours;
+proto$2.asDays = asDays;
+proto$2.asWeeks = asWeeks;
+proto$2.asMonths = asMonths;
+proto$2.asYears = asYears;
+proto$2.valueOf = valueOf$1;
+proto$2._bubble = bubble;
+proto$2.clone = clone$1;
+proto$2.get = get$2;
+proto$2.milliseconds = milliseconds;
+proto$2.seconds = seconds;
+proto$2.minutes = minutes;
+proto$2.hours = hours;
+proto$2.days = days;
+proto$2.weeks = weeks;
+proto$2.months = months;
+proto$2.years = years;
+proto$2.humanize = humanize;
+proto$2.toISOString = toISOString$1;
+proto$2.toString = toISOString$1;
+proto$2.toJSON = toISOString$1;
+proto$2.locale = locale;
+proto$2.localeData = localeData;
+
+// Deprecations
+proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
+proto$2.lang = lang;
+
+// Side effect imports
+
+// FORMATTING
+
+addFormatToken('X', 0, 0, 'unix');
+addFormatToken('x', 0, 0, 'valueOf');
+
+// PARSING
+
+addRegexToken('x', matchSigned);
+addRegexToken('X', matchTimestamp);
+addParseToken('X', function (input, array, config) {
+ config._d = new Date(parseFloat(input, 10) * 1000);
+});
+addParseToken('x', function (input, array, config) {
+ config._d = new Date(toInt(input));
+});
+
+// Side effect imports
+
+
+hooks.version = '2.20.1';
+
+setHookCallback(createLocal);
+
+hooks.fn = proto;
+hooks.min = min;
+hooks.max = max;
+hooks.now = now;
+hooks.utc = createUTC;
+hooks.unix = createUnix;
+hooks.months = listMonths;
+hooks.isDate = isDate;
+hooks.locale = getSetGlobalLocale;
+hooks.invalid = createInvalid;
+hooks.duration = createDuration;
+hooks.isMoment = isMoment;
+hooks.weekdays = listWeekdays;
+hooks.parseZone = createInZone;
+hooks.localeData = getLocale;
+hooks.isDuration = isDuration;
+hooks.monthsShort = listMonthsShort;
+hooks.weekdaysMin = listWeekdaysMin;
+hooks.defineLocale = defineLocale;
+hooks.updateLocale = updateLocale;
+hooks.locales = listLocales;
+hooks.weekdaysShort = listWeekdaysShort;
+hooks.normalizeUnits = normalizeUnits;
+hooks.relativeTimeRounding = getSetRelativeTimeRounding;
+hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
+hooks.calendarFormat = getCalendarFormat;
+hooks.prototype = proto;
+
+// currently HTML5 input type only supports 24-hour formats
+hooks.HTML5_FMT = {
+ DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', //
+ DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', //
+ DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', //
+ DATE: 'YYYY-MM-DD', //
+ TIME: 'HH:mm', //
+ TIME_SECONDS: 'HH:mm:ss', //
+ TIME_MS: 'HH:mm:ss.SSS', //
+ WEEK: 'YYYY-[W]WW', //
+ MONTH: 'YYYY-MM' //
+};
+
+return hooks;
+
+})));
+
+},{}],7:[function(require,module,exports){
+/**
+ * @namespace Chart
+ */
+var Chart = require(29)();
+
+Chart.helpers = require(45);
+
+// @todo dispatch these helpers into appropriated helpers/helpers.* file and write unit tests!
+require(27)(Chart);
+
+Chart.defaults = require(25);
+Chart.Element = require(26);
+Chart.elements = require(40);
+Chart.Interaction = require(28);
+Chart.layouts = require(30);
+Chart.platform = require(48);
+Chart.plugins = require(31);
+Chart.Ticks = require(34);
+
+require(22)(Chart);
+require(23)(Chart);
+require(24)(Chart);
+require(33)(Chart);
+require(32)(Chart);
+require(35)(Chart);
+
+require(55)(Chart);
+require(53)(Chart);
+require(54)(Chart);
+require(56)(Chart);
+require(57)(Chart);
+require(58)(Chart);
+
+// Controllers must be loaded after elements
+// See Chart.core.datasetController.dataElementType
+require(15)(Chart);
+require(16)(Chart);
+require(17)(Chart);
+require(18)(Chart);
+require(19)(Chart);
+require(20)(Chart);
+require(21)(Chart);
+
+require(8)(Chart);
+require(9)(Chart);
+require(10)(Chart);
+require(11)(Chart);
+require(12)(Chart);
+require(13)(Chart);
+require(14)(Chart);
+
+// Loading built-it plugins
+var plugins = require(49);
+for (var k in plugins) {
+ if (plugins.hasOwnProperty(k)) {
+ Chart.plugins.register(plugins[k]);
+ }
+}
+
+Chart.platform.initialize();
+
+module.exports = Chart;
+if (typeof window !== 'undefined') {
+ window.Chart = Chart;
+}
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, not available anymore
+ * @namespace Chart.Legend
+ * @deprecated since version 2.1.5
+ * @todo remove at version 3
+ * @private
+ */
+Chart.Legend = plugins.legend._element;
+
+/**
+ * Provided for backward compatibility, not available anymore
+ * @namespace Chart.Title
+ * @deprecated since version 2.1.5
+ * @todo remove at version 3
+ * @private
+ */
+Chart.Title = plugins.title._element;
+
+/**
+ * Provided for backward compatibility, use Chart.plugins instead
+ * @namespace Chart.pluginService
+ * @deprecated since version 2.1.5
+ * @todo remove at version 3
+ * @private
+ */
+Chart.pluginService = Chart.plugins;
+
+/**
+ * Provided for backward compatibility, inheriting from Chart.PlugingBase has no
+ * effect, instead simply create/register plugins via plain JavaScript objects.
+ * @interface Chart.PluginBase
+ * @deprecated since version 2.5.0
+ * @todo remove at version 3
+ * @private
+ */
+Chart.PluginBase = Chart.Element.extend({});
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.canvas instead.
+ * @namespace Chart.canvasHelpers
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ * @private
+ */
+Chart.canvasHelpers = Chart.helpers.canvas;
+
+/**
+ * Provided for backward compatibility, use Chart.layouts instead.
+ * @namespace Chart.layoutService
+ * @deprecated since version 2.8.0
+ * @todo remove at version 3
+ * @private
+ */
+Chart.layoutService = Chart.layouts;
+
+},{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"20":20,"21":21,"22":22,"23":23,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"40":40,"45":45,"48":48,"49":49,"53":53,"54":54,"55":55,"56":56,"57":57,"58":58,"8":8,"9":9}],8:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ Chart.Bar = function(context, config) {
+ config.type = 'bar';
+
+ return new Chart(context, config);
+ };
+
+};
+
+},{}],9:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ Chart.Bubble = function(context, config) {
+ config.type = 'bubble';
+ return new Chart(context, config);
+ };
+
+};
+
+},{}],10:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ Chart.Doughnut = function(context, config) {
+ config.type = 'doughnut';
+
+ return new Chart(context, config);
+ };
+
+};
+
+},{}],11:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ Chart.Line = function(context, config) {
+ config.type = 'line';
+
+ return new Chart(context, config);
+ };
+
+};
+
+},{}],12:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ Chart.PolarArea = function(context, config) {
+ config.type = 'polarArea';
+
+ return new Chart(context, config);
+ };
+
+};
+
+},{}],13:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ Chart.Radar = function(context, config) {
+ config.type = 'radar';
+
+ return new Chart(context, config);
+ };
+
+};
+
+},{}],14:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+ Chart.Scatter = function(context, config) {
+ config.type = 'scatter';
+ return new Chart(context, config);
+ };
+};
+
+},{}],15:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('bar', {
+ hover: {
+ mode: 'label'
+ },
+
+ scales: {
+ xAxes: [{
+ type: 'category',
+
+ // Specific to Bar Controller
+ categoryPercentage: 0.8,
+ barPercentage: 0.9,
+
+ // offset settings
+ offset: true,
+
+ // grid line settings
+ gridLines: {
+ offsetGridLines: true
+ }
+ }],
+
+ yAxes: [{
+ type: 'linear'
+ }]
+ }
+});
+
+defaults._set('horizontalBar', {
+ hover: {
+ mode: 'index',
+ axis: 'y'
+ },
+
+ scales: {
+ xAxes: [{
+ type: 'linear',
+ position: 'bottom'
+ }],
+
+ yAxes: [{
+ position: 'left',
+ type: 'category',
+
+ // Specific to Horizontal Bar Controller
+ categoryPercentage: 0.8,
+ barPercentage: 0.9,
+
+ // offset settings
+ offset: true,
+
+ // grid line settings
+ gridLines: {
+ offsetGridLines: true
+ }
+ }]
+ },
+
+ elements: {
+ rectangle: {
+ borderSkipped: 'left'
+ }
+ },
+
+ tooltips: {
+ callbacks: {
+ title: function(item, data) {
+ // Pick first xLabel for now
+ var title = '';
+
+ if (item.length > 0) {
+ if (item[0].yLabel) {
+ title = item[0].yLabel;
+ } else if (data.labels.length > 0 && item[0].index < data.labels.length) {
+ title = data.labels[item[0].index];
+ }
+ }
+
+ return title;
+ },
+
+ label: function(item, data) {
+ var datasetLabel = data.datasets[item.datasetIndex].label || '';
+ return datasetLabel + ': ' + item.xLabel;
+ }
+ },
+ mode: 'index',
+ axis: 'y'
+ }
+});
+
+/**
+ * Computes the "optimal" sample size to maintain bars equally sized while preventing overlap.
+ * @private
+ */
+function computeMinSampleSize(scale, pixels) {
+ var min = scale.isHorizontal() ? scale.width : scale.height;
+ var ticks = scale.getTicks();
+ var prev, curr, i, ilen;
+
+ for (i = 1, ilen = pixels.length; i < ilen; ++i) {
+ min = Math.min(min, pixels[i] - pixels[i - 1]);
+ }
+
+ for (i = 0, ilen = ticks.length; i < ilen; ++i) {
+ curr = scale.getPixelForTick(i);
+ min = i > 0 ? Math.min(min, curr - prev) : min;
+ prev = curr;
+ }
+
+ return min;
+}
+
+/**
+ * Computes an "ideal" category based on the absolute bar thickness or, if undefined or null,
+ * uses the smallest interval (see computeMinSampleSize) that prevents bar overlapping. This
+ * mode currently always generates bars equally sized (until we introduce scriptable options?).
+ * @private
+ */
+function computeFitCategoryTraits(index, ruler, options) {
+ var thickness = options.barThickness;
+ var count = ruler.stackCount;
+ var curr = ruler.pixels[index];
+ var size, ratio;
+
+ if (helpers.isNullOrUndef(thickness)) {
+ size = ruler.min * options.categoryPercentage;
+ ratio = options.barPercentage;
+ } else {
+ // When bar thickness is enforced, category and bar percentages are ignored.
+ // Note(SB): we could add support for relative bar thickness (e.g. barThickness: '50%')
+ // and deprecate barPercentage since this value is ignored when thickness is absolute.
+ size = thickness * count;
+ ratio = 1;
+ }
+
+ return {
+ chunk: size / count,
+ ratio: ratio,
+ start: curr - (size / 2)
+ };
+}
+
+/**
+ * Computes an "optimal" category that globally arranges bars side by side (no gap when
+ * percentage options are 1), based on the previous and following categories. This mode
+ * generates bars with different widths when data are not evenly spaced.
+ * @private
+ */
+function computeFlexCategoryTraits(index, ruler, options) {
+ var pixels = ruler.pixels;
+ var curr = pixels[index];
+ var prev = index > 0 ? pixels[index - 1] : null;
+ var next = index < pixels.length - 1 ? pixels[index + 1] : null;
+ var percent = options.categoryPercentage;
+ var start, size;
+
+ if (prev === null) {
+ // first data: its size is double based on the next point or,
+ // if it's also the last data, we use the scale end extremity.
+ prev = curr - (next === null ? ruler.end - curr : next - curr);
+ }
+
+ if (next === null) {
+ // last data: its size is also double based on the previous point.
+ next = curr + curr - prev;
+ }
+
+ start = curr - ((curr - prev) / 2) * percent;
+ size = ((next - prev) / 2) * percent;
+
+ return {
+ chunk: size / ruler.stackCount,
+ ratio: options.barPercentage,
+ start: start
+ };
+}
+
+module.exports = function(Chart) {
+
+ Chart.controllers.bar = Chart.DatasetController.extend({
+
+ dataElementType: elements.Rectangle,
+
+ initialize: function() {
+ var me = this;
+ var meta;
+
+ Chart.DatasetController.prototype.initialize.apply(me, arguments);
+
+ meta = me.getMeta();
+ meta.stack = me.getDataset().stack;
+ meta.bar = true;
+ },
+
+ update: function(reset) {
+ var me = this;
+ var rects = me.getMeta().data;
+ var i, ilen;
+
+ me._ruler = me.getRuler();
+
+ for (i = 0, ilen = rects.length; i < ilen; ++i) {
+ me.updateElement(rects[i], i, reset);
+ }
+ },
+
+ updateElement: function(rectangle, index, reset) {
+ var me = this;
+ var chart = me.chart;
+ var meta = me.getMeta();
+ var dataset = me.getDataset();
+ var custom = rectangle.custom || {};
+ var rectangleOptions = chart.options.elements.rectangle;
+
+ rectangle._xScale = me.getScaleForId(meta.xAxisID);
+ rectangle._yScale = me.getScaleForId(meta.yAxisID);
+ rectangle._datasetIndex = me.index;
+ rectangle._index = index;
+
+ rectangle._model = {
+ datasetLabel: dataset.label,
+ label: chart.data.labels[index],
+ borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleOptions.borderSkipped,
+ backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.backgroundColor, index, rectangleOptions.backgroundColor),
+ borderColor: custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.borderColor, index, rectangleOptions.borderColor),
+ borderWidth: custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.borderWidth, index, rectangleOptions.borderWidth)
+ };
+
+ me.updateElementGeometry(rectangle, index, reset);
+
+ rectangle.pivot();
+ },
+
+ /**
+ * @private
+ */
+ updateElementGeometry: function(rectangle, index, reset) {
+ var me = this;
+ var model = rectangle._model;
+ var vscale = me.getValueScale();
+ var base = vscale.getBasePixel();
+ var horizontal = vscale.isHorizontal();
+ var ruler = me._ruler || me.getRuler();
+ var vpixels = me.calculateBarValuePixels(me.index, index);
+ var ipixels = me.calculateBarIndexPixels(me.index, index, ruler);
+
+ model.horizontal = horizontal;
+ model.base = reset ? base : vpixels.base;
+ model.x = horizontal ? reset ? base : vpixels.head : ipixels.center;
+ model.y = horizontal ? ipixels.center : reset ? base : vpixels.head;
+ model.height = horizontal ? ipixels.size : undefined;
+ model.width = horizontal ? undefined : ipixels.size;
+ },
+
+ /**
+ * @private
+ */
+ getValueScaleId: function() {
+ return this.getMeta().yAxisID;
+ },
+
+ /**
+ * @private
+ */
+ getIndexScaleId: function() {
+ return this.getMeta().xAxisID;
+ },
+
+ /**
+ * @private
+ */
+ getValueScale: function() {
+ return this.getScaleForId(this.getValueScaleId());
+ },
+
+ /**
+ * @private
+ */
+ getIndexScale: function() {
+ return this.getScaleForId(this.getIndexScaleId());
+ },
+
+ /**
+ * Returns the stacks based on groups and bar visibility.
+ * @param {Number} [last] - The dataset index
+ * @returns {Array} The stack list
+ * @private
+ */
+ _getStacks: function(last) {
+ var me = this;
+ var chart = me.chart;
+ var scale = me.getIndexScale();
+ var stacked = scale.options.stacked;
+ var ilen = last === undefined ? chart.data.datasets.length : last + 1;
+ var stacks = [];
+ var i, meta;
+
+ for (i = 0; i < ilen; ++i) {
+ meta = chart.getDatasetMeta(i);
+ if (meta.bar && chart.isDatasetVisible(i) &&
+ (stacked === false ||
+ (stacked === true && stacks.indexOf(meta.stack) === -1) ||
+ (stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) {
+ stacks.push(meta.stack);
+ }
+ }
+
+ return stacks;
+ },
+
+ /**
+ * Returns the effective number of stacks based on groups and bar visibility.
+ * @private
+ */
+ getStackCount: function() {
+ return this._getStacks().length;
+ },
+
+ /**
+ * Returns the stack index for the given dataset based on groups and bar visibility.
+ * @param {Number} [datasetIndex] - The dataset index
+ * @param {String} [name] - The stack name to find
+ * @returns {Number} The stack index
+ * @private
+ */
+ getStackIndex: function(datasetIndex, name) {
+ var stacks = this._getStacks(datasetIndex);
+ var index = (name !== undefined)
+ ? stacks.indexOf(name)
+ : -1; // indexOf returns -1 if element is not present
+
+ return (index === -1)
+ ? stacks.length - 1
+ : index;
+ },
+
+ /**
+ * @private
+ */
+ getRuler: function() {
+ var me = this;
+ var scale = me.getIndexScale();
+ var stackCount = me.getStackCount();
+ var datasetIndex = me.index;
+ var isHorizontal = scale.isHorizontal();
+ var start = isHorizontal ? scale.left : scale.top;
+ var end = start + (isHorizontal ? scale.width : scale.height);
+ var pixels = [];
+ var i, ilen, min;
+
+ for (i = 0, ilen = me.getMeta().data.length; i < ilen; ++i) {
+ pixels.push(scale.getPixelForValue(null, i, datasetIndex));
+ }
+
+ min = helpers.isNullOrUndef(scale.options.barThickness)
+ ? computeMinSampleSize(scale, pixels)
+ : -1;
+
+ return {
+ min: min,
+ pixels: pixels,
+ start: start,
+ end: end,
+ stackCount: stackCount,
+ scale: scale
+ };
+ },
+
+ /**
+ * Note: pixel values are not clamped to the scale area.
+ * @private
+ */
+ calculateBarValuePixels: function(datasetIndex, index) {
+ var me = this;
+ var chart = me.chart;
+ var meta = me.getMeta();
+ var scale = me.getValueScale();
+ var datasets = chart.data.datasets;
+ var value = scale.getRightValue(datasets[datasetIndex].data[index]);
+ var stacked = scale.options.stacked;
+ var stack = meta.stack;
+ var start = 0;
+ var i, imeta, ivalue, base, head, size;
+
+ if (stacked || (stacked === undefined && stack !== undefined)) {
+ for (i = 0; i < datasetIndex; ++i) {
+ imeta = chart.getDatasetMeta(i);
+
+ if (imeta.bar &&
+ imeta.stack === stack &&
+ imeta.controller.getValueScaleId() === scale.id &&
+ chart.isDatasetVisible(i)) {
+
+ ivalue = scale.getRightValue(datasets[i].data[index]);
+ if ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) {
+ start += ivalue;
+ }
+ }
+ }
+ }
+
+ base = scale.getPixelForValue(start);
+ head = scale.getPixelForValue(start + value);
+ size = (head - base) / 2;
+
+ return {
+ size: size,
+ base: base,
+ head: head,
+ center: head + size / 2
+ };
+ },
+
+ /**
+ * @private
+ */
+ calculateBarIndexPixels: function(datasetIndex, index, ruler) {
+ var me = this;
+ var options = ruler.scale.options;
+ var range = options.barThickness === 'flex'
+ ? computeFlexCategoryTraits(index, ruler, options)
+ : computeFitCategoryTraits(index, ruler, options);
+
+ var stackIndex = me.getStackIndex(datasetIndex, me.getMeta().stack);
+ var center = range.start + (range.chunk * stackIndex) + (range.chunk / 2);
+ var size = Math.min(
+ helpers.valueOrDefault(options.maxBarThickness, Infinity),
+ range.chunk * range.ratio);
+
+ return {
+ base: center - size / 2,
+ head: center + size / 2,
+ center: center,
+ size: size
+ };
+ },
+
+ draw: function() {
+ var me = this;
+ var chart = me.chart;
+ var scale = me.getValueScale();
+ var rects = me.getMeta().data;
+ var dataset = me.getDataset();
+ var ilen = rects.length;
+ var i = 0;
+
+ helpers.canvas.clipArea(chart.ctx, chart.chartArea);
+
+ for (; i < ilen; ++i) {
+ if (!isNaN(scale.getRightValue(dataset.data[i]))) {
+ rects[i].draw();
+ }
+ }
+
+ helpers.canvas.unclipArea(chart.ctx);
+ },
+
+ setHoverStyle: function(rectangle) {
+ var dataset = this.chart.data.datasets[rectangle._datasetIndex];
+ var index = rectangle._index;
+ var custom = rectangle.custom || {};
+ var model = rectangle._model;
+
+ model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.valueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
+ model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.valueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor));
+ model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.valueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
+ },
+
+ removeHoverStyle: function(rectangle) {
+ var dataset = this.chart.data.datasets[rectangle._datasetIndex];
+ var index = rectangle._index;
+ var custom = rectangle.custom || {};
+ var model = rectangle._model;
+ var rectangleElementOptions = this.chart.options.elements.rectangle;
+
+ model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor);
+ model.borderColor = custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor);
+ model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth);
+ }
+ });
+
+ Chart.controllers.horizontalBar = Chart.controllers.bar.extend({
+ /**
+ * @private
+ */
+ getValueScaleId: function() {
+ return this.getMeta().xAxisID;
+ },
+
+ /**
+ * @private
+ */
+ getIndexScaleId: function() {
+ return this.getMeta().yAxisID;
+ }
+ });
+};
+
+},{"25":25,"40":40,"45":45}],16:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('bubble', {
+ hover: {
+ mode: 'single'
+ },
+
+ scales: {
+ xAxes: [{
+ type: 'linear', // bubble should probably use a linear scale by default
+ position: 'bottom',
+ id: 'x-axis-0' // need an ID so datasets can reference the scale
+ }],
+ yAxes: [{
+ type: 'linear',
+ position: 'left',
+ id: 'y-axis-0'
+ }]
+ },
+
+ tooltips: {
+ callbacks: {
+ title: function() {
+ // Title doesn't make sense for scatter since we format the data as a point
+ return '';
+ },
+ label: function(item, data) {
+ var datasetLabel = data.datasets[item.datasetIndex].label || '';
+ var dataPoint = data.datasets[item.datasetIndex].data[item.index];
+ return datasetLabel + ': (' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.r + ')';
+ }
+ }
+ }
+});
+
+
+module.exports = function(Chart) {
+
+ Chart.controllers.bubble = Chart.DatasetController.extend({
+ /**
+ * @protected
+ */
+ dataElementType: elements.Point,
+
+ /**
+ * @protected
+ */
+ update: function(reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var points = meta.data;
+
+ // Update Points
+ helpers.each(points, function(point, index) {
+ me.updateElement(point, index, reset);
+ });
+ },
+
+ /**
+ * @protected
+ */
+ updateElement: function(point, index, reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var custom = point.custom || {};
+ var xScale = me.getScaleForId(meta.xAxisID);
+ var yScale = me.getScaleForId(meta.yAxisID);
+ var options = me._resolveElementOptions(point, index);
+ var data = me.getDataset().data[index];
+ var dsIndex = me.index;
+
+ var x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex);
+ var y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex);
+
+ point._xScale = xScale;
+ point._yScale = yScale;
+ point._options = options;
+ point._datasetIndex = dsIndex;
+ point._index = index;
+ point._model = {
+ backgroundColor: options.backgroundColor,
+ borderColor: options.borderColor,
+ borderWidth: options.borderWidth,
+ hitRadius: options.hitRadius,
+ pointStyle: options.pointStyle,
+ radius: reset ? 0 : options.radius,
+ skip: custom.skip || isNaN(x) || isNaN(y),
+ x: x,
+ y: y,
+ };
+
+ point.pivot();
+ },
+
+ /**
+ * @protected
+ */
+ setHoverStyle: function(point) {
+ var model = point._model;
+ var options = point._options;
+
+ model.backgroundColor = helpers.valueOrDefault(options.hoverBackgroundColor, helpers.getHoverColor(options.backgroundColor));
+ model.borderColor = helpers.valueOrDefault(options.hoverBorderColor, helpers.getHoverColor(options.borderColor));
+ model.borderWidth = helpers.valueOrDefault(options.hoverBorderWidth, options.borderWidth);
+ model.radius = options.radius + options.hoverRadius;
+ },
+
+ /**
+ * @protected
+ */
+ removeHoverStyle: function(point) {
+ var model = point._model;
+ var options = point._options;
+
+ model.backgroundColor = options.backgroundColor;
+ model.borderColor = options.borderColor;
+ model.borderWidth = options.borderWidth;
+ model.radius = options.radius;
+ },
+
+ /**
+ * @private
+ */
+ _resolveElementOptions: function(point, index) {
+ var me = this;
+ var chart = me.chart;
+ var datasets = chart.data.datasets;
+ var dataset = datasets[me.index];
+ var custom = point.custom || {};
+ var options = chart.options.elements.point;
+ var resolve = helpers.options.resolve;
+ var data = dataset.data[index];
+ var values = {};
+ var i, ilen, key;
+
+ // Scriptable options
+ var context = {
+ chart: chart,
+ dataIndex: index,
+ dataset: dataset,
+ datasetIndex: me.index
+ };
+
+ var keys = [
+ 'backgroundColor',
+ 'borderColor',
+ 'borderWidth',
+ 'hoverBackgroundColor',
+ 'hoverBorderColor',
+ 'hoverBorderWidth',
+ 'hoverRadius',
+ 'hitRadius',
+ 'pointStyle'
+ ];
+
+ for (i = 0, ilen = keys.length; i < ilen; ++i) {
+ key = keys[i];
+ values[key] = resolve([
+ custom[key],
+ dataset[key],
+ options[key]
+ ], context, index);
+ }
+
+ // Custom radius resolution
+ values.radius = resolve([
+ custom.radius,
+ data ? data.r : undefined,
+ dataset.radius,
+ options.radius
+ ], context, index);
+
+ return values;
+ }
+ });
+};
+
+},{"25":25,"40":40,"45":45}],17:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('doughnut', {
+ animation: {
+ // Boolean - Whether we animate the rotation of the Doughnut
+ animateRotate: true,
+ // Boolean - Whether we animate scaling the Doughnut from the centre
+ animateScale: false
+ },
+ hover: {
+ mode: 'single'
+ },
+ legendCallback: function(chart) {
+ var text = [];
+ text.push('');
+
+ var data = chart.data;
+ var datasets = data.datasets;
+ var labels = data.labels;
+
+ if (datasets.length) {
+ for (var i = 0; i < datasets[0].data.length; ++i) {
+ text.push(' ');
+ if (labels[i]) {
+ text.push(labels[i]);
+ }
+ text.push(' ');
+ }
+ }
+
+ text.push(' ');
+ return text.join('');
+ },
+ legend: {
+ labels: {
+ generateLabels: function(chart) {
+ var data = chart.data;
+ if (data.labels.length && data.datasets.length) {
+ return data.labels.map(function(label, i) {
+ var meta = chart.getDatasetMeta(0);
+ var ds = data.datasets[0];
+ var arc = meta.data[i];
+ var custom = arc && arc.custom || {};
+ var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
+ var arcOpts = chart.options.elements.arc;
+ var fill = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
+ var stroke = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
+ var bw = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
+
+ return {
+ text: label,
+ fillStyle: fill,
+ strokeStyle: stroke,
+ lineWidth: bw,
+ hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
+
+ // Extra data used for toggling the correct item
+ index: i
+ };
+ });
+ }
+ return [];
+ }
+ },
+
+ onClick: function(e, legendItem) {
+ var index = legendItem.index;
+ var chart = this.chart;
+ var i, ilen, meta;
+
+ for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
+ meta = chart.getDatasetMeta(i);
+ // toggle visibility of index if exists
+ if (meta.data[index]) {
+ meta.data[index].hidden = !meta.data[index].hidden;
+ }
+ }
+
+ chart.update();
+ }
+ },
+
+ // The percentage of the chart that we cut out of the middle.
+ cutoutPercentage: 50,
+
+ // The rotation of the chart, where the first data arc begins.
+ rotation: Math.PI * -0.5,
+
+ // The total circumference of the chart.
+ circumference: Math.PI * 2.0,
+
+ // Need to override these to give a nice default
+ tooltips: {
+ callbacks: {
+ title: function() {
+ return '';
+ },
+ label: function(tooltipItem, data) {
+ var dataLabel = data.labels[tooltipItem.index];
+ var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
+
+ if (helpers.isArray(dataLabel)) {
+ // show value on first line of multiline label
+ // need to clone because we are changing the value
+ dataLabel = dataLabel.slice();
+ dataLabel[0] += value;
+ } else {
+ dataLabel += value;
+ }
+
+ return dataLabel;
+ }
+ }
+ }
+});
+
+defaults._set('pie', helpers.clone(defaults.doughnut));
+defaults._set('pie', {
+ cutoutPercentage: 0
+});
+
+module.exports = function(Chart) {
+
+ Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({
+
+ dataElementType: elements.Arc,
+
+ linkScales: helpers.noop,
+
+ // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly
+ getRingIndex: function(datasetIndex) {
+ var ringIndex = 0;
+
+ for (var j = 0; j < datasetIndex; ++j) {
+ if (this.chart.isDatasetVisible(j)) {
+ ++ringIndex;
+ }
+ }
+
+ return ringIndex;
+ },
+
+ update: function(reset) {
+ var me = this;
+ var chart = me.chart;
+ var chartArea = chart.chartArea;
+ var opts = chart.options;
+ var arcOpts = opts.elements.arc;
+ var availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth;
+ var availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth;
+ var minSize = Math.min(availableWidth, availableHeight);
+ var offset = {x: 0, y: 0};
+ var meta = me.getMeta();
+ var cutoutPercentage = opts.cutoutPercentage;
+ var circumference = opts.circumference;
+
+ // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc
+ if (circumference < Math.PI * 2.0) {
+ var startAngle = opts.rotation % (Math.PI * 2.0);
+ startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);
+ var endAngle = startAngle + circumference;
+ var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)};
+ var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)};
+ var contains0 = (startAngle <= 0 && endAngle >= 0) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle);
+ var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle);
+ var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle);
+ var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle);
+ var cutout = cutoutPercentage / 100.0;
+ var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))};
+ var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))};
+ var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5};
+ minSize = Math.min(availableWidth / size.width, availableHeight / size.height);
+ offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};
+ }
+
+ chart.borderWidth = me.getMaxBorderWidth(meta.data);
+ chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);
+ chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0);
+ chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
+ chart.offsetX = offset.x * chart.outerRadius;
+ chart.offsetY = offset.y * chart.outerRadius;
+
+ meta.total = me.calculateTotal();
+
+ me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));
+ me.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0);
+
+ helpers.each(meta.data, function(arc, index) {
+ me.updateElement(arc, index, reset);
+ });
+ },
+
+ updateElement: function(arc, index, reset) {
+ var me = this;
+ var chart = me.chart;
+ var chartArea = chart.chartArea;
+ var opts = chart.options;
+ var animationOpts = opts.animation;
+ var centerX = (chartArea.left + chartArea.right) / 2;
+ var centerY = (chartArea.top + chartArea.bottom) / 2;
+ var startAngle = opts.rotation; // non reset case handled later
+ var endAngle = opts.rotation; // non reset case handled later
+ var dataset = me.getDataset();
+ var circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI));
+ var innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius;
+ var outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius;
+ var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
+
+ helpers.extend(arc, {
+ // Utility
+ _datasetIndex: me.index,
+ _index: index,
+
+ // Desired view properties
+ _model: {
+ x: centerX + chart.offsetX,
+ y: centerY + chart.offsetY,
+ startAngle: startAngle,
+ endAngle: endAngle,
+ circumference: circumference,
+ outerRadius: outerRadius,
+ innerRadius: innerRadius,
+ label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])
+ }
+ });
+
+ var model = arc._model;
+ // Resets the visual styles
+ this.removeHoverStyle(arc);
+
+ // Set correct angles if not resetting
+ if (!reset || !animationOpts.animateRotate) {
+ if (index === 0) {
+ model.startAngle = opts.rotation;
+ } else {
+ model.startAngle = me.getMeta().data[index - 1]._model.endAngle;
+ }
+
+ model.endAngle = model.startAngle + model.circumference;
+ }
+
+ arc.pivot();
+ },
+
+ removeHoverStyle: function(arc) {
+ Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);
+ },
+
+ calculateTotal: function() {
+ var dataset = this.getDataset();
+ var meta = this.getMeta();
+ var total = 0;
+ var value;
+
+ helpers.each(meta.data, function(element, index) {
+ value = dataset.data[index];
+ if (!isNaN(value) && !element.hidden) {
+ total += Math.abs(value);
+ }
+ });
+
+ /* if (total === 0) {
+ total = NaN;
+ }*/
+
+ return total;
+ },
+
+ calculateCircumference: function(value) {
+ var total = this.getMeta().total;
+ if (total > 0 && !isNaN(value)) {
+ return (Math.PI * 2.0) * (Math.abs(value) / total);
+ }
+ return 0;
+ },
+
+ // gets the max border or hover width to properly scale pie charts
+ getMaxBorderWidth: function(arcs) {
+ var max = 0;
+ var index = this.index;
+ var length = arcs.length;
+ var borderWidth;
+ var hoverWidth;
+
+ for (var i = 0; i < length; i++) {
+ borderWidth = arcs[i]._model ? arcs[i]._model.borderWidth : 0;
+ hoverWidth = arcs[i]._chart ? arcs[i]._chart.config.data.datasets[index].hoverBorderWidth : 0;
+
+ max = borderWidth > max ? borderWidth : max;
+ max = hoverWidth > max ? hoverWidth : max;
+ }
+ return max;
+ }
+ });
+};
+
+},{"25":25,"40":40,"45":45}],18:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('line', {
+ showLines: true,
+ spanGaps: false,
+
+ hover: {
+ mode: 'label'
+ },
+
+ scales: {
+ xAxes: [{
+ type: 'category',
+ id: 'x-axis-0'
+ }],
+ yAxes: [{
+ type: 'linear',
+ id: 'y-axis-0'
+ }]
+ }
+});
+
+module.exports = function(Chart) {
+
+ function lineEnabled(dataset, options) {
+ return helpers.valueOrDefault(dataset.showLine, options.showLines);
+ }
+
+ Chart.controllers.line = Chart.DatasetController.extend({
+
+ datasetElementType: elements.Line,
+
+ dataElementType: elements.Point,
+
+ update: function(reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var line = meta.dataset;
+ var points = meta.data || [];
+ var options = me.chart.options;
+ var lineElementOptions = options.elements.line;
+ var scale = me.getScaleForId(meta.yAxisID);
+ var i, ilen, custom;
+ var dataset = me.getDataset();
+ var showLine = lineEnabled(dataset, options);
+
+ // Update Line
+ if (showLine) {
+ custom = line.custom || {};
+
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
+ dataset.lineTension = dataset.tension;
+ }
+
+ // Utility
+ line._scale = scale;
+ line._datasetIndex = me.index;
+ // Data
+ line._children = points;
+ // Model
+ line._model = {
+ // Appearance
+ // The default behavior of lines is to break at null values, according
+ // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158
+ // This option gives lines the ability to span gaps
+ spanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps,
+ tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, lineElementOptions.tension),
+ backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
+ borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
+ borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
+ borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),
+ borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
+ borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
+ borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
+ fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
+ steppedLine: custom.steppedLine ? custom.steppedLine : helpers.valueOrDefault(dataset.steppedLine, lineElementOptions.stepped),
+ cubicInterpolationMode: custom.cubicInterpolationMode ? custom.cubicInterpolationMode : helpers.valueOrDefault(dataset.cubicInterpolationMode, lineElementOptions.cubicInterpolationMode),
+ };
+
+ line.pivot();
+ }
+
+ // Update Points
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ me.updateElement(points[i], i, reset);
+ }
+
+ if (showLine && line._model.tension !== 0) {
+ me.updateBezierControlPoints();
+ }
+
+ // Now pivot the point for animation
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ points[i].pivot();
+ }
+ },
+
+ getPointBackgroundColor: function(point, index) {
+ var backgroundColor = this.chart.options.elements.point.backgroundColor;
+ var dataset = this.getDataset();
+ var custom = point.custom || {};
+
+ if (custom.backgroundColor) {
+ backgroundColor = custom.backgroundColor;
+ } else if (dataset.pointBackgroundColor) {
+ backgroundColor = helpers.valueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);
+ } else if (dataset.backgroundColor) {
+ backgroundColor = dataset.backgroundColor;
+ }
+
+ return backgroundColor;
+ },
+
+ getPointBorderColor: function(point, index) {
+ var borderColor = this.chart.options.elements.point.borderColor;
+ var dataset = this.getDataset();
+ var custom = point.custom || {};
+
+ if (custom.borderColor) {
+ borderColor = custom.borderColor;
+ } else if (dataset.pointBorderColor) {
+ borderColor = helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor);
+ } else if (dataset.borderColor) {
+ borderColor = dataset.borderColor;
+ }
+
+ return borderColor;
+ },
+
+ getPointBorderWidth: function(point, index) {
+ var borderWidth = this.chart.options.elements.point.borderWidth;
+ var dataset = this.getDataset();
+ var custom = point.custom || {};
+
+ if (!isNaN(custom.borderWidth)) {
+ borderWidth = custom.borderWidth;
+ } else if (!isNaN(dataset.pointBorderWidth) || helpers.isArray(dataset.pointBorderWidth)) {
+ borderWidth = helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);
+ } else if (!isNaN(dataset.borderWidth)) {
+ borderWidth = dataset.borderWidth;
+ }
+
+ return borderWidth;
+ },
+
+ updateElement: function(point, index, reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var custom = point.custom || {};
+ var dataset = me.getDataset();
+ var datasetIndex = me.index;
+ var value = dataset.data[index];
+ var yScale = me.getScaleForId(meta.yAxisID);
+ var xScale = me.getScaleForId(meta.xAxisID);
+ var pointOptions = me.chart.options.elements.point;
+ var x, y;
+
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
+ dataset.pointRadius = dataset.radius;
+ }
+ if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
+ dataset.pointHitRadius = dataset.hitRadius;
+ }
+
+ x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex);
+ y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);
+
+ // Utility
+ point._xScale = xScale;
+ point._yScale = yScale;
+ point._datasetIndex = datasetIndex;
+ point._index = index;
+
+ // Desired view properties
+ point._model = {
+ x: x,
+ y: y,
+ skip: custom.skip || isNaN(x) || isNaN(y),
+ // Appearance
+ radius: custom.radius || helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),
+ pointStyle: custom.pointStyle || helpers.valueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),
+ backgroundColor: me.getPointBackgroundColor(point, index),
+ borderColor: me.getPointBorderColor(point, index),
+ borderWidth: me.getPointBorderWidth(point, index),
+ tension: meta.dataset._model ? meta.dataset._model.tension : 0,
+ steppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false,
+ // Tooltip
+ hitRadius: custom.hitRadius || helpers.valueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)
+ };
+ },
+
+ calculatePointY: function(value, index, datasetIndex) {
+ var me = this;
+ var chart = me.chart;
+ var meta = me.getMeta();
+ var yScale = me.getScaleForId(meta.yAxisID);
+ var sumPos = 0;
+ var sumNeg = 0;
+ var i, ds, dsMeta;
+
+ if (yScale.options.stacked) {
+ for (i = 0; i < datasetIndex; i++) {
+ ds = chart.data.datasets[i];
+ dsMeta = chart.getDatasetMeta(i);
+ if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {
+ var stackedRightValue = Number(yScale.getRightValue(ds.data[index]));
+ if (stackedRightValue < 0) {
+ sumNeg += stackedRightValue || 0;
+ } else {
+ sumPos += stackedRightValue || 0;
+ }
+ }
+ }
+
+ var rightValue = Number(yScale.getRightValue(value));
+ if (rightValue < 0) {
+ return yScale.getPixelForValue(sumNeg + rightValue);
+ }
+ return yScale.getPixelForValue(sumPos + rightValue);
+ }
+
+ return yScale.getPixelForValue(value);
+ },
+
+ updateBezierControlPoints: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var area = me.chart.chartArea;
+ var points = (meta.data || []);
+ var i, ilen, point, model, controlPoints;
+
+ // Only consider points that are drawn in case the spanGaps option is used
+ if (meta.dataset._model.spanGaps) {
+ points = points.filter(function(pt) {
+ return !pt._model.skip;
+ });
+ }
+
+ function capControlPoint(pt, min, max) {
+ return Math.max(Math.min(pt, max), min);
+ }
+
+ if (meta.dataset._model.cubicInterpolationMode === 'monotone') {
+ helpers.splineCurveMonotone(points);
+ } else {
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ point = points[i];
+ model = point._model;
+ controlPoints = helpers.splineCurve(
+ helpers.previousItem(points, i)._model,
+ model,
+ helpers.nextItem(points, i)._model,
+ meta.dataset._model.tension
+ );
+ model.controlPointPreviousX = controlPoints.previous.x;
+ model.controlPointPreviousY = controlPoints.previous.y;
+ model.controlPointNextX = controlPoints.next.x;
+ model.controlPointNextY = controlPoints.next.y;
+ }
+ }
+
+ if (me.chart.options.elements.line.capBezierPoints) {
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ model = points[i]._model;
+ model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);
+ model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);
+ model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);
+ model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);
+ }
+ }
+ },
+
+ draw: function() {
+ var me = this;
+ var chart = me.chart;
+ var meta = me.getMeta();
+ var points = meta.data || [];
+ var area = chart.chartArea;
+ var ilen = points.length;
+ var i = 0;
+
+ helpers.canvas.clipArea(chart.ctx, area);
+
+ if (lineEnabled(me.getDataset(), chart.options)) {
+ meta.dataset.draw();
+ }
+
+ helpers.canvas.unclipArea(chart.ctx);
+
+ // Draw the points
+ for (; i < ilen; ++i) {
+ points[i].draw(area);
+ }
+ },
+
+ setHoverStyle: function(point) {
+ // Point
+ var dataset = this.chart.data.datasets[point._datasetIndex];
+ var index = point._index;
+ var custom = point.custom || {};
+ var model = point._model;
+
+ model.radius = custom.hoverRadius || helpers.valueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
+ model.backgroundColor = custom.hoverBackgroundColor || helpers.valueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
+ model.borderColor = custom.hoverBorderColor || helpers.valueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
+ model.borderWidth = custom.hoverBorderWidth || helpers.valueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
+ },
+
+ removeHoverStyle: function(point) {
+ var me = this;
+ var dataset = me.chart.data.datasets[point._datasetIndex];
+ var index = point._index;
+ var custom = point.custom || {};
+ var model = point._model;
+
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
+ dataset.pointRadius = dataset.radius;
+ }
+
+ model.radius = custom.radius || helpers.valueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);
+ model.backgroundColor = me.getPointBackgroundColor(point, index);
+ model.borderColor = me.getPointBorderColor(point, index);
+ model.borderWidth = me.getPointBorderWidth(point, index);
+ }
+ });
+};
+
+},{"25":25,"40":40,"45":45}],19:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('polarArea', {
+ scale: {
+ type: 'radialLinear',
+ angleLines: {
+ display: false
+ },
+ gridLines: {
+ circular: true
+ },
+ pointLabels: {
+ display: false
+ },
+ ticks: {
+ beginAtZero: true
+ }
+ },
+
+ // Boolean - Whether to animate the rotation of the chart
+ animation: {
+ animateRotate: true,
+ animateScale: true
+ },
+
+ startAngle: -0.5 * Math.PI,
+ legendCallback: function(chart) {
+ var text = [];
+ text.push('');
+
+ var data = chart.data;
+ var datasets = data.datasets;
+ var labels = data.labels;
+
+ if (datasets.length) {
+ for (var i = 0; i < datasets[0].data.length; ++i) {
+ text.push(' ');
+ if (labels[i]) {
+ text.push(labels[i]);
+ }
+ text.push(' ');
+ }
+ }
+
+ text.push(' ');
+ return text.join('');
+ },
+ legend: {
+ labels: {
+ generateLabels: function(chart) {
+ var data = chart.data;
+ if (data.labels.length && data.datasets.length) {
+ return data.labels.map(function(label, i) {
+ var meta = chart.getDatasetMeta(0);
+ var ds = data.datasets[0];
+ var arc = meta.data[i];
+ var custom = arc.custom || {};
+ var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
+ var arcOpts = chart.options.elements.arc;
+ var fill = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
+ var stroke = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
+ var bw = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
+
+ return {
+ text: label,
+ fillStyle: fill,
+ strokeStyle: stroke,
+ lineWidth: bw,
+ hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
+
+ // Extra data used for toggling the correct item
+ index: i
+ };
+ });
+ }
+ return [];
+ }
+ },
+
+ onClick: function(e, legendItem) {
+ var index = legendItem.index;
+ var chart = this.chart;
+ var i, ilen, meta;
+
+ for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
+ meta = chart.getDatasetMeta(i);
+ meta.data[index].hidden = !meta.data[index].hidden;
+ }
+
+ chart.update();
+ }
+ },
+
+ // Need to override these to give a nice default
+ tooltips: {
+ callbacks: {
+ title: function() {
+ return '';
+ },
+ label: function(item, data) {
+ return data.labels[item.index] + ': ' + item.yLabel;
+ }
+ }
+ }
+});
+
+module.exports = function(Chart) {
+
+ Chart.controllers.polarArea = Chart.DatasetController.extend({
+
+ dataElementType: elements.Arc,
+
+ linkScales: helpers.noop,
+
+ update: function(reset) {
+ var me = this;
+ var chart = me.chart;
+ var chartArea = chart.chartArea;
+ var meta = me.getMeta();
+ var opts = chart.options;
+ var arcOpts = opts.elements.arc;
+ var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
+ chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);
+ chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);
+ chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
+
+ me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);
+ me.innerRadius = me.outerRadius - chart.radiusLength;
+
+ meta.count = me.countVisibleElements();
+
+ helpers.each(meta.data, function(arc, index) {
+ me.updateElement(arc, index, reset);
+ });
+ },
+
+ updateElement: function(arc, index, reset) {
+ var me = this;
+ var chart = me.chart;
+ var dataset = me.getDataset();
+ var opts = chart.options;
+ var animationOpts = opts.animation;
+ var scale = chart.scale;
+ var labels = chart.data.labels;
+
+ var circumference = me.calculateCircumference(dataset.data[index]);
+ var centerX = scale.xCenter;
+ var centerY = scale.yCenter;
+
+ // If there is NaN data before us, we need to calculate the starting angle correctly.
+ // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data
+ var visibleCount = 0;
+ var meta = me.getMeta();
+ for (var i = 0; i < index; ++i) {
+ if (!isNaN(dataset.data[i]) && !meta.data[i].hidden) {
+ ++visibleCount;
+ }
+ }
+
+ // var negHalfPI = -0.5 * Math.PI;
+ var datasetStartAngle = opts.startAngle;
+ var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
+ var startAngle = datasetStartAngle + (circumference * visibleCount);
+ var endAngle = startAngle + (arc.hidden ? 0 : circumference);
+
+ var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
+
+ helpers.extend(arc, {
+ // Utility
+ _datasetIndex: me.index,
+ _index: index,
+ _scale: scale,
+
+ // Desired view properties
+ _model: {
+ x: centerX,
+ y: centerY,
+ innerRadius: 0,
+ outerRadius: reset ? resetRadius : distance,
+ startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,
+ endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,
+ label: helpers.valueAtIndexOrDefault(labels, index, labels[index])
+ }
+ });
+
+ // Apply border and fill style
+ me.removeHoverStyle(arc);
+
+ arc.pivot();
+ },
+
+ removeHoverStyle: function(arc) {
+ Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);
+ },
+
+ countVisibleElements: function() {
+ var dataset = this.getDataset();
+ var meta = this.getMeta();
+ var count = 0;
+
+ helpers.each(meta.data, function(element, index) {
+ if (!isNaN(dataset.data[index]) && !element.hidden) {
+ count++;
+ }
+ });
+
+ return count;
+ },
+
+ calculateCircumference: function(value) {
+ var count = this.getMeta().count;
+ if (count > 0 && !isNaN(value)) {
+ return (2 * Math.PI) / count;
+ }
+ return 0;
+ }
+ });
+};
+
+},{"25":25,"40":40,"45":45}],20:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('radar', {
+ scale: {
+ type: 'radialLinear'
+ },
+ elements: {
+ line: {
+ tension: 0 // no bezier in radar
+ }
+ }
+});
+
+module.exports = function(Chart) {
+
+ Chart.controllers.radar = Chart.DatasetController.extend({
+
+ datasetElementType: elements.Line,
+
+ dataElementType: elements.Point,
+
+ linkScales: helpers.noop,
+
+ update: function(reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var line = meta.dataset;
+ var points = meta.data;
+ var custom = line.custom || {};
+ var dataset = me.getDataset();
+ var lineElementOptions = me.chart.options.elements.line;
+ var scale = me.chart.scale;
+
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
+ dataset.lineTension = dataset.tension;
+ }
+
+ helpers.extend(meta.dataset, {
+ // Utility
+ _datasetIndex: me.index,
+ _scale: scale,
+ // Data
+ _children: points,
+ _loop: true,
+ // Model
+ _model: {
+ // Appearance
+ tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, lineElementOptions.tension),
+ backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
+ borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
+ borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
+ fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
+ borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),
+ borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
+ borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
+ borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
+ }
+ });
+
+ meta.dataset.pivot();
+
+ // Update Points
+ helpers.each(points, function(point, index) {
+ me.updateElement(point, index, reset);
+ }, me);
+
+ // Update bezier control points
+ me.updateBezierControlPoints();
+ },
+ updateElement: function(point, index, reset) {
+ var me = this;
+ var custom = point.custom || {};
+ var dataset = me.getDataset();
+ var scale = me.chart.scale;
+ var pointElementOptions = me.chart.options.elements.point;
+ var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);
+
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
+ dataset.pointRadius = dataset.radius;
+ }
+ if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
+ dataset.pointHitRadius = dataset.hitRadius;
+ }
+
+ helpers.extend(point, {
+ // Utility
+ _datasetIndex: me.index,
+ _index: index,
+ _scale: scale,
+
+ // Desired view properties
+ _model: {
+ x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales
+ y: reset ? scale.yCenter : pointPosition.y,
+
+ // Appearance
+ tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, me.chart.options.elements.line.tension),
+ radius: custom.radius ? custom.radius : helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),
+ backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor),
+ borderColor: custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),
+ borderWidth: custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),
+ pointStyle: custom.pointStyle ? custom.pointStyle : helpers.valueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),
+
+ // Tooltip
+ hitRadius: custom.hitRadius ? custom.hitRadius : helpers.valueAtIndexOrDefault(dataset.pointHitRadius, index, pointElementOptions.hitRadius)
+ }
+ });
+
+ point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
+ },
+ updateBezierControlPoints: function() {
+ var chartArea = this.chart.chartArea;
+ var meta = this.getMeta();
+
+ helpers.each(meta.data, function(point, index) {
+ var model = point._model;
+ var controlPoints = helpers.splineCurve(
+ helpers.previousItem(meta.data, index, true)._model,
+ model,
+ helpers.nextItem(meta.data, index, true)._model,
+ model.tension
+ );
+
+ // Prevent the bezier going outside of the bounds of the graph
+ model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);
+ model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);
+
+ model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);
+ model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);
+
+ // Now pivot the point for animation
+ point.pivot();
+ });
+ },
+
+ setHoverStyle: function(point) {
+ // Point
+ var dataset = this.chart.data.datasets[point._datasetIndex];
+ var custom = point.custom || {};
+ var index = point._index;
+ var model = point._model;
+
+ model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.valueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
+ model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.valueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
+ model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.valueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
+ model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.valueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
+ },
+
+ removeHoverStyle: function(point) {
+ var dataset = this.chart.data.datasets[point._datasetIndex];
+ var custom = point.custom || {};
+ var index = point._index;
+ var model = point._model;
+ var pointElementOptions = this.chart.options.elements.point;
+
+ model.radius = custom.radius ? custom.radius : helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius);
+ model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor);
+ model.borderColor = custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor);
+ model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth);
+ }
+ });
+};
+
+},{"25":25,"40":40,"45":45}],21:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+
+defaults._set('scatter', {
+ hover: {
+ mode: 'single'
+ },
+
+ scales: {
+ xAxes: [{
+ id: 'x-axis-1', // need an ID so datasets can reference the scale
+ type: 'linear', // scatter should not use a category axis
+ position: 'bottom'
+ }],
+ yAxes: [{
+ id: 'y-axis-1',
+ type: 'linear',
+ position: 'left'
+ }]
+ },
+
+ showLines: false,
+
+ tooltips: {
+ callbacks: {
+ title: function() {
+ return ''; // doesn't make sense for scatter since data are formatted as a point
+ },
+ label: function(item) {
+ return '(' + item.xLabel + ', ' + item.yLabel + ')';
+ }
+ }
+ }
+});
+
+module.exports = function(Chart) {
+
+ // Scatter charts use line controllers
+ Chart.controllers.scatter = Chart.controllers.line;
+
+};
+
+},{"25":25}],22:[function(require,module,exports){
+/* global window: false */
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+
+defaults._set('global', {
+ animation: {
+ duration: 1000,
+ easing: 'easeOutQuart',
+ onProgress: helpers.noop,
+ onComplete: helpers.noop
+ }
+});
+
+module.exports = function(Chart) {
+
+ Chart.Animation = Element.extend({
+ chart: null, // the animation associated chart instance
+ currentStep: 0, // the current animation step
+ numSteps: 60, // default number of steps
+ easing: '', // the easing to use for this animation
+ render: null, // render function used by the animation service
+
+ onAnimationProgress: null, // user specified callback to fire on each step of the animation
+ onAnimationComplete: null, // user specified callback to fire when the animation finishes
+ });
+
+ Chart.animationService = {
+ frameDuration: 17,
+ animations: [],
+ dropFrames: 0,
+ request: null,
+
+ /**
+ * @param {Chart} chart - The chart to animate.
+ * @param {Chart.Animation} animation - The animation that we will animate.
+ * @param {Number} duration - The animation duration in ms.
+ * @param {Boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions
+ */
+ addAnimation: function(chart, animation, duration, lazy) {
+ var animations = this.animations;
+ var i, ilen;
+
+ animation.chart = chart;
+
+ if (!lazy) {
+ chart.animating = true;
+ }
+
+ for (i = 0, ilen = animations.length; i < ilen; ++i) {
+ if (animations[i].chart === chart) {
+ animations[i] = animation;
+ return;
+ }
+ }
+
+ animations.push(animation);
+
+ // If there are no animations queued, manually kickstart a digest, for lack of a better word
+ if (animations.length === 1) {
+ this.requestAnimationFrame();
+ }
+ },
+
+ cancelAnimation: function(chart) {
+ var index = helpers.findIndex(this.animations, function(animation) {
+ return animation.chart === chart;
+ });
+
+ if (index !== -1) {
+ this.animations.splice(index, 1);
+ chart.animating = false;
+ }
+ },
+
+ requestAnimationFrame: function() {
+ var me = this;
+ if (me.request === null) {
+ // Skip animation frame requests until the active one is executed.
+ // This can happen when processing mouse events, e.g. 'mousemove'
+ // and 'mouseout' events will trigger multiple renders.
+ me.request = helpers.requestAnimFrame.call(window, function() {
+ me.request = null;
+ me.startDigest();
+ });
+ }
+ },
+
+ /**
+ * @private
+ */
+ startDigest: function() {
+ var me = this;
+ var startTime = Date.now();
+ var framesToDrop = 0;
+
+ if (me.dropFrames > 1) {
+ framesToDrop = Math.floor(me.dropFrames);
+ me.dropFrames = me.dropFrames % 1;
+ }
+
+ me.advance(1 + framesToDrop);
+
+ var endTime = Date.now();
+
+ me.dropFrames += (endTime - startTime) / me.frameDuration;
+
+ // Do we have more stuff to animate?
+ if (me.animations.length > 0) {
+ me.requestAnimationFrame();
+ }
+ },
+
+ /**
+ * @private
+ */
+ advance: function(count) {
+ var animations = this.animations;
+ var animation, chart;
+ var i = 0;
+
+ while (i < animations.length) {
+ animation = animations[i];
+ chart = animation.chart;
+
+ animation.currentStep = (animation.currentStep || 0) + count;
+ animation.currentStep = Math.min(animation.currentStep, animation.numSteps);
+
+ helpers.callback(animation.render, [chart, animation], chart);
+ helpers.callback(animation.onAnimationProgress, [animation], chart);
+
+ if (animation.currentStep >= animation.numSteps) {
+ helpers.callback(animation.onAnimationComplete, [animation], chart);
+ chart.animating = false;
+ animations.splice(i, 1);
+ } else {
+ ++i;
+ }
+ }
+ }
+ };
+
+ /**
+ * Provided for backward compatibility, use Chart.Animation instead
+ * @prop Chart.Animation#animationObject
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ */
+ Object.defineProperty(Chart.Animation.prototype, 'animationObject', {
+ get: function() {
+ return this;
+ }
+ });
+
+ /**
+ * Provided for backward compatibility, use Chart.Animation#chart instead
+ * @prop Chart.Animation#chartInstance
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ */
+ Object.defineProperty(Chart.Animation.prototype, 'chartInstance', {
+ get: function() {
+ return this.chart;
+ },
+ set: function(value) {
+ this.chart = value;
+ }
+ });
+
+};
+
+},{"25":25,"26":26,"45":45}],23:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var helpers = require(45);
+var Interaction = require(28);
+var layouts = require(30);
+var platform = require(48);
+var plugins = require(31);
+
+module.exports = function(Chart) {
+
+ // Create a dictionary of chart types, to allow for extension of existing types
+ Chart.types = {};
+
+ // Store a reference to each instance - allowing us to globally resize chart instances on window resize.
+ // Destroy method on the chart will remove the instance of the chart from this reference.
+ Chart.instances = {};
+
+ // Controllers available for dataset visualization eg. bar, line, slice, etc.
+ Chart.controllers = {};
+
+ /**
+ * Initializes the given config with global and chart default values.
+ */
+ function initConfig(config) {
+ config = config || {};
+
+ // Do NOT use configMerge() for the data object because this method merges arrays
+ // and so would change references to labels and datasets, preventing data updates.
+ var data = config.data = config.data || {};
+ data.datasets = data.datasets || [];
+ data.labels = data.labels || [];
+
+ config.options = helpers.configMerge(
+ defaults.global,
+ defaults[config.type],
+ config.options || {});
+
+ return config;
+ }
+
+ /**
+ * Updates the config of the chart
+ * @param chart {Chart} chart to update the options for
+ */
+ function updateConfig(chart) {
+ var newOptions = chart.options;
+
+ helpers.each(chart.scales, function(scale) {
+ layouts.removeBox(chart, scale);
+ });
+
+ newOptions = helpers.configMerge(
+ Chart.defaults.global,
+ Chart.defaults[chart.config.type],
+ newOptions);
+
+ chart.options = chart.config.options = newOptions;
+ chart.ensureScalesHaveIDs();
+ chart.buildOrUpdateScales();
+ // Tooltip
+ chart.tooltip._options = newOptions.tooltips;
+ chart.tooltip.initialize();
+ }
+
+ function positionIsHorizontal(position) {
+ return position === 'top' || position === 'bottom';
+ }
+
+ helpers.extend(Chart.prototype, /** @lends Chart */ {
+ /**
+ * @private
+ */
+ construct: function(item, config) {
+ var me = this;
+
+ config = initConfig(config);
+
+ var context = platform.acquireContext(item, config);
+ var canvas = context && context.canvas;
+ var height = canvas && canvas.height;
+ var width = canvas && canvas.width;
+
+ me.id = helpers.uid();
+ me.ctx = context;
+ me.canvas = canvas;
+ me.config = config;
+ me.width = width;
+ me.height = height;
+ me.aspectRatio = height ? width / height : null;
+ me.options = config.options;
+ me._bufferedRender = false;
+
+ /**
+ * Provided for backward compatibility, Chart and Chart.Controller have been merged,
+ * the "instance" still need to be defined since it might be called from plugins.
+ * @prop Chart#chart
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ * @private
+ */
+ me.chart = me;
+ me.controller = me; // chart.chart.controller #inception
+
+ // Add the chart instance to the global namespace
+ Chart.instances[me.id] = me;
+
+ // Define alias to the config data: `chart.data === chart.config.data`
+ Object.defineProperty(me, 'data', {
+ get: function() {
+ return me.config.data;
+ },
+ set: function(value) {
+ me.config.data = value;
+ }
+ });
+
+ if (!context || !canvas) {
+ // The given item is not a compatible context2d element, let's return before finalizing
+ // the chart initialization but after setting basic chart / controller properties that
+ // can help to figure out that the chart is not valid (e.g chart.canvas !== null);
+ // https://github.com/chartjs/Chart.js/issues/2807
+ console.error("Failed to create chart: can't acquire context from the given item");
+ return;
+ }
+
+ me.initialize();
+ me.update();
+ },
+
+ /**
+ * @private
+ */
+ initialize: function() {
+ var me = this;
+
+ // Before init plugin notification
+ plugins.notify(me, 'beforeInit');
+
+ helpers.retinaScale(me, me.options.devicePixelRatio);
+
+ me.bindEvents();
+
+ if (me.options.responsive) {
+ // Initial resize before chart draws (must be silent to preserve initial animations).
+ me.resize(true);
+ }
+
+ // Make sure scales have IDs and are built before we build any controllers.
+ me.ensureScalesHaveIDs();
+ me.buildOrUpdateScales();
+ me.initToolTip();
+
+ // After init plugin notification
+ plugins.notify(me, 'afterInit');
+
+ return me;
+ },
+
+ clear: function() {
+ helpers.canvas.clear(this);
+ return this;
+ },
+
+ stop: function() {
+ // Stops any current animation loop occurring
+ Chart.animationService.cancelAnimation(this);
+ return this;
+ },
+
+ resize: function(silent) {
+ var me = this;
+ var options = me.options;
+ var canvas = me.canvas;
+ var aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;
+
+ // the canvas render width and height will be casted to integers so make sure that
+ // the canvas display style uses the same integer values to avoid blurring effect.
+
+ // Set to 0 instead of canvas.size because the size defaults to 300x150 if the element is collased
+ var newWidth = Math.max(0, Math.floor(helpers.getMaximumWidth(canvas)));
+ var newHeight = Math.max(0, Math.floor(aspectRatio ? newWidth / aspectRatio : helpers.getMaximumHeight(canvas)));
+
+ if (me.width === newWidth && me.height === newHeight) {
+ return;
+ }
+
+ canvas.width = me.width = newWidth;
+ canvas.height = me.height = newHeight;
+ canvas.style.width = newWidth + 'px';
+ canvas.style.height = newHeight + 'px';
+
+ helpers.retinaScale(me, options.devicePixelRatio);
+
+ if (!silent) {
+ // Notify any plugins about the resize
+ var newSize = {width: newWidth, height: newHeight};
+ plugins.notify(me, 'resize', [newSize]);
+
+ // Notify of resize
+ if (me.options.onResize) {
+ me.options.onResize(me, newSize);
+ }
+
+ me.stop();
+ me.update(me.options.responsiveAnimationDuration);
+ }
+ },
+
+ ensureScalesHaveIDs: function() {
+ var options = this.options;
+ var scalesOptions = options.scales || {};
+ var scaleOptions = options.scale;
+
+ helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {
+ xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);
+ });
+
+ helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {
+ yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);
+ });
+
+ if (scaleOptions) {
+ scaleOptions.id = scaleOptions.id || 'scale';
+ }
+ },
+
+ /**
+ * Builds a map of scale ID to scale object for future lookup.
+ */
+ buildOrUpdateScales: function() {
+ var me = this;
+ var options = me.options;
+ var scales = me.scales || {};
+ var items = [];
+ var updated = Object.keys(scales).reduce(function(obj, id) {
+ obj[id] = false;
+ return obj;
+ }, {});
+
+ if (options.scales) {
+ items = items.concat(
+ (options.scales.xAxes || []).map(function(xAxisOptions) {
+ return {options: xAxisOptions, dtype: 'category', dposition: 'bottom'};
+ }),
+ (options.scales.yAxes || []).map(function(yAxisOptions) {
+ return {options: yAxisOptions, dtype: 'linear', dposition: 'left'};
+ })
+ );
+ }
+
+ if (options.scale) {
+ items.push({
+ options: options.scale,
+ dtype: 'radialLinear',
+ isDefault: true,
+ dposition: 'chartArea'
+ });
+ }
+
+ helpers.each(items, function(item) {
+ var scaleOptions = item.options;
+ var id = scaleOptions.id;
+ var scaleType = helpers.valueOrDefault(scaleOptions.type, item.dtype);
+
+ if (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {
+ scaleOptions.position = item.dposition;
+ }
+
+ updated[id] = true;
+ var scale = null;
+ if (id in scales && scales[id].type === scaleType) {
+ scale = scales[id];
+ scale.options = scaleOptions;
+ scale.ctx = me.ctx;
+ scale.chart = me;
+ } else {
+ var scaleClass = Chart.scaleService.getScaleConstructor(scaleType);
+ if (!scaleClass) {
+ return;
+ }
+ scale = new scaleClass({
+ id: id,
+ type: scaleType,
+ options: scaleOptions,
+ ctx: me.ctx,
+ chart: me
+ });
+ scales[scale.id] = scale;
+ }
+
+ scale.mergeTicksOptions();
+
+ // TODO(SB): I think we should be able to remove this custom case (options.scale)
+ // and consider it as a regular scale part of the "scales"" map only! This would
+ // make the logic easier and remove some useless? custom code.
+ if (item.isDefault) {
+ me.scale = scale;
+ }
+ });
+ // clear up discarded scales
+ helpers.each(updated, function(hasUpdated, id) {
+ if (!hasUpdated) {
+ delete scales[id];
+ }
+ });
+
+ me.scales = scales;
+
+ Chart.scaleService.addScalesToLayout(this);
+ },
+
+ buildOrUpdateControllers: function() {
+ var me = this;
+ var types = [];
+ var newControllers = [];
+
+ helpers.each(me.data.datasets, function(dataset, datasetIndex) {
+ var meta = me.getDatasetMeta(datasetIndex);
+ var type = dataset.type || me.config.type;
+
+ if (meta.type && meta.type !== type) {
+ me.destroyDatasetMeta(datasetIndex);
+ meta = me.getDatasetMeta(datasetIndex);
+ }
+ meta.type = type;
+
+ types.push(meta.type);
+
+ if (meta.controller) {
+ meta.controller.updateIndex(datasetIndex);
+ meta.controller.linkScales();
+ } else {
+ var ControllerClass = Chart.controllers[meta.type];
+ if (ControllerClass === undefined) {
+ throw new Error('"' + meta.type + '" is not a chart type.');
+ }
+
+ meta.controller = new ControllerClass(me, datasetIndex);
+ newControllers.push(meta.controller);
+ }
+ }, me);
+
+ return newControllers;
+ },
+
+ /**
+ * Reset the elements of all datasets
+ * @private
+ */
+ resetElements: function() {
+ var me = this;
+ helpers.each(me.data.datasets, function(dataset, datasetIndex) {
+ me.getDatasetMeta(datasetIndex).controller.reset();
+ }, me);
+ },
+
+ /**
+ * Resets the chart back to it's state before the initial animation
+ */
+ reset: function() {
+ this.resetElements();
+ this.tooltip.initialize();
+ },
+
+ update: function(config) {
+ var me = this;
+
+ if (!config || typeof config !== 'object') {
+ // backwards compatibility
+ config = {
+ duration: config,
+ lazy: arguments[1]
+ };
+ }
+
+ updateConfig(me);
+
+ // plugins options references might have change, let's invalidate the cache
+ // https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167
+ plugins._invalidate(me);
+
+ if (plugins.notify(me, 'beforeUpdate') === false) {
+ return;
+ }
+
+ // In case the entire data object changed
+ me.tooltip._data = me.data;
+
+ // Make sure dataset controllers are updated and new controllers are reset
+ var newControllers = me.buildOrUpdateControllers();
+
+ // Make sure all dataset controllers have correct meta data counts
+ helpers.each(me.data.datasets, function(dataset, datasetIndex) {
+ me.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();
+ }, me);
+
+ me.updateLayout();
+
+ // Can only reset the new controllers after the scales have been updated
+ if (me.options.animation && me.options.animation.duration) {
+ helpers.each(newControllers, function(controller) {
+ controller.reset();
+ });
+ }
+
+ me.updateDatasets();
+
+ // Need to reset tooltip in case it is displayed with elements that are removed
+ // after update.
+ me.tooltip.initialize();
+
+ // Last active contains items that were previously in the tooltip.
+ // When we reset the tooltip, we need to clear it
+ me.lastActive = [];
+
+ // Do this before render so that any plugins that need final scale updates can use it
+ plugins.notify(me, 'afterUpdate');
+
+ if (me._bufferedRender) {
+ me._bufferedRequest = {
+ duration: config.duration,
+ easing: config.easing,
+ lazy: config.lazy
+ };
+ } else {
+ me.render(config);
+ }
+ },
+
+ /**
+ * Updates the chart layout unless a plugin returns `false` to the `beforeLayout`
+ * hook, in which case, plugins will not be called on `afterLayout`.
+ * @private
+ */
+ updateLayout: function() {
+ var me = this;
+
+ if (plugins.notify(me, 'beforeLayout') === false) {
+ return;
+ }
+
+ layouts.update(this, this.width, this.height);
+
+ /**
+ * Provided for backward compatibility, use `afterLayout` instead.
+ * @method IPlugin#afterScaleUpdate
+ * @deprecated since version 2.5.0
+ * @todo remove at version 3
+ * @private
+ */
+ plugins.notify(me, 'afterScaleUpdate');
+ plugins.notify(me, 'afterLayout');
+ },
+
+ /**
+ * Updates all datasets unless a plugin returns `false` to the `beforeDatasetsUpdate`
+ * hook, in which case, plugins will not be called on `afterDatasetsUpdate`.
+ * @private
+ */
+ updateDatasets: function() {
+ var me = this;
+
+ if (plugins.notify(me, 'beforeDatasetsUpdate') === false) {
+ return;
+ }
+
+ for (var i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {
+ me.updateDataset(i);
+ }
+
+ plugins.notify(me, 'afterDatasetsUpdate');
+ },
+
+ /**
+ * Updates dataset at index unless a plugin returns `false` to the `beforeDatasetUpdate`
+ * hook, in which case, plugins will not be called on `afterDatasetUpdate`.
+ * @private
+ */
+ updateDataset: function(index) {
+ var me = this;
+ var meta = me.getDatasetMeta(index);
+ var args = {
+ meta: meta,
+ index: index
+ };
+
+ if (plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) {
+ return;
+ }
+
+ meta.controller.update();
+
+ plugins.notify(me, 'afterDatasetUpdate', [args]);
+ },
+
+ render: function(config) {
+ var me = this;
+
+ if (!config || typeof config !== 'object') {
+ // backwards compatibility
+ config = {
+ duration: config,
+ lazy: arguments[1]
+ };
+ }
+
+ var duration = config.duration;
+ var lazy = config.lazy;
+
+ if (plugins.notify(me, 'beforeRender') === false) {
+ return;
+ }
+
+ var animationOptions = me.options.animation;
+ var onComplete = function(animation) {
+ plugins.notify(me, 'afterRender');
+ helpers.callback(animationOptions && animationOptions.onComplete, [animation], me);
+ };
+
+ if (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) {
+ var animation = new Chart.Animation({
+ numSteps: (duration || animationOptions.duration) / 16.66, // 60 fps
+ easing: config.easing || animationOptions.easing,
+
+ render: function(chart, animationObject) {
+ var easingFunction = helpers.easing.effects[animationObject.easing];
+ var currentStep = animationObject.currentStep;
+ var stepDecimal = currentStep / animationObject.numSteps;
+
+ chart.draw(easingFunction(stepDecimal), stepDecimal, currentStep);
+ },
+
+ onAnimationProgress: animationOptions.onProgress,
+ onAnimationComplete: onComplete
+ });
+
+ Chart.animationService.addAnimation(me, animation, duration, lazy);
+ } else {
+ me.draw();
+
+ // See https://github.com/chartjs/Chart.js/issues/3781
+ onComplete(new Chart.Animation({numSteps: 0, chart: me}));
+ }
+
+ return me;
+ },
+
+ draw: function(easingValue) {
+ var me = this;
+
+ me.clear();
+
+ if (helpers.isNullOrUndef(easingValue)) {
+ easingValue = 1;
+ }
+
+ me.transition(easingValue);
+
+ if (plugins.notify(me, 'beforeDraw', [easingValue]) === false) {
+ return;
+ }
+
+ // Draw all the scales
+ helpers.each(me.boxes, function(box) {
+ box.draw(me.chartArea);
+ }, me);
+
+ if (me.scale) {
+ me.scale.draw();
+ }
+
+ me.drawDatasets(easingValue);
+ me._drawTooltip(easingValue);
+
+ plugins.notify(me, 'afterDraw', [easingValue]);
+ },
+
+ /**
+ * @private
+ */
+ transition: function(easingValue) {
+ var me = this;
+
+ for (var i = 0, ilen = (me.data.datasets || []).length; i < ilen; ++i) {
+ if (me.isDatasetVisible(i)) {
+ me.getDatasetMeta(i).controller.transition(easingValue);
+ }
+ }
+
+ me.tooltip.transition(easingValue);
+ },
+
+ /**
+ * Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw`
+ * hook, in which case, plugins will not be called on `afterDatasetsDraw`.
+ * @private
+ */
+ drawDatasets: function(easingValue) {
+ var me = this;
+
+ if (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) {
+ return;
+ }
+
+ // Draw datasets reversed to support proper line stacking
+ for (var i = (me.data.datasets || []).length - 1; i >= 0; --i) {
+ if (me.isDatasetVisible(i)) {
+ me.drawDataset(i, easingValue);
+ }
+ }
+
+ plugins.notify(me, 'afterDatasetsDraw', [easingValue]);
+ },
+
+ /**
+ * Draws dataset at index unless a plugin returns `false` to the `beforeDatasetDraw`
+ * hook, in which case, plugins will not be called on `afterDatasetDraw`.
+ * @private
+ */
+ drawDataset: function(index, easingValue) {
+ var me = this;
+ var meta = me.getDatasetMeta(index);
+ var args = {
+ meta: meta,
+ index: index,
+ easingValue: easingValue
+ };
+
+ if (plugins.notify(me, 'beforeDatasetDraw', [args]) === false) {
+ return;
+ }
+
+ meta.controller.draw(easingValue);
+
+ plugins.notify(me, 'afterDatasetDraw', [args]);
+ },
+
+ /**
+ * Draws tooltip unless a plugin returns `false` to the `beforeTooltipDraw`
+ * hook, in which case, plugins will not be called on `afterTooltipDraw`.
+ * @private
+ */
+ _drawTooltip: function(easingValue) {
+ var me = this;
+ var tooltip = me.tooltip;
+ var args = {
+ tooltip: tooltip,
+ easingValue: easingValue
+ };
+
+ if (plugins.notify(me, 'beforeTooltipDraw', [args]) === false) {
+ return;
+ }
+
+ tooltip.draw();
+
+ plugins.notify(me, 'afterTooltipDraw', [args]);
+ },
+
+ // Get the single element that was clicked on
+ // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw
+ getElementAtEvent: function(e) {
+ return Interaction.modes.single(this, e);
+ },
+
+ getElementsAtEvent: function(e) {
+ return Interaction.modes.label(this, e, {intersect: true});
+ },
+
+ getElementsAtXAxis: function(e) {
+ return Interaction.modes['x-axis'](this, e, {intersect: true});
+ },
+
+ getElementsAtEventForMode: function(e, mode, options) {
+ var method = Interaction.modes[mode];
+ if (typeof method === 'function') {
+ return method(this, e, options);
+ }
+
+ return [];
+ },
+
+ getDatasetAtEvent: function(e) {
+ return Interaction.modes.dataset(this, e, {intersect: true});
+ },
+
+ getDatasetMeta: function(datasetIndex) {
+ var me = this;
+ var dataset = me.data.datasets[datasetIndex];
+ if (!dataset._meta) {
+ dataset._meta = {};
+ }
+
+ var meta = dataset._meta[me.id];
+ if (!meta) {
+ meta = dataset._meta[me.id] = {
+ type: null,
+ data: [],
+ dataset: null,
+ controller: null,
+ hidden: null, // See isDatasetVisible() comment
+ xAxisID: null,
+ yAxisID: null
+ };
+ }
+
+ return meta;
+ },
+
+ getVisibleDatasetCount: function() {
+ var count = 0;
+ for (var i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
+ if (this.isDatasetVisible(i)) {
+ count++;
+ }
+ }
+ return count;
+ },
+
+ isDatasetVisible: function(datasetIndex) {
+ var meta = this.getDatasetMeta(datasetIndex);
+
+ // meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,
+ // the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.
+ return typeof meta.hidden === 'boolean' ? !meta.hidden : !this.data.datasets[datasetIndex].hidden;
+ },
+
+ generateLegend: function() {
+ return this.options.legendCallback(this);
+ },
+
+ /**
+ * @private
+ */
+ destroyDatasetMeta: function(datasetIndex) {
+ var id = this.id;
+ var dataset = this.data.datasets[datasetIndex];
+ var meta = dataset._meta && dataset._meta[id];
+
+ if (meta) {
+ meta.controller.destroy();
+ delete dataset._meta[id];
+ }
+ },
+
+ destroy: function() {
+ var me = this;
+ var canvas = me.canvas;
+ var i, ilen;
+
+ me.stop();
+
+ // dataset controllers need to cleanup associated data
+ for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {
+ me.destroyDatasetMeta(i);
+ }
+
+ if (canvas) {
+ me.unbindEvents();
+ helpers.canvas.clear(me);
+ platform.releaseContext(me.ctx);
+ me.canvas = null;
+ me.ctx = null;
+ }
+
+ plugins.notify(me, 'destroy');
+
+ delete Chart.instances[me.id];
+ },
+
+ toBase64Image: function() {
+ return this.canvas.toDataURL.apply(this.canvas, arguments);
+ },
+
+ initToolTip: function() {
+ var me = this;
+ me.tooltip = new Chart.Tooltip({
+ _chart: me,
+ _chartInstance: me, // deprecated, backward compatibility
+ _data: me.data,
+ _options: me.options.tooltips
+ }, me);
+ },
+
+ /**
+ * @private
+ */
+ bindEvents: function() {
+ var me = this;
+ var listeners = me._listeners = {};
+ var listener = function() {
+ me.eventHandler.apply(me, arguments);
+ };
+
+ helpers.each(me.options.events, function(type) {
+ platform.addEventListener(me, type, listener);
+ listeners[type] = listener;
+ });
+
+ // Elements used to detect size change should not be injected for non responsive charts.
+ // See https://github.com/chartjs/Chart.js/issues/2210
+ if (me.options.responsive) {
+ listener = function() {
+ me.resize();
+ };
+
+ platform.addEventListener(me, 'resize', listener);
+ listeners.resize = listener;
+ }
+ },
+
+ /**
+ * @private
+ */
+ unbindEvents: function() {
+ var me = this;
+ var listeners = me._listeners;
+ if (!listeners) {
+ return;
+ }
+
+ delete me._listeners;
+ helpers.each(listeners, function(listener, type) {
+ platform.removeEventListener(me, type, listener);
+ });
+ },
+
+ updateHoverStyle: function(elements, mode, enabled) {
+ var method = enabled ? 'setHoverStyle' : 'removeHoverStyle';
+ var element, i, ilen;
+
+ for (i = 0, ilen = elements.length; i < ilen; ++i) {
+ element = elements[i];
+ if (element) {
+ this.getDatasetMeta(element._datasetIndex).controller[method](element);
+ }
+ }
+ },
+
+ /**
+ * @private
+ */
+ eventHandler: function(e) {
+ var me = this;
+ var tooltip = me.tooltip;
+
+ if (plugins.notify(me, 'beforeEvent', [e]) === false) {
+ return;
+ }
+
+ // Buffer any update calls so that renders do not occur
+ me._bufferedRender = true;
+ me._bufferedRequest = null;
+
+ var changed = me.handleEvent(e);
+ // for smooth tooltip animations issue #4989
+ // the tooltip should be the source of change
+ // Animation check workaround:
+ // tooltip._start will be null when tooltip isn't animating
+ if (tooltip) {
+ changed = tooltip._start
+ ? tooltip.handleEvent(e)
+ : changed | tooltip.handleEvent(e);
+ }
+
+ plugins.notify(me, 'afterEvent', [e]);
+
+ var bufferedRequest = me._bufferedRequest;
+ if (bufferedRequest) {
+ // If we have an update that was triggered, we need to do a normal render
+ me.render(bufferedRequest);
+ } else if (changed && !me.animating) {
+ // If entering, leaving, or changing elements, animate the change via pivot
+ me.stop();
+
+ // We only need to render at this point. Updating will cause scales to be
+ // recomputed generating flicker & using more memory than necessary.
+ me.render(me.options.hover.animationDuration, true);
+ }
+
+ me._bufferedRender = false;
+ me._bufferedRequest = null;
+
+ return me;
+ },
+
+ /**
+ * Handle an event
+ * @private
+ * @param {IEvent} event the event to handle
+ * @return {Boolean} true if the chart needs to re-render
+ */
+ handleEvent: function(e) {
+ var me = this;
+ var options = me.options || {};
+ var hoverOptions = options.hover;
+ var changed = false;
+
+ me.lastActive = me.lastActive || [];
+
+ // Find Active Elements for hover and tooltips
+ if (e.type === 'mouseout') {
+ me.active = [];
+ } else {
+ me.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions);
+ }
+
+ // Invoke onHover hook
+ // Need to call with native event here to not break backwards compatibility
+ helpers.callback(options.onHover || options.hover.onHover, [e.native, me.active], me);
+
+ if (e.type === 'mouseup' || e.type === 'click') {
+ if (options.onClick) {
+ // Use e.native here for backwards compatibility
+ options.onClick.call(me, e.native, me.active);
+ }
+ }
+
+ // Remove styling for last active (even if it may still be active)
+ if (me.lastActive.length) {
+ me.updateHoverStyle(me.lastActive, hoverOptions.mode, false);
+ }
+
+ // Built in hover styling
+ if (me.active.length && hoverOptions.mode) {
+ me.updateHoverStyle(me.active, hoverOptions.mode, true);
+ }
+
+ changed = !helpers.arrayEquals(me.active, me.lastActive);
+
+ // Remember Last Actives
+ me.lastActive = me.active;
+
+ return changed;
+ }
+ });
+
+ /**
+ * Provided for backward compatibility, use Chart instead.
+ * @class Chart.Controller
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ * @private
+ */
+ Chart.Controller = Chart;
+};
+
+},{"25":25,"28":28,"30":30,"31":31,"45":45,"48":48}],24:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+
+module.exports = function(Chart) {
+
+ var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
+
+ /**
+ * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',
+ * 'unshift') and notify the listener AFTER the array has been altered. Listeners are
+ * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.
+ */
+ function listenArrayEvents(array, listener) {
+ if (array._chartjs) {
+ array._chartjs.listeners.push(listener);
+ return;
+ }
+
+ Object.defineProperty(array, '_chartjs', {
+ configurable: true,
+ enumerable: false,
+ value: {
+ listeners: [listener]
+ }
+ });
+
+ arrayEvents.forEach(function(key) {
+ var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);
+ var base = array[key];
+
+ Object.defineProperty(array, key, {
+ configurable: true,
+ enumerable: false,
+ value: function() {
+ var args = Array.prototype.slice.call(arguments);
+ var res = base.apply(this, args);
+
+ helpers.each(array._chartjs.listeners, function(object) {
+ if (typeof object[method] === 'function') {
+ object[method].apply(object, args);
+ }
+ });
+
+ return res;
+ }
+ });
+ });
+ }
+
+ /**
+ * Removes the given array event listener and cleanup extra attached properties (such as
+ * the _chartjs stub and overridden methods) if array doesn't have any more listeners.
+ */
+ function unlistenArrayEvents(array, listener) {
+ var stub = array._chartjs;
+ if (!stub) {
+ return;
+ }
+
+ var listeners = stub.listeners;
+ var index = listeners.indexOf(listener);
+ if (index !== -1) {
+ listeners.splice(index, 1);
+ }
+
+ if (listeners.length > 0) {
+ return;
+ }
+
+ arrayEvents.forEach(function(key) {
+ delete array[key];
+ });
+
+ delete array._chartjs;
+ }
+
+ // Base class for all dataset controllers (line, bar, etc)
+ Chart.DatasetController = function(chart, datasetIndex) {
+ this.initialize(chart, datasetIndex);
+ };
+
+ helpers.extend(Chart.DatasetController.prototype, {
+
+ /**
+ * Element type used to generate a meta dataset (e.g. Chart.element.Line).
+ * @type {Chart.core.element}
+ */
+ datasetElementType: null,
+
+ /**
+ * Element type used to generate a meta data (e.g. Chart.element.Point).
+ * @type {Chart.core.element}
+ */
+ dataElementType: null,
+
+ initialize: function(chart, datasetIndex) {
+ var me = this;
+ me.chart = chart;
+ me.index = datasetIndex;
+ me.linkScales();
+ me.addElements();
+ },
+
+ updateIndex: function(datasetIndex) {
+ this.index = datasetIndex;
+ },
+
+ linkScales: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var dataset = me.getDataset();
+
+ if (meta.xAxisID === null || !(meta.xAxisID in me.chart.scales)) {
+ meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;
+ }
+ if (meta.yAxisID === null || !(meta.yAxisID in me.chart.scales)) {
+ meta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;
+ }
+ },
+
+ getDataset: function() {
+ return this.chart.data.datasets[this.index];
+ },
+
+ getMeta: function() {
+ return this.chart.getDatasetMeta(this.index);
+ },
+
+ getScaleForId: function(scaleID) {
+ return this.chart.scales[scaleID];
+ },
+
+ reset: function() {
+ this.update(true);
+ },
+
+ /**
+ * @private
+ */
+ destroy: function() {
+ if (this._data) {
+ unlistenArrayEvents(this._data, this);
+ }
+ },
+
+ createMetaDataset: function() {
+ var me = this;
+ var type = me.datasetElementType;
+ return type && new type({
+ _chart: me.chart,
+ _datasetIndex: me.index
+ });
+ },
+
+ createMetaData: function(index) {
+ var me = this;
+ var type = me.dataElementType;
+ return type && new type({
+ _chart: me.chart,
+ _datasetIndex: me.index,
+ _index: index
+ });
+ },
+
+ addElements: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var data = me.getDataset().data || [];
+ var metaData = meta.data;
+ var i, ilen;
+
+ for (i = 0, ilen = data.length; i < ilen; ++i) {
+ metaData[i] = metaData[i] || me.createMetaData(i);
+ }
+
+ meta.dataset = meta.dataset || me.createMetaDataset();
+ },
+
+ addElementAndReset: function(index) {
+ var element = this.createMetaData(index);
+ this.getMeta().data.splice(index, 0, element);
+ this.updateElement(element, index, true);
+ },
+
+ buildOrUpdateElements: function() {
+ var me = this;
+ var dataset = me.getDataset();
+ var data = dataset.data || (dataset.data = []);
+
+ // In order to correctly handle data addition/deletion animation (an thus simulate
+ // real-time charts), we need to monitor these data modifications and synchronize
+ // the internal meta data accordingly.
+ if (me._data !== data) {
+ if (me._data) {
+ // This case happens when the user replaced the data array instance.
+ unlistenArrayEvents(me._data, me);
+ }
+
+ listenArrayEvents(data, me);
+ me._data = data;
+ }
+
+ // Re-sync meta data in case the user replaced the data array or if we missed
+ // any updates and so make sure that we handle number of datapoints changing.
+ me.resyncElements();
+ },
+
+ update: helpers.noop,
+
+ transition: function(easingValue) {
+ var meta = this.getMeta();
+ var elements = meta.data || [];
+ var ilen = elements.length;
+ var i = 0;
+
+ for (; i < ilen; ++i) {
+ elements[i].transition(easingValue);
+ }
+
+ if (meta.dataset) {
+ meta.dataset.transition(easingValue);
+ }
+ },
+
+ draw: function() {
+ var meta = this.getMeta();
+ var elements = meta.data || [];
+ var ilen = elements.length;
+ var i = 0;
+
+ if (meta.dataset) {
+ meta.dataset.draw();
+ }
+
+ for (; i < ilen; ++i) {
+ elements[i].draw();
+ }
+ },
+
+ removeHoverStyle: function(element, elementOpts) {
+ var dataset = this.chart.data.datasets[element._datasetIndex];
+ var index = element._index;
+ var custom = element.custom || {};
+ var valueOrDefault = helpers.valueAtIndexOrDefault;
+ var model = element._model;
+
+ model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);
+ model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);
+ model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);
+ },
+
+ setHoverStyle: function(element) {
+ var dataset = this.chart.data.datasets[element._datasetIndex];
+ var index = element._index;
+ var custom = element.custom || {};
+ var valueOrDefault = helpers.valueAtIndexOrDefault;
+ var getHoverColor = helpers.getHoverColor;
+ var model = element._model;
+
+ model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));
+ model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));
+ model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
+ },
+
+ /**
+ * @private
+ */
+ resyncElements: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var data = me.getDataset().data;
+ var numMeta = meta.data.length;
+ var numData = data.length;
+
+ if (numData < numMeta) {
+ meta.data.splice(numData, numMeta - numData);
+ } else if (numData > numMeta) {
+ me.insertElements(numMeta, numData - numMeta);
+ }
+ },
+
+ /**
+ * @private
+ */
+ insertElements: function(start, count) {
+ for (var i = 0; i < count; ++i) {
+ this.addElementAndReset(start + i);
+ }
+ },
+
+ /**
+ * @private
+ */
+ onDataPush: function() {
+ this.insertElements(this.getDataset().data.length - 1, arguments.length);
+ },
+
+ /**
+ * @private
+ */
+ onDataPop: function() {
+ this.getMeta().data.pop();
+ },
+
+ /**
+ * @private
+ */
+ onDataShift: function() {
+ this.getMeta().data.shift();
+ },
+
+ /**
+ * @private
+ */
+ onDataSplice: function(start, count) {
+ this.getMeta().data.splice(start, count);
+ this.insertElements(start, arguments.length - 2);
+ },
+
+ /**
+ * @private
+ */
+ onDataUnshift: function() {
+ this.insertElements(0, arguments.length);
+ }
+ });
+
+ Chart.DatasetController.extend = helpers.inherits;
+};
+
+},{"45":45}],25:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+
+module.exports = {
+ /**
+ * @private
+ */
+ _set: function(scope, values) {
+ return helpers.merge(this[scope] || (this[scope] = {}), values);
+ }
+};
+
+},{"45":45}],26:[function(require,module,exports){
+'use strict';
+
+var color = require(2);
+var helpers = require(45);
+
+function interpolate(start, view, model, ease) {
+ var keys = Object.keys(model);
+ var i, ilen, key, actual, origin, target, type, c0, c1;
+
+ for (i = 0, ilen = keys.length; i < ilen; ++i) {
+ key = keys[i];
+
+ target = model[key];
+
+ // if a value is added to the model after pivot() has been called, the view
+ // doesn't contain it, so let's initialize the view to the target value.
+ if (!view.hasOwnProperty(key)) {
+ view[key] = target;
+ }
+
+ actual = view[key];
+
+ if (actual === target || key[0] === '_') {
+ continue;
+ }
+
+ if (!start.hasOwnProperty(key)) {
+ start[key] = actual;
+ }
+
+ origin = start[key];
+
+ type = typeof target;
+
+ if (type === typeof origin) {
+ if (type === 'string') {
+ c0 = color(origin);
+ if (c0.valid) {
+ c1 = color(target);
+ if (c1.valid) {
+ view[key] = c1.mix(c0, ease).rgbString();
+ continue;
+ }
+ }
+ } else if (type === 'number' && isFinite(origin) && isFinite(target)) {
+ view[key] = origin + (target - origin) * ease;
+ continue;
+ }
+ }
+
+ view[key] = target;
+ }
+}
+
+var Element = function(configuration) {
+ helpers.extend(this, configuration);
+ this.initialize.apply(this, arguments);
+};
+
+helpers.extend(Element.prototype, {
+
+ initialize: function() {
+ this.hidden = false;
+ },
+
+ pivot: function() {
+ var me = this;
+ if (!me._view) {
+ me._view = helpers.clone(me._model);
+ }
+ me._start = {};
+ return me;
+ },
+
+ transition: function(ease) {
+ var me = this;
+ var model = me._model;
+ var start = me._start;
+ var view = me._view;
+
+ // No animation -> No Transition
+ if (!model || ease === 1) {
+ me._view = model;
+ me._start = null;
+ return me;
+ }
+
+ if (!view) {
+ view = me._view = {};
+ }
+
+ if (!start) {
+ start = me._start = {};
+ }
+
+ interpolate(start, view, model, ease);
+
+ return me;
+ },
+
+ tooltipPosition: function() {
+ return {
+ x: this._model.x,
+ y: this._model.y
+ };
+ },
+
+ hasValue: function() {
+ return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);
+ }
+});
+
+Element.extend = helpers.inherits;
+
+module.exports = Element;
+
+},{"2":2,"45":45}],27:[function(require,module,exports){
+/* global window: false */
+/* global document: false */
+'use strict';
+
+var color = require(2);
+var defaults = require(25);
+var helpers = require(45);
+
+module.exports = function(Chart) {
+
+ // -- Basic js utility methods
+
+ helpers.configMerge = function(/* objects ... */) {
+ return helpers.merge(helpers.clone(arguments[0]), [].slice.call(arguments, 1), {
+ merger: function(key, target, source, options) {
+ var tval = target[key] || {};
+ var sval = source[key];
+
+ if (key === 'scales') {
+ // scale config merging is complex. Add our own function here for that
+ target[key] = helpers.scaleMerge(tval, sval);
+ } else if (key === 'scale') {
+ // used in polar area & radar charts since there is only one scale
+ target[key] = helpers.merge(tval, [Chart.scaleService.getScaleDefaults(sval.type), sval]);
+ } else {
+ helpers._merger(key, target, source, options);
+ }
+ }
+ });
+ };
+
+ helpers.scaleMerge = function(/* objects ... */) {
+ return helpers.merge(helpers.clone(arguments[0]), [].slice.call(arguments, 1), {
+ merger: function(key, target, source, options) {
+ if (key === 'xAxes' || key === 'yAxes') {
+ var slen = source[key].length;
+ var i, type, scale;
+
+ if (!target[key]) {
+ target[key] = [];
+ }
+
+ for (i = 0; i < slen; ++i) {
+ scale = source[key][i];
+ type = helpers.valueOrDefault(scale.type, key === 'xAxes' ? 'category' : 'linear');
+
+ if (i >= target[key].length) {
+ target[key].push({});
+ }
+
+ if (!target[key][i].type || (scale.type && scale.type !== target[key][i].type)) {
+ // new/untyped scale or type changed: let's apply the new defaults
+ // then merge source scale to correctly overwrite the defaults.
+ helpers.merge(target[key][i], [Chart.scaleService.getScaleDefaults(type), scale]);
+ } else {
+ // scales type are the same
+ helpers.merge(target[key][i], scale);
+ }
+ }
+ } else {
+ helpers._merger(key, target, source, options);
+ }
+ }
+ });
+ };
+
+ helpers.where = function(collection, filterCallback) {
+ if (helpers.isArray(collection) && Array.prototype.filter) {
+ return collection.filter(filterCallback);
+ }
+ var filtered = [];
+
+ helpers.each(collection, function(item) {
+ if (filterCallback(item)) {
+ filtered.push(item);
+ }
+ });
+
+ return filtered;
+ };
+ helpers.findIndex = Array.prototype.findIndex ?
+ function(array, callback, scope) {
+ return array.findIndex(callback, scope);
+ } :
+ function(array, callback, scope) {
+ scope = scope === undefined ? array : scope;
+ for (var i = 0, ilen = array.length; i < ilen; ++i) {
+ if (callback.call(scope, array[i], i, array)) {
+ return i;
+ }
+ }
+ return -1;
+ };
+ helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {
+ // Default to start of the array
+ if (helpers.isNullOrUndef(startIndex)) {
+ startIndex = -1;
+ }
+ for (var i = startIndex + 1; i < arrayToSearch.length; i++) {
+ var currentItem = arrayToSearch[i];
+ if (filterCallback(currentItem)) {
+ return currentItem;
+ }
+ }
+ };
+ helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {
+ // Default to end of the array
+ if (helpers.isNullOrUndef(startIndex)) {
+ startIndex = arrayToSearch.length;
+ }
+ for (var i = startIndex - 1; i >= 0; i--) {
+ var currentItem = arrayToSearch[i];
+ if (filterCallback(currentItem)) {
+ return currentItem;
+ }
+ }
+ };
+
+ // -- Math methods
+ helpers.isNumber = function(n) {
+ return !isNaN(parseFloat(n)) && isFinite(n);
+ };
+ helpers.almostEquals = function(x, y, epsilon) {
+ return Math.abs(x - y) < epsilon;
+ };
+ helpers.almostWhole = function(x, epsilon) {
+ var rounded = Math.round(x);
+ return (((rounded - epsilon) < x) && ((rounded + epsilon) > x));
+ };
+ helpers.max = function(array) {
+ return array.reduce(function(max, value) {
+ if (!isNaN(value)) {
+ return Math.max(max, value);
+ }
+ return max;
+ }, Number.NEGATIVE_INFINITY);
+ };
+ helpers.min = function(array) {
+ return array.reduce(function(min, value) {
+ if (!isNaN(value)) {
+ return Math.min(min, value);
+ }
+ return min;
+ }, Number.POSITIVE_INFINITY);
+ };
+ helpers.sign = Math.sign ?
+ function(x) {
+ return Math.sign(x);
+ } :
+ function(x) {
+ x = +x; // convert to a number
+ if (x === 0 || isNaN(x)) {
+ return x;
+ }
+ return x > 0 ? 1 : -1;
+ };
+ helpers.log10 = Math.log10 ?
+ function(x) {
+ return Math.log10(x);
+ } :
+ function(x) {
+ var exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10.
+ // Check for whole powers of 10,
+ // which due to floating point rounding error should be corrected.
+ var powerOf10 = Math.round(exponent);
+ var isPowerOf10 = x === Math.pow(10, powerOf10);
+
+ return isPowerOf10 ? powerOf10 : exponent;
+ };
+ helpers.toRadians = function(degrees) {
+ return degrees * (Math.PI / 180);
+ };
+ helpers.toDegrees = function(radians) {
+ return radians * (180 / Math.PI);
+ };
+ // Gets the angle from vertical upright to the point about a centre.
+ helpers.getAngleFromPoint = function(centrePoint, anglePoint) {
+ var distanceFromXCenter = anglePoint.x - centrePoint.x;
+ var distanceFromYCenter = anglePoint.y - centrePoint.y;
+ var radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
+
+ var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);
+
+ if (angle < (-0.5 * Math.PI)) {
+ angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]
+ }
+
+ return {
+ angle: angle,
+ distance: radialDistanceFromCenter
+ };
+ };
+ helpers.distanceBetweenPoints = function(pt1, pt2) {
+ return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
+ };
+ helpers.aliasPixel = function(pixelWidth) {
+ return (pixelWidth % 2 === 0) ? 0 : 0.5;
+ };
+ helpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {
+ // Props to Rob Spencer at scaled innovation for his post on splining between points
+ // http://scaledinnovation.com/analytics/splines/aboutSplines.html
+
+ // This function must also respect "skipped" points
+
+ var previous = firstPoint.skip ? middlePoint : firstPoint;
+ var current = middlePoint;
+ var next = afterPoint.skip ? middlePoint : afterPoint;
+
+ var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));
+ var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));
+
+ var s01 = d01 / (d01 + d12);
+ var s12 = d12 / (d01 + d12);
+
+ // If all points are the same, s01 & s02 will be inf
+ s01 = isNaN(s01) ? 0 : s01;
+ s12 = isNaN(s12) ? 0 : s12;
+
+ var fa = t * s01; // scaling factor for triangle Ta
+ var fb = t * s12;
+
+ return {
+ previous: {
+ x: current.x - fa * (next.x - previous.x),
+ y: current.y - fa * (next.y - previous.y)
+ },
+ next: {
+ x: current.x + fb * (next.x - previous.x),
+ y: current.y + fb * (next.y - previous.y)
+ }
+ };
+ };
+ helpers.EPSILON = Number.EPSILON || 1e-14;
+ helpers.splineCurveMonotone = function(points) {
+ // This function calculates Bézier control points in a similar way than |splineCurve|,
+ // but preserves monotonicity of the provided data and ensures no local extremums are added
+ // between the dataset discrete points due to the interpolation.
+ // See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation
+
+ var pointsWithTangents = (points || []).map(function(point) {
+ return {
+ model: point._model,
+ deltaK: 0,
+ mK: 0
+ };
+ });
+
+ // Calculate slopes (deltaK) and initialize tangents (mK)
+ var pointsLen = pointsWithTangents.length;
+ var i, pointBefore, pointCurrent, pointAfter;
+ for (i = 0; i < pointsLen; ++i) {
+ pointCurrent = pointsWithTangents[i];
+ if (pointCurrent.model.skip) {
+ continue;
+ }
+
+ pointBefore = i > 0 ? pointsWithTangents[i - 1] : null;
+ pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;
+ if (pointAfter && !pointAfter.model.skip) {
+ var slopeDeltaX = (pointAfter.model.x - pointCurrent.model.x);
+
+ // In the case of two points that appear at the same x pixel, slopeDeltaX is 0
+ pointCurrent.deltaK = slopeDeltaX !== 0 ? (pointAfter.model.y - pointCurrent.model.y) / slopeDeltaX : 0;
+ }
+
+ if (!pointBefore || pointBefore.model.skip) {
+ pointCurrent.mK = pointCurrent.deltaK;
+ } else if (!pointAfter || pointAfter.model.skip) {
+ pointCurrent.mK = pointBefore.deltaK;
+ } else if (this.sign(pointBefore.deltaK) !== this.sign(pointCurrent.deltaK)) {
+ pointCurrent.mK = 0;
+ } else {
+ pointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2;
+ }
+ }
+
+ // Adjust tangents to ensure monotonic properties
+ var alphaK, betaK, tauK, squaredMagnitude;
+ for (i = 0; i < pointsLen - 1; ++i) {
+ pointCurrent = pointsWithTangents[i];
+ pointAfter = pointsWithTangents[i + 1];
+ if (pointCurrent.model.skip || pointAfter.model.skip) {
+ continue;
+ }
+
+ if (helpers.almostEquals(pointCurrent.deltaK, 0, this.EPSILON)) {
+ pointCurrent.mK = pointAfter.mK = 0;
+ continue;
+ }
+
+ alphaK = pointCurrent.mK / pointCurrent.deltaK;
+ betaK = pointAfter.mK / pointCurrent.deltaK;
+ squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);
+ if (squaredMagnitude <= 9) {
+ continue;
+ }
+
+ tauK = 3 / Math.sqrt(squaredMagnitude);
+ pointCurrent.mK = alphaK * tauK * pointCurrent.deltaK;
+ pointAfter.mK = betaK * tauK * pointCurrent.deltaK;
+ }
+
+ // Compute control points
+ var deltaX;
+ for (i = 0; i < pointsLen; ++i) {
+ pointCurrent = pointsWithTangents[i];
+ if (pointCurrent.model.skip) {
+ continue;
+ }
+
+ pointBefore = i > 0 ? pointsWithTangents[i - 1] : null;
+ pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;
+ if (pointBefore && !pointBefore.model.skip) {
+ deltaX = (pointCurrent.model.x - pointBefore.model.x) / 3;
+ pointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX;
+ pointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK;
+ }
+ if (pointAfter && !pointAfter.model.skip) {
+ deltaX = (pointAfter.model.x - pointCurrent.model.x) / 3;
+ pointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX;
+ pointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK;
+ }
+ }
+ };
+ helpers.nextItem = function(collection, index, loop) {
+ if (loop) {
+ return index >= collection.length - 1 ? collection[0] : collection[index + 1];
+ }
+ return index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];
+ };
+ helpers.previousItem = function(collection, index, loop) {
+ if (loop) {
+ return index <= 0 ? collection[collection.length - 1] : collection[index - 1];
+ }
+ return index <= 0 ? collection[0] : collection[index - 1];
+ };
+ // Implementation of the nice number algorithm used in determining where axis labels will go
+ helpers.niceNum = function(range, round) {
+ var exponent = Math.floor(helpers.log10(range));
+ var fraction = range / Math.pow(10, exponent);
+ var niceFraction;
+
+ if (round) {
+ if (fraction < 1.5) {
+ niceFraction = 1;
+ } else if (fraction < 3) {
+ niceFraction = 2;
+ } else if (fraction < 7) {
+ niceFraction = 5;
+ } else {
+ niceFraction = 10;
+ }
+ } else if (fraction <= 1.0) {
+ niceFraction = 1;
+ } else if (fraction <= 2) {
+ niceFraction = 2;
+ } else if (fraction <= 5) {
+ niceFraction = 5;
+ } else {
+ niceFraction = 10;
+ }
+
+ return niceFraction * Math.pow(10, exponent);
+ };
+ // Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
+ helpers.requestAnimFrame = (function() {
+ if (typeof window === 'undefined') {
+ return function(callback) {
+ callback();
+ };
+ }
+ return window.requestAnimationFrame ||
+ window.webkitRequestAnimationFrame ||
+ window.mozRequestAnimationFrame ||
+ window.oRequestAnimationFrame ||
+ window.msRequestAnimationFrame ||
+ function(callback) {
+ return window.setTimeout(callback, 1000 / 60);
+ };
+ }());
+ // -- DOM methods
+ helpers.getRelativePosition = function(evt, chart) {
+ var mouseX, mouseY;
+ var e = evt.originalEvent || evt;
+ var canvas = evt.currentTarget || evt.srcElement;
+ var boundingRect = canvas.getBoundingClientRect();
+
+ var touches = e.touches;
+ if (touches && touches.length > 0) {
+ mouseX = touches[0].clientX;
+ mouseY = touches[0].clientY;
+
+ } else {
+ mouseX = e.clientX;
+ mouseY = e.clientY;
+ }
+
+ // Scale mouse coordinates into canvas coordinates
+ // by following the pattern laid out by 'jerryj' in the comments of
+ // http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
+ var paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left'));
+ var paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top'));
+ var paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right'));
+ var paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom'));
+ var width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;
+ var height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;
+
+ // We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However
+ // the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here
+ mouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);
+ mouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);
+
+ return {
+ x: mouseX,
+ y: mouseY
+ };
+
+ };
+
+ // Private helper function to convert max-width/max-height values that may be percentages into a number
+ function parseMaxStyle(styleValue, node, parentProperty) {
+ var valueInPixels;
+ if (typeof styleValue === 'string') {
+ valueInPixels = parseInt(styleValue, 10);
+
+ if (styleValue.indexOf('%') !== -1) {
+ // percentage * size in dimension
+ valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];
+ }
+ } else {
+ valueInPixels = styleValue;
+ }
+
+ return valueInPixels;
+ }
+
+ /**
+ * Returns if the given value contains an effective constraint.
+ * @private
+ */
+ function isConstrainedValue(value) {
+ return value !== undefined && value !== null && value !== 'none';
+ }
+
+ // Private helper to get a constraint dimension
+ // @param domNode : the node to check the constraint on
+ // @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight)
+ // @param percentageProperty : property of parent to use when calculating width as a percentage
+ // @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser
+ function getConstraintDimension(domNode, maxStyle, percentageProperty) {
+ var view = document.defaultView;
+ var parentNode = domNode.parentNode;
+ var constrainedNode = view.getComputedStyle(domNode)[maxStyle];
+ var constrainedContainer = view.getComputedStyle(parentNode)[maxStyle];
+ var hasCNode = isConstrainedValue(constrainedNode);
+ var hasCContainer = isConstrainedValue(constrainedContainer);
+ var infinity = Number.POSITIVE_INFINITY;
+
+ if (hasCNode || hasCContainer) {
+ return Math.min(
+ hasCNode ? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity,
+ hasCContainer ? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity);
+ }
+
+ return 'none';
+ }
+ // returns Number or undefined if no constraint
+ helpers.getConstraintWidth = function(domNode) {
+ return getConstraintDimension(domNode, 'max-width', 'clientWidth');
+ };
+ // returns Number or undefined if no constraint
+ helpers.getConstraintHeight = function(domNode) {
+ return getConstraintDimension(domNode, 'max-height', 'clientHeight');
+ };
+ helpers.getMaximumWidth = function(domNode) {
+ var container = domNode.parentNode;
+ if (!container) {
+ return domNode.clientWidth;
+ }
+
+ var paddingLeft = parseInt(helpers.getStyle(container, 'padding-left'), 10);
+ var paddingRight = parseInt(helpers.getStyle(container, 'padding-right'), 10);
+ var w = container.clientWidth - paddingLeft - paddingRight;
+ var cw = helpers.getConstraintWidth(domNode);
+ return isNaN(cw) ? w : Math.min(w, cw);
+ };
+ helpers.getMaximumHeight = function(domNode) {
+ var container = domNode.parentNode;
+ if (!container) {
+ return domNode.clientHeight;
+ }
+
+ var paddingTop = parseInt(helpers.getStyle(container, 'padding-top'), 10);
+ var paddingBottom = parseInt(helpers.getStyle(container, 'padding-bottom'), 10);
+ var h = container.clientHeight - paddingTop - paddingBottom;
+ var ch = helpers.getConstraintHeight(domNode);
+ return isNaN(ch) ? h : Math.min(h, ch);
+ };
+ helpers.getStyle = function(el, property) {
+ return el.currentStyle ?
+ el.currentStyle[property] :
+ document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
+ };
+ helpers.retinaScale = function(chart, forceRatio) {
+ var pixelRatio = chart.currentDevicePixelRatio = forceRatio || window.devicePixelRatio || 1;
+ if (pixelRatio === 1) {
+ return;
+ }
+
+ var canvas = chart.canvas;
+ var height = chart.height;
+ var width = chart.width;
+
+ canvas.height = height * pixelRatio;
+ canvas.width = width * pixelRatio;
+ chart.ctx.scale(pixelRatio, pixelRatio);
+
+ // If no style has been set on the canvas, the render size is used as display size,
+ // making the chart visually bigger, so let's enforce it to the "correct" values.
+ // See https://github.com/chartjs/Chart.js/issues/3575
+ if (!canvas.style.height && !canvas.style.width) {
+ canvas.style.height = height + 'px';
+ canvas.style.width = width + 'px';
+ }
+ };
+ // -- Canvas methods
+ helpers.fontString = function(pixelSize, fontStyle, fontFamily) {
+ return fontStyle + ' ' + pixelSize + 'px ' + fontFamily;
+ };
+ helpers.longestText = function(ctx, font, arrayOfThings, cache) {
+ cache = cache || {};
+ var data = cache.data = cache.data || {};
+ var gc = cache.garbageCollect = cache.garbageCollect || [];
+
+ if (cache.font !== font) {
+ data = cache.data = {};
+ gc = cache.garbageCollect = [];
+ cache.font = font;
+ }
+
+ ctx.font = font;
+ var longest = 0;
+ helpers.each(arrayOfThings, function(thing) {
+ // Undefined strings and arrays should not be measured
+ if (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) {
+ longest = helpers.measureText(ctx, data, gc, longest, thing);
+ } else if (helpers.isArray(thing)) {
+ // if it is an array lets measure each element
+ // to do maybe simplify this function a bit so we can do this more recursively?
+ helpers.each(thing, function(nestedThing) {
+ // Undefined strings and arrays should not be measured
+ if (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) {
+ longest = helpers.measureText(ctx, data, gc, longest, nestedThing);
+ }
+ });
+ }
+ });
+
+ var gcLen = gc.length / 2;
+ if (gcLen > arrayOfThings.length) {
+ for (var i = 0; i < gcLen; i++) {
+ delete data[gc[i]];
+ }
+ gc.splice(0, gcLen);
+ }
+ return longest;
+ };
+ helpers.measureText = function(ctx, data, gc, longest, string) {
+ var textWidth = data[string];
+ if (!textWidth) {
+ textWidth = data[string] = ctx.measureText(string).width;
+ gc.push(string);
+ }
+ if (textWidth > longest) {
+ longest = textWidth;
+ }
+ return longest;
+ };
+ helpers.numberOfLabelLines = function(arrayOfThings) {
+ var numberOfLines = 1;
+ helpers.each(arrayOfThings, function(thing) {
+ if (helpers.isArray(thing)) {
+ if (thing.length > numberOfLines) {
+ numberOfLines = thing.length;
+ }
+ }
+ });
+ return numberOfLines;
+ };
+
+ helpers.color = !color ?
+ function(value) {
+ console.error('Color.js not found!');
+ return value;
+ } :
+ function(value) {
+ /* global CanvasGradient */
+ if (value instanceof CanvasGradient) {
+ value = defaults.global.defaultColor;
+ }
+
+ return color(value);
+ };
+
+ helpers.getHoverColor = function(colorValue) {
+ /* global CanvasPattern */
+ return (colorValue instanceof CanvasPattern) ?
+ colorValue :
+ helpers.color(colorValue).saturate(0.5).darken(0.1).rgbString();
+ };
+};
+
+},{"2":2,"25":25,"45":45}],28:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+
+/**
+ * Helper function to get relative position for an event
+ * @param {Event|IEvent} event - The event to get the position for
+ * @param {Chart} chart - The chart
+ * @returns {Point} the event position
+ */
+function getRelativePosition(e, chart) {
+ if (e.native) {
+ return {
+ x: e.x,
+ y: e.y
+ };
+ }
+
+ return helpers.getRelativePosition(e, chart);
+}
+
+/**
+ * Helper function to traverse all of the visible elements in the chart
+ * @param chart {chart} the chart
+ * @param handler {Function} the callback to execute for each visible item
+ */
+function parseVisibleItems(chart, handler) {
+ var datasets = chart.data.datasets;
+ var meta, i, j, ilen, jlen;
+
+ for (i = 0, ilen = datasets.length; i < ilen; ++i) {
+ if (!chart.isDatasetVisible(i)) {
+ continue;
+ }
+
+ meta = chart.getDatasetMeta(i);
+ for (j = 0, jlen = meta.data.length; j < jlen; ++j) {
+ var element = meta.data[j];
+ if (!element._view.skip) {
+ handler(element);
+ }
+ }
+ }
+}
+
+/**
+ * Helper function to get the items that intersect the event position
+ * @param items {ChartElement[]} elements to filter
+ * @param position {Point} the point to be nearest to
+ * @return {ChartElement[]} the nearest items
+ */
+function getIntersectItems(chart, position) {
+ var elements = [];
+
+ parseVisibleItems(chart, function(element) {
+ if (element.inRange(position.x, position.y)) {
+ elements.push(element);
+ }
+ });
+
+ return elements;
+}
+
+/**
+ * Helper function to get the items nearest to the event position considering all visible items in teh chart
+ * @param chart {Chart} the chart to look at elements from
+ * @param position {Point} the point to be nearest to
+ * @param intersect {Boolean} if true, only consider items that intersect the position
+ * @param distanceMetric {Function} function to provide the distance between points
+ * @return {ChartElement[]} the nearest items
+ */
+function getNearestItems(chart, position, intersect, distanceMetric) {
+ var minDistance = Number.POSITIVE_INFINITY;
+ var nearestItems = [];
+
+ parseVisibleItems(chart, function(element) {
+ if (intersect && !element.inRange(position.x, position.y)) {
+ return;
+ }
+
+ var center = element.getCenterPoint();
+ var distance = distanceMetric(position, center);
+
+ if (distance < minDistance) {
+ nearestItems = [element];
+ minDistance = distance;
+ } else if (distance === minDistance) {
+ // Can have multiple items at the same distance in which case we sort by size
+ nearestItems.push(element);
+ }
+ });
+
+ return nearestItems;
+}
+
+/**
+ * Get a distance metric function for two points based on the
+ * axis mode setting
+ * @param {String} axis the axis mode. x|y|xy
+ */
+function getDistanceMetricForAxis(axis) {
+ var useX = axis.indexOf('x') !== -1;
+ var useY = axis.indexOf('y') !== -1;
+
+ return function(pt1, pt2) {
+ var deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0;
+ var deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0;
+ return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
+ };
+}
+
+function indexMode(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ // Default axis for index mode is 'x' to match old behaviour
+ options.axis = options.axis || 'x';
+ var distanceMetric = getDistanceMetricForAxis(options.axis);
+ var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);
+ var elements = [];
+
+ if (!items.length) {
+ return [];
+ }
+
+ chart.data.datasets.forEach(function(dataset, datasetIndex) {
+ if (chart.isDatasetVisible(datasetIndex)) {
+ var meta = chart.getDatasetMeta(datasetIndex);
+ var element = meta.data[items[0]._index];
+
+ // don't count items that are skipped (null data)
+ if (element && !element._view.skip) {
+ elements.push(element);
+ }
+ }
+ });
+
+ return elements;
+}
+
+/**
+ * @interface IInteractionOptions
+ */
+/**
+ * If true, only consider items that intersect the point
+ * @name IInterfaceOptions#boolean
+ * @type Boolean
+ */
+
+/**
+ * Contains interaction related functions
+ * @namespace Chart.Interaction
+ */
+module.exports = {
+ // Helper function for different modes
+ modes: {
+ single: function(chart, e) {
+ var position = getRelativePosition(e, chart);
+ var elements = [];
+
+ parseVisibleItems(chart, function(element) {
+ if (element.inRange(position.x, position.y)) {
+ elements.push(element);
+ return elements;
+ }
+ });
+
+ return elements.slice(0, 1);
+ },
+
+ /**
+ * @function Chart.Interaction.modes.label
+ * @deprecated since version 2.4.0
+ * @todo remove at version 3
+ * @private
+ */
+ label: indexMode,
+
+ /**
+ * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something
+ * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item
+ * @function Chart.Interaction.modes.index
+ * @since v2.4.0
+ * @param chart {chart} the chart we are returning items from
+ * @param e {Event} the event we are find things at
+ * @param options {IInteractionOptions} options to use during interaction
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ index: indexMode,
+
+ /**
+ * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something
+ * If the options.intersect is false, we find the nearest item and return the items in that dataset
+ * @function Chart.Interaction.modes.dataset
+ * @param chart {chart} the chart we are returning items from
+ * @param e {Event} the event we are find things at
+ * @param options {IInteractionOptions} options to use during interaction
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ dataset: function(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ options.axis = options.axis || 'xy';
+ var distanceMetric = getDistanceMetricForAxis(options.axis);
+ var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);
+
+ if (items.length > 0) {
+ items = chart.getDatasetMeta(items[0]._datasetIndex).data;
+ }
+
+ return items;
+ },
+
+ /**
+ * @function Chart.Interaction.modes.x-axis
+ * @deprecated since version 2.4.0. Use index mode and intersect == true
+ * @todo remove at version 3
+ * @private
+ */
+ 'x-axis': function(chart, e) {
+ return indexMode(chart, e, {intersect: false});
+ },
+
+ /**
+ * Point mode returns all elements that hit test based on the event position
+ * of the event
+ * @function Chart.Interaction.modes.intersect
+ * @param chart {chart} the chart we are returning items from
+ * @param e {Event} the event we are find things at
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ point: function(chart, e) {
+ var position = getRelativePosition(e, chart);
+ return getIntersectItems(chart, position);
+ },
+
+ /**
+ * nearest mode returns the element closest to the point
+ * @function Chart.Interaction.modes.intersect
+ * @param chart {chart} the chart we are returning items from
+ * @param e {Event} the event we are find things at
+ * @param options {IInteractionOptions} options to use
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ nearest: function(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ options.axis = options.axis || 'xy';
+ var distanceMetric = getDistanceMetricForAxis(options.axis);
+ var nearestItems = getNearestItems(chart, position, options.intersect, distanceMetric);
+
+ // We have multiple items at the same distance from the event. Now sort by smallest
+ if (nearestItems.length > 1) {
+ nearestItems.sort(function(a, b) {
+ var sizeA = a.getArea();
+ var sizeB = b.getArea();
+ var ret = sizeA - sizeB;
+
+ if (ret === 0) {
+ // if equal sort by dataset index
+ ret = a._datasetIndex - b._datasetIndex;
+ }
+
+ return ret;
+ });
+ }
+
+ // Return only 1 item
+ return nearestItems.slice(0, 1);
+ },
+
+ /**
+ * x mode returns the elements that hit-test at the current x coordinate
+ * @function Chart.Interaction.modes.x
+ * @param chart {chart} the chart we are returning items from
+ * @param e {Event} the event we are find things at
+ * @param options {IInteractionOptions} options to use
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ x: function(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ var items = [];
+ var intersectsItem = false;
+
+ parseVisibleItems(chart, function(element) {
+ if (element.inXRange(position.x)) {
+ items.push(element);
+ }
+
+ if (element.inRange(position.x, position.y)) {
+ intersectsItem = true;
+ }
+ });
+
+ // If we want to trigger on an intersect and we don't have any items
+ // that intersect the position, return nothing
+ if (options.intersect && !intersectsItem) {
+ items = [];
+ }
+ return items;
+ },
+
+ /**
+ * y mode returns the elements that hit-test at the current y coordinate
+ * @function Chart.Interaction.modes.y
+ * @param chart {chart} the chart we are returning items from
+ * @param e {Event} the event we are find things at
+ * @param options {IInteractionOptions} options to use
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ y: function(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ var items = [];
+ var intersectsItem = false;
+
+ parseVisibleItems(chart, function(element) {
+ if (element.inYRange(position.y)) {
+ items.push(element);
+ }
+
+ if (element.inRange(position.x, position.y)) {
+ intersectsItem = true;
+ }
+ });
+
+ // If we want to trigger on an intersect and we don't have any items
+ // that intersect the position, return nothing
+ if (options.intersect && !intersectsItem) {
+ items = [];
+ }
+ return items;
+ }
+ }
+};
+
+},{"45":45}],29:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+
+defaults._set('global', {
+ responsive: true,
+ responsiveAnimationDuration: 0,
+ maintainAspectRatio: true,
+ events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
+ hover: {
+ onHover: null,
+ mode: 'nearest',
+ intersect: true,
+ animationDuration: 400
+ },
+ onClick: null,
+ defaultColor: 'rgba(0,0,0,0.1)',
+ defaultFontColor: '#666',
+ defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
+ defaultFontSize: 12,
+ defaultFontStyle: 'normal',
+ showLines: true,
+
+ // Element defaults defined in element extensions
+ elements: {},
+
+ // Layout options such as padding
+ layout: {
+ padding: {
+ top: 0,
+ right: 0,
+ bottom: 0,
+ left: 0
+ }
+ }
+});
+
+module.exports = function() {
+
+ // Occupy the global variable of Chart, and create a simple base class
+ var Chart = function(item, config) {
+ this.construct(item, config);
+ return this;
+ };
+
+ Chart.Chart = Chart;
+
+ return Chart;
+};
+
+},{"25":25}],30:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+
+function filterByPosition(array, position) {
+ return helpers.where(array, function(v) {
+ return v.position === position;
+ });
+}
+
+function sortByWeight(array, reverse) {
+ array.forEach(function(v, i) {
+ v._tmpIndex_ = i;
+ return v;
+ });
+ array.sort(function(a, b) {
+ var v0 = reverse ? b : a;
+ var v1 = reverse ? a : b;
+ return v0.weight === v1.weight ?
+ v0._tmpIndex_ - v1._tmpIndex_ :
+ v0.weight - v1.weight;
+ });
+ array.forEach(function(v) {
+ delete v._tmpIndex_;
+ });
+}
+
+/**
+ * @interface ILayoutItem
+ * @prop {String} position - The position of the item in the chart layout. Possible values are
+ * 'left', 'top', 'right', 'bottom', and 'chartArea'
+ * @prop {Number} weight - The weight used to sort the item. Higher weights are further away from the chart area
+ * @prop {Boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down
+ * @prop {Function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom)
+ * @prop {Function} update - Takes two parameters: width and height. Returns size of item
+ * @prop {Function} getPadding - Returns an object with padding on the edges
+ * @prop {Number} width - Width of item. Must be valid after update()
+ * @prop {Number} height - Height of item. Must be valid after update()
+ * @prop {Number} left - Left edge of the item. Set by layout system and cannot be used in update
+ * @prop {Number} top - Top edge of the item. Set by layout system and cannot be used in update
+ * @prop {Number} right - Right edge of the item. Set by layout system and cannot be used in update
+ * @prop {Number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update
+ */
+
+// The layout service is very self explanatory. It's responsible for the layout within a chart.
+// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need
+// It is this service's responsibility of carrying out that layout.
+module.exports = {
+ defaults: {},
+
+ /**
+ * Register a box to a chart.
+ * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.
+ * @param {Chart} chart - the chart to use
+ * @param {ILayoutItem} item - the item to add to be layed out
+ */
+ addBox: function(chart, item) {
+ if (!chart.boxes) {
+ chart.boxes = [];
+ }
+
+ // initialize item with default values
+ item.fullWidth = item.fullWidth || false;
+ item.position = item.position || 'top';
+ item.weight = item.weight || 0;
+
+ chart.boxes.push(item);
+ },
+
+ /**
+ * Remove a layoutItem from a chart
+ * @param {Chart} chart - the chart to remove the box from
+ * @param {Object} layoutItem - the item to remove from the layout
+ */
+ removeBox: function(chart, layoutItem) {
+ var index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1;
+ if (index !== -1) {
+ chart.boxes.splice(index, 1);
+ }
+ },
+
+ /**
+ * Sets (or updates) options on the given `item`.
+ * @param {Chart} chart - the chart in which the item lives (or will be added to)
+ * @param {Object} item - the item to configure with the given options
+ * @param {Object} options - the new item options.
+ */
+ configure: function(chart, item, options) {
+ var props = ['fullWidth', 'position', 'weight'];
+ var ilen = props.length;
+ var i = 0;
+ var prop;
+
+ for (; i < ilen; ++i) {
+ prop = props[i];
+ if (options.hasOwnProperty(prop)) {
+ item[prop] = options[prop];
+ }
+ }
+ },
+
+ /**
+ * Fits boxes of the given chart into the given size by having each box measure itself
+ * then running a fitting algorithm
+ * @param {Chart} chart - the chart
+ * @param {Number} width - the width to fit into
+ * @param {Number} height - the height to fit into
+ */
+ update: function(chart, width, height) {
+ if (!chart) {
+ return;
+ }
+
+ var layoutOptions = chart.options.layout || {};
+ var padding = helpers.options.toPadding(layoutOptions.padding);
+ var leftPadding = padding.left;
+ var rightPadding = padding.right;
+ var topPadding = padding.top;
+ var bottomPadding = padding.bottom;
+
+ var leftBoxes = filterByPosition(chart.boxes, 'left');
+ var rightBoxes = filterByPosition(chart.boxes, 'right');
+ var topBoxes = filterByPosition(chart.boxes, 'top');
+ var bottomBoxes = filterByPosition(chart.boxes, 'bottom');
+ var chartAreaBoxes = filterByPosition(chart.boxes, 'chartArea');
+
+ // Sort boxes by weight. A higher weight is further away from the chart area
+ sortByWeight(leftBoxes, true);
+ sortByWeight(rightBoxes, false);
+ sortByWeight(topBoxes, true);
+ sortByWeight(bottomBoxes, false);
+
+ // Essentially we now have any number of boxes on each of the 4 sides.
+ // Our canvas looks like the following.
+ // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and
+ // B1 is the bottom axis
+ // There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays
+ // These locations are single-box locations only, when trying to register a chartArea location that is already taken,
+ // an error will be thrown.
+ //
+ // |----------------------------------------------------|
+ // | T1 (Full Width) |
+ // |----------------------------------------------------|
+ // | | | T2 | |
+ // | |----|-------------------------------------|----|
+ // | | | C1 | | C2 | |
+ // | | |----| |----| |
+ // | | | | |
+ // | L1 | L2 | ChartArea (C0) | R1 |
+ // | | | | |
+ // | | |----| |----| |
+ // | | | C3 | | C4 | |
+ // | |----|-------------------------------------|----|
+ // | | | B1 | |
+ // |----------------------------------------------------|
+ // | B2 (Full Width) |
+ // |----------------------------------------------------|
+ //
+ // What we do to find the best sizing, we do the following
+ // 1. Determine the minimum size of the chart area.
+ // 2. Split the remaining width equally between each vertical axis
+ // 3. Split the remaining height equally between each horizontal axis
+ // 4. Give each layout the maximum size it can be. The layout will return it's minimum size
+ // 5. Adjust the sizes of each axis based on it's minimum reported size.
+ // 6. Refit each axis
+ // 7. Position each axis in the final location
+ // 8. Tell the chart the final location of the chart area
+ // 9. Tell any axes that overlay the chart area the positions of the chart area
+
+ // Step 1
+ var chartWidth = width - leftPadding - rightPadding;
+ var chartHeight = height - topPadding - bottomPadding;
+ var chartAreaWidth = chartWidth / 2; // min 50%
+ var chartAreaHeight = chartHeight / 2; // min 50%
+
+ // Step 2
+ var verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);
+
+ // Step 3
+ var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);
+
+ // Step 4
+ var maxChartAreaWidth = chartWidth;
+ var maxChartAreaHeight = chartHeight;
+ var minBoxSizes = [];
+
+ function getMinimumBoxSize(box) {
+ var minSize;
+ var isHorizontal = box.isHorizontal();
+
+ if (isHorizontal) {
+ minSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);
+ maxChartAreaHeight -= minSize.height;
+ } else {
+ minSize = box.update(verticalBoxWidth, maxChartAreaHeight);
+ maxChartAreaWidth -= minSize.width;
+ }
+
+ minBoxSizes.push({
+ horizontal: isHorizontal,
+ minSize: minSize,
+ box: box,
+ });
+ }
+
+ helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);
+
+ // If a horizontal box has padding, we move the left boxes over to avoid ugly charts (see issue #2478)
+ var maxHorizontalLeftPadding = 0;
+ var maxHorizontalRightPadding = 0;
+ var maxVerticalTopPadding = 0;
+ var maxVerticalBottomPadding = 0;
+
+ helpers.each(topBoxes.concat(bottomBoxes), function(horizontalBox) {
+ if (horizontalBox.getPadding) {
+ var boxPadding = horizontalBox.getPadding();
+ maxHorizontalLeftPadding = Math.max(maxHorizontalLeftPadding, boxPadding.left);
+ maxHorizontalRightPadding = Math.max(maxHorizontalRightPadding, boxPadding.right);
+ }
+ });
+
+ helpers.each(leftBoxes.concat(rightBoxes), function(verticalBox) {
+ if (verticalBox.getPadding) {
+ var boxPadding = verticalBox.getPadding();
+ maxVerticalTopPadding = Math.max(maxVerticalTopPadding, boxPadding.top);
+ maxVerticalBottomPadding = Math.max(maxVerticalBottomPadding, boxPadding.bottom);
+ }
+ });
+
+ // At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could
+ // be if the axes are drawn at their minimum sizes.
+ // Steps 5 & 6
+ var totalLeftBoxesWidth = leftPadding;
+ var totalRightBoxesWidth = rightPadding;
+ var totalTopBoxesHeight = topPadding;
+ var totalBottomBoxesHeight = bottomPadding;
+
+ // Function to fit a box
+ function fitBox(box) {
+ var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) {
+ return minBox.box === box;
+ });
+
+ if (minBoxSize) {
+ if (box.isHorizontal()) {
+ var scaleMargin = {
+ left: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding),
+ right: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding),
+ top: 0,
+ bottom: 0
+ };
+
+ // Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends
+ // on the margin. Sometimes they need to increase in size slightly
+ box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);
+ } else {
+ box.update(minBoxSize.minSize.width, maxChartAreaHeight);
+ }
+ }
+ }
+
+ // Update, and calculate the left and right margins for the horizontal boxes
+ helpers.each(leftBoxes.concat(rightBoxes), fitBox);
+
+ helpers.each(leftBoxes, function(box) {
+ totalLeftBoxesWidth += box.width;
+ });
+
+ helpers.each(rightBoxes, function(box) {
+ totalRightBoxesWidth += box.width;
+ });
+
+ // Set the Left and Right margins for the horizontal boxes
+ helpers.each(topBoxes.concat(bottomBoxes), fitBox);
+
+ // Figure out how much margin is on the top and bottom of the vertical boxes
+ helpers.each(topBoxes, function(box) {
+ totalTopBoxesHeight += box.height;
+ });
+
+ helpers.each(bottomBoxes, function(box) {
+ totalBottomBoxesHeight += box.height;
+ });
+
+ function finalFitVerticalBox(box) {
+ var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) {
+ return minSize.box === box;
+ });
+
+ var scaleMargin = {
+ left: 0,
+ right: 0,
+ top: totalTopBoxesHeight,
+ bottom: totalBottomBoxesHeight
+ };
+
+ if (minBoxSize) {
+ box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);
+ }
+ }
+
+ // Let the left layout know the final margin
+ helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);
+
+ // Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)
+ totalLeftBoxesWidth = leftPadding;
+ totalRightBoxesWidth = rightPadding;
+ totalTopBoxesHeight = topPadding;
+ totalBottomBoxesHeight = bottomPadding;
+
+ helpers.each(leftBoxes, function(box) {
+ totalLeftBoxesWidth += box.width;
+ });
+
+ helpers.each(rightBoxes, function(box) {
+ totalRightBoxesWidth += box.width;
+ });
+
+ helpers.each(topBoxes, function(box) {
+ totalTopBoxesHeight += box.height;
+ });
+ helpers.each(bottomBoxes, function(box) {
+ totalBottomBoxesHeight += box.height;
+ });
+
+ // We may be adding some padding to account for rotated x axis labels
+ var leftPaddingAddition = Math.max(maxHorizontalLeftPadding - totalLeftBoxesWidth, 0);
+ totalLeftBoxesWidth += leftPaddingAddition;
+ totalRightBoxesWidth += Math.max(maxHorizontalRightPadding - totalRightBoxesWidth, 0);
+
+ var topPaddingAddition = Math.max(maxVerticalTopPadding - totalTopBoxesHeight, 0);
+ totalTopBoxesHeight += topPaddingAddition;
+ totalBottomBoxesHeight += Math.max(maxVerticalBottomPadding - totalBottomBoxesHeight, 0);
+
+ // Figure out if our chart area changed. This would occur if the dataset layout label rotation
+ // changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do
+ // without calling `fit` again
+ var newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;
+ var newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;
+
+ if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {
+ helpers.each(leftBoxes, function(box) {
+ box.height = newMaxChartAreaHeight;
+ });
+
+ helpers.each(rightBoxes, function(box) {
+ box.height = newMaxChartAreaHeight;
+ });
+
+ helpers.each(topBoxes, function(box) {
+ if (!box.fullWidth) {
+ box.width = newMaxChartAreaWidth;
+ }
+ });
+
+ helpers.each(bottomBoxes, function(box) {
+ if (!box.fullWidth) {
+ box.width = newMaxChartAreaWidth;
+ }
+ });
+
+ maxChartAreaHeight = newMaxChartAreaHeight;
+ maxChartAreaWidth = newMaxChartAreaWidth;
+ }
+
+ // Step 7 - Position the boxes
+ var left = leftPadding + leftPaddingAddition;
+ var top = topPadding + topPaddingAddition;
+
+ function placeBox(box) {
+ if (box.isHorizontal()) {
+ box.left = box.fullWidth ? leftPadding : totalLeftBoxesWidth;
+ box.right = box.fullWidth ? width - rightPadding : totalLeftBoxesWidth + maxChartAreaWidth;
+ box.top = top;
+ box.bottom = top + box.height;
+
+ // Move to next point
+ top = box.bottom;
+
+ } else {
+
+ box.left = left;
+ box.right = left + box.width;
+ box.top = totalTopBoxesHeight;
+ box.bottom = totalTopBoxesHeight + maxChartAreaHeight;
+
+ // Move to next point
+ left = box.right;
+ }
+ }
+
+ helpers.each(leftBoxes.concat(topBoxes), placeBox);
+
+ // Account for chart width and height
+ left += maxChartAreaWidth;
+ top += maxChartAreaHeight;
+
+ helpers.each(rightBoxes, placeBox);
+ helpers.each(bottomBoxes, placeBox);
+
+ // Step 8
+ chart.chartArea = {
+ left: totalLeftBoxesWidth,
+ top: totalTopBoxesHeight,
+ right: totalLeftBoxesWidth + maxChartAreaWidth,
+ bottom: totalTopBoxesHeight + maxChartAreaHeight
+ };
+
+ // Step 9
+ helpers.each(chartAreaBoxes, function(box) {
+ box.left = chart.chartArea.left;
+ box.top = chart.chartArea.top;
+ box.right = chart.chartArea.right;
+ box.bottom = chart.chartArea.bottom;
+
+ box.update(maxChartAreaWidth, maxChartAreaHeight);
+ });
+ }
+};
+
+},{"45":45}],31:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var helpers = require(45);
+
+defaults._set('global', {
+ plugins: {}
+});
+
+/**
+ * The plugin service singleton
+ * @namespace Chart.plugins
+ * @since 2.1.0
+ */
+module.exports = {
+ /**
+ * Globally registered plugins.
+ * @private
+ */
+ _plugins: [],
+
+ /**
+ * This identifier is used to invalidate the descriptors cache attached to each chart
+ * when a global plugin is registered or unregistered. In this case, the cache ID is
+ * incremented and descriptors are regenerated during following API calls.
+ * @private
+ */
+ _cacheId: 0,
+
+ /**
+ * Registers the given plugin(s) if not already registered.
+ * @param {Array|Object} plugins plugin instance(s).
+ */
+ register: function(plugins) {
+ var p = this._plugins;
+ ([]).concat(plugins).forEach(function(plugin) {
+ if (p.indexOf(plugin) === -1) {
+ p.push(plugin);
+ }
+ });
+
+ this._cacheId++;
+ },
+
+ /**
+ * Unregisters the given plugin(s) only if registered.
+ * @param {Array|Object} plugins plugin instance(s).
+ */
+ unregister: function(plugins) {
+ var p = this._plugins;
+ ([]).concat(plugins).forEach(function(plugin) {
+ var idx = p.indexOf(plugin);
+ if (idx !== -1) {
+ p.splice(idx, 1);
+ }
+ });
+
+ this._cacheId++;
+ },
+
+ /**
+ * Remove all registered plugins.
+ * @since 2.1.5
+ */
+ clear: function() {
+ this._plugins = [];
+ this._cacheId++;
+ },
+
+ /**
+ * Returns the number of registered plugins?
+ * @returns {Number}
+ * @since 2.1.5
+ */
+ count: function() {
+ return this._plugins.length;
+ },
+
+ /**
+ * Returns all registered plugin instances.
+ * @returns {Array} array of plugin objects.
+ * @since 2.1.5
+ */
+ getAll: function() {
+ return this._plugins;
+ },
+
+ /**
+ * Calls enabled plugins for `chart` on the specified hook and with the given args.
+ * This method immediately returns as soon as a plugin explicitly returns false. The
+ * returned value can be used, for instance, to interrupt the current action.
+ * @param {Object} chart - The chart instance for which plugins should be called.
+ * @param {String} hook - The name of the plugin method to call (e.g. 'beforeUpdate').
+ * @param {Array} [args] - Extra arguments to apply to the hook call.
+ * @returns {Boolean} false if any of the plugins return false, else returns true.
+ */
+ notify: function(chart, hook, args) {
+ var descriptors = this.descriptors(chart);
+ var ilen = descriptors.length;
+ var i, descriptor, plugin, params, method;
+
+ for (i = 0; i < ilen; ++i) {
+ descriptor = descriptors[i];
+ plugin = descriptor.plugin;
+ method = plugin[hook];
+ if (typeof method === 'function') {
+ params = [chart].concat(args || []);
+ params.push(descriptor.options);
+ if (method.apply(plugin, params) === false) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ },
+
+ /**
+ * Returns descriptors of enabled plugins for the given chart.
+ * @returns {Array} [{ plugin, options }]
+ * @private
+ */
+ descriptors: function(chart) {
+ var cache = chart.$plugins || (chart.$plugins = {});
+ if (cache.id === this._cacheId) {
+ return cache.descriptors;
+ }
+
+ var plugins = [];
+ var descriptors = [];
+ var config = (chart && chart.config) || {};
+ var options = (config.options && config.options.plugins) || {};
+
+ this._plugins.concat(config.plugins || []).forEach(function(plugin) {
+ var idx = plugins.indexOf(plugin);
+ if (idx !== -1) {
+ return;
+ }
+
+ var id = plugin.id;
+ var opts = options[id];
+ if (opts === false) {
+ return;
+ }
+
+ if (opts === true) {
+ opts = helpers.clone(defaults.global.plugins[id]);
+ }
+
+ plugins.push(plugin);
+ descriptors.push({
+ plugin: plugin,
+ options: opts || {}
+ });
+ });
+
+ cache.descriptors = descriptors;
+ cache.id = this._cacheId;
+ return descriptors;
+ },
+
+ /**
+ * Invalidates cache for the given chart: descriptors hold a reference on plugin option,
+ * but in some cases, this reference can be changed by the user when updating options.
+ * https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167
+ * @private
+ */
+ _invalidate: function(chart) {
+ delete chart.$plugins;
+ }
+};
+
+/**
+ * Plugin extension hooks.
+ * @interface IPlugin
+ * @since 2.1.0
+ */
+/**
+ * @method IPlugin#beforeInit
+ * @desc Called before initializing `chart`.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#afterInit
+ * @desc Called after `chart` has been initialized and before the first update.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeUpdate
+ * @desc Called before updating `chart`. If any plugin returns `false`, the update
+ * is cancelled (and thus subsequent render(s)) until another `update` is triggered.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart update.
+ */
+/**
+ * @method IPlugin#afterUpdate
+ * @desc Called after `chart` has been updated and before rendering. Note that this
+ * hook will not be called if the chart update has been previously cancelled.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeDatasetsUpdate
+ * @desc Called before updating the `chart` datasets. If any plugin returns `false`,
+ * the datasets update is cancelled until another `update` is triggered.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} false to cancel the datasets update.
+ * @since version 2.1.5
+*/
+/**
+ * @method IPlugin#afterDatasetsUpdate
+ * @desc Called after the `chart` datasets have been updated. Note that this hook
+ * will not be called if the datasets update has been previously cancelled.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ * @since version 2.1.5
+ */
+/**
+ * @method IPlugin#beforeDatasetUpdate
+ * @desc Called before updating the `chart` dataset at the given `args.index`. If any plugin
+ * returns `false`, the datasets update is cancelled until another `update` is triggered.
+ * @param {Chart} chart - The chart instance.
+ * @param {Object} args - The call arguments.
+ * @param {Number} args.index - The dataset index.
+ * @param {Object} args.meta - The dataset metadata.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart datasets drawing.
+ */
+/**
+ * @method IPlugin#afterDatasetUpdate
+ * @desc Called after the `chart` datasets at the given `args.index` has been updated. Note
+ * that this hook will not be called if the datasets update has been previously cancelled.
+ * @param {Chart} chart - The chart instance.
+ * @param {Object} args - The call arguments.
+ * @param {Number} args.index - The dataset index.
+ * @param {Object} args.meta - The dataset metadata.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeLayout
+ * @desc Called before laying out `chart`. If any plugin returns `false`,
+ * the layout update is cancelled until another `update` is triggered.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart layout.
+ */
+/**
+ * @method IPlugin#afterLayout
+ * @desc Called after the `chart` has been layed out. Note that this hook will not
+ * be called if the layout update has been previously cancelled.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeRender
+ * @desc Called before rendering `chart`. If any plugin returns `false`,
+ * the rendering is cancelled until another `render` is triggered.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart rendering.
+ */
+/**
+ * @method IPlugin#afterRender
+ * @desc Called after the `chart` has been fully rendered (and animation completed). Note
+ * that this hook will not be called if the rendering has been previously cancelled.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeDraw
+ * @desc Called before drawing `chart` at every animation frame specified by the given
+ * easing value. If any plugin returns `false`, the frame drawing is cancelled until
+ * another `render` is triggered.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart drawing.
+ */
+/**
+ * @method IPlugin#afterDraw
+ * @desc Called after the `chart` has been drawn for the specific easing value. Note
+ * that this hook will not be called if the drawing has been previously cancelled.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeDatasetsDraw
+ * @desc Called before drawing the `chart` datasets. If any plugin returns `false`,
+ * the datasets drawing is cancelled until another `render` is triggered.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart datasets drawing.
+ */
+/**
+ * @method IPlugin#afterDatasetsDraw
+ * @desc Called after the `chart` datasets have been drawn. Note that this hook
+ * will not be called if the datasets drawing has been previously cancelled.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeDatasetDraw
+ * @desc Called before drawing the `chart` dataset at the given `args.index` (datasets
+ * are drawn in the reverse order). If any plugin returns `false`, the datasets drawing
+ * is cancelled until another `render` is triggered.
+ * @param {Chart} chart - The chart instance.
+ * @param {Object} args - The call arguments.
+ * @param {Number} args.index - The dataset index.
+ * @param {Object} args.meta - The dataset metadata.
+ * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart datasets drawing.
+ */
+/**
+ * @method IPlugin#afterDatasetDraw
+ * @desc Called after the `chart` datasets at the given `args.index` have been drawn
+ * (datasets are drawn in the reverse order). Note that this hook will not be called
+ * if the datasets drawing has been previously cancelled.
+ * @param {Chart} chart - The chart instance.
+ * @param {Object} args - The call arguments.
+ * @param {Number} args.index - The dataset index.
+ * @param {Object} args.meta - The dataset metadata.
+ * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeTooltipDraw
+ * @desc Called before drawing the `tooltip`. If any plugin returns `false`,
+ * the tooltip drawing is cancelled until another `render` is triggered.
+ * @param {Chart} chart - The chart instance.
+ * @param {Object} args - The call arguments.
+ * @param {Object} args.tooltip - The tooltip.
+ * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart tooltip drawing.
+ */
+/**
+ * @method IPlugin#afterTooltipDraw
+ * @desc Called after drawing the `tooltip`. Note that this hook will not
+ * be called if the tooltip drawing has been previously cancelled.
+ * @param {Chart} chart - The chart instance.
+ * @param {Object} args - The call arguments.
+ * @param {Object} args.tooltip - The tooltip.
+ * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeEvent
+ * @desc Called before processing the specified `event`. If any plugin returns `false`,
+ * the event will be discarded.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {IEvent} event - The event object.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#afterEvent
+ * @desc Called after the `event` has been consumed. Note that this hook
+ * will not be called if the `event` has been previously discarded.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {IEvent} event - The event object.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#resize
+ * @desc Called after the chart as been resized.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Number} size - The new canvas display size (eq. canvas.style width & height).
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#destroy
+ * @desc Called after the chart as been destroyed.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ */
+
+},{"25":25,"45":45}],32:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+var Ticks = require(34);
+
+defaults._set('scale', {
+ display: true,
+ position: 'left',
+ offset: false,
+
+ // grid line settings
+ gridLines: {
+ display: true,
+ color: 'rgba(0, 0, 0, 0.1)',
+ lineWidth: 1,
+ drawBorder: true,
+ drawOnChartArea: true,
+ drawTicks: true,
+ tickMarkLength: 10,
+ zeroLineWidth: 1,
+ zeroLineColor: 'rgba(0,0,0,0.25)',
+ zeroLineBorderDash: [],
+ zeroLineBorderDashOffset: 0.0,
+ offsetGridLines: false,
+ borderDash: [],
+ borderDashOffset: 0.0
+ },
+
+ // scale label
+ scaleLabel: {
+ // display property
+ display: false,
+
+ // actual label
+ labelString: '',
+
+ // line height
+ lineHeight: 1.2,
+
+ // top/bottom padding
+ padding: {
+ top: 4,
+ bottom: 4
+ }
+ },
+
+ // label settings
+ ticks: {
+ beginAtZero: false,
+ minRotation: 0,
+ maxRotation: 50,
+ mirror: false,
+ padding: 0,
+ reverse: false,
+ display: true,
+ autoSkip: true,
+ autoSkipPadding: 0,
+ labelOffset: 0,
+ // We pass through arrays to be rendered as multiline labels, we convert Others to strings here.
+ callback: Ticks.formatters.values,
+ minor: {},
+ major: {}
+ }
+});
+
+function labelsFromTicks(ticks) {
+ var labels = [];
+ var i, ilen;
+
+ for (i = 0, ilen = ticks.length; i < ilen; ++i) {
+ labels.push(ticks[i].label);
+ }
+
+ return labels;
+}
+
+function getLineValue(scale, index, offsetGridLines) {
+ var lineValue = scale.getPixelForTick(index);
+
+ if (offsetGridLines) {
+ if (index === 0) {
+ lineValue -= (scale.getPixelForTick(1) - lineValue) / 2;
+ } else {
+ lineValue -= (lineValue - scale.getPixelForTick(index - 1)) / 2;
+ }
+ }
+ return lineValue;
+}
+
+module.exports = function(Chart) {
+
+ function computeTextSize(context, tick, font) {
+ return helpers.isArray(tick) ?
+ helpers.longestText(context, font, tick) :
+ context.measureText(tick).width;
+ }
+
+ function parseFontOptions(options) {
+ var valueOrDefault = helpers.valueOrDefault;
+ var globalDefaults = defaults.global;
+ var size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize);
+ var style = valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle);
+ var family = valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily);
+
+ return {
+ size: size,
+ style: style,
+ family: family,
+ font: helpers.fontString(size, style, family)
+ };
+ }
+
+ function parseLineHeight(options) {
+ return helpers.options.toLineHeight(
+ helpers.valueOrDefault(options.lineHeight, 1.2),
+ helpers.valueOrDefault(options.fontSize, defaults.global.defaultFontSize));
+ }
+
+ Chart.Scale = Element.extend({
+ /**
+ * Get the padding needed for the scale
+ * @method getPadding
+ * @private
+ * @returns {Padding} the necessary padding
+ */
+ getPadding: function() {
+ var me = this;
+ return {
+ left: me.paddingLeft || 0,
+ top: me.paddingTop || 0,
+ right: me.paddingRight || 0,
+ bottom: me.paddingBottom || 0
+ };
+ },
+
+ /**
+ * Returns the scale tick objects ({label, major})
+ * @since 2.7
+ */
+ getTicks: function() {
+ return this._ticks;
+ },
+
+ // These methods are ordered by lifecyle. Utilities then follow.
+ // Any function defined here is inherited by all scale types.
+ // Any function can be extended by the scale type
+
+ mergeTicksOptions: function() {
+ var ticks = this.options.ticks;
+ if (ticks.minor === false) {
+ ticks.minor = {
+ display: false
+ };
+ }
+ if (ticks.major === false) {
+ ticks.major = {
+ display: false
+ };
+ }
+ for (var key in ticks) {
+ if (key !== 'major' && key !== 'minor') {
+ if (typeof ticks.minor[key] === 'undefined') {
+ ticks.minor[key] = ticks[key];
+ }
+ if (typeof ticks.major[key] === 'undefined') {
+ ticks.major[key] = ticks[key];
+ }
+ }
+ }
+ },
+ beforeUpdate: function() {
+ helpers.callback(this.options.beforeUpdate, [this]);
+ },
+ update: function(maxWidth, maxHeight, margins) {
+ var me = this;
+ var i, ilen, labels, label, ticks, tick;
+
+ // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
+ me.beforeUpdate();
+
+ // Absorb the master measurements
+ me.maxWidth = maxWidth;
+ me.maxHeight = maxHeight;
+ me.margins = helpers.extend({
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0
+ }, margins);
+ me.longestTextCache = me.longestTextCache || {};
+
+ // Dimensions
+ me.beforeSetDimensions();
+ me.setDimensions();
+ me.afterSetDimensions();
+
+ // Data min/max
+ me.beforeDataLimits();
+ me.determineDataLimits();
+ me.afterDataLimits();
+
+ // Ticks - `this.ticks` is now DEPRECATED!
+ // Internal ticks are now stored as objects in the PRIVATE `this._ticks` member
+ // and must not be accessed directly from outside this class. `this.ticks` being
+ // around for long time and not marked as private, we can't change its structure
+ // without unexpected breaking changes. If you need to access the scale ticks,
+ // use scale.getTicks() instead.
+
+ me.beforeBuildTicks();
+
+ // New implementations should return an array of objects but for BACKWARD COMPAT,
+ // we still support no return (`this.ticks` internally set by calling this method).
+ ticks = me.buildTicks() || [];
+
+ me.afterBuildTicks();
+
+ me.beforeTickToLabelConversion();
+
+ // New implementations should return the formatted tick labels but for BACKWARD
+ // COMPAT, we still support no return (`this.ticks` internally changed by calling
+ // this method and supposed to contain only string values).
+ labels = me.convertTicksToLabels(ticks) || me.ticks;
+
+ me.afterTickToLabelConversion();
+
+ me.ticks = labels; // BACKWARD COMPATIBILITY
+
+ // IMPORTANT: from this point, we consider that `this.ticks` will NEVER change!
+
+ // BACKWARD COMPAT: synchronize `_ticks` with labels (so potentially `this.ticks`)
+ for (i = 0, ilen = labels.length; i < ilen; ++i) {
+ label = labels[i];
+ tick = ticks[i];
+ if (!tick) {
+ ticks.push(tick = {
+ label: label,
+ major: false
+ });
+ } else {
+ tick.label = label;
+ }
+ }
+
+ me._ticks = ticks;
+
+ // Tick Rotation
+ me.beforeCalculateTickRotation();
+ me.calculateTickRotation();
+ me.afterCalculateTickRotation();
+ // Fit
+ me.beforeFit();
+ me.fit();
+ me.afterFit();
+ //
+ me.afterUpdate();
+
+ return me.minSize;
+
+ },
+ afterUpdate: function() {
+ helpers.callback(this.options.afterUpdate, [this]);
+ },
+
+ //
+
+ beforeSetDimensions: function() {
+ helpers.callback(this.options.beforeSetDimensions, [this]);
+ },
+ setDimensions: function() {
+ var me = this;
+ // Set the unconstrained dimension before label rotation
+ if (me.isHorizontal()) {
+ // Reset position before calculating rotation
+ me.width = me.maxWidth;
+ me.left = 0;
+ me.right = me.width;
+ } else {
+ me.height = me.maxHeight;
+
+ // Reset position before calculating rotation
+ me.top = 0;
+ me.bottom = me.height;
+ }
+
+ // Reset padding
+ me.paddingLeft = 0;
+ me.paddingTop = 0;
+ me.paddingRight = 0;
+ me.paddingBottom = 0;
+ },
+ afterSetDimensions: function() {
+ helpers.callback(this.options.afterSetDimensions, [this]);
+ },
+
+ // Data limits
+ beforeDataLimits: function() {
+ helpers.callback(this.options.beforeDataLimits, [this]);
+ },
+ determineDataLimits: helpers.noop,
+ afterDataLimits: function() {
+ helpers.callback(this.options.afterDataLimits, [this]);
+ },
+
+ //
+ beforeBuildTicks: function() {
+ helpers.callback(this.options.beforeBuildTicks, [this]);
+ },
+ buildTicks: helpers.noop,
+ afterBuildTicks: function() {
+ helpers.callback(this.options.afterBuildTicks, [this]);
+ },
+
+ beforeTickToLabelConversion: function() {
+ helpers.callback(this.options.beforeTickToLabelConversion, [this]);
+ },
+ convertTicksToLabels: function() {
+ var me = this;
+ // Convert ticks to strings
+ var tickOpts = me.options.ticks;
+ me.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback, this);
+ },
+ afterTickToLabelConversion: function() {
+ helpers.callback(this.options.afterTickToLabelConversion, [this]);
+ },
+
+ //
+
+ beforeCalculateTickRotation: function() {
+ helpers.callback(this.options.beforeCalculateTickRotation, [this]);
+ },
+ calculateTickRotation: function() {
+ var me = this;
+ var context = me.ctx;
+ var tickOpts = me.options.ticks;
+ var labels = labelsFromTicks(me._ticks);
+
+ // Get the width of each grid by calculating the difference
+ // between x offsets between 0 and 1.
+ var tickFont = parseFontOptions(tickOpts);
+ context.font = tickFont.font;
+
+ var labelRotation = tickOpts.minRotation || 0;
+
+ if (labels.length && me.options.display && me.isHorizontal()) {
+ var originalLabelWidth = helpers.longestText(context, tickFont.font, labels, me.longestTextCache);
+ var labelWidth = originalLabelWidth;
+ var cosRotation, sinRotation;
+
+ // Allow 3 pixels x2 padding either side for label readability
+ var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;
+
+ // Max label rotation can be set or default to 90 - also act as a loop counter
+ while (labelWidth > tickWidth && labelRotation < tickOpts.maxRotation) {
+ var angleRadians = helpers.toRadians(labelRotation);
+ cosRotation = Math.cos(angleRadians);
+ sinRotation = Math.sin(angleRadians);
+
+ if (sinRotation * originalLabelWidth > me.maxHeight) {
+ // go back one step
+ labelRotation--;
+ break;
+ }
+
+ labelRotation++;
+ labelWidth = cosRotation * originalLabelWidth;
+ }
+ }
+
+ me.labelRotation = labelRotation;
+ },
+ afterCalculateTickRotation: function() {
+ helpers.callback(this.options.afterCalculateTickRotation, [this]);
+ },
+
+ //
+
+ beforeFit: function() {
+ helpers.callback(this.options.beforeFit, [this]);
+ },
+ fit: function() {
+ var me = this;
+ // Reset
+ var minSize = me.minSize = {
+ width: 0,
+ height: 0
+ };
+
+ var labels = labelsFromTicks(me._ticks);
+
+ var opts = me.options;
+ var tickOpts = opts.ticks;
+ var scaleLabelOpts = opts.scaleLabel;
+ var gridLineOpts = opts.gridLines;
+ var display = opts.display;
+ var isHorizontal = me.isHorizontal();
+
+ var tickFont = parseFontOptions(tickOpts);
+ var tickMarkLength = opts.gridLines.tickMarkLength;
+
+ // Width
+ if (isHorizontal) {
+ // subtract the margins to line up with the chartArea if we are a full width scale
+ minSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth;
+ } else {
+ minSize.width = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
+ }
+
+ // height
+ if (isHorizontal) {
+ minSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
+ } else {
+ minSize.height = me.maxHeight; // fill all the height
+ }
+
+ // Are we showing a title for the scale?
+ if (scaleLabelOpts.display && display) {
+ var scaleLabelLineHeight = parseLineHeight(scaleLabelOpts);
+ var scaleLabelPadding = helpers.options.toPadding(scaleLabelOpts.padding);
+ var deltaHeight = scaleLabelLineHeight + scaleLabelPadding.height;
+
+ if (isHorizontal) {
+ minSize.height += deltaHeight;
+ } else {
+ minSize.width += deltaHeight;
+ }
+ }
+
+ // Don't bother fitting the ticks if we are not showing them
+ if (tickOpts.display && display) {
+ var largestTextWidth = helpers.longestText(me.ctx, tickFont.font, labels, me.longestTextCache);
+ var tallestLabelHeightInLines = helpers.numberOfLabelLines(labels);
+ var lineSpace = tickFont.size * 0.5;
+ var tickPadding = me.options.ticks.padding;
+
+ if (isHorizontal) {
+ // A horizontal axis is more constrained by the height.
+ me.longestLabelWidth = largestTextWidth;
+
+ var angleRadians = helpers.toRadians(me.labelRotation);
+ var cosRotation = Math.cos(angleRadians);
+ var sinRotation = Math.sin(angleRadians);
+
+ // TODO - improve this calculation
+ var labelHeight = (sinRotation * largestTextWidth)
+ + (tickFont.size * tallestLabelHeightInLines)
+ + (lineSpace * (tallestLabelHeightInLines - 1))
+ + lineSpace; // padding
+
+ minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight + tickPadding);
+
+ me.ctx.font = tickFont.font;
+ var firstLabelWidth = computeTextSize(me.ctx, labels[0], tickFont.font);
+ var lastLabelWidth = computeTextSize(me.ctx, labels[labels.length - 1], tickFont.font);
+
+ // Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned
+ // which means that the right padding is dominated by the font height
+ if (me.labelRotation !== 0) {
+ me.paddingLeft = opts.position === 'bottom' ? (cosRotation * firstLabelWidth) + 3 : (cosRotation * lineSpace) + 3; // add 3 px to move away from canvas edges
+ me.paddingRight = opts.position === 'bottom' ? (cosRotation * lineSpace) + 3 : (cosRotation * lastLabelWidth) + 3;
+ } else {
+ me.paddingLeft = firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges
+ me.paddingRight = lastLabelWidth / 2 + 3;
+ }
+ } else {
+ // A vertical axis is more constrained by the width. Labels are the
+ // dominant factor here, so get that length first and account for padding
+ if (tickOpts.mirror) {
+ largestTextWidth = 0;
+ } else {
+ // use lineSpace for consistency with horizontal axis
+ // tickPadding is not implemented for horizontal
+ largestTextWidth += tickPadding + lineSpace;
+ }
+
+ minSize.width = Math.min(me.maxWidth, minSize.width + largestTextWidth);
+
+ me.paddingTop = tickFont.size / 2;
+ me.paddingBottom = tickFont.size / 2;
+ }
+ }
+
+ me.handleMargins();
+
+ me.width = minSize.width;
+ me.height = minSize.height;
+ },
+
+ /**
+ * Handle margins and padding interactions
+ * @private
+ */
+ handleMargins: function() {
+ var me = this;
+ if (me.margins) {
+ me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);
+ me.paddingTop = Math.max(me.paddingTop - me.margins.top, 0);
+ me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);
+ me.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0);
+ }
+ },
+
+ afterFit: function() {
+ helpers.callback(this.options.afterFit, [this]);
+ },
+
+ // Shared Methods
+ isHorizontal: function() {
+ return this.options.position === 'top' || this.options.position === 'bottom';
+ },
+ isFullWidth: function() {
+ return (this.options.fullWidth);
+ },
+
+ // Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not
+ getRightValue: function(rawValue) {
+ // Null and undefined values first
+ if (helpers.isNullOrUndef(rawValue)) {
+ return NaN;
+ }
+ // isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values
+ if (typeof rawValue === 'number' && !isFinite(rawValue)) {
+ return NaN;
+ }
+ // If it is in fact an object, dive in one more level
+ if (rawValue) {
+ if (this.isHorizontal()) {
+ if (rawValue.x !== undefined) {
+ return this.getRightValue(rawValue.x);
+ }
+ } else if (rawValue.y !== undefined) {
+ return this.getRightValue(rawValue.y);
+ }
+ }
+
+ // Value is good, return it
+ return rawValue;
+ },
+
+ /**
+ * Used to get the value to display in the tooltip for the data at the given index
+ * @param index
+ * @param datasetIndex
+ */
+ getLabelForIndex: helpers.noop,
+
+ /**
+ * Returns the location of the given data point. Value can either be an index or a numerical value
+ * The coordinate (0, 0) is at the upper-left corner of the canvas
+ * @param value
+ * @param index
+ * @param datasetIndex
+ */
+ getPixelForValue: helpers.noop,
+
+ /**
+ * Used to get the data value from a given pixel. This is the inverse of getPixelForValue
+ * The coordinate (0, 0) is at the upper-left corner of the canvas
+ * @param pixel
+ */
+ getValueForPixel: helpers.noop,
+
+ /**
+ * Returns the location of the tick at the given index
+ * The coordinate (0, 0) is at the upper-left corner of the canvas
+ */
+ getPixelForTick: function(index) {
+ var me = this;
+ var offset = me.options.offset;
+ if (me.isHorizontal()) {
+ var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
+ var tickWidth = innerWidth / Math.max((me._ticks.length - (offset ? 0 : 1)), 1);
+ var pixel = (tickWidth * index) + me.paddingLeft;
+
+ if (offset) {
+ pixel += tickWidth / 2;
+ }
+
+ var finalVal = me.left + Math.round(pixel);
+ finalVal += me.isFullWidth() ? me.margins.left : 0;
+ return finalVal;
+ }
+ var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
+ return me.top + (index * (innerHeight / (me._ticks.length - 1)));
+ },
+
+ /**
+ * Utility for getting the pixel location of a percentage of scale
+ * The coordinate (0, 0) is at the upper-left corner of the canvas
+ */
+ getPixelForDecimal: function(decimal) {
+ var me = this;
+ if (me.isHorizontal()) {
+ var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
+ var valueOffset = (innerWidth * decimal) + me.paddingLeft;
+
+ var finalVal = me.left + Math.round(valueOffset);
+ finalVal += me.isFullWidth() ? me.margins.left : 0;
+ return finalVal;
+ }
+ return me.top + (decimal * me.height);
+ },
+
+ /**
+ * Returns the pixel for the minimum chart value
+ * The coordinate (0, 0) is at the upper-left corner of the canvas
+ */
+ getBasePixel: function() {
+ return this.getPixelForValue(this.getBaseValue());
+ },
+
+ getBaseValue: function() {
+ var me = this;
+ var min = me.min;
+ var max = me.max;
+
+ return me.beginAtZero ? 0 :
+ min < 0 && max < 0 ? max :
+ min > 0 && max > 0 ? min :
+ 0;
+ },
+
+ /**
+ * Returns a subset of ticks to be plotted to avoid overlapping labels.
+ * @private
+ */
+ _autoSkip: function(ticks) {
+ var skipRatio;
+ var me = this;
+ var isHorizontal = me.isHorizontal();
+ var optionTicks = me.options.ticks.minor;
+ var tickCount = ticks.length;
+ var labelRotationRadians = helpers.toRadians(me.labelRotation);
+ var cosRotation = Math.cos(labelRotationRadians);
+ var longestRotatedLabel = me.longestLabelWidth * cosRotation;
+ var result = [];
+ var i, tick, shouldSkip;
+
+ // figure out the maximum number of gridlines to show
+ var maxTicks;
+ if (optionTicks.maxTicksLimit) {
+ maxTicks = optionTicks.maxTicksLimit;
+ }
+
+ if (isHorizontal) {
+ skipRatio = false;
+
+ if ((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount > (me.width - (me.paddingLeft + me.paddingRight))) {
+ skipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount) / (me.width - (me.paddingLeft + me.paddingRight)));
+ }
+
+ // if they defined a max number of optionTicks,
+ // increase skipRatio until that number is met
+ if (maxTicks && tickCount > maxTicks) {
+ skipRatio = Math.max(skipRatio, Math.floor(tickCount / maxTicks));
+ }
+ }
+
+ for (i = 0; i < tickCount; i++) {
+ tick = ticks[i];
+
+ // Since we always show the last tick,we need may need to hide the last shown one before
+ shouldSkip = (skipRatio > 1 && i % skipRatio > 0) || (i % skipRatio === 0 && i + skipRatio >= tickCount);
+ if (shouldSkip && i !== tickCount - 1) {
+ // leave tick in place but make sure it's not displayed (#4635)
+ delete tick.label;
+ }
+ result.push(tick);
+ }
+ return result;
+ },
+
+ // Actually draw the scale on the canvas
+ // @param {rectangle} chartArea : the area of the chart to draw full grid lines on
+ draw: function(chartArea) {
+ var me = this;
+ var options = me.options;
+ if (!options.display) {
+ return;
+ }
+
+ var context = me.ctx;
+ var globalDefaults = defaults.global;
+ var optionTicks = options.ticks.minor;
+ var optionMajorTicks = options.ticks.major || optionTicks;
+ var gridLines = options.gridLines;
+ var scaleLabel = options.scaleLabel;
+
+ var isRotated = me.labelRotation !== 0;
+ var isHorizontal = me.isHorizontal();
+
+ var ticks = optionTicks.autoSkip ? me._autoSkip(me.getTicks()) : me.getTicks();
+ var tickFontColor = helpers.valueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);
+ var tickFont = parseFontOptions(optionTicks);
+ var majorTickFontColor = helpers.valueOrDefault(optionMajorTicks.fontColor, globalDefaults.defaultFontColor);
+ var majorTickFont = parseFontOptions(optionMajorTicks);
+
+ var tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0;
+
+ var scaleLabelFontColor = helpers.valueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);
+ var scaleLabelFont = parseFontOptions(scaleLabel);
+ var scaleLabelPadding = helpers.options.toPadding(scaleLabel.padding);
+ var labelRotationRadians = helpers.toRadians(me.labelRotation);
+
+ var itemsToDraw = [];
+
+ var axisWidth = me.options.gridLines.lineWidth;
+ var xTickStart = options.position === 'right' ? me.right : me.right - axisWidth - tl;
+ var xTickEnd = options.position === 'right' ? me.right + tl : me.right;
+ var yTickStart = options.position === 'bottom' ? me.top + axisWidth : me.bottom - tl - axisWidth;
+ var yTickEnd = options.position === 'bottom' ? me.top + axisWidth + tl : me.bottom + axisWidth;
+
+ helpers.each(ticks, function(tick, index) {
+ // autoskipper skipped this tick (#4635)
+ if (helpers.isNullOrUndef(tick.label)) {
+ return;
+ }
+
+ var label = tick.label;
+ var lineWidth, lineColor, borderDash, borderDashOffset;
+ if (index === me.zeroLineIndex && options.offset === gridLines.offsetGridLines) {
+ // Draw the first index specially
+ lineWidth = gridLines.zeroLineWidth;
+ lineColor = gridLines.zeroLineColor;
+ borderDash = gridLines.zeroLineBorderDash;
+ borderDashOffset = gridLines.zeroLineBorderDashOffset;
+ } else {
+ lineWidth = helpers.valueAtIndexOrDefault(gridLines.lineWidth, index);
+ lineColor = helpers.valueAtIndexOrDefault(gridLines.color, index);
+ borderDash = helpers.valueOrDefault(gridLines.borderDash, globalDefaults.borderDash);
+ borderDashOffset = helpers.valueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset);
+ }
+
+ // Common properties
+ var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;
+ var textAlign = 'middle';
+ var textBaseline = 'middle';
+ var tickPadding = optionTicks.padding;
+
+ if (isHorizontal) {
+ var labelYOffset = tl + tickPadding;
+
+ if (options.position === 'bottom') {
+ // bottom
+ textBaseline = !isRotated ? 'top' : 'middle';
+ textAlign = !isRotated ? 'center' : 'right';
+ labelY = me.top + labelYOffset;
+ } else {
+ // top
+ textBaseline = !isRotated ? 'bottom' : 'middle';
+ textAlign = !isRotated ? 'center' : 'left';
+ labelY = me.bottom - labelYOffset;
+ }
+
+ var xLineValue = getLineValue(me, index, gridLines.offsetGridLines && ticks.length > 1);
+ if (xLineValue < me.left) {
+ lineColor = 'rgba(0,0,0,0)';
+ }
+ xLineValue += helpers.aliasPixel(lineWidth);
+
+ labelX = me.getPixelForTick(index) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option)
+
+ tx1 = tx2 = x1 = x2 = xLineValue;
+ ty1 = yTickStart;
+ ty2 = yTickEnd;
+ y1 = chartArea.top;
+ y2 = chartArea.bottom + axisWidth;
+ } else {
+ var isLeft = options.position === 'left';
+ var labelXOffset;
+
+ if (optionTicks.mirror) {
+ textAlign = isLeft ? 'left' : 'right';
+ labelXOffset = tickPadding;
+ } else {
+ textAlign = isLeft ? 'right' : 'left';
+ labelXOffset = tl + tickPadding;
+ }
+
+ labelX = isLeft ? me.right - labelXOffset : me.left + labelXOffset;
+
+ var yLineValue = getLineValue(me, index, gridLines.offsetGridLines && ticks.length > 1);
+ if (yLineValue < me.top) {
+ lineColor = 'rgba(0,0,0,0)';
+ }
+ yLineValue += helpers.aliasPixel(lineWidth);
+
+ labelY = me.getPixelForTick(index) + optionTicks.labelOffset;
+
+ tx1 = xTickStart;
+ tx2 = xTickEnd;
+ x1 = chartArea.left;
+ x2 = chartArea.right + axisWidth;
+ ty1 = ty2 = y1 = y2 = yLineValue;
+ }
+
+ itemsToDraw.push({
+ tx1: tx1,
+ ty1: ty1,
+ tx2: tx2,
+ ty2: ty2,
+ x1: x1,
+ y1: y1,
+ x2: x2,
+ y2: y2,
+ labelX: labelX,
+ labelY: labelY,
+ glWidth: lineWidth,
+ glColor: lineColor,
+ glBorderDash: borderDash,
+ glBorderDashOffset: borderDashOffset,
+ rotation: -1 * labelRotationRadians,
+ label: label,
+ major: tick.major,
+ textBaseline: textBaseline,
+ textAlign: textAlign
+ });
+ });
+
+ // Draw all of the tick labels, tick marks, and grid lines at the correct places
+ helpers.each(itemsToDraw, function(itemToDraw) {
+ if (gridLines.display) {
+ context.save();
+ context.lineWidth = itemToDraw.glWidth;
+ context.strokeStyle = itemToDraw.glColor;
+ if (context.setLineDash) {
+ context.setLineDash(itemToDraw.glBorderDash);
+ context.lineDashOffset = itemToDraw.glBorderDashOffset;
+ }
+
+ context.beginPath();
+
+ if (gridLines.drawTicks) {
+ context.moveTo(itemToDraw.tx1, itemToDraw.ty1);
+ context.lineTo(itemToDraw.tx2, itemToDraw.ty2);
+ }
+
+ if (gridLines.drawOnChartArea) {
+ context.moveTo(itemToDraw.x1, itemToDraw.y1);
+ context.lineTo(itemToDraw.x2, itemToDraw.y2);
+ }
+
+ context.stroke();
+ context.restore();
+ }
+
+ if (optionTicks.display) {
+ // Make sure we draw text in the correct color and font
+ context.save();
+ context.translate(itemToDraw.labelX, itemToDraw.labelY);
+ context.rotate(itemToDraw.rotation);
+ context.font = itemToDraw.major ? majorTickFont.font : tickFont.font;
+ context.fillStyle = itemToDraw.major ? majorTickFontColor : tickFontColor;
+ context.textBaseline = itemToDraw.textBaseline;
+ context.textAlign = itemToDraw.textAlign;
+
+ var label = itemToDraw.label;
+ if (helpers.isArray(label)) {
+ var lineCount = label.length;
+ var lineHeight = tickFont.size * 1.5;
+ var y = me.isHorizontal() ? 0 : -lineHeight * (lineCount - 1) / 2;
+
+ for (var i = 0; i < lineCount; ++i) {
+ // We just make sure the multiline element is a string here..
+ context.fillText('' + label[i], 0, y);
+ // apply same lineSpacing as calculated @ L#320
+ y += lineHeight;
+ }
+ } else {
+ context.fillText(label, 0, 0);
+ }
+ context.restore();
+ }
+ });
+
+ if (scaleLabel.display) {
+ // Draw the scale label
+ var scaleLabelX;
+ var scaleLabelY;
+ var rotation = 0;
+ var halfLineHeight = parseLineHeight(scaleLabel) / 2;
+
+ if (isHorizontal) {
+ scaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width
+ scaleLabelY = options.position === 'bottom'
+ ? me.bottom - halfLineHeight - scaleLabelPadding.bottom
+ : me.top + halfLineHeight + scaleLabelPadding.top;
+ } else {
+ var isLeft = options.position === 'left';
+ scaleLabelX = isLeft
+ ? me.left + halfLineHeight + scaleLabelPadding.top
+ : me.right - halfLineHeight - scaleLabelPadding.top;
+ scaleLabelY = me.top + ((me.bottom - me.top) / 2);
+ rotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;
+ }
+
+ context.save();
+ context.translate(scaleLabelX, scaleLabelY);
+ context.rotate(rotation);
+ context.textAlign = 'center';
+ context.textBaseline = 'middle';
+ context.fillStyle = scaleLabelFontColor; // render in correct colour
+ context.font = scaleLabelFont.font;
+ context.fillText(scaleLabel.labelString, 0, 0);
+ context.restore();
+ }
+
+ if (gridLines.drawBorder) {
+ // Draw the line at the edge of the axis
+ context.lineWidth = helpers.valueAtIndexOrDefault(gridLines.lineWidth, 0);
+ context.strokeStyle = helpers.valueAtIndexOrDefault(gridLines.color, 0);
+ var x1 = me.left;
+ var x2 = me.right + axisWidth;
+ var y1 = me.top;
+ var y2 = me.bottom + axisWidth;
+
+ var aliasPixel = helpers.aliasPixel(context.lineWidth);
+ if (isHorizontal) {
+ y1 = y2 = options.position === 'top' ? me.bottom : me.top;
+ y1 += aliasPixel;
+ y2 += aliasPixel;
+ } else {
+ x1 = x2 = options.position === 'left' ? me.right : me.left;
+ x1 += aliasPixel;
+ x2 += aliasPixel;
+ }
+
+ context.beginPath();
+ context.moveTo(x1, y1);
+ context.lineTo(x2, y2);
+ context.stroke();
+ }
+ }
+ });
+};
+
+},{"25":25,"26":26,"34":34,"45":45}],33:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var helpers = require(45);
+var layouts = require(30);
+
+module.exports = function(Chart) {
+
+ Chart.scaleService = {
+ // Scale registration object. Extensions can register new scale types (such as log or DB scales) and then
+ // use the new chart options to grab the correct scale
+ constructors: {},
+ // Use a registration function so that we can move to an ES6 map when we no longer need to support
+ // old browsers
+
+ // Scale config defaults
+ defaults: {},
+ registerScaleType: function(type, scaleConstructor, scaleDefaults) {
+ this.constructors[type] = scaleConstructor;
+ this.defaults[type] = helpers.clone(scaleDefaults);
+ },
+ getScaleConstructor: function(type) {
+ return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;
+ },
+ getScaleDefaults: function(type) {
+ // Return the scale defaults merged with the global settings so that we always use the latest ones
+ return this.defaults.hasOwnProperty(type) ? helpers.merge({}, [defaults.scale, this.defaults[type]]) : {};
+ },
+ updateScaleDefaults: function(type, additions) {
+ var me = this;
+ if (me.defaults.hasOwnProperty(type)) {
+ me.defaults[type] = helpers.extend(me.defaults[type], additions);
+ }
+ },
+ addScalesToLayout: function(chart) {
+ // Adds each scale to the chart.boxes array to be sized accordingly
+ helpers.each(chart.scales, function(scale) {
+ // Set ILayoutItem parameters for backwards compatibility
+ scale.fullWidth = scale.options.fullWidth;
+ scale.position = scale.options.position;
+ scale.weight = scale.options.weight;
+ layouts.addBox(chart, scale);
+ });
+ }
+ };
+};
+
+},{"25":25,"30":30,"45":45}],34:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+
+/**
+ * Namespace to hold static tick generation functions
+ * @namespace Chart.Ticks
+ */
+module.exports = {
+ /**
+ * Namespace to hold formatters for different types of ticks
+ * @namespace Chart.Ticks.formatters
+ */
+ formatters: {
+ /**
+ * Formatter for value labels
+ * @method Chart.Ticks.formatters.values
+ * @param value the value to display
+ * @return {String|Array} the label to display
+ */
+ values: function(value) {
+ return helpers.isArray(value) ? value : '' + value;
+ },
+
+ /**
+ * Formatter for linear numeric ticks
+ * @method Chart.Ticks.formatters.linear
+ * @param tickValue {Number} the value to be formatted
+ * @param index {Number} the position of the tickValue parameter in the ticks array
+ * @param ticks {Array} the list of ticks being converted
+ * @return {String} string representation of the tickValue parameter
+ */
+ linear: function(tickValue, index, ticks) {
+ // If we have lots of ticks, don't use the ones
+ var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];
+
+ // If we have a number like 2.5 as the delta, figure out how many decimal places we need
+ if (Math.abs(delta) > 1) {
+ if (tickValue !== Math.floor(tickValue)) {
+ // not an integer
+ delta = tickValue - Math.floor(tickValue);
+ }
+ }
+
+ var logDelta = helpers.log10(Math.abs(delta));
+ var tickString = '';
+
+ if (tickValue !== 0) {
+ var numDecimal = -1 * Math.floor(logDelta);
+ numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places
+ tickString = tickValue.toFixed(numDecimal);
+ } else {
+ tickString = '0'; // never show decimal places for 0
+ }
+
+ return tickString;
+ },
+
+ logarithmic: function(tickValue, index, ticks) {
+ var remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue))));
+
+ if (tickValue === 0) {
+ return '0';
+ } else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) {
+ return tickValue.toExponential();
+ }
+ return '';
+ }
+ }
+};
+
+},{"45":45}],35:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+
+defaults._set('global', {
+ tooltips: {
+ enabled: true,
+ custom: null,
+ mode: 'nearest',
+ position: 'average',
+ intersect: true,
+ backgroundColor: 'rgba(0,0,0,0.8)',
+ titleFontStyle: 'bold',
+ titleSpacing: 2,
+ titleMarginBottom: 6,
+ titleFontColor: '#fff',
+ titleAlign: 'left',
+ bodySpacing: 2,
+ bodyFontColor: '#fff',
+ bodyAlign: 'left',
+ footerFontStyle: 'bold',
+ footerSpacing: 2,
+ footerMarginTop: 6,
+ footerFontColor: '#fff',
+ footerAlign: 'left',
+ yPadding: 6,
+ xPadding: 6,
+ caretPadding: 2,
+ caretSize: 5,
+ cornerRadius: 6,
+ multiKeyBackground: '#fff',
+ displayColors: true,
+ borderColor: 'rgba(0,0,0,0)',
+ borderWidth: 0,
+ callbacks: {
+ // Args are: (tooltipItems, data)
+ beforeTitle: helpers.noop,
+ title: function(tooltipItems, data) {
+ // Pick first xLabel for now
+ var title = '';
+ var labels = data.labels;
+ var labelCount = labels ? labels.length : 0;
+
+ if (tooltipItems.length > 0) {
+ var item = tooltipItems[0];
+
+ if (item.xLabel) {
+ title = item.xLabel;
+ } else if (labelCount > 0 && item.index < labelCount) {
+ title = labels[item.index];
+ }
+ }
+
+ return title;
+ },
+ afterTitle: helpers.noop,
+
+ // Args are: (tooltipItems, data)
+ beforeBody: helpers.noop,
+
+ // Args are: (tooltipItem, data)
+ beforeLabel: helpers.noop,
+ label: function(tooltipItem, data) {
+ var label = data.datasets[tooltipItem.datasetIndex].label || '';
+
+ if (label) {
+ label += ': ';
+ }
+ label += tooltipItem.yLabel;
+ return label;
+ },
+ labelColor: function(tooltipItem, chart) {
+ var meta = chart.getDatasetMeta(tooltipItem.datasetIndex);
+ var activeElement = meta.data[tooltipItem.index];
+ var view = activeElement._view;
+ return {
+ borderColor: view.borderColor,
+ backgroundColor: view.backgroundColor
+ };
+ },
+ labelTextColor: function() {
+ return this._options.bodyFontColor;
+ },
+ afterLabel: helpers.noop,
+
+ // Args are: (tooltipItems, data)
+ afterBody: helpers.noop,
+
+ // Args are: (tooltipItems, data)
+ beforeFooter: helpers.noop,
+ footer: helpers.noop,
+ afterFooter: helpers.noop
+ }
+ }
+});
+
+module.exports = function(Chart) {
+
+ /**
+ * Helper method to merge the opacity into a color
+ */
+ function mergeOpacity(colorString, opacity) {
+ var color = helpers.color(colorString);
+ return color.alpha(opacity * color.alpha()).rgbaString();
+ }
+
+ // Helper to push or concat based on if the 2nd parameter is an array or not
+ function pushOrConcat(base, toPush) {
+ if (toPush) {
+ if (helpers.isArray(toPush)) {
+ // base = base.concat(toPush);
+ Array.prototype.push.apply(base, toPush);
+ } else {
+ base.push(toPush);
+ }
+ }
+
+ return base;
+ }
+
+ // Private helper to create a tooltip item model
+ // @param element : the chart element (point, arc, bar) to create the tooltip item for
+ // @return : new tooltip item
+ function createTooltipItem(element) {
+ var xScale = element._xScale;
+ var yScale = element._yScale || element._scale; // handle radar || polarArea charts
+ var index = element._index;
+ var datasetIndex = element._datasetIndex;
+
+ return {
+ xLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',
+ yLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',
+ index: index,
+ datasetIndex: datasetIndex,
+ x: element._model.x,
+ y: element._model.y
+ };
+ }
+
+ /**
+ * Helper to get the reset model for the tooltip
+ * @param tooltipOpts {Object} the tooltip options
+ */
+ function getBaseModel(tooltipOpts) {
+ var globalDefaults = defaults.global;
+ var valueOrDefault = helpers.valueOrDefault;
+
+ return {
+ // Positioning
+ xPadding: tooltipOpts.xPadding,
+ yPadding: tooltipOpts.yPadding,
+ xAlign: tooltipOpts.xAlign,
+ yAlign: tooltipOpts.yAlign,
+
+ // Body
+ bodyFontColor: tooltipOpts.bodyFontColor,
+ _bodyFontFamily: valueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),
+ _bodyFontStyle: valueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),
+ _bodyAlign: tooltipOpts.bodyAlign,
+ bodyFontSize: valueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),
+ bodySpacing: tooltipOpts.bodySpacing,
+
+ // Title
+ titleFontColor: tooltipOpts.titleFontColor,
+ _titleFontFamily: valueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),
+ _titleFontStyle: valueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),
+ titleFontSize: valueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),
+ _titleAlign: tooltipOpts.titleAlign,
+ titleSpacing: tooltipOpts.titleSpacing,
+ titleMarginBottom: tooltipOpts.titleMarginBottom,
+
+ // Footer
+ footerFontColor: tooltipOpts.footerFontColor,
+ _footerFontFamily: valueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),
+ _footerFontStyle: valueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),
+ footerFontSize: valueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),
+ _footerAlign: tooltipOpts.footerAlign,
+ footerSpacing: tooltipOpts.footerSpacing,
+ footerMarginTop: tooltipOpts.footerMarginTop,
+
+ // Appearance
+ caretSize: tooltipOpts.caretSize,
+ cornerRadius: tooltipOpts.cornerRadius,
+ backgroundColor: tooltipOpts.backgroundColor,
+ opacity: 0,
+ legendColorBackground: tooltipOpts.multiKeyBackground,
+ displayColors: tooltipOpts.displayColors,
+ borderColor: tooltipOpts.borderColor,
+ borderWidth: tooltipOpts.borderWidth
+ };
+ }
+
+ /**
+ * Get the size of the tooltip
+ */
+ function getTooltipSize(tooltip, model) {
+ var ctx = tooltip._chart.ctx;
+
+ var height = model.yPadding * 2; // Tooltip Padding
+ var width = 0;
+
+ // Count of all lines in the body
+ var body = model.body;
+ var combinedBodyLength = body.reduce(function(count, bodyItem) {
+ return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;
+ }, 0);
+ combinedBodyLength += model.beforeBody.length + model.afterBody.length;
+
+ var titleLineCount = model.title.length;
+ var footerLineCount = model.footer.length;
+ var titleFontSize = model.titleFontSize;
+ var bodyFontSize = model.bodyFontSize;
+ var footerFontSize = model.footerFontSize;
+
+ height += titleLineCount * titleFontSize; // Title Lines
+ height += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing
+ height += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin
+ height += combinedBodyLength * bodyFontSize; // Body Lines
+ height += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing
+ height += footerLineCount ? model.footerMarginTop : 0; // Footer Margin
+ height += footerLineCount * (footerFontSize); // Footer Lines
+ height += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing
+
+ // Title width
+ var widthPadding = 0;
+ var maxLineWidth = function(line) {
+ width = Math.max(width, ctx.measureText(line).width + widthPadding);
+ };
+
+ ctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily);
+ helpers.each(model.title, maxLineWidth);
+
+ // Body width
+ ctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily);
+ helpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth);
+
+ // Body lines may include some extra width due to the color box
+ widthPadding = model.displayColors ? (bodyFontSize + 2) : 0;
+ helpers.each(body, function(bodyItem) {
+ helpers.each(bodyItem.before, maxLineWidth);
+ helpers.each(bodyItem.lines, maxLineWidth);
+ helpers.each(bodyItem.after, maxLineWidth);
+ });
+
+ // Reset back to 0
+ widthPadding = 0;
+
+ // Footer width
+ ctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily);
+ helpers.each(model.footer, maxLineWidth);
+
+ // Add padding
+ width += 2 * model.xPadding;
+
+ return {
+ width: width,
+ height: height
+ };
+ }
+
+ /**
+ * Helper to get the alignment of a tooltip given the size
+ */
+ function determineAlignment(tooltip, size) {
+ var model = tooltip._model;
+ var chart = tooltip._chart;
+ var chartArea = tooltip._chart.chartArea;
+ var xAlign = 'center';
+ var yAlign = 'center';
+
+ if (model.y < size.height) {
+ yAlign = 'top';
+ } else if (model.y > (chart.height - size.height)) {
+ yAlign = 'bottom';
+ }
+
+ var lf, rf; // functions to determine left, right alignment
+ var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart
+ var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges
+ var midX = (chartArea.left + chartArea.right) / 2;
+ var midY = (chartArea.top + chartArea.bottom) / 2;
+
+ if (yAlign === 'center') {
+ lf = function(x) {
+ return x <= midX;
+ };
+ rf = function(x) {
+ return x > midX;
+ };
+ } else {
+ lf = function(x) {
+ return x <= (size.width / 2);
+ };
+ rf = function(x) {
+ return x >= (chart.width - (size.width / 2));
+ };
+ }
+
+ olf = function(x) {
+ return x + size.width + model.caretSize + model.caretPadding > chart.width;
+ };
+ orf = function(x) {
+ return x - size.width - model.caretSize - model.caretPadding < 0;
+ };
+ yf = function(y) {
+ return y <= midY ? 'top' : 'bottom';
+ };
+
+ if (lf(model.x)) {
+ xAlign = 'left';
+
+ // Is tooltip too wide and goes over the right side of the chart.?
+ if (olf(model.x)) {
+ xAlign = 'center';
+ yAlign = yf(model.y);
+ }
+ } else if (rf(model.x)) {
+ xAlign = 'right';
+
+ // Is tooltip too wide and goes outside left edge of canvas?
+ if (orf(model.x)) {
+ xAlign = 'center';
+ yAlign = yf(model.y);
+ }
+ }
+
+ var opts = tooltip._options;
+ return {
+ xAlign: opts.xAlign ? opts.xAlign : xAlign,
+ yAlign: opts.yAlign ? opts.yAlign : yAlign
+ };
+ }
+
+ /**
+ * @Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment
+ */
+ function getBackgroundPoint(vm, size, alignment, chart) {
+ // Background Position
+ var x = vm.x;
+ var y = vm.y;
+
+ var caretSize = vm.caretSize;
+ var caretPadding = vm.caretPadding;
+ var cornerRadius = vm.cornerRadius;
+ var xAlign = alignment.xAlign;
+ var yAlign = alignment.yAlign;
+ var paddingAndSize = caretSize + caretPadding;
+ var radiusAndPadding = cornerRadius + caretPadding;
+
+ if (xAlign === 'right') {
+ x -= size.width;
+ } else if (xAlign === 'center') {
+ x -= (size.width / 2);
+ if (x + size.width > chart.width) {
+ x = chart.width - size.width;
+ }
+ if (x < 0) {
+ x = 0;
+ }
+ }
+
+ if (yAlign === 'top') {
+ y += paddingAndSize;
+ } else if (yAlign === 'bottom') {
+ y -= size.height + paddingAndSize;
+ } else {
+ y -= (size.height / 2);
+ }
+
+ if (yAlign === 'center') {
+ if (xAlign === 'left') {
+ x += paddingAndSize;
+ } else if (xAlign === 'right') {
+ x -= paddingAndSize;
+ }
+ } else if (xAlign === 'left') {
+ x -= radiusAndPadding;
+ } else if (xAlign === 'right') {
+ x += radiusAndPadding;
+ }
+
+ return {
+ x: x,
+ y: y
+ };
+ }
+
+ Chart.Tooltip = Element.extend({
+ initialize: function() {
+ this._model = getBaseModel(this._options);
+ this._lastActive = [];
+ },
+
+ // Get the title
+ // Args are: (tooltipItem, data)
+ getTitle: function() {
+ var me = this;
+ var opts = me._options;
+ var callbacks = opts.callbacks;
+
+ var beforeTitle = callbacks.beforeTitle.apply(me, arguments);
+ var title = callbacks.title.apply(me, arguments);
+ var afterTitle = callbacks.afterTitle.apply(me, arguments);
+
+ var lines = [];
+ lines = pushOrConcat(lines, beforeTitle);
+ lines = pushOrConcat(lines, title);
+ lines = pushOrConcat(lines, afterTitle);
+
+ return lines;
+ },
+
+ // Args are: (tooltipItem, data)
+ getBeforeBody: function() {
+ var lines = this._options.callbacks.beforeBody.apply(this, arguments);
+ return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
+ },
+
+ // Args are: (tooltipItem, data)
+ getBody: function(tooltipItems, data) {
+ var me = this;
+ var callbacks = me._options.callbacks;
+ var bodyItems = [];
+
+ helpers.each(tooltipItems, function(tooltipItem) {
+ var bodyItem = {
+ before: [],
+ lines: [],
+ after: []
+ };
+ pushOrConcat(bodyItem.before, callbacks.beforeLabel.call(me, tooltipItem, data));
+ pushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data));
+ pushOrConcat(bodyItem.after, callbacks.afterLabel.call(me, tooltipItem, data));
+
+ bodyItems.push(bodyItem);
+ });
+
+ return bodyItems;
+ },
+
+ // Args are: (tooltipItem, data)
+ getAfterBody: function() {
+ var lines = this._options.callbacks.afterBody.apply(this, arguments);
+ return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
+ },
+
+ // Get the footer and beforeFooter and afterFooter lines
+ // Args are: (tooltipItem, data)
+ getFooter: function() {
+ var me = this;
+ var callbacks = me._options.callbacks;
+
+ var beforeFooter = callbacks.beforeFooter.apply(me, arguments);
+ var footer = callbacks.footer.apply(me, arguments);
+ var afterFooter = callbacks.afterFooter.apply(me, arguments);
+
+ var lines = [];
+ lines = pushOrConcat(lines, beforeFooter);
+ lines = pushOrConcat(lines, footer);
+ lines = pushOrConcat(lines, afterFooter);
+
+ return lines;
+ },
+
+ update: function(changed) {
+ var me = this;
+ var opts = me._options;
+
+ // Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition
+ // that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time
+ // which breaks any animations.
+ var existingModel = me._model;
+ var model = me._model = getBaseModel(opts);
+ var active = me._active;
+
+ var data = me._data;
+
+ // In the case where active.length === 0 we need to keep these at existing values for good animations
+ var alignment = {
+ xAlign: existingModel.xAlign,
+ yAlign: existingModel.yAlign
+ };
+ var backgroundPoint = {
+ x: existingModel.x,
+ y: existingModel.y
+ };
+ var tooltipSize = {
+ width: existingModel.width,
+ height: existingModel.height
+ };
+ var tooltipPosition = {
+ x: existingModel.caretX,
+ y: existingModel.caretY
+ };
+
+ var i, len;
+
+ if (active.length) {
+ model.opacity = 1;
+
+ var labelColors = [];
+ var labelTextColors = [];
+ tooltipPosition = Chart.Tooltip.positioners[opts.position].call(me, active, me._eventPosition);
+
+ var tooltipItems = [];
+ for (i = 0, len = active.length; i < len; ++i) {
+ tooltipItems.push(createTooltipItem(active[i]));
+ }
+
+ // If the user provided a filter function, use it to modify the tooltip items
+ if (opts.filter) {
+ tooltipItems = tooltipItems.filter(function(a) {
+ return opts.filter(a, data);
+ });
+ }
+
+ // If the user provided a sorting function, use it to modify the tooltip items
+ if (opts.itemSort) {
+ tooltipItems = tooltipItems.sort(function(a, b) {
+ return opts.itemSort(a, b, data);
+ });
+ }
+
+ // Determine colors for boxes
+ helpers.each(tooltipItems, function(tooltipItem) {
+ labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, me._chart));
+ labelTextColors.push(opts.callbacks.labelTextColor.call(me, tooltipItem, me._chart));
+ });
+
+
+ // Build the Text Lines
+ model.title = me.getTitle(tooltipItems, data);
+ model.beforeBody = me.getBeforeBody(tooltipItems, data);
+ model.body = me.getBody(tooltipItems, data);
+ model.afterBody = me.getAfterBody(tooltipItems, data);
+ model.footer = me.getFooter(tooltipItems, data);
+
+ // Initial positioning and colors
+ model.x = Math.round(tooltipPosition.x);
+ model.y = Math.round(tooltipPosition.y);
+ model.caretPadding = opts.caretPadding;
+ model.labelColors = labelColors;
+ model.labelTextColors = labelTextColors;
+
+ // data points
+ model.dataPoints = tooltipItems;
+
+ // We need to determine alignment of the tooltip
+ tooltipSize = getTooltipSize(this, model);
+ alignment = determineAlignment(this, tooltipSize);
+ // Final Size and Position
+ backgroundPoint = getBackgroundPoint(model, tooltipSize, alignment, me._chart);
+ } else {
+ model.opacity = 0;
+ }
+
+ model.xAlign = alignment.xAlign;
+ model.yAlign = alignment.yAlign;
+ model.x = backgroundPoint.x;
+ model.y = backgroundPoint.y;
+ model.width = tooltipSize.width;
+ model.height = tooltipSize.height;
+
+ // Point where the caret on the tooltip points to
+ model.caretX = tooltipPosition.x;
+ model.caretY = tooltipPosition.y;
+
+ me._model = model;
+
+ if (changed && opts.custom) {
+ opts.custom.call(me, model);
+ }
+
+ return me;
+ },
+ drawCaret: function(tooltipPoint, size) {
+ var ctx = this._chart.ctx;
+ var vm = this._view;
+ var caretPosition = this.getCaretPosition(tooltipPoint, size, vm);
+
+ ctx.lineTo(caretPosition.x1, caretPosition.y1);
+ ctx.lineTo(caretPosition.x2, caretPosition.y2);
+ ctx.lineTo(caretPosition.x3, caretPosition.y3);
+ },
+ getCaretPosition: function(tooltipPoint, size, vm) {
+ var x1, x2, x3, y1, y2, y3;
+ var caretSize = vm.caretSize;
+ var cornerRadius = vm.cornerRadius;
+ var xAlign = vm.xAlign;
+ var yAlign = vm.yAlign;
+ var ptX = tooltipPoint.x;
+ var ptY = tooltipPoint.y;
+ var width = size.width;
+ var height = size.height;
+
+ if (yAlign === 'center') {
+ y2 = ptY + (height / 2);
+
+ if (xAlign === 'left') {
+ x1 = ptX;
+ x2 = x1 - caretSize;
+ x3 = x1;
+
+ y1 = y2 + caretSize;
+ y3 = y2 - caretSize;
+ } else {
+ x1 = ptX + width;
+ x2 = x1 + caretSize;
+ x3 = x1;
+
+ y1 = y2 - caretSize;
+ y3 = y2 + caretSize;
+ }
+ } else {
+ if (xAlign === 'left') {
+ x2 = ptX + cornerRadius + (caretSize);
+ x1 = x2 - caretSize;
+ x3 = x2 + caretSize;
+ } else if (xAlign === 'right') {
+ x2 = ptX + width - cornerRadius - caretSize;
+ x1 = x2 - caretSize;
+ x3 = x2 + caretSize;
+ } else {
+ x2 = vm.caretX;
+ x1 = x2 - caretSize;
+ x3 = x2 + caretSize;
+ }
+ if (yAlign === 'top') {
+ y1 = ptY;
+ y2 = y1 - caretSize;
+ y3 = y1;
+ } else {
+ y1 = ptY + height;
+ y2 = y1 + caretSize;
+ y3 = y1;
+ // invert drawing order
+ var tmp = x3;
+ x3 = x1;
+ x1 = tmp;
+ }
+ }
+ return {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3};
+ },
+ drawTitle: function(pt, vm, ctx, opacity) {
+ var title = vm.title;
+
+ if (title.length) {
+ ctx.textAlign = vm._titleAlign;
+ ctx.textBaseline = 'top';
+
+ var titleFontSize = vm.titleFontSize;
+ var titleSpacing = vm.titleSpacing;
+
+ ctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);
+ ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
+
+ var i, len;
+ for (i = 0, len = title.length; i < len; ++i) {
+ ctx.fillText(title[i], pt.x, pt.y);
+ pt.y += titleFontSize + titleSpacing; // Line Height and spacing
+
+ if (i + 1 === title.length) {
+ pt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing
+ }
+ }
+ }
+ },
+ drawBody: function(pt, vm, ctx, opacity) {
+ var bodyFontSize = vm.bodyFontSize;
+ var bodySpacing = vm.bodySpacing;
+ var body = vm.body;
+
+ ctx.textAlign = vm._bodyAlign;
+ ctx.textBaseline = 'top';
+ ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
+
+ // Before Body
+ var xLinePadding = 0;
+ var fillLineOfText = function(line) {
+ ctx.fillText(line, pt.x + xLinePadding, pt.y);
+ pt.y += bodyFontSize + bodySpacing;
+ };
+
+ // Before body lines
+ ctx.fillStyle = mergeOpacity(vm.bodyFontColor, opacity);
+ helpers.each(vm.beforeBody, fillLineOfText);
+
+ var drawColorBoxes = vm.displayColors;
+ xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;
+
+ // Draw body lines now
+ helpers.each(body, function(bodyItem, i) {
+ var textColor = mergeOpacity(vm.labelTextColors[i], opacity);
+ ctx.fillStyle = textColor;
+ helpers.each(bodyItem.before, fillLineOfText);
+
+ helpers.each(bodyItem.lines, function(line) {
+ // Draw Legend-like boxes if needed
+ if (drawColorBoxes) {
+ // Fill a white rect so that colours merge nicely if the opacity is < 1
+ ctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity);
+ ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
+
+ // Border
+ ctx.lineWidth = 1;
+ ctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);
+ ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
+
+ // Inner square
+ ctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);
+ ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);
+ ctx.fillStyle = textColor;
+ }
+
+ fillLineOfText(line);
+ });
+
+ helpers.each(bodyItem.after, fillLineOfText);
+ });
+
+ // Reset back to 0 for after body
+ xLinePadding = 0;
+
+ // After body lines
+ helpers.each(vm.afterBody, fillLineOfText);
+ pt.y -= bodySpacing; // Remove last body spacing
+ },
+ drawFooter: function(pt, vm, ctx, opacity) {
+ var footer = vm.footer;
+
+ if (footer.length) {
+ pt.y += vm.footerMarginTop;
+
+ ctx.textAlign = vm._footerAlign;
+ ctx.textBaseline = 'top';
+
+ ctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);
+ ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
+
+ helpers.each(footer, function(line) {
+ ctx.fillText(line, pt.x, pt.y);
+ pt.y += vm.footerFontSize + vm.footerSpacing;
+ });
+ }
+ },
+ drawBackground: function(pt, vm, ctx, tooltipSize, opacity) {
+ ctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity);
+ ctx.strokeStyle = mergeOpacity(vm.borderColor, opacity);
+ ctx.lineWidth = vm.borderWidth;
+ var xAlign = vm.xAlign;
+ var yAlign = vm.yAlign;
+ var x = pt.x;
+ var y = pt.y;
+ var width = tooltipSize.width;
+ var height = tooltipSize.height;
+ var radius = vm.cornerRadius;
+
+ ctx.beginPath();
+ ctx.moveTo(x + radius, y);
+ if (yAlign === 'top') {
+ this.drawCaret(pt, tooltipSize);
+ }
+ ctx.lineTo(x + width - radius, y);
+ ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
+ if (yAlign === 'center' && xAlign === 'right') {
+ this.drawCaret(pt, tooltipSize);
+ }
+ ctx.lineTo(x + width, y + height - radius);
+ ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
+ if (yAlign === 'bottom') {
+ this.drawCaret(pt, tooltipSize);
+ }
+ ctx.lineTo(x + radius, y + height);
+ ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
+ if (yAlign === 'center' && xAlign === 'left') {
+ this.drawCaret(pt, tooltipSize);
+ }
+ ctx.lineTo(x, y + radius);
+ ctx.quadraticCurveTo(x, y, x + radius, y);
+ ctx.closePath();
+
+ ctx.fill();
+
+ if (vm.borderWidth > 0) {
+ ctx.stroke();
+ }
+ },
+ draw: function() {
+ var ctx = this._chart.ctx;
+ var vm = this._view;
+
+ if (vm.opacity === 0) {
+ return;
+ }
+
+ var tooltipSize = {
+ width: vm.width,
+ height: vm.height
+ };
+ var pt = {
+ x: vm.x,
+ y: vm.y
+ };
+
+ // IE11/Edge does not like very small opacities, so snap to 0
+ var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;
+
+ // Truthy/falsey value for empty tooltip
+ var hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;
+
+ if (this._options.enabled && hasTooltipContent) {
+ // Draw Background
+ this.drawBackground(pt, vm, ctx, tooltipSize, opacity);
+
+ // Draw Title, Body, and Footer
+ pt.x += vm.xPadding;
+ pt.y += vm.yPadding;
+
+ // Titles
+ this.drawTitle(pt, vm, ctx, opacity);
+
+ // Body
+ this.drawBody(pt, vm, ctx, opacity);
+
+ // Footer
+ this.drawFooter(pt, vm, ctx, opacity);
+ }
+ },
+
+ /**
+ * Handle an event
+ * @private
+ * @param {IEvent} event - The event to handle
+ * @returns {Boolean} true if the tooltip changed
+ */
+ handleEvent: function(e) {
+ var me = this;
+ var options = me._options;
+ var changed = false;
+
+ me._lastActive = me._lastActive || [];
+
+ // Find Active Elements for tooltips
+ if (e.type === 'mouseout') {
+ me._active = [];
+ } else {
+ me._active = me._chart.getElementsAtEventForMode(e, options.mode, options);
+ }
+
+ // Remember Last Actives
+ changed = !helpers.arrayEquals(me._active, me._lastActive);
+
+ // Only handle target event on tooltip change
+ if (changed) {
+ me._lastActive = me._active;
+
+ if (options.enabled || options.custom) {
+ me._eventPosition = {
+ x: e.x,
+ y: e.y
+ };
+
+ me.update(true);
+ me.pivot();
+ }
+ }
+
+ return changed;
+ }
+ });
+
+ /**
+ * @namespace Chart.Tooltip.positioners
+ */
+ Chart.Tooltip.positioners = {
+ /**
+ * Average mode places the tooltip at the average position of the elements shown
+ * @function Chart.Tooltip.positioners.average
+ * @param elements {ChartElement[]} the elements being displayed in the tooltip
+ * @returns {Point} tooltip position
+ */
+ average: function(elements) {
+ if (!elements.length) {
+ return false;
+ }
+
+ var i, len;
+ var x = 0;
+ var y = 0;
+ var count = 0;
+
+ for (i = 0, len = elements.length; i < len; ++i) {
+ var el = elements[i];
+ if (el && el.hasValue()) {
+ var pos = el.tooltipPosition();
+ x += pos.x;
+ y += pos.y;
+ ++count;
+ }
+ }
+
+ return {
+ x: Math.round(x / count),
+ y: Math.round(y / count)
+ };
+ },
+
+ /**
+ * Gets the tooltip position nearest of the item nearest to the event position
+ * @function Chart.Tooltip.positioners.nearest
+ * @param elements {Chart.Element[]} the tooltip elements
+ * @param eventPosition {Point} the position of the event in canvas coordinates
+ * @returns {Point} the tooltip position
+ */
+ nearest: function(elements, eventPosition) {
+ var x = eventPosition.x;
+ var y = eventPosition.y;
+ var minDistance = Number.POSITIVE_INFINITY;
+ var i, len, nearestElement;
+
+ for (i = 0, len = elements.length; i < len; ++i) {
+ var el = elements[i];
+ if (el && el.hasValue()) {
+ var center = el.getCenterPoint();
+ var d = helpers.distanceBetweenPoints(eventPosition, center);
+
+ if (d < minDistance) {
+ minDistance = d;
+ nearestElement = el;
+ }
+ }
+ }
+
+ if (nearestElement) {
+ var tp = nearestElement.tooltipPosition();
+ x = tp.x;
+ y = tp.y;
+ }
+
+ return {
+ x: x,
+ y: y
+ };
+ }
+ };
+};
+
+},{"25":25,"26":26,"45":45}],36:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+
+defaults._set('global', {
+ elements: {
+ arc: {
+ backgroundColor: defaults.global.defaultColor,
+ borderColor: '#fff',
+ borderWidth: 2
+ }
+ }
+});
+
+module.exports = Element.extend({
+ inLabelRange: function(mouseX) {
+ var vm = this._view;
+
+ if (vm) {
+ return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));
+ }
+ return false;
+ },
+
+ inRange: function(chartX, chartY) {
+ var vm = this._view;
+
+ if (vm) {
+ var pointRelativePosition = helpers.getAngleFromPoint(vm, {x: chartX, y: chartY});
+ var angle = pointRelativePosition.angle;
+ var distance = pointRelativePosition.distance;
+
+ // Sanitise angle range
+ var startAngle = vm.startAngle;
+ var endAngle = vm.endAngle;
+ while (endAngle < startAngle) {
+ endAngle += 2.0 * Math.PI;
+ }
+ while (angle > endAngle) {
+ angle -= 2.0 * Math.PI;
+ }
+ while (angle < startAngle) {
+ angle += 2.0 * Math.PI;
+ }
+
+ // Check if within the range of the open/close angle
+ var betweenAngles = (angle >= startAngle && angle <= endAngle);
+ var withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);
+
+ return (betweenAngles && withinRadius);
+ }
+ return false;
+ },
+
+ getCenterPoint: function() {
+ var vm = this._view;
+ var halfAngle = (vm.startAngle + vm.endAngle) / 2;
+ var halfRadius = (vm.innerRadius + vm.outerRadius) / 2;
+ return {
+ x: vm.x + Math.cos(halfAngle) * halfRadius,
+ y: vm.y + Math.sin(halfAngle) * halfRadius
+ };
+ },
+
+ getArea: function() {
+ var vm = this._view;
+ return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2));
+ },
+
+ tooltipPosition: function() {
+ var vm = this._view;
+ var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2);
+ var rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;
+
+ return {
+ x: vm.x + (Math.cos(centreAngle) * rangeFromCentre),
+ y: vm.y + (Math.sin(centreAngle) * rangeFromCentre)
+ };
+ },
+
+ draw: function() {
+ var ctx = this._chart.ctx;
+ var vm = this._view;
+ var sA = vm.startAngle;
+ var eA = vm.endAngle;
+
+ ctx.beginPath();
+
+ ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);
+ ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);
+
+ ctx.closePath();
+ ctx.strokeStyle = vm.borderColor;
+ ctx.lineWidth = vm.borderWidth;
+
+ ctx.fillStyle = vm.backgroundColor;
+
+ ctx.fill();
+ ctx.lineJoin = 'bevel';
+
+ if (vm.borderWidth) {
+ ctx.stroke();
+ }
+ }
+});
+
+},{"25":25,"26":26,"45":45}],37:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+
+var globalDefaults = defaults.global;
+
+defaults._set('global', {
+ elements: {
+ line: {
+ tension: 0.4,
+ backgroundColor: globalDefaults.defaultColor,
+ borderWidth: 3,
+ borderColor: globalDefaults.defaultColor,
+ borderCapStyle: 'butt',
+ borderDash: [],
+ borderDashOffset: 0.0,
+ borderJoinStyle: 'miter',
+ capBezierPoints: true,
+ fill: true, // do we fill in the area between the line and its base axis
+ }
+ }
+});
+
+module.exports = Element.extend({
+ draw: function() {
+ var me = this;
+ var vm = me._view;
+ var ctx = me._chart.ctx;
+ var spanGaps = vm.spanGaps;
+ var points = me._children.slice(); // clone array
+ var globalOptionLineElements = globalDefaults.elements.line;
+ var lastDrawnIndex = -1;
+ var index, current, previous, currentVM;
+
+ // If we are looping, adding the first point again
+ if (me._loop && points.length) {
+ points.push(points[0]);
+ }
+
+ ctx.save();
+
+ // Stroke Line Options
+ ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;
+
+ // IE 9 and 10 do not support line dash
+ if (ctx.setLineDash) {
+ ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);
+ }
+
+ ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;
+ ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;
+ ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;
+ ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;
+
+ // Stroke Line
+ ctx.beginPath();
+ lastDrawnIndex = -1;
+
+ for (index = 0; index < points.length; ++index) {
+ current = points[index];
+ previous = helpers.previousItem(points, index);
+ currentVM = current._view;
+
+ // First point moves to it's starting position no matter what
+ if (index === 0) {
+ if (!currentVM.skip) {
+ ctx.moveTo(currentVM.x, currentVM.y);
+ lastDrawnIndex = index;
+ }
+ } else {
+ previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];
+
+ if (!currentVM.skip) {
+ if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {
+ // There was a gap and this is the first point after the gap
+ ctx.moveTo(currentVM.x, currentVM.y);
+ } else {
+ // Line to next point
+ helpers.canvas.lineTo(ctx, previous._view, current._view);
+ }
+ lastDrawnIndex = index;
+ }
+ }
+ }
+
+ ctx.stroke();
+ ctx.restore();
+ }
+});
+
+},{"25":25,"26":26,"45":45}],38:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+
+var defaultColor = defaults.global.defaultColor;
+
+defaults._set('global', {
+ elements: {
+ point: {
+ radius: 3,
+ pointStyle: 'circle',
+ backgroundColor: defaultColor,
+ borderColor: defaultColor,
+ borderWidth: 1,
+ // Hover
+ hitRadius: 1,
+ hoverRadius: 4,
+ hoverBorderWidth: 1
+ }
+ }
+});
+
+function xRange(mouseX) {
+ var vm = this._view;
+ return vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false;
+}
+
+function yRange(mouseY) {
+ var vm = this._view;
+ return vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false;
+}
+
+module.exports = Element.extend({
+ inRange: function(mouseX, mouseY) {
+ var vm = this._view;
+ return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;
+ },
+
+ inLabelRange: xRange,
+ inXRange: xRange,
+ inYRange: yRange,
+
+ getCenterPoint: function() {
+ var vm = this._view;
+ return {
+ x: vm.x,
+ y: vm.y
+ };
+ },
+
+ getArea: function() {
+ return Math.PI * Math.pow(this._view.radius, 2);
+ },
+
+ tooltipPosition: function() {
+ var vm = this._view;
+ return {
+ x: vm.x,
+ y: vm.y,
+ padding: vm.radius + vm.borderWidth
+ };
+ },
+
+ draw: function(chartArea) {
+ var vm = this._view;
+ var model = this._model;
+ var ctx = this._chart.ctx;
+ var pointStyle = vm.pointStyle;
+ var radius = vm.radius;
+ var x = vm.x;
+ var y = vm.y;
+ var color = helpers.color;
+ var errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.)
+ var ratio = 0;
+
+ if (vm.skip) {
+ return;
+ }
+
+ ctx.strokeStyle = vm.borderColor || defaultColor;
+ ctx.lineWidth = helpers.valueOrDefault(vm.borderWidth, defaults.global.elements.point.borderWidth);
+ ctx.fillStyle = vm.backgroundColor || defaultColor;
+
+ // Cliping for Points.
+ // going out from inner charArea?
+ if ((chartArea !== undefined) && ((model.x < chartArea.left) || (chartArea.right * errMargin < model.x) || (model.y < chartArea.top) || (chartArea.bottom * errMargin < model.y))) {
+ // Point fade out
+ if (model.x < chartArea.left) {
+ ratio = (x - model.x) / (chartArea.left - model.x);
+ } else if (chartArea.right * errMargin < model.x) {
+ ratio = (model.x - x) / (model.x - chartArea.right);
+ } else if (model.y < chartArea.top) {
+ ratio = (y - model.y) / (chartArea.top - model.y);
+ } else if (chartArea.bottom * errMargin < model.y) {
+ ratio = (model.y - y) / (model.y - chartArea.bottom);
+ }
+ ratio = Math.round(ratio * 100) / 100;
+ ctx.strokeStyle = color(ctx.strokeStyle).alpha(ratio).rgbString();
+ ctx.fillStyle = color(ctx.fillStyle).alpha(ratio).rgbString();
+ }
+
+ helpers.canvas.drawPoint(ctx, pointStyle, radius, x, y);
+ }
+});
+
+},{"25":25,"26":26,"45":45}],39:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+
+defaults._set('global', {
+ elements: {
+ rectangle: {
+ backgroundColor: defaults.global.defaultColor,
+ borderColor: defaults.global.defaultColor,
+ borderSkipped: 'bottom',
+ borderWidth: 0
+ }
+ }
+});
+
+function isVertical(bar) {
+ return bar._view.width !== undefined;
+}
+
+/**
+ * Helper function to get the bounds of the bar regardless of the orientation
+ * @param bar {Chart.Element.Rectangle} the bar
+ * @return {Bounds} bounds of the bar
+ * @private
+ */
+function getBarBounds(bar) {
+ var vm = bar._view;
+ var x1, x2, y1, y2;
+
+ if (isVertical(bar)) {
+ // vertical
+ var halfWidth = vm.width / 2;
+ x1 = vm.x - halfWidth;
+ x2 = vm.x + halfWidth;
+ y1 = Math.min(vm.y, vm.base);
+ y2 = Math.max(vm.y, vm.base);
+ } else {
+ // horizontal bar
+ var halfHeight = vm.height / 2;
+ x1 = Math.min(vm.x, vm.base);
+ x2 = Math.max(vm.x, vm.base);
+ y1 = vm.y - halfHeight;
+ y2 = vm.y + halfHeight;
+ }
+
+ return {
+ left: x1,
+ top: y1,
+ right: x2,
+ bottom: y2
+ };
+}
+
+module.exports = Element.extend({
+ draw: function() {
+ var ctx = this._chart.ctx;
+ var vm = this._view;
+ var left, right, top, bottom, signX, signY, borderSkipped;
+ var borderWidth = vm.borderWidth;
+
+ if (!vm.horizontal) {
+ // bar
+ left = vm.x - vm.width / 2;
+ right = vm.x + vm.width / 2;
+ top = vm.y;
+ bottom = vm.base;
+ signX = 1;
+ signY = bottom > top ? 1 : -1;
+ borderSkipped = vm.borderSkipped || 'bottom';
+ } else {
+ // horizontal bar
+ left = vm.base;
+ right = vm.x;
+ top = vm.y - vm.height / 2;
+ bottom = vm.y + vm.height / 2;
+ signX = right > left ? 1 : -1;
+ signY = 1;
+ borderSkipped = vm.borderSkipped || 'left';
+ }
+
+ // Canvas doesn't allow us to stroke inside the width so we can
+ // adjust the sizes to fit if we're setting a stroke on the line
+ if (borderWidth) {
+ // borderWidth shold be less than bar width and bar height.
+ var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
+ borderWidth = borderWidth > barSize ? barSize : borderWidth;
+ var halfStroke = borderWidth / 2;
+ // Adjust borderWidth when bar top position is near vm.base(zero).
+ var borderLeft = left + (borderSkipped !== 'left' ? halfStroke * signX : 0);
+ var borderRight = right + (borderSkipped !== 'right' ? -halfStroke * signX : 0);
+ var borderTop = top + (borderSkipped !== 'top' ? halfStroke * signY : 0);
+ var borderBottom = bottom + (borderSkipped !== 'bottom' ? -halfStroke * signY : 0);
+ // not become a vertical line?
+ if (borderLeft !== borderRight) {
+ top = borderTop;
+ bottom = borderBottom;
+ }
+ // not become a horizontal line?
+ if (borderTop !== borderBottom) {
+ left = borderLeft;
+ right = borderRight;
+ }
+ }
+
+ ctx.beginPath();
+ ctx.fillStyle = vm.backgroundColor;
+ ctx.strokeStyle = vm.borderColor;
+ ctx.lineWidth = borderWidth;
+
+ // Corner points, from bottom-left to bottom-right clockwise
+ // | 1 2 |
+ // | 0 3 |
+ var corners = [
+ [left, bottom],
+ [left, top],
+ [right, top],
+ [right, bottom]
+ ];
+
+ // Find first (starting) corner with fallback to 'bottom'
+ var borders = ['bottom', 'left', 'top', 'right'];
+ var startCorner = borders.indexOf(borderSkipped, 0);
+ if (startCorner === -1) {
+ startCorner = 0;
+ }
+
+ function cornerAt(index) {
+ return corners[(startCorner + index) % 4];
+ }
+
+ // Draw rectangle from 'startCorner'
+ var corner = cornerAt(0);
+ ctx.moveTo(corner[0], corner[1]);
+
+ for (var i = 1; i < 4; i++) {
+ corner = cornerAt(i);
+ ctx.lineTo(corner[0], corner[1]);
+ }
+
+ ctx.fill();
+ if (borderWidth) {
+ ctx.stroke();
+ }
+ },
+
+ height: function() {
+ var vm = this._view;
+ return vm.base - vm.y;
+ },
+
+ inRange: function(mouseX, mouseY) {
+ var inRange = false;
+
+ if (this._view) {
+ var bounds = getBarBounds(this);
+ inRange = mouseX >= bounds.left && mouseX <= bounds.right && mouseY >= bounds.top && mouseY <= bounds.bottom;
+ }
+
+ return inRange;
+ },
+
+ inLabelRange: function(mouseX, mouseY) {
+ var me = this;
+ if (!me._view) {
+ return false;
+ }
+
+ var inRange = false;
+ var bounds = getBarBounds(me);
+
+ if (isVertical(me)) {
+ inRange = mouseX >= bounds.left && mouseX <= bounds.right;
+ } else {
+ inRange = mouseY >= bounds.top && mouseY <= bounds.bottom;
+ }
+
+ return inRange;
+ },
+
+ inXRange: function(mouseX) {
+ var bounds = getBarBounds(this);
+ return mouseX >= bounds.left && mouseX <= bounds.right;
+ },
+
+ inYRange: function(mouseY) {
+ var bounds = getBarBounds(this);
+ return mouseY >= bounds.top && mouseY <= bounds.bottom;
+ },
+
+ getCenterPoint: function() {
+ var vm = this._view;
+ var x, y;
+ if (isVertical(this)) {
+ x = vm.x;
+ y = (vm.y + vm.base) / 2;
+ } else {
+ x = (vm.x + vm.base) / 2;
+ y = vm.y;
+ }
+
+ return {x: x, y: y};
+ },
+
+ getArea: function() {
+ var vm = this._view;
+ return vm.width * Math.abs(vm.y - vm.base);
+ },
+
+ tooltipPosition: function() {
+ var vm = this._view;
+ return {
+ x: vm.x,
+ y: vm.y
+ };
+ }
+});
+
+},{"25":25,"26":26}],40:[function(require,module,exports){
+'use strict';
+
+module.exports = {};
+module.exports.Arc = require(36);
+module.exports.Line = require(37);
+module.exports.Point = require(38);
+module.exports.Rectangle = require(39);
+
+},{"36":36,"37":37,"38":38,"39":39}],41:[function(require,module,exports){
+'use strict';
+
+var helpers = require(42);
+
+/**
+ * @namespace Chart.helpers.canvas
+ */
+var exports = module.exports = {
+ /**
+ * Clears the entire canvas associated to the given `chart`.
+ * @param {Chart} chart - The chart for which to clear the canvas.
+ */
+ clear: function(chart) {
+ chart.ctx.clearRect(0, 0, chart.width, chart.height);
+ },
+
+ /**
+ * Creates a "path" for a rectangle with rounded corners at position (x, y) with a
+ * given size (width, height) and the same `radius` for all corners.
+ * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context.
+ * @param {Number} x - The x axis of the coordinate for the rectangle starting point.
+ * @param {Number} y - The y axis of the coordinate for the rectangle starting point.
+ * @param {Number} width - The rectangle's width.
+ * @param {Number} height - The rectangle's height.
+ * @param {Number} radius - The rounded amount (in pixels) for the four corners.
+ * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object?
+ */
+ roundedRect: function(ctx, x, y, width, height, radius) {
+ if (radius) {
+ var rx = Math.min(radius, width / 2);
+ var ry = Math.min(radius, height / 2);
+
+ ctx.moveTo(x + rx, y);
+ ctx.lineTo(x + width - rx, y);
+ ctx.quadraticCurveTo(x + width, y, x + width, y + ry);
+ ctx.lineTo(x + width, y + height - ry);
+ ctx.quadraticCurveTo(x + width, y + height, x + width - rx, y + height);
+ ctx.lineTo(x + rx, y + height);
+ ctx.quadraticCurveTo(x, y + height, x, y + height - ry);
+ ctx.lineTo(x, y + ry);
+ ctx.quadraticCurveTo(x, y, x + rx, y);
+ } else {
+ ctx.rect(x, y, width, height);
+ }
+ },
+
+ drawPoint: function(ctx, style, radius, x, y) {
+ var type, edgeLength, xOffset, yOffset, height, size;
+
+ if (style && typeof style === 'object') {
+ type = style.toString();
+ if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
+ ctx.drawImage(style, x - style.width / 2, y - style.height / 2, style.width, style.height);
+ return;
+ }
+ }
+
+ if (isNaN(radius) || radius <= 0) {
+ return;
+ }
+
+ switch (style) {
+ // Default includes circle
+ default:
+ ctx.beginPath();
+ ctx.arc(x, y, radius, 0, Math.PI * 2);
+ ctx.closePath();
+ ctx.fill();
+ break;
+ case 'triangle':
+ ctx.beginPath();
+ edgeLength = 3 * radius / Math.sqrt(3);
+ height = edgeLength * Math.sqrt(3) / 2;
+ ctx.moveTo(x - edgeLength / 2, y + height / 3);
+ ctx.lineTo(x + edgeLength / 2, y + height / 3);
+ ctx.lineTo(x, y - 2 * height / 3);
+ ctx.closePath();
+ ctx.fill();
+ break;
+ case 'rect':
+ size = 1 / Math.SQRT2 * radius;
+ ctx.beginPath();
+ ctx.fillRect(x - size, y - size, 2 * size, 2 * size);
+ ctx.strokeRect(x - size, y - size, 2 * size, 2 * size);
+ break;
+ case 'rectRounded':
+ var offset = radius / Math.SQRT2;
+ var leftX = x - offset;
+ var topY = y - offset;
+ var sideSize = Math.SQRT2 * radius;
+ ctx.beginPath();
+ this.roundedRect(ctx, leftX, topY, sideSize, sideSize, radius / 2);
+ ctx.closePath();
+ ctx.fill();
+ break;
+ case 'rectRot':
+ size = 1 / Math.SQRT2 * radius;
+ ctx.beginPath();
+ ctx.moveTo(x - size, y);
+ ctx.lineTo(x, y + size);
+ ctx.lineTo(x + size, y);
+ ctx.lineTo(x, y - size);
+ ctx.closePath();
+ ctx.fill();
+ break;
+ case 'cross':
+ ctx.beginPath();
+ ctx.moveTo(x, y + radius);
+ ctx.lineTo(x, y - radius);
+ ctx.moveTo(x - radius, y);
+ ctx.lineTo(x + radius, y);
+ ctx.closePath();
+ break;
+ case 'crossRot':
+ ctx.beginPath();
+ xOffset = Math.cos(Math.PI / 4) * radius;
+ yOffset = Math.sin(Math.PI / 4) * radius;
+ ctx.moveTo(x - xOffset, y - yOffset);
+ ctx.lineTo(x + xOffset, y + yOffset);
+ ctx.moveTo(x - xOffset, y + yOffset);
+ ctx.lineTo(x + xOffset, y - yOffset);
+ ctx.closePath();
+ break;
+ case 'star':
+ ctx.beginPath();
+ ctx.moveTo(x, y + radius);
+ ctx.lineTo(x, y - radius);
+ ctx.moveTo(x - radius, y);
+ ctx.lineTo(x + radius, y);
+ xOffset = Math.cos(Math.PI / 4) * radius;
+ yOffset = Math.sin(Math.PI / 4) * radius;
+ ctx.moveTo(x - xOffset, y - yOffset);
+ ctx.lineTo(x + xOffset, y + yOffset);
+ ctx.moveTo(x - xOffset, y + yOffset);
+ ctx.lineTo(x + xOffset, y - yOffset);
+ ctx.closePath();
+ break;
+ case 'line':
+ ctx.beginPath();
+ ctx.moveTo(x - radius, y);
+ ctx.lineTo(x + radius, y);
+ ctx.closePath();
+ break;
+ case 'dash':
+ ctx.beginPath();
+ ctx.moveTo(x, y);
+ ctx.lineTo(x + radius, y);
+ ctx.closePath();
+ break;
+ }
+
+ ctx.stroke();
+ },
+
+ clipArea: function(ctx, area) {
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);
+ ctx.clip();
+ },
+
+ unclipArea: function(ctx) {
+ ctx.restore();
+ },
+
+ lineTo: function(ctx, previous, target, flip) {
+ if (target.steppedLine) {
+ if ((target.steppedLine === 'after' && !flip) || (target.steppedLine !== 'after' && flip)) {
+ ctx.lineTo(previous.x, target.y);
+ } else {
+ ctx.lineTo(target.x, previous.y);
+ }
+ ctx.lineTo(target.x, target.y);
+ return;
+ }
+
+ if (!target.tension) {
+ ctx.lineTo(target.x, target.y);
+ return;
+ }
+
+ ctx.bezierCurveTo(
+ flip ? previous.controlPointPreviousX : previous.controlPointNextX,
+ flip ? previous.controlPointPreviousY : previous.controlPointNextY,
+ flip ? target.controlPointNextX : target.controlPointPreviousX,
+ flip ? target.controlPointNextY : target.controlPointPreviousY,
+ target.x,
+ target.y);
+ }
+};
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.canvas.clear instead.
+ * @namespace Chart.helpers.clear
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.clear = exports.clear;
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead.
+ * @namespace Chart.helpers.drawRoundedRectangle
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.drawRoundedRectangle = function(ctx) {
+ ctx.beginPath();
+ exports.roundedRect.apply(exports, arguments);
+ ctx.closePath();
+};
+
+},{"42":42}],42:[function(require,module,exports){
+'use strict';
+
+/**
+ * @namespace Chart.helpers
+ */
+var helpers = {
+ /**
+ * An empty function that can be used, for example, for optional callback.
+ */
+ noop: function() {},
+
+ /**
+ * Returns a unique id, sequentially generated from a global variable.
+ * @returns {Number}
+ * @function
+ */
+ uid: (function() {
+ var id = 0;
+ return function() {
+ return id++;
+ };
+ }()),
+
+ /**
+ * Returns true if `value` is neither null nor undefined, else returns false.
+ * @param {*} value - The value to test.
+ * @returns {Boolean}
+ * @since 2.7.0
+ */
+ isNullOrUndef: function(value) {
+ return value === null || typeof value === 'undefined';
+ },
+
+ /**
+ * Returns true if `value` is an array, else returns false.
+ * @param {*} value - The value to test.
+ * @returns {Boolean}
+ * @function
+ */
+ isArray: Array.isArray ? Array.isArray : function(value) {
+ return Object.prototype.toString.call(value) === '[object Array]';
+ },
+
+ /**
+ * Returns true if `value` is an object (excluding null), else returns false.
+ * @param {*} value - The value to test.
+ * @returns {Boolean}
+ * @since 2.7.0
+ */
+ isObject: function(value) {
+ return value !== null && Object.prototype.toString.call(value) === '[object Object]';
+ },
+
+ /**
+ * Returns `value` if defined, else returns `defaultValue`.
+ * @param {*} value - The value to return if defined.
+ * @param {*} defaultValue - The value to return if `value` is undefined.
+ * @returns {*}
+ */
+ valueOrDefault: function(value, defaultValue) {
+ return typeof value === 'undefined' ? defaultValue : value;
+ },
+
+ /**
+ * Returns value at the given `index` in array if defined, else returns `defaultValue`.
+ * @param {Array} value - The array to lookup for value at `index`.
+ * @param {Number} index - The index in `value` to lookup for value.
+ * @param {*} defaultValue - The value to return if `value[index]` is undefined.
+ * @returns {*}
+ */
+ valueAtIndexOrDefault: function(value, index, defaultValue) {
+ return helpers.valueOrDefault(helpers.isArray(value) ? value[index] : value, defaultValue);
+ },
+
+ /**
+ * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the
+ * value returned by `fn`. If `fn` is not a function, this method returns undefined.
+ * @param {Function} fn - The function to call.
+ * @param {Array|undefined|null} args - The arguments with which `fn` should be called.
+ * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`.
+ * @returns {*}
+ */
+ callback: function(fn, args, thisArg) {
+ if (fn && typeof fn.call === 'function') {
+ return fn.apply(thisArg, args);
+ }
+ },
+
+ /**
+ * Note(SB) for performance sake, this method should only be used when loopable type
+ * is unknown or in none intensive code (not called often and small loopable). Else
+ * it's preferable to use a regular for() loop and save extra function calls.
+ * @param {Object|Array} loopable - The object or array to be iterated.
+ * @param {Function} fn - The function to call for each item.
+ * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`.
+ * @param {Boolean} [reverse] - If true, iterates backward on the loopable.
+ */
+ each: function(loopable, fn, thisArg, reverse) {
+ var i, len, keys;
+ if (helpers.isArray(loopable)) {
+ len = loopable.length;
+ if (reverse) {
+ for (i = len - 1; i >= 0; i--) {
+ fn.call(thisArg, loopable[i], i);
+ }
+ } else {
+ for (i = 0; i < len; i++) {
+ fn.call(thisArg, loopable[i], i);
+ }
+ }
+ } else if (helpers.isObject(loopable)) {
+ keys = Object.keys(loopable);
+ len = keys.length;
+ for (i = 0; i < len; i++) {
+ fn.call(thisArg, loopable[keys[i]], keys[i]);
+ }
+ }
+ },
+
+ /**
+ * Returns true if the `a0` and `a1` arrays have the same content, else returns false.
+ * @see http://stackoverflow.com/a/14853974
+ * @param {Array} a0 - The array to compare
+ * @param {Array} a1 - The array to compare
+ * @returns {Boolean}
+ */
+ arrayEquals: function(a0, a1) {
+ var i, ilen, v0, v1;
+
+ if (!a0 || !a1 || a0.length !== a1.length) {
+ return false;
+ }
+
+ for (i = 0, ilen = a0.length; i < ilen; ++i) {
+ v0 = a0[i];
+ v1 = a1[i];
+
+ if (v0 instanceof Array && v1 instanceof Array) {
+ if (!helpers.arrayEquals(v0, v1)) {
+ return false;
+ }
+ } else if (v0 !== v1) {
+ // NOTE: two different object instances will never be equal: {x:20} != {x:20}
+ return false;
+ }
+ }
+
+ return true;
+ },
+
+ /**
+ * Returns a deep copy of `source` without keeping references on objects and arrays.
+ * @param {*} source - The value to clone.
+ * @returns {*}
+ */
+ clone: function(source) {
+ if (helpers.isArray(source)) {
+ return source.map(helpers.clone);
+ }
+
+ if (helpers.isObject(source)) {
+ var target = {};
+ var keys = Object.keys(source);
+ var klen = keys.length;
+ var k = 0;
+
+ for (; k < klen; ++k) {
+ target[keys[k]] = helpers.clone(source[keys[k]]);
+ }
+
+ return target;
+ }
+
+ return source;
+ },
+
+ /**
+ * The default merger when Chart.helpers.merge is called without merger option.
+ * Note(SB): this method is also used by configMerge and scaleMerge as fallback.
+ * @private
+ */
+ _merger: function(key, target, source, options) {
+ var tval = target[key];
+ var sval = source[key];
+
+ if (helpers.isObject(tval) && helpers.isObject(sval)) {
+ helpers.merge(tval, sval, options);
+ } else {
+ target[key] = helpers.clone(sval);
+ }
+ },
+
+ /**
+ * Merges source[key] in target[key] only if target[key] is undefined.
+ * @private
+ */
+ _mergerIf: function(key, target, source) {
+ var tval = target[key];
+ var sval = source[key];
+
+ if (helpers.isObject(tval) && helpers.isObject(sval)) {
+ helpers.mergeIf(tval, sval);
+ } else if (!target.hasOwnProperty(key)) {
+ target[key] = helpers.clone(sval);
+ }
+ },
+
+ /**
+ * Recursively deep copies `source` properties into `target` with the given `options`.
+ * IMPORTANT: `target` is not cloned and will be updated with `source` properties.
+ * @param {Object} target - The target object in which all sources are merged into.
+ * @param {Object|Array(Object)} source - Object(s) to merge into `target`.
+ * @param {Object} [options] - Merging options:
+ * @param {Function} [options.merger] - The merge method (key, target, source, options)
+ * @returns {Object} The `target` object.
+ */
+ merge: function(target, source, options) {
+ var sources = helpers.isArray(source) ? source : [source];
+ var ilen = sources.length;
+ var merge, i, keys, klen, k;
+
+ if (!helpers.isObject(target)) {
+ return target;
+ }
+
+ options = options || {};
+ merge = options.merger || helpers._merger;
+
+ for (i = 0; i < ilen; ++i) {
+ source = sources[i];
+ if (!helpers.isObject(source)) {
+ continue;
+ }
+
+ keys = Object.keys(source);
+ for (k = 0, klen = keys.length; k < klen; ++k) {
+ merge(keys[k], target, source, options);
+ }
+ }
+
+ return target;
+ },
+
+ /**
+ * Recursively deep copies `source` properties into `target` *only* if not defined in target.
+ * IMPORTANT: `target` is not cloned and will be updated with `source` properties.
+ * @param {Object} target - The target object in which all sources are merged into.
+ * @param {Object|Array(Object)} source - Object(s) to merge into `target`.
+ * @returns {Object} The `target` object.
+ */
+ mergeIf: function(target, source) {
+ return helpers.merge(target, source, {merger: helpers._mergerIf});
+ },
+
+ /**
+ * Applies the contents of two or more objects together into the first object.
+ * @param {Object} target - The target object in which all objects are merged into.
+ * @param {Object} arg1 - Object containing additional properties to merge in target.
+ * @param {Object} argN - Additional objects containing properties to merge in target.
+ * @returns {Object} The `target` object.
+ */
+ extend: function(target) {
+ var setFn = function(value, key) {
+ target[key] = value;
+ };
+ for (var i = 1, ilen = arguments.length; i < ilen; ++i) {
+ helpers.each(arguments[i], setFn);
+ }
+ return target;
+ },
+
+ /**
+ * Basic javascript inheritance based on the model created in Backbone.js
+ */
+ inherits: function(extensions) {
+ var me = this;
+ var ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() {
+ return me.apply(this, arguments);
+ };
+
+ var Surrogate = function() {
+ this.constructor = ChartElement;
+ };
+
+ Surrogate.prototype = me.prototype;
+ ChartElement.prototype = new Surrogate();
+ ChartElement.extend = helpers.inherits;
+
+ if (extensions) {
+ helpers.extend(ChartElement.prototype, extensions);
+ }
+
+ ChartElement.__super__ = me.prototype;
+ return ChartElement;
+ }
+};
+
+module.exports = helpers;
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.callback instead.
+ * @function Chart.helpers.callCallback
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.callCallback = helpers.callback;
+
+/**
+ * Provided for backward compatibility, use Array.prototype.indexOf instead.
+ * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+
+ * @function Chart.helpers.indexOf
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.indexOf = function(array, item, fromIndex) {
+ return Array.prototype.indexOf.call(array, item, fromIndex);
+};
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead.
+ * @function Chart.helpers.getValueOrDefault
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.getValueOrDefault = helpers.valueOrDefault;
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead.
+ * @function Chart.helpers.getValueAtIndexOrDefault
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
+
+},{}],43:[function(require,module,exports){
+'use strict';
+
+var helpers = require(42);
+
+/**
+ * Easing functions adapted from Robert Penner's easing equations.
+ * @namespace Chart.helpers.easingEffects
+ * @see http://www.robertpenner.com/easing/
+ */
+var effects = {
+ linear: function(t) {
+ return t;
+ },
+
+ easeInQuad: function(t) {
+ return t * t;
+ },
+
+ easeOutQuad: function(t) {
+ return -t * (t - 2);
+ },
+
+ easeInOutQuad: function(t) {
+ if ((t /= 0.5) < 1) {
+ return 0.5 * t * t;
+ }
+ return -0.5 * ((--t) * (t - 2) - 1);
+ },
+
+ easeInCubic: function(t) {
+ return t * t * t;
+ },
+
+ easeOutCubic: function(t) {
+ return (t = t - 1) * t * t + 1;
+ },
+
+ easeInOutCubic: function(t) {
+ if ((t /= 0.5) < 1) {
+ return 0.5 * t * t * t;
+ }
+ return 0.5 * ((t -= 2) * t * t + 2);
+ },
+
+ easeInQuart: function(t) {
+ return t * t * t * t;
+ },
+
+ easeOutQuart: function(t) {
+ return -((t = t - 1) * t * t * t - 1);
+ },
+
+ easeInOutQuart: function(t) {
+ if ((t /= 0.5) < 1) {
+ return 0.5 * t * t * t * t;
+ }
+ return -0.5 * ((t -= 2) * t * t * t - 2);
+ },
+
+ easeInQuint: function(t) {
+ return t * t * t * t * t;
+ },
+
+ easeOutQuint: function(t) {
+ return (t = t - 1) * t * t * t * t + 1;
+ },
+
+ easeInOutQuint: function(t) {
+ if ((t /= 0.5) < 1) {
+ return 0.5 * t * t * t * t * t;
+ }
+ return 0.5 * ((t -= 2) * t * t * t * t + 2);
+ },
+
+ easeInSine: function(t) {
+ return -Math.cos(t * (Math.PI / 2)) + 1;
+ },
+
+ easeOutSine: function(t) {
+ return Math.sin(t * (Math.PI / 2));
+ },
+
+ easeInOutSine: function(t) {
+ return -0.5 * (Math.cos(Math.PI * t) - 1);
+ },
+
+ easeInExpo: function(t) {
+ return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1));
+ },
+
+ easeOutExpo: function(t) {
+ return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1;
+ },
+
+ easeInOutExpo: function(t) {
+ if (t === 0) {
+ return 0;
+ }
+ if (t === 1) {
+ return 1;
+ }
+ if ((t /= 0.5) < 1) {
+ return 0.5 * Math.pow(2, 10 * (t - 1));
+ }
+ return 0.5 * (-Math.pow(2, -10 * --t) + 2);
+ },
+
+ easeInCirc: function(t) {
+ if (t >= 1) {
+ return t;
+ }
+ return -(Math.sqrt(1 - t * t) - 1);
+ },
+
+ easeOutCirc: function(t) {
+ return Math.sqrt(1 - (t = t - 1) * t);
+ },
+
+ easeInOutCirc: function(t) {
+ if ((t /= 0.5) < 1) {
+ return -0.5 * (Math.sqrt(1 - t * t) - 1);
+ }
+ return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1);
+ },
+
+ easeInElastic: function(t) {
+ var s = 1.70158;
+ var p = 0;
+ var a = 1;
+ if (t === 0) {
+ return 0;
+ }
+ if (t === 1) {
+ return 1;
+ }
+ if (!p) {
+ p = 0.3;
+ }
+ if (a < 1) {
+ a = 1;
+ s = p / 4;
+ } else {
+ s = p / (2 * Math.PI) * Math.asin(1 / a);
+ }
+ return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));
+ },
+
+ easeOutElastic: function(t) {
+ var s = 1.70158;
+ var p = 0;
+ var a = 1;
+ if (t === 0) {
+ return 0;
+ }
+ if (t === 1) {
+ return 1;
+ }
+ if (!p) {
+ p = 0.3;
+ }
+ if (a < 1) {
+ a = 1;
+ s = p / 4;
+ } else {
+ s = p / (2 * Math.PI) * Math.asin(1 / a);
+ }
+ return a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1;
+ },
+
+ easeInOutElastic: function(t) {
+ var s = 1.70158;
+ var p = 0;
+ var a = 1;
+ if (t === 0) {
+ return 0;
+ }
+ if ((t /= 0.5) === 2) {
+ return 1;
+ }
+ if (!p) {
+ p = 0.45;
+ }
+ if (a < 1) {
+ a = 1;
+ s = p / 4;
+ } else {
+ s = p / (2 * Math.PI) * Math.asin(1 / a);
+ }
+ if (t < 1) {
+ return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));
+ }
+ return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1;
+ },
+ easeInBack: function(t) {
+ var s = 1.70158;
+ return t * t * ((s + 1) * t - s);
+ },
+
+ easeOutBack: function(t) {
+ var s = 1.70158;
+ return (t = t - 1) * t * ((s + 1) * t + s) + 1;
+ },
+
+ easeInOutBack: function(t) {
+ var s = 1.70158;
+ if ((t /= 0.5) < 1) {
+ return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s));
+ }
+ return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
+ },
+
+ easeInBounce: function(t) {
+ return 1 - effects.easeOutBounce(1 - t);
+ },
+
+ easeOutBounce: function(t) {
+ if (t < (1 / 2.75)) {
+ return 7.5625 * t * t;
+ }
+ if (t < (2 / 2.75)) {
+ return 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75;
+ }
+ if (t < (2.5 / 2.75)) {
+ return 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375;
+ }
+ return 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375;
+ },
+
+ easeInOutBounce: function(t) {
+ if (t < 0.5) {
+ return effects.easeInBounce(t * 2) * 0.5;
+ }
+ return effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5;
+ }
+};
+
+module.exports = {
+ effects: effects
+};
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.easing.effects instead.
+ * @function Chart.helpers.easingEffects
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.easingEffects = effects;
+
+},{"42":42}],44:[function(require,module,exports){
+'use strict';
+
+var helpers = require(42);
+
+/**
+ * @alias Chart.helpers.options
+ * @namespace
+ */
+module.exports = {
+ /**
+ * Converts the given line height `value` in pixels for a specific font `size`.
+ * @param {Number|String} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em').
+ * @param {Number} size - The font size (in pixels) used to resolve relative `value`.
+ * @returns {Number} The effective line height in pixels (size * 1.2 if value is invalid).
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height
+ * @since 2.7.0
+ */
+ toLineHeight: function(value, size) {
+ var matches = ('' + value).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);
+ if (!matches || matches[1] === 'normal') {
+ return size * 1.2;
+ }
+
+ value = +matches[2];
+
+ switch (matches[3]) {
+ case 'px':
+ return value;
+ case '%':
+ value /= 100;
+ break;
+ default:
+ break;
+ }
+
+ return size * value;
+ },
+
+ /**
+ * Converts the given value into a padding object with pre-computed width/height.
+ * @param {Number|Object} value - If a number, set the value to all TRBL component,
+ * else, if and object, use defined properties and sets undefined ones to 0.
+ * @returns {Object} The padding values (top, right, bottom, left, width, height)
+ * @since 2.7.0
+ */
+ toPadding: function(value) {
+ var t, r, b, l;
+
+ if (helpers.isObject(value)) {
+ t = +value.top || 0;
+ r = +value.right || 0;
+ b = +value.bottom || 0;
+ l = +value.left || 0;
+ } else {
+ t = r = b = l = +value || 0;
+ }
+
+ return {
+ top: t,
+ right: r,
+ bottom: b,
+ left: l,
+ height: t + b,
+ width: l + r
+ };
+ },
+
+ /**
+ * Evaluates the given `inputs` sequentially and returns the first defined value.
+ * @param {Array[]} inputs - An array of values, falling back to the last value.
+ * @param {Object} [context] - If defined and the current value is a function, the value
+ * is called with `context` as first argument and the result becomes the new input.
+ * @param {Number} [index] - If defined and the current value is an array, the value
+ * at `index` become the new input.
+ * @since 2.7.0
+ */
+ resolve: function(inputs, context, index) {
+ var i, ilen, value;
+
+ for (i = 0, ilen = inputs.length; i < ilen; ++i) {
+ value = inputs[i];
+ if (value === undefined) {
+ continue;
+ }
+ if (context !== undefined && typeof value === 'function') {
+ value = value(context);
+ }
+ if (index !== undefined && helpers.isArray(value)) {
+ value = value[index];
+ }
+ if (value !== undefined) {
+ return value;
+ }
+ }
+ }
+};
+
+},{"42":42}],45:[function(require,module,exports){
+'use strict';
+
+module.exports = require(42);
+module.exports.easing = require(43);
+module.exports.canvas = require(41);
+module.exports.options = require(44);
+
+},{"41":41,"42":42,"43":43,"44":44}],46:[function(require,module,exports){
+/**
+ * Platform fallback implementation (minimal).
+ * @see https://github.com/chartjs/Chart.js/pull/4591#issuecomment-319575939
+ */
+
+module.exports = {
+ acquireContext: function(item) {
+ if (item && item.canvas) {
+ // Support for any object associated to a canvas (including a context2d)
+ item = item.canvas;
+ }
+
+ return item && item.getContext('2d') || null;
+ }
+};
+
+},{}],47:[function(require,module,exports){
+/**
+ * Chart.Platform implementation for targeting a web browser
+ */
+
+'use strict';
+
+var helpers = require(45);
+
+var EXPANDO_KEY = '$chartjs';
+var CSS_PREFIX = 'chartjs-';
+var CSS_RENDER_MONITOR = CSS_PREFIX + 'render-monitor';
+var CSS_RENDER_ANIMATION = CSS_PREFIX + 'render-animation';
+var ANIMATION_START_EVENTS = ['animationstart', 'webkitAnimationStart'];
+
+/**
+ * DOM event types -> Chart.js event types.
+ * Note: only events with different types are mapped.
+ * @see https://developer.mozilla.org/en-US/docs/Web/Events
+ */
+var EVENT_TYPES = {
+ touchstart: 'mousedown',
+ touchmove: 'mousemove',
+ touchend: 'mouseup',
+ pointerenter: 'mouseenter',
+ pointerdown: 'mousedown',
+ pointermove: 'mousemove',
+ pointerup: 'mouseup',
+ pointerleave: 'mouseout',
+ pointerout: 'mouseout'
+};
+
+/**
+ * The "used" size is the final value of a dimension property after all calculations have
+ * been performed. This method uses the computed style of `element` but returns undefined
+ * if the computed style is not expressed in pixels. That can happen in some cases where
+ * `element` has a size relative to its parent and this last one is not yet displayed,
+ * for example because of `display: none` on a parent node.
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
+ * @returns {Number} Size in pixels or undefined if unknown.
+ */
+function readUsedSize(element, property) {
+ var value = helpers.getStyle(element, property);
+ var matches = value && value.match(/^(\d+)(\.\d+)?px$/);
+ return matches ? Number(matches[1]) : undefined;
+}
+
+/**
+ * Initializes the canvas style and render size without modifying the canvas display size,
+ * since responsiveness is handled by the controller.resize() method. The config is used
+ * to determine the aspect ratio to apply in case no explicit height has been specified.
+ */
+function initCanvas(canvas, config) {
+ var style = canvas.style;
+
+ // NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it
+ // returns null or '' if no explicit value has been set to the canvas attribute.
+ var renderHeight = canvas.getAttribute('height');
+ var renderWidth = canvas.getAttribute('width');
+
+ // Chart.js modifies some canvas values that we want to restore on destroy
+ canvas[EXPANDO_KEY] = {
+ initial: {
+ height: renderHeight,
+ width: renderWidth,
+ style: {
+ display: style.display,
+ height: style.height,
+ width: style.width
+ }
+ }
+ };
+
+ // Force canvas to display as block to avoid extra space caused by inline
+ // elements, which would interfere with the responsive resize process.
+ // https://github.com/chartjs/Chart.js/issues/2538
+ style.display = style.display || 'block';
+
+ if (renderWidth === null || renderWidth === '') {
+ var displayWidth = readUsedSize(canvas, 'width');
+ if (displayWidth !== undefined) {
+ canvas.width = displayWidth;
+ }
+ }
+
+ if (renderHeight === null || renderHeight === '') {
+ if (canvas.style.height === '') {
+ // If no explicit render height and style height, let's apply the aspect ratio,
+ // which one can be specified by the user but also by charts as default option
+ // (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2.
+ canvas.height = canvas.width / (config.options.aspectRatio || 2);
+ } else {
+ var displayHeight = readUsedSize(canvas, 'height');
+ if (displayWidth !== undefined) {
+ canvas.height = displayHeight;
+ }
+ }
+ }
+
+ return canvas;
+}
+
+/**
+ * Detects support for options object argument in addEventListener.
+ * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
+ * @private
+ */
+var supportsEventListenerOptions = (function() {
+ var supports = false;
+ try {
+ var options = Object.defineProperty({}, 'passive', {
+ get: function() {
+ supports = true;
+ }
+ });
+ window.addEventListener('e', null, options);
+ } catch (e) {
+ // continue regardless of error
+ }
+ return supports;
+}());
+
+// Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events.
+// https://github.com/chartjs/Chart.js/issues/4287
+var eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false;
+
+function addEventListener(node, type, listener) {
+ node.addEventListener(type, listener, eventListenerOptions);
+}
+
+function removeEventListener(node, type, listener) {
+ node.removeEventListener(type, listener, eventListenerOptions);
+}
+
+function createEvent(type, chart, x, y, nativeEvent) {
+ return {
+ type: type,
+ chart: chart,
+ native: nativeEvent || null,
+ x: x !== undefined ? x : null,
+ y: y !== undefined ? y : null,
+ };
+}
+
+function fromNativeEvent(event, chart) {
+ var type = EVENT_TYPES[event.type] || event.type;
+ var pos = helpers.getRelativePosition(event, chart);
+ return createEvent(type, chart, pos.x, pos.y, event);
+}
+
+function throttled(fn, thisArg) {
+ var ticking = false;
+ var args = [];
+
+ return function() {
+ args = Array.prototype.slice.call(arguments);
+ thisArg = thisArg || this;
+
+ if (!ticking) {
+ ticking = true;
+ helpers.requestAnimFrame.call(window, function() {
+ ticking = false;
+ fn.apply(thisArg, args);
+ });
+ }
+ };
+}
+
+// Implementation based on https://github.com/marcj/css-element-queries
+function createResizer(handler) {
+ var resizer = document.createElement('div');
+ var cls = CSS_PREFIX + 'size-monitor';
+ var maxSize = 1000000;
+ var style =
+ 'position:absolute;' +
+ 'left:0;' +
+ 'top:0;' +
+ 'right:0;' +
+ 'bottom:0;' +
+ 'overflow:hidden;' +
+ 'pointer-events:none;' +
+ 'visibility:hidden;' +
+ 'z-index:-1;';
+
+ resizer.style.cssText = style;
+ resizer.className = cls;
+ resizer.innerHTML =
+ '' +
+ '';
+
+ var expand = resizer.childNodes[0];
+ var shrink = resizer.childNodes[1];
+
+ resizer._reset = function() {
+ expand.scrollLeft = maxSize;
+ expand.scrollTop = maxSize;
+ shrink.scrollLeft = maxSize;
+ shrink.scrollTop = maxSize;
+ };
+ var onScroll = function() {
+ resizer._reset();
+ handler();
+ };
+
+ addEventListener(expand, 'scroll', onScroll.bind(expand, 'expand'));
+ addEventListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink'));
+
+ return resizer;
+}
+
+// https://davidwalsh.name/detect-node-insertion
+function watchForRender(node, handler) {
+ var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});
+ var proxy = expando.renderProxy = function(e) {
+ if (e.animationName === CSS_RENDER_ANIMATION) {
+ handler();
+ }
+ };
+
+ helpers.each(ANIMATION_START_EVENTS, function(type) {
+ addEventListener(node, type, proxy);
+ });
+
+ // #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class
+ // is removed then added back immediately (same animation frame?). Accessing the
+ // `offsetParent` property will force a reflow and re-evaluate the CSS animation.
+ // https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics
+ // https://github.com/chartjs/Chart.js/issues/4737
+ expando.reflow = !!node.offsetParent;
+
+ node.classList.add(CSS_RENDER_MONITOR);
+}
+
+function unwatchForRender(node) {
+ var expando = node[EXPANDO_KEY] || {};
+ var proxy = expando.renderProxy;
+
+ if (proxy) {
+ helpers.each(ANIMATION_START_EVENTS, function(type) {
+ removeEventListener(node, type, proxy);
+ });
+
+ delete expando.renderProxy;
+ }
+
+ node.classList.remove(CSS_RENDER_MONITOR);
+}
+
+function addResizeListener(node, listener, chart) {
+ var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});
+
+ // Let's keep track of this added resizer and thus avoid DOM query when removing it.
+ var resizer = expando.resizer = createResizer(throttled(function() {
+ if (expando.resizer) {
+ return listener(createEvent('resize', chart));
+ }
+ }));
+
+ // The resizer needs to be attached to the node parent, so we first need to be
+ // sure that `node` is attached to the DOM before injecting the resizer element.
+ watchForRender(node, function() {
+ if (expando.resizer) {
+ var container = node.parentNode;
+ if (container && container !== resizer.parentNode) {
+ container.insertBefore(resizer, container.firstChild);
+ }
+
+ // The container size might have changed, let's reset the resizer state.
+ resizer._reset();
+ }
+ });
+}
+
+function removeResizeListener(node) {
+ var expando = node[EXPANDO_KEY] || {};
+ var resizer = expando.resizer;
+
+ delete expando.resizer;
+ unwatchForRender(node);
+
+ if (resizer && resizer.parentNode) {
+ resizer.parentNode.removeChild(resizer);
+ }
+}
+
+function injectCSS(platform, css) {
+ // http://stackoverflow.com/q/3922139
+ var style = platform._style || document.createElement('style');
+ if (!platform._style) {
+ platform._style = style;
+ css = '/* Chart.js */\n' + css;
+ style.setAttribute('type', 'text/css');
+ document.getElementsByTagName('head')[0].appendChild(style);
+ }
+
+ style.appendChild(document.createTextNode(css));
+}
+
+module.exports = {
+ /**
+ * This property holds whether this platform is enabled for the current environment.
+ * Currently used by platform.js to select the proper implementation.
+ * @private
+ */
+ _enabled: typeof window !== 'undefined' && typeof document !== 'undefined',
+
+ initialize: function() {
+ var keyframes = 'from{opacity:0.99}to{opacity:1}';
+
+ injectCSS(this,
+ // DOM rendering detection
+ // https://davidwalsh.name/detect-node-insertion
+ '@-webkit-keyframes ' + CSS_RENDER_ANIMATION + '{' + keyframes + '}' +
+ '@keyframes ' + CSS_RENDER_ANIMATION + '{' + keyframes + '}' +
+ '.' + CSS_RENDER_MONITOR + '{' +
+ '-webkit-animation:' + CSS_RENDER_ANIMATION + ' 0.001s;' +
+ 'animation:' + CSS_RENDER_ANIMATION + ' 0.001s;' +
+ '}'
+ );
+ },
+
+ acquireContext: function(item, config) {
+ if (typeof item === 'string') {
+ item = document.getElementById(item);
+ } else if (item.length) {
+ // Support for array based queries (such as jQuery)
+ item = item[0];
+ }
+
+ if (item && item.canvas) {
+ // Support for any object associated to a canvas (including a context2d)
+ item = item.canvas;
+ }
+
+ // To prevent canvas fingerprinting, some add-ons undefine the getContext
+ // method, for example: https://github.com/kkapsner/CanvasBlocker
+ // https://github.com/chartjs/Chart.js/issues/2807
+ var context = item && item.getContext && item.getContext('2d');
+
+ // `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is
+ // inside an iframe or when running in a protected environment. We could guess the
+ // types from their toString() value but let's keep things flexible and assume it's
+ // a sufficient condition if the item has a context2D which has item as `canvas`.
+ // https://github.com/chartjs/Chart.js/issues/3887
+ // https://github.com/chartjs/Chart.js/issues/4102
+ // https://github.com/chartjs/Chart.js/issues/4152
+ if (context && context.canvas === item) {
+ initCanvas(item, config);
+ return context;
+ }
+
+ return null;
+ },
+
+ releaseContext: function(context) {
+ var canvas = context.canvas;
+ if (!canvas[EXPANDO_KEY]) {
+ return;
+ }
+
+ var initial = canvas[EXPANDO_KEY].initial;
+ ['height', 'width'].forEach(function(prop) {
+ var value = initial[prop];
+ if (helpers.isNullOrUndef(value)) {
+ canvas.removeAttribute(prop);
+ } else {
+ canvas.setAttribute(prop, value);
+ }
+ });
+
+ helpers.each(initial.style || {}, function(value, key) {
+ canvas.style[key] = value;
+ });
+
+ // The canvas render size might have been changed (and thus the state stack discarded),
+ // we can't use save() and restore() to restore the initial state. So make sure that at
+ // least the canvas context is reset to the default state by setting the canvas width.
+ // https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html
+ canvas.width = canvas.width;
+
+ delete canvas[EXPANDO_KEY];
+ },
+
+ addEventListener: function(chart, type, listener) {
+ var canvas = chart.canvas;
+ if (type === 'resize') {
+ // Note: the resize event is not supported on all browsers.
+ addResizeListener(canvas, listener, chart);
+ return;
+ }
+
+ var expando = listener[EXPANDO_KEY] || (listener[EXPANDO_KEY] = {});
+ var proxies = expando.proxies || (expando.proxies = {});
+ var proxy = proxies[chart.id + '_' + type] = function(event) {
+ listener(fromNativeEvent(event, chart));
+ };
+
+ addEventListener(canvas, type, proxy);
+ },
+
+ removeEventListener: function(chart, type, listener) {
+ var canvas = chart.canvas;
+ if (type === 'resize') {
+ // Note: the resize event is not supported on all browsers.
+ removeResizeListener(canvas, listener);
+ return;
+ }
+
+ var expando = listener[EXPANDO_KEY] || {};
+ var proxies = expando.proxies || {};
+ var proxy = proxies[chart.id + '_' + type];
+ if (!proxy) {
+ return;
+ }
+
+ removeEventListener(canvas, type, proxy);
+ }
+};
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use EventTarget.addEventListener instead.
+ * EventTarget.addEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
+ * @function Chart.helpers.addEvent
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.addEvent = addEventListener;
+
+/**
+ * Provided for backward compatibility, use EventTarget.removeEventListener instead.
+ * EventTarget.removeEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener
+ * @function Chart.helpers.removeEvent
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.removeEvent = removeEventListener;
+
+},{"45":45}],48:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+var basic = require(46);
+var dom = require(47);
+
+// @TODO Make possible to select another platform at build time.
+var implementation = dom._enabled ? dom : basic;
+
+/**
+ * @namespace Chart.platform
+ * @see https://chartjs.gitbooks.io/proposals/content/Platform.html
+ * @since 2.4.0
+ */
+module.exports = helpers.extend({
+ /**
+ * @since 2.7.0
+ */
+ initialize: function() {},
+
+ /**
+ * Called at chart construction time, returns a context2d instance implementing
+ * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}.
+ * @param {*} item - The native item from which to acquire context (platform specific)
+ * @param {Object} options - The chart options
+ * @returns {CanvasRenderingContext2D} context2d instance
+ */
+ acquireContext: function() {},
+
+ /**
+ * Called at chart destruction time, releases any resources associated to the context
+ * previously returned by the acquireContext() method.
+ * @param {CanvasRenderingContext2D} context - The context2d instance
+ * @returns {Boolean} true if the method succeeded, else false
+ */
+ releaseContext: function() {},
+
+ /**
+ * Registers the specified listener on the given chart.
+ * @param {Chart} chart - Chart from which to listen for event
+ * @param {String} type - The ({@link IEvent}) type to listen for
+ * @param {Function} listener - Receives a notification (an object that implements
+ * the {@link IEvent} interface) when an event of the specified type occurs.
+ */
+ addEventListener: function() {},
+
+ /**
+ * Removes the specified listener previously registered with addEventListener.
+ * @param {Chart} chart -Chart from which to remove the listener
+ * @param {String} type - The ({@link IEvent}) type to remove
+ * @param {Function} listener - The listener function to remove from the event target.
+ */
+ removeEventListener: function() {}
+
+}, implementation);
+
+/**
+ * @interface IPlatform
+ * Allows abstracting platform dependencies away from the chart
+ * @borrows Chart.platform.acquireContext as acquireContext
+ * @borrows Chart.platform.releaseContext as releaseContext
+ * @borrows Chart.platform.addEventListener as addEventListener
+ * @borrows Chart.platform.removeEventListener as removeEventListener
+ */
+
+/**
+ * @interface IEvent
+ * @prop {String} type - The event type name, possible values are:
+ * 'contextmenu', 'mouseenter', 'mousedown', 'mousemove', 'mouseup', 'mouseout',
+ * 'click', 'dblclick', 'keydown', 'keypress', 'keyup' and 'resize'
+ * @prop {*} native - The original native event (null for emulated events, e.g. 'resize')
+ * @prop {Number} x - The mouse x position, relative to the canvas (null for incompatible events)
+ * @prop {Number} y - The mouse y position, relative to the canvas (null for incompatible events)
+ */
+
+},{"45":45,"46":46,"47":47}],49:[function(require,module,exports){
+'use strict';
+
+module.exports = {};
+module.exports.filler = require(50);
+module.exports.legend = require(51);
+module.exports.title = require(52);
+
+},{"50":50,"51":51,"52":52}],50:[function(require,module,exports){
+/**
+ * Plugin based on discussion from the following Chart.js issues:
+ * @see https://github.com/chartjs/Chart.js/issues/2380#issuecomment-279961569
+ * @see https://github.com/chartjs/Chart.js/issues/2440#issuecomment-256461897
+ */
+
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('global', {
+ plugins: {
+ filler: {
+ propagate: true
+ }
+ }
+});
+
+var mappers = {
+ dataset: function(source) {
+ var index = source.fill;
+ var chart = source.chart;
+ var meta = chart.getDatasetMeta(index);
+ var visible = meta && chart.isDatasetVisible(index);
+ var points = (visible && meta.dataset._children) || [];
+ var length = points.length || 0;
+
+ return !length ? null : function(point, i) {
+ return (i < length && points[i]._view) || null;
+ };
+ },
+
+ boundary: function(source) {
+ var boundary = source.boundary;
+ var x = boundary ? boundary.x : null;
+ var y = boundary ? boundary.y : null;
+
+ return function(point) {
+ return {
+ x: x === null ? point.x : x,
+ y: y === null ? point.y : y,
+ };
+ };
+ }
+};
+
+// @todo if (fill[0] === '#')
+function decodeFill(el, index, count) {
+ var model = el._model || {};
+ var fill = model.fill;
+ var target;
+
+ if (fill === undefined) {
+ fill = !!model.backgroundColor;
+ }
+
+ if (fill === false || fill === null) {
+ return false;
+ }
+
+ if (fill === true) {
+ return 'origin';
+ }
+
+ target = parseFloat(fill, 10);
+ if (isFinite(target) && Math.floor(target) === target) {
+ if (fill[0] === '-' || fill[0] === '+') {
+ target = index + target;
+ }
+
+ if (target === index || target < 0 || target >= count) {
+ return false;
+ }
+
+ return target;
+ }
+
+ switch (fill) {
+ // compatibility
+ case 'bottom':
+ return 'start';
+ case 'top':
+ return 'end';
+ case 'zero':
+ return 'origin';
+ // supported boundaries
+ case 'origin':
+ case 'start':
+ case 'end':
+ return fill;
+ // invalid fill values
+ default:
+ return false;
+ }
+}
+
+function computeBoundary(source) {
+ var model = source.el._model || {};
+ var scale = source.el._scale || {};
+ var fill = source.fill;
+ var target = null;
+ var horizontal;
+
+ if (isFinite(fill)) {
+ return null;
+ }
+
+ // Backward compatibility: until v3, we still need to support boundary values set on
+ // the model (scaleTop, scaleBottom and scaleZero) because some external plugins and
+ // controllers might still use it (e.g. the Smith chart).
+
+ if (fill === 'start') {
+ target = model.scaleBottom === undefined ? scale.bottom : model.scaleBottom;
+ } else if (fill === 'end') {
+ target = model.scaleTop === undefined ? scale.top : model.scaleTop;
+ } else if (model.scaleZero !== undefined) {
+ target = model.scaleZero;
+ } else if (scale.getBasePosition) {
+ target = scale.getBasePosition();
+ } else if (scale.getBasePixel) {
+ target = scale.getBasePixel();
+ }
+
+ if (target !== undefined && target !== null) {
+ if (target.x !== undefined && target.y !== undefined) {
+ return target;
+ }
+
+ if (typeof target === 'number' && isFinite(target)) {
+ horizontal = scale.isHorizontal();
+ return {
+ x: horizontal ? target : null,
+ y: horizontal ? null : target
+ };
+ }
+ }
+
+ return null;
+}
+
+function resolveTarget(sources, index, propagate) {
+ var source = sources[index];
+ var fill = source.fill;
+ var visited = [index];
+ var target;
+
+ if (!propagate) {
+ return fill;
+ }
+
+ while (fill !== false && visited.indexOf(fill) === -1) {
+ if (!isFinite(fill)) {
+ return fill;
+ }
+
+ target = sources[fill];
+ if (!target) {
+ return false;
+ }
+
+ if (target.visible) {
+ return fill;
+ }
+
+ visited.push(fill);
+ fill = target.fill;
+ }
+
+ return false;
+}
+
+function createMapper(source) {
+ var fill = source.fill;
+ var type = 'dataset';
+
+ if (fill === false) {
+ return null;
+ }
+
+ if (!isFinite(fill)) {
+ type = 'boundary';
+ }
+
+ return mappers[type](source);
+}
+
+function isDrawable(point) {
+ return point && !point.skip;
+}
+
+function drawArea(ctx, curve0, curve1, len0, len1) {
+ var i;
+
+ if (!len0 || !len1) {
+ return;
+ }
+
+ // building first area curve (normal)
+ ctx.moveTo(curve0[0].x, curve0[0].y);
+ for (i = 1; i < len0; ++i) {
+ helpers.canvas.lineTo(ctx, curve0[i - 1], curve0[i]);
+ }
+
+ // joining the two area curves
+ ctx.lineTo(curve1[len1 - 1].x, curve1[len1 - 1].y);
+
+ // building opposite area curve (reverse)
+ for (i = len1 - 1; i > 0; --i) {
+ helpers.canvas.lineTo(ctx, curve1[i], curve1[i - 1], true);
+ }
+}
+
+function doFill(ctx, points, mapper, view, color, loop) {
+ var count = points.length;
+ var span = view.spanGaps;
+ var curve0 = [];
+ var curve1 = [];
+ var len0 = 0;
+ var len1 = 0;
+ var i, ilen, index, p0, p1, d0, d1;
+
+ ctx.beginPath();
+
+ for (i = 0, ilen = (count + !!loop); i < ilen; ++i) {
+ index = i % count;
+ p0 = points[index]._view;
+ p1 = mapper(p0, index, view);
+ d0 = isDrawable(p0);
+ d1 = isDrawable(p1);
+
+ if (d0 && d1) {
+ len0 = curve0.push(p0);
+ len1 = curve1.push(p1);
+ } else if (len0 && len1) {
+ if (!span) {
+ drawArea(ctx, curve0, curve1, len0, len1);
+ len0 = len1 = 0;
+ curve0 = [];
+ curve1 = [];
+ } else {
+ if (d0) {
+ curve0.push(p0);
+ }
+ if (d1) {
+ curve1.push(p1);
+ }
+ }
+ }
+ }
+
+ drawArea(ctx, curve0, curve1, len0, len1);
+
+ ctx.closePath();
+ ctx.fillStyle = color;
+ ctx.fill();
+}
+
+module.exports = {
+ id: 'filler',
+
+ afterDatasetsUpdate: function(chart, options) {
+ var count = (chart.data.datasets || []).length;
+ var propagate = options.propagate;
+ var sources = [];
+ var meta, i, el, source;
+
+ for (i = 0; i < count; ++i) {
+ meta = chart.getDatasetMeta(i);
+ el = meta.dataset;
+ source = null;
+
+ if (el && el._model && el instanceof elements.Line) {
+ source = {
+ visible: chart.isDatasetVisible(i),
+ fill: decodeFill(el, i, count),
+ chart: chart,
+ el: el
+ };
+ }
+
+ meta.$filler = source;
+ sources.push(source);
+ }
+
+ for (i = 0; i < count; ++i) {
+ source = sources[i];
+ if (!source) {
+ continue;
+ }
+
+ source.fill = resolveTarget(sources, i, propagate);
+ source.boundary = computeBoundary(source);
+ source.mapper = createMapper(source);
+ }
+ },
+
+ beforeDatasetDraw: function(chart, args) {
+ var meta = args.meta.$filler;
+ if (!meta) {
+ return;
+ }
+
+ var ctx = chart.ctx;
+ var el = meta.el;
+ var view = el._view;
+ var points = el._children || [];
+ var mapper = meta.mapper;
+ var color = view.backgroundColor || defaults.global.defaultColor;
+
+ if (mapper && color && points.length) {
+ helpers.canvas.clipArea(ctx, chart.chartArea);
+ doFill(ctx, points, mapper, view, color, el._loop);
+ helpers.canvas.unclipArea(ctx);
+ }
+ }
+};
+
+},{"25":25,"40":40,"45":45}],51:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+var layouts = require(30);
+
+var noop = helpers.noop;
+
+defaults._set('global', {
+ legend: {
+ display: true,
+ position: 'top',
+ fullWidth: true,
+ reverse: false,
+ weight: 1000,
+
+ // a callback that will handle
+ onClick: function(e, legendItem) {
+ var index = legendItem.datasetIndex;
+ var ci = this.chart;
+ var meta = ci.getDatasetMeta(index);
+
+ // See controller.isDatasetVisible comment
+ meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
+
+ // We hid a dataset ... rerender the chart
+ ci.update();
+ },
+
+ onHover: null,
+
+ labels: {
+ boxWidth: 40,
+ padding: 10,
+ // Generates labels shown in the legend
+ // Valid properties to return:
+ // text : text to display
+ // fillStyle : fill of coloured box
+ // strokeStyle: stroke of coloured box
+ // hidden : if this legend item refers to a hidden item
+ // lineCap : cap style for line
+ // lineDash
+ // lineDashOffset :
+ // lineJoin :
+ // lineWidth :
+ generateLabels: function(chart) {
+ var data = chart.data;
+ return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {
+ return {
+ text: dataset.label,
+ fillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]),
+ hidden: !chart.isDatasetVisible(i),
+ lineCap: dataset.borderCapStyle,
+ lineDash: dataset.borderDash,
+ lineDashOffset: dataset.borderDashOffset,
+ lineJoin: dataset.borderJoinStyle,
+ lineWidth: dataset.borderWidth,
+ strokeStyle: dataset.borderColor,
+ pointStyle: dataset.pointStyle,
+
+ // Below is extra data used for toggling the datasets
+ datasetIndex: i
+ };
+ }, this) : [];
+ }
+ }
+ },
+
+ legendCallback: function(chart) {
+ var text = [];
+ text.push('');
+ for (var i = 0; i < chart.data.datasets.length; i++) {
+ text.push(' ');
+ if (chart.data.datasets[i].label) {
+ text.push(chart.data.datasets[i].label);
+ }
+ text.push(' ');
+ }
+ text.push(' ');
+ return text.join('');
+ }
+});
+
+/**
+ * Helper function to get the box width based on the usePointStyle option
+ * @param labelopts {Object} the label options on the legend
+ * @param fontSize {Number} the label font size
+ * @return {Number} width of the color box area
+ */
+function getBoxWidth(labelOpts, fontSize) {
+ return labelOpts.usePointStyle ?
+ fontSize * Math.SQRT2 :
+ labelOpts.boxWidth;
+}
+
+/**
+ * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required!
+ */
+var Legend = Element.extend({
+
+ initialize: function(config) {
+ helpers.extend(this, config);
+
+ // Contains hit boxes for each dataset (in dataset order)
+ this.legendHitBoxes = [];
+
+ // Are we in doughnut mode which has a different data type
+ this.doughnutMode = false;
+ },
+
+ // These methods are ordered by lifecycle. Utilities then follow.
+ // Any function defined here is inherited by all legend types.
+ // Any function can be extended by the legend type
+
+ beforeUpdate: noop,
+ update: function(maxWidth, maxHeight, margins) {
+ var me = this;
+
+ // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
+ me.beforeUpdate();
+
+ // Absorb the master measurements
+ me.maxWidth = maxWidth;
+ me.maxHeight = maxHeight;
+ me.margins = margins;
+
+ // Dimensions
+ me.beforeSetDimensions();
+ me.setDimensions();
+ me.afterSetDimensions();
+ // Labels
+ me.beforeBuildLabels();
+ me.buildLabels();
+ me.afterBuildLabels();
+
+ // Fit
+ me.beforeFit();
+ me.fit();
+ me.afterFit();
+ //
+ me.afterUpdate();
+
+ return me.minSize;
+ },
+ afterUpdate: noop,
+
+ //
+
+ beforeSetDimensions: noop,
+ setDimensions: function() {
+ var me = this;
+ // Set the unconstrained dimension before label rotation
+ if (me.isHorizontal()) {
+ // Reset position before calculating rotation
+ me.width = me.maxWidth;
+ me.left = 0;
+ me.right = me.width;
+ } else {
+ me.height = me.maxHeight;
+
+ // Reset position before calculating rotation
+ me.top = 0;
+ me.bottom = me.height;
+ }
+
+ // Reset padding
+ me.paddingLeft = 0;
+ me.paddingTop = 0;
+ me.paddingRight = 0;
+ me.paddingBottom = 0;
+
+ // Reset minSize
+ me.minSize = {
+ width: 0,
+ height: 0
+ };
+ },
+ afterSetDimensions: noop,
+
+ //
+
+ beforeBuildLabels: noop,
+ buildLabels: function() {
+ var me = this;
+ var labelOpts = me.options.labels || {};
+ var legendItems = helpers.callback(labelOpts.generateLabels, [me.chart], me) || [];
+
+ if (labelOpts.filter) {
+ legendItems = legendItems.filter(function(item) {
+ return labelOpts.filter(item, me.chart.data);
+ });
+ }
+
+ if (me.options.reverse) {
+ legendItems.reverse();
+ }
+
+ me.legendItems = legendItems;
+ },
+ afterBuildLabels: noop,
+
+ //
+
+ beforeFit: noop,
+ fit: function() {
+ var me = this;
+ var opts = me.options;
+ var labelOpts = opts.labels;
+ var display = opts.display;
+
+ var ctx = me.ctx;
+
+ var globalDefault = defaults.global;
+ var valueOrDefault = helpers.valueOrDefault;
+ var fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize);
+ var fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle);
+ var fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily);
+ var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
+
+ // Reset hit boxes
+ var hitboxes = me.legendHitBoxes = [];
+
+ var minSize = me.minSize;
+ var isHorizontal = me.isHorizontal();
+
+ if (isHorizontal) {
+ minSize.width = me.maxWidth; // fill all the width
+ minSize.height = display ? 10 : 0;
+ } else {
+ minSize.width = display ? 10 : 0;
+ minSize.height = me.maxHeight; // fill all the height
+ }
+
+ // Increase sizes here
+ if (display) {
+ ctx.font = labelFont;
+
+ if (isHorizontal) {
+ // Labels
+
+ // Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one
+ var lineWidths = me.lineWidths = [0];
+ var totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0;
+
+ ctx.textAlign = 'left';
+ ctx.textBaseline = 'top';
+
+ helpers.each(me.legendItems, function(legendItem, i) {
+ var boxWidth = getBoxWidth(labelOpts, fontSize);
+ var width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
+
+ if (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {
+ totalHeight += fontSize + (labelOpts.padding);
+ lineWidths[lineWidths.length] = me.left;
+ }
+
+ // Store the hitbox width and height here. Final position will be updated in `draw`
+ hitboxes[i] = {
+ left: 0,
+ top: 0,
+ width: width,
+ height: fontSize
+ };
+
+ lineWidths[lineWidths.length - 1] += width + labelOpts.padding;
+ });
+
+ minSize.height += totalHeight;
+
+ } else {
+ var vPadding = labelOpts.padding;
+ var columnWidths = me.columnWidths = [];
+ var totalWidth = labelOpts.padding;
+ var currentColWidth = 0;
+ var currentColHeight = 0;
+ var itemHeight = fontSize + vPadding;
+
+ helpers.each(me.legendItems, function(legendItem, i) {
+ var boxWidth = getBoxWidth(labelOpts, fontSize);
+ var itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
+
+ // If too tall, go to new column
+ if (currentColHeight + itemHeight > minSize.height) {
+ totalWidth += currentColWidth + labelOpts.padding;
+ columnWidths.push(currentColWidth); // previous column width
+
+ currentColWidth = 0;
+ currentColHeight = 0;
+ }
+
+ // Get max width
+ currentColWidth = Math.max(currentColWidth, itemWidth);
+ currentColHeight += itemHeight;
+
+ // Store the hitbox width and height here. Final position will be updated in `draw`
+ hitboxes[i] = {
+ left: 0,
+ top: 0,
+ width: itemWidth,
+ height: fontSize
+ };
+ });
+
+ totalWidth += currentColWidth;
+ columnWidths.push(currentColWidth);
+ minSize.width += totalWidth;
+ }
+ }
+
+ me.width = minSize.width;
+ me.height = minSize.height;
+ },
+ afterFit: noop,
+
+ // Shared Methods
+ isHorizontal: function() {
+ return this.options.position === 'top' || this.options.position === 'bottom';
+ },
+
+ // Actually draw the legend on the canvas
+ draw: function() {
+ var me = this;
+ var opts = me.options;
+ var labelOpts = opts.labels;
+ var globalDefault = defaults.global;
+ var lineDefault = globalDefault.elements.line;
+ var legendWidth = me.width;
+ var lineWidths = me.lineWidths;
+
+ if (opts.display) {
+ var ctx = me.ctx;
+ var valueOrDefault = helpers.valueOrDefault;
+ var fontColor = valueOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor);
+ var fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize);
+ var fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle);
+ var fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily);
+ var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
+ var cursor;
+
+ // Canvas setup
+ ctx.textAlign = 'left';
+ ctx.textBaseline = 'middle';
+ ctx.lineWidth = 0.5;
+ ctx.strokeStyle = fontColor; // for strikethrough effect
+ ctx.fillStyle = fontColor; // render in correct colour
+ ctx.font = labelFont;
+
+ var boxWidth = getBoxWidth(labelOpts, fontSize);
+ var hitboxes = me.legendHitBoxes;
+
+ // current position
+ var drawLegendBox = function(x, y, legendItem) {
+ if (isNaN(boxWidth) || boxWidth <= 0) {
+ return;
+ }
+
+ // Set the ctx for the box
+ ctx.save();
+
+ ctx.fillStyle = valueOrDefault(legendItem.fillStyle, globalDefault.defaultColor);
+ ctx.lineCap = valueOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);
+ ctx.lineDashOffset = valueOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);
+ ctx.lineJoin = valueOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);
+ ctx.lineWidth = valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth);
+ ctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);
+ var isLineWidthZero = (valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth) === 0);
+
+ if (ctx.setLineDash) {
+ // IE 9 and 10 do not support line dash
+ ctx.setLineDash(valueOrDefault(legendItem.lineDash, lineDefault.borderDash));
+ }
+
+ if (opts.labels && opts.labels.usePointStyle) {
+ // Recalculate x and y for drawPoint() because its expecting
+ // x and y to be center of figure (instead of top left)
+ var radius = fontSize * Math.SQRT2 / 2;
+ var offSet = radius / Math.SQRT2;
+ var centerX = x + offSet;
+ var centerY = y + offSet;
+
+ // Draw pointStyle as legend symbol
+ helpers.canvas.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);
+ } else {
+ // Draw box as legend symbol
+ if (!isLineWidthZero) {
+ ctx.strokeRect(x, y, boxWidth, fontSize);
+ }
+ ctx.fillRect(x, y, boxWidth, fontSize);
+ }
+
+ ctx.restore();
+ };
+ var fillText = function(x, y, legendItem, textWidth) {
+ var halfFontSize = fontSize / 2;
+ var xLeft = boxWidth + halfFontSize + x;
+ var yMiddle = y + halfFontSize;
+
+ ctx.fillText(legendItem.text, xLeft, yMiddle);
+
+ if (legendItem.hidden) {
+ // Strikethrough the text if hidden
+ ctx.beginPath();
+ ctx.lineWidth = 2;
+ ctx.moveTo(xLeft, yMiddle);
+ ctx.lineTo(xLeft + textWidth, yMiddle);
+ ctx.stroke();
+ }
+ };
+
+ // Horizontal
+ var isHorizontal = me.isHorizontal();
+ if (isHorizontal) {
+ cursor = {
+ x: me.left + ((legendWidth - lineWidths[0]) / 2),
+ y: me.top + labelOpts.padding,
+ line: 0
+ };
+ } else {
+ cursor = {
+ x: me.left + labelOpts.padding,
+ y: me.top + labelOpts.padding,
+ line: 0
+ };
+ }
+
+ var itemHeight = fontSize + labelOpts.padding;
+ helpers.each(me.legendItems, function(legendItem, i) {
+ var textWidth = ctx.measureText(legendItem.text).width;
+ var width = boxWidth + (fontSize / 2) + textWidth;
+ var x = cursor.x;
+ var y = cursor.y;
+
+ if (isHorizontal) {
+ if (x + width >= legendWidth) {
+ y = cursor.y += itemHeight;
+ cursor.line++;
+ x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);
+ }
+ } else if (y + itemHeight > me.bottom) {
+ x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;
+ y = cursor.y = me.top + labelOpts.padding;
+ cursor.line++;
+ }
+
+ drawLegendBox(x, y, legendItem);
+
+ hitboxes[i].left = x;
+ hitboxes[i].top = y;
+
+ // Fill the actual label
+ fillText(x, y, legendItem, textWidth);
+
+ if (isHorizontal) {
+ cursor.x += width + (labelOpts.padding);
+ } else {
+ cursor.y += itemHeight;
+ }
+
+ });
+ }
+ },
+
+ /**
+ * Handle an event
+ * @private
+ * @param {IEvent} event - The event to handle
+ * @return {Boolean} true if a change occured
+ */
+ handleEvent: function(e) {
+ var me = this;
+ var opts = me.options;
+ var type = e.type === 'mouseup' ? 'click' : e.type;
+ var changed = false;
+
+ if (type === 'mousemove') {
+ if (!opts.onHover) {
+ return;
+ }
+ } else if (type === 'click') {
+ if (!opts.onClick) {
+ return;
+ }
+ } else {
+ return;
+ }
+
+ // Chart event already has relative position in it
+ var x = e.x;
+ var y = e.y;
+
+ if (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) {
+ // See if we are touching one of the dataset boxes
+ var lh = me.legendHitBoxes;
+ for (var i = 0; i < lh.length; ++i) {
+ var hitBox = lh[i];
+
+ if (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {
+ // Touching an element
+ if (type === 'click') {
+ // use e.native for backwards compatibility
+ opts.onClick.call(me, e.native, me.legendItems[i]);
+ changed = true;
+ break;
+ } else if (type === 'mousemove') {
+ // use e.native for backwards compatibility
+ opts.onHover.call(me, e.native, me.legendItems[i]);
+ changed = true;
+ break;
+ }
+ }
+ }
+ }
+
+ return changed;
+ }
+});
+
+function createNewLegendAndAttach(chart, legendOpts) {
+ var legend = new Legend({
+ ctx: chart.ctx,
+ options: legendOpts,
+ chart: chart
+ });
+
+ layouts.configure(chart, legend, legendOpts);
+ layouts.addBox(chart, legend);
+ chart.legend = legend;
+}
+
+module.exports = {
+ id: 'legend',
+
+ /**
+ * Backward compatibility: since 2.1.5, the legend is registered as a plugin, making
+ * Chart.Legend obsolete. To avoid a breaking change, we export the Legend as part of
+ * the plugin, which one will be re-exposed in the chart.js file.
+ * https://github.com/chartjs/Chart.js/pull/2640
+ * @private
+ */
+ _element: Legend,
+
+ beforeInit: function(chart) {
+ var legendOpts = chart.options.legend;
+
+ if (legendOpts) {
+ createNewLegendAndAttach(chart, legendOpts);
+ }
+ },
+
+ beforeUpdate: function(chart) {
+ var legendOpts = chart.options.legend;
+ var legend = chart.legend;
+
+ if (legendOpts) {
+ helpers.mergeIf(legendOpts, defaults.global.legend);
+
+ if (legend) {
+ layouts.configure(chart, legend, legendOpts);
+ legend.options = legendOpts;
+ } else {
+ createNewLegendAndAttach(chart, legendOpts);
+ }
+ } else if (legend) {
+ layouts.removeBox(chart, legend);
+ delete chart.legend;
+ }
+ },
+
+ afterEvent: function(chart, e) {
+ var legend = chart.legend;
+ if (legend) {
+ legend.handleEvent(e);
+ }
+ }
+};
+
+},{"25":25,"26":26,"30":30,"45":45}],52:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+var layouts = require(30);
+
+var noop = helpers.noop;
+
+defaults._set('global', {
+ title: {
+ display: false,
+ fontStyle: 'bold',
+ fullWidth: true,
+ lineHeight: 1.2,
+ padding: 10,
+ position: 'top',
+ text: '',
+ weight: 2000 // by default greater than legend (1000) to be above
+ }
+});
+
+/**
+ * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required!
+ */
+var Title = Element.extend({
+ initialize: function(config) {
+ var me = this;
+ helpers.extend(me, config);
+
+ // Contains hit boxes for each dataset (in dataset order)
+ me.legendHitBoxes = [];
+ },
+
+ // These methods are ordered by lifecycle. Utilities then follow.
+
+ beforeUpdate: noop,
+ update: function(maxWidth, maxHeight, margins) {
+ var me = this;
+
+ // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
+ me.beforeUpdate();
+
+ // Absorb the master measurements
+ me.maxWidth = maxWidth;
+ me.maxHeight = maxHeight;
+ me.margins = margins;
+
+ // Dimensions
+ me.beforeSetDimensions();
+ me.setDimensions();
+ me.afterSetDimensions();
+ // Labels
+ me.beforeBuildLabels();
+ me.buildLabels();
+ me.afterBuildLabels();
+
+ // Fit
+ me.beforeFit();
+ me.fit();
+ me.afterFit();
+ //
+ me.afterUpdate();
+
+ return me.minSize;
+
+ },
+ afterUpdate: noop,
+
+ //
+
+ beforeSetDimensions: noop,
+ setDimensions: function() {
+ var me = this;
+ // Set the unconstrained dimension before label rotation
+ if (me.isHorizontal()) {
+ // Reset position before calculating rotation
+ me.width = me.maxWidth;
+ me.left = 0;
+ me.right = me.width;
+ } else {
+ me.height = me.maxHeight;
+
+ // Reset position before calculating rotation
+ me.top = 0;
+ me.bottom = me.height;
+ }
+
+ // Reset padding
+ me.paddingLeft = 0;
+ me.paddingTop = 0;
+ me.paddingRight = 0;
+ me.paddingBottom = 0;
+
+ // Reset minSize
+ me.minSize = {
+ width: 0,
+ height: 0
+ };
+ },
+ afterSetDimensions: noop,
+
+ //
+
+ beforeBuildLabels: noop,
+ buildLabels: noop,
+ afterBuildLabels: noop,
+
+ //
+
+ beforeFit: noop,
+ fit: function() {
+ var me = this;
+ var valueOrDefault = helpers.valueOrDefault;
+ var opts = me.options;
+ var display = opts.display;
+ var fontSize = valueOrDefault(opts.fontSize, defaults.global.defaultFontSize);
+ var minSize = me.minSize;
+ var lineCount = helpers.isArray(opts.text) ? opts.text.length : 1;
+ var lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize);
+ var textSize = display ? (lineCount * lineHeight) + (opts.padding * 2) : 0;
+
+ if (me.isHorizontal()) {
+ minSize.width = me.maxWidth; // fill all the width
+ minSize.height = textSize;
+ } else {
+ minSize.width = textSize;
+ minSize.height = me.maxHeight; // fill all the height
+ }
+
+ me.width = minSize.width;
+ me.height = minSize.height;
+
+ },
+ afterFit: noop,
+
+ // Shared Methods
+ isHorizontal: function() {
+ var pos = this.options.position;
+ return pos === 'top' || pos === 'bottom';
+ },
+
+ // Actually draw the title block on the canvas
+ draw: function() {
+ var me = this;
+ var ctx = me.ctx;
+ var valueOrDefault = helpers.valueOrDefault;
+ var opts = me.options;
+ var globalDefaults = defaults.global;
+
+ if (opts.display) {
+ var fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize);
+ var fontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle);
+ var fontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily);
+ var titleFont = helpers.fontString(fontSize, fontStyle, fontFamily);
+ var lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize);
+ var offset = lineHeight / 2 + opts.padding;
+ var rotation = 0;
+ var top = me.top;
+ var left = me.left;
+ var bottom = me.bottom;
+ var right = me.right;
+ var maxWidth, titleX, titleY;
+
+ ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour
+ ctx.font = titleFont;
+
+ // Horizontal
+ if (me.isHorizontal()) {
+ titleX = left + ((right - left) / 2); // midpoint of the width
+ titleY = top + offset;
+ maxWidth = right - left;
+ } else {
+ titleX = opts.position === 'left' ? left + offset : right - offset;
+ titleY = top + ((bottom - top) / 2);
+ maxWidth = bottom - top;
+ rotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);
+ }
+
+ ctx.save();
+ ctx.translate(titleX, titleY);
+ ctx.rotate(rotation);
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'middle';
+
+ var text = opts.text;
+ if (helpers.isArray(text)) {
+ var y = 0;
+ for (var i = 0; i < text.length; ++i) {
+ ctx.fillText(text[i], 0, y, maxWidth);
+ y += lineHeight;
+ }
+ } else {
+ ctx.fillText(text, 0, 0, maxWidth);
+ }
+
+ ctx.restore();
+ }
+ }
+});
+
+function createNewTitleBlockAndAttach(chart, titleOpts) {
+ var title = new Title({
+ ctx: chart.ctx,
+ options: titleOpts,
+ chart: chart
+ });
+
+ layouts.configure(chart, title, titleOpts);
+ layouts.addBox(chart, title);
+ chart.titleBlock = title;
+}
+
+module.exports = {
+ id: 'title',
+
+ /**
+ * Backward compatibility: since 2.1.5, the title is registered as a plugin, making
+ * Chart.Title obsolete. To avoid a breaking change, we export the Title as part of
+ * the plugin, which one will be re-exposed in the chart.js file.
+ * https://github.com/chartjs/Chart.js/pull/2640
+ * @private
+ */
+ _element: Title,
+
+ beforeInit: function(chart) {
+ var titleOpts = chart.options.title;
+
+ if (titleOpts) {
+ createNewTitleBlockAndAttach(chart, titleOpts);
+ }
+ },
+
+ beforeUpdate: function(chart) {
+ var titleOpts = chart.options.title;
+ var titleBlock = chart.titleBlock;
+
+ if (titleOpts) {
+ helpers.mergeIf(titleOpts, defaults.global.title);
+
+ if (titleBlock) {
+ layouts.configure(chart, titleBlock, titleOpts);
+ titleBlock.options = titleOpts;
+ } else {
+ createNewTitleBlockAndAttach(chart, titleOpts);
+ }
+ } else if (titleBlock) {
+ layouts.removeBox(chart, titleBlock);
+ delete chart.titleBlock;
+ }
+ }
+};
+
+},{"25":25,"26":26,"30":30,"45":45}],53:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ // Default config for a category scale
+ var defaultConfig = {
+ position: 'bottom'
+ };
+
+ var DatasetScale = Chart.Scale.extend({
+ /**
+ * Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use those
+ * else fall back to data.labels
+ * @private
+ */
+ getLabels: function() {
+ var data = this.chart.data;
+ return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;
+ },
+
+ determineDataLimits: function() {
+ var me = this;
+ var labels = me.getLabels();
+ me.minIndex = 0;
+ me.maxIndex = labels.length - 1;
+ var findIndex;
+
+ if (me.options.ticks.min !== undefined) {
+ // user specified min value
+ findIndex = labels.indexOf(me.options.ticks.min);
+ me.minIndex = findIndex !== -1 ? findIndex : me.minIndex;
+ }
+
+ if (me.options.ticks.max !== undefined) {
+ // user specified max value
+ findIndex = labels.indexOf(me.options.ticks.max);
+ me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;
+ }
+
+ me.min = labels[me.minIndex];
+ me.max = labels[me.maxIndex];
+ },
+
+ buildTicks: function() {
+ var me = this;
+ var labels = me.getLabels();
+ // If we are viewing some subset of labels, slice the original array
+ me.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1);
+ },
+
+ getLabelForIndex: function(index, datasetIndex) {
+ var me = this;
+ var data = me.chart.data;
+ var isHorizontal = me.isHorizontal();
+
+ if (data.yLabels && !isHorizontal) {
+ return me.getRightValue(data.datasets[datasetIndex].data[index]);
+ }
+ return me.ticks[index - me.minIndex];
+ },
+
+ // Used to get data value locations. Value can either be an index or a numerical value
+ getPixelForValue: function(value, index) {
+ var me = this;
+ var offset = me.options.offset;
+ // 1 is added because we need the length but we have the indexes
+ var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - (offset ? 0 : 1)), 1);
+
+ // If value is a data object, then index is the index in the data array,
+ // not the index of the scale. We need to change that.
+ var valueCategory;
+ if (value !== undefined && value !== null) {
+ valueCategory = me.isHorizontal() ? value.x : value.y;
+ }
+ if (valueCategory !== undefined || (value !== undefined && isNaN(index))) {
+ var labels = me.getLabels();
+ value = valueCategory || value;
+ var idx = labels.indexOf(value);
+ index = idx !== -1 ? idx : index;
+ }
+
+ if (me.isHorizontal()) {
+ var valueWidth = me.width / offsetAmt;
+ var widthOffset = (valueWidth * (index - me.minIndex));
+
+ if (offset) {
+ widthOffset += (valueWidth / 2);
+ }
+
+ return me.left + Math.round(widthOffset);
+ }
+ var valueHeight = me.height / offsetAmt;
+ var heightOffset = (valueHeight * (index - me.minIndex));
+
+ if (offset) {
+ heightOffset += (valueHeight / 2);
+ }
+
+ return me.top + Math.round(heightOffset);
+ },
+ getPixelForTick: function(index) {
+ return this.getPixelForValue(this.ticks[index], index + this.minIndex, null);
+ },
+ getValueForPixel: function(pixel) {
+ var me = this;
+ var offset = me.options.offset;
+ var value;
+ var offsetAmt = Math.max((me._ticks.length - (offset ? 0 : 1)), 1);
+ var horz = me.isHorizontal();
+ var valueDimension = (horz ? me.width : me.height) / offsetAmt;
+
+ pixel -= horz ? me.left : me.top;
+
+ if (offset) {
+ pixel -= (valueDimension / 2);
+ }
+
+ if (pixel <= 0) {
+ value = 0;
+ } else {
+ value = Math.round(pixel / valueDimension);
+ }
+
+ return value + me.minIndex;
+ },
+ getBasePixel: function() {
+ return this.bottom;
+ }
+ });
+
+ Chart.scaleService.registerScaleType('category', DatasetScale, defaultConfig);
+
+};
+
+},{}],54:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var helpers = require(45);
+var Ticks = require(34);
+
+module.exports = function(Chart) {
+
+ var defaultConfig = {
+ position: 'left',
+ ticks: {
+ callback: Ticks.formatters.linear
+ }
+ };
+
+ var LinearScale = Chart.LinearScaleBase.extend({
+
+ determineDataLimits: function() {
+ var me = this;
+ var opts = me.options;
+ var chart = me.chart;
+ var data = chart.data;
+ var datasets = data.datasets;
+ var isHorizontal = me.isHorizontal();
+ var DEFAULT_MIN = 0;
+ var DEFAULT_MAX = 1;
+
+ function IDMatches(meta) {
+ return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
+ }
+
+ // First Calculate the range
+ me.min = null;
+ me.max = null;
+
+ var hasStacks = opts.stacked;
+ if (hasStacks === undefined) {
+ helpers.each(datasets, function(dataset, datasetIndex) {
+ if (hasStacks) {
+ return;
+ }
+
+ var meta = chart.getDatasetMeta(datasetIndex);
+ if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
+ meta.stack !== undefined) {
+ hasStacks = true;
+ }
+ });
+ }
+
+ if (opts.stacked || hasStacks) {
+ var valuesPerStack = {};
+
+ helpers.each(datasets, function(dataset, datasetIndex) {
+ var meta = chart.getDatasetMeta(datasetIndex);
+ var key = [
+ meta.type,
+ // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
+ ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),
+ meta.stack
+ ].join('.');
+
+ if (valuesPerStack[key] === undefined) {
+ valuesPerStack[key] = {
+ positiveValues: [],
+ negativeValues: []
+ };
+ }
+
+ // Store these per type
+ var positiveValues = valuesPerStack[key].positiveValues;
+ var negativeValues = valuesPerStack[key].negativeValues;
+
+ if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
+ helpers.each(dataset.data, function(rawValue, index) {
+ var value = +me.getRightValue(rawValue);
+ if (isNaN(value) || meta.data[index].hidden) {
+ return;
+ }
+
+ positiveValues[index] = positiveValues[index] || 0;
+ negativeValues[index] = negativeValues[index] || 0;
+
+ if (opts.relativePoints) {
+ positiveValues[index] = 100;
+ } else if (value < 0) {
+ negativeValues[index] += value;
+ } else {
+ positiveValues[index] += value;
+ }
+ });
+ }
+ });
+
+ helpers.each(valuesPerStack, function(valuesForType) {
+ var values = valuesForType.positiveValues.concat(valuesForType.negativeValues);
+ var minVal = helpers.min(values);
+ var maxVal = helpers.max(values);
+ me.min = me.min === null ? minVal : Math.min(me.min, minVal);
+ me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
+ });
+
+ } else {
+ helpers.each(datasets, function(dataset, datasetIndex) {
+ var meta = chart.getDatasetMeta(datasetIndex);
+ if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
+ helpers.each(dataset.data, function(rawValue, index) {
+ var value = +me.getRightValue(rawValue);
+ if (isNaN(value) || meta.data[index].hidden) {
+ return;
+ }
+
+ if (me.min === null) {
+ me.min = value;
+ } else if (value < me.min) {
+ me.min = value;
+ }
+
+ if (me.max === null) {
+ me.max = value;
+ } else if (value > me.max) {
+ me.max = value;
+ }
+ });
+ }
+ });
+ }
+
+ me.min = isFinite(me.min) && !isNaN(me.min) ? me.min : DEFAULT_MIN;
+ me.max = isFinite(me.max) && !isNaN(me.max) ? me.max : DEFAULT_MAX;
+
+ // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
+ this.handleTickRangeOptions();
+ },
+ getTickLimit: function() {
+ var maxTicks;
+ var me = this;
+ var tickOpts = me.options.ticks;
+
+ if (me.isHorizontal()) {
+ maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50));
+ } else {
+ // The factor of 2 used to scale the font size has been experimentally determined.
+ var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, defaults.global.defaultFontSize);
+ maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize)));
+ }
+
+ return maxTicks;
+ },
+ // Called after the ticks are built. We need
+ handleDirectionalChanges: function() {
+ if (!this.isHorizontal()) {
+ // We are in a vertical orientation. The top value is the highest. So reverse the array
+ this.ticks.reverse();
+ }
+ },
+ getLabelForIndex: function(index, datasetIndex) {
+ return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
+ },
+ // Utils
+ getPixelForValue: function(value) {
+ // This must be called after fit has been run so that
+ // this.left, this.top, this.right, and this.bottom have been defined
+ var me = this;
+ var start = me.start;
+
+ var rightValue = +me.getRightValue(value);
+ var pixel;
+ var range = me.end - start;
+
+ if (me.isHorizontal()) {
+ pixel = me.left + (me.width / range * (rightValue - start));
+ } else {
+ pixel = me.bottom - (me.height / range * (rightValue - start));
+ }
+ return pixel;
+ },
+ getValueForPixel: function(pixel) {
+ var me = this;
+ var isHorizontal = me.isHorizontal();
+ var innerDimension = isHorizontal ? me.width : me.height;
+ var offset = (isHorizontal ? pixel - me.left : me.bottom - pixel) / innerDimension;
+ return me.start + ((me.end - me.start) * offset);
+ },
+ getPixelForTick: function(index) {
+ return this.getPixelForValue(this.ticksAsNumbers[index]);
+ }
+ });
+ Chart.scaleService.registerScaleType('linear', LinearScale, defaultConfig);
+
+};
+
+},{"25":25,"34":34,"45":45}],55:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+
+/**
+ * Generate a set of linear ticks
+ * @param generationOptions the options used to generate the ticks
+ * @param dataRange the range of the data
+ * @returns {Array} array of tick values
+ */
+function generateTicks(generationOptions, dataRange) {
+ var ticks = [];
+ // To get a "nice" value for the tick spacing, we will use the appropriately named
+ // "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks
+ // for details.
+
+ var spacing;
+ if (generationOptions.stepSize && generationOptions.stepSize > 0) {
+ spacing = generationOptions.stepSize;
+ } else {
+ var niceRange = helpers.niceNum(dataRange.max - dataRange.min, false);
+ spacing = helpers.niceNum(niceRange / (generationOptions.maxTicks - 1), true);
+ }
+ var niceMin = Math.floor(dataRange.min / spacing) * spacing;
+ var niceMax = Math.ceil(dataRange.max / spacing) * spacing;
+
+ // If min, max and stepSize is set and they make an evenly spaced scale use it.
+ if (generationOptions.min && generationOptions.max && generationOptions.stepSize) {
+ // If very close to our whole number, use it.
+ if (helpers.almostWhole((generationOptions.max - generationOptions.min) / generationOptions.stepSize, spacing / 1000)) {
+ niceMin = generationOptions.min;
+ niceMax = generationOptions.max;
+ }
+ }
+
+ var numSpaces = (niceMax - niceMin) / spacing;
+ // If very close to our rounded value, use it.
+ if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {
+ numSpaces = Math.round(numSpaces);
+ } else {
+ numSpaces = Math.ceil(numSpaces);
+ }
+
+ var precision = 1;
+ if (spacing < 1) {
+ precision = Math.pow(10, spacing.toString().length - 2);
+ niceMin = Math.round(niceMin * precision) / precision;
+ niceMax = Math.round(niceMax * precision) / precision;
+ }
+ ticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin);
+ for (var j = 1; j < numSpaces; ++j) {
+ ticks.push(Math.round((niceMin + j * spacing) * precision) / precision);
+ }
+ ticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax);
+
+ return ticks;
+}
+
+
+module.exports = function(Chart) {
+
+ var noop = helpers.noop;
+
+ Chart.LinearScaleBase = Chart.Scale.extend({
+ getRightValue: function(value) {
+ if (typeof value === 'string') {
+ return +value;
+ }
+ return Chart.Scale.prototype.getRightValue.call(this, value);
+ },
+
+ handleTickRangeOptions: function() {
+ var me = this;
+ var opts = me.options;
+ var tickOpts = opts.ticks;
+
+ // If we are forcing it to begin at 0, but 0 will already be rendered on the chart,
+ // do nothing since that would make the chart weird. If the user really wants a weird chart
+ // axis, they can manually override it
+ if (tickOpts.beginAtZero) {
+ var minSign = helpers.sign(me.min);
+ var maxSign = helpers.sign(me.max);
+
+ if (minSign < 0 && maxSign < 0) {
+ // move the top up to 0
+ me.max = 0;
+ } else if (minSign > 0 && maxSign > 0) {
+ // move the bottom down to 0
+ me.min = 0;
+ }
+ }
+
+ var setMin = tickOpts.min !== undefined || tickOpts.suggestedMin !== undefined;
+ var setMax = tickOpts.max !== undefined || tickOpts.suggestedMax !== undefined;
+
+ if (tickOpts.min !== undefined) {
+ me.min = tickOpts.min;
+ } else if (tickOpts.suggestedMin !== undefined) {
+ if (me.min === null) {
+ me.min = tickOpts.suggestedMin;
+ } else {
+ me.min = Math.min(me.min, tickOpts.suggestedMin);
+ }
+ }
+
+ if (tickOpts.max !== undefined) {
+ me.max = tickOpts.max;
+ } else if (tickOpts.suggestedMax !== undefined) {
+ if (me.max === null) {
+ me.max = tickOpts.suggestedMax;
+ } else {
+ me.max = Math.max(me.max, tickOpts.suggestedMax);
+ }
+ }
+
+ if (setMin !== setMax) {
+ // We set the min or the max but not both.
+ // So ensure that our range is good
+ // Inverted or 0 length range can happen when
+ // ticks.min is set, and no datasets are visible
+ if (me.min >= me.max) {
+ if (setMin) {
+ me.max = me.min + 1;
+ } else {
+ me.min = me.max - 1;
+ }
+ }
+ }
+
+ if (me.min === me.max) {
+ me.max++;
+
+ if (!tickOpts.beginAtZero) {
+ me.min--;
+ }
+ }
+ },
+ getTickLimit: noop,
+ handleDirectionalChanges: noop,
+
+ buildTicks: function() {
+ var me = this;
+ var opts = me.options;
+ var tickOpts = opts.ticks;
+
+ // Figure out what the max number of ticks we can support it is based on the size of
+ // the axis area. For now, we say that the minimum tick spacing in pixels must be 50
+ // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on
+ // the graph. Make sure we always have at least 2 ticks
+ var maxTicks = me.getTickLimit();
+ maxTicks = Math.max(2, maxTicks);
+
+ var numericGeneratorOptions = {
+ maxTicks: maxTicks,
+ min: tickOpts.min,
+ max: tickOpts.max,
+ stepSize: helpers.valueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize)
+ };
+ var ticks = me.ticks = generateTicks(numericGeneratorOptions, me);
+
+ me.handleDirectionalChanges();
+
+ // At this point, we need to update our max and min given the tick values since we have expanded the
+ // range of the scale
+ me.max = helpers.max(ticks);
+ me.min = helpers.min(ticks);
+
+ if (tickOpts.reverse) {
+ ticks.reverse();
+
+ me.start = me.max;
+ me.end = me.min;
+ } else {
+ me.start = me.min;
+ me.end = me.max;
+ }
+ },
+ convertTicksToLabels: function() {
+ var me = this;
+ me.ticksAsNumbers = me.ticks.slice();
+ me.zeroLineIndex = me.ticks.indexOf(0);
+
+ Chart.Scale.prototype.convertTicksToLabels.call(me);
+ }
+ });
+};
+
+},{"45":45}],56:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+var Ticks = require(34);
+
+/**
+ * Generate a set of logarithmic ticks
+ * @param generationOptions the options used to generate the ticks
+ * @param dataRange the range of the data
+ * @returns {Array} array of tick values
+ */
+function generateTicks(generationOptions, dataRange) {
+ var ticks = [];
+ var valueOrDefault = helpers.valueOrDefault;
+
+ // Figure out what the max number of ticks we can support it is based on the size of
+ // the axis area. For now, we say that the minimum tick spacing in pixels must be 50
+ // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on
+ // the graph
+ var tickVal = valueOrDefault(generationOptions.min, Math.pow(10, Math.floor(helpers.log10(dataRange.min))));
+
+ var endExp = Math.floor(helpers.log10(dataRange.max));
+ var endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));
+ var exp, significand;
+
+ if (tickVal === 0) {
+ exp = Math.floor(helpers.log10(dataRange.minNotZero));
+ significand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));
+
+ ticks.push(tickVal);
+ tickVal = significand * Math.pow(10, exp);
+ } else {
+ exp = Math.floor(helpers.log10(tickVal));
+ significand = Math.floor(tickVal / Math.pow(10, exp));
+ }
+ var precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1;
+
+ do {
+ ticks.push(tickVal);
+
+ ++significand;
+ if (significand === 10) {
+ significand = 1;
+ ++exp;
+ precision = exp >= 0 ? 1 : precision;
+ }
+
+ tickVal = Math.round(significand * Math.pow(10, exp) * precision) / precision;
+ } while (exp < endExp || (exp === endExp && significand < endSignificand));
+
+ var lastTick = valueOrDefault(generationOptions.max, tickVal);
+ ticks.push(lastTick);
+
+ return ticks;
+}
+
+
+module.exports = function(Chart) {
+
+ var defaultConfig = {
+ position: 'left',
+
+ // label settings
+ ticks: {
+ callback: Ticks.formatters.logarithmic
+ }
+ };
+
+ var LogarithmicScale = Chart.Scale.extend({
+ determineDataLimits: function() {
+ var me = this;
+ var opts = me.options;
+ var chart = me.chart;
+ var data = chart.data;
+ var datasets = data.datasets;
+ var isHorizontal = me.isHorizontal();
+ function IDMatches(meta) {
+ return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
+ }
+
+ // Calculate Range
+ me.min = null;
+ me.max = null;
+ me.minNotZero = null;
+
+ var hasStacks = opts.stacked;
+ if (hasStacks === undefined) {
+ helpers.each(datasets, function(dataset, datasetIndex) {
+ if (hasStacks) {
+ return;
+ }
+
+ var meta = chart.getDatasetMeta(datasetIndex);
+ if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
+ meta.stack !== undefined) {
+ hasStacks = true;
+ }
+ });
+ }
+
+ if (opts.stacked || hasStacks) {
+ var valuesPerStack = {};
+
+ helpers.each(datasets, function(dataset, datasetIndex) {
+ var meta = chart.getDatasetMeta(datasetIndex);
+ var key = [
+ meta.type,
+ // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
+ ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),
+ meta.stack
+ ].join('.');
+
+ if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
+ if (valuesPerStack[key] === undefined) {
+ valuesPerStack[key] = [];
+ }
+
+ helpers.each(dataset.data, function(rawValue, index) {
+ var values = valuesPerStack[key];
+ var value = +me.getRightValue(rawValue);
+ // invalid, hidden and negative values are ignored
+ if (isNaN(value) || meta.data[index].hidden || value < 0) {
+ return;
+ }
+ values[index] = values[index] || 0;
+ values[index] += value;
+ });
+ }
+ });
+
+ helpers.each(valuesPerStack, function(valuesForType) {
+ if (valuesForType.length > 0) {
+ var minVal = helpers.min(valuesForType);
+ var maxVal = helpers.max(valuesForType);
+ me.min = me.min === null ? minVal : Math.min(me.min, minVal);
+ me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
+ }
+ });
+
+ } else {
+ helpers.each(datasets, function(dataset, datasetIndex) {
+ var meta = chart.getDatasetMeta(datasetIndex);
+ if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
+ helpers.each(dataset.data, function(rawValue, index) {
+ var value = +me.getRightValue(rawValue);
+ // invalid, hidden and negative values are ignored
+ if (isNaN(value) || meta.data[index].hidden || value < 0) {
+ return;
+ }
+
+ if (me.min === null) {
+ me.min = value;
+ } else if (value < me.min) {
+ me.min = value;
+ }
+
+ if (me.max === null) {
+ me.max = value;
+ } else if (value > me.max) {
+ me.max = value;
+ }
+
+ if (value !== 0 && (me.minNotZero === null || value < me.minNotZero)) {
+ me.minNotZero = value;
+ }
+ });
+ }
+ });
+ }
+
+ // Common base implementation to handle ticks.min, ticks.max
+ this.handleTickRangeOptions();
+ },
+ handleTickRangeOptions: function() {
+ var me = this;
+ var opts = me.options;
+ var tickOpts = opts.ticks;
+ var valueOrDefault = helpers.valueOrDefault;
+ var DEFAULT_MIN = 1;
+ var DEFAULT_MAX = 10;
+
+ me.min = valueOrDefault(tickOpts.min, me.min);
+ me.max = valueOrDefault(tickOpts.max, me.max);
+
+ if (me.min === me.max) {
+ if (me.min !== 0 && me.min !== null) {
+ me.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1);
+ me.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1);
+ } else {
+ me.min = DEFAULT_MIN;
+ me.max = DEFAULT_MAX;
+ }
+ }
+ if (me.min === null) {
+ me.min = Math.pow(10, Math.floor(helpers.log10(me.max)) - 1);
+ }
+ if (me.max === null) {
+ me.max = me.min !== 0
+ ? Math.pow(10, Math.floor(helpers.log10(me.min)) + 1)
+ : DEFAULT_MAX;
+ }
+ if (me.minNotZero === null) {
+ if (me.min > 0) {
+ me.minNotZero = me.min;
+ } else if (me.max < 1) {
+ me.minNotZero = Math.pow(10, Math.floor(helpers.log10(me.max)));
+ } else {
+ me.minNotZero = DEFAULT_MIN;
+ }
+ }
+ },
+ buildTicks: function() {
+ var me = this;
+ var opts = me.options;
+ var tickOpts = opts.ticks;
+ var reverse = !me.isHorizontal();
+
+ var generationOptions = {
+ min: tickOpts.min,
+ max: tickOpts.max
+ };
+ var ticks = me.ticks = generateTicks(generationOptions, me);
+
+ // At this point, we need to update our max and min given the tick values since we have expanded the
+ // range of the scale
+ me.max = helpers.max(ticks);
+ me.min = helpers.min(ticks);
+
+ if (tickOpts.reverse) {
+ reverse = !reverse;
+ me.start = me.max;
+ me.end = me.min;
+ } else {
+ me.start = me.min;
+ me.end = me.max;
+ }
+ if (reverse) {
+ ticks.reverse();
+ }
+ },
+ convertTicksToLabels: function() {
+ this.tickValues = this.ticks.slice();
+
+ Chart.Scale.prototype.convertTicksToLabels.call(this);
+ },
+ // Get the correct tooltip label
+ getLabelForIndex: function(index, datasetIndex) {
+ return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
+ },
+ getPixelForTick: function(index) {
+ return this.getPixelForValue(this.tickValues[index]);
+ },
+ /**
+ * Returns the value of the first tick.
+ * @param {Number} value - The minimum not zero value.
+ * @return {Number} The first tick value.
+ * @private
+ */
+ _getFirstTickValue: function(value) {
+ var exp = Math.floor(helpers.log10(value));
+ var significand = Math.floor(value / Math.pow(10, exp));
+
+ return significand * Math.pow(10, exp);
+ },
+ getPixelForValue: function(value) {
+ var me = this;
+ var reverse = me.options.ticks.reverse;
+ var log10 = helpers.log10;
+ var firstTickValue = me._getFirstTickValue(me.minNotZero);
+ var offset = 0;
+ var innerDimension, pixel, start, end, sign;
+
+ value = +me.getRightValue(value);
+ if (reverse) {
+ start = me.end;
+ end = me.start;
+ sign = -1;
+ } else {
+ start = me.start;
+ end = me.end;
+ sign = 1;
+ }
+ if (me.isHorizontal()) {
+ innerDimension = me.width;
+ pixel = reverse ? me.right : me.left;
+ } else {
+ innerDimension = me.height;
+ sign *= -1; // invert, since the upper-left corner of the canvas is at pixel (0, 0)
+ pixel = reverse ? me.top : me.bottom;
+ }
+ if (value !== start) {
+ if (start === 0) { // include zero tick
+ offset = helpers.getValueOrDefault(
+ me.options.ticks.fontSize,
+ Chart.defaults.global.defaultFontSize
+ );
+ innerDimension -= offset;
+ start = firstTickValue;
+ }
+ if (value !== 0) {
+ offset += innerDimension / (log10(end) - log10(start)) * (log10(value) - log10(start));
+ }
+ pixel += sign * offset;
+ }
+ return pixel;
+ },
+ getValueForPixel: function(pixel) {
+ var me = this;
+ var reverse = me.options.ticks.reverse;
+ var log10 = helpers.log10;
+ var firstTickValue = me._getFirstTickValue(me.minNotZero);
+ var innerDimension, start, end, value;
+
+ if (reverse) {
+ start = me.end;
+ end = me.start;
+ } else {
+ start = me.start;
+ end = me.end;
+ }
+ if (me.isHorizontal()) {
+ innerDimension = me.width;
+ value = reverse ? me.right - pixel : pixel - me.left;
+ } else {
+ innerDimension = me.height;
+ value = reverse ? pixel - me.top : me.bottom - pixel;
+ }
+ if (value !== start) {
+ if (start === 0) { // include zero tick
+ var offset = helpers.getValueOrDefault(
+ me.options.ticks.fontSize,
+ Chart.defaults.global.defaultFontSize
+ );
+ value -= offset;
+ innerDimension -= offset;
+ start = firstTickValue;
+ }
+ value *= log10(end) - log10(start);
+ value /= innerDimension;
+ value = Math.pow(10, log10(start) + value);
+ }
+ return value;
+ }
+ });
+ Chart.scaleService.registerScaleType('logarithmic', LogarithmicScale, defaultConfig);
+
+};
+
+},{"34":34,"45":45}],57:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var helpers = require(45);
+var Ticks = require(34);
+
+module.exports = function(Chart) {
+
+ var globalDefaults = defaults.global;
+
+ var defaultConfig = {
+ display: true,
+
+ // Boolean - Whether to animate scaling the chart from the centre
+ animate: true,
+ position: 'chartArea',
+
+ angleLines: {
+ display: true,
+ color: 'rgba(0, 0, 0, 0.1)',
+ lineWidth: 1
+ },
+
+ gridLines: {
+ circular: false
+ },
+
+ // label settings
+ ticks: {
+ // Boolean - Show a backdrop to the scale label
+ showLabelBackdrop: true,
+
+ // String - The colour of the label backdrop
+ backdropColor: 'rgba(255,255,255,0.75)',
+
+ // Number - The backdrop padding above & below the label in pixels
+ backdropPaddingY: 2,
+
+ // Number - The backdrop padding to the side of the label in pixels
+ backdropPaddingX: 2,
+
+ callback: Ticks.formatters.linear
+ },
+
+ pointLabels: {
+ // Boolean - if true, show point labels
+ display: true,
+
+ // Number - Point label font size in pixels
+ fontSize: 10,
+
+ // Function - Used to convert point labels
+ callback: function(label) {
+ return label;
+ }
+ }
+ };
+
+ function getValueCount(scale) {
+ var opts = scale.options;
+ return opts.angleLines.display || opts.pointLabels.display ? scale.chart.data.labels.length : 0;
+ }
+
+ function getPointLabelFontOptions(scale) {
+ var pointLabelOptions = scale.options.pointLabels;
+ var fontSize = helpers.valueOrDefault(pointLabelOptions.fontSize, globalDefaults.defaultFontSize);
+ var fontStyle = helpers.valueOrDefault(pointLabelOptions.fontStyle, globalDefaults.defaultFontStyle);
+ var fontFamily = helpers.valueOrDefault(pointLabelOptions.fontFamily, globalDefaults.defaultFontFamily);
+ var font = helpers.fontString(fontSize, fontStyle, fontFamily);
+
+ return {
+ size: fontSize,
+ style: fontStyle,
+ family: fontFamily,
+ font: font
+ };
+ }
+
+ function measureLabelSize(ctx, fontSize, label) {
+ if (helpers.isArray(label)) {
+ return {
+ w: helpers.longestText(ctx, ctx.font, label),
+ h: (label.length * fontSize) + ((label.length - 1) * 1.5 * fontSize)
+ };
+ }
+
+ return {
+ w: ctx.measureText(label).width,
+ h: fontSize
+ };
+ }
+
+ function determineLimits(angle, pos, size, min, max) {
+ if (angle === min || angle === max) {
+ return {
+ start: pos - (size / 2),
+ end: pos + (size / 2)
+ };
+ } else if (angle < min || angle > max) {
+ return {
+ start: pos - size - 5,
+ end: pos
+ };
+ }
+
+ return {
+ start: pos,
+ end: pos + size + 5
+ };
+ }
+
+ /**
+ * Helper function to fit a radial linear scale with point labels
+ */
+ function fitWithPointLabels(scale) {
+ /*
+ * Right, this is really confusing and there is a lot of maths going on here
+ * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9
+ *
+ * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif
+ *
+ * Solution:
+ *
+ * We assume the radius of the polygon is half the size of the canvas at first
+ * at each index we check if the text overlaps.
+ *
+ * Where it does, we store that angle and that index.
+ *
+ * After finding the largest index and angle we calculate how much we need to remove
+ * from the shape radius to move the point inwards by that x.
+ *
+ * We average the left and right distances to get the maximum shape radius that can fit in the box
+ * along with labels.
+ *
+ * Once we have that, we can find the centre point for the chart, by taking the x text protrusion
+ * on each side, removing that from the size, halving it and adding the left x protrusion width.
+ *
+ * This will mean we have a shape fitted to the canvas, as large as it can be with the labels
+ * and position it in the most space efficient manner
+ *
+ * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif
+ */
+
+ var plFont = getPointLabelFontOptions(scale);
+
+ // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.
+ // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points
+ var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);
+ var furthestLimits = {
+ r: scale.width,
+ l: 0,
+ t: scale.height,
+ b: 0
+ };
+ var furthestAngles = {};
+ var i, textSize, pointPosition;
+
+ scale.ctx.font = plFont.font;
+ scale._pointLabelSizes = [];
+
+ var valueCount = getValueCount(scale);
+ for (i = 0; i < valueCount; i++) {
+ pointPosition = scale.getPointPosition(i, largestPossibleRadius);
+ textSize = measureLabelSize(scale.ctx, plFont.size, scale.pointLabels[i] || '');
+ scale._pointLabelSizes[i] = textSize;
+
+ // Add quarter circle to make degree 0 mean top of circle
+ var angleRadians = scale.getIndexAngle(i);
+ var angle = helpers.toDegrees(angleRadians) % 360;
+ var hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);
+ var vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);
+
+ if (hLimits.start < furthestLimits.l) {
+ furthestLimits.l = hLimits.start;
+ furthestAngles.l = angleRadians;
+ }
+
+ if (hLimits.end > furthestLimits.r) {
+ furthestLimits.r = hLimits.end;
+ furthestAngles.r = angleRadians;
+ }
+
+ if (vLimits.start < furthestLimits.t) {
+ furthestLimits.t = vLimits.start;
+ furthestAngles.t = angleRadians;
+ }
+
+ if (vLimits.end > furthestLimits.b) {
+ furthestLimits.b = vLimits.end;
+ furthestAngles.b = angleRadians;
+ }
+ }
+
+ scale.setReductions(largestPossibleRadius, furthestLimits, furthestAngles);
+ }
+
+ /**
+ * Helper function to fit a radial linear scale with no point labels
+ */
+ function fit(scale) {
+ var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);
+ scale.drawingArea = Math.round(largestPossibleRadius);
+ scale.setCenterPoint(0, 0, 0, 0);
+ }
+
+ function getTextAlignForAngle(angle) {
+ if (angle === 0 || angle === 180) {
+ return 'center';
+ } else if (angle < 180) {
+ return 'left';
+ }
+
+ return 'right';
+ }
+
+ function fillText(ctx, text, position, fontSize) {
+ if (helpers.isArray(text)) {
+ var y = position.y;
+ var spacing = 1.5 * fontSize;
+
+ for (var i = 0; i < text.length; ++i) {
+ ctx.fillText(text[i], position.x, y);
+ y += spacing;
+ }
+ } else {
+ ctx.fillText(text, position.x, position.y);
+ }
+ }
+
+ function adjustPointPositionForLabelHeight(angle, textSize, position) {
+ if (angle === 90 || angle === 270) {
+ position.y -= (textSize.h / 2);
+ } else if (angle > 270 || angle < 90) {
+ position.y -= textSize.h;
+ }
+ }
+
+ function drawPointLabels(scale) {
+ var ctx = scale.ctx;
+ var opts = scale.options;
+ var angleLineOpts = opts.angleLines;
+ var pointLabelOpts = opts.pointLabels;
+
+ ctx.lineWidth = angleLineOpts.lineWidth;
+ ctx.strokeStyle = angleLineOpts.color;
+
+ var outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max);
+
+ // Point Label Font
+ var plFont = getPointLabelFontOptions(scale);
+
+ ctx.textBaseline = 'top';
+
+ for (var i = getValueCount(scale) - 1; i >= 0; i--) {
+ if (angleLineOpts.display) {
+ var outerPosition = scale.getPointPosition(i, outerDistance);
+ ctx.beginPath();
+ ctx.moveTo(scale.xCenter, scale.yCenter);
+ ctx.lineTo(outerPosition.x, outerPosition.y);
+ ctx.stroke();
+ ctx.closePath();
+ }
+
+ if (pointLabelOpts.display) {
+ // Extra 3px out for some label spacing
+ var pointLabelPosition = scale.getPointPosition(i, outerDistance + 5);
+
+ // Keep this in loop since we may support array properties here
+ var pointLabelFontColor = helpers.valueAtIndexOrDefault(pointLabelOpts.fontColor, i, globalDefaults.defaultFontColor);
+ ctx.font = plFont.font;
+ ctx.fillStyle = pointLabelFontColor;
+
+ var angleRadians = scale.getIndexAngle(i);
+ var angle = helpers.toDegrees(angleRadians);
+ ctx.textAlign = getTextAlignForAngle(angle);
+ adjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition);
+ fillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.size);
+ }
+ }
+ }
+
+ function drawRadiusLine(scale, gridLineOpts, radius, index) {
+ var ctx = scale.ctx;
+ ctx.strokeStyle = helpers.valueAtIndexOrDefault(gridLineOpts.color, index - 1);
+ ctx.lineWidth = helpers.valueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);
+
+ if (scale.options.gridLines.circular) {
+ // Draw circular arcs between the points
+ ctx.beginPath();
+ ctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2);
+ ctx.closePath();
+ ctx.stroke();
+ } else {
+ // Draw straight lines connecting each index
+ var valueCount = getValueCount(scale);
+
+ if (valueCount === 0) {
+ return;
+ }
+
+ ctx.beginPath();
+ var pointPosition = scale.getPointPosition(0, radius);
+ ctx.moveTo(pointPosition.x, pointPosition.y);
+
+ for (var i = 1; i < valueCount; i++) {
+ pointPosition = scale.getPointPosition(i, radius);
+ ctx.lineTo(pointPosition.x, pointPosition.y);
+ }
+
+ ctx.closePath();
+ ctx.stroke();
+ }
+ }
+
+ function numberOrZero(param) {
+ return helpers.isNumber(param) ? param : 0;
+ }
+
+ var LinearRadialScale = Chart.LinearScaleBase.extend({
+ setDimensions: function() {
+ var me = this;
+ var opts = me.options;
+ var tickOpts = opts.ticks;
+ // Set the unconstrained dimension before label rotation
+ me.width = me.maxWidth;
+ me.height = me.maxHeight;
+ me.xCenter = Math.round(me.width / 2);
+ me.yCenter = Math.round(me.height / 2);
+
+ var minSize = helpers.min([me.height, me.width]);
+ var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
+ me.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2);
+ },
+ determineDataLimits: function() {
+ var me = this;
+ var chart = me.chart;
+ var min = Number.POSITIVE_INFINITY;
+ var max = Number.NEGATIVE_INFINITY;
+
+ helpers.each(chart.data.datasets, function(dataset, datasetIndex) {
+ if (chart.isDatasetVisible(datasetIndex)) {
+ var meta = chart.getDatasetMeta(datasetIndex);
+
+ helpers.each(dataset.data, function(rawValue, index) {
+ var value = +me.getRightValue(rawValue);
+ if (isNaN(value) || meta.data[index].hidden) {
+ return;
+ }
+
+ min = Math.min(value, min);
+ max = Math.max(value, max);
+ });
+ }
+ });
+
+ me.min = (min === Number.POSITIVE_INFINITY ? 0 : min);
+ me.max = (max === Number.NEGATIVE_INFINITY ? 0 : max);
+
+ // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
+ me.handleTickRangeOptions();
+ },
+ getTickLimit: function() {
+ var tickOpts = this.options.ticks;
+ var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
+ return Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize)));
+ },
+ convertTicksToLabels: function() {
+ var me = this;
+
+ Chart.LinearScaleBase.prototype.convertTicksToLabels.call(me);
+
+ // Point labels
+ me.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me);
+ },
+ getLabelForIndex: function(index, datasetIndex) {
+ return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
+ },
+ fit: function() {
+ if (this.options.pointLabels.display) {
+ fitWithPointLabels(this);
+ } else {
+ fit(this);
+ }
+ },
+ /**
+ * Set radius reductions and determine new radius and center point
+ * @private
+ */
+ setReductions: function(largestPossibleRadius, furthestLimits, furthestAngles) {
+ var me = this;
+ var radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l);
+ var radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r);
+ var radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t);
+ var radiusReductionBottom = -Math.max(furthestLimits.b - me.height, 0) / Math.cos(furthestAngles.b);
+
+ radiusReductionLeft = numberOrZero(radiusReductionLeft);
+ radiusReductionRight = numberOrZero(radiusReductionRight);
+ radiusReductionTop = numberOrZero(radiusReductionTop);
+ radiusReductionBottom = numberOrZero(radiusReductionBottom);
+
+ me.drawingArea = Math.min(
+ Math.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2),
+ Math.round(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2));
+ me.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom);
+ },
+ setCenterPoint: function(leftMovement, rightMovement, topMovement, bottomMovement) {
+ var me = this;
+ var maxRight = me.width - rightMovement - me.drawingArea;
+ var maxLeft = leftMovement + me.drawingArea;
+ var maxTop = topMovement + me.drawingArea;
+ var maxBottom = me.height - bottomMovement - me.drawingArea;
+
+ me.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left);
+ me.yCenter = Math.round(((maxTop + maxBottom) / 2) + me.top);
+ },
+
+ getIndexAngle: function(index) {
+ var angleMultiplier = (Math.PI * 2) / getValueCount(this);
+ var startAngle = this.chart.options && this.chart.options.startAngle ?
+ this.chart.options.startAngle :
+ 0;
+
+ var startAngleRadians = startAngle * Math.PI * 2 / 360;
+
+ // Start from the top instead of right, so remove a quarter of the circle
+ return index * angleMultiplier + startAngleRadians;
+ },
+ getDistanceFromCenterForValue: function(value) {
+ var me = this;
+
+ if (value === null) {
+ return 0; // null always in center
+ }
+
+ // Take into account half font size + the yPadding of the top value
+ var scalingFactor = me.drawingArea / (me.max - me.min);
+ if (me.options.ticks.reverse) {
+ return (me.max - value) * scalingFactor;
+ }
+ return (value - me.min) * scalingFactor;
+ },
+ getPointPosition: function(index, distanceFromCenter) {
+ var me = this;
+ var thisAngle = me.getIndexAngle(index) - (Math.PI / 2);
+ return {
+ x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter,
+ y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter
+ };
+ },
+ getPointPositionForValue: function(index, value) {
+ return this.getPointPosition(index, this.getDistanceFromCenterForValue(value));
+ },
+
+ getBasePosition: function() {
+ var me = this;
+ var min = me.min;
+ var max = me.max;
+
+ return me.getPointPositionForValue(0,
+ me.beginAtZero ? 0 :
+ min < 0 && max < 0 ? max :
+ min > 0 && max > 0 ? min :
+ 0);
+ },
+
+ draw: function() {
+ var me = this;
+ var opts = me.options;
+ var gridLineOpts = opts.gridLines;
+ var tickOpts = opts.ticks;
+ var valueOrDefault = helpers.valueOrDefault;
+
+ if (opts.display) {
+ var ctx = me.ctx;
+ var startAngle = this.getIndexAngle(0);
+
+ // Tick Font
+ var tickFontSize = valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
+ var tickFontStyle = valueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);
+ var tickFontFamily = valueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);
+ var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
+
+ helpers.each(me.ticks, function(label, index) {
+ // Don't draw a centre value (if it is minimum)
+ if (index > 0 || tickOpts.reverse) {
+ var yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);
+
+ // Draw circular lines around the scale
+ if (gridLineOpts.display && index !== 0) {
+ drawRadiusLine(me, gridLineOpts, yCenterOffset, index);
+ }
+
+ if (tickOpts.display) {
+ var tickFontColor = valueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor);
+ ctx.font = tickLabelFont;
+
+ ctx.save();
+ ctx.translate(me.xCenter, me.yCenter);
+ ctx.rotate(startAngle);
+
+ if (tickOpts.showLabelBackdrop) {
+ var labelWidth = ctx.measureText(label).width;
+ ctx.fillStyle = tickOpts.backdropColor;
+ ctx.fillRect(
+ -labelWidth / 2 - tickOpts.backdropPaddingX,
+ -yCenterOffset - tickFontSize / 2 - tickOpts.backdropPaddingY,
+ labelWidth + tickOpts.backdropPaddingX * 2,
+ tickFontSize + tickOpts.backdropPaddingY * 2
+ );
+ }
+
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'middle';
+ ctx.fillStyle = tickFontColor;
+ ctx.fillText(label, 0, -yCenterOffset);
+ ctx.restore();
+ }
+ }
+ });
+
+ if (opts.angleLines.display || opts.pointLabels.display) {
+ drawPointLabels(me);
+ }
+ }
+ }
+ });
+ Chart.scaleService.registerScaleType('radialLinear', LinearRadialScale, defaultConfig);
+
+};
+
+},{"25":25,"34":34,"45":45}],58:[function(require,module,exports){
+/* global window: false */
+'use strict';
+
+var moment = require(6);
+moment = typeof moment === 'function' ? moment : window.moment;
+
+var defaults = require(25);
+var helpers = require(45);
+
+// Integer constants are from the ES6 spec.
+var MIN_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991;
+var MAX_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
+
+var INTERVALS = {
+ millisecond: {
+ common: true,
+ size: 1,
+ steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]
+ },
+ second: {
+ common: true,
+ size: 1000,
+ steps: [1, 2, 5, 10, 30]
+ },
+ minute: {
+ common: true,
+ size: 60000,
+ steps: [1, 2, 5, 10, 30]
+ },
+ hour: {
+ common: true,
+ size: 3600000,
+ steps: [1, 2, 3, 6, 12]
+ },
+ day: {
+ common: true,
+ size: 86400000,
+ steps: [1, 2, 5]
+ },
+ week: {
+ common: false,
+ size: 604800000,
+ steps: [1, 2, 3, 4]
+ },
+ month: {
+ common: true,
+ size: 2.628e9,
+ steps: [1, 2, 3]
+ },
+ quarter: {
+ common: false,
+ size: 7.884e9,
+ steps: [1, 2, 3, 4]
+ },
+ year: {
+ common: true,
+ size: 3.154e10
+ }
+};
+
+var UNITS = Object.keys(INTERVALS);
+
+function sorter(a, b) {
+ return a - b;
+}
+
+function arrayUnique(items) {
+ var hash = {};
+ var out = [];
+ var i, ilen, item;
+
+ for (i = 0, ilen = items.length; i < ilen; ++i) {
+ item = items[i];
+ if (!hash[item]) {
+ hash[item] = true;
+ out.push(item);
+ }
+ }
+
+ return out;
+}
+
+/**
+ * Returns an array of {time, pos} objects used to interpolate a specific `time` or position
+ * (`pos`) on the scale, by searching entries before and after the requested value. `pos` is
+ * a decimal between 0 and 1: 0 being the start of the scale (left or top) and 1 the other
+ * extremity (left + width or top + height). Note that it would be more optimized to directly
+ * store pre-computed pixels, but the scale dimensions are not guaranteed at the time we need
+ * to create the lookup table. The table ALWAYS contains at least two items: min and max.
+ *
+ * @param {Number[]} timestamps - timestamps sorted from lowest to highest.
+ * @param {String} distribution - If 'linear', timestamps will be spread linearly along the min
+ * and max range, so basically, the table will contains only two items: {min, 0} and {max, 1}.
+ * If 'series', timestamps will be positioned at the same distance from each other. In this
+ * case, only timestamps that break the time linearity are registered, meaning that in the
+ * best case, all timestamps are linear, the table contains only min and max.
+ */
+function buildLookupTable(timestamps, min, max, distribution) {
+ if (distribution === 'linear' || !timestamps.length) {
+ return [
+ {time: min, pos: 0},
+ {time: max, pos: 1}
+ ];
+ }
+
+ var table = [];
+ var items = [min];
+ var i, ilen, prev, curr, next;
+
+ for (i = 0, ilen = timestamps.length; i < ilen; ++i) {
+ curr = timestamps[i];
+ if (curr > min && curr < max) {
+ items.push(curr);
+ }
+ }
+
+ items.push(max);
+
+ for (i = 0, ilen = items.length; i < ilen; ++i) {
+ next = items[i + 1];
+ prev = items[i - 1];
+ curr = items[i];
+
+ // only add points that breaks the scale linearity
+ if (prev === undefined || next === undefined || Math.round((next + prev) / 2) !== curr) {
+ table.push({time: curr, pos: i / (ilen - 1)});
+ }
+ }
+
+ return table;
+}
+
+// @see adapted from http://www.anujgakhar.com/2014/03/01/binary-search-in-javascript/
+function lookup(table, key, value) {
+ var lo = 0;
+ var hi = table.length - 1;
+ var mid, i0, i1;
+
+ while (lo >= 0 && lo <= hi) {
+ mid = (lo + hi) >> 1;
+ i0 = table[mid - 1] || null;
+ i1 = table[mid];
+
+ if (!i0) {
+ // given value is outside table (before first item)
+ return {lo: null, hi: i1};
+ } else if (i1[key] < value) {
+ lo = mid + 1;
+ } else if (i0[key] > value) {
+ hi = mid - 1;
+ } else {
+ return {lo: i0, hi: i1};
+ }
+ }
+
+ // given value is outside table (after last item)
+ return {lo: i1, hi: null};
+}
+
+/**
+ * Linearly interpolates the given source `value` using the table items `skey` values and
+ * returns the associated `tkey` value. For example, interpolate(table, 'time', 42, 'pos')
+ * returns the position for a timestamp equal to 42. If value is out of bounds, values at
+ * index [0, 1] or [n - 1, n] are used for the interpolation.
+ */
+function interpolate(table, skey, sval, tkey) {
+ var range = lookup(table, skey, sval);
+
+ // Note: the lookup table ALWAYS contains at least 2 items (min and max)
+ var prev = !range.lo ? table[0] : !range.hi ? table[table.length - 2] : range.lo;
+ var next = !range.lo ? table[1] : !range.hi ? table[table.length - 1] : range.hi;
+
+ var span = next[skey] - prev[skey];
+ var ratio = span ? (sval - prev[skey]) / span : 0;
+ var offset = (next[tkey] - prev[tkey]) * ratio;
+
+ return prev[tkey] + offset;
+}
+
+/**
+ * Convert the given value to a moment object using the given time options.
+ * @see http://momentjs.com/docs/#/parsing/
+ */
+function momentify(value, options) {
+ var parser = options.parser;
+ var format = options.parser || options.format;
+
+ if (typeof parser === 'function') {
+ return parser(value);
+ }
+
+ if (typeof value === 'string' && typeof format === 'string') {
+ return moment(value, format);
+ }
+
+ if (!(value instanceof moment)) {
+ value = moment(value);
+ }
+
+ if (value.isValid()) {
+ return value;
+ }
+
+ // Labels are in an incompatible moment format and no `parser` has been provided.
+ // The user might still use the deprecated `format` option to convert his inputs.
+ if (typeof format === 'function') {
+ return format(value);
+ }
+
+ return value;
+}
+
+function parse(input, scale) {
+ if (helpers.isNullOrUndef(input)) {
+ return null;
+ }
+
+ var options = scale.options.time;
+ var value = momentify(scale.getRightValue(input), options);
+ if (!value.isValid()) {
+ return null;
+ }
+
+ if (options.round) {
+ value.startOf(options.round);
+ }
+
+ return value.valueOf();
+}
+
+/**
+ * Returns the number of unit to skip to be able to display up to `capacity` number of ticks
+ * in `unit` for the given `min` / `max` range and respecting the interval steps constraints.
+ */
+function determineStepSize(min, max, unit, capacity) {
+ var range = max - min;
+ var interval = INTERVALS[unit];
+ var milliseconds = interval.size;
+ var steps = interval.steps;
+ var i, ilen, factor;
+
+ if (!steps) {
+ return Math.ceil(range / (capacity * milliseconds));
+ }
+
+ for (i = 0, ilen = steps.length; i < ilen; ++i) {
+ factor = steps[i];
+ if (Math.ceil(range / (milliseconds * factor)) <= capacity) {
+ break;
+ }
+ }
+
+ return factor;
+}
+
+/**
+ * Figures out what unit results in an appropriate number of auto-generated ticks
+ */
+function determineUnitForAutoTicks(minUnit, min, max, capacity) {
+ var ilen = UNITS.length;
+ var i, interval, factor;
+
+ for (i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) {
+ interval = INTERVALS[UNITS[i]];
+ factor = interval.steps ? interval.steps[interval.steps.length - 1] : MAX_INTEGER;
+
+ if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) {
+ return UNITS[i];
+ }
+ }
+
+ return UNITS[ilen - 1];
+}
+
+/**
+ * Figures out what unit to format a set of ticks with
+ */
+function determineUnitForFormatting(ticks, minUnit, min, max) {
+ var duration = moment.duration(moment(max).diff(moment(min)));
+ var ilen = UNITS.length;
+ var i, unit;
+
+ for (i = ilen - 1; i >= UNITS.indexOf(minUnit); i--) {
+ unit = UNITS[i];
+ if (INTERVALS[unit].common && duration.as(unit) >= ticks.length) {
+ return unit;
+ }
+ }
+
+ return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0];
+}
+
+function determineMajorUnit(unit) {
+ for (var i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i) {
+ if (INTERVALS[UNITS[i]].common) {
+ return UNITS[i];
+ }
+ }
+}
+
+/**
+ * Generates a maximum of `capacity` timestamps between min and max, rounded to the
+ * `minor` unit, aligned on the `major` unit and using the given scale time `options`.
+ * Important: this method can return ticks outside the min and max range, it's the
+ * responsibility of the calling code to clamp values if needed.
+ */
+function generate(min, max, capacity, options) {
+ var timeOpts = options.time;
+ var minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, capacity);
+ var major = determineMajorUnit(minor);
+ var stepSize = helpers.valueOrDefault(timeOpts.stepSize, timeOpts.unitStepSize);
+ var weekday = minor === 'week' ? timeOpts.isoWeekday : false;
+ var majorTicksEnabled = options.ticks.major.enabled;
+ var interval = INTERVALS[minor];
+ var first = moment(min);
+ var last = moment(max);
+ var ticks = [];
+ var time;
+
+ if (!stepSize) {
+ stepSize = determineStepSize(min, max, minor, capacity);
+ }
+
+ // For 'week' unit, handle the first day of week option
+ if (weekday) {
+ first = first.isoWeekday(weekday);
+ last = last.isoWeekday(weekday);
+ }
+
+ // Align first/last ticks on unit
+ first = first.startOf(weekday ? 'day' : minor);
+ last = last.startOf(weekday ? 'day' : minor);
+
+ // Make sure that the last tick include max
+ if (last < max) {
+ last.add(1, minor);
+ }
+
+ time = moment(first);
+
+ if (majorTicksEnabled && major && !weekday && !timeOpts.round) {
+ // Align the first tick on the previous `minor` unit aligned on the `major` unit:
+ // we first aligned time on the previous `major` unit then add the number of full
+ // stepSize there is between first and the previous major time.
+ time.startOf(major);
+ time.add(~~((first - time) / (interval.size * stepSize)) * stepSize, minor);
+ }
+
+ for (; time < last; time.add(stepSize, minor)) {
+ ticks.push(+time);
+ }
+
+ ticks.push(+time);
+
+ return ticks;
+}
+
+/**
+ * Returns the right and left offsets from edges in the form of {left, right}.
+ * Offsets are added when the `offset` option is true.
+ */
+function computeOffsets(table, ticks, min, max, options) {
+ var left = 0;
+ var right = 0;
+ var upper, lower;
+
+ if (options.offset && ticks.length) {
+ if (!options.time.min) {
+ upper = ticks.length > 1 ? ticks[1] : max;
+ lower = ticks[0];
+ left = (
+ interpolate(table, 'time', upper, 'pos') -
+ interpolate(table, 'time', lower, 'pos')
+ ) / 2;
+ }
+ if (!options.time.max) {
+ upper = ticks[ticks.length - 1];
+ lower = ticks.length > 1 ? ticks[ticks.length - 2] : min;
+ right = (
+ interpolate(table, 'time', upper, 'pos') -
+ interpolate(table, 'time', lower, 'pos')
+ ) / 2;
+ }
+ }
+
+ return {left: left, right: right};
+}
+
+function ticksFromTimestamps(values, majorUnit) {
+ var ticks = [];
+ var i, ilen, value, major;
+
+ for (i = 0, ilen = values.length; i < ilen; ++i) {
+ value = values[i];
+ major = majorUnit ? value === +moment(value).startOf(majorUnit) : false;
+
+ ticks.push({
+ value: value,
+ major: major
+ });
+ }
+
+ return ticks;
+}
+
+function determineLabelFormat(data, timeOpts) {
+ var i, momentDate, hasTime;
+ var ilen = data.length;
+
+ // find the label with the most parts (milliseconds, minutes, etc.)
+ // format all labels with the same level of detail as the most specific label
+ for (i = 0; i < ilen; i++) {
+ momentDate = momentify(data[i], timeOpts);
+ if (momentDate.millisecond() !== 0) {
+ return 'MMM D, YYYY h:mm:ss.SSS a';
+ }
+ if (momentDate.second() !== 0 || momentDate.minute() !== 0 || momentDate.hour() !== 0) {
+ hasTime = true;
+ }
+ }
+ if (hasTime) {
+ return 'MMM D, YYYY h:mm:ss a';
+ }
+ return 'MMM D, YYYY';
+}
+
+module.exports = function(Chart) {
+
+ var defaultConfig = {
+ position: 'bottom',
+
+ /**
+ * Data distribution along the scale:
+ * - 'linear': data are spread according to their time (distances can vary),
+ * - 'series': data are spread at the same distance from each other.
+ * @see https://github.com/chartjs/Chart.js/pull/4507
+ * @since 2.7.0
+ */
+ distribution: 'linear',
+
+ /**
+ * Scale boundary strategy (bypassed by min/max time options)
+ * - `data`: make sure data are fully visible, ticks outside are removed
+ * - `ticks`: make sure ticks are fully visible, data outside are truncated
+ * @see https://github.com/chartjs/Chart.js/pull/4556
+ * @since 2.7.0
+ */
+ bounds: 'data',
+
+ time: {
+ parser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment
+ format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/
+ unit: false, // false == automatic or override with week, month, year, etc.
+ round: false, // none, or override with week, month, year, etc.
+ displayFormat: false, // DEPRECATED
+ isoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/
+ minUnit: 'millisecond',
+
+ // defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/
+ displayFormats: {
+ millisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM,
+ second: 'h:mm:ss a', // 11:20:01 AM
+ minute: 'h:mm a', // 11:20 AM
+ hour: 'hA', // 5PM
+ day: 'MMM D', // Sep 4
+ week: 'll', // Week 46, or maybe "[W]WW - YYYY" ?
+ month: 'MMM YYYY', // Sept 2015
+ quarter: '[Q]Q - YYYY', // Q3
+ year: 'YYYY' // 2015
+ },
+ },
+ ticks: {
+ autoSkip: false,
+
+ /**
+ * Ticks generation input values:
+ * - 'auto': generates "optimal" ticks based on scale size and time options.
+ * - 'data': generates ticks from data (including labels from data {t|x|y} objects).
+ * - 'labels': generates ticks from user given `data.labels` values ONLY.
+ * @see https://github.com/chartjs/Chart.js/pull/4507
+ * @since 2.7.0
+ */
+ source: 'auto',
+
+ major: {
+ enabled: false
+ }
+ }
+ };
+
+ var TimeScale = Chart.Scale.extend({
+ initialize: function() {
+ if (!moment) {
+ throw new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com');
+ }
+
+ this.mergeTicksOptions();
+
+ Chart.Scale.prototype.initialize.call(this);
+ },
+
+ update: function() {
+ var me = this;
+ var options = me.options;
+
+ // DEPRECATIONS: output a message only one time per update
+ if (options.time && options.time.format) {
+ console.warn('options.time.format is deprecated and replaced by options.time.parser.');
+ }
+
+ return Chart.Scale.prototype.update.apply(me, arguments);
+ },
+
+ /**
+ * Allows data to be referenced via 't' attribute
+ */
+ getRightValue: function(rawValue) {
+ if (rawValue && rawValue.t !== undefined) {
+ rawValue = rawValue.t;
+ }
+ return Chart.Scale.prototype.getRightValue.call(this, rawValue);
+ },
+
+ determineDataLimits: function() {
+ var me = this;
+ var chart = me.chart;
+ var timeOpts = me.options.time;
+ var unit = timeOpts.unit || 'day';
+ var min = MAX_INTEGER;
+ var max = MIN_INTEGER;
+ var timestamps = [];
+ var datasets = [];
+ var labels = [];
+ var i, j, ilen, jlen, data, timestamp;
+
+ // Convert labels to timestamps
+ for (i = 0, ilen = chart.data.labels.length; i < ilen; ++i) {
+ labels.push(parse(chart.data.labels[i], me));
+ }
+
+ // Convert data to timestamps
+ for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
+ if (chart.isDatasetVisible(i)) {
+ data = chart.data.datasets[i].data;
+
+ // Let's consider that all data have the same format.
+ if (helpers.isObject(data[0])) {
+ datasets[i] = [];
+
+ for (j = 0, jlen = data.length; j < jlen; ++j) {
+ timestamp = parse(data[j], me);
+ timestamps.push(timestamp);
+ datasets[i][j] = timestamp;
+ }
+ } else {
+ timestamps.push.apply(timestamps, labels);
+ datasets[i] = labels.slice(0);
+ }
+ } else {
+ datasets[i] = [];
+ }
+ }
+
+ if (labels.length) {
+ // Sort labels **after** data have been converted
+ labels = arrayUnique(labels).sort(sorter);
+ min = Math.min(min, labels[0]);
+ max = Math.max(max, labels[labels.length - 1]);
+ }
+
+ if (timestamps.length) {
+ timestamps = arrayUnique(timestamps).sort(sorter);
+ min = Math.min(min, timestamps[0]);
+ max = Math.max(max, timestamps[timestamps.length - 1]);
+ }
+
+ min = parse(timeOpts.min, me) || min;
+ max = parse(timeOpts.max, me) || max;
+
+ // In case there is no valid min/max, set limits based on unit time option
+ min = min === MAX_INTEGER ? +moment().startOf(unit) : min;
+ max = max === MIN_INTEGER ? +moment().endOf(unit) + 1 : max;
+
+ // Make sure that max is strictly higher than min (required by the lookup table)
+ me.min = Math.min(min, max);
+ me.max = Math.max(min + 1, max);
+
+ // PRIVATE
+ me._horizontal = me.isHorizontal();
+ me._table = [];
+ me._timestamps = {
+ data: timestamps,
+ datasets: datasets,
+ labels: labels
+ };
+ },
+
+ buildTicks: function() {
+ var me = this;
+ var min = me.min;
+ var max = me.max;
+ var options = me.options;
+ var timeOpts = options.time;
+ var timestamps = [];
+ var ticks = [];
+ var i, ilen, timestamp;
+
+ switch (options.ticks.source) {
+ case 'data':
+ timestamps = me._timestamps.data;
+ break;
+ case 'labels':
+ timestamps = me._timestamps.labels;
+ break;
+ case 'auto':
+ default:
+ timestamps = generate(min, max, me.getLabelCapacity(min), options);
+ }
+
+ if (options.bounds === 'ticks' && timestamps.length) {
+ min = timestamps[0];
+ max = timestamps[timestamps.length - 1];
+ }
+
+ // Enforce limits with user min/max options
+ min = parse(timeOpts.min, me) || min;
+ max = parse(timeOpts.max, me) || max;
+
+ // Remove ticks outside the min/max range
+ for (i = 0, ilen = timestamps.length; i < ilen; ++i) {
+ timestamp = timestamps[i];
+ if (timestamp >= min && timestamp <= max) {
+ ticks.push(timestamp);
+ }
+ }
+
+ me.min = min;
+ me.max = max;
+
+ // PRIVATE
+ me._unit = timeOpts.unit || determineUnitForFormatting(ticks, timeOpts.minUnit, me.min, me.max);
+ me._majorUnit = determineMajorUnit(me._unit);
+ me._table = buildLookupTable(me._timestamps.data, min, max, options.distribution);
+ me._offsets = computeOffsets(me._table, ticks, min, max, options);
+ me._labelFormat = determineLabelFormat(me._timestamps.data, timeOpts);
+
+ return ticksFromTimestamps(ticks, me._majorUnit);
+ },
+
+ getLabelForIndex: function(index, datasetIndex) {
+ var me = this;
+ var data = me.chart.data;
+ var timeOpts = me.options.time;
+ var label = data.labels && index < data.labels.length ? data.labels[index] : '';
+ var value = data.datasets[datasetIndex].data[index];
+
+ if (helpers.isObject(value)) {
+ label = me.getRightValue(value);
+ }
+ if (timeOpts.tooltipFormat) {
+ return momentify(label, timeOpts).format(timeOpts.tooltipFormat);
+ }
+ if (typeof label === 'string') {
+ return label;
+ }
+
+ return momentify(label, timeOpts).format(me._labelFormat);
+ },
+
+ /**
+ * Function to format an individual tick mark
+ * @private
+ */
+ tickFormatFunction: function(tick, index, ticks, formatOverride) {
+ var me = this;
+ var options = me.options;
+ var time = tick.valueOf();
+ var formats = options.time.displayFormats;
+ var minorFormat = formats[me._unit];
+ var majorUnit = me._majorUnit;
+ var majorFormat = formats[majorUnit];
+ var majorTime = tick.clone().startOf(majorUnit).valueOf();
+ var majorTickOpts = options.ticks.major;
+ var major = majorTickOpts.enabled && majorUnit && majorFormat && time === majorTime;
+ var label = tick.format(formatOverride ? formatOverride : major ? majorFormat : minorFormat);
+ var tickOpts = major ? majorTickOpts : options.ticks.minor;
+ var formatter = helpers.valueOrDefault(tickOpts.callback, tickOpts.userCallback);
+
+ return formatter ? formatter(label, index, ticks) : label;
+ },
+
+ convertTicksToLabels: function(ticks) {
+ var labels = [];
+ var i, ilen;
+
+ for (i = 0, ilen = ticks.length; i < ilen; ++i) {
+ labels.push(this.tickFormatFunction(moment(ticks[i].value), i, ticks));
+ }
+
+ return labels;
+ },
+
+ /**
+ * @private
+ */
+ getPixelForOffset: function(time) {
+ var me = this;
+ var size = me._horizontal ? me.width : me.height;
+ var start = me._horizontal ? me.left : me.top;
+ var pos = interpolate(me._table, 'time', time, 'pos');
+
+ return start + size * (me._offsets.left + pos) / (me._offsets.left + 1 + me._offsets.right);
+ },
+
+ getPixelForValue: function(value, index, datasetIndex) {
+ var me = this;
+ var time = null;
+
+ if (index !== undefined && datasetIndex !== undefined) {
+ time = me._timestamps.datasets[datasetIndex][index];
+ }
+
+ if (time === null) {
+ time = parse(value, me);
+ }
+
+ if (time !== null) {
+ return me.getPixelForOffset(time);
+ }
+ },
+
+ getPixelForTick: function(index) {
+ var ticks = this.getTicks();
+ return index >= 0 && index < ticks.length ?
+ this.getPixelForOffset(ticks[index].value) :
+ null;
+ },
+
+ getValueForPixel: function(pixel) {
+ var me = this;
+ var size = me._horizontal ? me.width : me.height;
+ var start = me._horizontal ? me.left : me.top;
+ var pos = (size ? (pixel - start) / size : 0) * (me._offsets.left + 1 + me._offsets.left) - me._offsets.right;
+ var time = interpolate(me._table, 'pos', pos, 'time');
+
+ return moment(time);
+ },
+
+ /**
+ * Crude approximation of what the label width might be
+ * @private
+ */
+ getLabelWidth: function(label) {
+ var me = this;
+ var ticksOpts = me.options.ticks;
+ var tickLabelWidth = me.ctx.measureText(label).width;
+ var angle = helpers.toRadians(ticksOpts.maxRotation);
+ var cosRotation = Math.cos(angle);
+ var sinRotation = Math.sin(angle);
+ var tickFontSize = helpers.valueOrDefault(ticksOpts.fontSize, defaults.global.defaultFontSize);
+
+ return (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);
+ },
+
+ /**
+ * @private
+ */
+ getLabelCapacity: function(exampleTime) {
+ var me = this;
+
+ var formatOverride = me.options.time.displayFormats.millisecond; // Pick the longest format for guestimation
+
+ var exampleLabel = me.tickFormatFunction(moment(exampleTime), 0, [], formatOverride);
+ var tickLabelWidth = me.getLabelWidth(exampleLabel);
+ var innerWidth = me.isHorizontal() ? me.width : me.height;
+
+ var capacity = Math.floor(innerWidth / tickLabelWidth);
+ return capacity > 0 ? capacity : 1;
+ }
+ });
+
+ Chart.scaleService.registerScaleType('time', TimeScale, defaultConfig);
+};
+
+},{"25":25,"45":45,"6":6}]},{},[7])(7)
+});
\ No newline at end of file
diff --git a/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/chart/Chart.bundle.min.js b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/chart/Chart.bundle.min.js
new file mode 100644
index 0000000..5a00396
--- /dev/null
+++ b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/chart/Chart.bundle.min.js
@@ -0,0 +1,10 @@
+/*!
+ * Chart.js
+ * http://chartjs.org/
+ * Version: 2.7.2
+ *
+ * Copyright 2018 Chart.js Contributors
+ * Released under the MIT license
+ * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
+ */
+!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Chart=t()}}(function(){return function t(e,i,n){function a(o,s){if(!i[o]){if(!e[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(r)return r(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var d=i[o]={exports:{}};e[o][0].call(d.exports,function(t){var i=e[o][1][t];return a(i||t)},d,d.exports,t,e,i,n)}return i[o].exports}for(var r="function"==typeof require&&require,o=0;oi?(e+.05)/(i+.05):(i+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,i=(e[0]+t)%360;return e[0]=i<0?360+i:i,this.setValues("hsl",e),this},mix:function(t,e){var i=this,n=t,a=void 0===e?.5:e,r=2*a-1,o=i.alpha()-n.alpha(),s=((r*o==-1?r:(r+o)/(1+r*o))+1)/2,l=1-s;return this.rgb(s*i.red()+l*n.red(),s*i.green()+l*n.green(),s*i.blue()+l*n.blue()).alpha(i.alpha()*a+n.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,i=new r,n=this.values,a=i.values;for(var o in n)n.hasOwnProperty(o)&&(t=n[o],"[object Array]"===(e={}.toString.call(t))?a[o]=t.slice(0):"[object Number]"===e?a[o]=t:console.error("unexpected color value:",t));return i}},r.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},r.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},r.prototype.getValues=function(t){for(var e=this.values,i={},n=0;n.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)+.1805*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)),100*(.2126*e+.7152*i+.0722*n),100*(.0193*e+.1192*i+.9505*n)]}function d(t){var e=u(t),i=e[0],n=e[1],a=e[2];return n/=100,a/=108.883,i=(i/=95.047)>.008856?Math.pow(i,1/3):7.787*i+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(i-n),200*(n-(a=a>.008856?Math.pow(a,1/3):7.787*a+16/116))]}function h(t){var e,i,n,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return[r=255*l,r,r];e=2*l-(i=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(n=o+1/3*-(u-1))<0&&n++,n>1&&n--,r=6*n<1?e+6*(i-e)*n:2*n<1?i:3*n<2?e+(i-e)*(2/3-n)*6:e,a[u]=255*r;return a}function c(t){var e=t[0]/60,i=t[1]/100,n=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*n*(1-i),s=255*n*(1-i*r),l=255*n*(1-i*(1-r));n*=255;switch(a){case 0:return[n,l,o];case 1:return[s,n,o];case 2:return[o,n,l];case 3:return[o,s,n];case 4:return[l,o,n];case 5:return[n,o,s]}}function f(t){var e,i,n,a,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),n=6*o-(e=Math.floor(6*o)),0!=(1&e)&&(n=1-n),a=s+n*((i=1-l)-s),e){default:case 6:case 0:r=i,g=a,b=s;break;case 1:r=a,g=i,b=s;break;case 2:r=s,g=i,b=a;break;case 3:r=s,g=a,b=i;break;case 4:r=a,g=s,b=i;break;case 5:r=i,g=s,b=a}return[255*r,255*g,255*b]}function m(t){var e=t[0]/100,i=t[1]/100,n=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a))]}function p(t){var e,i,n,a=t[0]/100,r=t[1]/100,o=t[2]/100;return i=-.9689*a+1.8758*r+.0415*o,n=.0557*a+-.204*r+1.057*o,e=(e=3.2406*a+-1.5372*r+-.4986*o)>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n*=12.92,[255*(e=Math.min(Math.max(0,e),1)),255*(i=Math.min(Math.max(0,i),1)),255*(n=Math.min(Math.max(0,n),1))]}function v(t){var e=t[0],i=t[1],n=t[2];return i/=100,n/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(e-i),200*(i-(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116))]}function y(t){var e,i,n,a,r=t[0],o=t[1],s=t[2];return r<=8?a=(i=100*r/903.3)/100*7.787+16/116:(i=100*Math.pow((r+16)/116,3),a=Math.pow(i/100,1/3)),[e=e/95.047<=.008856?e=95.047*(o/500+a-16/116)/7.787:95.047*Math.pow(o/500+a,3),i,n=n/108.883<=.008859?n=108.883*(a-s/200-16/116)/7.787:108.883*Math.pow(a-s/200,3)]}function x(t){var e,i=t[0],n=t[1],a=t[2];return(e=360*Math.atan2(a,n)/2/Math.PI)<0&&(e+=360),[i,Math.sqrt(n*n+a*a),e]}function _(t){return p(y(t))}function k(t){var e,i=t[0],n=t[1];return e=t[2]/360*2*Math.PI,[i,n*Math.cos(e),n*Math.sin(e)]}function w(t){return M[t]}e.exports={rgb2hsl:n,rgb2hsv:a,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:function(t){return x(d(t))},hsl2rgb:h,hsl2hsv:function(t){var e=t[0],i=t[1]/100,n=t[2]/100;if(0===n)return[0,0,0];return[e,100*(2*(i*=(n*=2)<=1?n:2-n)/(n+i)),100*((n+i)/2)]},hsl2hwb:function(t){return o(h(t))},hsl2cmyk:function(t){return s(h(t))},hsl2keyword:function(t){return l(h(t))},hsv2rgb:c,hsv2hsl:function(t){var e,i,n=t[0],a=t[1]/100,r=t[2]/100;return e=a*r,[n,100*(e=(e/=(i=(2-a)*r)<=1?i:2-i)||0),100*(i/=2)]},hsv2hwb:function(t){return o(c(t))},hsv2cmyk:function(t){return s(c(t))},hsv2keyword:function(t){return l(c(t))},hwb2rgb:f,hwb2hsl:function(t){return n(f(t))},hwb2hsv:function(t){return a(f(t))},hwb2cmyk:function(t){return s(f(t))},hwb2keyword:function(t){return l(f(t))},cmyk2rgb:m,cmyk2hsl:function(t){return n(m(t))},cmyk2hsv:function(t){return a(m(t))},cmyk2hwb:function(t){return o(m(t))},cmyk2keyword:function(t){return l(m(t))},keyword2rgb:w,keyword2hsl:function(t){return n(w(t))},keyword2hsv:function(t){return a(w(t))},keyword2hwb:function(t){return o(w(t))},keyword2cmyk:function(t){return s(w(t))},keyword2lab:function(t){return d(w(t))},keyword2xyz:function(t){return u(w(t))},xyz2rgb:p,xyz2lab:v,xyz2lch:function(t){return x(v(t))},lab2xyz:y,lab2rgb:_,lab2lch:x,lch2lab:k,lch2xyz:function(t){return y(k(t))},lch2rgb:function(t){return _(k(t))}};var M={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},S={};for(var D in M)S[JSON.stringify(M[D])]=D},{}],4:[function(t,e,i){var n=t(3),a=function(){return new u};for(var r in n){a[r+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),n[t](e)}}(r);var o=/(\w+)2(\w+)/.exec(r),s=o[1],l=o[2];(a[s]=a[s]||{})[l]=a[r]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var i=n[t](e);if("string"==typeof i||void 0===i)return i;for(var a=0;a>>0,n=0;n0)for(i=0;i=0?i?"+":"":"-")+Math.pow(10,Math.max(0,a)).toString().substr(1)+n}var H=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,V=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,B={},E={};function j(t,e,i,n){var a=n;"string"==typeof n&&(a=function(){return this[n]()}),t&&(E[t]=a),e&&(E[e[0]]=function(){return z(a.apply(this,arguments),e[1],e[2])}),i&&(E[i]=function(){return this.localeData().ordinal(a.apply(this,arguments),t)})}function U(t,e){return t.isValid()?(e=q(e,t.localeData()),B[e]=B[e]||function(t){var e,i,n,a=t.match(H);for(e=0,i=a.length;e=0&&V.test(t);)t=t.replace(V,n),V.lastIndex=0,i-=1;return t}var G=/\d/,Z=/\d\d/,X=/\d{3}/,J=/\d{4}/,K=/[+-]?\d{6}/,$=/\d\d?/,Q=/\d\d\d\d?/,tt=/\d\d\d\d\d\d?/,et=/\d{1,3}/,it=/\d{1,4}/,nt=/[+-]?\d{1,6}/,at=/\d+/,rt=/[+-]?\d+/,ot=/Z|[+-]\d\d:?\d\d/gi,st=/Z|[+-]\d\d(?::?\d\d)?/gi,lt=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,ut={};function dt(t,e,i){ut[t]=O(e)?e:function(t,n){return t&&i?i:e}}function ht(t,e){return h(ut,t)?ut[t](e._strict,e._locale):new RegExp(ct(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,i,n,a){return e||i||n||a})))}function ct(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var ft={};function gt(t,e){var i,n=e;for("string"==typeof t&&(t=[t]),l(e)&&(n=function(t,i){i[e]=w(t)}),i=0;i68?1900:2e3)};var Ct,Pt=Tt("FullYear",!0);function Tt(t,e){return function(i){return null!=i?(It(this,t,i),a.updateOffset(this,e),this):Ot(this,t)}}function Ot(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function It(t,e,i){t.isValid()&&!isNaN(i)&&("FullYear"===e&&Dt(t.year())&&1===t.month()&&29===t.date()?t._d["set"+(t._isUTC?"UTC":"")+e](i,t.month(),At(i,t.month())):t._d["set"+(t._isUTC?"UTC":"")+e](i))}function At(t,e){if(isNaN(t)||isNaN(e))return NaN;var i,n=(e%(i=12)+i)%i;return t+=(e-n)/12,1===n?Dt(t)?29:28:31-n%7%2}Ct=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var e;for(e=0;e=0&&isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t),e}function Bt(t,e,i){var n=7+e-i;return-((7+Vt(t,0,n).getUTCDay()-e)%7)+n-1}function Et(t,e,i,n,a){var r,o,s=1+7*(e-1)+(7+i-n)%7+Bt(t,n,a);return s<=0?o=St(r=t-1)+s:s>St(t)?(r=t+1,o=s-St(t)):(r=t,o=s),{year:r,dayOfYear:o}}function jt(t,e,i){var n,a,r=Bt(t.year(),e,i),o=Math.floor((t.dayOfYear()-r-1)/7)+1;return o<1?n=o+Ut(a=t.year()-1,e,i):o>Ut(t.year(),e,i)?(n=o-Ut(t.year(),e,i),a=t.year()+1):(a=t.year(),n=o),{week:n,year:a}}function Ut(t,e,i){var n=Bt(t,e,i),a=Bt(t+1,e,i);return(St(t)-n+a)/7}j("w",["ww",2],"wo","week"),j("W",["WW",2],"Wo","isoWeek"),R("week","w"),R("isoWeek","W"),N("week",5),N("isoWeek",5),dt("w",$),dt("ww",$,Z),dt("W",$),dt("WW",$,Z),mt(["w","ww","W","WW"],function(t,e,i,n){e[n.substr(0,1)]=w(t)});j("d",0,"do","day"),j("dd",0,0,function(t){return this.localeData().weekdaysMin(this,t)}),j("ddd",0,0,function(t){return this.localeData().weekdaysShort(this,t)}),j("dddd",0,0,function(t){return this.localeData().weekdays(this,t)}),j("e",0,0,"weekday"),j("E",0,0,"isoWeekday"),R("day","d"),R("weekday","e"),R("isoWeekday","E"),N("day",11),N("weekday",11),N("isoWeekday",11),dt("d",$),dt("e",$),dt("E",$),dt("dd",function(t,e){return e.weekdaysMinRegex(t)}),dt("ddd",function(t,e){return e.weekdaysShortRegex(t)}),dt("dddd",function(t,e){return e.weekdaysRegex(t)}),mt(["dd","ddd","dddd"],function(t,e,i,n){var a=i._locale.weekdaysParse(t,n,i._strict);null!=a?e.d=a:g(i).invalidWeekday=t}),mt(["d","e","E"],function(t,e,i,n){e[n]=w(t)});var qt="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_");var Gt="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");var Zt="Su_Mo_Tu_We_Th_Fr_Sa".split("_");var Xt=lt;var Jt=lt;var Kt=lt;function $t(){function t(t,e){return e.length-t.length}var e,i,n,a,r,o=[],s=[],l=[],u=[];for(e=0;e<7;e++)i=f([2e3,1]).day(e),n=this.weekdaysMin(i,""),a=this.weekdaysShort(i,""),r=this.weekdays(i,""),o.push(n),s.push(a),l.push(r),u.push(n),u.push(a),u.push(r);for(o.sort(t),s.sort(t),l.sort(t),u.sort(t),e=0;e<7;e++)s[e]=ct(s[e]),l[e]=ct(l[e]),u[e]=ct(u[e]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function Qt(){return this.hours()%12||12}function te(t,e){j(t,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)})}function ee(t,e){return e._meridiemParse}j("H",["HH",2],0,"hour"),j("h",["hh",2],0,Qt),j("k",["kk",2],0,function(){return this.hours()||24}),j("hmm",0,0,function(){return""+Qt.apply(this)+z(this.minutes(),2)}),j("hmmss",0,0,function(){return""+Qt.apply(this)+z(this.minutes(),2)+z(this.seconds(),2)}),j("Hmm",0,0,function(){return""+this.hours()+z(this.minutes(),2)}),j("Hmmss",0,0,function(){return""+this.hours()+z(this.minutes(),2)+z(this.seconds(),2)}),te("a",!0),te("A",!1),R("hour","h"),N("hour",13),dt("a",ee),dt("A",ee),dt("H",$),dt("h",$),dt("k",$),dt("HH",$,Z),dt("hh",$,Z),dt("kk",$,Z),dt("hmm",Q),dt("hmmss",tt),dt("Hmm",Q),dt("Hmmss",tt),gt(["H","HH"],bt),gt(["k","kk"],function(t,e,i){var n=w(t);e[bt]=24===n?0:n}),gt(["a","A"],function(t,e,i){i._isPm=i._locale.isPM(t),i._meridiem=t}),gt(["h","hh"],function(t,e,i){e[bt]=w(t),g(i).bigHour=!0}),gt("hmm",function(t,e,i){var n=t.length-2;e[bt]=w(t.substr(0,n)),e[xt]=w(t.substr(n)),g(i).bigHour=!0}),gt("hmmss",function(t,e,i){var n=t.length-4,a=t.length-2;e[bt]=w(t.substr(0,n)),e[xt]=w(t.substr(n,2)),e[_t]=w(t.substr(a)),g(i).bigHour=!0}),gt("Hmm",function(t,e,i){var n=t.length-2;e[bt]=w(t.substr(0,n)),e[xt]=w(t.substr(n))}),gt("Hmmss",function(t,e,i){var n=t.length-4,a=t.length-2;e[bt]=w(t.substr(0,n)),e[xt]=w(t.substr(n,2)),e[_t]=w(t.substr(a))});var ie,ne=Tt("Hours",!0),ae={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d 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"},months:Rt,monthsShort:Lt,week:{dow:0,doy:6},weekdays:qt,weekdaysMin:Zt,weekdaysShort:Gt,meridiemParse:/[ap]\.?m?\.?/i},re={},oe={};function se(t){return t?t.toLowerCase().replace("_","-"):t}function le(i){var n=null;if(!re[i]&&void 0!==e&&e&&e.exports)try{n=ie._abbr,t("./locale/"+i),ue(n)}catch(t){}return re[i]}function ue(t,e){var i;return t&&(i=s(e)?he(t):de(t,e))&&(ie=i),ie._abbr}function de(t,e){if(null!==e){var i=ae;if(e.abbr=t,null!=re[t])T("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=re[t]._config;else if(null!=e.parentLocale){if(null==re[e.parentLocale])return oe[e.parentLocale]||(oe[e.parentLocale]=[]),oe[e.parentLocale].push({name:t,config:e}),null;i=re[e.parentLocale]._config}return re[t]=new A(I(i,e)),oe[t]&&oe[t].forEach(function(t){de(t.name,t.config)}),ue(t),re[t]}return delete re[t],null}function he(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return ie;if(!r(t)){if(e=le(t))return e;t=[t]}return function(t){for(var e,i,n,a,r=0;r0;){if(n=le(a.slice(0,e).join("-")))return n;if(i&&i.length>=e&&M(a,i,!0)>=e-1)break;e--}r++}return null}(t)}function ce(t){var e,i=t._a;return i&&-2===g(t).overflow&&(e=i[vt]<0||i[vt]>11?vt:i[yt]<1||i[yt]>At(i[pt],i[vt])?yt:i[bt]<0||i[bt]>24||24===i[bt]&&(0!==i[xt]||0!==i[_t]||0!==i[kt])?bt:i[xt]<0||i[xt]>59?xt:i[_t]<0||i[_t]>59?_t:i[kt]<0||i[kt]>999?kt:-1,g(t)._overflowDayOfYear&&(eyt)&&(e=yt),g(t)._overflowWeeks&&-1===e&&(e=wt),g(t)._overflowWeekday&&-1===e&&(e=Mt),g(t).overflow=e),t}function fe(t,e,i){return null!=t?t:null!=e?e:i}function ge(t){var e,i,n,r,o,s=[];if(!t._d){var l,u;for(l=t,u=new Date(a.now()),n=l._useUTC?[u.getUTCFullYear(),u.getUTCMonth(),u.getUTCDate()]:[u.getFullYear(),u.getMonth(),u.getDate()],t._w&&null==t._a[yt]&&null==t._a[vt]&&function(t){var e,i,n,a,r,o,s,l;if(null!=(e=t._w).GG||null!=e.W||null!=e.E)r=1,o=4,i=fe(e.GG,t._a[pt],jt(Te(),1,4).year),n=fe(e.W,1),((a=fe(e.E,1))<1||a>7)&&(l=!0);else{r=t._locale._week.dow,o=t._locale._week.doy;var u=jt(Te(),r,o);i=fe(e.gg,t._a[pt],u.year),n=fe(e.w,u.week),null!=e.d?((a=e.d)<0||a>6)&&(l=!0):null!=e.e?(a=e.e+r,(e.e<0||e.e>6)&&(l=!0)):a=r}n<1||n>Ut(i,r,o)?g(t)._overflowWeeks=!0:null!=l?g(t)._overflowWeekday=!0:(s=Et(i,n,a,r,o),t._a[pt]=s.year,t._dayOfYear=s.dayOfYear)}(t),null!=t._dayOfYear&&(o=fe(t._a[pt],n[pt]),(t._dayOfYear>St(o)||0===t._dayOfYear)&&(g(t)._overflowDayOfYear=!0),i=Vt(o,0,t._dayOfYear),t._a[vt]=i.getUTCMonth(),t._a[yt]=i.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=s[e]=n[e];for(;e<7;e++)t._a[e]=s[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[bt]&&0===t._a[xt]&&0===t._a[_t]&&0===t._a[kt]&&(t._nextDay=!0,t._a[bt]=0),t._d=(t._useUTC?Vt:function(t,e,i,n,a,r,o){var s=new Date(t,e,i,n,a,r,o);return t<100&&t>=0&&isFinite(s.getFullYear())&&s.setFullYear(t),s}).apply(null,s),r=t._useUTC?t._d.getUTCDay():t._d.getDay(),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[bt]=24),t._w&&void 0!==t._w.d&&t._w.d!==r&&(g(t).weekdayMismatch=!0)}}var me=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pe=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ve=/Z|[+-]\d\d(?::?\d\d)?/,ye=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],be=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],xe=/^\/?Date\((\-?\d+)/i;function _e(t){var e,i,n,a,r,o,s=t._i,l=me.exec(s)||pe.exec(s);if(l){for(g(t).iso=!0,e=0,i=ye.length;e0&&g(t).unusedInput.push(o),d=d.slice(d.indexOf(i)+i.length),f+=i.length),E[r]?(i?g(t).empty=!1:g(t).unusedTokens.push(r),s=r,u=t,null!=(l=i)&&h(ft,s)&&ft[s](l,u._a,u,s)):t._strict&&!i&&g(t).unusedTokens.push(r);g(t).charsLeftOver=c-f,d.length>0&&g(t).unusedInput.push(d),t._a[bt]<=12&&!0===g(t).bigHour&&t._a[bt]>0&&(g(t).bigHour=void 0),g(t).parsedDateParts=t._a.slice(0),g(t).meridiem=t._meridiem,t._a[bt]=function(t,e,i){var n;if(null==i)return e;return null!=t.meridiemHour?t.meridiemHour(e,i):null!=t.isPM?((n=t.isPM(i))&&e<12&&(e+=12),n||12!==e||(e=0),e):e}(t._locale,t._a[bt],t._meridiem),ge(t),ce(t)}else Se(t);else _e(t)}function Ce(t){var e,i,n,h,f=t._i,v=t._f;return t._locale=t._locale||he(t._l),null===f||void 0===v&&""===f?p({nullInput:!0}):("string"==typeof f&&(t._i=f=t._locale.preparse(f)),_(f)?new x(ce(f)):(u(f)?t._d=f:r(v)?function(t){var e,i,n,a,r;if(0===t._f.length)return g(t).invalidFormat=!0,void(t._d=new Date(NaN));for(a=0;athis?this:t:p()});function Ae(t,e){var i,n;if(1===e.length&&r(e[0])&&(e=e[0]),!e.length)return Te();for(i=e[0],n=1;n(r=Ut(t,n,a))&&(e=r),function(t,e,i,n,a){var r=Et(t,e,i,n,a),o=Vt(r.year,0,r.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}.call(this,t,e,i,n,a))}j(0,["gg",2],0,function(){return this.weekYear()%100}),j(0,["GG",2],0,function(){return this.isoWeekYear()%100}),ii("gggg","weekYear"),ii("ggggg","weekYear"),ii("GGGG","isoWeekYear"),ii("GGGGG","isoWeekYear"),R("weekYear","gg"),R("isoWeekYear","GG"),N("weekYear",1),N("isoWeekYear",1),dt("G",rt),dt("g",rt),dt("GG",$,Z),dt("gg",$,Z),dt("GGGG",it,J),dt("gggg",it,J),dt("GGGGG",nt,K),dt("ggggg",nt,K),mt(["gggg","ggggg","GGGG","GGGGG"],function(t,e,i,n){e[n.substr(0,2)]=w(t)}),mt(["gg","GG"],function(t,e,i,n){e[n]=a.parseTwoDigitYear(t)}),j("Q",0,"Qo","quarter"),R("quarter","Q"),N("quarter",7),dt("Q",G),gt("Q",function(t,e){e[vt]=3*(w(t)-1)}),j("D",["DD",2],"Do","date"),R("date","D"),N("date",9),dt("D",$),dt("DD",$,Z),dt("Do",function(t,e){return t?e._dayOfMonthOrdinalParse||e._ordinalParse:e._dayOfMonthOrdinalParseLenient}),gt(["D","DD"],yt),gt("Do",function(t,e){e[yt]=w(t.match($)[0])});var ai=Tt("Date",!0);j("DDD",["DDDD",3],"DDDo","dayOfYear"),R("dayOfYear","DDD"),N("dayOfYear",4),dt("DDD",et),dt("DDDD",X),gt(["DDD","DDDD"],function(t,e,i){i._dayOfYear=w(t)}),j("m",["mm",2],0,"minute"),R("minute","m"),N("minute",14),dt("m",$),dt("mm",$,Z),gt(["m","mm"],xt);var ri=Tt("Minutes",!1);j("s",["ss",2],0,"second"),R("second","s"),N("second",15),dt("s",$),dt("ss",$,Z),gt(["s","ss"],_t);var oi,si=Tt("Seconds",!1);for(j("S",0,0,function(){return~~(this.millisecond()/100)}),j(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),j(0,["SSS",3],0,"millisecond"),j(0,["SSSS",4],0,function(){return 10*this.millisecond()}),j(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),j(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),j(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),j(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),j(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),R("millisecond","ms"),N("millisecond",16),dt("S",et,G),dt("SS",et,Z),dt("SSS",et,X),oi="SSSS";oi.length<=9;oi+="S")dt(oi,at);function li(t,e){e[kt]=w(1e3*("0."+t))}for(oi="S";oi.length<=9;oi+="S")gt(oi,li);var ui=Tt("Milliseconds",!1);j("z",0,0,"zoneAbbr"),j("zz",0,0,"zoneName");var di=x.prototype;function hi(t){return t}di.add=Je,di.calendar=function(t,e){var i=t||Te(),n=He(i,this).startOf("day"),r=a.calendarFormat(this,n)||"sameElse",o=e&&(O(e[r])?e[r].call(this,i):e[r]);return this.format(o||this.localeData().calendar(r,this,Te(i)))},di.clone=function(){return new x(this)},di.diff=function(t,e,i){var n,a,r;if(!this.isValid())return NaN;if(!(n=He(t,this)).isValid())return NaN;switch(a=6e4*(n.utcOffset()-this.utcOffset()),e=L(e)){case"year":r=$e(this,n)/12;break;case"month":r=$e(this,n);break;case"quarter":r=$e(this,n)/3;break;case"second":r=(this-n)/1e3;break;case"minute":r=(this-n)/6e4;break;case"hour":r=(this-n)/36e5;break;case"day":r=(this-n-a)/864e5;break;case"week":r=(this-n-a)/6048e5;break;default:r=this-n}return i?r:k(r)},di.endOf=function(t){return void 0===(t=L(t))||"millisecond"===t?this:("date"===t&&(t="day"),this.startOf(t).add(1,"isoWeek"===t?"week":t).subtract(1,"ms"))},di.format=function(t){t||(t=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var e=U(this,t);return this.localeData().postformat(e)},di.from=function(t,e){return this.isValid()&&(_(t)&&t.isValid()||Te(t).isValid())?Ue({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},di.fromNow=function(t){return this.from(Te(),t)},di.to=function(t,e){return this.isValid()&&(_(t)&&t.isValid()||Te(t).isValid())?Ue({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},di.toNow=function(t){return this.to(Te(),t)},di.get=function(t){return O(this[t=L(t)])?this[t]():this},di.invalidAt=function(){return g(this).overflow},di.isAfter=function(t,e){var i=_(t)?t:Te(t);return!(!this.isValid()||!i.isValid())&&("millisecond"===(e=L(s(e)?"millisecond":e))?this.valueOf()>i.valueOf():i.valueOf()9999?U(i,e?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):O(Date.prototype.toISOString)?e?this.toDate().toISOString():new Date(this._d.valueOf()).toISOString().replace("Z",U(i,"Z")):U(i,e?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},di.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t="moment",e="";this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",e="Z");var i="["+t+'("]',n=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",a=e+'[")]';return this.format(i+n+"-MM-DD[T]HH:mm:ss.SSS"+a)},di.toJSON=function(){return this.isValid()?this.toISOString():null},di.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},di.unix=function(){return Math.floor(this.valueOf()/1e3)},di.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},di.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},di.year=Pt,di.isLeapYear=function(){return Dt(this.year())},di.weekYear=function(t){return ni.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},di.isoWeekYear=function(t){return ni.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)},di.quarter=di.quarters=function(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)},di.month=Yt,di.daysInMonth=function(){return At(this.year(),this.month())},di.week=di.weeks=function(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")},di.isoWeek=di.isoWeeks=function(t){var e=jt(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")},di.weeksInYear=function(){var t=this.localeData()._week;return Ut(this.year(),t.dow,t.doy)},di.isoWeeksInYear=function(){return Ut(this.year(),1,4)},di.date=ai,di.day=di.days=function(t){if(!this.isValid())return null!=t?this:NaN;var e,i,n=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(e=t,i=this.localeData(),t="string"!=typeof e?e:isNaN(e)?"number"==typeof(e=i.weekdaysParse(e))?e:null:parseInt(e,10),this.add(t-n,"d")):n},di.weekday=function(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")},di.isoWeekday=function(t){if(!this.isValid())return null!=t?this:NaN;if(null!=t){var e=(i=t,n=this.localeData(),"string"==typeof i?n.weekdaysParse(i)%7||7:isNaN(i)?null:i);return this.day(this.day()%7?e:e-7)}return this.day()||7;var i,n},di.dayOfYear=function(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")},di.hour=di.hours=ne,di.minute=di.minutes=ri,di.second=di.seconds=si,di.millisecond=di.milliseconds=ui,di.utcOffset=function(t,e,i){var n,r=this._offset||0;if(!this.isValid())return null!=t?this:NaN;if(null!=t){if("string"==typeof t){if(null===(t=ze(st,t)))return this}else Math.abs(t)<16&&!i&&(t*=60);return!this._isUTC&&e&&(n=Ve(this)),this._offset=t,this._isUTC=!0,null!=n&&this.add(n,"m"),r!==t&&(!e||this._changeInProgress?Xe(this,Ue(t-r,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?r:Ve(this)},di.utc=function(t){return this.utcOffset(0,t)},di.local=function(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(Ve(this),"m")),this},di.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var t=ze(ot,this._i);null!=t?this.utcOffset(t):this.utcOffset(0,!0)}return this},di.hasAlignedHourOffset=function(t){return!!this.isValid()&&(t=t?Te(t).utcOffset():0,(this.utcOffset()-t)%60==0)},di.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},di.isLocal=function(){return!!this.isValid()&&!this._isUTC},di.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},di.isUtc=Be,di.isUTC=Be,di.zoneAbbr=function(){return this._isUTC?"UTC":""},di.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},di.dates=D("dates accessor is deprecated. Use date instead.",ai),di.months=D("months accessor is deprecated. Use month instead",Yt),di.years=D("years accessor is deprecated. Use year instead",Pt),di.zone=D("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()}),di.isDSTShifted=D("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!s(this._isDSTShifted))return this._isDSTShifted;var t={};if(y(t,this),(t=Ce(t))._a){var e=t._isUTC?f(t._a):Te(t._a);this._isDSTShifted=this.isValid()&&M(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted});var ci=A.prototype;function fi(t,e,i,n){var a=he(),r=f().set(n,e);return a[i](r,t)}function gi(t,e,i){if(l(t)&&(e=t,t=void 0),t=t||"",null!=e)return fi(t,e,i,"month");var n,a=[];for(n=0;n<12;n++)a[n]=fi(t,n,i,"month");return a}function mi(t,e,i,n){"boolean"==typeof t?(l(e)&&(i=e,e=void 0),e=e||""):(i=e=t,t=!1,l(e)&&(i=e,e=void 0),e=e||"");var a,r=he(),o=t?r._week.dow:0;if(null!=i)return fi(e,(i+o)%7,n,"day");var s=[];for(a=0;a<7;a++)s[a]=fi(e,(a+o)%7,n,"day");return s}ci.calendar=function(t,e,i){var n=this._calendar[t]||this._calendar.sameElse;return O(n)?n.call(e,i):n},ci.longDateFormat=function(t){var e=this._longDateFormat[t],i=this._longDateFormat[t.toUpperCase()];return e||!i?e:(this._longDateFormat[t]=i.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])},ci.invalidDate=function(){return this._invalidDate},ci.ordinal=function(t){return this._ordinal.replace("%d",t)},ci.preparse=hi,ci.postformat=hi,ci.relativeTime=function(t,e,i,n){var a=this._relativeTime[i];return O(a)?a(t,e,i,n):a.replace(/%d/i,t)},ci.pastFuture=function(t,e){var i=this._relativeTime[t>0?"future":"past"];return O(i)?i(e):i.replace(/%s/i,e)},ci.set=function(t){var e,i;for(i in t)O(e=t[i])?this[i]=e:this["_"+i]=e;this._config=t,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},ci.months=function(t,e){return t?r(this._months)?this._months[t.month()]:this._months[(this._months.isFormat||Ft).test(e)?"format":"standalone"][t.month()]:r(this._months)?this._months:this._months.standalone},ci.monthsShort=function(t,e){return t?r(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[Ft.test(e)?"format":"standalone"][t.month()]:r(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},ci.monthsParse=function(t,e,i){var n,a,r;if(this._monthsParseExact)return function(t,e,i){var n,a,r,o=t.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],n=0;n<12;++n)r=f([2e3,n]),this._shortMonthsParse[n]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[n]=this.months(r,"").toLocaleLowerCase();return i?"MMM"===e?-1!==(a=Ct.call(this._shortMonthsParse,o))?a:null:-1!==(a=Ct.call(this._longMonthsParse,o))?a:null:"MMM"===e?-1!==(a=Ct.call(this._shortMonthsParse,o))?a:-1!==(a=Ct.call(this._longMonthsParse,o))?a:null:-1!==(a=Ct.call(this._longMonthsParse,o))?a:-1!==(a=Ct.call(this._shortMonthsParse,o))?a:null}.call(this,t,e,i);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),n=0;n<12;n++){if(a=f([2e3,n]),i&&!this._longMonthsParse[n]&&(this._longMonthsParse[n]=new RegExp("^"+this.months(a,"").replace(".","")+"$","i"),this._shortMonthsParse[n]=new RegExp("^"+this.monthsShort(a,"").replace(".","")+"$","i")),i||this._monthsParse[n]||(r="^"+this.months(a,"")+"|^"+this.monthsShort(a,""),this._monthsParse[n]=new RegExp(r.replace(".",""),"i")),i&&"MMMM"===e&&this._longMonthsParse[n].test(t))return n;if(i&&"MMM"===e&&this._shortMonthsParse[n].test(t))return n;if(!i&&this._monthsParse[n].test(t))return n}},ci.monthsRegex=function(t){return this._monthsParseExact?(h(this,"_monthsRegex")||Ht.call(this),t?this._monthsStrictRegex:this._monthsRegex):(h(this,"_monthsRegex")||(this._monthsRegex=zt),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)},ci.monthsShortRegex=function(t){return this._monthsParseExact?(h(this,"_monthsRegex")||Ht.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):(h(this,"_monthsShortRegex")||(this._monthsShortRegex=Nt),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)},ci.week=function(t){return jt(t,this._week.dow,this._week.doy).week},ci.firstDayOfYear=function(){return this._week.doy},ci.firstDayOfWeek=function(){return this._week.dow},ci.weekdays=function(t,e){return t?r(this._weekdays)?this._weekdays[t.day()]:this._weekdays[this._weekdays.isFormat.test(e)?"format":"standalone"][t.day()]:r(this._weekdays)?this._weekdays:this._weekdays.standalone},ci.weekdaysMin=function(t){return t?this._weekdaysMin[t.day()]:this._weekdaysMin},ci.weekdaysShort=function(t){return t?this._weekdaysShort[t.day()]:this._weekdaysShort},ci.weekdaysParse=function(t,e,i){var n,a,r;if(this._weekdaysParseExact)return function(t,e,i){var n,a,r,o=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],n=0;n<7;++n)r=f([2e3,1]).day(n),this._minWeekdaysParse[n]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[n]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[n]=this.weekdays(r,"").toLocaleLowerCase();return i?"dddd"===e?-1!==(a=Ct.call(this._weekdaysParse,o))?a:null:"ddd"===e?-1!==(a=Ct.call(this._shortWeekdaysParse,o))?a:null:-1!==(a=Ct.call(this._minWeekdaysParse,o))?a:null:"dddd"===e?-1!==(a=Ct.call(this._weekdaysParse,o))?a:-1!==(a=Ct.call(this._shortWeekdaysParse,o))?a:-1!==(a=Ct.call(this._minWeekdaysParse,o))?a:null:"ddd"===e?-1!==(a=Ct.call(this._shortWeekdaysParse,o))?a:-1!==(a=Ct.call(this._weekdaysParse,o))?a:-1!==(a=Ct.call(this._minWeekdaysParse,o))?a:null:-1!==(a=Ct.call(this._minWeekdaysParse,o))?a:-1!==(a=Ct.call(this._weekdaysParse,o))?a:-1!==(a=Ct.call(this._shortWeekdaysParse,o))?a:null}.call(this,t,e,i);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),n=0;n<7;n++){if(a=f([2e3,1]).day(n),i&&!this._fullWeekdaysParse[n]&&(this._fullWeekdaysParse[n]=new RegExp("^"+this.weekdays(a,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[n]=new RegExp("^"+this.weekdaysShort(a,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[n]=new RegExp("^"+this.weekdaysMin(a,"").replace(".",".?")+"$","i")),this._weekdaysParse[n]||(r="^"+this.weekdays(a,"")+"|^"+this.weekdaysShort(a,"")+"|^"+this.weekdaysMin(a,""),this._weekdaysParse[n]=new RegExp(r.replace(".",""),"i")),i&&"dddd"===e&&this._fullWeekdaysParse[n].test(t))return n;if(i&&"ddd"===e&&this._shortWeekdaysParse[n].test(t))return n;if(i&&"dd"===e&&this._minWeekdaysParse[n].test(t))return n;if(!i&&this._weekdaysParse[n].test(t))return n}},ci.weekdaysRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||$t.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(h(this,"_weekdaysRegex")||(this._weekdaysRegex=Xt),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)},ci.weekdaysShortRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||$t.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(h(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Jt),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},ci.weekdaysMinRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||$t.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(h(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Kt),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},ci.isPM=function(t){return"p"===(t+"").toLowerCase().charAt(0)},ci.meridiem=function(t,e,i){return t>11?i?"pm":"PM":i?"am":"AM"},ue("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10;return t+(1===w(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")}}),a.lang=D("moment.lang is deprecated. Use moment.locale instead.",ue),a.langData=D("moment.langData is deprecated. Use moment.localeData instead.",he);var pi=Math.abs;function vi(t,e,i,n){var a=Ue(e,i);return t._milliseconds+=n*a._milliseconds,t._days+=n*a._days,t._months+=n*a._months,t._bubble()}function yi(t){return t<0?Math.floor(t):Math.ceil(t)}function bi(t){return 4800*t/146097}function xi(t){return 146097*t/4800}function _i(t){return function(){return this.as(t)}}var ki=_i("ms"),wi=_i("s"),Mi=_i("m"),Si=_i("h"),Di=_i("d"),Ci=_i("w"),Pi=_i("M"),Ti=_i("y");function Oi(t){return function(){return this.isValid()?this._data[t]:NaN}}var Ii=Oi("milliseconds"),Ai=Oi("seconds"),Fi=Oi("minutes"),Ri=Oi("hours"),Li=Oi("days"),Wi=Oi("months"),Yi=Oi("years");var Ni=Math.round,zi={ss:44,s:45,m:45,h:22,d:26,M:11};var Hi=Math.abs;function Vi(t){return(t>0)-(t<0)||+t}function Bi(){if(!this.isValid())return this.localeData().invalidDate();var t,e,i=Hi(this._milliseconds)/1e3,n=Hi(this._days),a=Hi(this._months);e=k((t=k(i/60))/60),i%=60,t%=60;var r=k(a/12),o=a%=12,s=n,l=e,u=t,d=i?i.toFixed(3).replace(/\.?0+$/,""):"",h=this.asSeconds();if(!h)return"P0D";var c=h<0?"-":"",f=Vi(this._months)!==Vi(h)?"-":"",g=Vi(this._days)!==Vi(h)?"-":"",m=Vi(this._milliseconds)!==Vi(h)?"-":"";return c+"P"+(r?f+r+"Y":"")+(o?f+o+"M":"")+(s?g+s+"D":"")+(l||u||d?"T":"")+(l?m+l+"H":"")+(u?m+u+"M":"")+(d?m+d+"S":"")}var Ei=Re.prototype;return Ei.isValid=function(){return this._isValid},Ei.abs=function(){var t=this._data;return this._milliseconds=pi(this._milliseconds),this._days=pi(this._days),this._months=pi(this._months),t.milliseconds=pi(t.milliseconds),t.seconds=pi(t.seconds),t.minutes=pi(t.minutes),t.hours=pi(t.hours),t.months=pi(t.months),t.years=pi(t.years),this},Ei.add=function(t,e){return vi(this,t,e,1)},Ei.subtract=function(t,e){return vi(this,t,e,-1)},Ei.as=function(t){if(!this.isValid())return NaN;var e,i,n=this._milliseconds;if("month"===(t=L(t))||"year"===t)return e=this._days+n/864e5,i=this._months+bi(e),"month"===t?i:i/12;switch(e=this._days+Math.round(xi(this._months)),t){case"week":return e/7+n/6048e5;case"day":return e+n/864e5;case"hour":return 24*e+n/36e5;case"minute":return 1440*e+n/6e4;case"second":return 86400*e+n/1e3;case"millisecond":return Math.floor(864e5*e)+n;default:throw new Error("Unknown unit "+t)}},Ei.asMilliseconds=ki,Ei.asSeconds=wi,Ei.asMinutes=Mi,Ei.asHours=Si,Ei.asDays=Di,Ei.asWeeks=Ci,Ei.asMonths=Pi,Ei.asYears=Ti,Ei.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*w(this._months/12):NaN},Ei._bubble=function(){var t,e,i,n,a,r=this._milliseconds,o=this._days,s=this._months,l=this._data;return r>=0&&o>=0&&s>=0||r<=0&&o<=0&&s<=0||(r+=864e5*yi(xi(s)+o),o=0,s=0),l.milliseconds=r%1e3,t=k(r/1e3),l.seconds=t%60,e=k(t/60),l.minutes=e%60,i=k(e/60),l.hours=i%24,s+=a=k(bi(o+=k(i/24))),o-=yi(xi(a)),n=k(s/12),s%=12,l.days=o,l.months=s,l.years=n,this},Ei.clone=function(){return Ue(this)},Ei.get=function(t){return t=L(t),this.isValid()?this[t+"s"]():NaN},Ei.milliseconds=Ii,Ei.seconds=Ai,Ei.minutes=Fi,Ei.hours=Ri,Ei.days=Li,Ei.weeks=function(){return k(this.days()/7)},Ei.months=Wi,Ei.years=Yi,Ei.humanize=function(t){if(!this.isValid())return this.localeData().invalidDate();var e,i,n,a,r,o,s,l,u,d,h,c=this.localeData(),f=(i=!t,n=c,a=Ue(e=this).abs(),r=Ni(a.as("s")),o=Ni(a.as("m")),s=Ni(a.as("h")),l=Ni(a.as("d")),u=Ni(a.as("M")),d=Ni(a.as("y")),(h=r<=zi.ss&&["s",r]||r0,h[4]=n,function(t,e,i,n,a){return a.relativeTime(e||1,!!i,t,n)}.apply(null,h));return t&&(f=c.pastFuture(+this,f)),c.postformat(f)},Ei.toISOString=Bi,Ei.toString=Bi,Ei.toJSON=Bi,Ei.locale=Qe,Ei.localeData=ei,Ei.toIsoString=D("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Bi),Ei.lang=ti,j("X",0,0,"unix"),j("x",0,0,"valueOf"),dt("x",rt),dt("X",/[+-]?\d+(\.\d{1,3})?/),gt("X",function(t,e,i){i._d=new Date(1e3*parseFloat(t,10))}),gt("x",function(t,e,i){i._d=new Date(w(t))}),a.version="2.20.1",i=Te,a.fn=di,a.min=function(){return Ae("isBefore",[].slice.call(arguments,0))},a.max=function(){return Ae("isAfter",[].slice.call(arguments,0))},a.now=function(){return Date.now?Date.now():+new Date},a.utc=f,a.unix=function(t){return Te(1e3*t)},a.months=function(t,e){return gi(t,e,"months")},a.isDate=u,a.locale=ue,a.invalid=p,a.duration=Ue,a.isMoment=_,a.weekdays=function(t,e,i){return mi(t,e,i,"weekdays")},a.parseZone=function(){return Te.apply(null,arguments).parseZone()},a.localeData=he,a.isDuration=Le,a.monthsShort=function(t,e){return gi(t,e,"monthsShort")},a.weekdaysMin=function(t,e,i){return mi(t,e,i,"weekdaysMin")},a.defineLocale=de,a.updateLocale=function(t,e){if(null!=e){var i,n,a=ae;null!=(n=le(t))&&(a=n._config),(i=new A(e=I(a,e))).parentLocale=re[t],re[t]=i,ue(t)}else null!=re[t]&&(null!=re[t].parentLocale?re[t]=re[t].parentLocale:null!=re[t]&&delete re[t]);return re[t]},a.locales=function(){return C(re)},a.weekdaysShort=function(t,e,i){return mi(t,e,i,"weekdaysShort")},a.normalizeUnits=L,a.relativeTimeRounding=function(t){return void 0===t?Ni:"function"==typeof t&&(Ni=t,!0)},a.relativeTimeThreshold=function(t,e){return void 0!==zi[t]&&(void 0===e?zi[t]:(zi[t]=e,"s"===t&&(zi.ss=e-1),!0))},a.calendarFormat=function(t,e){var i=t.diff(e,"days",!0);return i<-6?"sameElse":i<-1?"lastWeek":i<0?"lastDay":i<1?"sameDay":i<2?"nextDay":i<7?"nextWeek":"sameElse"},a.prototype=di,a.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"YYYY-[W]WW",MONTH:"YYYY-MM"},a},"object"==typeof i&&void 0!==e?e.exports=a():n.moment=a()},{}],7:[function(t,e,i){var n=t(29)();n.helpers=t(45),t(27)(n),n.defaults=t(25),n.Element=t(26),n.elements=t(40),n.Interaction=t(28),n.layouts=t(30),n.platform=t(48),n.plugins=t(31),n.Ticks=t(34),t(22)(n),t(23)(n),t(24)(n),t(33)(n),t(32)(n),t(35)(n),t(55)(n),t(53)(n),t(54)(n),t(56)(n),t(57)(n),t(58)(n),t(15)(n),t(16)(n),t(17)(n),t(18)(n),t(19)(n),t(20)(n),t(21)(n),t(8)(n),t(9)(n),t(10)(n),t(11)(n),t(12)(n),t(13)(n),t(14)(n);var a=t(49);for(var r in a)a.hasOwnProperty(r)&&n.plugins.register(a[r]);n.platform.initialize(),e.exports=n,"undefined"!=typeof window&&(window.Chart=n),n.Legend=a.legend._element,n.Title=a.title._element,n.pluginService=n.plugins,n.PluginBase=n.Element.extend({}),n.canvasHelpers=n.helpers.canvas,n.layoutService=n.layouts},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,34:34,35:35,40:40,45:45,48:48,49:49,53:53,54:54,55:55,56:56,57:57,58:58,8:8,9:9}],8:[function(t,e,i){"use strict";e.exports=function(t){t.Bar=function(e,i){return i.type="bar",new t(e,i)}}},{}],9:[function(t,e,i){"use strict";e.exports=function(t){t.Bubble=function(e,i){return i.type="bubble",new t(e,i)}}},{}],10:[function(t,e,i){"use strict";e.exports=function(t){t.Doughnut=function(e,i){return i.type="doughnut",new t(e,i)}}},{}],11:[function(t,e,i){"use strict";e.exports=function(t){t.Line=function(e,i){return i.type="line",new t(e,i)}}},{}],12:[function(t,e,i){"use strict";e.exports=function(t){t.PolarArea=function(e,i){return i.type="polarArea",new t(e,i)}}},{}],13:[function(t,e,i){"use strict";e.exports=function(t){t.Radar=function(e,i){return i.type="radar",new t(e,i)}}},{}],14:[function(t,e,i){"use strict";e.exports=function(t){t.Scatter=function(e,i){return i.type="scatter",new t(e,i)}}},{}],15:[function(t,e,i){"use strict";var n=t(25),a=t(40),r=t(45);n._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),n._set("horizontalBar",{hover:{mode:"index",axis:"y"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var i="";return t.length>0&&(t[0].yLabel?i=t[0].yLabel:e.labels.length>0&&t[0].index0?Math.min(o,n-i):o,i=n;return o}(i,u):-1,pixels:u,start:s,end:l,stackCount:n,scale:i}},calculateBarValuePixels:function(t,e){var i,n,a,r,o,s,l=this.chart,u=this.getMeta(),d=this.getValueScale(),h=l.data.datasets,c=d.getRightValue(h[t].data[e]),f=d.options.stacked,g=u.stack,m=0;if(f||void 0===f&&void 0!==g)for(i=0;i=0&&a>0)&&(m+=a));return r=d.getPixelForValue(m),{size:s=((o=d.getPixelForValue(m+c))-r)/2,base:r,head:o,center:o+s/2}},calculateBarIndexPixels:function(t,e,i){var n,a,o,s,l,u,d,h,c,f,g,m,p,v,y,b,x,_=i.scale.options,k="flex"===_.barThickness?(c=e,g=_,p=(f=i).pixels,v=p[c],y=c>0?p[c-1]:null,b=c');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var r=0;r '),a[r]&&e.push(a[r]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(i,n){var a=t.getDatasetMeta(0),o=e.datasets[0],s=a.data[n],l=s&&s.custom||{},u=r.valueAtIndexOrDefault,d=t.options.elements.arc;return{text:i,fillStyle:l.backgroundColor?l.backgroundColor:u(o.backgroundColor,n,d.backgroundColor),strokeStyle:l.borderColor?l.borderColor:u(o.borderColor,n,d.borderColor),lineWidth:l.borderWidth?l.borderWidth:u(o.borderWidth,n,d.borderWidth),hidden:isNaN(o.data[n])||a.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var i,n,a,r=e.index,o=this.chart;for(i=0,n=(o.data.datasets||[]).length;i=Math.PI?-1:g<-Math.PI?1:0))+f,p=Math.cos(g),v=Math.sin(g),y=Math.cos(m),b=Math.sin(m),x=g<=0&&m>=0||g<=2*Math.PI&&2*Math.PI<=m,_=g<=.5*Math.PI&&.5*Math.PI<=m||g<=2.5*Math.PI&&2.5*Math.PI<=m,k=g<=-Math.PI&&-Math.PI<=m||g<=Math.PI&&Math.PI<=m,w=g<=.5*-Math.PI&&.5*-Math.PI<=m||g<=1.5*Math.PI&&1.5*Math.PI<=m,M=c/100,S=k?-1:Math.min(p*(p<0?1:M),y*(y<0?1:M)),D=w?-1:Math.min(v*(v<0?1:M),b*(b<0?1:M)),C=x?1:Math.max(p*(p>0?1:M),y*(y>0?1:M)),P=_?1:Math.max(v*(v>0?1:M),b*(b>0?1:M)),T=.5*(C-S),O=.5*(P-D);u=Math.min(s/T,l/O),d={x:-.5*(C+S),y:-.5*(P+D)}}i.borderWidth=e.getMaxBorderWidth(h.data),i.outerRadius=Math.max((u-i.borderWidth)/2,0),i.innerRadius=Math.max(c?i.outerRadius/100*c:0,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=d.x*i.outerRadius,i.offsetY=d.y*i.outerRadius,h.total=e.calculateTotal(),e.outerRadius=i.outerRadius-i.radiusLength*e.getRingIndex(e.index),e.innerRadius=Math.max(e.outerRadius-i.radiusLength,0),r.each(h.data,function(i,n){e.updateElement(i,n,t)})},updateElement:function(t,e,i){var n=this,a=n.chart,o=a.chartArea,s=a.options,l=s.animation,u=(o.left+o.right)/2,d=(o.top+o.bottom)/2,h=s.rotation,c=s.rotation,f=n.getDataset(),g=i&&l.animateRotate?0:t.hidden?0:n.calculateCircumference(f.data[e])*(s.circumference/(2*Math.PI)),m=i&&l.animateScale?0:n.innerRadius,p=i&&l.animateScale?0:n.outerRadius,v=r.valueAtIndexOrDefault;r.extend(t,{_datasetIndex:n.index,_index:e,_model:{x:u+a.offsetX,y:d+a.offsetY,startAngle:h,endAngle:c,circumference:g,outerRadius:p,innerRadius:m,label:v(f.label,e,a.data.labels[e])}});var y=t._model;this.removeHoverStyle(t),i&&l.animateRotate||(y.startAngle=0===e?s.rotation:n.getMeta().data[e-1]._model.endAngle,y.endAngle=y.startAngle+y.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,e=this.getDataset(),i=this.getMeta(),n=0;return r.each(i.data,function(i,a){t=e.data[a],isNaN(t)||i.hidden||(n+=Math.abs(t))}),n},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){for(var e,i,n=0,a=this.index,r=t.length,o=0;o(n=e>n?e:n)?i:n;return n}})}},{25:25,40:40,45:45}],18:[function(t,e,i){"use strict";var n=t(25),a=t(40),r=t(45);n._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}}),e.exports=function(t){function e(t,e){return r.valueOrDefault(t.showLine,e.showLines)}t.controllers.line=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,update:function(t){var i,n,a,o=this,s=o.getMeta(),l=s.dataset,u=s.data||[],d=o.chart.options,h=d.elements.line,c=o.getScaleForId(s.yAxisID),f=o.getDataset(),g=e(f,d);for(g&&(a=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=c,l._datasetIndex=o.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:a.tension?a.tension:r.valueOrDefault(f.lineTension,h.tension),backgroundColor:a.backgroundColor?a.backgroundColor:f.backgroundColor||h.backgroundColor,borderWidth:a.borderWidth?a.borderWidth:f.borderWidth||h.borderWidth,borderColor:a.borderColor?a.borderColor:f.borderColor||h.borderColor,borderCapStyle:a.borderCapStyle?a.borderCapStyle:f.borderCapStyle||h.borderCapStyle,borderDash:a.borderDash?a.borderDash:f.borderDash||h.borderDash,borderDashOffset:a.borderDashOffset?a.borderDashOffset:f.borderDashOffset||h.borderDashOffset,borderJoinStyle:a.borderJoinStyle?a.borderJoinStyle:f.borderJoinStyle||h.borderJoinStyle,fill:a.fill?a.fill:void 0!==f.fill?f.fill:h.fill,steppedLine:a.steppedLine?a.steppedLine:r.valueOrDefault(f.steppedLine,h.stepped),cubicInterpolationMode:a.cubicInterpolationMode?a.cubicInterpolationMode:r.valueOrDefault(f.cubicInterpolationMode,h.cubicInterpolationMode)},l.pivot()),i=0,n=u.length;i');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var r=0;r '),a[r]&&e.push(a[r]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(i,n){var a=t.getDatasetMeta(0),o=e.datasets[0],s=a.data[n].custom||{},l=r.valueAtIndexOrDefault,u=t.options.elements.arc;return{text:i,fillStyle:s.backgroundColor?s.backgroundColor:l(o.backgroundColor,n,u.backgroundColor),strokeStyle:s.borderColor?s.borderColor:l(o.borderColor,n,u.borderColor),lineWidth:s.borderWidth?s.borderWidth:l(o.borderWidth,n,u.borderWidth),hidden:isNaN(o.data[n])||a.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var i,n,a,r=e.index,o=this.chart;for(i=0,n=(o.data.datasets||[]).length;i0&&!isNaN(t)?2*Math.PI/e:0}})}},{25:25,40:40,45:45}],20:[function(t,e,i){"use strict";var n=t(25),a=t(40),r=t(45);n._set("radar",{scale:{type:"radialLinear"},elements:{line:{tension:0}}}),e.exports=function(t){t.controllers.radar=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,linkScales:r.noop,update:function(t){var e=this,i=e.getMeta(),n=i.dataset,a=i.data,o=n.custom||{},s=e.getDataset(),l=e.chart.options.elements.line,u=e.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),r.extend(i.dataset,{_datasetIndex:e.index,_scale:u,_children:a,_loop:!0,_model:{tension:o.tension?o.tension:r.valueOrDefault(s.lineTension,l.tension),backgroundColor:o.backgroundColor?o.backgroundColor:s.backgroundColor||l.backgroundColor,borderWidth:o.borderWidth?o.borderWidth:s.borderWidth||l.borderWidth,borderColor:o.borderColor?o.borderColor:s.borderColor||l.borderColor,fill:o.fill?o.fill:void 0!==s.fill?s.fill:l.fill,borderCapStyle:o.borderCapStyle?o.borderCapStyle:s.borderCapStyle||l.borderCapStyle,borderDash:o.borderDash?o.borderDash:s.borderDash||l.borderDash,borderDashOffset:o.borderDashOffset?o.borderDashOffset:s.borderDashOffset||l.borderDashOffset,borderJoinStyle:o.borderJoinStyle?o.borderJoinStyle:s.borderJoinStyle||l.borderJoinStyle}}),i.dataset.pivot(),r.each(a,function(i,n){e.updateElement(i,n,t)},e),e.updateBezierControlPoints()},updateElement:function(t,e,i){var n=this,a=t.custom||{},o=n.getDataset(),s=n.chart.scale,l=n.chart.options.elements.point,u=s.getPointPositionForValue(e,o.data[e]);void 0!==o.radius&&void 0===o.pointRadius&&(o.pointRadius=o.radius),void 0!==o.hitRadius&&void 0===o.pointHitRadius&&(o.pointHitRadius=o.hitRadius),r.extend(t,{_datasetIndex:n.index,_index:e,_scale:s,_model:{x:i?s.xCenter:u.x,y:i?s.yCenter:u.y,tension:a.tension?a.tension:r.valueOrDefault(o.lineTension,n.chart.options.elements.line.tension),radius:a.radius?a.radius:r.valueAtIndexOrDefault(o.pointRadius,e,l.radius),backgroundColor:a.backgroundColor?a.backgroundColor:r.valueAtIndexOrDefault(o.pointBackgroundColor,e,l.backgroundColor),borderColor:a.borderColor?a.borderColor:r.valueAtIndexOrDefault(o.pointBorderColor,e,l.borderColor),borderWidth:a.borderWidth?a.borderWidth:r.valueAtIndexOrDefault(o.pointBorderWidth,e,l.borderWidth),pointStyle:a.pointStyle?a.pointStyle:r.valueAtIndexOrDefault(o.pointStyle,e,l.pointStyle),hitRadius:a.hitRadius?a.hitRadius:r.valueAtIndexOrDefault(o.pointHitRadius,e,l.hitRadius)}}),t._model.skip=a.skip?a.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,e=this.getMeta();r.each(e.data,function(i,n){var a=i._model,o=r.splineCurve(r.previousItem(e.data,n,!0)._model,a,r.nextItem(e.data,n,!0)._model,a.tension);a.controlPointPreviousX=Math.max(Math.min(o.previous.x,t.right),t.left),a.controlPointPreviousY=Math.max(Math.min(o.previous.y,t.bottom),t.top),a.controlPointNextX=Math.max(Math.min(o.next.x,t.right),t.left),a.controlPointNextY=Math.max(Math.min(o.next.y,t.bottom),t.top),i.pivot()})},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,a=t._model;a.radius=i.hoverRadius?i.hoverRadius:r.valueAtIndexOrDefault(e.pointHoverRadius,n,this.chart.options.elements.point.hoverRadius),a.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:r.valueAtIndexOrDefault(e.pointHoverBackgroundColor,n,r.getHoverColor(a.backgroundColor)),a.borderColor=i.hoverBorderColor?i.hoverBorderColor:r.valueAtIndexOrDefault(e.pointHoverBorderColor,n,r.getHoverColor(a.borderColor)),a.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:r.valueAtIndexOrDefault(e.pointHoverBorderWidth,n,a.borderWidth)},removeHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,a=t._model,o=this.chart.options.elements.point;a.radius=i.radius?i.radius:r.valueAtIndexOrDefault(e.pointRadius,n,o.radius),a.backgroundColor=i.backgroundColor?i.backgroundColor:r.valueAtIndexOrDefault(e.pointBackgroundColor,n,o.backgroundColor),a.borderColor=i.borderColor?i.borderColor:r.valueAtIndexOrDefault(e.pointBorderColor,n,o.borderColor),a.borderWidth=i.borderWidth?i.borderWidth:r.valueAtIndexOrDefault(e.pointBorderWidth,n,o.borderWidth)}})}},{25:25,40:40,45:45}],21:[function(t,e,i){"use strict";t(25)._set("scatter",{hover:{mode:"single"},scales:{xAxes:[{id:"x-axis-1",type:"linear",position:"bottom"}],yAxes:[{id:"y-axis-1",type:"linear",position:"left"}]},showLines:!1,tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}}),e.exports=function(t){t.controllers.scatter=t.controllers.line}},{25:25}],22:[function(t,e,i){"use strict";var n=t(25),a=t(26),r=t(45);n._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:r.noop,onComplete:r.noop}}),e.exports=function(t){t.Animation=a.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,i,n){var a,r,o=this.animations;for(e.chart=t,n||(t.animating=!0),a=0,r=o.length;a1&&(i=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1),t.advance(1+i);var n=Date.now();t.dropFrames+=(n-e)/t.frameDuration,t.animations.length>0&&t.requestAnimationFrame()},advance:function(t){for(var e,i,n=this.animations,a=0;a=e.numSteps?(r.callback(e.onAnimationComplete,[e],i),i.animating=!1,n.splice(a,1)):++a}},Object.defineProperty(t.Animation.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(t.Animation.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}})}},{25:25,26:26,45:45}],23:[function(t,e,i){"use strict";var n=t(25),a=t(45),r=t(28),o=t(30),s=t(48),l=t(31);e.exports=function(t){function e(t){return"top"===t||"bottom"===t}t.types={},t.instances={},t.controllers={},a.extend(t.prototype,{construct:function(e,i){var r,o,l=this;(o=(r=(r=i)||{}).data=r.data||{}).datasets=o.datasets||[],o.labels=o.labels||[],r.options=a.configMerge(n.global,n[r.type],r.options||{}),i=r;var u=s.acquireContext(e,i),d=u&&u.canvas,h=d&&d.height,c=d&&d.width;l.id=a.uid(),l.ctx=u,l.canvas=d,l.config=i,l.width=c,l.height=h,l.aspectRatio=h?c/h:null,l.options=i.options,l._bufferedRender=!1,l.chart=l,l.controller=l,t.instances[l.id]=l,Object.defineProperty(l,"data",{get:function(){return l.config.data},set:function(t){l.config.data=t}}),u&&d?(l.initialize(),l.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return l.notify(t,"beforeInit"),a.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.initToolTip(),l.notify(t,"afterInit"),t},clear:function(){return a.canvas.clear(this),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(t){var e=this,i=e.options,n=e.canvas,r=i.maintainAspectRatio&&e.aspectRatio||null,o=Math.max(0,Math.floor(a.getMaximumWidth(n))),s=Math.max(0,Math.floor(r?o/r:a.getMaximumHeight(n)));if((e.width!==o||e.height!==s)&&(n.width=e.width=o,n.height=e.height=s,n.style.width=o+"px",n.style.height=s+"px",a.retinaScale(e,i.devicePixelRatio),!t)){var u={width:o,height:s};l.notify(e,"resize",[u]),e.options.onResize&&e.options.onResize(e,u),e.stop(),e.update(e.options.responsiveAnimationDuration)}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},i=t.scale;a.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),a.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),i&&(i.id=i.id||"scale")},buildOrUpdateScales:function(){var i=this,n=i.options,r=i.scales||{},o=[],s=Object.keys(r).reduce(function(t,e){return t[e]=!1,t},{});n.scales&&(o=o.concat((n.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(n.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),n.scale&&o.push({options:n.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),a.each(o,function(n){var o=n.options,l=o.id,u=a.valueOrDefault(o.type,n.dtype);e(o.position)!==e(n.dposition)&&(o.position=n.dposition),s[l]=!0;var d=null;if(l in r&&r[l].type===u)(d=r[l]).options=o,d.ctx=i.ctx,d.chart=i;else{var h=t.scaleService.getScaleConstructor(u);if(!h)return;d=new h({id:l,type:u,options:o,ctx:i.ctx,chart:i}),r[d.id]=d}d.mergeTicksOptions(),n.isDefault&&(i.scale=d)}),a.each(s,function(t,e){t||delete r[e]}),i.scales=r,t.scaleService.addScalesToLayout(this)},buildOrUpdateControllers:function(){var e=this,i=[],n=[];return a.each(e.data.datasets,function(a,r){var o=e.getDatasetMeta(r),s=a.type||e.config.type;if(o.type&&o.type!==s&&(e.destroyDatasetMeta(r),o=e.getDatasetMeta(r)),o.type=s,i.push(o.type),o.controller)o.controller.updateIndex(r),o.controller.linkScales();else{var l=t.controllers[o.type];if(void 0===l)throw new Error('"'+o.type+'" is not a chart type.');o.controller=new l(e,r),n.push(o.controller)}},e),n},resetElements:function(){var t=this;a.each(t.data.datasets,function(e,i){t.getDatasetMeta(i).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(e){var i,n,r=this;if(e&&"object"==typeof e||(e={duration:e,lazy:arguments[1]}),n=(i=r).options,a.each(i.scales,function(t){o.removeBox(i,t)}),n=a.configMerge(t.defaults.global,t.defaults[i.config.type],n),i.options=i.config.options=n,i.ensureScalesHaveIDs(),i.buildOrUpdateScales(),i.tooltip._options=n.tooltips,i.tooltip.initialize(),l._invalidate(r),!1!==l.notify(r,"beforeUpdate")){r.tooltip._data=r.data;var s=r.buildOrUpdateControllers();a.each(r.data.datasets,function(t,e){r.getDatasetMeta(e).controller.buildOrUpdateElements()},r),r.updateLayout(),r.options.animation&&r.options.animation.duration&&a.each(s,function(t){t.reset()}),r.updateDatasets(),r.tooltip.initialize(),r.lastActive=[],l.notify(r,"afterUpdate"),r._bufferedRender?r._bufferedRequest={duration:e.duration,easing:e.easing,lazy:e.lazy}:r.render(e)}},updateLayout:function(){!1!==l.notify(this,"beforeLayout")&&(o.update(this,this.width,this.height),l.notify(this,"afterScaleUpdate"),l.notify(this,"afterLayout"))},updateDatasets:function(){if(!1!==l.notify(this,"beforeDatasetsUpdate")){for(var t=0,e=this.data.datasets.length;t=0;--i)e.isDatasetVisible(i)&&e.drawDataset(i,t);l.notify(e,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var i=this.getDatasetMeta(t),n={meta:i,index:t,easingValue:e};!1!==l.notify(this,"beforeDatasetDraw",[n])&&(i.controller.draw(e),l.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,i={tooltip:e,easingValue:t};!1!==l.notify(this,"beforeTooltipDraw",[i])&&(e.draw(),l.notify(this,"afterTooltipDraw",[i]))},getElementAtEvent:function(t){return r.modes.single(this,t)},getElementsAtEvent:function(t){return r.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return r.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,i){var n=r.modes[e];return"function"==typeof n?n(this,t,i):[]},getDatasetAtEvent:function(t){return r.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var i=e._meta[this.id];return i||(i=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,i=this.data.datasets.length;e0||(e.forEach(function(e){delete t[e]}),delete t._chartjs)}}t.DatasetController=function(t,e){this.initialize(t,e)},n.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){this.chart=t,this.index=e,this.linkScales(),this.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),i=t.getDataset();null!==e.xAxisID&&e.xAxisID in t.chart.scales||(e.xAxisID=i.xAxisID||t.chart.options.scales.xAxes[0].id),null!==e.yAxisID&&e.yAxisID in t.chart.scales||(e.yAxisID=i.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},destroy:function(){this._data&&i(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,i=this.getMeta(),n=this.getDataset().data||[],a=i.data;for(t=0,e=n.length;ti&&this.insertElements(i,n-i)},insertElements:function(t,e){for(var i=0;i=i[e].length&&i[e].push({}),!i[e][o].type||l.type&&l.type!==i[e][o].type?r.merge(i[e][o],[t.scaleService.getScaleDefaults(s),l]):r.merge(i[e][o],l)}else r._merger(e,i,n,a)}})},r.where=function(t,e){if(r.isArray(t)&&Array.prototype.filter)return t.filter(e);var i=[];return r.each(t,function(t){e(t)&&i.push(t)}),i},r.findIndex=Array.prototype.findIndex?function(t,e,i){return t.findIndex(e,i)}:function(t,e,i){i=void 0===i?t:i;for(var n=0,a=t.length;n=0;n--){var a=t[n];if(e(a))return a}},r.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},r.almostEquals=function(t,e,i){return Math.abs(t-e)t},r.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},r.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},r.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},r.log10=Math.log10?function(t){return Math.log10(t)}:function(t){var e=Math.log(t)*Math.LOG10E,i=Math.round(e);return t===Math.pow(10,i)?i:e},r.toRadians=function(t){return t*(Math.PI/180)},r.toDegrees=function(t){return t*(180/Math.PI)},r.getAngleFromPoint=function(t,e){var i=e.x-t.x,n=e.y-t.y,a=Math.sqrt(i*i+n*n),r=Math.atan2(n,i);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},r.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},r.aliasPixel=function(t){return t%2==0?0:.5},r.splineCurve=function(t,e,i,n){var a=t.skip?e:t,r=e,o=i.skip?e:i,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),h=n*(u=isNaN(u)?0:u),c=n*(d=isNaN(d)?0:d);return{previous:{x:r.x-h*(o.x-a.x),y:r.y-h*(o.y-a.y)},next:{x:r.x+c*(o.x-a.x),y:r.y+c*(o.y-a.y)}}},r.EPSILON=Number.EPSILON||1e-14,r.splineCurveMonotone=function(t){var e,i,n,a,o,s,l,u,d,h=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),c=h.length;for(e=0;e0?h[e-1]:null,(a=e0?h[e-1]:null,a=e=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},r.previousItem=function(t,e,i){return i?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},r.niceNum=function(t,e){var i=Math.floor(r.log10(t)),n=t/Math.pow(10,i);return(e?n<1.5?1:n<3?2:n<7?5:10:n<=1?1:n<=2?2:n<=5?5:10)*Math.pow(10,i)},r.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},r.getRelativePosition=function(t,e){var i,n,a=t.originalEvent||t,o=t.currentTarget||t.srcElement,s=o.getBoundingClientRect(),l=a.touches;l&&l.length>0?(i=l[0].clientX,n=l[0].clientY):(i=a.clientX,n=a.clientY);var u=parseFloat(r.getStyle(o,"padding-left")),d=parseFloat(r.getStyle(o,"padding-top")),h=parseFloat(r.getStyle(o,"padding-right")),c=parseFloat(r.getStyle(o,"padding-bottom")),f=s.right-s.left-u-h,g=s.bottom-s.top-d-c;return{x:i=Math.round((i-s.left-u)/f*o.width/e.currentDevicePixelRatio),y:n=Math.round((n-s.top-d)/g*o.height/e.currentDevicePixelRatio)}},r.getConstraintWidth=function(t){return o(t,"max-width","clientWidth")},r.getConstraintHeight=function(t){return o(t,"max-height","clientHeight")},r.getMaximumWidth=function(t){var e=t.parentNode;if(!e)return t.clientWidth;var i=parseInt(r.getStyle(e,"padding-left"),10),n=parseInt(r.getStyle(e,"padding-right"),10),a=e.clientWidth-i-n,o=r.getConstraintWidth(t);return isNaN(o)?a:Math.min(a,o)},r.getMaximumHeight=function(t){var e=t.parentNode;if(!e)return t.clientHeight;var i=parseInt(r.getStyle(e,"padding-top"),10),n=parseInt(r.getStyle(e,"padding-bottom"),10),a=e.clientHeight-i-n,o=r.getConstraintHeight(t);return isNaN(o)?a:Math.min(a,o)},r.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},r.retinaScale=function(t,e){var i=t.currentDevicePixelRatio=e||window.devicePixelRatio||1;if(1!==i){var n=t.canvas,a=t.height,r=t.width;n.height=a*i,n.width=r*i,t.ctx.scale(i,i),n.style.height||n.style.width||(n.style.height=a+"px",n.style.width=r+"px")}},r.fontString=function(t,e,i){return e+" "+t+"px "+i},r.longestText=function(t,e,i,n){var a=(n=n||{}).data=n.data||{},o=n.garbageCollect=n.garbageCollect||[];n.font!==e&&(a=n.data={},o=n.garbageCollect=[],n.font=e),t.font=e;var s=0;r.each(i,function(e){null!=e&&!0!==r.isArray(e)?s=r.measureText(t,a,o,s,e):r.isArray(e)&&r.each(e,function(e){null==e||r.isArray(e)||(s=r.measureText(t,a,o,s,e))})});var l=o.length/2;if(l>i.length){for(var u=0;un&&(n=r),n},r.numberOfLabelLines=function(t){var e=1;return r.each(t,function(t){r.isArray(t)&&t.length>e&&(e=t.length)}),e},r.color=n?function(t){return t instanceof CanvasGradient&&(t=a.global.defaultColor),n(t)}:function(t){return console.error("Color.js not found!"),t},r.getHoverColor=function(t){return t instanceof CanvasPattern?t:r.color(t).saturate(.5).darken(.1).rgbString()}}},{2:2,25:25,45:45}],28:[function(t,e,i){"use strict";var n=t(45);function a(t,e){return t.native?{x:t.x,y:t.y}:n.getRelativePosition(t,e)}function r(t,e){var i,n,a,r,o;for(n=0,r=t.data.datasets.length;n0&&(u=t.getDatasetMeta(u[0]._datasetIndex).data),u},"x-axis":function(t,e){return u(t,e,{intersect:!1})},point:function(t,e){return o(t,a(e,t))},nearest:function(t,e,i){var n=a(e,t);i.axis=i.axis||"xy";var r=l(i.axis),o=s(t,n,i.intersect,r);return o.length>1&&o.sort(function(t,e){var i=t.getArea()-e.getArea();return 0===i&&(i=t._datasetIndex-e._datasetIndex),i}),o.slice(0,1)},x:function(t,e,i){var n=a(e,t),o=[],s=!1;return r(t,function(t){t.inXRange(n.x)&&o.push(t),t.inRange(n.x,n.y)&&(s=!0)}),i.intersect&&!s&&(o=[]),o},y:function(t,e,i){var n=a(e,t),o=[],s=!1;return r(t,function(t){t.inYRange(n.y)&&o.push(t),t.inRange(n.x,n.y)&&(s=!0)}),i.intersect&&!s&&(o=[]),o}}}},{45:45}],29:[function(t,e,i){"use strict";t(25)._set("global",{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},layout:{padding:{top:0,right:0,bottom:0,left:0}}}),e.exports=function(){var t=function(t,e){return this.construct(t,e),this};return t.Chart=t,t}},{25:25}],30:[function(t,e,i){"use strict";var n=t(45);function a(t,e){return n.where(t,function(t){return t.position===e})}function r(t,e){t.forEach(function(t,e){return t._tmpIndex_=e,t}),t.sort(function(t,i){var n=e?i:t,a=e?t:i;return n.weight===a.weight?n._tmpIndex_-a._tmpIndex_:n.weight-a.weight}),t.forEach(function(t){delete t._tmpIndex_})}e.exports={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,t.boxes.push(e)},removeBox:function(t,e){var i=t.boxes?t.boxes.indexOf(e):-1;-1!==i&&t.boxes.splice(i,1)},configure:function(t,e,i){for(var n,a=["fullWidth","position","weight"],r=a.length,o=0;oc&<.maxHeight){l--;break}l++,h=u*d}t.labelRotation=l},afterCalculateTickRotation:function(){r.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){r.callback(this.options.beforeFit,[this])},fit:function(){var t=this,n=t.minSize={width:0,height:0},a=s(t._ticks),l=t.options,u=l.ticks,d=l.scaleLabel,h=l.gridLines,c=l.display,f=t.isHorizontal(),g=i(u),m=l.gridLines.tickMarkLength;if(n.width=f?t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:c&&h.drawTicks?m:0,n.height=f?c&&h.drawTicks?m:0:t.maxHeight,d.display&&c){var p=o(d)+r.options.toPadding(d.padding).height;f?n.height+=p:n.width+=p}if(u.display&&c){var v=r.longestText(t.ctx,g.font,a,t.longestTextCache),y=r.numberOfLabelLines(a),b=.5*g.size,x=t.options.ticks.padding;if(f){t.longestLabelWidth=v;var _=r.toRadians(t.labelRotation),k=Math.cos(_),w=Math.sin(_)*v+g.size*y+b*(y-1)+b;n.height=Math.min(t.maxHeight,n.height+w+x),t.ctx.font=g.font;var M=e(t.ctx,a[0],g.font),S=e(t.ctx,a[a.length-1],g.font);0!==t.labelRotation?(t.paddingLeft="bottom"===l.position?k*M+3:k*b+3,t.paddingRight="bottom"===l.position?k*b+3:k*S+3):(t.paddingLeft=M/2+3,t.paddingRight=S/2+3)}else u.mirror?v=0:v+=x+b,n.width=Math.min(t.maxWidth,n.width+v),t.paddingTop=g.size/2,t.paddingBottom=g.size/2}t.handleMargins(),t.width=n.width,t.height=n.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){r.callback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(r.isNullOrUndef(t))return NaN;if("number"==typeof t&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},getLabelForIndex:r.noop,getPixelForValue:r.noop,getValueForPixel:r.noop,getPixelForTick:function(t){var e=this,i=e.options.offset;if(e.isHorizontal()){var n=(e.width-(e.paddingLeft+e.paddingRight))/Math.max(e._ticks.length-(i?0:1),1),a=n*t+e.paddingLeft;i&&(a+=n/2);var r=e.left+Math.round(a);return r+=e.isFullWidth()?e.margins.left:0}var o=e.height-(e.paddingTop+e.paddingBottom);return e.top+t*(o/(e._ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var i=(e.width-(e.paddingLeft+e.paddingRight))*t+e.paddingLeft,n=e.left+Math.round(i);return n+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,i,n,a,o=this,s=o.isHorizontal(),l=o.options.ticks.minor,u=t.length,d=r.toRadians(o.labelRotation),h=Math.cos(d),c=o.longestLabelWidth*h,f=[];for(l.maxTicksLimit&&(a=l.maxTicksLimit),s&&(e=!1,(c+l.autoSkipPadding)*u>o.width-(o.paddingLeft+o.paddingRight)&&(e=1+Math.floor((c+l.autoSkipPadding)*u/(o.width-(o.paddingLeft+o.paddingRight)))),a&&u>a&&(e=Math.max(e,Math.floor(u/a)))),i=0;i1&&i%e>0||i%e==0&&i+e>=u)&&i!==u-1&&delete n.label,f.push(n);return f},draw:function(t){var e=this,a=e.options;if(a.display){var s=e.ctx,u=n.global,d=a.ticks.minor,h=a.ticks.major||d,c=a.gridLines,f=a.scaleLabel,g=0!==e.labelRotation,m=e.isHorizontal(),p=d.autoSkip?e._autoSkip(e.getTicks()):e.getTicks(),v=r.valueOrDefault(d.fontColor,u.defaultFontColor),y=i(d),b=r.valueOrDefault(h.fontColor,u.defaultFontColor),x=i(h),_=c.drawTicks?c.tickMarkLength:0,k=r.valueOrDefault(f.fontColor,u.defaultFontColor),w=i(f),M=r.options.toPadding(f.padding),S=r.toRadians(e.labelRotation),D=[],C=e.options.gridLines.lineWidth,P="right"===a.position?e.right:e.right-C-_,T="right"===a.position?e.right+_:e.right,O="bottom"===a.position?e.top+C:e.bottom-_-C,I="bottom"===a.position?e.top+C+_:e.bottom+C;if(r.each(p,function(i,n){if(!r.isNullOrUndef(i.label)){var o,s,h,f,v,y,b,x,k,w,M,A,F,R,L=i.label;n===e.zeroLineIndex&&a.offset===c.offsetGridLines?(o=c.zeroLineWidth,s=c.zeroLineColor,h=c.zeroLineBorderDash,f=c.zeroLineBorderDashOffset):(o=r.valueAtIndexOrDefault(c.lineWidth,n),s=r.valueAtIndexOrDefault(c.color,n),h=r.valueOrDefault(c.borderDash,u.borderDash),f=r.valueOrDefault(c.borderDashOffset,u.borderDashOffset));var W="middle",Y="middle",N=d.padding;if(m){var z=_+N;"bottom"===a.position?(Y=g?"middle":"top",W=g?"right":"center",R=e.top+z):(Y=g?"middle":"bottom",W=g?"left":"center",R=e.bottom-z);var H=l(e,n,c.offsetGridLines&&p.length>1);H1);E3?i[2]-i[1]:i[1]-i[0];Math.abs(a)>1&&t!==Math.floor(t)&&(a=t-Math.floor(t));var r=n.log10(Math.abs(a)),o="";if(0!==t){var s=-1*Math.floor(r);s=Math.max(Math.min(s,20),0),o=t.toFixed(s)}else o="0";return o},logarithmic:function(t,e,i){var a=t/Math.pow(10,Math.floor(n.log10(t)));return 0===t?"0":1===a||2===a||5===a||0===e||e===i.length-1?t.toExponential():""}}}},{45:45}],35:[function(t,e,i){"use strict";var n=t(25),a=t(26),r=t(45);n._set("global",{tooltips:{enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:r.noop,title:function(t,e){var i="",n=e.labels,a=n?n.length:0;if(t.length>0){var r=t[0];r.xLabel?i=r.xLabel:a>0&&r.indexl.height-e.height&&(h="bottom");var c=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===h?(i=function(t){return t<=c},n=function(t){return t>c}):(i=function(t){return t<=e.width/2},n=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},r=function(t){return t-e.width-s.caretSize-s.caretPadding<0},o=function(t){return t<=f?"top":"bottom"},i(s.x)?(d="left",a(s.x)&&(d="center",h=o(s.y))):n(s.x)&&(d="right",r(s.x)&&(d="center",h=o(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:h}}(this,A=function(t,e){var i=t._chart.ctx,n=2*e.yPadding,a=0,o=e.body,s=o.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);s+=e.beforeBody.length+e.afterBody.length;var l=e.title.length,u=e.footer.length,d=e.titleFontSize,h=e.bodyFontSize,c=e.footerFontSize;n+=l*d,n+=l?(l-1)*e.titleSpacing:0,n+=l?e.titleMarginBottom:0,n+=s*h,n+=s?(s-1)*e.bodySpacing:0,n+=u?e.footerMarginTop:0,n+=u*c,n+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){a=Math.max(a,i.measureText(t).width+f)};return i.font=r.fontString(d,e._titleFontStyle,e._titleFontFamily),r.each(e.title,g),i.font=r.fontString(h,e._bodyFontStyle,e._bodyFontFamily),r.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?h+2:0,r.each(o,function(t){r.each(t.before,g),r.each(t.lines,g),r.each(t.after,g)}),f=0,i.font=r.fontString(c,e._footerFontStyle,e._footerFontFamily),r.each(e.footer,g),{width:a+=2*e.xPadding,height:n}}(this,C)),a=C,s=A,l=O,u=M._chart,d=a.x,h=a.y,c=a.caretSize,f=a.caretPadding,g=a.cornerRadius,m=l.xAlign,p=l.yAlign,v=c+f,y=g+f,"right"===m?d-=s.width:"center"===m&&((d-=s.width/2)+s.width>u.width&&(d=u.width-s.width),d<0&&(d=0)),"top"===p?h+=v:h-="bottom"===p?s.height+v:s.height/2,"center"===p?"left"===m?d+=v:"right"===m&&(d-=v):"left"===m?d-=y:"right"===m&&(d+=y),I={x:d,y:h}}else C.opacity=0;return C.xAlign=O.xAlign,C.yAlign=O.yAlign,C.x=I.x,C.y=I.y,C.width=A.width,C.height=A.height,C.caretX=F.x,C.caretY=F.y,M._model=C,e&&S.custom&&S.custom.call(M,C),M},drawCaret:function(t,e){var i=this._chart.ctx,n=this._view,a=this.getCaretPosition(t,e,n);i.lineTo(a.x1,a.y1),i.lineTo(a.x2,a.y2),i.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,i){var n,a,r,o,s,l,u=i.caretSize,d=i.cornerRadius,h=i.xAlign,c=i.yAlign,f=t.x,g=t.y,m=e.width,p=e.height;if("center"===c)s=g+p/2,"left"===h?(a=(n=f)-u,r=n,o=s+u,l=s-u):(a=(n=f+m)+u,r=n,o=s-u,l=s+u);else if("left"===h?(n=(a=f+d+u)-u,r=a+u):"right"===h?(n=(a=f+m-d-u)-u,r=a+u):(n=(a=i.caretX)-u,r=a+u),"top"===c)s=(o=g)-u,l=o;else{s=(o=g+p)+u,l=o;var v=r;r=n,n=v}return{x1:n,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,i,n,a){var o=i.title;if(o.length){n.textAlign=i._titleAlign,n.textBaseline="top";var s,l,u=i.titleFontSize,d=i.titleSpacing;for(n.fillStyle=e(i.titleFontColor,a),n.font=r.fontString(u,i._titleFontStyle,i._titleFontFamily),s=0,l=o.length;s0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var i={width:e.width,height:e.height},n={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&r&&(this.drawBackground(n,e,t,i,a),n.x+=e.xPadding,n.y+=e.yPadding,this.drawTitle(n,e,t,a),this.drawBody(n,e,t,a),this.drawFooter(n,e,t,a))}},handleEvent:function(t){var e,i=this,n=i._options;return i._lastActive=i._lastActive||[],"mouseout"===t.type?i._active=[]:i._active=i._chart.getElementsAtEventForMode(t,n.mode,n),(e=!r.arrayEquals(i._active,i._lastActive))&&(i._lastActive=i._active,(n.enabled||n.custom)&&(i._eventPosition={x:t.x,y:t.y},i.update(!0),i.pivot())),e}}),t.Tooltip.positioners={average:function(t){if(!t.length)return!1;var e,i,n=0,a=0,r=0;for(e=0,i=t.length;el;)a-=2*Math.PI;for(;a=s&&a<=l,d=o>=i.innerRadius&&o<=i.outerRadius;return u&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,i=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,i=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},draw:function(){var t=this._chart.ctx,e=this._view,i=e.startAngle,n=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,i,n),t.arc(e.x,e.y,e.innerRadius,n,i,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})},{25:25,26:26,45:45}],37:[function(t,e,i){"use strict";var n=t(25),a=t(26),r=t(45),o=n.global;n._set("global",{elements:{line:{tension:.4,backgroundColor:o.defaultColor,borderWidth:3,borderColor:o.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}}),e.exports=a.extend({draw:function(){var t,e,i,n,a=this._view,s=this._chart.ctx,l=a.spanGaps,u=this._children.slice(),d=o.elements.line,h=-1;for(this._loop&&u.length&&u.push(u[0]),s.save(),s.lineCap=a.borderCapStyle||d.borderCapStyle,s.setLineDash&&s.setLineDash(a.borderDash||d.borderDash),s.lineDashOffset=a.borderDashOffset||d.borderDashOffset,s.lineJoin=a.borderJoinStyle||d.borderJoinStyle,s.lineWidth=a.borderWidth||d.borderWidth,s.strokeStyle=a.borderColor||o.defaultColor,s.beginPath(),h=-1,t=0;tt?1:-1,r=1,o=l.borderSkipped||"left"):(t=l.x-l.width/2,e=l.x+l.width/2,i=l.y,a=1,r=(n=l.base)>i?1:-1,o=l.borderSkipped||"bottom"),u){var d=Math.min(Math.abs(t-e),Math.abs(i-n)),h=(u=u>d?d:u)/2,c=t+("left"!==o?h*a:0),f=e+("right"!==o?-h*a:0),g=i+("top"!==o?h*r:0),m=n+("bottom"!==o?-h*r:0);c!==f&&(i=g,n=m),g!==m&&(t=c,e=f)}s.beginPath(),s.fillStyle=l.backgroundColor,s.strokeStyle=l.borderColor,s.lineWidth=u;var p=[[t,n],[t,i],[e,i],[e,n]],v=["bottom","left","top","right"].indexOf(o,0);function y(t){return p[(v+t)%4]}-1===v&&(v=0);var b=y(0);s.moveTo(b[0],b[1]);for(var x=1;x<4;x++)b=y(x),s.lineTo(b[0],b[1]);s.fill(),u&&s.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var i=!1;if(this._view){var n=o(this);i=t>=n.left&&t<=n.right&&e>=n.top&&e<=n.bottom}return i},inLabelRange:function(t,e){if(!this._view)return!1;var i=o(this);return r(this)?t>=i.left&&t<=i.right:e>=i.top&&e<=i.bottom},inXRange:function(t){var e=o(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=o(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,e,i=this._view;return r(this)?(t=i.x,e=(i.y+i.base)/2):(t=(i.x+i.base)/2,e=i.y),{x:t,y:e}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})},{25:25,26:26}],40:[function(t,e,i){"use strict";e.exports={},e.exports.Arc=t(36),e.exports.Line=t(37),e.exports.Point=t(38),e.exports.Rectangle=t(39)},{36:36,37:37,38:38,39:39}],41:[function(t,e,i){"use strict";var n=t(42);i=e.exports={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,i,n,a,r){if(r){var o=Math.min(r,n/2),s=Math.min(r,a/2);t.moveTo(e+o,i),t.lineTo(e+n-o,i),t.quadraticCurveTo(e+n,i,e+n,i+s),t.lineTo(e+n,i+a-s),t.quadraticCurveTo(e+n,i+a,e+n-o,i+a),t.lineTo(e+o,i+a),t.quadraticCurveTo(e,i+a,e,i+a-s),t.lineTo(e,i+s),t.quadraticCurveTo(e,i,e+o,i)}else t.rect(e,i,n,a)},drawPoint:function(t,e,i,n,a){var r,o,s,l,u,d;if(!e||"object"!=typeof e||"[object HTMLImageElement]"!==(r=e.toString())&&"[object HTMLCanvasElement]"!==r){if(!(isNaN(i)||i<=0)){switch(e){default:t.beginPath(),t.arc(n,a,i,0,2*Math.PI),t.closePath(),t.fill();break;case"triangle":t.beginPath(),u=(o=3*i/Math.sqrt(3))*Math.sqrt(3)/2,t.moveTo(n-o/2,a+u/3),t.lineTo(n+o/2,a+u/3),t.lineTo(n,a-2*u/3),t.closePath(),t.fill();break;case"rect":d=1/Math.SQRT2*i,t.beginPath(),t.fillRect(n-d,a-d,2*d,2*d),t.strokeRect(n-d,a-d,2*d,2*d);break;case"rectRounded":var h=i/Math.SQRT2,c=n-h,f=a-h,g=Math.SQRT2*i;t.beginPath(),this.roundedRect(t,c,f,g,g,i/2),t.closePath(),t.fill();break;case"rectRot":d=1/Math.SQRT2*i,t.beginPath(),t.moveTo(n-d,a),t.lineTo(n,a+d),t.lineTo(n+d,a),t.lineTo(n,a-d),t.closePath(),t.fill();break;case"cross":t.beginPath(),t.moveTo(n,a+i),t.lineTo(n,a-i),t.moveTo(n-i,a),t.lineTo(n+i,a),t.closePath();break;case"crossRot":t.beginPath(),s=Math.cos(Math.PI/4)*i,l=Math.sin(Math.PI/4)*i,t.moveTo(n-s,a-l),t.lineTo(n+s,a+l),t.moveTo(n-s,a+l),t.lineTo(n+s,a-l),t.closePath();break;case"star":t.beginPath(),t.moveTo(n,a+i),t.lineTo(n,a-i),t.moveTo(n-i,a),t.lineTo(n+i,a),s=Math.cos(Math.PI/4)*i,l=Math.sin(Math.PI/4)*i,t.moveTo(n-s,a-l),t.lineTo(n+s,a+l),t.moveTo(n-s,a+l),t.lineTo(n+s,a-l),t.closePath();break;case"line":t.beginPath(),t.moveTo(n-i,a),t.lineTo(n+i,a),t.closePath();break;case"dash":t.beginPath(),t.moveTo(n,a),t.lineTo(n+i,a),t.closePath()}t.stroke()}}else t.drawImage(e,n-e.width/2,a-e.height/2,e.width,e.height)},clipArea:function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},unclipArea:function(t){t.restore()},lineTo:function(t,e,i,n){if(i.steppedLine)return"after"===i.steppedLine&&!n||"after"!==i.steppedLine&&n?t.lineTo(e.x,i.y):t.lineTo(i.x,e.y),void t.lineTo(i.x,i.y);i.tension?t.bezierCurveTo(n?e.controlPointPreviousX:e.controlPointNextX,n?e.controlPointPreviousY:e.controlPointNextY,n?i.controlPointNextX:i.controlPointPreviousX,n?i.controlPointNextY:i.controlPointPreviousY,i.x,i.y):t.lineTo(i.x,i.y)}};n.clear=i.clear,n.drawRoundedRectangle=function(t){t.beginPath(),i.roundedRect.apply(i,arguments),t.closePath()}},{42:42}],42:[function(t,e,i){"use strict";var n,a={noop:function(){},uid:(n=0,function(){return n++}),isNullOrUndef:function(t){return null==t},isArray:Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},isObject:function(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)},valueOrDefault:function(t,e){return void 0===t?e:t},valueAtIndexOrDefault:function(t,e,i){return a.valueOrDefault(a.isArray(t)?t[e]:t,i)},callback:function(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)},each:function(t,e,i,n){var r,o,s;if(a.isArray(t))if(o=t.length,n)for(r=o-1;r>=0;r--)e.call(i,t[r],r);else for(r=0;r=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:1===t?1:(i||(i=.3),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),-n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i))},easeOutElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:1===t?1:(i||(i=.3),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),n*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/i)+1)},easeInOutElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:2==(t/=.5)?1:(i||(i=.45),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),t<1?n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*-.5:n*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*.5+1)},easeInBack:function(t){return t*t*(2.70158*t-1.70158)},easeOutBack:function(t){return(t-=1)*t*(2.70158*t+1.70158)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-a.easeOutBounce(1-t)},easeOutBounce:function(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},easeInOutBounce:function(t){return t<.5?.5*a.easeInBounce(2*t):.5*a.easeOutBounce(2*t-1)+.5}};e.exports={effects:a},n.easingEffects=a},{42:42}],44:[function(t,e,i){"use strict";var n=t(42);e.exports={toLineHeight:function(t,e){var i=(""+t).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t},toPadding:function(t){var e,i,a,r;return n.isObject(t)?(e=+t.top||0,i=+t.right||0,a=+t.bottom||0,r=+t.left||0):e=i=a=r=+t||0,{top:e,right:i,bottom:a,left:r,height:e+a,width:r+i}},resolve:function(t,e,i){var a,r,o;for(a=0,r=t.length;a
';var a=e.childNodes[0],o=e.childNodes[1];e._reset=function(){a.scrollLeft=1e6,a.scrollTop=1e6,o.scrollLeft=1e6,o.scrollTop=1e6};var s=function(){e._reset(),t()};return c(a,"scroll",s.bind(a,"expand")),c(o,"scroll",s.bind(o,"shrink")),e}((u=function(){if(b.resizer)return e(g("resize",i))},h=!1,f=[],function(){f=Array.prototype.slice.call(arguments),d=d||this,h||(h=!0,n.requestAnimFrame.call(window,function(){h=!1,u.apply(d,f)}))}));p=function(){if(b.resizer){var e=t.parentNode;e&&e!==x.parentNode&&e.insertBefore(x,e.firstChild),x._reset()}},v=(m=t)[a]||(m[a]={}),y=v.renderProxy=function(t){t.animationName===s&&p()},n.each(l,function(t){c(m,t,y)}),v.reflow=!!m.offsetParent,m.classList.add(o)}function p(t){var e,i,r,s=t[a]||{},u=s.resizer;delete s.resizer,i=(e=t)[a]||{},(r=i.renderProxy)&&(n.each(l,function(t){f(e,t,r)}),delete i.renderProxy),e.classList.remove(o),u&&u.parentNode&&u.parentNode.removeChild(u)}e.exports={_enabled:"undefined"!=typeof window&&"undefined"!=typeof document,initialize:function(){var t,e,i,n="from{opacity:0.99}to{opacity:1}";e="@-webkit-keyframes "+s+"{"+n+"}@keyframes "+s+"{"+n+"}."+o+"{-webkit-animation:"+s+" 0.001s;animation:"+s+" 0.001s;}",i=(t=this)._style||document.createElement("style"),t._style||(t._style=i,e="/* Chart.js */\n"+e,i.setAttribute("type","text/css"),document.getElementsByTagName("head")[0].appendChild(i)),i.appendChild(document.createTextNode(e))},acquireContext:function(t,e){"string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas);var i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){var i=t.style,n=t.getAttribute("height"),r=t.getAttribute("width");if(t[a]={initial:{height:n,width:r,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",null===r||""===r){var o=d(t,"width");void 0!==o&&(t.width=o)}if(null===n||""===n)if(""===t.style.height)t.height=t.width/(e.options.aspectRatio||2);else{var s=d(t,"height");void 0!==o&&(t.height=s)}}(t,e),i):null},releaseContext:function(t){var e=t.canvas;if(e[a]){var i=e[a].initial;["height","width"].forEach(function(t){var a=i[t];n.isNullOrUndef(a)?e.removeAttribute(t):e.setAttribute(t,a)}),n.each(i.style||{},function(t,i){e.style[i]=t}),e.width=e.width,delete e[a]}},addEventListener:function(t,e,i){var r=t.canvas;if("resize"!==e){var o=i[a]||(i[a]={});c(r,e,(o.proxies||(o.proxies={}))[t.id+"_"+e]=function(e){var a,r,o,s;i((r=t,o=u[(a=e).type]||a.type,s=n.getRelativePosition(a,r),g(o,r,s.x,s.y,a)))})}else m(r,i,t)},removeEventListener:function(t,e,i){var n=t.canvas;if("resize"!==e){var r=((i[a]||{}).proxies||{})[t.id+"_"+e];r&&f(n,e,r)}else p(n)}},n.addEvent=c,n.removeEvent=f},{45:45}],48:[function(t,e,i){"use strict";var n=t(45),a=t(46),r=t(47),o=r._enabled?r:a;e.exports=n.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},o)},{45:45,46:46,47:47}],49:[function(t,e,i){"use strict";e.exports={},e.exports.filler=t(50),e.exports.legend=t(51),e.exports.title=t(52)},{50:50,51:51,52:52}],50:[function(t,e,i){"use strict";var n=t(25),a=t(40),r=t(45);n._set("global",{plugins:{filler:{propagate:!0}}});var o={dataset:function(t){var e=t.fill,i=t.chart,n=i.getDatasetMeta(e),a=n&&i.isDatasetVisible(e)&&n.dataset._children||[],r=a.length||0;return r?function(t,e){return e=i)&&n;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function l(t){var e,i=t.el._model||{},n=t.el._scale||{},a=t.fill,r=null;if(isFinite(a))return null;if("start"===a?r=void 0===i.scaleBottom?n.bottom:i.scaleBottom:"end"===a?r=void 0===i.scaleTop?n.top:i.scaleTop:void 0!==i.scaleZero?r=i.scaleZero:n.getBasePosition?r=n.getBasePosition():n.getBasePixel&&(r=n.getBasePixel()),null!=r){if(void 0!==r.x&&void 0!==r.y)return r;if("number"==typeof r&&isFinite(r))return{x:(e=n.isHorizontal())?r:null,y:e?null:r}}return null}function u(t,e,i){var n,a=t[e].fill,r=[e];if(!i)return a;for(;!1!==a&&-1===r.indexOf(a);){if(!isFinite(a))return a;if(!(n=t[a]))return!1;if(n.visible)return a;r.push(a),a=n.fill}return!1}function d(t){return t&&!t.skip}function h(t,e,i,n,a){var o;if(n&&a){for(t.moveTo(e[0].x,e[0].y),o=1;o0;--o)r.canvas.lineTo(t,i[o],i[o-1],!0)}}e.exports={id:"filler",afterDatasetsUpdate:function(t,e){var i,n,r,d,h,c,f,g=(t.data.datasets||[]).length,m=e.propagate,p=[];for(n=0;n');for(var i=0;i '),t.data.datasets[i].label&&e.push(t.data.datasets[i].label),e.push("");return e.push(" "),e.join("")}});var u=a.extend({initialize:function(t){r.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:s,update:function(t,e,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n.margins=i,n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeBuildLabels(),n.buildLabels(),n.afterBuildLabels(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:s,beforeSetDimensions:s,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:s,beforeBuildLabels:s,buildLabels:function(){var t=this,e=t.options.labels||{},i=r.callback(e.generateLabels,[t.chart],t)||[];e.filter&&(i=i.filter(function(i){return e.filter(i,t.chart.data)})),t.options.reverse&&i.reverse(),t.legendItems=i},afterBuildLabels:s,beforeFit:s,fit:function(){var t=this,e=t.options,i=e.labels,a=e.display,o=t.ctx,s=n.global,u=r.valueOrDefault,d=u(i.fontSize,s.defaultFontSize),h=u(i.fontStyle,s.defaultFontStyle),c=u(i.fontFamily,s.defaultFontFamily),f=r.fontString(d,h,c),g=t.legendHitBoxes=[],m=t.minSize,p=t.isHorizontal();if(p?(m.width=t.maxWidth,m.height=a?10:0):(m.width=a?10:0,m.height=t.maxHeight),a)if(o.font=f,p){var v=t.lineWidths=[0],y=t.legendItems.length?d+i.padding:0;o.textAlign="left",o.textBaseline="top",r.each(t.legendItems,function(e,n){var a=l(i,d)+d/2+o.measureText(e.text).width;v[v.length-1]+a+i.padding>=t.width&&(y+=d+i.padding,v[v.length]=t.left),g[n]={left:0,top:0,width:a,height:d},v[v.length-1]+=a+i.padding}),m.height+=y}else{var b=i.padding,x=t.columnWidths=[],_=i.padding,k=0,w=0,M=d+b;r.each(t.legendItems,function(t,e){var n=l(i,d)+d/2+o.measureText(t.text).width;w+M>m.height&&(_+=k+i.padding,x.push(k),k=0,w=0),k=Math.max(k,n),w+=M,g[e]={left:0,top:0,width:n,height:d}}),_+=k,x.push(k),m.width+=_}t.width=m.width,t.height=m.height},afterFit:s,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,i=e.labels,a=n.global,o=a.elements.line,s=t.width,u=t.lineWidths;if(e.display){var d,h=t.ctx,c=r.valueOrDefault,f=c(i.fontColor,a.defaultFontColor),g=c(i.fontSize,a.defaultFontSize),m=c(i.fontStyle,a.defaultFontStyle),p=c(i.fontFamily,a.defaultFontFamily),v=r.fontString(g,m,p);h.textAlign="left",h.textBaseline="middle",h.lineWidth=.5,h.strokeStyle=f,h.fillStyle=f,h.font=v;var y=l(i,g),b=t.legendHitBoxes,x=t.isHorizontal();d=x?{x:t.left+(s-u[0])/2,y:t.top+i.padding,line:0}:{x:t.left+i.padding,y:t.top+i.padding,line:0};var _=g+i.padding;r.each(t.legendItems,function(n,l){var f,m,p,v,k,w=h.measureText(n.text).width,M=y+g/2+w,S=d.x,D=d.y;x?S+M>=s&&(D=d.y+=_,d.line++,S=d.x=t.left+(s-u[d.line])/2):D+_>t.bottom&&(S=d.x=S+t.columnWidths[d.line]+i.padding,D=d.y=t.top+i.padding,d.line++),function(t,i,n){if(!(isNaN(y)||y<=0)){h.save(),h.fillStyle=c(n.fillStyle,a.defaultColor),h.lineCap=c(n.lineCap,o.borderCapStyle),h.lineDashOffset=c(n.lineDashOffset,o.borderDashOffset),h.lineJoin=c(n.lineJoin,o.borderJoinStyle),h.lineWidth=c(n.lineWidth,o.borderWidth),h.strokeStyle=c(n.strokeStyle,a.defaultColor);var s=0===c(n.lineWidth,o.borderWidth);if(h.setLineDash&&h.setLineDash(c(n.lineDash,o.borderDash)),e.labels&&e.labels.usePointStyle){var l=g*Math.SQRT2/2,u=l/Math.SQRT2,d=t+u,f=i+u;r.canvas.drawPoint(h,n.pointStyle,l,d,f)}else s||h.strokeRect(t,i,y,g),h.fillRect(t,i,y,g);h.restore()}}(S,D,n),b[l].left=S,b[l].top=D,f=n,m=w,v=y+(p=g/2)+S,k=D+p,h.fillText(f.text,v,k),f.hidden&&(h.beginPath(),h.lineWidth=2,h.moveTo(v,k),h.lineTo(v+m,k),h.stroke()),x?d.x+=M+i.padding:d.y+=_})}},handleEvent:function(t){var e=this,i=e.options,n="mouseup"===t.type?"click":t.type,a=!1;if("mousemove"===n){if(!i.onHover)return}else{if("click"!==n)return;if(!i.onClick)return}var r=t.x,o=t.y;if(r>=e.left&&r<=e.right&&o>=e.top&&o<=e.bottom)for(var s=e.legendHitBoxes,l=0;l=u.left&&r<=u.left+u.width&&o>=u.top&&o<=u.top+u.height){if("click"===n){i.onClick.call(e,t.native,e.legendItems[l]),a=!0;break}if("mousemove"===n){i.onHover.call(e,t.native,e.legendItems[l]),a=!0;break}}}return a}});function d(t,e){var i=new u({ctx:t.ctx,options:e,chart:t});o.configure(t,i,e),o.addBox(t,i),t.legend=i}e.exports={id:"legend",_element:u,beforeInit:function(t){var e=t.options.legend;e&&d(t,e)},beforeUpdate:function(t){var e=t.options.legend,i=t.legend;e?(r.mergeIf(e,n.global.legend),i?(o.configure(t,i,e),i.options=e):d(t,e)):i&&(o.removeBox(t,i),delete t.legend)},afterEvent:function(t,e){var i=t.legend;i&&i.handleEvent(e)}}},{25:25,26:26,30:30,45:45}],52:[function(t,e,i){"use strict";var n=t(25),a=t(26),r=t(45),o=t(30),s=r.noop;n._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,lineHeight:1.2,padding:10,position:"top",text:"",weight:2e3}});var l=a.extend({initialize:function(t){r.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:s,update:function(t,e,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n.margins=i,n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeBuildLabels(),n.buildLabels(),n.afterBuildLabels(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:s,beforeSetDimensions:s,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:s,beforeBuildLabels:s,buildLabels:s,afterBuildLabels:s,beforeFit:s,fit:function(){var t=r.valueOrDefault,e=this.options,i=e.display,a=t(e.fontSize,n.global.defaultFontSize),o=this.minSize,s=r.isArray(e.text)?e.text.length:1,l=r.options.toLineHeight(e.lineHeight,a),u=i?s*l+2*e.padding:0;this.isHorizontal()?(o.width=this.maxWidth,o.height=u):(o.width=u,o.height=this.maxHeight),this.width=o.width,this.height=o.height},afterFit:s,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this.ctx,e=r.valueOrDefault,i=this.options,a=n.global;if(i.display){var o,s,l,u=e(i.fontSize,a.defaultFontSize),d=e(i.fontStyle,a.defaultFontStyle),h=e(i.fontFamily,a.defaultFontFamily),c=r.fontString(u,d,h),f=r.options.toLineHeight(i.lineHeight,u),g=f/2+i.padding,m=0,p=this.top,v=this.left,y=this.bottom,b=this.right;t.fillStyle=e(i.fontColor,a.defaultFontColor),t.font=c,this.isHorizontal()?(s=v+(b-v)/2,l=p+g,o=b-v):(s="left"===i.position?v+g:b-g,l=p+(y-p)/2,o=y-p,m=Math.PI*("left"===i.position?-.5:.5)),t.save(),t.translate(s,l),t.rotate(m),t.textAlign="center",t.textBaseline="middle";var x=i.text;if(r.isArray(x))for(var _=0,k=0;kt.max&&(t.max=n))})});t.min=isFinite(t.min)&&!isNaN(t.min)?t.min:0,t.max=isFinite(t.max)&&!isNaN(t.max)?t.max:1,this.handleTickRangeOptions()},getTickLimit:function(){var t,e=this.options.ticks;if(this.isHorizontal())t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.width/50));else{var i=a.valueOrDefault(e.fontSize,n.global.defaultFontSize);t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.height/(2*i)))}return t},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e=this.start,i=+this.getRightValue(t),n=this.end-e;return this.isHorizontal()?this.left+this.width/n*(i-e):this.bottom-this.height/n*(i-e)},getValueForPixel:function(t){var e=this.isHorizontal(),i=e?this.width:this.height,n=(e?t-this.left:this.bottom-t)/i;return this.start+(this.end-this.start)*n},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",i,e)}},{25:25,34:34,45:45}],55:[function(t,e,i){"use strict";var n=t(45);e.exports=function(t){var e=n.noop;t.LinearScaleBase=t.Scale.extend({getRightValue:function(e){return"string"==typeof e?+e:t.Scale.prototype.getRightValue.call(this,e)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var i=n.sign(t.min),a=n.sign(t.max);i<0&&a<0?t.max=0:i>0&&a>0&&(t.min=0)}var r=void 0!==e.min||void 0!==e.suggestedMin,o=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),r!==o&&t.min>=t.max&&(r?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:e,handleDirectionalChanges:e,buildTicks:function(){var t=this,e=t.options.ticks,i=t.getTickLimit(),a={maxTicks:i=Math.max(2,i),min:e.min,max:e.max,stepSize:n.valueOrDefault(e.fixedStepSize,e.stepSize)},r=t.ticks=function(t,e){var i,a=[];if(t.stepSize&&t.stepSize>0)i=t.stepSize;else{var r=n.niceNum(e.max-e.min,!1);i=n.niceNum(r/(t.maxTicks-1),!0)}var o=Math.floor(e.min/i)*i,s=Math.ceil(e.max/i)*i;t.min&&t.max&&t.stepSize&&n.almostWhole((t.max-t.min)/t.stepSize,i/1e3)&&(o=t.min,s=t.max);var l=(s-o)/i;l=n.almostEquals(l,Math.round(l),i/1e3)?Math.round(l):Math.ceil(l);var u=1;i<1&&(u=Math.pow(10,i.toString().length-2),o=Math.round(o*u)/u,s=Math.round(s*u)/u),a.push(void 0!==t.min?t.min:o);for(var d=1;d0){var i=n.min(e),a=n.max(e);t.min=null===t.min?i:Math.min(t.min,i),t.max=null===t.max?a:Math.max(t.max,a)}})}else n.each(a,function(e,a){var r=i.getDatasetMeta(a);i.isDatasetVisible(a)&&o(r)&&n.each(e.data,function(e,i){var n=+t.getRightValue(e);isNaN(n)||r.data[i].hidden||n<0||(null===t.min?t.min=n:nt.max&&(t.max=n),0!==n&&(null===t.minNotZero||n0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(n.log10(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,i=!t.isHorizontal(),a={min:e.min,max:e.max},r=t.ticks=function(t,e){var i,a,r=[],o=n.valueOrDefault,s=o(t.min,Math.pow(10,Math.floor(n.log10(e.min)))),l=Math.floor(n.log10(e.max)),u=Math.ceil(e.max/Math.pow(10,l));0===s?(i=Math.floor(n.log10(e.minNotZero)),a=Math.floor(e.minNotZero/Math.pow(10,i)),r.push(s),s=a*Math.pow(10,i)):(i=Math.floor(n.log10(s)),a=Math.floor(s/Math.pow(10,i)));for(var d=i<0?Math.pow(10,Math.abs(i)):1;r.push(s),10==++a&&(a=1,d=++i>=0?1:d),s=Math.round(a*Math.pow(10,i)*d)/d,ia?{start:e-i-5,end:e}:{start:e,end:e+i+5}}function u(t,e,i,n){if(a.isArray(e))for(var r=i.y,o=1.5*n,s=0;sd.r&&(d.r=y.end,h.r=p),b.startd.b&&(d.b=b.end,h.b=p)}t.setReductions(u,d,h)}(this):(t=this,e=Math.min(t.height/2,t.width/2),t.drawingArea=Math.round(e),t.setCenterPoint(0,0,0,0))},setReductions:function(t,e,i){var n=e.l/Math.sin(i.l),a=Math.max(e.r-this.width,0)/Math.sin(i.r),r=-e.t/Math.cos(i.t),o=-Math.max(e.b-this.height,0)/Math.cos(i.b);n=d(n),a=d(a),r=d(r),o=d(o),this.drawingArea=Math.min(Math.round(t-(n+a)/2),Math.round(t-(r+o)/2)),this.setCenterPoint(n,a,r,o)},setCenterPoint:function(t,e,i,n){var a=this,r=a.width-e-a.drawingArea,o=t+a.drawingArea,s=i+a.drawingArea,l=a.height-n-a.drawingArea;a.xCenter=Math.round((o+r)/2+a.left),a.yCenter=Math.round((s+l)/2+a.top)},getIndexAngle:function(t){return t*(2*Math.PI/o(this))+(this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){if(null===t)return 0;var e=this.drawingArea/(this.max-this.min);return this.options.ticks.reverse?(this.max-t)*e:(t-this.min)*e},getPointPosition:function(t,e){var i=this.getIndexAngle(t)-Math.PI/2;return{x:Math.round(Math.cos(i)*e)+this.xCenter,y:Math.round(Math.sin(i)*e)+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this.min,e=this.max;return this.getPointPositionForValue(0,this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0)},draw:function(){var t=this,i=t.options,n=i.gridLines,r=i.ticks,l=a.valueOrDefault;if(i.display){var d=t.ctx,h=this.getIndexAngle(0),c=l(r.fontSize,e.defaultFontSize),f=l(r.fontStyle,e.defaultFontStyle),g=l(r.fontFamily,e.defaultFontFamily),m=a.fontString(c,f,g);a.each(t.ticks,function(i,s){if(s>0||r.reverse){var u=t.getDistanceFromCenterForValue(t.ticksAsNumbers[s]);if(n.display&&0!==s&&function(t,e,i,n){var r=t.ctx;if(r.strokeStyle=a.valueAtIndexOrDefault(e.color,n-1),r.lineWidth=a.valueAtIndexOrDefault(e.lineWidth,n-1),t.options.gridLines.circular)r.beginPath(),r.arc(t.xCenter,t.yCenter,i,0,2*Math.PI),r.closePath(),r.stroke();else{var s=o(t);if(0===s)return;r.beginPath();var l=t.getPointPosition(0,i);r.moveTo(l.x,l.y);for(var u=1;u=0;p--){if(r.display){var v=t.getPointPosition(p,g);i.beginPath(),i.moveTo(t.xCenter,t.yCenter),i.lineTo(v.x,v.y),i.stroke(),i.closePath()}if(l.display){var y=t.getPointPosition(p,g+5),b=a.valueAtIndexOrDefault(l.fontColor,p,e.defaultFontColor);i.font=m.font,i.fillStyle=b;var x=t.getIndexAngle(p),_=a.toDegrees(x);i.textAlign=0===(f=_)||180===f?"center":f<180?"left":"right",d=_,h=t._pointLabelSizes[p],c=y,90===d||270===d?c.y-=h.h/2:(d>270||d<90)&&(c.y-=h.h),u(i,t.pointLabels[p]||"",y,m.size)}}}(t)}}});t.scaleService.registerScaleType("radialLinear",h,i)}},{25:25,34:34,45:45}],58:[function(t,e,i){"use strict";var n=t(6);n="function"==typeof n?n:window.moment;var a=t(25),r=t(45),o=Number.MIN_SAFE_INTEGER||-9007199254740991,s=Number.MAX_SAFE_INTEGER||9007199254740991,l={millisecond:{common:!0,size:1,steps:[1,2,5,10,20,50,100,250,500]},second:{common:!0,size:1e3,steps:[1,2,5,10,30]},minute:{common:!0,size:6e4,steps:[1,2,5,10,30]},hour:{common:!0,size:36e5,steps:[1,2,3,6,12]},day:{common:!0,size:864e5,steps:[1,2,5]},week:{common:!1,size:6048e5,steps:[1,2,3,4]},month:{common:!0,size:2628e6,steps:[1,2,3]},quarter:{common:!1,size:7884e6,steps:[1,2,3,4]},year:{common:!0,size:3154e7}},u=Object.keys(l);function d(t,e){return t-e}function h(t){var e,i,n,a={},r=[];for(e=0,i=t.length;e=0&&o<=s;){if(a=t[(n=o+s>>1)-1]||null,r=t[n],!a)return{lo:null,hi:r};if(r[e]i))return{lo:a,hi:r};s=n-1}}return{lo:r,hi:null}}(t,e,i),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],o=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=o[e]-r[e],l=s?(i-r[e])/s:0,u=(o[n]-r[n])*l;return r[n]+u}function f(t,e){var i=e.parser,a=e.parser||e.format;return"function"==typeof i?i(t):"string"==typeof t&&"string"==typeof a?n(t,a):(t instanceof n||(t=n(t)),t.isValid()?t:"function"==typeof a?a(t):t)}function g(t,e){if(r.isNullOrUndef(t))return null;var i=e.options.time,n=f(e.getRightValue(t),i);return n.isValid()?(i.round&&n.startOf(i.round),n.valueOf()):null}function m(t){for(var e=u.indexOf(t)+1,i=u.length;e=_&&i<=k&&D.push(i);return x.min=_,x.max=k,x._unit=M.unit||function(t,e,i,a){var r,o,s=n.duration(n(a).diff(n(i)));for(r=u.length-1;r>=u.indexOf(e);r--)if(o=u[r],l[o].common&&s.as(o)>=t.length)return o;return u[e?u.indexOf(e):0]}(D,M.minUnit,x.min,x.max),x._majorUnit=m(x._unit),x._table=function(t,e,i,n){if("linear"===n||!t.length)return[{time:e,pos:0},{time:i,pos:1}];var a,r,o,s,l,u=[],d=[e];for(a=0,r=t.length;ae&&s1?r[1]:s,v=r[0],y=(c(a,"time",h,"pos")-c(a,"time",v,"pos"))/2),d.time.max||(h=r[r.length-1],v=r.length>1?r[r.length-2]:o,b=(c(a,"time",h,"pos")-c(a,"time",v,"pos"))/2)),{left:y,right:b}),x._labelFormat=function(t,e){var i,n,a,r=t.length;for(i=0;i=0&&t0?o:1}});t.scaleService.registerScaleType("time",e,{position:"bottom",distribution:"linear",bounds:"data",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}})}},{25:25,45:45,6:6}]},{},[7])(7)});
\ No newline at end of file
diff --git a/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/chart/Chart.js b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/chart/Chart.js
new file mode 100644
index 0000000..ca566ba
--- /dev/null
+++ b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/chart/Chart.js
@@ -0,0 +1,14384 @@
+/*!
+ * Chart.js
+ * http://chartjs.org/
+ * Version: 2.7.2
+ *
+ * Copyright 2018 Chart.js Contributors
+ * Released under the MIT license
+ * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
+ */
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chart = f()}})(function(){var define,module,exports;return (function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o lum2) {
+ return (lum1 + 0.05) / (lum2 + 0.05);
+ }
+ return (lum2 + 0.05) / (lum1 + 0.05);
+ },
+
+ level: function (color2) {
+ var contrastRatio = this.contrast(color2);
+ if (contrastRatio >= 7.1) {
+ return 'AAA';
+ }
+
+ return (contrastRatio >= 4.5) ? 'AA' : '';
+ },
+
+ dark: function () {
+ // YIQ equation from http://24ways.org/2010/calculating-color-contrast
+ var rgb = this.values.rgb;
+ var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;
+ return yiq < 128;
+ },
+
+ light: function () {
+ return !this.dark();
+ },
+
+ negate: function () {
+ var rgb = [];
+ for (var i = 0; i < 3; i++) {
+ rgb[i] = 255 - this.values.rgb[i];
+ }
+ this.setValues('rgb', rgb);
+ return this;
+ },
+
+ lighten: function (ratio) {
+ var hsl = this.values.hsl;
+ hsl[2] += hsl[2] * ratio;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ darken: function (ratio) {
+ var hsl = this.values.hsl;
+ hsl[2] -= hsl[2] * ratio;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ saturate: function (ratio) {
+ var hsl = this.values.hsl;
+ hsl[1] += hsl[1] * ratio;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ desaturate: function (ratio) {
+ var hsl = this.values.hsl;
+ hsl[1] -= hsl[1] * ratio;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ whiten: function (ratio) {
+ var hwb = this.values.hwb;
+ hwb[1] += hwb[1] * ratio;
+ this.setValues('hwb', hwb);
+ return this;
+ },
+
+ blacken: function (ratio) {
+ var hwb = this.values.hwb;
+ hwb[2] += hwb[2] * ratio;
+ this.setValues('hwb', hwb);
+ return this;
+ },
+
+ greyscale: function () {
+ var rgb = this.values.rgb;
+ // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
+ var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;
+ this.setValues('rgb', [val, val, val]);
+ return this;
+ },
+
+ clearer: function (ratio) {
+ var alpha = this.values.alpha;
+ this.setValues('alpha', alpha - (alpha * ratio));
+ return this;
+ },
+
+ opaquer: function (ratio) {
+ var alpha = this.values.alpha;
+ this.setValues('alpha', alpha + (alpha * ratio));
+ return this;
+ },
+
+ rotate: function (degrees) {
+ var hsl = this.values.hsl;
+ var hue = (hsl[0] + degrees) % 360;
+ hsl[0] = hue < 0 ? 360 + hue : hue;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ /**
+ * Ported from sass implementation in C
+ * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209
+ */
+ mix: function (mixinColor, weight) {
+ var color1 = this;
+ var color2 = mixinColor;
+ var p = weight === undefined ? 0.5 : weight;
+
+ var w = 2 * p - 1;
+ var a = color1.alpha() - color2.alpha();
+
+ var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ return this
+ .rgb(
+ w1 * color1.red() + w2 * color2.red(),
+ w1 * color1.green() + w2 * color2.green(),
+ w1 * color1.blue() + w2 * color2.blue()
+ )
+ .alpha(color1.alpha() * p + color2.alpha() * (1 - p));
+ },
+
+ toJSON: function () {
+ return this.rgb();
+ },
+
+ clone: function () {
+ // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,
+ // making the final build way to big to embed in Chart.js. So let's do it manually,
+ // assuming that values to clone are 1 dimension arrays containing only numbers,
+ // except 'alpha' which is a number.
+ var result = new Color();
+ var source = this.values;
+ var target = result.values;
+ var value, type;
+
+ for (var prop in source) {
+ if (source.hasOwnProperty(prop)) {
+ value = source[prop];
+ type = ({}).toString.call(value);
+ if (type === '[object Array]') {
+ target[prop] = value.slice(0);
+ } else if (type === '[object Number]') {
+ target[prop] = value;
+ } else {
+ console.error('unexpected color value:', value);
+ }
+ }
+ }
+
+ return result;
+ }
+};
+
+Color.prototype.spaces = {
+ rgb: ['red', 'green', 'blue'],
+ hsl: ['hue', 'saturation', 'lightness'],
+ hsv: ['hue', 'saturation', 'value'],
+ hwb: ['hue', 'whiteness', 'blackness'],
+ cmyk: ['cyan', 'magenta', 'yellow', 'black']
+};
+
+Color.prototype.maxes = {
+ rgb: [255, 255, 255],
+ hsl: [360, 100, 100],
+ hsv: [360, 100, 100],
+ hwb: [360, 100, 100],
+ cmyk: [100, 100, 100, 100]
+};
+
+Color.prototype.getValues = function (space) {
+ var values = this.values;
+ var vals = {};
+
+ for (var i = 0; i < space.length; i++) {
+ vals[space.charAt(i)] = values[space][i];
+ }
+
+ if (values.alpha !== 1) {
+ vals.a = values.alpha;
+ }
+
+ // {r: 255, g: 255, b: 255, a: 0.4}
+ return vals;
+};
+
+Color.prototype.setValues = function (space, vals) {
+ var values = this.values;
+ var spaces = this.spaces;
+ var maxes = this.maxes;
+ var alpha = 1;
+ var i;
+
+ this.valid = true;
+
+ if (space === 'alpha') {
+ alpha = vals;
+ } else if (vals.length) {
+ // [10, 10, 10]
+ values[space] = vals.slice(0, space.length);
+ alpha = vals[space.length];
+ } else if (vals[space.charAt(0)] !== undefined) {
+ // {r: 10, g: 10, b: 10}
+ for (i = 0; i < space.length; i++) {
+ values[space][i] = vals[space.charAt(i)];
+ }
+
+ alpha = vals.a;
+ } else if (vals[spaces[space][0]] !== undefined) {
+ // {red: 10, green: 10, blue: 10}
+ var chans = spaces[space];
+
+ for (i = 0; i < space.length; i++) {
+ values[space][i] = vals[chans[i]];
+ }
+
+ alpha = vals.alpha;
+ }
+
+ values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));
+
+ if (space === 'alpha') {
+ return false;
+ }
+
+ var capped;
+
+ // cap values of the space prior converting all values
+ for (i = 0; i < space.length; i++) {
+ capped = Math.max(0, Math.min(maxes[space][i], values[space][i]));
+ values[space][i] = Math.round(capped);
+ }
+
+ // convert to all the other color spaces
+ for (var sname in spaces) {
+ if (sname !== space) {
+ values[sname] = convert[space][sname](values[space]);
+ }
+ }
+
+ return true;
+};
+
+Color.prototype.setSpace = function (space, args) {
+ var vals = args[0];
+
+ if (vals === undefined) {
+ // color.rgb()
+ return this.getValues(space);
+ }
+
+ // color.rgb(10, 10, 10)
+ if (typeof vals === 'number') {
+ vals = Array.prototype.slice.call(args);
+ }
+
+ this.setValues(space, vals);
+ return this;
+};
+
+Color.prototype.setChannel = function (space, index, val) {
+ var svalues = this.values[space];
+ if (val === undefined) {
+ // color.red()
+ return svalues[index];
+ } else if (val === svalues[index]) {
+ // color.red(color.red())
+ return this;
+ }
+
+ // color.red(100)
+ svalues[index] = val;
+ this.setValues(space, svalues);
+
+ return this;
+};
+
+if (typeof window !== 'undefined') {
+ window.Color = Color;
+}
+
+module.exports = Color;
+
+},{"2":2,"5":5}],4:[function(require,module,exports){
+/* MIT license */
+
+module.exports = {
+ rgb2hsl: rgb2hsl,
+ rgb2hsv: rgb2hsv,
+ rgb2hwb: rgb2hwb,
+ rgb2cmyk: rgb2cmyk,
+ rgb2keyword: rgb2keyword,
+ rgb2xyz: rgb2xyz,
+ rgb2lab: rgb2lab,
+ rgb2lch: rgb2lch,
+
+ hsl2rgb: hsl2rgb,
+ hsl2hsv: hsl2hsv,
+ hsl2hwb: hsl2hwb,
+ hsl2cmyk: hsl2cmyk,
+ hsl2keyword: hsl2keyword,
+
+ hsv2rgb: hsv2rgb,
+ hsv2hsl: hsv2hsl,
+ hsv2hwb: hsv2hwb,
+ hsv2cmyk: hsv2cmyk,
+ hsv2keyword: hsv2keyword,
+
+ hwb2rgb: hwb2rgb,
+ hwb2hsl: hwb2hsl,
+ hwb2hsv: hwb2hsv,
+ hwb2cmyk: hwb2cmyk,
+ hwb2keyword: hwb2keyword,
+
+ cmyk2rgb: cmyk2rgb,
+ cmyk2hsl: cmyk2hsl,
+ cmyk2hsv: cmyk2hsv,
+ cmyk2hwb: cmyk2hwb,
+ cmyk2keyword: cmyk2keyword,
+
+ keyword2rgb: keyword2rgb,
+ keyword2hsl: keyword2hsl,
+ keyword2hsv: keyword2hsv,
+ keyword2hwb: keyword2hwb,
+ keyword2cmyk: keyword2cmyk,
+ keyword2lab: keyword2lab,
+ keyword2xyz: keyword2xyz,
+
+ xyz2rgb: xyz2rgb,
+ xyz2lab: xyz2lab,
+ xyz2lch: xyz2lch,
+
+ lab2xyz: lab2xyz,
+ lab2rgb: lab2rgb,
+ lab2lch: lab2lch,
+
+ lch2lab: lch2lab,
+ lch2xyz: lch2xyz,
+ lch2rgb: lch2rgb
+}
+
+
+function rgb2hsl(rgb) {
+ var r = rgb[0]/255,
+ g = rgb[1]/255,
+ b = rgb[2]/255,
+ min = Math.min(r, g, b),
+ max = Math.max(r, g, b),
+ delta = max - min,
+ h, s, l;
+
+ if (max == min)
+ h = 0;
+ else if (r == max)
+ h = (g - b) / delta;
+ else if (g == max)
+ h = 2 + (b - r) / delta;
+ else if (b == max)
+ h = 4 + (r - g)/ delta;
+
+ h = Math.min(h * 60, 360);
+
+ if (h < 0)
+ h += 360;
+
+ l = (min + max) / 2;
+
+ if (max == min)
+ s = 0;
+ else if (l <= 0.5)
+ s = delta / (max + min);
+ else
+ s = delta / (2 - max - min);
+
+ return [h, s * 100, l * 100];
+}
+
+function rgb2hsv(rgb) {
+ var r = rgb[0],
+ g = rgb[1],
+ b = rgb[2],
+ min = Math.min(r, g, b),
+ max = Math.max(r, g, b),
+ delta = max - min,
+ h, s, v;
+
+ if (max == 0)
+ s = 0;
+ else
+ s = (delta/max * 1000)/10;
+
+ if (max == min)
+ h = 0;
+ else if (r == max)
+ h = (g - b) / delta;
+ else if (g == max)
+ h = 2 + (b - r) / delta;
+ else if (b == max)
+ h = 4 + (r - g) / delta;
+
+ h = Math.min(h * 60, 360);
+
+ if (h < 0)
+ h += 360;
+
+ v = ((max / 255) * 1000) / 10;
+
+ return [h, s, v];
+}
+
+function rgb2hwb(rgb) {
+ var r = rgb[0],
+ g = rgb[1],
+ b = rgb[2],
+ h = rgb2hsl(rgb)[0],
+ w = 1/255 * Math.min(r, Math.min(g, b)),
+ b = 1 - 1/255 * Math.max(r, Math.max(g, b));
+
+ return [h, w * 100, b * 100];
+}
+
+function rgb2cmyk(rgb) {
+ var r = rgb[0] / 255,
+ g = rgb[1] / 255,
+ b = rgb[2] / 255,
+ c, m, y, k;
+
+ k = Math.min(1 - r, 1 - g, 1 - b);
+ c = (1 - r - k) / (1 - k) || 0;
+ m = (1 - g - k) / (1 - k) || 0;
+ y = (1 - b - k) / (1 - k) || 0;
+ return [c * 100, m * 100, y * 100, k * 100];
+}
+
+function rgb2keyword(rgb) {
+ return reverseKeywords[JSON.stringify(rgb)];
+}
+
+function rgb2xyz(rgb) {
+ var r = rgb[0] / 255,
+ g = rgb[1] / 255,
+ b = rgb[2] / 255;
+
+ // assume sRGB
+ r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
+ g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
+ b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
+
+ var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
+ var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
+ var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
+
+ return [x * 100, y *100, z * 100];
+}
+
+function rgb2lab(rgb) {
+ var xyz = rgb2xyz(rgb),
+ x = xyz[0],
+ y = xyz[1],
+ z = xyz[2],
+ l, a, b;
+
+ x /= 95.047;
+ y /= 100;
+ z /= 108.883;
+
+ x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
+ y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
+ z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
+
+ l = (116 * y) - 16;
+ a = 500 * (x - y);
+ b = 200 * (y - z);
+
+ return [l, a, b];
+}
+
+function rgb2lch(args) {
+ return lab2lch(rgb2lab(args));
+}
+
+function hsl2rgb(hsl) {
+ var h = hsl[0] / 360,
+ s = hsl[1] / 100,
+ l = hsl[2] / 100,
+ t1, t2, t3, rgb, val;
+
+ if (s == 0) {
+ val = l * 255;
+ return [val, val, val];
+ }
+
+ if (l < 0.5)
+ t2 = l * (1 + s);
+ else
+ t2 = l + s - l * s;
+ t1 = 2 * l - t2;
+
+ rgb = [0, 0, 0];
+ for (var i = 0; i < 3; i++) {
+ t3 = h + 1 / 3 * - (i - 1);
+ t3 < 0 && t3++;
+ t3 > 1 && t3--;
+
+ if (6 * t3 < 1)
+ val = t1 + (t2 - t1) * 6 * t3;
+ else if (2 * t3 < 1)
+ val = t2;
+ else if (3 * t3 < 2)
+ val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
+ else
+ val = t1;
+
+ rgb[i] = val * 255;
+ }
+
+ return rgb;
+}
+
+function hsl2hsv(hsl) {
+ var h = hsl[0],
+ s = hsl[1] / 100,
+ l = hsl[2] / 100,
+ sv, v;
+
+ if(l === 0) {
+ // no need to do calc on black
+ // also avoids divide by 0 error
+ return [0, 0, 0];
+ }
+
+ l *= 2;
+ s *= (l <= 1) ? l : 2 - l;
+ v = (l + s) / 2;
+ sv = (2 * s) / (l + s);
+ return [h, sv * 100, v * 100];
+}
+
+function hsl2hwb(args) {
+ return rgb2hwb(hsl2rgb(args));
+}
+
+function hsl2cmyk(args) {
+ return rgb2cmyk(hsl2rgb(args));
+}
+
+function hsl2keyword(args) {
+ return rgb2keyword(hsl2rgb(args));
+}
+
+
+function hsv2rgb(hsv) {
+ var h = hsv[0] / 60,
+ s = hsv[1] / 100,
+ v = hsv[2] / 100,
+ hi = Math.floor(h) % 6;
+
+ var f = h - Math.floor(h),
+ p = 255 * v * (1 - s),
+ q = 255 * v * (1 - (s * f)),
+ t = 255 * v * (1 - (s * (1 - f))),
+ v = 255 * v;
+
+ switch(hi) {
+ case 0:
+ return [v, t, p];
+ case 1:
+ return [q, v, p];
+ case 2:
+ return [p, v, t];
+ case 3:
+ return [p, q, v];
+ case 4:
+ return [t, p, v];
+ case 5:
+ return [v, p, q];
+ }
+}
+
+function hsv2hsl(hsv) {
+ var h = hsv[0],
+ s = hsv[1] / 100,
+ v = hsv[2] / 100,
+ sl, l;
+
+ l = (2 - s) * v;
+ sl = s * v;
+ sl /= (l <= 1) ? l : 2 - l;
+ sl = sl || 0;
+ l /= 2;
+ return [h, sl * 100, l * 100];
+}
+
+function hsv2hwb(args) {
+ return rgb2hwb(hsv2rgb(args))
+}
+
+function hsv2cmyk(args) {
+ return rgb2cmyk(hsv2rgb(args));
+}
+
+function hsv2keyword(args) {
+ return rgb2keyword(hsv2rgb(args));
+}
+
+// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
+function hwb2rgb(hwb) {
+ var h = hwb[0] / 360,
+ wh = hwb[1] / 100,
+ bl = hwb[2] / 100,
+ ratio = wh + bl,
+ i, v, f, n;
+
+ // wh + bl cant be > 1
+ if (ratio > 1) {
+ wh /= ratio;
+ bl /= ratio;
+ }
+
+ i = Math.floor(6 * h);
+ v = 1 - bl;
+ f = 6 * h - i;
+ if ((i & 0x01) != 0) {
+ f = 1 - f;
+ }
+ n = wh + f * (v - wh); // linear interpolation
+
+ switch (i) {
+ default:
+ case 6:
+ case 0: r = v; g = n; b = wh; break;
+ case 1: r = n; g = v; b = wh; break;
+ case 2: r = wh; g = v; b = n; break;
+ case 3: r = wh; g = n; b = v; break;
+ case 4: r = n; g = wh; b = v; break;
+ case 5: r = v; g = wh; b = n; break;
+ }
+
+ return [r * 255, g * 255, b * 255];
+}
+
+function hwb2hsl(args) {
+ return rgb2hsl(hwb2rgb(args));
+}
+
+function hwb2hsv(args) {
+ return rgb2hsv(hwb2rgb(args));
+}
+
+function hwb2cmyk(args) {
+ return rgb2cmyk(hwb2rgb(args));
+}
+
+function hwb2keyword(args) {
+ return rgb2keyword(hwb2rgb(args));
+}
+
+function cmyk2rgb(cmyk) {
+ var c = cmyk[0] / 100,
+ m = cmyk[1] / 100,
+ y = cmyk[2] / 100,
+ k = cmyk[3] / 100,
+ r, g, b;
+
+ r = 1 - Math.min(1, c * (1 - k) + k);
+ g = 1 - Math.min(1, m * (1 - k) + k);
+ b = 1 - Math.min(1, y * (1 - k) + k);
+ return [r * 255, g * 255, b * 255];
+}
+
+function cmyk2hsl(args) {
+ return rgb2hsl(cmyk2rgb(args));
+}
+
+function cmyk2hsv(args) {
+ return rgb2hsv(cmyk2rgb(args));
+}
+
+function cmyk2hwb(args) {
+ return rgb2hwb(cmyk2rgb(args));
+}
+
+function cmyk2keyword(args) {
+ return rgb2keyword(cmyk2rgb(args));
+}
+
+
+function xyz2rgb(xyz) {
+ var x = xyz[0] / 100,
+ y = xyz[1] / 100,
+ z = xyz[2] / 100,
+ r, g, b;
+
+ r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
+ g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
+ b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
+
+ // assume sRGB
+ r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
+ : r = (r * 12.92);
+
+ g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
+ : g = (g * 12.92);
+
+ b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
+ : b = (b * 12.92);
+
+ r = Math.min(Math.max(0, r), 1);
+ g = Math.min(Math.max(0, g), 1);
+ b = Math.min(Math.max(0, b), 1);
+
+ return [r * 255, g * 255, b * 255];
+}
+
+function xyz2lab(xyz) {
+ var x = xyz[0],
+ y = xyz[1],
+ z = xyz[2],
+ l, a, b;
+
+ x /= 95.047;
+ y /= 100;
+ z /= 108.883;
+
+ x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
+ y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
+ z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
+
+ l = (116 * y) - 16;
+ a = 500 * (x - y);
+ b = 200 * (y - z);
+
+ return [l, a, b];
+}
+
+function xyz2lch(args) {
+ return lab2lch(xyz2lab(args));
+}
+
+function lab2xyz(lab) {
+ var l = lab[0],
+ a = lab[1],
+ b = lab[2],
+ x, y, z, y2;
+
+ if (l <= 8) {
+ y = (l * 100) / 903.3;
+ y2 = (7.787 * (y / 100)) + (16 / 116);
+ } else {
+ y = 100 * Math.pow((l + 16) / 116, 3);
+ y2 = Math.pow(y / 100, 1/3);
+ }
+
+ x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3);
+
+ z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3);
+
+ return [x, y, z];
+}
+
+function lab2lch(lab) {
+ var l = lab[0],
+ a = lab[1],
+ b = lab[2],
+ hr, h, c;
+
+ hr = Math.atan2(b, a);
+ h = hr * 360 / 2 / Math.PI;
+ if (h < 0) {
+ h += 360;
+ }
+ c = Math.sqrt(a * a + b * b);
+ return [l, c, h];
+}
+
+function lab2rgb(args) {
+ return xyz2rgb(lab2xyz(args));
+}
+
+function lch2lab(lch) {
+ var l = lch[0],
+ c = lch[1],
+ h = lch[2],
+ a, b, hr;
+
+ hr = h / 360 * 2 * Math.PI;
+ a = c * Math.cos(hr);
+ b = c * Math.sin(hr);
+ return [l, a, b];
+}
+
+function lch2xyz(args) {
+ return lab2xyz(lch2lab(args));
+}
+
+function lch2rgb(args) {
+ return lab2rgb(lch2lab(args));
+}
+
+function keyword2rgb(keyword) {
+ return cssKeywords[keyword];
+}
+
+function keyword2hsl(args) {
+ return rgb2hsl(keyword2rgb(args));
+}
+
+function keyword2hsv(args) {
+ return rgb2hsv(keyword2rgb(args));
+}
+
+function keyword2hwb(args) {
+ return rgb2hwb(keyword2rgb(args));
+}
+
+function keyword2cmyk(args) {
+ return rgb2cmyk(keyword2rgb(args));
+}
+
+function keyword2lab(args) {
+ return rgb2lab(keyword2rgb(args));
+}
+
+function keyword2xyz(args) {
+ return rgb2xyz(keyword2rgb(args));
+}
+
+var cssKeywords = {
+ aliceblue: [240,248,255],
+ antiquewhite: [250,235,215],
+ aqua: [0,255,255],
+ aquamarine: [127,255,212],
+ azure: [240,255,255],
+ beige: [245,245,220],
+ bisque: [255,228,196],
+ black: [0,0,0],
+ blanchedalmond: [255,235,205],
+ blue: [0,0,255],
+ blueviolet: [138,43,226],
+ brown: [165,42,42],
+ burlywood: [222,184,135],
+ cadetblue: [95,158,160],
+ chartreuse: [127,255,0],
+ chocolate: [210,105,30],
+ coral: [255,127,80],
+ cornflowerblue: [100,149,237],
+ cornsilk: [255,248,220],
+ crimson: [220,20,60],
+ cyan: [0,255,255],
+ darkblue: [0,0,139],
+ darkcyan: [0,139,139],
+ darkgoldenrod: [184,134,11],
+ darkgray: [169,169,169],
+ darkgreen: [0,100,0],
+ darkgrey: [169,169,169],
+ darkkhaki: [189,183,107],
+ darkmagenta: [139,0,139],
+ darkolivegreen: [85,107,47],
+ darkorange: [255,140,0],
+ darkorchid: [153,50,204],
+ darkred: [139,0,0],
+ darksalmon: [233,150,122],
+ darkseagreen: [143,188,143],
+ darkslateblue: [72,61,139],
+ darkslategray: [47,79,79],
+ darkslategrey: [47,79,79],
+ darkturquoise: [0,206,209],
+ darkviolet: [148,0,211],
+ deeppink: [255,20,147],
+ deepskyblue: [0,191,255],
+ dimgray: [105,105,105],
+ dimgrey: [105,105,105],
+ dodgerblue: [30,144,255],
+ firebrick: [178,34,34],
+ floralwhite: [255,250,240],
+ forestgreen: [34,139,34],
+ fuchsia: [255,0,255],
+ gainsboro: [220,220,220],
+ ghostwhite: [248,248,255],
+ gold: [255,215,0],
+ goldenrod: [218,165,32],
+ gray: [128,128,128],
+ green: [0,128,0],
+ greenyellow: [173,255,47],
+ grey: [128,128,128],
+ honeydew: [240,255,240],
+ hotpink: [255,105,180],
+ indianred: [205,92,92],
+ indigo: [75,0,130],
+ ivory: [255,255,240],
+ khaki: [240,230,140],
+ lavender: [230,230,250],
+ lavenderblush: [255,240,245],
+ lawngreen: [124,252,0],
+ lemonchiffon: [255,250,205],
+ lightblue: [173,216,230],
+ lightcoral: [240,128,128],
+ lightcyan: [224,255,255],
+ lightgoldenrodyellow: [250,250,210],
+ lightgray: [211,211,211],
+ lightgreen: [144,238,144],
+ lightgrey: [211,211,211],
+ lightpink: [255,182,193],
+ lightsalmon: [255,160,122],
+ lightseagreen: [32,178,170],
+ lightskyblue: [135,206,250],
+ lightslategray: [119,136,153],
+ lightslategrey: [119,136,153],
+ lightsteelblue: [176,196,222],
+ lightyellow: [255,255,224],
+ lime: [0,255,0],
+ limegreen: [50,205,50],
+ linen: [250,240,230],
+ magenta: [255,0,255],
+ maroon: [128,0,0],
+ mediumaquamarine: [102,205,170],
+ mediumblue: [0,0,205],
+ mediumorchid: [186,85,211],
+ mediumpurple: [147,112,219],
+ mediumseagreen: [60,179,113],
+ mediumslateblue: [123,104,238],
+ mediumspringgreen: [0,250,154],
+ mediumturquoise: [72,209,204],
+ mediumvioletred: [199,21,133],
+ midnightblue: [25,25,112],
+ mintcream: [245,255,250],
+ mistyrose: [255,228,225],
+ moccasin: [255,228,181],
+ navajowhite: [255,222,173],
+ navy: [0,0,128],
+ oldlace: [253,245,230],
+ olive: [128,128,0],
+ olivedrab: [107,142,35],
+ orange: [255,165,0],
+ orangered: [255,69,0],
+ orchid: [218,112,214],
+ palegoldenrod: [238,232,170],
+ palegreen: [152,251,152],
+ paleturquoise: [175,238,238],
+ palevioletred: [219,112,147],
+ papayawhip: [255,239,213],
+ peachpuff: [255,218,185],
+ peru: [205,133,63],
+ pink: [255,192,203],
+ plum: [221,160,221],
+ powderblue: [176,224,230],
+ purple: [128,0,128],
+ rebeccapurple: [102, 51, 153],
+ red: [255,0,0],
+ rosybrown: [188,143,143],
+ royalblue: [65,105,225],
+ saddlebrown: [139,69,19],
+ salmon: [250,128,114],
+ sandybrown: [244,164,96],
+ seagreen: [46,139,87],
+ seashell: [255,245,238],
+ sienna: [160,82,45],
+ silver: [192,192,192],
+ skyblue: [135,206,235],
+ slateblue: [106,90,205],
+ slategray: [112,128,144],
+ slategrey: [112,128,144],
+ snow: [255,250,250],
+ springgreen: [0,255,127],
+ steelblue: [70,130,180],
+ tan: [210,180,140],
+ teal: [0,128,128],
+ thistle: [216,191,216],
+ tomato: [255,99,71],
+ turquoise: [64,224,208],
+ violet: [238,130,238],
+ wheat: [245,222,179],
+ white: [255,255,255],
+ whitesmoke: [245,245,245],
+ yellow: [255,255,0],
+ yellowgreen: [154,205,50]
+};
+
+var reverseKeywords = {};
+for (var key in cssKeywords) {
+ reverseKeywords[JSON.stringify(cssKeywords[key])] = key;
+}
+
+},{}],5:[function(require,module,exports){
+var conversions = require(4);
+
+var convert = function() {
+ return new Converter();
+}
+
+for (var func in conversions) {
+ // export Raw versions
+ convert[func + "Raw"] = (function(func) {
+ // accept array or plain args
+ return function(arg) {
+ if (typeof arg == "number")
+ arg = Array.prototype.slice.call(arguments);
+ return conversions[func](arg);
+ }
+ })(func);
+
+ var pair = /(\w+)2(\w+)/.exec(func),
+ from = pair[1],
+ to = pair[2];
+
+ // export rgb2hsl and ["rgb"]["hsl"]
+ convert[from] = convert[from] || {};
+
+ convert[from][to] = convert[func] = (function(func) {
+ return function(arg) {
+ if (typeof arg == "number")
+ arg = Array.prototype.slice.call(arguments);
+
+ var val = conversions[func](arg);
+ if (typeof val == "string" || val === undefined)
+ return val; // keyword
+
+ for (var i = 0; i < val.length; i++)
+ val[i] = Math.round(val[i]);
+ return val;
+ }
+ })(func);
+}
+
+
+/* Converter does lazy conversion and caching */
+var Converter = function() {
+ this.convs = {};
+};
+
+/* Either get the values for a space or
+ set the values for a space, depending on args */
+Converter.prototype.routeSpace = function(space, args) {
+ var values = args[0];
+ if (values === undefined) {
+ // color.rgb()
+ return this.getValues(space);
+ }
+ // color.rgb(10, 10, 10)
+ if (typeof values == "number") {
+ values = Array.prototype.slice.call(args);
+ }
+
+ return this.setValues(space, values);
+};
+
+/* Set the values for a space, invalidating cache */
+Converter.prototype.setValues = function(space, values) {
+ this.space = space;
+ this.convs = {};
+ this.convs[space] = values;
+ return this;
+};
+
+/* Get the values for a space. If there's already
+ a conversion for the space, fetch it, otherwise
+ compute it */
+Converter.prototype.getValues = function(space) {
+ var vals = this.convs[space];
+ if (!vals) {
+ var fspace = this.space,
+ from = this.convs[fspace];
+ vals = convert[fspace][space](from);
+
+ this.convs[space] = vals;
+ }
+ return vals;
+};
+
+["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) {
+ Converter.prototype[space] = function(vals) {
+ return this.routeSpace(space, arguments);
+ }
+});
+
+module.exports = convert;
+},{"4":4}],6:[function(require,module,exports){
+'use strict'
+
+module.exports = {
+ "aliceblue": [240, 248, 255],
+ "antiquewhite": [250, 235, 215],
+ "aqua": [0, 255, 255],
+ "aquamarine": [127, 255, 212],
+ "azure": [240, 255, 255],
+ "beige": [245, 245, 220],
+ "bisque": [255, 228, 196],
+ "black": [0, 0, 0],
+ "blanchedalmond": [255, 235, 205],
+ "blue": [0, 0, 255],
+ "blueviolet": [138, 43, 226],
+ "brown": [165, 42, 42],
+ "burlywood": [222, 184, 135],
+ "cadetblue": [95, 158, 160],
+ "chartreuse": [127, 255, 0],
+ "chocolate": [210, 105, 30],
+ "coral": [255, 127, 80],
+ "cornflowerblue": [100, 149, 237],
+ "cornsilk": [255, 248, 220],
+ "crimson": [220, 20, 60],
+ "cyan": [0, 255, 255],
+ "darkblue": [0, 0, 139],
+ "darkcyan": [0, 139, 139],
+ "darkgoldenrod": [184, 134, 11],
+ "darkgray": [169, 169, 169],
+ "darkgreen": [0, 100, 0],
+ "darkgrey": [169, 169, 169],
+ "darkkhaki": [189, 183, 107],
+ "darkmagenta": [139, 0, 139],
+ "darkolivegreen": [85, 107, 47],
+ "darkorange": [255, 140, 0],
+ "darkorchid": [153, 50, 204],
+ "darkred": [139, 0, 0],
+ "darksalmon": [233, 150, 122],
+ "darkseagreen": [143, 188, 143],
+ "darkslateblue": [72, 61, 139],
+ "darkslategray": [47, 79, 79],
+ "darkslategrey": [47, 79, 79],
+ "darkturquoise": [0, 206, 209],
+ "darkviolet": [148, 0, 211],
+ "deeppink": [255, 20, 147],
+ "deepskyblue": [0, 191, 255],
+ "dimgray": [105, 105, 105],
+ "dimgrey": [105, 105, 105],
+ "dodgerblue": [30, 144, 255],
+ "firebrick": [178, 34, 34],
+ "floralwhite": [255, 250, 240],
+ "forestgreen": [34, 139, 34],
+ "fuchsia": [255, 0, 255],
+ "gainsboro": [220, 220, 220],
+ "ghostwhite": [248, 248, 255],
+ "gold": [255, 215, 0],
+ "goldenrod": [218, 165, 32],
+ "gray": [128, 128, 128],
+ "green": [0, 128, 0],
+ "greenyellow": [173, 255, 47],
+ "grey": [128, 128, 128],
+ "honeydew": [240, 255, 240],
+ "hotpink": [255, 105, 180],
+ "indianred": [205, 92, 92],
+ "indigo": [75, 0, 130],
+ "ivory": [255, 255, 240],
+ "khaki": [240, 230, 140],
+ "lavender": [230, 230, 250],
+ "lavenderblush": [255, 240, 245],
+ "lawngreen": [124, 252, 0],
+ "lemonchiffon": [255, 250, 205],
+ "lightblue": [173, 216, 230],
+ "lightcoral": [240, 128, 128],
+ "lightcyan": [224, 255, 255],
+ "lightgoldenrodyellow": [250, 250, 210],
+ "lightgray": [211, 211, 211],
+ "lightgreen": [144, 238, 144],
+ "lightgrey": [211, 211, 211],
+ "lightpink": [255, 182, 193],
+ "lightsalmon": [255, 160, 122],
+ "lightseagreen": [32, 178, 170],
+ "lightskyblue": [135, 206, 250],
+ "lightslategray": [119, 136, 153],
+ "lightslategrey": [119, 136, 153],
+ "lightsteelblue": [176, 196, 222],
+ "lightyellow": [255, 255, 224],
+ "lime": [0, 255, 0],
+ "limegreen": [50, 205, 50],
+ "linen": [250, 240, 230],
+ "magenta": [255, 0, 255],
+ "maroon": [128, 0, 0],
+ "mediumaquamarine": [102, 205, 170],
+ "mediumblue": [0, 0, 205],
+ "mediumorchid": [186, 85, 211],
+ "mediumpurple": [147, 112, 219],
+ "mediumseagreen": [60, 179, 113],
+ "mediumslateblue": [123, 104, 238],
+ "mediumspringgreen": [0, 250, 154],
+ "mediumturquoise": [72, 209, 204],
+ "mediumvioletred": [199, 21, 133],
+ "midnightblue": [25, 25, 112],
+ "mintcream": [245, 255, 250],
+ "mistyrose": [255, 228, 225],
+ "moccasin": [255, 228, 181],
+ "navajowhite": [255, 222, 173],
+ "navy": [0, 0, 128],
+ "oldlace": [253, 245, 230],
+ "olive": [128, 128, 0],
+ "olivedrab": [107, 142, 35],
+ "orange": [255, 165, 0],
+ "orangered": [255, 69, 0],
+ "orchid": [218, 112, 214],
+ "palegoldenrod": [238, 232, 170],
+ "palegreen": [152, 251, 152],
+ "paleturquoise": [175, 238, 238],
+ "palevioletred": [219, 112, 147],
+ "papayawhip": [255, 239, 213],
+ "peachpuff": [255, 218, 185],
+ "peru": [205, 133, 63],
+ "pink": [255, 192, 203],
+ "plum": [221, 160, 221],
+ "powderblue": [176, 224, 230],
+ "purple": [128, 0, 128],
+ "rebeccapurple": [102, 51, 153],
+ "red": [255, 0, 0],
+ "rosybrown": [188, 143, 143],
+ "royalblue": [65, 105, 225],
+ "saddlebrown": [139, 69, 19],
+ "salmon": [250, 128, 114],
+ "sandybrown": [244, 164, 96],
+ "seagreen": [46, 139, 87],
+ "seashell": [255, 245, 238],
+ "sienna": [160, 82, 45],
+ "silver": [192, 192, 192],
+ "skyblue": [135, 206, 235],
+ "slateblue": [106, 90, 205],
+ "slategray": [112, 128, 144],
+ "slategrey": [112, 128, 144],
+ "snow": [255, 250, 250],
+ "springgreen": [0, 255, 127],
+ "steelblue": [70, 130, 180],
+ "tan": [210, 180, 140],
+ "teal": [0, 128, 128],
+ "thistle": [216, 191, 216],
+ "tomato": [255, 99, 71],
+ "turquoise": [64, 224, 208],
+ "violet": [238, 130, 238],
+ "wheat": [245, 222, 179],
+ "white": [255, 255, 255],
+ "whitesmoke": [245, 245, 245],
+ "yellow": [255, 255, 0],
+ "yellowgreen": [154, 205, 50]
+};
+
+},{}],7:[function(require,module,exports){
+/**
+ * @namespace Chart
+ */
+var Chart = require(29)();
+
+Chart.helpers = require(45);
+
+// @todo dispatch these helpers into appropriated helpers/helpers.* file and write unit tests!
+require(27)(Chart);
+
+Chart.defaults = require(25);
+Chart.Element = require(26);
+Chart.elements = require(40);
+Chart.Interaction = require(28);
+Chart.layouts = require(30);
+Chart.platform = require(48);
+Chart.plugins = require(31);
+Chart.Ticks = require(34);
+
+require(22)(Chart);
+require(23)(Chart);
+require(24)(Chart);
+require(33)(Chart);
+require(32)(Chart);
+require(35)(Chart);
+
+require(55)(Chart);
+require(53)(Chart);
+require(54)(Chart);
+require(56)(Chart);
+require(57)(Chart);
+require(58)(Chart);
+
+// Controllers must be loaded after elements
+// See Chart.core.datasetController.dataElementType
+require(15)(Chart);
+require(16)(Chart);
+require(17)(Chart);
+require(18)(Chart);
+require(19)(Chart);
+require(20)(Chart);
+require(21)(Chart);
+
+require(8)(Chart);
+require(9)(Chart);
+require(10)(Chart);
+require(11)(Chart);
+require(12)(Chart);
+require(13)(Chart);
+require(14)(Chart);
+
+// Loading built-it plugins
+var plugins = require(49);
+for (var k in plugins) {
+ if (plugins.hasOwnProperty(k)) {
+ Chart.plugins.register(plugins[k]);
+ }
+}
+
+Chart.platform.initialize();
+
+module.exports = Chart;
+if (typeof window !== 'undefined') {
+ window.Chart = Chart;
+}
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, not available anymore
+ * @namespace Chart.Legend
+ * @deprecated since version 2.1.5
+ * @todo remove at version 3
+ * @private
+ */
+Chart.Legend = plugins.legend._element;
+
+/**
+ * Provided for backward compatibility, not available anymore
+ * @namespace Chart.Title
+ * @deprecated since version 2.1.5
+ * @todo remove at version 3
+ * @private
+ */
+Chart.Title = plugins.title._element;
+
+/**
+ * Provided for backward compatibility, use Chart.plugins instead
+ * @namespace Chart.pluginService
+ * @deprecated since version 2.1.5
+ * @todo remove at version 3
+ * @private
+ */
+Chart.pluginService = Chart.plugins;
+
+/**
+ * Provided for backward compatibility, inheriting from Chart.PlugingBase has no
+ * effect, instead simply create/register plugins via plain JavaScript objects.
+ * @interface Chart.PluginBase
+ * @deprecated since version 2.5.0
+ * @todo remove at version 3
+ * @private
+ */
+Chart.PluginBase = Chart.Element.extend({});
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.canvas instead.
+ * @namespace Chart.canvasHelpers
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ * @private
+ */
+Chart.canvasHelpers = Chart.helpers.canvas;
+
+/**
+ * Provided for backward compatibility, use Chart.layouts instead.
+ * @namespace Chart.layoutService
+ * @deprecated since version 2.8.0
+ * @todo remove at version 3
+ * @private
+ */
+Chart.layoutService = Chart.layouts;
+
+},{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"20":20,"21":21,"22":22,"23":23,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"40":40,"45":45,"48":48,"49":49,"53":53,"54":54,"55":55,"56":56,"57":57,"58":58,"8":8,"9":9}],8:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ Chart.Bar = function(context, config) {
+ config.type = 'bar';
+
+ return new Chart(context, config);
+ };
+
+};
+
+},{}],9:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ Chart.Bubble = function(context, config) {
+ config.type = 'bubble';
+ return new Chart(context, config);
+ };
+
+};
+
+},{}],10:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ Chart.Doughnut = function(context, config) {
+ config.type = 'doughnut';
+
+ return new Chart(context, config);
+ };
+
+};
+
+},{}],11:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ Chart.Line = function(context, config) {
+ config.type = 'line';
+
+ return new Chart(context, config);
+ };
+
+};
+
+},{}],12:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ Chart.PolarArea = function(context, config) {
+ config.type = 'polarArea';
+
+ return new Chart(context, config);
+ };
+
+};
+
+},{}],13:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ Chart.Radar = function(context, config) {
+ config.type = 'radar';
+
+ return new Chart(context, config);
+ };
+
+};
+
+},{}],14:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+ Chart.Scatter = function(context, config) {
+ config.type = 'scatter';
+ return new Chart(context, config);
+ };
+};
+
+},{}],15:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('bar', {
+ hover: {
+ mode: 'label'
+ },
+
+ scales: {
+ xAxes: [{
+ type: 'category',
+
+ // Specific to Bar Controller
+ categoryPercentage: 0.8,
+ barPercentage: 0.9,
+
+ // offset settings
+ offset: true,
+
+ // grid line settings
+ gridLines: {
+ offsetGridLines: true
+ }
+ }],
+
+ yAxes: [{
+ type: 'linear'
+ }]
+ }
+});
+
+defaults._set('horizontalBar', {
+ hover: {
+ mode: 'index',
+ axis: 'y'
+ },
+
+ scales: {
+ xAxes: [{
+ type: 'linear',
+ position: 'bottom'
+ }],
+
+ yAxes: [{
+ position: 'left',
+ type: 'category',
+
+ // Specific to Horizontal Bar Controller
+ categoryPercentage: 0.8,
+ barPercentage: 0.9,
+
+ // offset settings
+ offset: true,
+
+ // grid line settings
+ gridLines: {
+ offsetGridLines: true
+ }
+ }]
+ },
+
+ elements: {
+ rectangle: {
+ borderSkipped: 'left'
+ }
+ },
+
+ tooltips: {
+ callbacks: {
+ title: function(item, data) {
+ // Pick first xLabel for now
+ var title = '';
+
+ if (item.length > 0) {
+ if (item[0].yLabel) {
+ title = item[0].yLabel;
+ } else if (data.labels.length > 0 && item[0].index < data.labels.length) {
+ title = data.labels[item[0].index];
+ }
+ }
+
+ return title;
+ },
+
+ label: function(item, data) {
+ var datasetLabel = data.datasets[item.datasetIndex].label || '';
+ return datasetLabel + ': ' + item.xLabel;
+ }
+ },
+ mode: 'index',
+ axis: 'y'
+ }
+});
+
+/**
+ * Computes the "optimal" sample size to maintain bars equally sized while preventing overlap.
+ * @private
+ */
+function computeMinSampleSize(scale, pixels) {
+ var min = scale.isHorizontal() ? scale.width : scale.height;
+ var ticks = scale.getTicks();
+ var prev, curr, i, ilen;
+
+ for (i = 1, ilen = pixels.length; i < ilen; ++i) {
+ min = Math.min(min, pixels[i] - pixels[i - 1]);
+ }
+
+ for (i = 0, ilen = ticks.length; i < ilen; ++i) {
+ curr = scale.getPixelForTick(i);
+ min = i > 0 ? Math.min(min, curr - prev) : min;
+ prev = curr;
+ }
+
+ return min;
+}
+
+/**
+ * Computes an "ideal" category based on the absolute bar thickness or, if undefined or null,
+ * uses the smallest interval (see computeMinSampleSize) that prevents bar overlapping. This
+ * mode currently always generates bars equally sized (until we introduce scriptable options?).
+ * @private
+ */
+function computeFitCategoryTraits(index, ruler, options) {
+ var thickness = options.barThickness;
+ var count = ruler.stackCount;
+ var curr = ruler.pixels[index];
+ var size, ratio;
+
+ if (helpers.isNullOrUndef(thickness)) {
+ size = ruler.min * options.categoryPercentage;
+ ratio = options.barPercentage;
+ } else {
+ // When bar thickness is enforced, category and bar percentages are ignored.
+ // Note(SB): we could add support for relative bar thickness (e.g. barThickness: '50%')
+ // and deprecate barPercentage since this value is ignored when thickness is absolute.
+ size = thickness * count;
+ ratio = 1;
+ }
+
+ return {
+ chunk: size / count,
+ ratio: ratio,
+ start: curr - (size / 2)
+ };
+}
+
+/**
+ * Computes an "optimal" category that globally arranges bars side by side (no gap when
+ * percentage options are 1), based on the previous and following categories. This mode
+ * generates bars with different widths when data are not evenly spaced.
+ * @private
+ */
+function computeFlexCategoryTraits(index, ruler, options) {
+ var pixels = ruler.pixels;
+ var curr = pixels[index];
+ var prev = index > 0 ? pixels[index - 1] : null;
+ var next = index < pixels.length - 1 ? pixels[index + 1] : null;
+ var percent = options.categoryPercentage;
+ var start, size;
+
+ if (prev === null) {
+ // first data: its size is double based on the next point or,
+ // if it's also the last data, we use the scale end extremity.
+ prev = curr - (next === null ? ruler.end - curr : next - curr);
+ }
+
+ if (next === null) {
+ // last data: its size is also double based on the previous point.
+ next = curr + curr - prev;
+ }
+
+ start = curr - ((curr - prev) / 2) * percent;
+ size = ((next - prev) / 2) * percent;
+
+ return {
+ chunk: size / ruler.stackCount,
+ ratio: options.barPercentage,
+ start: start
+ };
+}
+
+module.exports = function(Chart) {
+
+ Chart.controllers.bar = Chart.DatasetController.extend({
+
+ dataElementType: elements.Rectangle,
+
+ initialize: function() {
+ var me = this;
+ var meta;
+
+ Chart.DatasetController.prototype.initialize.apply(me, arguments);
+
+ meta = me.getMeta();
+ meta.stack = me.getDataset().stack;
+ meta.bar = true;
+ },
+
+ update: function(reset) {
+ var me = this;
+ var rects = me.getMeta().data;
+ var i, ilen;
+
+ me._ruler = me.getRuler();
+
+ for (i = 0, ilen = rects.length; i < ilen; ++i) {
+ me.updateElement(rects[i], i, reset);
+ }
+ },
+
+ updateElement: function(rectangle, index, reset) {
+ var me = this;
+ var chart = me.chart;
+ var meta = me.getMeta();
+ var dataset = me.getDataset();
+ var custom = rectangle.custom || {};
+ var rectangleOptions = chart.options.elements.rectangle;
+
+ rectangle._xScale = me.getScaleForId(meta.xAxisID);
+ rectangle._yScale = me.getScaleForId(meta.yAxisID);
+ rectangle._datasetIndex = me.index;
+ rectangle._index = index;
+
+ rectangle._model = {
+ datasetLabel: dataset.label,
+ label: chart.data.labels[index],
+ borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleOptions.borderSkipped,
+ backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.backgroundColor, index, rectangleOptions.backgroundColor),
+ borderColor: custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.borderColor, index, rectangleOptions.borderColor),
+ borderWidth: custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.borderWidth, index, rectangleOptions.borderWidth)
+ };
+
+ me.updateElementGeometry(rectangle, index, reset);
+
+ rectangle.pivot();
+ },
+
+ /**
+ * @private
+ */
+ updateElementGeometry: function(rectangle, index, reset) {
+ var me = this;
+ var model = rectangle._model;
+ var vscale = me.getValueScale();
+ var base = vscale.getBasePixel();
+ var horizontal = vscale.isHorizontal();
+ var ruler = me._ruler || me.getRuler();
+ var vpixels = me.calculateBarValuePixels(me.index, index);
+ var ipixels = me.calculateBarIndexPixels(me.index, index, ruler);
+
+ model.horizontal = horizontal;
+ model.base = reset ? base : vpixels.base;
+ model.x = horizontal ? reset ? base : vpixels.head : ipixels.center;
+ model.y = horizontal ? ipixels.center : reset ? base : vpixels.head;
+ model.height = horizontal ? ipixels.size : undefined;
+ model.width = horizontal ? undefined : ipixels.size;
+ },
+
+ /**
+ * @private
+ */
+ getValueScaleId: function() {
+ return this.getMeta().yAxisID;
+ },
+
+ /**
+ * @private
+ */
+ getIndexScaleId: function() {
+ return this.getMeta().xAxisID;
+ },
+
+ /**
+ * @private
+ */
+ getValueScale: function() {
+ return this.getScaleForId(this.getValueScaleId());
+ },
+
+ /**
+ * @private
+ */
+ getIndexScale: function() {
+ return this.getScaleForId(this.getIndexScaleId());
+ },
+
+ /**
+ * Returns the stacks based on groups and bar visibility.
+ * @param {Number} [last] - The dataset index
+ * @returns {Array} The stack list
+ * @private
+ */
+ _getStacks: function(last) {
+ var me = this;
+ var chart = me.chart;
+ var scale = me.getIndexScale();
+ var stacked = scale.options.stacked;
+ var ilen = last === undefined ? chart.data.datasets.length : last + 1;
+ var stacks = [];
+ var i, meta;
+
+ for (i = 0; i < ilen; ++i) {
+ meta = chart.getDatasetMeta(i);
+ if (meta.bar && chart.isDatasetVisible(i) &&
+ (stacked === false ||
+ (stacked === true && stacks.indexOf(meta.stack) === -1) ||
+ (stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) {
+ stacks.push(meta.stack);
+ }
+ }
+
+ return stacks;
+ },
+
+ /**
+ * Returns the effective number of stacks based on groups and bar visibility.
+ * @private
+ */
+ getStackCount: function() {
+ return this._getStacks().length;
+ },
+
+ /**
+ * Returns the stack index for the given dataset based on groups and bar visibility.
+ * @param {Number} [datasetIndex] - The dataset index
+ * @param {String} [name] - The stack name to find
+ * @returns {Number} The stack index
+ * @private
+ */
+ getStackIndex: function(datasetIndex, name) {
+ var stacks = this._getStacks(datasetIndex);
+ var index = (name !== undefined)
+ ? stacks.indexOf(name)
+ : -1; // indexOf returns -1 if element is not present
+
+ return (index === -1)
+ ? stacks.length - 1
+ : index;
+ },
+
+ /**
+ * @private
+ */
+ getRuler: function() {
+ var me = this;
+ var scale = me.getIndexScale();
+ var stackCount = me.getStackCount();
+ var datasetIndex = me.index;
+ var isHorizontal = scale.isHorizontal();
+ var start = isHorizontal ? scale.left : scale.top;
+ var end = start + (isHorizontal ? scale.width : scale.height);
+ var pixels = [];
+ var i, ilen, min;
+
+ for (i = 0, ilen = me.getMeta().data.length; i < ilen; ++i) {
+ pixels.push(scale.getPixelForValue(null, i, datasetIndex));
+ }
+
+ min = helpers.isNullOrUndef(scale.options.barThickness)
+ ? computeMinSampleSize(scale, pixels)
+ : -1;
+
+ return {
+ min: min,
+ pixels: pixels,
+ start: start,
+ end: end,
+ stackCount: stackCount,
+ scale: scale
+ };
+ },
+
+ /**
+ * Note: pixel values are not clamped to the scale area.
+ * @private
+ */
+ calculateBarValuePixels: function(datasetIndex, index) {
+ var me = this;
+ var chart = me.chart;
+ var meta = me.getMeta();
+ var scale = me.getValueScale();
+ var datasets = chart.data.datasets;
+ var value = scale.getRightValue(datasets[datasetIndex].data[index]);
+ var stacked = scale.options.stacked;
+ var stack = meta.stack;
+ var start = 0;
+ var i, imeta, ivalue, base, head, size;
+
+ if (stacked || (stacked === undefined && stack !== undefined)) {
+ for (i = 0; i < datasetIndex; ++i) {
+ imeta = chart.getDatasetMeta(i);
+
+ if (imeta.bar &&
+ imeta.stack === stack &&
+ imeta.controller.getValueScaleId() === scale.id &&
+ chart.isDatasetVisible(i)) {
+
+ ivalue = scale.getRightValue(datasets[i].data[index]);
+ if ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) {
+ start += ivalue;
+ }
+ }
+ }
+ }
+
+ base = scale.getPixelForValue(start);
+ head = scale.getPixelForValue(start + value);
+ size = (head - base) / 2;
+
+ return {
+ size: size,
+ base: base,
+ head: head,
+ center: head + size / 2
+ };
+ },
+
+ /**
+ * @private
+ */
+ calculateBarIndexPixels: function(datasetIndex, index, ruler) {
+ var me = this;
+ var options = ruler.scale.options;
+ var range = options.barThickness === 'flex'
+ ? computeFlexCategoryTraits(index, ruler, options)
+ : computeFitCategoryTraits(index, ruler, options);
+
+ var stackIndex = me.getStackIndex(datasetIndex, me.getMeta().stack);
+ var center = range.start + (range.chunk * stackIndex) + (range.chunk / 2);
+ var size = Math.min(
+ helpers.valueOrDefault(options.maxBarThickness, Infinity),
+ range.chunk * range.ratio);
+
+ return {
+ base: center - size / 2,
+ head: center + size / 2,
+ center: center,
+ size: size
+ };
+ },
+
+ draw: function() {
+ var me = this;
+ var chart = me.chart;
+ var scale = me.getValueScale();
+ var rects = me.getMeta().data;
+ var dataset = me.getDataset();
+ var ilen = rects.length;
+ var i = 0;
+
+ helpers.canvas.clipArea(chart.ctx, chart.chartArea);
+
+ for (; i < ilen; ++i) {
+ if (!isNaN(scale.getRightValue(dataset.data[i]))) {
+ rects[i].draw();
+ }
+ }
+
+ helpers.canvas.unclipArea(chart.ctx);
+ },
+
+ setHoverStyle: function(rectangle) {
+ var dataset = this.chart.data.datasets[rectangle._datasetIndex];
+ var index = rectangle._index;
+ var custom = rectangle.custom || {};
+ var model = rectangle._model;
+
+ model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.valueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
+ model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.valueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor));
+ model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.valueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
+ },
+
+ removeHoverStyle: function(rectangle) {
+ var dataset = this.chart.data.datasets[rectangle._datasetIndex];
+ var index = rectangle._index;
+ var custom = rectangle.custom || {};
+ var model = rectangle._model;
+ var rectangleElementOptions = this.chart.options.elements.rectangle;
+
+ model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor);
+ model.borderColor = custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor);
+ model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth);
+ }
+ });
+
+ Chart.controllers.horizontalBar = Chart.controllers.bar.extend({
+ /**
+ * @private
+ */
+ getValueScaleId: function() {
+ return this.getMeta().xAxisID;
+ },
+
+ /**
+ * @private
+ */
+ getIndexScaleId: function() {
+ return this.getMeta().yAxisID;
+ }
+ });
+};
+
+},{"25":25,"40":40,"45":45}],16:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('bubble', {
+ hover: {
+ mode: 'single'
+ },
+
+ scales: {
+ xAxes: [{
+ type: 'linear', // bubble should probably use a linear scale by default
+ position: 'bottom',
+ id: 'x-axis-0' // need an ID so datasets can reference the scale
+ }],
+ yAxes: [{
+ type: 'linear',
+ position: 'left',
+ id: 'y-axis-0'
+ }]
+ },
+
+ tooltips: {
+ callbacks: {
+ title: function() {
+ // Title doesn't make sense for scatter since we format the data as a point
+ return '';
+ },
+ label: function(item, data) {
+ var datasetLabel = data.datasets[item.datasetIndex].label || '';
+ var dataPoint = data.datasets[item.datasetIndex].data[item.index];
+ return datasetLabel + ': (' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.r + ')';
+ }
+ }
+ }
+});
+
+
+module.exports = function(Chart) {
+
+ Chart.controllers.bubble = Chart.DatasetController.extend({
+ /**
+ * @protected
+ */
+ dataElementType: elements.Point,
+
+ /**
+ * @protected
+ */
+ update: function(reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var points = meta.data;
+
+ // Update Points
+ helpers.each(points, function(point, index) {
+ me.updateElement(point, index, reset);
+ });
+ },
+
+ /**
+ * @protected
+ */
+ updateElement: function(point, index, reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var custom = point.custom || {};
+ var xScale = me.getScaleForId(meta.xAxisID);
+ var yScale = me.getScaleForId(meta.yAxisID);
+ var options = me._resolveElementOptions(point, index);
+ var data = me.getDataset().data[index];
+ var dsIndex = me.index;
+
+ var x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex);
+ var y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex);
+
+ point._xScale = xScale;
+ point._yScale = yScale;
+ point._options = options;
+ point._datasetIndex = dsIndex;
+ point._index = index;
+ point._model = {
+ backgroundColor: options.backgroundColor,
+ borderColor: options.borderColor,
+ borderWidth: options.borderWidth,
+ hitRadius: options.hitRadius,
+ pointStyle: options.pointStyle,
+ radius: reset ? 0 : options.radius,
+ skip: custom.skip || isNaN(x) || isNaN(y),
+ x: x,
+ y: y,
+ };
+
+ point.pivot();
+ },
+
+ /**
+ * @protected
+ */
+ setHoverStyle: function(point) {
+ var model = point._model;
+ var options = point._options;
+
+ model.backgroundColor = helpers.valueOrDefault(options.hoverBackgroundColor, helpers.getHoverColor(options.backgroundColor));
+ model.borderColor = helpers.valueOrDefault(options.hoverBorderColor, helpers.getHoverColor(options.borderColor));
+ model.borderWidth = helpers.valueOrDefault(options.hoverBorderWidth, options.borderWidth);
+ model.radius = options.radius + options.hoverRadius;
+ },
+
+ /**
+ * @protected
+ */
+ removeHoverStyle: function(point) {
+ var model = point._model;
+ var options = point._options;
+
+ model.backgroundColor = options.backgroundColor;
+ model.borderColor = options.borderColor;
+ model.borderWidth = options.borderWidth;
+ model.radius = options.radius;
+ },
+
+ /**
+ * @private
+ */
+ _resolveElementOptions: function(point, index) {
+ var me = this;
+ var chart = me.chart;
+ var datasets = chart.data.datasets;
+ var dataset = datasets[me.index];
+ var custom = point.custom || {};
+ var options = chart.options.elements.point;
+ var resolve = helpers.options.resolve;
+ var data = dataset.data[index];
+ var values = {};
+ var i, ilen, key;
+
+ // Scriptable options
+ var context = {
+ chart: chart,
+ dataIndex: index,
+ dataset: dataset,
+ datasetIndex: me.index
+ };
+
+ var keys = [
+ 'backgroundColor',
+ 'borderColor',
+ 'borderWidth',
+ 'hoverBackgroundColor',
+ 'hoverBorderColor',
+ 'hoverBorderWidth',
+ 'hoverRadius',
+ 'hitRadius',
+ 'pointStyle'
+ ];
+
+ for (i = 0, ilen = keys.length; i < ilen; ++i) {
+ key = keys[i];
+ values[key] = resolve([
+ custom[key],
+ dataset[key],
+ options[key]
+ ], context, index);
+ }
+
+ // Custom radius resolution
+ values.radius = resolve([
+ custom.radius,
+ data ? data.r : undefined,
+ dataset.radius,
+ options.radius
+ ], context, index);
+
+ return values;
+ }
+ });
+};
+
+},{"25":25,"40":40,"45":45}],17:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('doughnut', {
+ animation: {
+ // Boolean - Whether we animate the rotation of the Doughnut
+ animateRotate: true,
+ // Boolean - Whether we animate scaling the Doughnut from the centre
+ animateScale: false
+ },
+ hover: {
+ mode: 'single'
+ },
+ legendCallback: function(chart) {
+ var text = [];
+ text.push('');
+
+ var data = chart.data;
+ var datasets = data.datasets;
+ var labels = data.labels;
+
+ if (datasets.length) {
+ for (var i = 0; i < datasets[0].data.length; ++i) {
+ text.push(' ');
+ if (labels[i]) {
+ text.push(labels[i]);
+ }
+ text.push(' ');
+ }
+ }
+
+ text.push(' ');
+ return text.join('');
+ },
+ legend: {
+ labels: {
+ generateLabels: function(chart) {
+ var data = chart.data;
+ if (data.labels.length && data.datasets.length) {
+ return data.labels.map(function(label, i) {
+ var meta = chart.getDatasetMeta(0);
+ var ds = data.datasets[0];
+ var arc = meta.data[i];
+ var custom = arc && arc.custom || {};
+ var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
+ var arcOpts = chart.options.elements.arc;
+ var fill = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
+ var stroke = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
+ var bw = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
+
+ return {
+ text: label,
+ fillStyle: fill,
+ strokeStyle: stroke,
+ lineWidth: bw,
+ hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
+
+ // Extra data used for toggling the correct item
+ index: i
+ };
+ });
+ }
+ return [];
+ }
+ },
+
+ onClick: function(e, legendItem) {
+ var index = legendItem.index;
+ var chart = this.chart;
+ var i, ilen, meta;
+
+ for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
+ meta = chart.getDatasetMeta(i);
+ // toggle visibility of index if exists
+ if (meta.data[index]) {
+ meta.data[index].hidden = !meta.data[index].hidden;
+ }
+ }
+
+ chart.update();
+ }
+ },
+
+ // The percentage of the chart that we cut out of the middle.
+ cutoutPercentage: 50,
+
+ // The rotation of the chart, where the first data arc begins.
+ rotation: Math.PI * -0.5,
+
+ // The total circumference of the chart.
+ circumference: Math.PI * 2.0,
+
+ // Need to override these to give a nice default
+ tooltips: {
+ callbacks: {
+ title: function() {
+ return '';
+ },
+ label: function(tooltipItem, data) {
+ var dataLabel = data.labels[tooltipItem.index];
+ var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
+
+ if (helpers.isArray(dataLabel)) {
+ // show value on first line of multiline label
+ // need to clone because we are changing the value
+ dataLabel = dataLabel.slice();
+ dataLabel[0] += value;
+ } else {
+ dataLabel += value;
+ }
+
+ return dataLabel;
+ }
+ }
+ }
+});
+
+defaults._set('pie', helpers.clone(defaults.doughnut));
+defaults._set('pie', {
+ cutoutPercentage: 0
+});
+
+module.exports = function(Chart) {
+
+ Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({
+
+ dataElementType: elements.Arc,
+
+ linkScales: helpers.noop,
+
+ // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly
+ getRingIndex: function(datasetIndex) {
+ var ringIndex = 0;
+
+ for (var j = 0; j < datasetIndex; ++j) {
+ if (this.chart.isDatasetVisible(j)) {
+ ++ringIndex;
+ }
+ }
+
+ return ringIndex;
+ },
+
+ update: function(reset) {
+ var me = this;
+ var chart = me.chart;
+ var chartArea = chart.chartArea;
+ var opts = chart.options;
+ var arcOpts = opts.elements.arc;
+ var availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth;
+ var availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth;
+ var minSize = Math.min(availableWidth, availableHeight);
+ var offset = {x: 0, y: 0};
+ var meta = me.getMeta();
+ var cutoutPercentage = opts.cutoutPercentage;
+ var circumference = opts.circumference;
+
+ // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc
+ if (circumference < Math.PI * 2.0) {
+ var startAngle = opts.rotation % (Math.PI * 2.0);
+ startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);
+ var endAngle = startAngle + circumference;
+ var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)};
+ var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)};
+ var contains0 = (startAngle <= 0 && endAngle >= 0) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle);
+ var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle);
+ var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle);
+ var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle);
+ var cutout = cutoutPercentage / 100.0;
+ var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))};
+ var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))};
+ var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5};
+ minSize = Math.min(availableWidth / size.width, availableHeight / size.height);
+ offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};
+ }
+
+ chart.borderWidth = me.getMaxBorderWidth(meta.data);
+ chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);
+ chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0);
+ chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
+ chart.offsetX = offset.x * chart.outerRadius;
+ chart.offsetY = offset.y * chart.outerRadius;
+
+ meta.total = me.calculateTotal();
+
+ me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));
+ me.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0);
+
+ helpers.each(meta.data, function(arc, index) {
+ me.updateElement(arc, index, reset);
+ });
+ },
+
+ updateElement: function(arc, index, reset) {
+ var me = this;
+ var chart = me.chart;
+ var chartArea = chart.chartArea;
+ var opts = chart.options;
+ var animationOpts = opts.animation;
+ var centerX = (chartArea.left + chartArea.right) / 2;
+ var centerY = (chartArea.top + chartArea.bottom) / 2;
+ var startAngle = opts.rotation; // non reset case handled later
+ var endAngle = opts.rotation; // non reset case handled later
+ var dataset = me.getDataset();
+ var circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI));
+ var innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius;
+ var outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius;
+ var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
+
+ helpers.extend(arc, {
+ // Utility
+ _datasetIndex: me.index,
+ _index: index,
+
+ // Desired view properties
+ _model: {
+ x: centerX + chart.offsetX,
+ y: centerY + chart.offsetY,
+ startAngle: startAngle,
+ endAngle: endAngle,
+ circumference: circumference,
+ outerRadius: outerRadius,
+ innerRadius: innerRadius,
+ label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])
+ }
+ });
+
+ var model = arc._model;
+ // Resets the visual styles
+ this.removeHoverStyle(arc);
+
+ // Set correct angles if not resetting
+ if (!reset || !animationOpts.animateRotate) {
+ if (index === 0) {
+ model.startAngle = opts.rotation;
+ } else {
+ model.startAngle = me.getMeta().data[index - 1]._model.endAngle;
+ }
+
+ model.endAngle = model.startAngle + model.circumference;
+ }
+
+ arc.pivot();
+ },
+
+ removeHoverStyle: function(arc) {
+ Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);
+ },
+
+ calculateTotal: function() {
+ var dataset = this.getDataset();
+ var meta = this.getMeta();
+ var total = 0;
+ var value;
+
+ helpers.each(meta.data, function(element, index) {
+ value = dataset.data[index];
+ if (!isNaN(value) && !element.hidden) {
+ total += Math.abs(value);
+ }
+ });
+
+ /* if (total === 0) {
+ total = NaN;
+ }*/
+
+ return total;
+ },
+
+ calculateCircumference: function(value) {
+ var total = this.getMeta().total;
+ if (total > 0 && !isNaN(value)) {
+ return (Math.PI * 2.0) * (Math.abs(value) / total);
+ }
+ return 0;
+ },
+
+ // gets the max border or hover width to properly scale pie charts
+ getMaxBorderWidth: function(arcs) {
+ var max = 0;
+ var index = this.index;
+ var length = arcs.length;
+ var borderWidth;
+ var hoverWidth;
+
+ for (var i = 0; i < length; i++) {
+ borderWidth = arcs[i]._model ? arcs[i]._model.borderWidth : 0;
+ hoverWidth = arcs[i]._chart ? arcs[i]._chart.config.data.datasets[index].hoverBorderWidth : 0;
+
+ max = borderWidth > max ? borderWidth : max;
+ max = hoverWidth > max ? hoverWidth : max;
+ }
+ return max;
+ }
+ });
+};
+
+},{"25":25,"40":40,"45":45}],18:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('line', {
+ showLines: true,
+ spanGaps: false,
+
+ hover: {
+ mode: 'label'
+ },
+
+ scales: {
+ xAxes: [{
+ type: 'category',
+ id: 'x-axis-0'
+ }],
+ yAxes: [{
+ type: 'linear',
+ id: 'y-axis-0'
+ }]
+ }
+});
+
+module.exports = function(Chart) {
+
+ function lineEnabled(dataset, options) {
+ return helpers.valueOrDefault(dataset.showLine, options.showLines);
+ }
+
+ Chart.controllers.line = Chart.DatasetController.extend({
+
+ datasetElementType: elements.Line,
+
+ dataElementType: elements.Point,
+
+ update: function(reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var line = meta.dataset;
+ var points = meta.data || [];
+ var options = me.chart.options;
+ var lineElementOptions = options.elements.line;
+ var scale = me.getScaleForId(meta.yAxisID);
+ var i, ilen, custom;
+ var dataset = me.getDataset();
+ var showLine = lineEnabled(dataset, options);
+
+ // Update Line
+ if (showLine) {
+ custom = line.custom || {};
+
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
+ dataset.lineTension = dataset.tension;
+ }
+
+ // Utility
+ line._scale = scale;
+ line._datasetIndex = me.index;
+ // Data
+ line._children = points;
+ // Model
+ line._model = {
+ // Appearance
+ // The default behavior of lines is to break at null values, according
+ // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158
+ // This option gives lines the ability to span gaps
+ spanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps,
+ tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, lineElementOptions.tension),
+ backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
+ borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
+ borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
+ borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),
+ borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
+ borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
+ borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
+ fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
+ steppedLine: custom.steppedLine ? custom.steppedLine : helpers.valueOrDefault(dataset.steppedLine, lineElementOptions.stepped),
+ cubicInterpolationMode: custom.cubicInterpolationMode ? custom.cubicInterpolationMode : helpers.valueOrDefault(dataset.cubicInterpolationMode, lineElementOptions.cubicInterpolationMode),
+ };
+
+ line.pivot();
+ }
+
+ // Update Points
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ me.updateElement(points[i], i, reset);
+ }
+
+ if (showLine && line._model.tension !== 0) {
+ me.updateBezierControlPoints();
+ }
+
+ // Now pivot the point for animation
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ points[i].pivot();
+ }
+ },
+
+ getPointBackgroundColor: function(point, index) {
+ var backgroundColor = this.chart.options.elements.point.backgroundColor;
+ var dataset = this.getDataset();
+ var custom = point.custom || {};
+
+ if (custom.backgroundColor) {
+ backgroundColor = custom.backgroundColor;
+ } else if (dataset.pointBackgroundColor) {
+ backgroundColor = helpers.valueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);
+ } else if (dataset.backgroundColor) {
+ backgroundColor = dataset.backgroundColor;
+ }
+
+ return backgroundColor;
+ },
+
+ getPointBorderColor: function(point, index) {
+ var borderColor = this.chart.options.elements.point.borderColor;
+ var dataset = this.getDataset();
+ var custom = point.custom || {};
+
+ if (custom.borderColor) {
+ borderColor = custom.borderColor;
+ } else if (dataset.pointBorderColor) {
+ borderColor = helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor);
+ } else if (dataset.borderColor) {
+ borderColor = dataset.borderColor;
+ }
+
+ return borderColor;
+ },
+
+ getPointBorderWidth: function(point, index) {
+ var borderWidth = this.chart.options.elements.point.borderWidth;
+ var dataset = this.getDataset();
+ var custom = point.custom || {};
+
+ if (!isNaN(custom.borderWidth)) {
+ borderWidth = custom.borderWidth;
+ } else if (!isNaN(dataset.pointBorderWidth) || helpers.isArray(dataset.pointBorderWidth)) {
+ borderWidth = helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);
+ } else if (!isNaN(dataset.borderWidth)) {
+ borderWidth = dataset.borderWidth;
+ }
+
+ return borderWidth;
+ },
+
+ updateElement: function(point, index, reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var custom = point.custom || {};
+ var dataset = me.getDataset();
+ var datasetIndex = me.index;
+ var value = dataset.data[index];
+ var yScale = me.getScaleForId(meta.yAxisID);
+ var xScale = me.getScaleForId(meta.xAxisID);
+ var pointOptions = me.chart.options.elements.point;
+ var x, y;
+
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
+ dataset.pointRadius = dataset.radius;
+ }
+ if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
+ dataset.pointHitRadius = dataset.hitRadius;
+ }
+
+ x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex);
+ y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);
+
+ // Utility
+ point._xScale = xScale;
+ point._yScale = yScale;
+ point._datasetIndex = datasetIndex;
+ point._index = index;
+
+ // Desired view properties
+ point._model = {
+ x: x,
+ y: y,
+ skip: custom.skip || isNaN(x) || isNaN(y),
+ // Appearance
+ radius: custom.radius || helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),
+ pointStyle: custom.pointStyle || helpers.valueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),
+ backgroundColor: me.getPointBackgroundColor(point, index),
+ borderColor: me.getPointBorderColor(point, index),
+ borderWidth: me.getPointBorderWidth(point, index),
+ tension: meta.dataset._model ? meta.dataset._model.tension : 0,
+ steppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false,
+ // Tooltip
+ hitRadius: custom.hitRadius || helpers.valueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)
+ };
+ },
+
+ calculatePointY: function(value, index, datasetIndex) {
+ var me = this;
+ var chart = me.chart;
+ var meta = me.getMeta();
+ var yScale = me.getScaleForId(meta.yAxisID);
+ var sumPos = 0;
+ var sumNeg = 0;
+ var i, ds, dsMeta;
+
+ if (yScale.options.stacked) {
+ for (i = 0; i < datasetIndex; i++) {
+ ds = chart.data.datasets[i];
+ dsMeta = chart.getDatasetMeta(i);
+ if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {
+ var stackedRightValue = Number(yScale.getRightValue(ds.data[index]));
+ if (stackedRightValue < 0) {
+ sumNeg += stackedRightValue || 0;
+ } else {
+ sumPos += stackedRightValue || 0;
+ }
+ }
+ }
+
+ var rightValue = Number(yScale.getRightValue(value));
+ if (rightValue < 0) {
+ return yScale.getPixelForValue(sumNeg + rightValue);
+ }
+ return yScale.getPixelForValue(sumPos + rightValue);
+ }
+
+ return yScale.getPixelForValue(value);
+ },
+
+ updateBezierControlPoints: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var area = me.chart.chartArea;
+ var points = (meta.data || []);
+ var i, ilen, point, model, controlPoints;
+
+ // Only consider points that are drawn in case the spanGaps option is used
+ if (meta.dataset._model.spanGaps) {
+ points = points.filter(function(pt) {
+ return !pt._model.skip;
+ });
+ }
+
+ function capControlPoint(pt, min, max) {
+ return Math.max(Math.min(pt, max), min);
+ }
+
+ if (meta.dataset._model.cubicInterpolationMode === 'monotone') {
+ helpers.splineCurveMonotone(points);
+ } else {
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ point = points[i];
+ model = point._model;
+ controlPoints = helpers.splineCurve(
+ helpers.previousItem(points, i)._model,
+ model,
+ helpers.nextItem(points, i)._model,
+ meta.dataset._model.tension
+ );
+ model.controlPointPreviousX = controlPoints.previous.x;
+ model.controlPointPreviousY = controlPoints.previous.y;
+ model.controlPointNextX = controlPoints.next.x;
+ model.controlPointNextY = controlPoints.next.y;
+ }
+ }
+
+ if (me.chart.options.elements.line.capBezierPoints) {
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ model = points[i]._model;
+ model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);
+ model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);
+ model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);
+ model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);
+ }
+ }
+ },
+
+ draw: function() {
+ var me = this;
+ var chart = me.chart;
+ var meta = me.getMeta();
+ var points = meta.data || [];
+ var area = chart.chartArea;
+ var ilen = points.length;
+ var i = 0;
+
+ helpers.canvas.clipArea(chart.ctx, area);
+
+ if (lineEnabled(me.getDataset(), chart.options)) {
+ meta.dataset.draw();
+ }
+
+ helpers.canvas.unclipArea(chart.ctx);
+
+ // Draw the points
+ for (; i < ilen; ++i) {
+ points[i].draw(area);
+ }
+ },
+
+ setHoverStyle: function(point) {
+ // Point
+ var dataset = this.chart.data.datasets[point._datasetIndex];
+ var index = point._index;
+ var custom = point.custom || {};
+ var model = point._model;
+
+ model.radius = custom.hoverRadius || helpers.valueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
+ model.backgroundColor = custom.hoverBackgroundColor || helpers.valueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
+ model.borderColor = custom.hoverBorderColor || helpers.valueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
+ model.borderWidth = custom.hoverBorderWidth || helpers.valueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
+ },
+
+ removeHoverStyle: function(point) {
+ var me = this;
+ var dataset = me.chart.data.datasets[point._datasetIndex];
+ var index = point._index;
+ var custom = point.custom || {};
+ var model = point._model;
+
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
+ dataset.pointRadius = dataset.radius;
+ }
+
+ model.radius = custom.radius || helpers.valueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);
+ model.backgroundColor = me.getPointBackgroundColor(point, index);
+ model.borderColor = me.getPointBorderColor(point, index);
+ model.borderWidth = me.getPointBorderWidth(point, index);
+ }
+ });
+};
+
+},{"25":25,"40":40,"45":45}],19:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('polarArea', {
+ scale: {
+ type: 'radialLinear',
+ angleLines: {
+ display: false
+ },
+ gridLines: {
+ circular: true
+ },
+ pointLabels: {
+ display: false
+ },
+ ticks: {
+ beginAtZero: true
+ }
+ },
+
+ // Boolean - Whether to animate the rotation of the chart
+ animation: {
+ animateRotate: true,
+ animateScale: true
+ },
+
+ startAngle: -0.5 * Math.PI,
+ legendCallback: function(chart) {
+ var text = [];
+ text.push('');
+
+ var data = chart.data;
+ var datasets = data.datasets;
+ var labels = data.labels;
+
+ if (datasets.length) {
+ for (var i = 0; i < datasets[0].data.length; ++i) {
+ text.push(' ');
+ if (labels[i]) {
+ text.push(labels[i]);
+ }
+ text.push(' ');
+ }
+ }
+
+ text.push(' ');
+ return text.join('');
+ },
+ legend: {
+ labels: {
+ generateLabels: function(chart) {
+ var data = chart.data;
+ if (data.labels.length && data.datasets.length) {
+ return data.labels.map(function(label, i) {
+ var meta = chart.getDatasetMeta(0);
+ var ds = data.datasets[0];
+ var arc = meta.data[i];
+ var custom = arc.custom || {};
+ var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
+ var arcOpts = chart.options.elements.arc;
+ var fill = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
+ var stroke = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
+ var bw = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
+
+ return {
+ text: label,
+ fillStyle: fill,
+ strokeStyle: stroke,
+ lineWidth: bw,
+ hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
+
+ // Extra data used for toggling the correct item
+ index: i
+ };
+ });
+ }
+ return [];
+ }
+ },
+
+ onClick: function(e, legendItem) {
+ var index = legendItem.index;
+ var chart = this.chart;
+ var i, ilen, meta;
+
+ for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
+ meta = chart.getDatasetMeta(i);
+ meta.data[index].hidden = !meta.data[index].hidden;
+ }
+
+ chart.update();
+ }
+ },
+
+ // Need to override these to give a nice default
+ tooltips: {
+ callbacks: {
+ title: function() {
+ return '';
+ },
+ label: function(item, data) {
+ return data.labels[item.index] + ': ' + item.yLabel;
+ }
+ }
+ }
+});
+
+module.exports = function(Chart) {
+
+ Chart.controllers.polarArea = Chart.DatasetController.extend({
+
+ dataElementType: elements.Arc,
+
+ linkScales: helpers.noop,
+
+ update: function(reset) {
+ var me = this;
+ var chart = me.chart;
+ var chartArea = chart.chartArea;
+ var meta = me.getMeta();
+ var opts = chart.options;
+ var arcOpts = opts.elements.arc;
+ var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
+ chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);
+ chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);
+ chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
+
+ me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);
+ me.innerRadius = me.outerRadius - chart.radiusLength;
+
+ meta.count = me.countVisibleElements();
+
+ helpers.each(meta.data, function(arc, index) {
+ me.updateElement(arc, index, reset);
+ });
+ },
+
+ updateElement: function(arc, index, reset) {
+ var me = this;
+ var chart = me.chart;
+ var dataset = me.getDataset();
+ var opts = chart.options;
+ var animationOpts = opts.animation;
+ var scale = chart.scale;
+ var labels = chart.data.labels;
+
+ var circumference = me.calculateCircumference(dataset.data[index]);
+ var centerX = scale.xCenter;
+ var centerY = scale.yCenter;
+
+ // If there is NaN data before us, we need to calculate the starting angle correctly.
+ // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data
+ var visibleCount = 0;
+ var meta = me.getMeta();
+ for (var i = 0; i < index; ++i) {
+ if (!isNaN(dataset.data[i]) && !meta.data[i].hidden) {
+ ++visibleCount;
+ }
+ }
+
+ // var negHalfPI = -0.5 * Math.PI;
+ var datasetStartAngle = opts.startAngle;
+ var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
+ var startAngle = datasetStartAngle + (circumference * visibleCount);
+ var endAngle = startAngle + (arc.hidden ? 0 : circumference);
+
+ var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
+
+ helpers.extend(arc, {
+ // Utility
+ _datasetIndex: me.index,
+ _index: index,
+ _scale: scale,
+
+ // Desired view properties
+ _model: {
+ x: centerX,
+ y: centerY,
+ innerRadius: 0,
+ outerRadius: reset ? resetRadius : distance,
+ startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,
+ endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,
+ label: helpers.valueAtIndexOrDefault(labels, index, labels[index])
+ }
+ });
+
+ // Apply border and fill style
+ me.removeHoverStyle(arc);
+
+ arc.pivot();
+ },
+
+ removeHoverStyle: function(arc) {
+ Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);
+ },
+
+ countVisibleElements: function() {
+ var dataset = this.getDataset();
+ var meta = this.getMeta();
+ var count = 0;
+
+ helpers.each(meta.data, function(element, index) {
+ if (!isNaN(dataset.data[index]) && !element.hidden) {
+ count++;
+ }
+ });
+
+ return count;
+ },
+
+ calculateCircumference: function(value) {
+ var count = this.getMeta().count;
+ if (count > 0 && !isNaN(value)) {
+ return (2 * Math.PI) / count;
+ }
+ return 0;
+ }
+ });
+};
+
+},{"25":25,"40":40,"45":45}],20:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('radar', {
+ scale: {
+ type: 'radialLinear'
+ },
+ elements: {
+ line: {
+ tension: 0 // no bezier in radar
+ }
+ }
+});
+
+module.exports = function(Chart) {
+
+ Chart.controllers.radar = Chart.DatasetController.extend({
+
+ datasetElementType: elements.Line,
+
+ dataElementType: elements.Point,
+
+ linkScales: helpers.noop,
+
+ update: function(reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var line = meta.dataset;
+ var points = meta.data;
+ var custom = line.custom || {};
+ var dataset = me.getDataset();
+ var lineElementOptions = me.chart.options.elements.line;
+ var scale = me.chart.scale;
+
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
+ dataset.lineTension = dataset.tension;
+ }
+
+ helpers.extend(meta.dataset, {
+ // Utility
+ _datasetIndex: me.index,
+ _scale: scale,
+ // Data
+ _children: points,
+ _loop: true,
+ // Model
+ _model: {
+ // Appearance
+ tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, lineElementOptions.tension),
+ backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
+ borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
+ borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
+ fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
+ borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),
+ borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
+ borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
+ borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
+ }
+ });
+
+ meta.dataset.pivot();
+
+ // Update Points
+ helpers.each(points, function(point, index) {
+ me.updateElement(point, index, reset);
+ }, me);
+
+ // Update bezier control points
+ me.updateBezierControlPoints();
+ },
+ updateElement: function(point, index, reset) {
+ var me = this;
+ var custom = point.custom || {};
+ var dataset = me.getDataset();
+ var scale = me.chart.scale;
+ var pointElementOptions = me.chart.options.elements.point;
+ var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);
+
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
+ dataset.pointRadius = dataset.radius;
+ }
+ if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
+ dataset.pointHitRadius = dataset.hitRadius;
+ }
+
+ helpers.extend(point, {
+ // Utility
+ _datasetIndex: me.index,
+ _index: index,
+ _scale: scale,
+
+ // Desired view properties
+ _model: {
+ x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales
+ y: reset ? scale.yCenter : pointPosition.y,
+
+ // Appearance
+ tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, me.chart.options.elements.line.tension),
+ radius: custom.radius ? custom.radius : helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),
+ backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor),
+ borderColor: custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),
+ borderWidth: custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),
+ pointStyle: custom.pointStyle ? custom.pointStyle : helpers.valueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),
+
+ // Tooltip
+ hitRadius: custom.hitRadius ? custom.hitRadius : helpers.valueAtIndexOrDefault(dataset.pointHitRadius, index, pointElementOptions.hitRadius)
+ }
+ });
+
+ point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
+ },
+ updateBezierControlPoints: function() {
+ var chartArea = this.chart.chartArea;
+ var meta = this.getMeta();
+
+ helpers.each(meta.data, function(point, index) {
+ var model = point._model;
+ var controlPoints = helpers.splineCurve(
+ helpers.previousItem(meta.data, index, true)._model,
+ model,
+ helpers.nextItem(meta.data, index, true)._model,
+ model.tension
+ );
+
+ // Prevent the bezier going outside of the bounds of the graph
+ model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);
+ model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);
+
+ model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);
+ model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);
+
+ // Now pivot the point for animation
+ point.pivot();
+ });
+ },
+
+ setHoverStyle: function(point) {
+ // Point
+ var dataset = this.chart.data.datasets[point._datasetIndex];
+ var custom = point.custom || {};
+ var index = point._index;
+ var model = point._model;
+
+ model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.valueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
+ model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.valueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
+ model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.valueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
+ model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.valueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
+ },
+
+ removeHoverStyle: function(point) {
+ var dataset = this.chart.data.datasets[point._datasetIndex];
+ var custom = point.custom || {};
+ var index = point._index;
+ var model = point._model;
+ var pointElementOptions = this.chart.options.elements.point;
+
+ model.radius = custom.radius ? custom.radius : helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius);
+ model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor);
+ model.borderColor = custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor);
+ model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth);
+ }
+ });
+};
+
+},{"25":25,"40":40,"45":45}],21:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+
+defaults._set('scatter', {
+ hover: {
+ mode: 'single'
+ },
+
+ scales: {
+ xAxes: [{
+ id: 'x-axis-1', // need an ID so datasets can reference the scale
+ type: 'linear', // scatter should not use a category axis
+ position: 'bottom'
+ }],
+ yAxes: [{
+ id: 'y-axis-1',
+ type: 'linear',
+ position: 'left'
+ }]
+ },
+
+ showLines: false,
+
+ tooltips: {
+ callbacks: {
+ title: function() {
+ return ''; // doesn't make sense for scatter since data are formatted as a point
+ },
+ label: function(item) {
+ return '(' + item.xLabel + ', ' + item.yLabel + ')';
+ }
+ }
+ }
+});
+
+module.exports = function(Chart) {
+
+ // Scatter charts use line controllers
+ Chart.controllers.scatter = Chart.controllers.line;
+
+};
+
+},{"25":25}],22:[function(require,module,exports){
+/* global window: false */
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+
+defaults._set('global', {
+ animation: {
+ duration: 1000,
+ easing: 'easeOutQuart',
+ onProgress: helpers.noop,
+ onComplete: helpers.noop
+ }
+});
+
+module.exports = function(Chart) {
+
+ Chart.Animation = Element.extend({
+ chart: null, // the animation associated chart instance
+ currentStep: 0, // the current animation step
+ numSteps: 60, // default number of steps
+ easing: '', // the easing to use for this animation
+ render: null, // render function used by the animation service
+
+ onAnimationProgress: null, // user specified callback to fire on each step of the animation
+ onAnimationComplete: null, // user specified callback to fire when the animation finishes
+ });
+
+ Chart.animationService = {
+ frameDuration: 17,
+ animations: [],
+ dropFrames: 0,
+ request: null,
+
+ /**
+ * @param {Chart} chart - The chart to animate.
+ * @param {Chart.Animation} animation - The animation that we will animate.
+ * @param {Number} duration - The animation duration in ms.
+ * @param {Boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions
+ */
+ addAnimation: function(chart, animation, duration, lazy) {
+ var animations = this.animations;
+ var i, ilen;
+
+ animation.chart = chart;
+
+ if (!lazy) {
+ chart.animating = true;
+ }
+
+ for (i = 0, ilen = animations.length; i < ilen; ++i) {
+ if (animations[i].chart === chart) {
+ animations[i] = animation;
+ return;
+ }
+ }
+
+ animations.push(animation);
+
+ // If there are no animations queued, manually kickstart a digest, for lack of a better word
+ if (animations.length === 1) {
+ this.requestAnimationFrame();
+ }
+ },
+
+ cancelAnimation: function(chart) {
+ var index = helpers.findIndex(this.animations, function(animation) {
+ return animation.chart === chart;
+ });
+
+ if (index !== -1) {
+ this.animations.splice(index, 1);
+ chart.animating = false;
+ }
+ },
+
+ requestAnimationFrame: function() {
+ var me = this;
+ if (me.request === null) {
+ // Skip animation frame requests until the active one is executed.
+ // This can happen when processing mouse events, e.g. 'mousemove'
+ // and 'mouseout' events will trigger multiple renders.
+ me.request = helpers.requestAnimFrame.call(window, function() {
+ me.request = null;
+ me.startDigest();
+ });
+ }
+ },
+
+ /**
+ * @private
+ */
+ startDigest: function() {
+ var me = this;
+ var startTime = Date.now();
+ var framesToDrop = 0;
+
+ if (me.dropFrames > 1) {
+ framesToDrop = Math.floor(me.dropFrames);
+ me.dropFrames = me.dropFrames % 1;
+ }
+
+ me.advance(1 + framesToDrop);
+
+ var endTime = Date.now();
+
+ me.dropFrames += (endTime - startTime) / me.frameDuration;
+
+ // Do we have more stuff to animate?
+ if (me.animations.length > 0) {
+ me.requestAnimationFrame();
+ }
+ },
+
+ /**
+ * @private
+ */
+ advance: function(count) {
+ var animations = this.animations;
+ var animation, chart;
+ var i = 0;
+
+ while (i < animations.length) {
+ animation = animations[i];
+ chart = animation.chart;
+
+ animation.currentStep = (animation.currentStep || 0) + count;
+ animation.currentStep = Math.min(animation.currentStep, animation.numSteps);
+
+ helpers.callback(animation.render, [chart, animation], chart);
+ helpers.callback(animation.onAnimationProgress, [animation], chart);
+
+ if (animation.currentStep >= animation.numSteps) {
+ helpers.callback(animation.onAnimationComplete, [animation], chart);
+ chart.animating = false;
+ animations.splice(i, 1);
+ } else {
+ ++i;
+ }
+ }
+ }
+ };
+
+ /**
+ * Provided for backward compatibility, use Chart.Animation instead
+ * @prop Chart.Animation#animationObject
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ */
+ Object.defineProperty(Chart.Animation.prototype, 'animationObject', {
+ get: function() {
+ return this;
+ }
+ });
+
+ /**
+ * Provided for backward compatibility, use Chart.Animation#chart instead
+ * @prop Chart.Animation#chartInstance
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ */
+ Object.defineProperty(Chart.Animation.prototype, 'chartInstance', {
+ get: function() {
+ return this.chart;
+ },
+ set: function(value) {
+ this.chart = value;
+ }
+ });
+
+};
+
+},{"25":25,"26":26,"45":45}],23:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var helpers = require(45);
+var Interaction = require(28);
+var layouts = require(30);
+var platform = require(48);
+var plugins = require(31);
+
+module.exports = function(Chart) {
+
+ // Create a dictionary of chart types, to allow for extension of existing types
+ Chart.types = {};
+
+ // Store a reference to each instance - allowing us to globally resize chart instances on window resize.
+ // Destroy method on the chart will remove the instance of the chart from this reference.
+ Chart.instances = {};
+
+ // Controllers available for dataset visualization eg. bar, line, slice, etc.
+ Chart.controllers = {};
+
+ /**
+ * Initializes the given config with global and chart default values.
+ */
+ function initConfig(config) {
+ config = config || {};
+
+ // Do NOT use configMerge() for the data object because this method merges arrays
+ // and so would change references to labels and datasets, preventing data updates.
+ var data = config.data = config.data || {};
+ data.datasets = data.datasets || [];
+ data.labels = data.labels || [];
+
+ config.options = helpers.configMerge(
+ defaults.global,
+ defaults[config.type],
+ config.options || {});
+
+ return config;
+ }
+
+ /**
+ * Updates the config of the chart
+ * @param chart {Chart} chart to update the options for
+ */
+ function updateConfig(chart) {
+ var newOptions = chart.options;
+
+ helpers.each(chart.scales, function(scale) {
+ layouts.removeBox(chart, scale);
+ });
+
+ newOptions = helpers.configMerge(
+ Chart.defaults.global,
+ Chart.defaults[chart.config.type],
+ newOptions);
+
+ chart.options = chart.config.options = newOptions;
+ chart.ensureScalesHaveIDs();
+ chart.buildOrUpdateScales();
+ // Tooltip
+ chart.tooltip._options = newOptions.tooltips;
+ chart.tooltip.initialize();
+ }
+
+ function positionIsHorizontal(position) {
+ return position === 'top' || position === 'bottom';
+ }
+
+ helpers.extend(Chart.prototype, /** @lends Chart */ {
+ /**
+ * @private
+ */
+ construct: function(item, config) {
+ var me = this;
+
+ config = initConfig(config);
+
+ var context = platform.acquireContext(item, config);
+ var canvas = context && context.canvas;
+ var height = canvas && canvas.height;
+ var width = canvas && canvas.width;
+
+ me.id = helpers.uid();
+ me.ctx = context;
+ me.canvas = canvas;
+ me.config = config;
+ me.width = width;
+ me.height = height;
+ me.aspectRatio = height ? width / height : null;
+ me.options = config.options;
+ me._bufferedRender = false;
+
+ /**
+ * Provided for backward compatibility, Chart and Chart.Controller have been merged,
+ * the "instance" still need to be defined since it might be called from plugins.
+ * @prop Chart#chart
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ * @private
+ */
+ me.chart = me;
+ me.controller = me; // chart.chart.controller #inception
+
+ // Add the chart instance to the global namespace
+ Chart.instances[me.id] = me;
+
+ // Define alias to the config data: `chart.data === chart.config.data`
+ Object.defineProperty(me, 'data', {
+ get: function() {
+ return me.config.data;
+ },
+ set: function(value) {
+ me.config.data = value;
+ }
+ });
+
+ if (!context || !canvas) {
+ // The given item is not a compatible context2d element, let's return before finalizing
+ // the chart initialization but after setting basic chart / controller properties that
+ // can help to figure out that the chart is not valid (e.g chart.canvas !== null);
+ // https://github.com/chartjs/Chart.js/issues/2807
+ console.error("Failed to create chart: can't acquire context from the given item");
+ return;
+ }
+
+ me.initialize();
+ me.update();
+ },
+
+ /**
+ * @private
+ */
+ initialize: function() {
+ var me = this;
+
+ // Before init plugin notification
+ plugins.notify(me, 'beforeInit');
+
+ helpers.retinaScale(me, me.options.devicePixelRatio);
+
+ me.bindEvents();
+
+ if (me.options.responsive) {
+ // Initial resize before chart draws (must be silent to preserve initial animations).
+ me.resize(true);
+ }
+
+ // Make sure scales have IDs and are built before we build any controllers.
+ me.ensureScalesHaveIDs();
+ me.buildOrUpdateScales();
+ me.initToolTip();
+
+ // After init plugin notification
+ plugins.notify(me, 'afterInit');
+
+ return me;
+ },
+
+ clear: function() {
+ helpers.canvas.clear(this);
+ return this;
+ },
+
+ stop: function() {
+ // Stops any current animation loop occurring
+ Chart.animationService.cancelAnimation(this);
+ return this;
+ },
+
+ resize: function(silent) {
+ var me = this;
+ var options = me.options;
+ var canvas = me.canvas;
+ var aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;
+
+ // the canvas render width and height will be casted to integers so make sure that
+ // the canvas display style uses the same integer values to avoid blurring effect.
+
+ // Set to 0 instead of canvas.size because the size defaults to 300x150 if the element is collased
+ var newWidth = Math.max(0, Math.floor(helpers.getMaximumWidth(canvas)));
+ var newHeight = Math.max(0, Math.floor(aspectRatio ? newWidth / aspectRatio : helpers.getMaximumHeight(canvas)));
+
+ if (me.width === newWidth && me.height === newHeight) {
+ return;
+ }
+
+ canvas.width = me.width = newWidth;
+ canvas.height = me.height = newHeight;
+ canvas.style.width = newWidth + 'px';
+ canvas.style.height = newHeight + 'px';
+
+ helpers.retinaScale(me, options.devicePixelRatio);
+
+ if (!silent) {
+ // Notify any plugins about the resize
+ var newSize = {width: newWidth, height: newHeight};
+ plugins.notify(me, 'resize', [newSize]);
+
+ // Notify of resize
+ if (me.options.onResize) {
+ me.options.onResize(me, newSize);
+ }
+
+ me.stop();
+ me.update(me.options.responsiveAnimationDuration);
+ }
+ },
+
+ ensureScalesHaveIDs: function() {
+ var options = this.options;
+ var scalesOptions = options.scales || {};
+ var scaleOptions = options.scale;
+
+ helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {
+ xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);
+ });
+
+ helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {
+ yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);
+ });
+
+ if (scaleOptions) {
+ scaleOptions.id = scaleOptions.id || 'scale';
+ }
+ },
+
+ /**
+ * Builds a map of scale ID to scale object for future lookup.
+ */
+ buildOrUpdateScales: function() {
+ var me = this;
+ var options = me.options;
+ var scales = me.scales || {};
+ var items = [];
+ var updated = Object.keys(scales).reduce(function(obj, id) {
+ obj[id] = false;
+ return obj;
+ }, {});
+
+ if (options.scales) {
+ items = items.concat(
+ (options.scales.xAxes || []).map(function(xAxisOptions) {
+ return {options: xAxisOptions, dtype: 'category', dposition: 'bottom'};
+ }),
+ (options.scales.yAxes || []).map(function(yAxisOptions) {
+ return {options: yAxisOptions, dtype: 'linear', dposition: 'left'};
+ })
+ );
+ }
+
+ if (options.scale) {
+ items.push({
+ options: options.scale,
+ dtype: 'radialLinear',
+ isDefault: true,
+ dposition: 'chartArea'
+ });
+ }
+
+ helpers.each(items, function(item) {
+ var scaleOptions = item.options;
+ var id = scaleOptions.id;
+ var scaleType = helpers.valueOrDefault(scaleOptions.type, item.dtype);
+
+ if (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {
+ scaleOptions.position = item.dposition;
+ }
+
+ updated[id] = true;
+ var scale = null;
+ if (id in scales && scales[id].type === scaleType) {
+ scale = scales[id];
+ scale.options = scaleOptions;
+ scale.ctx = me.ctx;
+ scale.chart = me;
+ } else {
+ var scaleClass = Chart.scaleService.getScaleConstructor(scaleType);
+ if (!scaleClass) {
+ return;
+ }
+ scale = new scaleClass({
+ id: id,
+ type: scaleType,
+ options: scaleOptions,
+ ctx: me.ctx,
+ chart: me
+ });
+ scales[scale.id] = scale;
+ }
+
+ scale.mergeTicksOptions();
+
+ // TODO(SB): I think we should be able to remove this custom case (options.scale)
+ // and consider it as a regular scale part of the "scales"" map only! This would
+ // make the logic easier and remove some useless? custom code.
+ if (item.isDefault) {
+ me.scale = scale;
+ }
+ });
+ // clear up discarded scales
+ helpers.each(updated, function(hasUpdated, id) {
+ if (!hasUpdated) {
+ delete scales[id];
+ }
+ });
+
+ me.scales = scales;
+
+ Chart.scaleService.addScalesToLayout(this);
+ },
+
+ buildOrUpdateControllers: function() {
+ var me = this;
+ var types = [];
+ var newControllers = [];
+
+ helpers.each(me.data.datasets, function(dataset, datasetIndex) {
+ var meta = me.getDatasetMeta(datasetIndex);
+ var type = dataset.type || me.config.type;
+
+ if (meta.type && meta.type !== type) {
+ me.destroyDatasetMeta(datasetIndex);
+ meta = me.getDatasetMeta(datasetIndex);
+ }
+ meta.type = type;
+
+ types.push(meta.type);
+
+ if (meta.controller) {
+ meta.controller.updateIndex(datasetIndex);
+ meta.controller.linkScales();
+ } else {
+ var ControllerClass = Chart.controllers[meta.type];
+ if (ControllerClass === undefined) {
+ throw new Error('"' + meta.type + '" is not a chart type.');
+ }
+
+ meta.controller = new ControllerClass(me, datasetIndex);
+ newControllers.push(meta.controller);
+ }
+ }, me);
+
+ return newControllers;
+ },
+
+ /**
+ * Reset the elements of all datasets
+ * @private
+ */
+ resetElements: function() {
+ var me = this;
+ helpers.each(me.data.datasets, function(dataset, datasetIndex) {
+ me.getDatasetMeta(datasetIndex).controller.reset();
+ }, me);
+ },
+
+ /**
+ * Resets the chart back to it's state before the initial animation
+ */
+ reset: function() {
+ this.resetElements();
+ this.tooltip.initialize();
+ },
+
+ update: function(config) {
+ var me = this;
+
+ if (!config || typeof config !== 'object') {
+ // backwards compatibility
+ config = {
+ duration: config,
+ lazy: arguments[1]
+ };
+ }
+
+ updateConfig(me);
+
+ // plugins options references might have change, let's invalidate the cache
+ // https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167
+ plugins._invalidate(me);
+
+ if (plugins.notify(me, 'beforeUpdate') === false) {
+ return;
+ }
+
+ // In case the entire data object changed
+ me.tooltip._data = me.data;
+
+ // Make sure dataset controllers are updated and new controllers are reset
+ var newControllers = me.buildOrUpdateControllers();
+
+ // Make sure all dataset controllers have correct meta data counts
+ helpers.each(me.data.datasets, function(dataset, datasetIndex) {
+ me.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();
+ }, me);
+
+ me.updateLayout();
+
+ // Can only reset the new controllers after the scales have been updated
+ if (me.options.animation && me.options.animation.duration) {
+ helpers.each(newControllers, function(controller) {
+ controller.reset();
+ });
+ }
+
+ me.updateDatasets();
+
+ // Need to reset tooltip in case it is displayed with elements that are removed
+ // after update.
+ me.tooltip.initialize();
+
+ // Last active contains items that were previously in the tooltip.
+ // When we reset the tooltip, we need to clear it
+ me.lastActive = [];
+
+ // Do this before render so that any plugins that need final scale updates can use it
+ plugins.notify(me, 'afterUpdate');
+
+ if (me._bufferedRender) {
+ me._bufferedRequest = {
+ duration: config.duration,
+ easing: config.easing,
+ lazy: config.lazy
+ };
+ } else {
+ me.render(config);
+ }
+ },
+
+ /**
+ * Updates the chart layout unless a plugin returns `false` to the `beforeLayout`
+ * hook, in which case, plugins will not be called on `afterLayout`.
+ * @private
+ */
+ updateLayout: function() {
+ var me = this;
+
+ if (plugins.notify(me, 'beforeLayout') === false) {
+ return;
+ }
+
+ layouts.update(this, this.width, this.height);
+
+ /**
+ * Provided for backward compatibility, use `afterLayout` instead.
+ * @method IPlugin#afterScaleUpdate
+ * @deprecated since version 2.5.0
+ * @todo remove at version 3
+ * @private
+ */
+ plugins.notify(me, 'afterScaleUpdate');
+ plugins.notify(me, 'afterLayout');
+ },
+
+ /**
+ * Updates all datasets unless a plugin returns `false` to the `beforeDatasetsUpdate`
+ * hook, in which case, plugins will not be called on `afterDatasetsUpdate`.
+ * @private
+ */
+ updateDatasets: function() {
+ var me = this;
+
+ if (plugins.notify(me, 'beforeDatasetsUpdate') === false) {
+ return;
+ }
+
+ for (var i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {
+ me.updateDataset(i);
+ }
+
+ plugins.notify(me, 'afterDatasetsUpdate');
+ },
+
+ /**
+ * Updates dataset at index unless a plugin returns `false` to the `beforeDatasetUpdate`
+ * hook, in which case, plugins will not be called on `afterDatasetUpdate`.
+ * @private
+ */
+ updateDataset: function(index) {
+ var me = this;
+ var meta = me.getDatasetMeta(index);
+ var args = {
+ meta: meta,
+ index: index
+ };
+
+ if (plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) {
+ return;
+ }
+
+ meta.controller.update();
+
+ plugins.notify(me, 'afterDatasetUpdate', [args]);
+ },
+
+ render: function(config) {
+ var me = this;
+
+ if (!config || typeof config !== 'object') {
+ // backwards compatibility
+ config = {
+ duration: config,
+ lazy: arguments[1]
+ };
+ }
+
+ var duration = config.duration;
+ var lazy = config.lazy;
+
+ if (plugins.notify(me, 'beforeRender') === false) {
+ return;
+ }
+
+ var animationOptions = me.options.animation;
+ var onComplete = function(animation) {
+ plugins.notify(me, 'afterRender');
+ helpers.callback(animationOptions && animationOptions.onComplete, [animation], me);
+ };
+
+ if (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) {
+ var animation = new Chart.Animation({
+ numSteps: (duration || animationOptions.duration) / 16.66, // 60 fps
+ easing: config.easing || animationOptions.easing,
+
+ render: function(chart, animationObject) {
+ var easingFunction = helpers.easing.effects[animationObject.easing];
+ var currentStep = animationObject.currentStep;
+ var stepDecimal = currentStep / animationObject.numSteps;
+
+ chart.draw(easingFunction(stepDecimal), stepDecimal, currentStep);
+ },
+
+ onAnimationProgress: animationOptions.onProgress,
+ onAnimationComplete: onComplete
+ });
+
+ Chart.animationService.addAnimation(me, animation, duration, lazy);
+ } else {
+ me.draw();
+
+ // See https://github.com/chartjs/Chart.js/issues/3781
+ onComplete(new Chart.Animation({numSteps: 0, chart: me}));
+ }
+
+ return me;
+ },
+
+ draw: function(easingValue) {
+ var me = this;
+
+ me.clear();
+
+ if (helpers.isNullOrUndef(easingValue)) {
+ easingValue = 1;
+ }
+
+ me.transition(easingValue);
+
+ if (plugins.notify(me, 'beforeDraw', [easingValue]) === false) {
+ return;
+ }
+
+ // Draw all the scales
+ helpers.each(me.boxes, function(box) {
+ box.draw(me.chartArea);
+ }, me);
+
+ if (me.scale) {
+ me.scale.draw();
+ }
+
+ me.drawDatasets(easingValue);
+ me._drawTooltip(easingValue);
+
+ plugins.notify(me, 'afterDraw', [easingValue]);
+ },
+
+ /**
+ * @private
+ */
+ transition: function(easingValue) {
+ var me = this;
+
+ for (var i = 0, ilen = (me.data.datasets || []).length; i < ilen; ++i) {
+ if (me.isDatasetVisible(i)) {
+ me.getDatasetMeta(i).controller.transition(easingValue);
+ }
+ }
+
+ me.tooltip.transition(easingValue);
+ },
+
+ /**
+ * Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw`
+ * hook, in which case, plugins will not be called on `afterDatasetsDraw`.
+ * @private
+ */
+ drawDatasets: function(easingValue) {
+ var me = this;
+
+ if (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) {
+ return;
+ }
+
+ // Draw datasets reversed to support proper line stacking
+ for (var i = (me.data.datasets || []).length - 1; i >= 0; --i) {
+ if (me.isDatasetVisible(i)) {
+ me.drawDataset(i, easingValue);
+ }
+ }
+
+ plugins.notify(me, 'afterDatasetsDraw', [easingValue]);
+ },
+
+ /**
+ * Draws dataset at index unless a plugin returns `false` to the `beforeDatasetDraw`
+ * hook, in which case, plugins will not be called on `afterDatasetDraw`.
+ * @private
+ */
+ drawDataset: function(index, easingValue) {
+ var me = this;
+ var meta = me.getDatasetMeta(index);
+ var args = {
+ meta: meta,
+ index: index,
+ easingValue: easingValue
+ };
+
+ if (plugins.notify(me, 'beforeDatasetDraw', [args]) === false) {
+ return;
+ }
+
+ meta.controller.draw(easingValue);
+
+ plugins.notify(me, 'afterDatasetDraw', [args]);
+ },
+
+ /**
+ * Draws tooltip unless a plugin returns `false` to the `beforeTooltipDraw`
+ * hook, in which case, plugins will not be called on `afterTooltipDraw`.
+ * @private
+ */
+ _drawTooltip: function(easingValue) {
+ var me = this;
+ var tooltip = me.tooltip;
+ var args = {
+ tooltip: tooltip,
+ easingValue: easingValue
+ };
+
+ if (plugins.notify(me, 'beforeTooltipDraw', [args]) === false) {
+ return;
+ }
+
+ tooltip.draw();
+
+ plugins.notify(me, 'afterTooltipDraw', [args]);
+ },
+
+ // Get the single element that was clicked on
+ // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw
+ getElementAtEvent: function(e) {
+ return Interaction.modes.single(this, e);
+ },
+
+ getElementsAtEvent: function(e) {
+ return Interaction.modes.label(this, e, {intersect: true});
+ },
+
+ getElementsAtXAxis: function(e) {
+ return Interaction.modes['x-axis'](this, e, {intersect: true});
+ },
+
+ getElementsAtEventForMode: function(e, mode, options) {
+ var method = Interaction.modes[mode];
+ if (typeof method === 'function') {
+ return method(this, e, options);
+ }
+
+ return [];
+ },
+
+ getDatasetAtEvent: function(e) {
+ return Interaction.modes.dataset(this, e, {intersect: true});
+ },
+
+ getDatasetMeta: function(datasetIndex) {
+ var me = this;
+ var dataset = me.data.datasets[datasetIndex];
+ if (!dataset._meta) {
+ dataset._meta = {};
+ }
+
+ var meta = dataset._meta[me.id];
+ if (!meta) {
+ meta = dataset._meta[me.id] = {
+ type: null,
+ data: [],
+ dataset: null,
+ controller: null,
+ hidden: null, // See isDatasetVisible() comment
+ xAxisID: null,
+ yAxisID: null
+ };
+ }
+
+ return meta;
+ },
+
+ getVisibleDatasetCount: function() {
+ var count = 0;
+ for (var i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
+ if (this.isDatasetVisible(i)) {
+ count++;
+ }
+ }
+ return count;
+ },
+
+ isDatasetVisible: function(datasetIndex) {
+ var meta = this.getDatasetMeta(datasetIndex);
+
+ // meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,
+ // the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.
+ return typeof meta.hidden === 'boolean' ? !meta.hidden : !this.data.datasets[datasetIndex].hidden;
+ },
+
+ generateLegend: function() {
+ return this.options.legendCallback(this);
+ },
+
+ /**
+ * @private
+ */
+ destroyDatasetMeta: function(datasetIndex) {
+ var id = this.id;
+ var dataset = this.data.datasets[datasetIndex];
+ var meta = dataset._meta && dataset._meta[id];
+
+ if (meta) {
+ meta.controller.destroy();
+ delete dataset._meta[id];
+ }
+ },
+
+ destroy: function() {
+ var me = this;
+ var canvas = me.canvas;
+ var i, ilen;
+
+ me.stop();
+
+ // dataset controllers need to cleanup associated data
+ for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {
+ me.destroyDatasetMeta(i);
+ }
+
+ if (canvas) {
+ me.unbindEvents();
+ helpers.canvas.clear(me);
+ platform.releaseContext(me.ctx);
+ me.canvas = null;
+ me.ctx = null;
+ }
+
+ plugins.notify(me, 'destroy');
+
+ delete Chart.instances[me.id];
+ },
+
+ toBase64Image: function() {
+ return this.canvas.toDataURL.apply(this.canvas, arguments);
+ },
+
+ initToolTip: function() {
+ var me = this;
+ me.tooltip = new Chart.Tooltip({
+ _chart: me,
+ _chartInstance: me, // deprecated, backward compatibility
+ _data: me.data,
+ _options: me.options.tooltips
+ }, me);
+ },
+
+ /**
+ * @private
+ */
+ bindEvents: function() {
+ var me = this;
+ var listeners = me._listeners = {};
+ var listener = function() {
+ me.eventHandler.apply(me, arguments);
+ };
+
+ helpers.each(me.options.events, function(type) {
+ platform.addEventListener(me, type, listener);
+ listeners[type] = listener;
+ });
+
+ // Elements used to detect size change should not be injected for non responsive charts.
+ // See https://github.com/chartjs/Chart.js/issues/2210
+ if (me.options.responsive) {
+ listener = function() {
+ me.resize();
+ };
+
+ platform.addEventListener(me, 'resize', listener);
+ listeners.resize = listener;
+ }
+ },
+
+ /**
+ * @private
+ */
+ unbindEvents: function() {
+ var me = this;
+ var listeners = me._listeners;
+ if (!listeners) {
+ return;
+ }
+
+ delete me._listeners;
+ helpers.each(listeners, function(listener, type) {
+ platform.removeEventListener(me, type, listener);
+ });
+ },
+
+ updateHoverStyle: function(elements, mode, enabled) {
+ var method = enabled ? 'setHoverStyle' : 'removeHoverStyle';
+ var element, i, ilen;
+
+ for (i = 0, ilen = elements.length; i < ilen; ++i) {
+ element = elements[i];
+ if (element) {
+ this.getDatasetMeta(element._datasetIndex).controller[method](element);
+ }
+ }
+ },
+
+ /**
+ * @private
+ */
+ eventHandler: function(e) {
+ var me = this;
+ var tooltip = me.tooltip;
+
+ if (plugins.notify(me, 'beforeEvent', [e]) === false) {
+ return;
+ }
+
+ // Buffer any update calls so that renders do not occur
+ me._bufferedRender = true;
+ me._bufferedRequest = null;
+
+ var changed = me.handleEvent(e);
+ // for smooth tooltip animations issue #4989
+ // the tooltip should be the source of change
+ // Animation check workaround:
+ // tooltip._start will be null when tooltip isn't animating
+ if (tooltip) {
+ changed = tooltip._start
+ ? tooltip.handleEvent(e)
+ : changed | tooltip.handleEvent(e);
+ }
+
+ plugins.notify(me, 'afterEvent', [e]);
+
+ var bufferedRequest = me._bufferedRequest;
+ if (bufferedRequest) {
+ // If we have an update that was triggered, we need to do a normal render
+ me.render(bufferedRequest);
+ } else if (changed && !me.animating) {
+ // If entering, leaving, or changing elements, animate the change via pivot
+ me.stop();
+
+ // We only need to render at this point. Updating will cause scales to be
+ // recomputed generating flicker & using more memory than necessary.
+ me.render(me.options.hover.animationDuration, true);
+ }
+
+ me._bufferedRender = false;
+ me._bufferedRequest = null;
+
+ return me;
+ },
+
+ /**
+ * Handle an event
+ * @private
+ * @param {IEvent} event the event to handle
+ * @return {Boolean} true if the chart needs to re-render
+ */
+ handleEvent: function(e) {
+ var me = this;
+ var options = me.options || {};
+ var hoverOptions = options.hover;
+ var changed = false;
+
+ me.lastActive = me.lastActive || [];
+
+ // Find Active Elements for hover and tooltips
+ if (e.type === 'mouseout') {
+ me.active = [];
+ } else {
+ me.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions);
+ }
+
+ // Invoke onHover hook
+ // Need to call with native event here to not break backwards compatibility
+ helpers.callback(options.onHover || options.hover.onHover, [e.native, me.active], me);
+
+ if (e.type === 'mouseup' || e.type === 'click') {
+ if (options.onClick) {
+ // Use e.native here for backwards compatibility
+ options.onClick.call(me, e.native, me.active);
+ }
+ }
+
+ // Remove styling for last active (even if it may still be active)
+ if (me.lastActive.length) {
+ me.updateHoverStyle(me.lastActive, hoverOptions.mode, false);
+ }
+
+ // Built in hover styling
+ if (me.active.length && hoverOptions.mode) {
+ me.updateHoverStyle(me.active, hoverOptions.mode, true);
+ }
+
+ changed = !helpers.arrayEquals(me.active, me.lastActive);
+
+ // Remember Last Actives
+ me.lastActive = me.active;
+
+ return changed;
+ }
+ });
+
+ /**
+ * Provided for backward compatibility, use Chart instead.
+ * @class Chart.Controller
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ * @private
+ */
+ Chart.Controller = Chart;
+};
+
+},{"25":25,"28":28,"30":30,"31":31,"45":45,"48":48}],24:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+
+module.exports = function(Chart) {
+
+ var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
+
+ /**
+ * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',
+ * 'unshift') and notify the listener AFTER the array has been altered. Listeners are
+ * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.
+ */
+ function listenArrayEvents(array, listener) {
+ if (array._chartjs) {
+ array._chartjs.listeners.push(listener);
+ return;
+ }
+
+ Object.defineProperty(array, '_chartjs', {
+ configurable: true,
+ enumerable: false,
+ value: {
+ listeners: [listener]
+ }
+ });
+
+ arrayEvents.forEach(function(key) {
+ var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);
+ var base = array[key];
+
+ Object.defineProperty(array, key, {
+ configurable: true,
+ enumerable: false,
+ value: function() {
+ var args = Array.prototype.slice.call(arguments);
+ var res = base.apply(this, args);
+
+ helpers.each(array._chartjs.listeners, function(object) {
+ if (typeof object[method] === 'function') {
+ object[method].apply(object, args);
+ }
+ });
+
+ return res;
+ }
+ });
+ });
+ }
+
+ /**
+ * Removes the given array event listener and cleanup extra attached properties (such as
+ * the _chartjs stub and overridden methods) if array doesn't have any more listeners.
+ */
+ function unlistenArrayEvents(array, listener) {
+ var stub = array._chartjs;
+ if (!stub) {
+ return;
+ }
+
+ var listeners = stub.listeners;
+ var index = listeners.indexOf(listener);
+ if (index !== -1) {
+ listeners.splice(index, 1);
+ }
+
+ if (listeners.length > 0) {
+ return;
+ }
+
+ arrayEvents.forEach(function(key) {
+ delete array[key];
+ });
+
+ delete array._chartjs;
+ }
+
+ // Base class for all dataset controllers (line, bar, etc)
+ Chart.DatasetController = function(chart, datasetIndex) {
+ this.initialize(chart, datasetIndex);
+ };
+
+ helpers.extend(Chart.DatasetController.prototype, {
+
+ /**
+ * Element type used to generate a meta dataset (e.g. Chart.element.Line).
+ * @type {Chart.core.element}
+ */
+ datasetElementType: null,
+
+ /**
+ * Element type used to generate a meta data (e.g. Chart.element.Point).
+ * @type {Chart.core.element}
+ */
+ dataElementType: null,
+
+ initialize: function(chart, datasetIndex) {
+ var me = this;
+ me.chart = chart;
+ me.index = datasetIndex;
+ me.linkScales();
+ me.addElements();
+ },
+
+ updateIndex: function(datasetIndex) {
+ this.index = datasetIndex;
+ },
+
+ linkScales: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var dataset = me.getDataset();
+
+ if (meta.xAxisID === null || !(meta.xAxisID in me.chart.scales)) {
+ meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;
+ }
+ if (meta.yAxisID === null || !(meta.yAxisID in me.chart.scales)) {
+ meta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;
+ }
+ },
+
+ getDataset: function() {
+ return this.chart.data.datasets[this.index];
+ },
+
+ getMeta: function() {
+ return this.chart.getDatasetMeta(this.index);
+ },
+
+ getScaleForId: function(scaleID) {
+ return this.chart.scales[scaleID];
+ },
+
+ reset: function() {
+ this.update(true);
+ },
+
+ /**
+ * @private
+ */
+ destroy: function() {
+ if (this._data) {
+ unlistenArrayEvents(this._data, this);
+ }
+ },
+
+ createMetaDataset: function() {
+ var me = this;
+ var type = me.datasetElementType;
+ return type && new type({
+ _chart: me.chart,
+ _datasetIndex: me.index
+ });
+ },
+
+ createMetaData: function(index) {
+ var me = this;
+ var type = me.dataElementType;
+ return type && new type({
+ _chart: me.chart,
+ _datasetIndex: me.index,
+ _index: index
+ });
+ },
+
+ addElements: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var data = me.getDataset().data || [];
+ var metaData = meta.data;
+ var i, ilen;
+
+ for (i = 0, ilen = data.length; i < ilen; ++i) {
+ metaData[i] = metaData[i] || me.createMetaData(i);
+ }
+
+ meta.dataset = meta.dataset || me.createMetaDataset();
+ },
+
+ addElementAndReset: function(index) {
+ var element = this.createMetaData(index);
+ this.getMeta().data.splice(index, 0, element);
+ this.updateElement(element, index, true);
+ },
+
+ buildOrUpdateElements: function() {
+ var me = this;
+ var dataset = me.getDataset();
+ var data = dataset.data || (dataset.data = []);
+
+ // In order to correctly handle data addition/deletion animation (an thus simulate
+ // real-time charts), we need to monitor these data modifications and synchronize
+ // the internal meta data accordingly.
+ if (me._data !== data) {
+ if (me._data) {
+ // This case happens when the user replaced the data array instance.
+ unlistenArrayEvents(me._data, me);
+ }
+
+ listenArrayEvents(data, me);
+ me._data = data;
+ }
+
+ // Re-sync meta data in case the user replaced the data array or if we missed
+ // any updates and so make sure that we handle number of datapoints changing.
+ me.resyncElements();
+ },
+
+ update: helpers.noop,
+
+ transition: function(easingValue) {
+ var meta = this.getMeta();
+ var elements = meta.data || [];
+ var ilen = elements.length;
+ var i = 0;
+
+ for (; i < ilen; ++i) {
+ elements[i].transition(easingValue);
+ }
+
+ if (meta.dataset) {
+ meta.dataset.transition(easingValue);
+ }
+ },
+
+ draw: function() {
+ var meta = this.getMeta();
+ var elements = meta.data || [];
+ var ilen = elements.length;
+ var i = 0;
+
+ if (meta.dataset) {
+ meta.dataset.draw();
+ }
+
+ for (; i < ilen; ++i) {
+ elements[i].draw();
+ }
+ },
+
+ removeHoverStyle: function(element, elementOpts) {
+ var dataset = this.chart.data.datasets[element._datasetIndex];
+ var index = element._index;
+ var custom = element.custom || {};
+ var valueOrDefault = helpers.valueAtIndexOrDefault;
+ var model = element._model;
+
+ model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);
+ model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);
+ model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);
+ },
+
+ setHoverStyle: function(element) {
+ var dataset = this.chart.data.datasets[element._datasetIndex];
+ var index = element._index;
+ var custom = element.custom || {};
+ var valueOrDefault = helpers.valueAtIndexOrDefault;
+ var getHoverColor = helpers.getHoverColor;
+ var model = element._model;
+
+ model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));
+ model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));
+ model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
+ },
+
+ /**
+ * @private
+ */
+ resyncElements: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var data = me.getDataset().data;
+ var numMeta = meta.data.length;
+ var numData = data.length;
+
+ if (numData < numMeta) {
+ meta.data.splice(numData, numMeta - numData);
+ } else if (numData > numMeta) {
+ me.insertElements(numMeta, numData - numMeta);
+ }
+ },
+
+ /**
+ * @private
+ */
+ insertElements: function(start, count) {
+ for (var i = 0; i < count; ++i) {
+ this.addElementAndReset(start + i);
+ }
+ },
+
+ /**
+ * @private
+ */
+ onDataPush: function() {
+ this.insertElements(this.getDataset().data.length - 1, arguments.length);
+ },
+
+ /**
+ * @private
+ */
+ onDataPop: function() {
+ this.getMeta().data.pop();
+ },
+
+ /**
+ * @private
+ */
+ onDataShift: function() {
+ this.getMeta().data.shift();
+ },
+
+ /**
+ * @private
+ */
+ onDataSplice: function(start, count) {
+ this.getMeta().data.splice(start, count);
+ this.insertElements(start, arguments.length - 2);
+ },
+
+ /**
+ * @private
+ */
+ onDataUnshift: function() {
+ this.insertElements(0, arguments.length);
+ }
+ });
+
+ Chart.DatasetController.extend = helpers.inherits;
+};
+
+},{"45":45}],25:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+
+module.exports = {
+ /**
+ * @private
+ */
+ _set: function(scope, values) {
+ return helpers.merge(this[scope] || (this[scope] = {}), values);
+ }
+};
+
+},{"45":45}],26:[function(require,module,exports){
+'use strict';
+
+var color = require(3);
+var helpers = require(45);
+
+function interpolate(start, view, model, ease) {
+ var keys = Object.keys(model);
+ var i, ilen, key, actual, origin, target, type, c0, c1;
+
+ for (i = 0, ilen = keys.length; i < ilen; ++i) {
+ key = keys[i];
+
+ target = model[key];
+
+ // if a value is added to the model after pivot() has been called, the view
+ // doesn't contain it, so let's initialize the view to the target value.
+ if (!view.hasOwnProperty(key)) {
+ view[key] = target;
+ }
+
+ actual = view[key];
+
+ if (actual === target || key[0] === '_') {
+ continue;
+ }
+
+ if (!start.hasOwnProperty(key)) {
+ start[key] = actual;
+ }
+
+ origin = start[key];
+
+ type = typeof target;
+
+ if (type === typeof origin) {
+ if (type === 'string') {
+ c0 = color(origin);
+ if (c0.valid) {
+ c1 = color(target);
+ if (c1.valid) {
+ view[key] = c1.mix(c0, ease).rgbString();
+ continue;
+ }
+ }
+ } else if (type === 'number' && isFinite(origin) && isFinite(target)) {
+ view[key] = origin + (target - origin) * ease;
+ continue;
+ }
+ }
+
+ view[key] = target;
+ }
+}
+
+var Element = function(configuration) {
+ helpers.extend(this, configuration);
+ this.initialize.apply(this, arguments);
+};
+
+helpers.extend(Element.prototype, {
+
+ initialize: function() {
+ this.hidden = false;
+ },
+
+ pivot: function() {
+ var me = this;
+ if (!me._view) {
+ me._view = helpers.clone(me._model);
+ }
+ me._start = {};
+ return me;
+ },
+
+ transition: function(ease) {
+ var me = this;
+ var model = me._model;
+ var start = me._start;
+ var view = me._view;
+
+ // No animation -> No Transition
+ if (!model || ease === 1) {
+ me._view = model;
+ me._start = null;
+ return me;
+ }
+
+ if (!view) {
+ view = me._view = {};
+ }
+
+ if (!start) {
+ start = me._start = {};
+ }
+
+ interpolate(start, view, model, ease);
+
+ return me;
+ },
+
+ tooltipPosition: function() {
+ return {
+ x: this._model.x,
+ y: this._model.y
+ };
+ },
+
+ hasValue: function() {
+ return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);
+ }
+});
+
+Element.extend = helpers.inherits;
+
+module.exports = Element;
+
+},{"3":3,"45":45}],27:[function(require,module,exports){
+/* global window: false */
+/* global document: false */
+'use strict';
+
+var color = require(3);
+var defaults = require(25);
+var helpers = require(45);
+
+module.exports = function(Chart) {
+
+ // -- Basic js utility methods
+
+ helpers.configMerge = function(/* objects ... */) {
+ return helpers.merge(helpers.clone(arguments[0]), [].slice.call(arguments, 1), {
+ merger: function(key, target, source, options) {
+ var tval = target[key] || {};
+ var sval = source[key];
+
+ if (key === 'scales') {
+ // scale config merging is complex. Add our own function here for that
+ target[key] = helpers.scaleMerge(tval, sval);
+ } else if (key === 'scale') {
+ // used in polar area & radar charts since there is only one scale
+ target[key] = helpers.merge(tval, [Chart.scaleService.getScaleDefaults(sval.type), sval]);
+ } else {
+ helpers._merger(key, target, source, options);
+ }
+ }
+ });
+ };
+
+ helpers.scaleMerge = function(/* objects ... */) {
+ return helpers.merge(helpers.clone(arguments[0]), [].slice.call(arguments, 1), {
+ merger: function(key, target, source, options) {
+ if (key === 'xAxes' || key === 'yAxes') {
+ var slen = source[key].length;
+ var i, type, scale;
+
+ if (!target[key]) {
+ target[key] = [];
+ }
+
+ for (i = 0; i < slen; ++i) {
+ scale = source[key][i];
+ type = helpers.valueOrDefault(scale.type, key === 'xAxes' ? 'category' : 'linear');
+
+ if (i >= target[key].length) {
+ target[key].push({});
+ }
+
+ if (!target[key][i].type || (scale.type && scale.type !== target[key][i].type)) {
+ // new/untyped scale or type changed: let's apply the new defaults
+ // then merge source scale to correctly overwrite the defaults.
+ helpers.merge(target[key][i], [Chart.scaleService.getScaleDefaults(type), scale]);
+ } else {
+ // scales type are the same
+ helpers.merge(target[key][i], scale);
+ }
+ }
+ } else {
+ helpers._merger(key, target, source, options);
+ }
+ }
+ });
+ };
+
+ helpers.where = function(collection, filterCallback) {
+ if (helpers.isArray(collection) && Array.prototype.filter) {
+ return collection.filter(filterCallback);
+ }
+ var filtered = [];
+
+ helpers.each(collection, function(item) {
+ if (filterCallback(item)) {
+ filtered.push(item);
+ }
+ });
+
+ return filtered;
+ };
+ helpers.findIndex = Array.prototype.findIndex ?
+ function(array, callback, scope) {
+ return array.findIndex(callback, scope);
+ } :
+ function(array, callback, scope) {
+ scope = scope === undefined ? array : scope;
+ for (var i = 0, ilen = array.length; i < ilen; ++i) {
+ if (callback.call(scope, array[i], i, array)) {
+ return i;
+ }
+ }
+ return -1;
+ };
+ helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {
+ // Default to start of the array
+ if (helpers.isNullOrUndef(startIndex)) {
+ startIndex = -1;
+ }
+ for (var i = startIndex + 1; i < arrayToSearch.length; i++) {
+ var currentItem = arrayToSearch[i];
+ if (filterCallback(currentItem)) {
+ return currentItem;
+ }
+ }
+ };
+ helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {
+ // Default to end of the array
+ if (helpers.isNullOrUndef(startIndex)) {
+ startIndex = arrayToSearch.length;
+ }
+ for (var i = startIndex - 1; i >= 0; i--) {
+ var currentItem = arrayToSearch[i];
+ if (filterCallback(currentItem)) {
+ return currentItem;
+ }
+ }
+ };
+
+ // -- Math methods
+ helpers.isNumber = function(n) {
+ return !isNaN(parseFloat(n)) && isFinite(n);
+ };
+ helpers.almostEquals = function(x, y, epsilon) {
+ return Math.abs(x - y) < epsilon;
+ };
+ helpers.almostWhole = function(x, epsilon) {
+ var rounded = Math.round(x);
+ return (((rounded - epsilon) < x) && ((rounded + epsilon) > x));
+ };
+ helpers.max = function(array) {
+ return array.reduce(function(max, value) {
+ if (!isNaN(value)) {
+ return Math.max(max, value);
+ }
+ return max;
+ }, Number.NEGATIVE_INFINITY);
+ };
+ helpers.min = function(array) {
+ return array.reduce(function(min, value) {
+ if (!isNaN(value)) {
+ return Math.min(min, value);
+ }
+ return min;
+ }, Number.POSITIVE_INFINITY);
+ };
+ helpers.sign = Math.sign ?
+ function(x) {
+ return Math.sign(x);
+ } :
+ function(x) {
+ x = +x; // convert to a number
+ if (x === 0 || isNaN(x)) {
+ return x;
+ }
+ return x > 0 ? 1 : -1;
+ };
+ helpers.log10 = Math.log10 ?
+ function(x) {
+ return Math.log10(x);
+ } :
+ function(x) {
+ var exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10.
+ // Check for whole powers of 10,
+ // which due to floating point rounding error should be corrected.
+ var powerOf10 = Math.round(exponent);
+ var isPowerOf10 = x === Math.pow(10, powerOf10);
+
+ return isPowerOf10 ? powerOf10 : exponent;
+ };
+ helpers.toRadians = function(degrees) {
+ return degrees * (Math.PI / 180);
+ };
+ helpers.toDegrees = function(radians) {
+ return radians * (180 / Math.PI);
+ };
+ // Gets the angle from vertical upright to the point about a centre.
+ helpers.getAngleFromPoint = function(centrePoint, anglePoint) {
+ var distanceFromXCenter = anglePoint.x - centrePoint.x;
+ var distanceFromYCenter = anglePoint.y - centrePoint.y;
+ var radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
+
+ var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);
+
+ if (angle < (-0.5 * Math.PI)) {
+ angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]
+ }
+
+ return {
+ angle: angle,
+ distance: radialDistanceFromCenter
+ };
+ };
+ helpers.distanceBetweenPoints = function(pt1, pt2) {
+ return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
+ };
+ helpers.aliasPixel = function(pixelWidth) {
+ return (pixelWidth % 2 === 0) ? 0 : 0.5;
+ };
+ helpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {
+ // Props to Rob Spencer at scaled innovation for his post on splining between points
+ // http://scaledinnovation.com/analytics/splines/aboutSplines.html
+
+ // This function must also respect "skipped" points
+
+ var previous = firstPoint.skip ? middlePoint : firstPoint;
+ var current = middlePoint;
+ var next = afterPoint.skip ? middlePoint : afterPoint;
+
+ var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));
+ var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));
+
+ var s01 = d01 / (d01 + d12);
+ var s12 = d12 / (d01 + d12);
+
+ // If all points are the same, s01 & s02 will be inf
+ s01 = isNaN(s01) ? 0 : s01;
+ s12 = isNaN(s12) ? 0 : s12;
+
+ var fa = t * s01; // scaling factor for triangle Ta
+ var fb = t * s12;
+
+ return {
+ previous: {
+ x: current.x - fa * (next.x - previous.x),
+ y: current.y - fa * (next.y - previous.y)
+ },
+ next: {
+ x: current.x + fb * (next.x - previous.x),
+ y: current.y + fb * (next.y - previous.y)
+ }
+ };
+ };
+ helpers.EPSILON = Number.EPSILON || 1e-14;
+ helpers.splineCurveMonotone = function(points) {
+ // This function calculates Bézier control points in a similar way than |splineCurve|,
+ // but preserves monotonicity of the provided data and ensures no local extremums are added
+ // between the dataset discrete points due to the interpolation.
+ // See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation
+
+ var pointsWithTangents = (points || []).map(function(point) {
+ return {
+ model: point._model,
+ deltaK: 0,
+ mK: 0
+ };
+ });
+
+ // Calculate slopes (deltaK) and initialize tangents (mK)
+ var pointsLen = pointsWithTangents.length;
+ var i, pointBefore, pointCurrent, pointAfter;
+ for (i = 0; i < pointsLen; ++i) {
+ pointCurrent = pointsWithTangents[i];
+ if (pointCurrent.model.skip) {
+ continue;
+ }
+
+ pointBefore = i > 0 ? pointsWithTangents[i - 1] : null;
+ pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;
+ if (pointAfter && !pointAfter.model.skip) {
+ var slopeDeltaX = (pointAfter.model.x - pointCurrent.model.x);
+
+ // In the case of two points that appear at the same x pixel, slopeDeltaX is 0
+ pointCurrent.deltaK = slopeDeltaX !== 0 ? (pointAfter.model.y - pointCurrent.model.y) / slopeDeltaX : 0;
+ }
+
+ if (!pointBefore || pointBefore.model.skip) {
+ pointCurrent.mK = pointCurrent.deltaK;
+ } else if (!pointAfter || pointAfter.model.skip) {
+ pointCurrent.mK = pointBefore.deltaK;
+ } else if (this.sign(pointBefore.deltaK) !== this.sign(pointCurrent.deltaK)) {
+ pointCurrent.mK = 0;
+ } else {
+ pointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2;
+ }
+ }
+
+ // Adjust tangents to ensure monotonic properties
+ var alphaK, betaK, tauK, squaredMagnitude;
+ for (i = 0; i < pointsLen - 1; ++i) {
+ pointCurrent = pointsWithTangents[i];
+ pointAfter = pointsWithTangents[i + 1];
+ if (pointCurrent.model.skip || pointAfter.model.skip) {
+ continue;
+ }
+
+ if (helpers.almostEquals(pointCurrent.deltaK, 0, this.EPSILON)) {
+ pointCurrent.mK = pointAfter.mK = 0;
+ continue;
+ }
+
+ alphaK = pointCurrent.mK / pointCurrent.deltaK;
+ betaK = pointAfter.mK / pointCurrent.deltaK;
+ squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);
+ if (squaredMagnitude <= 9) {
+ continue;
+ }
+
+ tauK = 3 / Math.sqrt(squaredMagnitude);
+ pointCurrent.mK = alphaK * tauK * pointCurrent.deltaK;
+ pointAfter.mK = betaK * tauK * pointCurrent.deltaK;
+ }
+
+ // Compute control points
+ var deltaX;
+ for (i = 0; i < pointsLen; ++i) {
+ pointCurrent = pointsWithTangents[i];
+ if (pointCurrent.model.skip) {
+ continue;
+ }
+
+ pointBefore = i > 0 ? pointsWithTangents[i - 1] : null;
+ pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;
+ if (pointBefore && !pointBefore.model.skip) {
+ deltaX = (pointCurrent.model.x - pointBefore.model.x) / 3;
+ pointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX;
+ pointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK;
+ }
+ if (pointAfter && !pointAfter.model.skip) {
+ deltaX = (pointAfter.model.x - pointCurrent.model.x) / 3;
+ pointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX;
+ pointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK;
+ }
+ }
+ };
+ helpers.nextItem = function(collection, index, loop) {
+ if (loop) {
+ return index >= collection.length - 1 ? collection[0] : collection[index + 1];
+ }
+ return index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];
+ };
+ helpers.previousItem = function(collection, index, loop) {
+ if (loop) {
+ return index <= 0 ? collection[collection.length - 1] : collection[index - 1];
+ }
+ return index <= 0 ? collection[0] : collection[index - 1];
+ };
+ // Implementation of the nice number algorithm used in determining where axis labels will go
+ helpers.niceNum = function(range, round) {
+ var exponent = Math.floor(helpers.log10(range));
+ var fraction = range / Math.pow(10, exponent);
+ var niceFraction;
+
+ if (round) {
+ if (fraction < 1.5) {
+ niceFraction = 1;
+ } else if (fraction < 3) {
+ niceFraction = 2;
+ } else if (fraction < 7) {
+ niceFraction = 5;
+ } else {
+ niceFraction = 10;
+ }
+ } else if (fraction <= 1.0) {
+ niceFraction = 1;
+ } else if (fraction <= 2) {
+ niceFraction = 2;
+ } else if (fraction <= 5) {
+ niceFraction = 5;
+ } else {
+ niceFraction = 10;
+ }
+
+ return niceFraction * Math.pow(10, exponent);
+ };
+ // Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
+ helpers.requestAnimFrame = (function() {
+ if (typeof window === 'undefined') {
+ return function(callback) {
+ callback();
+ };
+ }
+ return window.requestAnimationFrame ||
+ window.webkitRequestAnimationFrame ||
+ window.mozRequestAnimationFrame ||
+ window.oRequestAnimationFrame ||
+ window.msRequestAnimationFrame ||
+ function(callback) {
+ return window.setTimeout(callback, 1000 / 60);
+ };
+ }());
+ // -- DOM methods
+ helpers.getRelativePosition = function(evt, chart) {
+ var mouseX, mouseY;
+ var e = evt.originalEvent || evt;
+ var canvas = evt.currentTarget || evt.srcElement;
+ var boundingRect = canvas.getBoundingClientRect();
+
+ var touches = e.touches;
+ if (touches && touches.length > 0) {
+ mouseX = touches[0].clientX;
+ mouseY = touches[0].clientY;
+
+ } else {
+ mouseX = e.clientX;
+ mouseY = e.clientY;
+ }
+
+ // Scale mouse coordinates into canvas coordinates
+ // by following the pattern laid out by 'jerryj' in the comments of
+ // http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
+ var paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left'));
+ var paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top'));
+ var paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right'));
+ var paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom'));
+ var width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;
+ var height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;
+
+ // We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However
+ // the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here
+ mouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);
+ mouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);
+
+ return {
+ x: mouseX,
+ y: mouseY
+ };
+
+ };
+
+ // Private helper function to convert max-width/max-height values that may be percentages into a number
+ function parseMaxStyle(styleValue, node, parentProperty) {
+ var valueInPixels;
+ if (typeof styleValue === 'string') {
+ valueInPixels = parseInt(styleValue, 10);
+
+ if (styleValue.indexOf('%') !== -1) {
+ // percentage * size in dimension
+ valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];
+ }
+ } else {
+ valueInPixels = styleValue;
+ }
+
+ return valueInPixels;
+ }
+
+ /**
+ * Returns if the given value contains an effective constraint.
+ * @private
+ */
+ function isConstrainedValue(value) {
+ return value !== undefined && value !== null && value !== 'none';
+ }
+
+ // Private helper to get a constraint dimension
+ // @param domNode : the node to check the constraint on
+ // @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight)
+ // @param percentageProperty : property of parent to use when calculating width as a percentage
+ // @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser
+ function getConstraintDimension(domNode, maxStyle, percentageProperty) {
+ var view = document.defaultView;
+ var parentNode = domNode.parentNode;
+ var constrainedNode = view.getComputedStyle(domNode)[maxStyle];
+ var constrainedContainer = view.getComputedStyle(parentNode)[maxStyle];
+ var hasCNode = isConstrainedValue(constrainedNode);
+ var hasCContainer = isConstrainedValue(constrainedContainer);
+ var infinity = Number.POSITIVE_INFINITY;
+
+ if (hasCNode || hasCContainer) {
+ return Math.min(
+ hasCNode ? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity,
+ hasCContainer ? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity);
+ }
+
+ return 'none';
+ }
+ // returns Number or undefined if no constraint
+ helpers.getConstraintWidth = function(domNode) {
+ return getConstraintDimension(domNode, 'max-width', 'clientWidth');
+ };
+ // returns Number or undefined if no constraint
+ helpers.getConstraintHeight = function(domNode) {
+ return getConstraintDimension(domNode, 'max-height', 'clientHeight');
+ };
+ helpers.getMaximumWidth = function(domNode) {
+ var container = domNode.parentNode;
+ if (!container) {
+ return domNode.clientWidth;
+ }
+
+ var paddingLeft = parseInt(helpers.getStyle(container, 'padding-left'), 10);
+ var paddingRight = parseInt(helpers.getStyle(container, 'padding-right'), 10);
+ var w = container.clientWidth - paddingLeft - paddingRight;
+ var cw = helpers.getConstraintWidth(domNode);
+ return isNaN(cw) ? w : Math.min(w, cw);
+ };
+ helpers.getMaximumHeight = function(domNode) {
+ var container = domNode.parentNode;
+ if (!container) {
+ return domNode.clientHeight;
+ }
+
+ var paddingTop = parseInt(helpers.getStyle(container, 'padding-top'), 10);
+ var paddingBottom = parseInt(helpers.getStyle(container, 'padding-bottom'), 10);
+ var h = container.clientHeight - paddingTop - paddingBottom;
+ var ch = helpers.getConstraintHeight(domNode);
+ return isNaN(ch) ? h : Math.min(h, ch);
+ };
+ helpers.getStyle = function(el, property) {
+ return el.currentStyle ?
+ el.currentStyle[property] :
+ document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
+ };
+ helpers.retinaScale = function(chart, forceRatio) {
+ var pixelRatio = chart.currentDevicePixelRatio = forceRatio || window.devicePixelRatio || 1;
+ if (pixelRatio === 1) {
+ return;
+ }
+
+ var canvas = chart.canvas;
+ var height = chart.height;
+ var width = chart.width;
+
+ canvas.height = height * pixelRatio;
+ canvas.width = width * pixelRatio;
+ chart.ctx.scale(pixelRatio, pixelRatio);
+
+ // If no style has been set on the canvas, the render size is used as display size,
+ // making the chart visually bigger, so let's enforce it to the "correct" values.
+ // See https://github.com/chartjs/Chart.js/issues/3575
+ if (!canvas.style.height && !canvas.style.width) {
+ canvas.style.height = height + 'px';
+ canvas.style.width = width + 'px';
+ }
+ };
+ // -- Canvas methods
+ helpers.fontString = function(pixelSize, fontStyle, fontFamily) {
+ return fontStyle + ' ' + pixelSize + 'px ' + fontFamily;
+ };
+ helpers.longestText = function(ctx, font, arrayOfThings, cache) {
+ cache = cache || {};
+ var data = cache.data = cache.data || {};
+ var gc = cache.garbageCollect = cache.garbageCollect || [];
+
+ if (cache.font !== font) {
+ data = cache.data = {};
+ gc = cache.garbageCollect = [];
+ cache.font = font;
+ }
+
+ ctx.font = font;
+ var longest = 0;
+ helpers.each(arrayOfThings, function(thing) {
+ // Undefined strings and arrays should not be measured
+ if (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) {
+ longest = helpers.measureText(ctx, data, gc, longest, thing);
+ } else if (helpers.isArray(thing)) {
+ // if it is an array lets measure each element
+ // to do maybe simplify this function a bit so we can do this more recursively?
+ helpers.each(thing, function(nestedThing) {
+ // Undefined strings and arrays should not be measured
+ if (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) {
+ longest = helpers.measureText(ctx, data, gc, longest, nestedThing);
+ }
+ });
+ }
+ });
+
+ var gcLen = gc.length / 2;
+ if (gcLen > arrayOfThings.length) {
+ for (var i = 0; i < gcLen; i++) {
+ delete data[gc[i]];
+ }
+ gc.splice(0, gcLen);
+ }
+ return longest;
+ };
+ helpers.measureText = function(ctx, data, gc, longest, string) {
+ var textWidth = data[string];
+ if (!textWidth) {
+ textWidth = data[string] = ctx.measureText(string).width;
+ gc.push(string);
+ }
+ if (textWidth > longest) {
+ longest = textWidth;
+ }
+ return longest;
+ };
+ helpers.numberOfLabelLines = function(arrayOfThings) {
+ var numberOfLines = 1;
+ helpers.each(arrayOfThings, function(thing) {
+ if (helpers.isArray(thing)) {
+ if (thing.length > numberOfLines) {
+ numberOfLines = thing.length;
+ }
+ }
+ });
+ return numberOfLines;
+ };
+
+ helpers.color = !color ?
+ function(value) {
+ console.error('Color.js not found!');
+ return value;
+ } :
+ function(value) {
+ /* global CanvasGradient */
+ if (value instanceof CanvasGradient) {
+ value = defaults.global.defaultColor;
+ }
+
+ return color(value);
+ };
+
+ helpers.getHoverColor = function(colorValue) {
+ /* global CanvasPattern */
+ return (colorValue instanceof CanvasPattern) ?
+ colorValue :
+ helpers.color(colorValue).saturate(0.5).darken(0.1).rgbString();
+ };
+};
+
+},{"25":25,"3":3,"45":45}],28:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+
+/**
+ * Helper function to get relative position for an event
+ * @param {Event|IEvent} event - The event to get the position for
+ * @param {Chart} chart - The chart
+ * @returns {Point} the event position
+ */
+function getRelativePosition(e, chart) {
+ if (e.native) {
+ return {
+ x: e.x,
+ y: e.y
+ };
+ }
+
+ return helpers.getRelativePosition(e, chart);
+}
+
+/**
+ * Helper function to traverse all of the visible elements in the chart
+ * @param chart {chart} the chart
+ * @param handler {Function} the callback to execute for each visible item
+ */
+function parseVisibleItems(chart, handler) {
+ var datasets = chart.data.datasets;
+ var meta, i, j, ilen, jlen;
+
+ for (i = 0, ilen = datasets.length; i < ilen; ++i) {
+ if (!chart.isDatasetVisible(i)) {
+ continue;
+ }
+
+ meta = chart.getDatasetMeta(i);
+ for (j = 0, jlen = meta.data.length; j < jlen; ++j) {
+ var element = meta.data[j];
+ if (!element._view.skip) {
+ handler(element);
+ }
+ }
+ }
+}
+
+/**
+ * Helper function to get the items that intersect the event position
+ * @param items {ChartElement[]} elements to filter
+ * @param position {Point} the point to be nearest to
+ * @return {ChartElement[]} the nearest items
+ */
+function getIntersectItems(chart, position) {
+ var elements = [];
+
+ parseVisibleItems(chart, function(element) {
+ if (element.inRange(position.x, position.y)) {
+ elements.push(element);
+ }
+ });
+
+ return elements;
+}
+
+/**
+ * Helper function to get the items nearest to the event position considering all visible items in teh chart
+ * @param chart {Chart} the chart to look at elements from
+ * @param position {Point} the point to be nearest to
+ * @param intersect {Boolean} if true, only consider items that intersect the position
+ * @param distanceMetric {Function} function to provide the distance between points
+ * @return {ChartElement[]} the nearest items
+ */
+function getNearestItems(chart, position, intersect, distanceMetric) {
+ var minDistance = Number.POSITIVE_INFINITY;
+ var nearestItems = [];
+
+ parseVisibleItems(chart, function(element) {
+ if (intersect && !element.inRange(position.x, position.y)) {
+ return;
+ }
+
+ var center = element.getCenterPoint();
+ var distance = distanceMetric(position, center);
+
+ if (distance < minDistance) {
+ nearestItems = [element];
+ minDistance = distance;
+ } else if (distance === minDistance) {
+ // Can have multiple items at the same distance in which case we sort by size
+ nearestItems.push(element);
+ }
+ });
+
+ return nearestItems;
+}
+
+/**
+ * Get a distance metric function for two points based on the
+ * axis mode setting
+ * @param {String} axis the axis mode. x|y|xy
+ */
+function getDistanceMetricForAxis(axis) {
+ var useX = axis.indexOf('x') !== -1;
+ var useY = axis.indexOf('y') !== -1;
+
+ return function(pt1, pt2) {
+ var deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0;
+ var deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0;
+ return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
+ };
+}
+
+function indexMode(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ // Default axis for index mode is 'x' to match old behaviour
+ options.axis = options.axis || 'x';
+ var distanceMetric = getDistanceMetricForAxis(options.axis);
+ var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);
+ var elements = [];
+
+ if (!items.length) {
+ return [];
+ }
+
+ chart.data.datasets.forEach(function(dataset, datasetIndex) {
+ if (chart.isDatasetVisible(datasetIndex)) {
+ var meta = chart.getDatasetMeta(datasetIndex);
+ var element = meta.data[items[0]._index];
+
+ // don't count items that are skipped (null data)
+ if (element && !element._view.skip) {
+ elements.push(element);
+ }
+ }
+ });
+
+ return elements;
+}
+
+/**
+ * @interface IInteractionOptions
+ */
+/**
+ * If true, only consider items that intersect the point
+ * @name IInterfaceOptions#boolean
+ * @type Boolean
+ */
+
+/**
+ * Contains interaction related functions
+ * @namespace Chart.Interaction
+ */
+module.exports = {
+ // Helper function for different modes
+ modes: {
+ single: function(chart, e) {
+ var position = getRelativePosition(e, chart);
+ var elements = [];
+
+ parseVisibleItems(chart, function(element) {
+ if (element.inRange(position.x, position.y)) {
+ elements.push(element);
+ return elements;
+ }
+ });
+
+ return elements.slice(0, 1);
+ },
+
+ /**
+ * @function Chart.Interaction.modes.label
+ * @deprecated since version 2.4.0
+ * @todo remove at version 3
+ * @private
+ */
+ label: indexMode,
+
+ /**
+ * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something
+ * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item
+ * @function Chart.Interaction.modes.index
+ * @since v2.4.0
+ * @param chart {chart} the chart we are returning items from
+ * @param e {Event} the event we are find things at
+ * @param options {IInteractionOptions} options to use during interaction
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ index: indexMode,
+
+ /**
+ * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something
+ * If the options.intersect is false, we find the nearest item and return the items in that dataset
+ * @function Chart.Interaction.modes.dataset
+ * @param chart {chart} the chart we are returning items from
+ * @param e {Event} the event we are find things at
+ * @param options {IInteractionOptions} options to use during interaction
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ dataset: function(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ options.axis = options.axis || 'xy';
+ var distanceMetric = getDistanceMetricForAxis(options.axis);
+ var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);
+
+ if (items.length > 0) {
+ items = chart.getDatasetMeta(items[0]._datasetIndex).data;
+ }
+
+ return items;
+ },
+
+ /**
+ * @function Chart.Interaction.modes.x-axis
+ * @deprecated since version 2.4.0. Use index mode and intersect == true
+ * @todo remove at version 3
+ * @private
+ */
+ 'x-axis': function(chart, e) {
+ return indexMode(chart, e, {intersect: false});
+ },
+
+ /**
+ * Point mode returns all elements that hit test based on the event position
+ * of the event
+ * @function Chart.Interaction.modes.intersect
+ * @param chart {chart} the chart we are returning items from
+ * @param e {Event} the event we are find things at
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ point: function(chart, e) {
+ var position = getRelativePosition(e, chart);
+ return getIntersectItems(chart, position);
+ },
+
+ /**
+ * nearest mode returns the element closest to the point
+ * @function Chart.Interaction.modes.intersect
+ * @param chart {chart} the chart we are returning items from
+ * @param e {Event} the event we are find things at
+ * @param options {IInteractionOptions} options to use
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ nearest: function(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ options.axis = options.axis || 'xy';
+ var distanceMetric = getDistanceMetricForAxis(options.axis);
+ var nearestItems = getNearestItems(chart, position, options.intersect, distanceMetric);
+
+ // We have multiple items at the same distance from the event. Now sort by smallest
+ if (nearestItems.length > 1) {
+ nearestItems.sort(function(a, b) {
+ var sizeA = a.getArea();
+ var sizeB = b.getArea();
+ var ret = sizeA - sizeB;
+
+ if (ret === 0) {
+ // if equal sort by dataset index
+ ret = a._datasetIndex - b._datasetIndex;
+ }
+
+ return ret;
+ });
+ }
+
+ // Return only 1 item
+ return nearestItems.slice(0, 1);
+ },
+
+ /**
+ * x mode returns the elements that hit-test at the current x coordinate
+ * @function Chart.Interaction.modes.x
+ * @param chart {chart} the chart we are returning items from
+ * @param e {Event} the event we are find things at
+ * @param options {IInteractionOptions} options to use
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ x: function(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ var items = [];
+ var intersectsItem = false;
+
+ parseVisibleItems(chart, function(element) {
+ if (element.inXRange(position.x)) {
+ items.push(element);
+ }
+
+ if (element.inRange(position.x, position.y)) {
+ intersectsItem = true;
+ }
+ });
+
+ // If we want to trigger on an intersect and we don't have any items
+ // that intersect the position, return nothing
+ if (options.intersect && !intersectsItem) {
+ items = [];
+ }
+ return items;
+ },
+
+ /**
+ * y mode returns the elements that hit-test at the current y coordinate
+ * @function Chart.Interaction.modes.y
+ * @param chart {chart} the chart we are returning items from
+ * @param e {Event} the event we are find things at
+ * @param options {IInteractionOptions} options to use
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ y: function(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ var items = [];
+ var intersectsItem = false;
+
+ parseVisibleItems(chart, function(element) {
+ if (element.inYRange(position.y)) {
+ items.push(element);
+ }
+
+ if (element.inRange(position.x, position.y)) {
+ intersectsItem = true;
+ }
+ });
+
+ // If we want to trigger on an intersect and we don't have any items
+ // that intersect the position, return nothing
+ if (options.intersect && !intersectsItem) {
+ items = [];
+ }
+ return items;
+ }
+ }
+};
+
+},{"45":45}],29:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+
+defaults._set('global', {
+ responsive: true,
+ responsiveAnimationDuration: 0,
+ maintainAspectRatio: true,
+ events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
+ hover: {
+ onHover: null,
+ mode: 'nearest',
+ intersect: true,
+ animationDuration: 400
+ },
+ onClick: null,
+ defaultColor: 'rgba(0,0,0,0.1)',
+ defaultFontColor: '#666',
+ defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
+ defaultFontSize: 12,
+ defaultFontStyle: 'normal',
+ showLines: true,
+
+ // Element defaults defined in element extensions
+ elements: {},
+
+ // Layout options such as padding
+ layout: {
+ padding: {
+ top: 0,
+ right: 0,
+ bottom: 0,
+ left: 0
+ }
+ }
+});
+
+module.exports = function() {
+
+ // Occupy the global variable of Chart, and create a simple base class
+ var Chart = function(item, config) {
+ this.construct(item, config);
+ return this;
+ };
+
+ Chart.Chart = Chart;
+
+ return Chart;
+};
+
+},{"25":25}],30:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+
+function filterByPosition(array, position) {
+ return helpers.where(array, function(v) {
+ return v.position === position;
+ });
+}
+
+function sortByWeight(array, reverse) {
+ array.forEach(function(v, i) {
+ v._tmpIndex_ = i;
+ return v;
+ });
+ array.sort(function(a, b) {
+ var v0 = reverse ? b : a;
+ var v1 = reverse ? a : b;
+ return v0.weight === v1.weight ?
+ v0._tmpIndex_ - v1._tmpIndex_ :
+ v0.weight - v1.weight;
+ });
+ array.forEach(function(v) {
+ delete v._tmpIndex_;
+ });
+}
+
+/**
+ * @interface ILayoutItem
+ * @prop {String} position - The position of the item in the chart layout. Possible values are
+ * 'left', 'top', 'right', 'bottom', and 'chartArea'
+ * @prop {Number} weight - The weight used to sort the item. Higher weights are further away from the chart area
+ * @prop {Boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down
+ * @prop {Function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom)
+ * @prop {Function} update - Takes two parameters: width and height. Returns size of item
+ * @prop {Function} getPadding - Returns an object with padding on the edges
+ * @prop {Number} width - Width of item. Must be valid after update()
+ * @prop {Number} height - Height of item. Must be valid after update()
+ * @prop {Number} left - Left edge of the item. Set by layout system and cannot be used in update
+ * @prop {Number} top - Top edge of the item. Set by layout system and cannot be used in update
+ * @prop {Number} right - Right edge of the item. Set by layout system and cannot be used in update
+ * @prop {Number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update
+ */
+
+// The layout service is very self explanatory. It's responsible for the layout within a chart.
+// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need
+// It is this service's responsibility of carrying out that layout.
+module.exports = {
+ defaults: {},
+
+ /**
+ * Register a box to a chart.
+ * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.
+ * @param {Chart} chart - the chart to use
+ * @param {ILayoutItem} item - the item to add to be layed out
+ */
+ addBox: function(chart, item) {
+ if (!chart.boxes) {
+ chart.boxes = [];
+ }
+
+ // initialize item with default values
+ item.fullWidth = item.fullWidth || false;
+ item.position = item.position || 'top';
+ item.weight = item.weight || 0;
+
+ chart.boxes.push(item);
+ },
+
+ /**
+ * Remove a layoutItem from a chart
+ * @param {Chart} chart - the chart to remove the box from
+ * @param {Object} layoutItem - the item to remove from the layout
+ */
+ removeBox: function(chart, layoutItem) {
+ var index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1;
+ if (index !== -1) {
+ chart.boxes.splice(index, 1);
+ }
+ },
+
+ /**
+ * Sets (or updates) options on the given `item`.
+ * @param {Chart} chart - the chart in which the item lives (or will be added to)
+ * @param {Object} item - the item to configure with the given options
+ * @param {Object} options - the new item options.
+ */
+ configure: function(chart, item, options) {
+ var props = ['fullWidth', 'position', 'weight'];
+ var ilen = props.length;
+ var i = 0;
+ var prop;
+
+ for (; i < ilen; ++i) {
+ prop = props[i];
+ if (options.hasOwnProperty(prop)) {
+ item[prop] = options[prop];
+ }
+ }
+ },
+
+ /**
+ * Fits boxes of the given chart into the given size by having each box measure itself
+ * then running a fitting algorithm
+ * @param {Chart} chart - the chart
+ * @param {Number} width - the width to fit into
+ * @param {Number} height - the height to fit into
+ */
+ update: function(chart, width, height) {
+ if (!chart) {
+ return;
+ }
+
+ var layoutOptions = chart.options.layout || {};
+ var padding = helpers.options.toPadding(layoutOptions.padding);
+ var leftPadding = padding.left;
+ var rightPadding = padding.right;
+ var topPadding = padding.top;
+ var bottomPadding = padding.bottom;
+
+ var leftBoxes = filterByPosition(chart.boxes, 'left');
+ var rightBoxes = filterByPosition(chart.boxes, 'right');
+ var topBoxes = filterByPosition(chart.boxes, 'top');
+ var bottomBoxes = filterByPosition(chart.boxes, 'bottom');
+ var chartAreaBoxes = filterByPosition(chart.boxes, 'chartArea');
+
+ // Sort boxes by weight. A higher weight is further away from the chart area
+ sortByWeight(leftBoxes, true);
+ sortByWeight(rightBoxes, false);
+ sortByWeight(topBoxes, true);
+ sortByWeight(bottomBoxes, false);
+
+ // Essentially we now have any number of boxes on each of the 4 sides.
+ // Our canvas looks like the following.
+ // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and
+ // B1 is the bottom axis
+ // There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays
+ // These locations are single-box locations only, when trying to register a chartArea location that is already taken,
+ // an error will be thrown.
+ //
+ // |----------------------------------------------------|
+ // | T1 (Full Width) |
+ // |----------------------------------------------------|
+ // | | | T2 | |
+ // | |----|-------------------------------------|----|
+ // | | | C1 | | C2 | |
+ // | | |----| |----| |
+ // | | | | |
+ // | L1 | L2 | ChartArea (C0) | R1 |
+ // | | | | |
+ // | | |----| |----| |
+ // | | | C3 | | C4 | |
+ // | |----|-------------------------------------|----|
+ // | | | B1 | |
+ // |----------------------------------------------------|
+ // | B2 (Full Width) |
+ // |----------------------------------------------------|
+ //
+ // What we do to find the best sizing, we do the following
+ // 1. Determine the minimum size of the chart area.
+ // 2. Split the remaining width equally between each vertical axis
+ // 3. Split the remaining height equally between each horizontal axis
+ // 4. Give each layout the maximum size it can be. The layout will return it's minimum size
+ // 5. Adjust the sizes of each axis based on it's minimum reported size.
+ // 6. Refit each axis
+ // 7. Position each axis in the final location
+ // 8. Tell the chart the final location of the chart area
+ // 9. Tell any axes that overlay the chart area the positions of the chart area
+
+ // Step 1
+ var chartWidth = width - leftPadding - rightPadding;
+ var chartHeight = height - topPadding - bottomPadding;
+ var chartAreaWidth = chartWidth / 2; // min 50%
+ var chartAreaHeight = chartHeight / 2; // min 50%
+
+ // Step 2
+ var verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);
+
+ // Step 3
+ var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);
+
+ // Step 4
+ var maxChartAreaWidth = chartWidth;
+ var maxChartAreaHeight = chartHeight;
+ var minBoxSizes = [];
+
+ function getMinimumBoxSize(box) {
+ var minSize;
+ var isHorizontal = box.isHorizontal();
+
+ if (isHorizontal) {
+ minSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);
+ maxChartAreaHeight -= minSize.height;
+ } else {
+ minSize = box.update(verticalBoxWidth, maxChartAreaHeight);
+ maxChartAreaWidth -= minSize.width;
+ }
+
+ minBoxSizes.push({
+ horizontal: isHorizontal,
+ minSize: minSize,
+ box: box,
+ });
+ }
+
+ helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);
+
+ // If a horizontal box has padding, we move the left boxes over to avoid ugly charts (see issue #2478)
+ var maxHorizontalLeftPadding = 0;
+ var maxHorizontalRightPadding = 0;
+ var maxVerticalTopPadding = 0;
+ var maxVerticalBottomPadding = 0;
+
+ helpers.each(topBoxes.concat(bottomBoxes), function(horizontalBox) {
+ if (horizontalBox.getPadding) {
+ var boxPadding = horizontalBox.getPadding();
+ maxHorizontalLeftPadding = Math.max(maxHorizontalLeftPadding, boxPadding.left);
+ maxHorizontalRightPadding = Math.max(maxHorizontalRightPadding, boxPadding.right);
+ }
+ });
+
+ helpers.each(leftBoxes.concat(rightBoxes), function(verticalBox) {
+ if (verticalBox.getPadding) {
+ var boxPadding = verticalBox.getPadding();
+ maxVerticalTopPadding = Math.max(maxVerticalTopPadding, boxPadding.top);
+ maxVerticalBottomPadding = Math.max(maxVerticalBottomPadding, boxPadding.bottom);
+ }
+ });
+
+ // At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could
+ // be if the axes are drawn at their minimum sizes.
+ // Steps 5 & 6
+ var totalLeftBoxesWidth = leftPadding;
+ var totalRightBoxesWidth = rightPadding;
+ var totalTopBoxesHeight = topPadding;
+ var totalBottomBoxesHeight = bottomPadding;
+
+ // Function to fit a box
+ function fitBox(box) {
+ var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) {
+ return minBox.box === box;
+ });
+
+ if (minBoxSize) {
+ if (box.isHorizontal()) {
+ var scaleMargin = {
+ left: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding),
+ right: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding),
+ top: 0,
+ bottom: 0
+ };
+
+ // Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends
+ // on the margin. Sometimes they need to increase in size slightly
+ box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);
+ } else {
+ box.update(minBoxSize.minSize.width, maxChartAreaHeight);
+ }
+ }
+ }
+
+ // Update, and calculate the left and right margins for the horizontal boxes
+ helpers.each(leftBoxes.concat(rightBoxes), fitBox);
+
+ helpers.each(leftBoxes, function(box) {
+ totalLeftBoxesWidth += box.width;
+ });
+
+ helpers.each(rightBoxes, function(box) {
+ totalRightBoxesWidth += box.width;
+ });
+
+ // Set the Left and Right margins for the horizontal boxes
+ helpers.each(topBoxes.concat(bottomBoxes), fitBox);
+
+ // Figure out how much margin is on the top and bottom of the vertical boxes
+ helpers.each(topBoxes, function(box) {
+ totalTopBoxesHeight += box.height;
+ });
+
+ helpers.each(bottomBoxes, function(box) {
+ totalBottomBoxesHeight += box.height;
+ });
+
+ function finalFitVerticalBox(box) {
+ var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) {
+ return minSize.box === box;
+ });
+
+ var scaleMargin = {
+ left: 0,
+ right: 0,
+ top: totalTopBoxesHeight,
+ bottom: totalBottomBoxesHeight
+ };
+
+ if (minBoxSize) {
+ box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);
+ }
+ }
+
+ // Let the left layout know the final margin
+ helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);
+
+ // Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)
+ totalLeftBoxesWidth = leftPadding;
+ totalRightBoxesWidth = rightPadding;
+ totalTopBoxesHeight = topPadding;
+ totalBottomBoxesHeight = bottomPadding;
+
+ helpers.each(leftBoxes, function(box) {
+ totalLeftBoxesWidth += box.width;
+ });
+
+ helpers.each(rightBoxes, function(box) {
+ totalRightBoxesWidth += box.width;
+ });
+
+ helpers.each(topBoxes, function(box) {
+ totalTopBoxesHeight += box.height;
+ });
+ helpers.each(bottomBoxes, function(box) {
+ totalBottomBoxesHeight += box.height;
+ });
+
+ // We may be adding some padding to account for rotated x axis labels
+ var leftPaddingAddition = Math.max(maxHorizontalLeftPadding - totalLeftBoxesWidth, 0);
+ totalLeftBoxesWidth += leftPaddingAddition;
+ totalRightBoxesWidth += Math.max(maxHorizontalRightPadding - totalRightBoxesWidth, 0);
+
+ var topPaddingAddition = Math.max(maxVerticalTopPadding - totalTopBoxesHeight, 0);
+ totalTopBoxesHeight += topPaddingAddition;
+ totalBottomBoxesHeight += Math.max(maxVerticalBottomPadding - totalBottomBoxesHeight, 0);
+
+ // Figure out if our chart area changed. This would occur if the dataset layout label rotation
+ // changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do
+ // without calling `fit` again
+ var newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;
+ var newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;
+
+ if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {
+ helpers.each(leftBoxes, function(box) {
+ box.height = newMaxChartAreaHeight;
+ });
+
+ helpers.each(rightBoxes, function(box) {
+ box.height = newMaxChartAreaHeight;
+ });
+
+ helpers.each(topBoxes, function(box) {
+ if (!box.fullWidth) {
+ box.width = newMaxChartAreaWidth;
+ }
+ });
+
+ helpers.each(bottomBoxes, function(box) {
+ if (!box.fullWidth) {
+ box.width = newMaxChartAreaWidth;
+ }
+ });
+
+ maxChartAreaHeight = newMaxChartAreaHeight;
+ maxChartAreaWidth = newMaxChartAreaWidth;
+ }
+
+ // Step 7 - Position the boxes
+ var left = leftPadding + leftPaddingAddition;
+ var top = topPadding + topPaddingAddition;
+
+ function placeBox(box) {
+ if (box.isHorizontal()) {
+ box.left = box.fullWidth ? leftPadding : totalLeftBoxesWidth;
+ box.right = box.fullWidth ? width - rightPadding : totalLeftBoxesWidth + maxChartAreaWidth;
+ box.top = top;
+ box.bottom = top + box.height;
+
+ // Move to next point
+ top = box.bottom;
+
+ } else {
+
+ box.left = left;
+ box.right = left + box.width;
+ box.top = totalTopBoxesHeight;
+ box.bottom = totalTopBoxesHeight + maxChartAreaHeight;
+
+ // Move to next point
+ left = box.right;
+ }
+ }
+
+ helpers.each(leftBoxes.concat(topBoxes), placeBox);
+
+ // Account for chart width and height
+ left += maxChartAreaWidth;
+ top += maxChartAreaHeight;
+
+ helpers.each(rightBoxes, placeBox);
+ helpers.each(bottomBoxes, placeBox);
+
+ // Step 8
+ chart.chartArea = {
+ left: totalLeftBoxesWidth,
+ top: totalTopBoxesHeight,
+ right: totalLeftBoxesWidth + maxChartAreaWidth,
+ bottom: totalTopBoxesHeight + maxChartAreaHeight
+ };
+
+ // Step 9
+ helpers.each(chartAreaBoxes, function(box) {
+ box.left = chart.chartArea.left;
+ box.top = chart.chartArea.top;
+ box.right = chart.chartArea.right;
+ box.bottom = chart.chartArea.bottom;
+
+ box.update(maxChartAreaWidth, maxChartAreaHeight);
+ });
+ }
+};
+
+},{"45":45}],31:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var helpers = require(45);
+
+defaults._set('global', {
+ plugins: {}
+});
+
+/**
+ * The plugin service singleton
+ * @namespace Chart.plugins
+ * @since 2.1.0
+ */
+module.exports = {
+ /**
+ * Globally registered plugins.
+ * @private
+ */
+ _plugins: [],
+
+ /**
+ * This identifier is used to invalidate the descriptors cache attached to each chart
+ * when a global plugin is registered or unregistered. In this case, the cache ID is
+ * incremented and descriptors are regenerated during following API calls.
+ * @private
+ */
+ _cacheId: 0,
+
+ /**
+ * Registers the given plugin(s) if not already registered.
+ * @param {Array|Object} plugins plugin instance(s).
+ */
+ register: function(plugins) {
+ var p = this._plugins;
+ ([]).concat(plugins).forEach(function(plugin) {
+ if (p.indexOf(plugin) === -1) {
+ p.push(plugin);
+ }
+ });
+
+ this._cacheId++;
+ },
+
+ /**
+ * Unregisters the given plugin(s) only if registered.
+ * @param {Array|Object} plugins plugin instance(s).
+ */
+ unregister: function(plugins) {
+ var p = this._plugins;
+ ([]).concat(plugins).forEach(function(plugin) {
+ var idx = p.indexOf(plugin);
+ if (idx !== -1) {
+ p.splice(idx, 1);
+ }
+ });
+
+ this._cacheId++;
+ },
+
+ /**
+ * Remove all registered plugins.
+ * @since 2.1.5
+ */
+ clear: function() {
+ this._plugins = [];
+ this._cacheId++;
+ },
+
+ /**
+ * Returns the number of registered plugins?
+ * @returns {Number}
+ * @since 2.1.5
+ */
+ count: function() {
+ return this._plugins.length;
+ },
+
+ /**
+ * Returns all registered plugin instances.
+ * @returns {Array} array of plugin objects.
+ * @since 2.1.5
+ */
+ getAll: function() {
+ return this._plugins;
+ },
+
+ /**
+ * Calls enabled plugins for `chart` on the specified hook and with the given args.
+ * This method immediately returns as soon as a plugin explicitly returns false. The
+ * returned value can be used, for instance, to interrupt the current action.
+ * @param {Object} chart - The chart instance for which plugins should be called.
+ * @param {String} hook - The name of the plugin method to call (e.g. 'beforeUpdate').
+ * @param {Array} [args] - Extra arguments to apply to the hook call.
+ * @returns {Boolean} false if any of the plugins return false, else returns true.
+ */
+ notify: function(chart, hook, args) {
+ var descriptors = this.descriptors(chart);
+ var ilen = descriptors.length;
+ var i, descriptor, plugin, params, method;
+
+ for (i = 0; i < ilen; ++i) {
+ descriptor = descriptors[i];
+ plugin = descriptor.plugin;
+ method = plugin[hook];
+ if (typeof method === 'function') {
+ params = [chart].concat(args || []);
+ params.push(descriptor.options);
+ if (method.apply(plugin, params) === false) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ },
+
+ /**
+ * Returns descriptors of enabled plugins for the given chart.
+ * @returns {Array} [{ plugin, options }]
+ * @private
+ */
+ descriptors: function(chart) {
+ var cache = chart.$plugins || (chart.$plugins = {});
+ if (cache.id === this._cacheId) {
+ return cache.descriptors;
+ }
+
+ var plugins = [];
+ var descriptors = [];
+ var config = (chart && chart.config) || {};
+ var options = (config.options && config.options.plugins) || {};
+
+ this._plugins.concat(config.plugins || []).forEach(function(plugin) {
+ var idx = plugins.indexOf(plugin);
+ if (idx !== -1) {
+ return;
+ }
+
+ var id = plugin.id;
+ var opts = options[id];
+ if (opts === false) {
+ return;
+ }
+
+ if (opts === true) {
+ opts = helpers.clone(defaults.global.plugins[id]);
+ }
+
+ plugins.push(plugin);
+ descriptors.push({
+ plugin: plugin,
+ options: opts || {}
+ });
+ });
+
+ cache.descriptors = descriptors;
+ cache.id = this._cacheId;
+ return descriptors;
+ },
+
+ /**
+ * Invalidates cache for the given chart: descriptors hold a reference on plugin option,
+ * but in some cases, this reference can be changed by the user when updating options.
+ * https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167
+ * @private
+ */
+ _invalidate: function(chart) {
+ delete chart.$plugins;
+ }
+};
+
+/**
+ * Plugin extension hooks.
+ * @interface IPlugin
+ * @since 2.1.0
+ */
+/**
+ * @method IPlugin#beforeInit
+ * @desc Called before initializing `chart`.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#afterInit
+ * @desc Called after `chart` has been initialized and before the first update.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeUpdate
+ * @desc Called before updating `chart`. If any plugin returns `false`, the update
+ * is cancelled (and thus subsequent render(s)) until another `update` is triggered.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart update.
+ */
+/**
+ * @method IPlugin#afterUpdate
+ * @desc Called after `chart` has been updated and before rendering. Note that this
+ * hook will not be called if the chart update has been previously cancelled.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeDatasetsUpdate
+ * @desc Called before updating the `chart` datasets. If any plugin returns `false`,
+ * the datasets update is cancelled until another `update` is triggered.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} false to cancel the datasets update.
+ * @since version 2.1.5
+*/
+/**
+ * @method IPlugin#afterDatasetsUpdate
+ * @desc Called after the `chart` datasets have been updated. Note that this hook
+ * will not be called if the datasets update has been previously cancelled.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ * @since version 2.1.5
+ */
+/**
+ * @method IPlugin#beforeDatasetUpdate
+ * @desc Called before updating the `chart` dataset at the given `args.index`. If any plugin
+ * returns `false`, the datasets update is cancelled until another `update` is triggered.
+ * @param {Chart} chart - The chart instance.
+ * @param {Object} args - The call arguments.
+ * @param {Number} args.index - The dataset index.
+ * @param {Object} args.meta - The dataset metadata.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart datasets drawing.
+ */
+/**
+ * @method IPlugin#afterDatasetUpdate
+ * @desc Called after the `chart` datasets at the given `args.index` has been updated. Note
+ * that this hook will not be called if the datasets update has been previously cancelled.
+ * @param {Chart} chart - The chart instance.
+ * @param {Object} args - The call arguments.
+ * @param {Number} args.index - The dataset index.
+ * @param {Object} args.meta - The dataset metadata.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeLayout
+ * @desc Called before laying out `chart`. If any plugin returns `false`,
+ * the layout update is cancelled until another `update` is triggered.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart layout.
+ */
+/**
+ * @method IPlugin#afterLayout
+ * @desc Called after the `chart` has been layed out. Note that this hook will not
+ * be called if the layout update has been previously cancelled.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeRender
+ * @desc Called before rendering `chart`. If any plugin returns `false`,
+ * the rendering is cancelled until another `render` is triggered.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart rendering.
+ */
+/**
+ * @method IPlugin#afterRender
+ * @desc Called after the `chart` has been fully rendered (and animation completed). Note
+ * that this hook will not be called if the rendering has been previously cancelled.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeDraw
+ * @desc Called before drawing `chart` at every animation frame specified by the given
+ * easing value. If any plugin returns `false`, the frame drawing is cancelled until
+ * another `render` is triggered.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart drawing.
+ */
+/**
+ * @method IPlugin#afterDraw
+ * @desc Called after the `chart` has been drawn for the specific easing value. Note
+ * that this hook will not be called if the drawing has been previously cancelled.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeDatasetsDraw
+ * @desc Called before drawing the `chart` datasets. If any plugin returns `false`,
+ * the datasets drawing is cancelled until another `render` is triggered.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart datasets drawing.
+ */
+/**
+ * @method IPlugin#afterDatasetsDraw
+ * @desc Called after the `chart` datasets have been drawn. Note that this hook
+ * will not be called if the datasets drawing has been previously cancelled.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeDatasetDraw
+ * @desc Called before drawing the `chart` dataset at the given `args.index` (datasets
+ * are drawn in the reverse order). If any plugin returns `false`, the datasets drawing
+ * is cancelled until another `render` is triggered.
+ * @param {Chart} chart - The chart instance.
+ * @param {Object} args - The call arguments.
+ * @param {Number} args.index - The dataset index.
+ * @param {Object} args.meta - The dataset metadata.
+ * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart datasets drawing.
+ */
+/**
+ * @method IPlugin#afterDatasetDraw
+ * @desc Called after the `chart` datasets at the given `args.index` have been drawn
+ * (datasets are drawn in the reverse order). Note that this hook will not be called
+ * if the datasets drawing has been previously cancelled.
+ * @param {Chart} chart - The chart instance.
+ * @param {Object} args - The call arguments.
+ * @param {Number} args.index - The dataset index.
+ * @param {Object} args.meta - The dataset metadata.
+ * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeTooltipDraw
+ * @desc Called before drawing the `tooltip`. If any plugin returns `false`,
+ * the tooltip drawing is cancelled until another `render` is triggered.
+ * @param {Chart} chart - The chart instance.
+ * @param {Object} args - The call arguments.
+ * @param {Object} args.tooltip - The tooltip.
+ * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ * @returns {Boolean} `false` to cancel the chart tooltip drawing.
+ */
+/**
+ * @method IPlugin#afterTooltipDraw
+ * @desc Called after drawing the `tooltip`. Note that this hook will not
+ * be called if the tooltip drawing has been previously cancelled.
+ * @param {Chart} chart - The chart instance.
+ * @param {Object} args - The call arguments.
+ * @param {Object} args.tooltip - The tooltip.
+ * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#beforeEvent
+ * @desc Called before processing the specified `event`. If any plugin returns `false`,
+ * the event will be discarded.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {IEvent} event - The event object.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#afterEvent
+ * @desc Called after the `event` has been consumed. Note that this hook
+ * will not be called if the `event` has been previously discarded.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {IEvent} event - The event object.
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#resize
+ * @desc Called after the chart as been resized.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Number} size - The new canvas display size (eq. canvas.style width & height).
+ * @param {Object} options - The plugin options.
+ */
+/**
+ * @method IPlugin#destroy
+ * @desc Called after the chart as been destroyed.
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {Object} options - The plugin options.
+ */
+
+},{"25":25,"45":45}],32:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+var Ticks = require(34);
+
+defaults._set('scale', {
+ display: true,
+ position: 'left',
+ offset: false,
+
+ // grid line settings
+ gridLines: {
+ display: true,
+ color: 'rgba(0, 0, 0, 0.1)',
+ lineWidth: 1,
+ drawBorder: true,
+ drawOnChartArea: true,
+ drawTicks: true,
+ tickMarkLength: 10,
+ zeroLineWidth: 1,
+ zeroLineColor: 'rgba(0,0,0,0.25)',
+ zeroLineBorderDash: [],
+ zeroLineBorderDashOffset: 0.0,
+ offsetGridLines: false,
+ borderDash: [],
+ borderDashOffset: 0.0
+ },
+
+ // scale label
+ scaleLabel: {
+ // display property
+ display: false,
+
+ // actual label
+ labelString: '',
+
+ // line height
+ lineHeight: 1.2,
+
+ // top/bottom padding
+ padding: {
+ top: 4,
+ bottom: 4
+ }
+ },
+
+ // label settings
+ ticks: {
+ beginAtZero: false,
+ minRotation: 0,
+ maxRotation: 50,
+ mirror: false,
+ padding: 0,
+ reverse: false,
+ display: true,
+ autoSkip: true,
+ autoSkipPadding: 0,
+ labelOffset: 0,
+ // We pass through arrays to be rendered as multiline labels, we convert Others to strings here.
+ callback: Ticks.formatters.values,
+ minor: {},
+ major: {}
+ }
+});
+
+function labelsFromTicks(ticks) {
+ var labels = [];
+ var i, ilen;
+
+ for (i = 0, ilen = ticks.length; i < ilen; ++i) {
+ labels.push(ticks[i].label);
+ }
+
+ return labels;
+}
+
+function getLineValue(scale, index, offsetGridLines) {
+ var lineValue = scale.getPixelForTick(index);
+
+ if (offsetGridLines) {
+ if (index === 0) {
+ lineValue -= (scale.getPixelForTick(1) - lineValue) / 2;
+ } else {
+ lineValue -= (lineValue - scale.getPixelForTick(index - 1)) / 2;
+ }
+ }
+ return lineValue;
+}
+
+module.exports = function(Chart) {
+
+ function computeTextSize(context, tick, font) {
+ return helpers.isArray(tick) ?
+ helpers.longestText(context, font, tick) :
+ context.measureText(tick).width;
+ }
+
+ function parseFontOptions(options) {
+ var valueOrDefault = helpers.valueOrDefault;
+ var globalDefaults = defaults.global;
+ var size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize);
+ var style = valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle);
+ var family = valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily);
+
+ return {
+ size: size,
+ style: style,
+ family: family,
+ font: helpers.fontString(size, style, family)
+ };
+ }
+
+ function parseLineHeight(options) {
+ return helpers.options.toLineHeight(
+ helpers.valueOrDefault(options.lineHeight, 1.2),
+ helpers.valueOrDefault(options.fontSize, defaults.global.defaultFontSize));
+ }
+
+ Chart.Scale = Element.extend({
+ /**
+ * Get the padding needed for the scale
+ * @method getPadding
+ * @private
+ * @returns {Padding} the necessary padding
+ */
+ getPadding: function() {
+ var me = this;
+ return {
+ left: me.paddingLeft || 0,
+ top: me.paddingTop || 0,
+ right: me.paddingRight || 0,
+ bottom: me.paddingBottom || 0
+ };
+ },
+
+ /**
+ * Returns the scale tick objects ({label, major})
+ * @since 2.7
+ */
+ getTicks: function() {
+ return this._ticks;
+ },
+
+ // These methods are ordered by lifecyle. Utilities then follow.
+ // Any function defined here is inherited by all scale types.
+ // Any function can be extended by the scale type
+
+ mergeTicksOptions: function() {
+ var ticks = this.options.ticks;
+ if (ticks.minor === false) {
+ ticks.minor = {
+ display: false
+ };
+ }
+ if (ticks.major === false) {
+ ticks.major = {
+ display: false
+ };
+ }
+ for (var key in ticks) {
+ if (key !== 'major' && key !== 'minor') {
+ if (typeof ticks.minor[key] === 'undefined') {
+ ticks.minor[key] = ticks[key];
+ }
+ if (typeof ticks.major[key] === 'undefined') {
+ ticks.major[key] = ticks[key];
+ }
+ }
+ }
+ },
+ beforeUpdate: function() {
+ helpers.callback(this.options.beforeUpdate, [this]);
+ },
+ update: function(maxWidth, maxHeight, margins) {
+ var me = this;
+ var i, ilen, labels, label, ticks, tick;
+
+ // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
+ me.beforeUpdate();
+
+ // Absorb the master measurements
+ me.maxWidth = maxWidth;
+ me.maxHeight = maxHeight;
+ me.margins = helpers.extend({
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0
+ }, margins);
+ me.longestTextCache = me.longestTextCache || {};
+
+ // Dimensions
+ me.beforeSetDimensions();
+ me.setDimensions();
+ me.afterSetDimensions();
+
+ // Data min/max
+ me.beforeDataLimits();
+ me.determineDataLimits();
+ me.afterDataLimits();
+
+ // Ticks - `this.ticks` is now DEPRECATED!
+ // Internal ticks are now stored as objects in the PRIVATE `this._ticks` member
+ // and must not be accessed directly from outside this class. `this.ticks` being
+ // around for long time and not marked as private, we can't change its structure
+ // without unexpected breaking changes. If you need to access the scale ticks,
+ // use scale.getTicks() instead.
+
+ me.beforeBuildTicks();
+
+ // New implementations should return an array of objects but for BACKWARD COMPAT,
+ // we still support no return (`this.ticks` internally set by calling this method).
+ ticks = me.buildTicks() || [];
+
+ me.afterBuildTicks();
+
+ me.beforeTickToLabelConversion();
+
+ // New implementations should return the formatted tick labels but for BACKWARD
+ // COMPAT, we still support no return (`this.ticks` internally changed by calling
+ // this method and supposed to contain only string values).
+ labels = me.convertTicksToLabels(ticks) || me.ticks;
+
+ me.afterTickToLabelConversion();
+
+ me.ticks = labels; // BACKWARD COMPATIBILITY
+
+ // IMPORTANT: from this point, we consider that `this.ticks` will NEVER change!
+
+ // BACKWARD COMPAT: synchronize `_ticks` with labels (so potentially `this.ticks`)
+ for (i = 0, ilen = labels.length; i < ilen; ++i) {
+ label = labels[i];
+ tick = ticks[i];
+ if (!tick) {
+ ticks.push(tick = {
+ label: label,
+ major: false
+ });
+ } else {
+ tick.label = label;
+ }
+ }
+
+ me._ticks = ticks;
+
+ // Tick Rotation
+ me.beforeCalculateTickRotation();
+ me.calculateTickRotation();
+ me.afterCalculateTickRotation();
+ // Fit
+ me.beforeFit();
+ me.fit();
+ me.afterFit();
+ //
+ me.afterUpdate();
+
+ return me.minSize;
+
+ },
+ afterUpdate: function() {
+ helpers.callback(this.options.afterUpdate, [this]);
+ },
+
+ //
+
+ beforeSetDimensions: function() {
+ helpers.callback(this.options.beforeSetDimensions, [this]);
+ },
+ setDimensions: function() {
+ var me = this;
+ // Set the unconstrained dimension before label rotation
+ if (me.isHorizontal()) {
+ // Reset position before calculating rotation
+ me.width = me.maxWidth;
+ me.left = 0;
+ me.right = me.width;
+ } else {
+ me.height = me.maxHeight;
+
+ // Reset position before calculating rotation
+ me.top = 0;
+ me.bottom = me.height;
+ }
+
+ // Reset padding
+ me.paddingLeft = 0;
+ me.paddingTop = 0;
+ me.paddingRight = 0;
+ me.paddingBottom = 0;
+ },
+ afterSetDimensions: function() {
+ helpers.callback(this.options.afterSetDimensions, [this]);
+ },
+
+ // Data limits
+ beforeDataLimits: function() {
+ helpers.callback(this.options.beforeDataLimits, [this]);
+ },
+ determineDataLimits: helpers.noop,
+ afterDataLimits: function() {
+ helpers.callback(this.options.afterDataLimits, [this]);
+ },
+
+ //
+ beforeBuildTicks: function() {
+ helpers.callback(this.options.beforeBuildTicks, [this]);
+ },
+ buildTicks: helpers.noop,
+ afterBuildTicks: function() {
+ helpers.callback(this.options.afterBuildTicks, [this]);
+ },
+
+ beforeTickToLabelConversion: function() {
+ helpers.callback(this.options.beforeTickToLabelConversion, [this]);
+ },
+ convertTicksToLabels: function() {
+ var me = this;
+ // Convert ticks to strings
+ var tickOpts = me.options.ticks;
+ me.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback, this);
+ },
+ afterTickToLabelConversion: function() {
+ helpers.callback(this.options.afterTickToLabelConversion, [this]);
+ },
+
+ //
+
+ beforeCalculateTickRotation: function() {
+ helpers.callback(this.options.beforeCalculateTickRotation, [this]);
+ },
+ calculateTickRotation: function() {
+ var me = this;
+ var context = me.ctx;
+ var tickOpts = me.options.ticks;
+ var labels = labelsFromTicks(me._ticks);
+
+ // Get the width of each grid by calculating the difference
+ // between x offsets between 0 and 1.
+ var tickFont = parseFontOptions(tickOpts);
+ context.font = tickFont.font;
+
+ var labelRotation = tickOpts.minRotation || 0;
+
+ if (labels.length && me.options.display && me.isHorizontal()) {
+ var originalLabelWidth = helpers.longestText(context, tickFont.font, labels, me.longestTextCache);
+ var labelWidth = originalLabelWidth;
+ var cosRotation, sinRotation;
+
+ // Allow 3 pixels x2 padding either side for label readability
+ var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;
+
+ // Max label rotation can be set or default to 90 - also act as a loop counter
+ while (labelWidth > tickWidth && labelRotation < tickOpts.maxRotation) {
+ var angleRadians = helpers.toRadians(labelRotation);
+ cosRotation = Math.cos(angleRadians);
+ sinRotation = Math.sin(angleRadians);
+
+ if (sinRotation * originalLabelWidth > me.maxHeight) {
+ // go back one step
+ labelRotation--;
+ break;
+ }
+
+ labelRotation++;
+ labelWidth = cosRotation * originalLabelWidth;
+ }
+ }
+
+ me.labelRotation = labelRotation;
+ },
+ afterCalculateTickRotation: function() {
+ helpers.callback(this.options.afterCalculateTickRotation, [this]);
+ },
+
+ //
+
+ beforeFit: function() {
+ helpers.callback(this.options.beforeFit, [this]);
+ },
+ fit: function() {
+ var me = this;
+ // Reset
+ var minSize = me.minSize = {
+ width: 0,
+ height: 0
+ };
+
+ var labels = labelsFromTicks(me._ticks);
+
+ var opts = me.options;
+ var tickOpts = opts.ticks;
+ var scaleLabelOpts = opts.scaleLabel;
+ var gridLineOpts = opts.gridLines;
+ var display = opts.display;
+ var isHorizontal = me.isHorizontal();
+
+ var tickFont = parseFontOptions(tickOpts);
+ var tickMarkLength = opts.gridLines.tickMarkLength;
+
+ // Width
+ if (isHorizontal) {
+ // subtract the margins to line up with the chartArea if we are a full width scale
+ minSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth;
+ } else {
+ minSize.width = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
+ }
+
+ // height
+ if (isHorizontal) {
+ minSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
+ } else {
+ minSize.height = me.maxHeight; // fill all the height
+ }
+
+ // Are we showing a title for the scale?
+ if (scaleLabelOpts.display && display) {
+ var scaleLabelLineHeight = parseLineHeight(scaleLabelOpts);
+ var scaleLabelPadding = helpers.options.toPadding(scaleLabelOpts.padding);
+ var deltaHeight = scaleLabelLineHeight + scaleLabelPadding.height;
+
+ if (isHorizontal) {
+ minSize.height += deltaHeight;
+ } else {
+ minSize.width += deltaHeight;
+ }
+ }
+
+ // Don't bother fitting the ticks if we are not showing them
+ if (tickOpts.display && display) {
+ var largestTextWidth = helpers.longestText(me.ctx, tickFont.font, labels, me.longestTextCache);
+ var tallestLabelHeightInLines = helpers.numberOfLabelLines(labels);
+ var lineSpace = tickFont.size * 0.5;
+ var tickPadding = me.options.ticks.padding;
+
+ if (isHorizontal) {
+ // A horizontal axis is more constrained by the height.
+ me.longestLabelWidth = largestTextWidth;
+
+ var angleRadians = helpers.toRadians(me.labelRotation);
+ var cosRotation = Math.cos(angleRadians);
+ var sinRotation = Math.sin(angleRadians);
+
+ // TODO - improve this calculation
+ var labelHeight = (sinRotation * largestTextWidth)
+ + (tickFont.size * tallestLabelHeightInLines)
+ + (lineSpace * (tallestLabelHeightInLines - 1))
+ + lineSpace; // padding
+
+ minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight + tickPadding);
+
+ me.ctx.font = tickFont.font;
+ var firstLabelWidth = computeTextSize(me.ctx, labels[0], tickFont.font);
+ var lastLabelWidth = computeTextSize(me.ctx, labels[labels.length - 1], tickFont.font);
+
+ // Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned
+ // which means that the right padding is dominated by the font height
+ if (me.labelRotation !== 0) {
+ me.paddingLeft = opts.position === 'bottom' ? (cosRotation * firstLabelWidth) + 3 : (cosRotation * lineSpace) + 3; // add 3 px to move away from canvas edges
+ me.paddingRight = opts.position === 'bottom' ? (cosRotation * lineSpace) + 3 : (cosRotation * lastLabelWidth) + 3;
+ } else {
+ me.paddingLeft = firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges
+ me.paddingRight = lastLabelWidth / 2 + 3;
+ }
+ } else {
+ // A vertical axis is more constrained by the width. Labels are the
+ // dominant factor here, so get that length first and account for padding
+ if (tickOpts.mirror) {
+ largestTextWidth = 0;
+ } else {
+ // use lineSpace for consistency with horizontal axis
+ // tickPadding is not implemented for horizontal
+ largestTextWidth += tickPadding + lineSpace;
+ }
+
+ minSize.width = Math.min(me.maxWidth, minSize.width + largestTextWidth);
+
+ me.paddingTop = tickFont.size / 2;
+ me.paddingBottom = tickFont.size / 2;
+ }
+ }
+
+ me.handleMargins();
+
+ me.width = minSize.width;
+ me.height = minSize.height;
+ },
+
+ /**
+ * Handle margins and padding interactions
+ * @private
+ */
+ handleMargins: function() {
+ var me = this;
+ if (me.margins) {
+ me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);
+ me.paddingTop = Math.max(me.paddingTop - me.margins.top, 0);
+ me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);
+ me.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0);
+ }
+ },
+
+ afterFit: function() {
+ helpers.callback(this.options.afterFit, [this]);
+ },
+
+ // Shared Methods
+ isHorizontal: function() {
+ return this.options.position === 'top' || this.options.position === 'bottom';
+ },
+ isFullWidth: function() {
+ return (this.options.fullWidth);
+ },
+
+ // Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not
+ getRightValue: function(rawValue) {
+ // Null and undefined values first
+ if (helpers.isNullOrUndef(rawValue)) {
+ return NaN;
+ }
+ // isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values
+ if (typeof rawValue === 'number' && !isFinite(rawValue)) {
+ return NaN;
+ }
+ // If it is in fact an object, dive in one more level
+ if (rawValue) {
+ if (this.isHorizontal()) {
+ if (rawValue.x !== undefined) {
+ return this.getRightValue(rawValue.x);
+ }
+ } else if (rawValue.y !== undefined) {
+ return this.getRightValue(rawValue.y);
+ }
+ }
+
+ // Value is good, return it
+ return rawValue;
+ },
+
+ /**
+ * Used to get the value to display in the tooltip for the data at the given index
+ * @param index
+ * @param datasetIndex
+ */
+ getLabelForIndex: helpers.noop,
+
+ /**
+ * Returns the location of the given data point. Value can either be an index or a numerical value
+ * The coordinate (0, 0) is at the upper-left corner of the canvas
+ * @param value
+ * @param index
+ * @param datasetIndex
+ */
+ getPixelForValue: helpers.noop,
+
+ /**
+ * Used to get the data value from a given pixel. This is the inverse of getPixelForValue
+ * The coordinate (0, 0) is at the upper-left corner of the canvas
+ * @param pixel
+ */
+ getValueForPixel: helpers.noop,
+
+ /**
+ * Returns the location of the tick at the given index
+ * The coordinate (0, 0) is at the upper-left corner of the canvas
+ */
+ getPixelForTick: function(index) {
+ var me = this;
+ var offset = me.options.offset;
+ if (me.isHorizontal()) {
+ var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
+ var tickWidth = innerWidth / Math.max((me._ticks.length - (offset ? 0 : 1)), 1);
+ var pixel = (tickWidth * index) + me.paddingLeft;
+
+ if (offset) {
+ pixel += tickWidth / 2;
+ }
+
+ var finalVal = me.left + Math.round(pixel);
+ finalVal += me.isFullWidth() ? me.margins.left : 0;
+ return finalVal;
+ }
+ var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
+ return me.top + (index * (innerHeight / (me._ticks.length - 1)));
+ },
+
+ /**
+ * Utility for getting the pixel location of a percentage of scale
+ * The coordinate (0, 0) is at the upper-left corner of the canvas
+ */
+ getPixelForDecimal: function(decimal) {
+ var me = this;
+ if (me.isHorizontal()) {
+ var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
+ var valueOffset = (innerWidth * decimal) + me.paddingLeft;
+
+ var finalVal = me.left + Math.round(valueOffset);
+ finalVal += me.isFullWidth() ? me.margins.left : 0;
+ return finalVal;
+ }
+ return me.top + (decimal * me.height);
+ },
+
+ /**
+ * Returns the pixel for the minimum chart value
+ * The coordinate (0, 0) is at the upper-left corner of the canvas
+ */
+ getBasePixel: function() {
+ return this.getPixelForValue(this.getBaseValue());
+ },
+
+ getBaseValue: function() {
+ var me = this;
+ var min = me.min;
+ var max = me.max;
+
+ return me.beginAtZero ? 0 :
+ min < 0 && max < 0 ? max :
+ min > 0 && max > 0 ? min :
+ 0;
+ },
+
+ /**
+ * Returns a subset of ticks to be plotted to avoid overlapping labels.
+ * @private
+ */
+ _autoSkip: function(ticks) {
+ var skipRatio;
+ var me = this;
+ var isHorizontal = me.isHorizontal();
+ var optionTicks = me.options.ticks.minor;
+ var tickCount = ticks.length;
+ var labelRotationRadians = helpers.toRadians(me.labelRotation);
+ var cosRotation = Math.cos(labelRotationRadians);
+ var longestRotatedLabel = me.longestLabelWidth * cosRotation;
+ var result = [];
+ var i, tick, shouldSkip;
+
+ // figure out the maximum number of gridlines to show
+ var maxTicks;
+ if (optionTicks.maxTicksLimit) {
+ maxTicks = optionTicks.maxTicksLimit;
+ }
+
+ if (isHorizontal) {
+ skipRatio = false;
+
+ if ((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount > (me.width - (me.paddingLeft + me.paddingRight))) {
+ skipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount) / (me.width - (me.paddingLeft + me.paddingRight)));
+ }
+
+ // if they defined a max number of optionTicks,
+ // increase skipRatio until that number is met
+ if (maxTicks && tickCount > maxTicks) {
+ skipRatio = Math.max(skipRatio, Math.floor(tickCount / maxTicks));
+ }
+ }
+
+ for (i = 0; i < tickCount; i++) {
+ tick = ticks[i];
+
+ // Since we always show the last tick,we need may need to hide the last shown one before
+ shouldSkip = (skipRatio > 1 && i % skipRatio > 0) || (i % skipRatio === 0 && i + skipRatio >= tickCount);
+ if (shouldSkip && i !== tickCount - 1) {
+ // leave tick in place but make sure it's not displayed (#4635)
+ delete tick.label;
+ }
+ result.push(tick);
+ }
+ return result;
+ },
+
+ // Actually draw the scale on the canvas
+ // @param {rectangle} chartArea : the area of the chart to draw full grid lines on
+ draw: function(chartArea) {
+ var me = this;
+ var options = me.options;
+ if (!options.display) {
+ return;
+ }
+
+ var context = me.ctx;
+ var globalDefaults = defaults.global;
+ var optionTicks = options.ticks.minor;
+ var optionMajorTicks = options.ticks.major || optionTicks;
+ var gridLines = options.gridLines;
+ var scaleLabel = options.scaleLabel;
+
+ var isRotated = me.labelRotation !== 0;
+ var isHorizontal = me.isHorizontal();
+
+ var ticks = optionTicks.autoSkip ? me._autoSkip(me.getTicks()) : me.getTicks();
+ var tickFontColor = helpers.valueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);
+ var tickFont = parseFontOptions(optionTicks);
+ var majorTickFontColor = helpers.valueOrDefault(optionMajorTicks.fontColor, globalDefaults.defaultFontColor);
+ var majorTickFont = parseFontOptions(optionMajorTicks);
+
+ var tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0;
+
+ var scaleLabelFontColor = helpers.valueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);
+ var scaleLabelFont = parseFontOptions(scaleLabel);
+ var scaleLabelPadding = helpers.options.toPadding(scaleLabel.padding);
+ var labelRotationRadians = helpers.toRadians(me.labelRotation);
+
+ var itemsToDraw = [];
+
+ var axisWidth = me.options.gridLines.lineWidth;
+ var xTickStart = options.position === 'right' ? me.right : me.right - axisWidth - tl;
+ var xTickEnd = options.position === 'right' ? me.right + tl : me.right;
+ var yTickStart = options.position === 'bottom' ? me.top + axisWidth : me.bottom - tl - axisWidth;
+ var yTickEnd = options.position === 'bottom' ? me.top + axisWidth + tl : me.bottom + axisWidth;
+
+ helpers.each(ticks, function(tick, index) {
+ // autoskipper skipped this tick (#4635)
+ if (helpers.isNullOrUndef(tick.label)) {
+ return;
+ }
+
+ var label = tick.label;
+ var lineWidth, lineColor, borderDash, borderDashOffset;
+ if (index === me.zeroLineIndex && options.offset === gridLines.offsetGridLines) {
+ // Draw the first index specially
+ lineWidth = gridLines.zeroLineWidth;
+ lineColor = gridLines.zeroLineColor;
+ borderDash = gridLines.zeroLineBorderDash;
+ borderDashOffset = gridLines.zeroLineBorderDashOffset;
+ } else {
+ lineWidth = helpers.valueAtIndexOrDefault(gridLines.lineWidth, index);
+ lineColor = helpers.valueAtIndexOrDefault(gridLines.color, index);
+ borderDash = helpers.valueOrDefault(gridLines.borderDash, globalDefaults.borderDash);
+ borderDashOffset = helpers.valueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset);
+ }
+
+ // Common properties
+ var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;
+ var textAlign = 'middle';
+ var textBaseline = 'middle';
+ var tickPadding = optionTicks.padding;
+
+ if (isHorizontal) {
+ var labelYOffset = tl + tickPadding;
+
+ if (options.position === 'bottom') {
+ // bottom
+ textBaseline = !isRotated ? 'top' : 'middle';
+ textAlign = !isRotated ? 'center' : 'right';
+ labelY = me.top + labelYOffset;
+ } else {
+ // top
+ textBaseline = !isRotated ? 'bottom' : 'middle';
+ textAlign = !isRotated ? 'center' : 'left';
+ labelY = me.bottom - labelYOffset;
+ }
+
+ var xLineValue = getLineValue(me, index, gridLines.offsetGridLines && ticks.length > 1);
+ if (xLineValue < me.left) {
+ lineColor = 'rgba(0,0,0,0)';
+ }
+ xLineValue += helpers.aliasPixel(lineWidth);
+
+ labelX = me.getPixelForTick(index) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option)
+
+ tx1 = tx2 = x1 = x2 = xLineValue;
+ ty1 = yTickStart;
+ ty2 = yTickEnd;
+ y1 = chartArea.top;
+ y2 = chartArea.bottom + axisWidth;
+ } else {
+ var isLeft = options.position === 'left';
+ var labelXOffset;
+
+ if (optionTicks.mirror) {
+ textAlign = isLeft ? 'left' : 'right';
+ labelXOffset = tickPadding;
+ } else {
+ textAlign = isLeft ? 'right' : 'left';
+ labelXOffset = tl + tickPadding;
+ }
+
+ labelX = isLeft ? me.right - labelXOffset : me.left + labelXOffset;
+
+ var yLineValue = getLineValue(me, index, gridLines.offsetGridLines && ticks.length > 1);
+ if (yLineValue < me.top) {
+ lineColor = 'rgba(0,0,0,0)';
+ }
+ yLineValue += helpers.aliasPixel(lineWidth);
+
+ labelY = me.getPixelForTick(index) + optionTicks.labelOffset;
+
+ tx1 = xTickStart;
+ tx2 = xTickEnd;
+ x1 = chartArea.left;
+ x2 = chartArea.right + axisWidth;
+ ty1 = ty2 = y1 = y2 = yLineValue;
+ }
+
+ itemsToDraw.push({
+ tx1: tx1,
+ ty1: ty1,
+ tx2: tx2,
+ ty2: ty2,
+ x1: x1,
+ y1: y1,
+ x2: x2,
+ y2: y2,
+ labelX: labelX,
+ labelY: labelY,
+ glWidth: lineWidth,
+ glColor: lineColor,
+ glBorderDash: borderDash,
+ glBorderDashOffset: borderDashOffset,
+ rotation: -1 * labelRotationRadians,
+ label: label,
+ major: tick.major,
+ textBaseline: textBaseline,
+ textAlign: textAlign
+ });
+ });
+
+ // Draw all of the tick labels, tick marks, and grid lines at the correct places
+ helpers.each(itemsToDraw, function(itemToDraw) {
+ if (gridLines.display) {
+ context.save();
+ context.lineWidth = itemToDraw.glWidth;
+ context.strokeStyle = itemToDraw.glColor;
+ if (context.setLineDash) {
+ context.setLineDash(itemToDraw.glBorderDash);
+ context.lineDashOffset = itemToDraw.glBorderDashOffset;
+ }
+
+ context.beginPath();
+
+ if (gridLines.drawTicks) {
+ context.moveTo(itemToDraw.tx1, itemToDraw.ty1);
+ context.lineTo(itemToDraw.tx2, itemToDraw.ty2);
+ }
+
+ if (gridLines.drawOnChartArea) {
+ context.moveTo(itemToDraw.x1, itemToDraw.y1);
+ context.lineTo(itemToDraw.x2, itemToDraw.y2);
+ }
+
+ context.stroke();
+ context.restore();
+ }
+
+ if (optionTicks.display) {
+ // Make sure we draw text in the correct color and font
+ context.save();
+ context.translate(itemToDraw.labelX, itemToDraw.labelY);
+ context.rotate(itemToDraw.rotation);
+ context.font = itemToDraw.major ? majorTickFont.font : tickFont.font;
+ context.fillStyle = itemToDraw.major ? majorTickFontColor : tickFontColor;
+ context.textBaseline = itemToDraw.textBaseline;
+ context.textAlign = itemToDraw.textAlign;
+
+ var label = itemToDraw.label;
+ if (helpers.isArray(label)) {
+ var lineCount = label.length;
+ var lineHeight = tickFont.size * 1.5;
+ var y = me.isHorizontal() ? 0 : -lineHeight * (lineCount - 1) / 2;
+
+ for (var i = 0; i < lineCount; ++i) {
+ // We just make sure the multiline element is a string here..
+ context.fillText('' + label[i], 0, y);
+ // apply same lineSpacing as calculated @ L#320
+ y += lineHeight;
+ }
+ } else {
+ context.fillText(label, 0, 0);
+ }
+ context.restore();
+ }
+ });
+
+ if (scaleLabel.display) {
+ // Draw the scale label
+ var scaleLabelX;
+ var scaleLabelY;
+ var rotation = 0;
+ var halfLineHeight = parseLineHeight(scaleLabel) / 2;
+
+ if (isHorizontal) {
+ scaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width
+ scaleLabelY = options.position === 'bottom'
+ ? me.bottom - halfLineHeight - scaleLabelPadding.bottom
+ : me.top + halfLineHeight + scaleLabelPadding.top;
+ } else {
+ var isLeft = options.position === 'left';
+ scaleLabelX = isLeft
+ ? me.left + halfLineHeight + scaleLabelPadding.top
+ : me.right - halfLineHeight - scaleLabelPadding.top;
+ scaleLabelY = me.top + ((me.bottom - me.top) / 2);
+ rotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;
+ }
+
+ context.save();
+ context.translate(scaleLabelX, scaleLabelY);
+ context.rotate(rotation);
+ context.textAlign = 'center';
+ context.textBaseline = 'middle';
+ context.fillStyle = scaleLabelFontColor; // render in correct colour
+ context.font = scaleLabelFont.font;
+ context.fillText(scaleLabel.labelString, 0, 0);
+ context.restore();
+ }
+
+ if (gridLines.drawBorder) {
+ // Draw the line at the edge of the axis
+ context.lineWidth = helpers.valueAtIndexOrDefault(gridLines.lineWidth, 0);
+ context.strokeStyle = helpers.valueAtIndexOrDefault(gridLines.color, 0);
+ var x1 = me.left;
+ var x2 = me.right + axisWidth;
+ var y1 = me.top;
+ var y2 = me.bottom + axisWidth;
+
+ var aliasPixel = helpers.aliasPixel(context.lineWidth);
+ if (isHorizontal) {
+ y1 = y2 = options.position === 'top' ? me.bottom : me.top;
+ y1 += aliasPixel;
+ y2 += aliasPixel;
+ } else {
+ x1 = x2 = options.position === 'left' ? me.right : me.left;
+ x1 += aliasPixel;
+ x2 += aliasPixel;
+ }
+
+ context.beginPath();
+ context.moveTo(x1, y1);
+ context.lineTo(x2, y2);
+ context.stroke();
+ }
+ }
+ });
+};
+
+},{"25":25,"26":26,"34":34,"45":45}],33:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var helpers = require(45);
+var layouts = require(30);
+
+module.exports = function(Chart) {
+
+ Chart.scaleService = {
+ // Scale registration object. Extensions can register new scale types (such as log or DB scales) and then
+ // use the new chart options to grab the correct scale
+ constructors: {},
+ // Use a registration function so that we can move to an ES6 map when we no longer need to support
+ // old browsers
+
+ // Scale config defaults
+ defaults: {},
+ registerScaleType: function(type, scaleConstructor, scaleDefaults) {
+ this.constructors[type] = scaleConstructor;
+ this.defaults[type] = helpers.clone(scaleDefaults);
+ },
+ getScaleConstructor: function(type) {
+ return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;
+ },
+ getScaleDefaults: function(type) {
+ // Return the scale defaults merged with the global settings so that we always use the latest ones
+ return this.defaults.hasOwnProperty(type) ? helpers.merge({}, [defaults.scale, this.defaults[type]]) : {};
+ },
+ updateScaleDefaults: function(type, additions) {
+ var me = this;
+ if (me.defaults.hasOwnProperty(type)) {
+ me.defaults[type] = helpers.extend(me.defaults[type], additions);
+ }
+ },
+ addScalesToLayout: function(chart) {
+ // Adds each scale to the chart.boxes array to be sized accordingly
+ helpers.each(chart.scales, function(scale) {
+ // Set ILayoutItem parameters for backwards compatibility
+ scale.fullWidth = scale.options.fullWidth;
+ scale.position = scale.options.position;
+ scale.weight = scale.options.weight;
+ layouts.addBox(chart, scale);
+ });
+ }
+ };
+};
+
+},{"25":25,"30":30,"45":45}],34:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+
+/**
+ * Namespace to hold static tick generation functions
+ * @namespace Chart.Ticks
+ */
+module.exports = {
+ /**
+ * Namespace to hold formatters for different types of ticks
+ * @namespace Chart.Ticks.formatters
+ */
+ formatters: {
+ /**
+ * Formatter for value labels
+ * @method Chart.Ticks.formatters.values
+ * @param value the value to display
+ * @return {String|Array} the label to display
+ */
+ values: function(value) {
+ return helpers.isArray(value) ? value : '' + value;
+ },
+
+ /**
+ * Formatter for linear numeric ticks
+ * @method Chart.Ticks.formatters.linear
+ * @param tickValue {Number} the value to be formatted
+ * @param index {Number} the position of the tickValue parameter in the ticks array
+ * @param ticks {Array} the list of ticks being converted
+ * @return {String} string representation of the tickValue parameter
+ */
+ linear: function(tickValue, index, ticks) {
+ // If we have lots of ticks, don't use the ones
+ var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];
+
+ // If we have a number like 2.5 as the delta, figure out how many decimal places we need
+ if (Math.abs(delta) > 1) {
+ if (tickValue !== Math.floor(tickValue)) {
+ // not an integer
+ delta = tickValue - Math.floor(tickValue);
+ }
+ }
+
+ var logDelta = helpers.log10(Math.abs(delta));
+ var tickString = '';
+
+ if (tickValue !== 0) {
+ var numDecimal = -1 * Math.floor(logDelta);
+ numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places
+ tickString = tickValue.toFixed(numDecimal);
+ } else {
+ tickString = '0'; // never show decimal places for 0
+ }
+
+ return tickString;
+ },
+
+ logarithmic: function(tickValue, index, ticks) {
+ var remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue))));
+
+ if (tickValue === 0) {
+ return '0';
+ } else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) {
+ return tickValue.toExponential();
+ }
+ return '';
+ }
+ }
+};
+
+},{"45":45}],35:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+
+defaults._set('global', {
+ tooltips: {
+ enabled: true,
+ custom: null,
+ mode: 'nearest',
+ position: 'average',
+ intersect: true,
+ backgroundColor: 'rgba(0,0,0,0.8)',
+ titleFontStyle: 'bold',
+ titleSpacing: 2,
+ titleMarginBottom: 6,
+ titleFontColor: '#fff',
+ titleAlign: 'left',
+ bodySpacing: 2,
+ bodyFontColor: '#fff',
+ bodyAlign: 'left',
+ footerFontStyle: 'bold',
+ footerSpacing: 2,
+ footerMarginTop: 6,
+ footerFontColor: '#fff',
+ footerAlign: 'left',
+ yPadding: 6,
+ xPadding: 6,
+ caretPadding: 2,
+ caretSize: 5,
+ cornerRadius: 6,
+ multiKeyBackground: '#fff',
+ displayColors: true,
+ borderColor: 'rgba(0,0,0,0)',
+ borderWidth: 0,
+ callbacks: {
+ // Args are: (tooltipItems, data)
+ beforeTitle: helpers.noop,
+ title: function(tooltipItems, data) {
+ // Pick first xLabel for now
+ var title = '';
+ var labels = data.labels;
+ var labelCount = labels ? labels.length : 0;
+
+ if (tooltipItems.length > 0) {
+ var item = tooltipItems[0];
+
+ if (item.xLabel) {
+ title = item.xLabel;
+ } else if (labelCount > 0 && item.index < labelCount) {
+ title = labels[item.index];
+ }
+ }
+
+ return title;
+ },
+ afterTitle: helpers.noop,
+
+ // Args are: (tooltipItems, data)
+ beforeBody: helpers.noop,
+
+ // Args are: (tooltipItem, data)
+ beforeLabel: helpers.noop,
+ label: function(tooltipItem, data) {
+ var label = data.datasets[tooltipItem.datasetIndex].label || '';
+
+ if (label) {
+ label += ': ';
+ }
+ label += tooltipItem.yLabel;
+ return label;
+ },
+ labelColor: function(tooltipItem, chart) {
+ var meta = chart.getDatasetMeta(tooltipItem.datasetIndex);
+ var activeElement = meta.data[tooltipItem.index];
+ var view = activeElement._view;
+ return {
+ borderColor: view.borderColor,
+ backgroundColor: view.backgroundColor
+ };
+ },
+ labelTextColor: function() {
+ return this._options.bodyFontColor;
+ },
+ afterLabel: helpers.noop,
+
+ // Args are: (tooltipItems, data)
+ afterBody: helpers.noop,
+
+ // Args are: (tooltipItems, data)
+ beforeFooter: helpers.noop,
+ footer: helpers.noop,
+ afterFooter: helpers.noop
+ }
+ }
+});
+
+module.exports = function(Chart) {
+
+ /**
+ * Helper method to merge the opacity into a color
+ */
+ function mergeOpacity(colorString, opacity) {
+ var color = helpers.color(colorString);
+ return color.alpha(opacity * color.alpha()).rgbaString();
+ }
+
+ // Helper to push or concat based on if the 2nd parameter is an array or not
+ function pushOrConcat(base, toPush) {
+ if (toPush) {
+ if (helpers.isArray(toPush)) {
+ // base = base.concat(toPush);
+ Array.prototype.push.apply(base, toPush);
+ } else {
+ base.push(toPush);
+ }
+ }
+
+ return base;
+ }
+
+ // Private helper to create a tooltip item model
+ // @param element : the chart element (point, arc, bar) to create the tooltip item for
+ // @return : new tooltip item
+ function createTooltipItem(element) {
+ var xScale = element._xScale;
+ var yScale = element._yScale || element._scale; // handle radar || polarArea charts
+ var index = element._index;
+ var datasetIndex = element._datasetIndex;
+
+ return {
+ xLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',
+ yLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',
+ index: index,
+ datasetIndex: datasetIndex,
+ x: element._model.x,
+ y: element._model.y
+ };
+ }
+
+ /**
+ * Helper to get the reset model for the tooltip
+ * @param tooltipOpts {Object} the tooltip options
+ */
+ function getBaseModel(tooltipOpts) {
+ var globalDefaults = defaults.global;
+ var valueOrDefault = helpers.valueOrDefault;
+
+ return {
+ // Positioning
+ xPadding: tooltipOpts.xPadding,
+ yPadding: tooltipOpts.yPadding,
+ xAlign: tooltipOpts.xAlign,
+ yAlign: tooltipOpts.yAlign,
+
+ // Body
+ bodyFontColor: tooltipOpts.bodyFontColor,
+ _bodyFontFamily: valueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),
+ _bodyFontStyle: valueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),
+ _bodyAlign: tooltipOpts.bodyAlign,
+ bodyFontSize: valueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),
+ bodySpacing: tooltipOpts.bodySpacing,
+
+ // Title
+ titleFontColor: tooltipOpts.titleFontColor,
+ _titleFontFamily: valueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),
+ _titleFontStyle: valueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),
+ titleFontSize: valueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),
+ _titleAlign: tooltipOpts.titleAlign,
+ titleSpacing: tooltipOpts.titleSpacing,
+ titleMarginBottom: tooltipOpts.titleMarginBottom,
+
+ // Footer
+ footerFontColor: tooltipOpts.footerFontColor,
+ _footerFontFamily: valueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),
+ _footerFontStyle: valueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),
+ footerFontSize: valueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),
+ _footerAlign: tooltipOpts.footerAlign,
+ footerSpacing: tooltipOpts.footerSpacing,
+ footerMarginTop: tooltipOpts.footerMarginTop,
+
+ // Appearance
+ caretSize: tooltipOpts.caretSize,
+ cornerRadius: tooltipOpts.cornerRadius,
+ backgroundColor: tooltipOpts.backgroundColor,
+ opacity: 0,
+ legendColorBackground: tooltipOpts.multiKeyBackground,
+ displayColors: tooltipOpts.displayColors,
+ borderColor: tooltipOpts.borderColor,
+ borderWidth: tooltipOpts.borderWidth
+ };
+ }
+
+ /**
+ * Get the size of the tooltip
+ */
+ function getTooltipSize(tooltip, model) {
+ var ctx = tooltip._chart.ctx;
+
+ var height = model.yPadding * 2; // Tooltip Padding
+ var width = 0;
+
+ // Count of all lines in the body
+ var body = model.body;
+ var combinedBodyLength = body.reduce(function(count, bodyItem) {
+ return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;
+ }, 0);
+ combinedBodyLength += model.beforeBody.length + model.afterBody.length;
+
+ var titleLineCount = model.title.length;
+ var footerLineCount = model.footer.length;
+ var titleFontSize = model.titleFontSize;
+ var bodyFontSize = model.bodyFontSize;
+ var footerFontSize = model.footerFontSize;
+
+ height += titleLineCount * titleFontSize; // Title Lines
+ height += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing
+ height += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin
+ height += combinedBodyLength * bodyFontSize; // Body Lines
+ height += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing
+ height += footerLineCount ? model.footerMarginTop : 0; // Footer Margin
+ height += footerLineCount * (footerFontSize); // Footer Lines
+ height += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing
+
+ // Title width
+ var widthPadding = 0;
+ var maxLineWidth = function(line) {
+ width = Math.max(width, ctx.measureText(line).width + widthPadding);
+ };
+
+ ctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily);
+ helpers.each(model.title, maxLineWidth);
+
+ // Body width
+ ctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily);
+ helpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth);
+
+ // Body lines may include some extra width due to the color box
+ widthPadding = model.displayColors ? (bodyFontSize + 2) : 0;
+ helpers.each(body, function(bodyItem) {
+ helpers.each(bodyItem.before, maxLineWidth);
+ helpers.each(bodyItem.lines, maxLineWidth);
+ helpers.each(bodyItem.after, maxLineWidth);
+ });
+
+ // Reset back to 0
+ widthPadding = 0;
+
+ // Footer width
+ ctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily);
+ helpers.each(model.footer, maxLineWidth);
+
+ // Add padding
+ width += 2 * model.xPadding;
+
+ return {
+ width: width,
+ height: height
+ };
+ }
+
+ /**
+ * Helper to get the alignment of a tooltip given the size
+ */
+ function determineAlignment(tooltip, size) {
+ var model = tooltip._model;
+ var chart = tooltip._chart;
+ var chartArea = tooltip._chart.chartArea;
+ var xAlign = 'center';
+ var yAlign = 'center';
+
+ if (model.y < size.height) {
+ yAlign = 'top';
+ } else if (model.y > (chart.height - size.height)) {
+ yAlign = 'bottom';
+ }
+
+ var lf, rf; // functions to determine left, right alignment
+ var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart
+ var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges
+ var midX = (chartArea.left + chartArea.right) / 2;
+ var midY = (chartArea.top + chartArea.bottom) / 2;
+
+ if (yAlign === 'center') {
+ lf = function(x) {
+ return x <= midX;
+ };
+ rf = function(x) {
+ return x > midX;
+ };
+ } else {
+ lf = function(x) {
+ return x <= (size.width / 2);
+ };
+ rf = function(x) {
+ return x >= (chart.width - (size.width / 2));
+ };
+ }
+
+ olf = function(x) {
+ return x + size.width + model.caretSize + model.caretPadding > chart.width;
+ };
+ orf = function(x) {
+ return x - size.width - model.caretSize - model.caretPadding < 0;
+ };
+ yf = function(y) {
+ return y <= midY ? 'top' : 'bottom';
+ };
+
+ if (lf(model.x)) {
+ xAlign = 'left';
+
+ // Is tooltip too wide and goes over the right side of the chart.?
+ if (olf(model.x)) {
+ xAlign = 'center';
+ yAlign = yf(model.y);
+ }
+ } else if (rf(model.x)) {
+ xAlign = 'right';
+
+ // Is tooltip too wide and goes outside left edge of canvas?
+ if (orf(model.x)) {
+ xAlign = 'center';
+ yAlign = yf(model.y);
+ }
+ }
+
+ var opts = tooltip._options;
+ return {
+ xAlign: opts.xAlign ? opts.xAlign : xAlign,
+ yAlign: opts.yAlign ? opts.yAlign : yAlign
+ };
+ }
+
+ /**
+ * @Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment
+ */
+ function getBackgroundPoint(vm, size, alignment, chart) {
+ // Background Position
+ var x = vm.x;
+ var y = vm.y;
+
+ var caretSize = vm.caretSize;
+ var caretPadding = vm.caretPadding;
+ var cornerRadius = vm.cornerRadius;
+ var xAlign = alignment.xAlign;
+ var yAlign = alignment.yAlign;
+ var paddingAndSize = caretSize + caretPadding;
+ var radiusAndPadding = cornerRadius + caretPadding;
+
+ if (xAlign === 'right') {
+ x -= size.width;
+ } else if (xAlign === 'center') {
+ x -= (size.width / 2);
+ if (x + size.width > chart.width) {
+ x = chart.width - size.width;
+ }
+ if (x < 0) {
+ x = 0;
+ }
+ }
+
+ if (yAlign === 'top') {
+ y += paddingAndSize;
+ } else if (yAlign === 'bottom') {
+ y -= size.height + paddingAndSize;
+ } else {
+ y -= (size.height / 2);
+ }
+
+ if (yAlign === 'center') {
+ if (xAlign === 'left') {
+ x += paddingAndSize;
+ } else if (xAlign === 'right') {
+ x -= paddingAndSize;
+ }
+ } else if (xAlign === 'left') {
+ x -= radiusAndPadding;
+ } else if (xAlign === 'right') {
+ x += radiusAndPadding;
+ }
+
+ return {
+ x: x,
+ y: y
+ };
+ }
+
+ Chart.Tooltip = Element.extend({
+ initialize: function() {
+ this._model = getBaseModel(this._options);
+ this._lastActive = [];
+ },
+
+ // Get the title
+ // Args are: (tooltipItem, data)
+ getTitle: function() {
+ var me = this;
+ var opts = me._options;
+ var callbacks = opts.callbacks;
+
+ var beforeTitle = callbacks.beforeTitle.apply(me, arguments);
+ var title = callbacks.title.apply(me, arguments);
+ var afterTitle = callbacks.afterTitle.apply(me, arguments);
+
+ var lines = [];
+ lines = pushOrConcat(lines, beforeTitle);
+ lines = pushOrConcat(lines, title);
+ lines = pushOrConcat(lines, afterTitle);
+
+ return lines;
+ },
+
+ // Args are: (tooltipItem, data)
+ getBeforeBody: function() {
+ var lines = this._options.callbacks.beforeBody.apply(this, arguments);
+ return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
+ },
+
+ // Args are: (tooltipItem, data)
+ getBody: function(tooltipItems, data) {
+ var me = this;
+ var callbacks = me._options.callbacks;
+ var bodyItems = [];
+
+ helpers.each(tooltipItems, function(tooltipItem) {
+ var bodyItem = {
+ before: [],
+ lines: [],
+ after: []
+ };
+ pushOrConcat(bodyItem.before, callbacks.beforeLabel.call(me, tooltipItem, data));
+ pushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data));
+ pushOrConcat(bodyItem.after, callbacks.afterLabel.call(me, tooltipItem, data));
+
+ bodyItems.push(bodyItem);
+ });
+
+ return bodyItems;
+ },
+
+ // Args are: (tooltipItem, data)
+ getAfterBody: function() {
+ var lines = this._options.callbacks.afterBody.apply(this, arguments);
+ return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
+ },
+
+ // Get the footer and beforeFooter and afterFooter lines
+ // Args are: (tooltipItem, data)
+ getFooter: function() {
+ var me = this;
+ var callbacks = me._options.callbacks;
+
+ var beforeFooter = callbacks.beforeFooter.apply(me, arguments);
+ var footer = callbacks.footer.apply(me, arguments);
+ var afterFooter = callbacks.afterFooter.apply(me, arguments);
+
+ var lines = [];
+ lines = pushOrConcat(lines, beforeFooter);
+ lines = pushOrConcat(lines, footer);
+ lines = pushOrConcat(lines, afterFooter);
+
+ return lines;
+ },
+
+ update: function(changed) {
+ var me = this;
+ var opts = me._options;
+
+ // Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition
+ // that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time
+ // which breaks any animations.
+ var existingModel = me._model;
+ var model = me._model = getBaseModel(opts);
+ var active = me._active;
+
+ var data = me._data;
+
+ // In the case where active.length === 0 we need to keep these at existing values for good animations
+ var alignment = {
+ xAlign: existingModel.xAlign,
+ yAlign: existingModel.yAlign
+ };
+ var backgroundPoint = {
+ x: existingModel.x,
+ y: existingModel.y
+ };
+ var tooltipSize = {
+ width: existingModel.width,
+ height: existingModel.height
+ };
+ var tooltipPosition = {
+ x: existingModel.caretX,
+ y: existingModel.caretY
+ };
+
+ var i, len;
+
+ if (active.length) {
+ model.opacity = 1;
+
+ var labelColors = [];
+ var labelTextColors = [];
+ tooltipPosition = Chart.Tooltip.positioners[opts.position].call(me, active, me._eventPosition);
+
+ var tooltipItems = [];
+ for (i = 0, len = active.length; i < len; ++i) {
+ tooltipItems.push(createTooltipItem(active[i]));
+ }
+
+ // If the user provided a filter function, use it to modify the tooltip items
+ if (opts.filter) {
+ tooltipItems = tooltipItems.filter(function(a) {
+ return opts.filter(a, data);
+ });
+ }
+
+ // If the user provided a sorting function, use it to modify the tooltip items
+ if (opts.itemSort) {
+ tooltipItems = tooltipItems.sort(function(a, b) {
+ return opts.itemSort(a, b, data);
+ });
+ }
+
+ // Determine colors for boxes
+ helpers.each(tooltipItems, function(tooltipItem) {
+ labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, me._chart));
+ labelTextColors.push(opts.callbacks.labelTextColor.call(me, tooltipItem, me._chart));
+ });
+
+
+ // Build the Text Lines
+ model.title = me.getTitle(tooltipItems, data);
+ model.beforeBody = me.getBeforeBody(tooltipItems, data);
+ model.body = me.getBody(tooltipItems, data);
+ model.afterBody = me.getAfterBody(tooltipItems, data);
+ model.footer = me.getFooter(tooltipItems, data);
+
+ // Initial positioning and colors
+ model.x = Math.round(tooltipPosition.x);
+ model.y = Math.round(tooltipPosition.y);
+ model.caretPadding = opts.caretPadding;
+ model.labelColors = labelColors;
+ model.labelTextColors = labelTextColors;
+
+ // data points
+ model.dataPoints = tooltipItems;
+
+ // We need to determine alignment of the tooltip
+ tooltipSize = getTooltipSize(this, model);
+ alignment = determineAlignment(this, tooltipSize);
+ // Final Size and Position
+ backgroundPoint = getBackgroundPoint(model, tooltipSize, alignment, me._chart);
+ } else {
+ model.opacity = 0;
+ }
+
+ model.xAlign = alignment.xAlign;
+ model.yAlign = alignment.yAlign;
+ model.x = backgroundPoint.x;
+ model.y = backgroundPoint.y;
+ model.width = tooltipSize.width;
+ model.height = tooltipSize.height;
+
+ // Point where the caret on the tooltip points to
+ model.caretX = tooltipPosition.x;
+ model.caretY = tooltipPosition.y;
+
+ me._model = model;
+
+ if (changed && opts.custom) {
+ opts.custom.call(me, model);
+ }
+
+ return me;
+ },
+ drawCaret: function(tooltipPoint, size) {
+ var ctx = this._chart.ctx;
+ var vm = this._view;
+ var caretPosition = this.getCaretPosition(tooltipPoint, size, vm);
+
+ ctx.lineTo(caretPosition.x1, caretPosition.y1);
+ ctx.lineTo(caretPosition.x2, caretPosition.y2);
+ ctx.lineTo(caretPosition.x3, caretPosition.y3);
+ },
+ getCaretPosition: function(tooltipPoint, size, vm) {
+ var x1, x2, x3, y1, y2, y3;
+ var caretSize = vm.caretSize;
+ var cornerRadius = vm.cornerRadius;
+ var xAlign = vm.xAlign;
+ var yAlign = vm.yAlign;
+ var ptX = tooltipPoint.x;
+ var ptY = tooltipPoint.y;
+ var width = size.width;
+ var height = size.height;
+
+ if (yAlign === 'center') {
+ y2 = ptY + (height / 2);
+
+ if (xAlign === 'left') {
+ x1 = ptX;
+ x2 = x1 - caretSize;
+ x3 = x1;
+
+ y1 = y2 + caretSize;
+ y3 = y2 - caretSize;
+ } else {
+ x1 = ptX + width;
+ x2 = x1 + caretSize;
+ x3 = x1;
+
+ y1 = y2 - caretSize;
+ y3 = y2 + caretSize;
+ }
+ } else {
+ if (xAlign === 'left') {
+ x2 = ptX + cornerRadius + (caretSize);
+ x1 = x2 - caretSize;
+ x3 = x2 + caretSize;
+ } else if (xAlign === 'right') {
+ x2 = ptX + width - cornerRadius - caretSize;
+ x1 = x2 - caretSize;
+ x3 = x2 + caretSize;
+ } else {
+ x2 = vm.caretX;
+ x1 = x2 - caretSize;
+ x3 = x2 + caretSize;
+ }
+ if (yAlign === 'top') {
+ y1 = ptY;
+ y2 = y1 - caretSize;
+ y3 = y1;
+ } else {
+ y1 = ptY + height;
+ y2 = y1 + caretSize;
+ y3 = y1;
+ // invert drawing order
+ var tmp = x3;
+ x3 = x1;
+ x1 = tmp;
+ }
+ }
+ return {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3};
+ },
+ drawTitle: function(pt, vm, ctx, opacity) {
+ var title = vm.title;
+
+ if (title.length) {
+ ctx.textAlign = vm._titleAlign;
+ ctx.textBaseline = 'top';
+
+ var titleFontSize = vm.titleFontSize;
+ var titleSpacing = vm.titleSpacing;
+
+ ctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);
+ ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
+
+ var i, len;
+ for (i = 0, len = title.length; i < len; ++i) {
+ ctx.fillText(title[i], pt.x, pt.y);
+ pt.y += titleFontSize + titleSpacing; // Line Height and spacing
+
+ if (i + 1 === title.length) {
+ pt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing
+ }
+ }
+ }
+ },
+ drawBody: function(pt, vm, ctx, opacity) {
+ var bodyFontSize = vm.bodyFontSize;
+ var bodySpacing = vm.bodySpacing;
+ var body = vm.body;
+
+ ctx.textAlign = vm._bodyAlign;
+ ctx.textBaseline = 'top';
+ ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
+
+ // Before Body
+ var xLinePadding = 0;
+ var fillLineOfText = function(line) {
+ ctx.fillText(line, pt.x + xLinePadding, pt.y);
+ pt.y += bodyFontSize + bodySpacing;
+ };
+
+ // Before body lines
+ ctx.fillStyle = mergeOpacity(vm.bodyFontColor, opacity);
+ helpers.each(vm.beforeBody, fillLineOfText);
+
+ var drawColorBoxes = vm.displayColors;
+ xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;
+
+ // Draw body lines now
+ helpers.each(body, function(bodyItem, i) {
+ var textColor = mergeOpacity(vm.labelTextColors[i], opacity);
+ ctx.fillStyle = textColor;
+ helpers.each(bodyItem.before, fillLineOfText);
+
+ helpers.each(bodyItem.lines, function(line) {
+ // Draw Legend-like boxes if needed
+ if (drawColorBoxes) {
+ // Fill a white rect so that colours merge nicely if the opacity is < 1
+ ctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity);
+ ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
+
+ // Border
+ ctx.lineWidth = 1;
+ ctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);
+ ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
+
+ // Inner square
+ ctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);
+ ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);
+ ctx.fillStyle = textColor;
+ }
+
+ fillLineOfText(line);
+ });
+
+ helpers.each(bodyItem.after, fillLineOfText);
+ });
+
+ // Reset back to 0 for after body
+ xLinePadding = 0;
+
+ // After body lines
+ helpers.each(vm.afterBody, fillLineOfText);
+ pt.y -= bodySpacing; // Remove last body spacing
+ },
+ drawFooter: function(pt, vm, ctx, opacity) {
+ var footer = vm.footer;
+
+ if (footer.length) {
+ pt.y += vm.footerMarginTop;
+
+ ctx.textAlign = vm._footerAlign;
+ ctx.textBaseline = 'top';
+
+ ctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);
+ ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
+
+ helpers.each(footer, function(line) {
+ ctx.fillText(line, pt.x, pt.y);
+ pt.y += vm.footerFontSize + vm.footerSpacing;
+ });
+ }
+ },
+ drawBackground: function(pt, vm, ctx, tooltipSize, opacity) {
+ ctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity);
+ ctx.strokeStyle = mergeOpacity(vm.borderColor, opacity);
+ ctx.lineWidth = vm.borderWidth;
+ var xAlign = vm.xAlign;
+ var yAlign = vm.yAlign;
+ var x = pt.x;
+ var y = pt.y;
+ var width = tooltipSize.width;
+ var height = tooltipSize.height;
+ var radius = vm.cornerRadius;
+
+ ctx.beginPath();
+ ctx.moveTo(x + radius, y);
+ if (yAlign === 'top') {
+ this.drawCaret(pt, tooltipSize);
+ }
+ ctx.lineTo(x + width - radius, y);
+ ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
+ if (yAlign === 'center' && xAlign === 'right') {
+ this.drawCaret(pt, tooltipSize);
+ }
+ ctx.lineTo(x + width, y + height - radius);
+ ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
+ if (yAlign === 'bottom') {
+ this.drawCaret(pt, tooltipSize);
+ }
+ ctx.lineTo(x + radius, y + height);
+ ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
+ if (yAlign === 'center' && xAlign === 'left') {
+ this.drawCaret(pt, tooltipSize);
+ }
+ ctx.lineTo(x, y + radius);
+ ctx.quadraticCurveTo(x, y, x + radius, y);
+ ctx.closePath();
+
+ ctx.fill();
+
+ if (vm.borderWidth > 0) {
+ ctx.stroke();
+ }
+ },
+ draw: function() {
+ var ctx = this._chart.ctx;
+ var vm = this._view;
+
+ if (vm.opacity === 0) {
+ return;
+ }
+
+ var tooltipSize = {
+ width: vm.width,
+ height: vm.height
+ };
+ var pt = {
+ x: vm.x,
+ y: vm.y
+ };
+
+ // IE11/Edge does not like very small opacities, so snap to 0
+ var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;
+
+ // Truthy/falsey value for empty tooltip
+ var hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;
+
+ if (this._options.enabled && hasTooltipContent) {
+ // Draw Background
+ this.drawBackground(pt, vm, ctx, tooltipSize, opacity);
+
+ // Draw Title, Body, and Footer
+ pt.x += vm.xPadding;
+ pt.y += vm.yPadding;
+
+ // Titles
+ this.drawTitle(pt, vm, ctx, opacity);
+
+ // Body
+ this.drawBody(pt, vm, ctx, opacity);
+
+ // Footer
+ this.drawFooter(pt, vm, ctx, opacity);
+ }
+ },
+
+ /**
+ * Handle an event
+ * @private
+ * @param {IEvent} event - The event to handle
+ * @returns {Boolean} true if the tooltip changed
+ */
+ handleEvent: function(e) {
+ var me = this;
+ var options = me._options;
+ var changed = false;
+
+ me._lastActive = me._lastActive || [];
+
+ // Find Active Elements for tooltips
+ if (e.type === 'mouseout') {
+ me._active = [];
+ } else {
+ me._active = me._chart.getElementsAtEventForMode(e, options.mode, options);
+ }
+
+ // Remember Last Actives
+ changed = !helpers.arrayEquals(me._active, me._lastActive);
+
+ // Only handle target event on tooltip change
+ if (changed) {
+ me._lastActive = me._active;
+
+ if (options.enabled || options.custom) {
+ me._eventPosition = {
+ x: e.x,
+ y: e.y
+ };
+
+ me.update(true);
+ me.pivot();
+ }
+ }
+
+ return changed;
+ }
+ });
+
+ /**
+ * @namespace Chart.Tooltip.positioners
+ */
+ Chart.Tooltip.positioners = {
+ /**
+ * Average mode places the tooltip at the average position of the elements shown
+ * @function Chart.Tooltip.positioners.average
+ * @param elements {ChartElement[]} the elements being displayed in the tooltip
+ * @returns {Point} tooltip position
+ */
+ average: function(elements) {
+ if (!elements.length) {
+ return false;
+ }
+
+ var i, len;
+ var x = 0;
+ var y = 0;
+ var count = 0;
+
+ for (i = 0, len = elements.length; i < len; ++i) {
+ var el = elements[i];
+ if (el && el.hasValue()) {
+ var pos = el.tooltipPosition();
+ x += pos.x;
+ y += pos.y;
+ ++count;
+ }
+ }
+
+ return {
+ x: Math.round(x / count),
+ y: Math.round(y / count)
+ };
+ },
+
+ /**
+ * Gets the tooltip position nearest of the item nearest to the event position
+ * @function Chart.Tooltip.positioners.nearest
+ * @param elements {Chart.Element[]} the tooltip elements
+ * @param eventPosition {Point} the position of the event in canvas coordinates
+ * @returns {Point} the tooltip position
+ */
+ nearest: function(elements, eventPosition) {
+ var x = eventPosition.x;
+ var y = eventPosition.y;
+ var minDistance = Number.POSITIVE_INFINITY;
+ var i, len, nearestElement;
+
+ for (i = 0, len = elements.length; i < len; ++i) {
+ var el = elements[i];
+ if (el && el.hasValue()) {
+ var center = el.getCenterPoint();
+ var d = helpers.distanceBetweenPoints(eventPosition, center);
+
+ if (d < minDistance) {
+ minDistance = d;
+ nearestElement = el;
+ }
+ }
+ }
+
+ if (nearestElement) {
+ var tp = nearestElement.tooltipPosition();
+ x = tp.x;
+ y = tp.y;
+ }
+
+ return {
+ x: x,
+ y: y
+ };
+ }
+ };
+};
+
+},{"25":25,"26":26,"45":45}],36:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+
+defaults._set('global', {
+ elements: {
+ arc: {
+ backgroundColor: defaults.global.defaultColor,
+ borderColor: '#fff',
+ borderWidth: 2
+ }
+ }
+});
+
+module.exports = Element.extend({
+ inLabelRange: function(mouseX) {
+ var vm = this._view;
+
+ if (vm) {
+ return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));
+ }
+ return false;
+ },
+
+ inRange: function(chartX, chartY) {
+ var vm = this._view;
+
+ if (vm) {
+ var pointRelativePosition = helpers.getAngleFromPoint(vm, {x: chartX, y: chartY});
+ var angle = pointRelativePosition.angle;
+ var distance = pointRelativePosition.distance;
+
+ // Sanitise angle range
+ var startAngle = vm.startAngle;
+ var endAngle = vm.endAngle;
+ while (endAngle < startAngle) {
+ endAngle += 2.0 * Math.PI;
+ }
+ while (angle > endAngle) {
+ angle -= 2.0 * Math.PI;
+ }
+ while (angle < startAngle) {
+ angle += 2.0 * Math.PI;
+ }
+
+ // Check if within the range of the open/close angle
+ var betweenAngles = (angle >= startAngle && angle <= endAngle);
+ var withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);
+
+ return (betweenAngles && withinRadius);
+ }
+ return false;
+ },
+
+ getCenterPoint: function() {
+ var vm = this._view;
+ var halfAngle = (vm.startAngle + vm.endAngle) / 2;
+ var halfRadius = (vm.innerRadius + vm.outerRadius) / 2;
+ return {
+ x: vm.x + Math.cos(halfAngle) * halfRadius,
+ y: vm.y + Math.sin(halfAngle) * halfRadius
+ };
+ },
+
+ getArea: function() {
+ var vm = this._view;
+ return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2));
+ },
+
+ tooltipPosition: function() {
+ var vm = this._view;
+ var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2);
+ var rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;
+
+ return {
+ x: vm.x + (Math.cos(centreAngle) * rangeFromCentre),
+ y: vm.y + (Math.sin(centreAngle) * rangeFromCentre)
+ };
+ },
+
+ draw: function() {
+ var ctx = this._chart.ctx;
+ var vm = this._view;
+ var sA = vm.startAngle;
+ var eA = vm.endAngle;
+
+ ctx.beginPath();
+
+ ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);
+ ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);
+
+ ctx.closePath();
+ ctx.strokeStyle = vm.borderColor;
+ ctx.lineWidth = vm.borderWidth;
+
+ ctx.fillStyle = vm.backgroundColor;
+
+ ctx.fill();
+ ctx.lineJoin = 'bevel';
+
+ if (vm.borderWidth) {
+ ctx.stroke();
+ }
+ }
+});
+
+},{"25":25,"26":26,"45":45}],37:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+
+var globalDefaults = defaults.global;
+
+defaults._set('global', {
+ elements: {
+ line: {
+ tension: 0.4,
+ backgroundColor: globalDefaults.defaultColor,
+ borderWidth: 3,
+ borderColor: globalDefaults.defaultColor,
+ borderCapStyle: 'butt',
+ borderDash: [],
+ borderDashOffset: 0.0,
+ borderJoinStyle: 'miter',
+ capBezierPoints: true,
+ fill: true, // do we fill in the area between the line and its base axis
+ }
+ }
+});
+
+module.exports = Element.extend({
+ draw: function() {
+ var me = this;
+ var vm = me._view;
+ var ctx = me._chart.ctx;
+ var spanGaps = vm.spanGaps;
+ var points = me._children.slice(); // clone array
+ var globalOptionLineElements = globalDefaults.elements.line;
+ var lastDrawnIndex = -1;
+ var index, current, previous, currentVM;
+
+ // If we are looping, adding the first point again
+ if (me._loop && points.length) {
+ points.push(points[0]);
+ }
+
+ ctx.save();
+
+ // Stroke Line Options
+ ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;
+
+ // IE 9 and 10 do not support line dash
+ if (ctx.setLineDash) {
+ ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);
+ }
+
+ ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;
+ ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;
+ ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;
+ ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;
+
+ // Stroke Line
+ ctx.beginPath();
+ lastDrawnIndex = -1;
+
+ for (index = 0; index < points.length; ++index) {
+ current = points[index];
+ previous = helpers.previousItem(points, index);
+ currentVM = current._view;
+
+ // First point moves to it's starting position no matter what
+ if (index === 0) {
+ if (!currentVM.skip) {
+ ctx.moveTo(currentVM.x, currentVM.y);
+ lastDrawnIndex = index;
+ }
+ } else {
+ previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];
+
+ if (!currentVM.skip) {
+ if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {
+ // There was a gap and this is the first point after the gap
+ ctx.moveTo(currentVM.x, currentVM.y);
+ } else {
+ // Line to next point
+ helpers.canvas.lineTo(ctx, previous._view, current._view);
+ }
+ lastDrawnIndex = index;
+ }
+ }
+ }
+
+ ctx.stroke();
+ ctx.restore();
+ }
+});
+
+},{"25":25,"26":26,"45":45}],38:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+
+var defaultColor = defaults.global.defaultColor;
+
+defaults._set('global', {
+ elements: {
+ point: {
+ radius: 3,
+ pointStyle: 'circle',
+ backgroundColor: defaultColor,
+ borderColor: defaultColor,
+ borderWidth: 1,
+ // Hover
+ hitRadius: 1,
+ hoverRadius: 4,
+ hoverBorderWidth: 1
+ }
+ }
+});
+
+function xRange(mouseX) {
+ var vm = this._view;
+ return vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false;
+}
+
+function yRange(mouseY) {
+ var vm = this._view;
+ return vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false;
+}
+
+module.exports = Element.extend({
+ inRange: function(mouseX, mouseY) {
+ var vm = this._view;
+ return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;
+ },
+
+ inLabelRange: xRange,
+ inXRange: xRange,
+ inYRange: yRange,
+
+ getCenterPoint: function() {
+ var vm = this._view;
+ return {
+ x: vm.x,
+ y: vm.y
+ };
+ },
+
+ getArea: function() {
+ return Math.PI * Math.pow(this._view.radius, 2);
+ },
+
+ tooltipPosition: function() {
+ var vm = this._view;
+ return {
+ x: vm.x,
+ y: vm.y,
+ padding: vm.radius + vm.borderWidth
+ };
+ },
+
+ draw: function(chartArea) {
+ var vm = this._view;
+ var model = this._model;
+ var ctx = this._chart.ctx;
+ var pointStyle = vm.pointStyle;
+ var radius = vm.radius;
+ var x = vm.x;
+ var y = vm.y;
+ var color = helpers.color;
+ var errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.)
+ var ratio = 0;
+
+ if (vm.skip) {
+ return;
+ }
+
+ ctx.strokeStyle = vm.borderColor || defaultColor;
+ ctx.lineWidth = helpers.valueOrDefault(vm.borderWidth, defaults.global.elements.point.borderWidth);
+ ctx.fillStyle = vm.backgroundColor || defaultColor;
+
+ // Cliping for Points.
+ // going out from inner charArea?
+ if ((chartArea !== undefined) && ((model.x < chartArea.left) || (chartArea.right * errMargin < model.x) || (model.y < chartArea.top) || (chartArea.bottom * errMargin < model.y))) {
+ // Point fade out
+ if (model.x < chartArea.left) {
+ ratio = (x - model.x) / (chartArea.left - model.x);
+ } else if (chartArea.right * errMargin < model.x) {
+ ratio = (model.x - x) / (model.x - chartArea.right);
+ } else if (model.y < chartArea.top) {
+ ratio = (y - model.y) / (chartArea.top - model.y);
+ } else if (chartArea.bottom * errMargin < model.y) {
+ ratio = (model.y - y) / (model.y - chartArea.bottom);
+ }
+ ratio = Math.round(ratio * 100) / 100;
+ ctx.strokeStyle = color(ctx.strokeStyle).alpha(ratio).rgbString();
+ ctx.fillStyle = color(ctx.fillStyle).alpha(ratio).rgbString();
+ }
+
+ helpers.canvas.drawPoint(ctx, pointStyle, radius, x, y);
+ }
+});
+
+},{"25":25,"26":26,"45":45}],39:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+
+defaults._set('global', {
+ elements: {
+ rectangle: {
+ backgroundColor: defaults.global.defaultColor,
+ borderColor: defaults.global.defaultColor,
+ borderSkipped: 'bottom',
+ borderWidth: 0
+ }
+ }
+});
+
+function isVertical(bar) {
+ return bar._view.width !== undefined;
+}
+
+/**
+ * Helper function to get the bounds of the bar regardless of the orientation
+ * @param bar {Chart.Element.Rectangle} the bar
+ * @return {Bounds} bounds of the bar
+ * @private
+ */
+function getBarBounds(bar) {
+ var vm = bar._view;
+ var x1, x2, y1, y2;
+
+ if (isVertical(bar)) {
+ // vertical
+ var halfWidth = vm.width / 2;
+ x1 = vm.x - halfWidth;
+ x2 = vm.x + halfWidth;
+ y1 = Math.min(vm.y, vm.base);
+ y2 = Math.max(vm.y, vm.base);
+ } else {
+ // horizontal bar
+ var halfHeight = vm.height / 2;
+ x1 = Math.min(vm.x, vm.base);
+ x2 = Math.max(vm.x, vm.base);
+ y1 = vm.y - halfHeight;
+ y2 = vm.y + halfHeight;
+ }
+
+ return {
+ left: x1,
+ top: y1,
+ right: x2,
+ bottom: y2
+ };
+}
+
+module.exports = Element.extend({
+ draw: function() {
+ var ctx = this._chart.ctx;
+ var vm = this._view;
+ var left, right, top, bottom, signX, signY, borderSkipped;
+ var borderWidth = vm.borderWidth;
+
+ if (!vm.horizontal) {
+ // bar
+ left = vm.x - vm.width / 2;
+ right = vm.x + vm.width / 2;
+ top = vm.y;
+ bottom = vm.base;
+ signX = 1;
+ signY = bottom > top ? 1 : -1;
+ borderSkipped = vm.borderSkipped || 'bottom';
+ } else {
+ // horizontal bar
+ left = vm.base;
+ right = vm.x;
+ top = vm.y - vm.height / 2;
+ bottom = vm.y + vm.height / 2;
+ signX = right > left ? 1 : -1;
+ signY = 1;
+ borderSkipped = vm.borderSkipped || 'left';
+ }
+
+ // Canvas doesn't allow us to stroke inside the width so we can
+ // adjust the sizes to fit if we're setting a stroke on the line
+ if (borderWidth) {
+ // borderWidth shold be less than bar width and bar height.
+ var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
+ borderWidth = borderWidth > barSize ? barSize : borderWidth;
+ var halfStroke = borderWidth / 2;
+ // Adjust borderWidth when bar top position is near vm.base(zero).
+ var borderLeft = left + (borderSkipped !== 'left' ? halfStroke * signX : 0);
+ var borderRight = right + (borderSkipped !== 'right' ? -halfStroke * signX : 0);
+ var borderTop = top + (borderSkipped !== 'top' ? halfStroke * signY : 0);
+ var borderBottom = bottom + (borderSkipped !== 'bottom' ? -halfStroke * signY : 0);
+ // not become a vertical line?
+ if (borderLeft !== borderRight) {
+ top = borderTop;
+ bottom = borderBottom;
+ }
+ // not become a horizontal line?
+ if (borderTop !== borderBottom) {
+ left = borderLeft;
+ right = borderRight;
+ }
+ }
+
+ ctx.beginPath();
+ ctx.fillStyle = vm.backgroundColor;
+ ctx.strokeStyle = vm.borderColor;
+ ctx.lineWidth = borderWidth;
+
+ // Corner points, from bottom-left to bottom-right clockwise
+ // | 1 2 |
+ // | 0 3 |
+ var corners = [
+ [left, bottom],
+ [left, top],
+ [right, top],
+ [right, bottom]
+ ];
+
+ // Find first (starting) corner with fallback to 'bottom'
+ var borders = ['bottom', 'left', 'top', 'right'];
+ var startCorner = borders.indexOf(borderSkipped, 0);
+ if (startCorner === -1) {
+ startCorner = 0;
+ }
+
+ function cornerAt(index) {
+ return corners[(startCorner + index) % 4];
+ }
+
+ // Draw rectangle from 'startCorner'
+ var corner = cornerAt(0);
+ ctx.moveTo(corner[0], corner[1]);
+
+ for (var i = 1; i < 4; i++) {
+ corner = cornerAt(i);
+ ctx.lineTo(corner[0], corner[1]);
+ }
+
+ ctx.fill();
+ if (borderWidth) {
+ ctx.stroke();
+ }
+ },
+
+ height: function() {
+ var vm = this._view;
+ return vm.base - vm.y;
+ },
+
+ inRange: function(mouseX, mouseY) {
+ var inRange = false;
+
+ if (this._view) {
+ var bounds = getBarBounds(this);
+ inRange = mouseX >= bounds.left && mouseX <= bounds.right && mouseY >= bounds.top && mouseY <= bounds.bottom;
+ }
+
+ return inRange;
+ },
+
+ inLabelRange: function(mouseX, mouseY) {
+ var me = this;
+ if (!me._view) {
+ return false;
+ }
+
+ var inRange = false;
+ var bounds = getBarBounds(me);
+
+ if (isVertical(me)) {
+ inRange = mouseX >= bounds.left && mouseX <= bounds.right;
+ } else {
+ inRange = mouseY >= bounds.top && mouseY <= bounds.bottom;
+ }
+
+ return inRange;
+ },
+
+ inXRange: function(mouseX) {
+ var bounds = getBarBounds(this);
+ return mouseX >= bounds.left && mouseX <= bounds.right;
+ },
+
+ inYRange: function(mouseY) {
+ var bounds = getBarBounds(this);
+ return mouseY >= bounds.top && mouseY <= bounds.bottom;
+ },
+
+ getCenterPoint: function() {
+ var vm = this._view;
+ var x, y;
+ if (isVertical(this)) {
+ x = vm.x;
+ y = (vm.y + vm.base) / 2;
+ } else {
+ x = (vm.x + vm.base) / 2;
+ y = vm.y;
+ }
+
+ return {x: x, y: y};
+ },
+
+ getArea: function() {
+ var vm = this._view;
+ return vm.width * Math.abs(vm.y - vm.base);
+ },
+
+ tooltipPosition: function() {
+ var vm = this._view;
+ return {
+ x: vm.x,
+ y: vm.y
+ };
+ }
+});
+
+},{"25":25,"26":26}],40:[function(require,module,exports){
+'use strict';
+
+module.exports = {};
+module.exports.Arc = require(36);
+module.exports.Line = require(37);
+module.exports.Point = require(38);
+module.exports.Rectangle = require(39);
+
+},{"36":36,"37":37,"38":38,"39":39}],41:[function(require,module,exports){
+'use strict';
+
+var helpers = require(42);
+
+/**
+ * @namespace Chart.helpers.canvas
+ */
+var exports = module.exports = {
+ /**
+ * Clears the entire canvas associated to the given `chart`.
+ * @param {Chart} chart - The chart for which to clear the canvas.
+ */
+ clear: function(chart) {
+ chart.ctx.clearRect(0, 0, chart.width, chart.height);
+ },
+
+ /**
+ * Creates a "path" for a rectangle with rounded corners at position (x, y) with a
+ * given size (width, height) and the same `radius` for all corners.
+ * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context.
+ * @param {Number} x - The x axis of the coordinate for the rectangle starting point.
+ * @param {Number} y - The y axis of the coordinate for the rectangle starting point.
+ * @param {Number} width - The rectangle's width.
+ * @param {Number} height - The rectangle's height.
+ * @param {Number} radius - The rounded amount (in pixels) for the four corners.
+ * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object?
+ */
+ roundedRect: function(ctx, x, y, width, height, radius) {
+ if (radius) {
+ var rx = Math.min(radius, width / 2);
+ var ry = Math.min(radius, height / 2);
+
+ ctx.moveTo(x + rx, y);
+ ctx.lineTo(x + width - rx, y);
+ ctx.quadraticCurveTo(x + width, y, x + width, y + ry);
+ ctx.lineTo(x + width, y + height - ry);
+ ctx.quadraticCurveTo(x + width, y + height, x + width - rx, y + height);
+ ctx.lineTo(x + rx, y + height);
+ ctx.quadraticCurveTo(x, y + height, x, y + height - ry);
+ ctx.lineTo(x, y + ry);
+ ctx.quadraticCurveTo(x, y, x + rx, y);
+ } else {
+ ctx.rect(x, y, width, height);
+ }
+ },
+
+ drawPoint: function(ctx, style, radius, x, y) {
+ var type, edgeLength, xOffset, yOffset, height, size;
+
+ if (style && typeof style === 'object') {
+ type = style.toString();
+ if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
+ ctx.drawImage(style, x - style.width / 2, y - style.height / 2, style.width, style.height);
+ return;
+ }
+ }
+
+ if (isNaN(radius) || radius <= 0) {
+ return;
+ }
+
+ switch (style) {
+ // Default includes circle
+ default:
+ ctx.beginPath();
+ ctx.arc(x, y, radius, 0, Math.PI * 2);
+ ctx.closePath();
+ ctx.fill();
+ break;
+ case 'triangle':
+ ctx.beginPath();
+ edgeLength = 3 * radius / Math.sqrt(3);
+ height = edgeLength * Math.sqrt(3) / 2;
+ ctx.moveTo(x - edgeLength / 2, y + height / 3);
+ ctx.lineTo(x + edgeLength / 2, y + height / 3);
+ ctx.lineTo(x, y - 2 * height / 3);
+ ctx.closePath();
+ ctx.fill();
+ break;
+ case 'rect':
+ size = 1 / Math.SQRT2 * radius;
+ ctx.beginPath();
+ ctx.fillRect(x - size, y - size, 2 * size, 2 * size);
+ ctx.strokeRect(x - size, y - size, 2 * size, 2 * size);
+ break;
+ case 'rectRounded':
+ var offset = radius / Math.SQRT2;
+ var leftX = x - offset;
+ var topY = y - offset;
+ var sideSize = Math.SQRT2 * radius;
+ ctx.beginPath();
+ this.roundedRect(ctx, leftX, topY, sideSize, sideSize, radius / 2);
+ ctx.closePath();
+ ctx.fill();
+ break;
+ case 'rectRot':
+ size = 1 / Math.SQRT2 * radius;
+ ctx.beginPath();
+ ctx.moveTo(x - size, y);
+ ctx.lineTo(x, y + size);
+ ctx.lineTo(x + size, y);
+ ctx.lineTo(x, y - size);
+ ctx.closePath();
+ ctx.fill();
+ break;
+ case 'cross':
+ ctx.beginPath();
+ ctx.moveTo(x, y + radius);
+ ctx.lineTo(x, y - radius);
+ ctx.moveTo(x - radius, y);
+ ctx.lineTo(x + radius, y);
+ ctx.closePath();
+ break;
+ case 'crossRot':
+ ctx.beginPath();
+ xOffset = Math.cos(Math.PI / 4) * radius;
+ yOffset = Math.sin(Math.PI / 4) * radius;
+ ctx.moveTo(x - xOffset, y - yOffset);
+ ctx.lineTo(x + xOffset, y + yOffset);
+ ctx.moveTo(x - xOffset, y + yOffset);
+ ctx.lineTo(x + xOffset, y - yOffset);
+ ctx.closePath();
+ break;
+ case 'star':
+ ctx.beginPath();
+ ctx.moveTo(x, y + radius);
+ ctx.lineTo(x, y - radius);
+ ctx.moveTo(x - radius, y);
+ ctx.lineTo(x + radius, y);
+ xOffset = Math.cos(Math.PI / 4) * radius;
+ yOffset = Math.sin(Math.PI / 4) * radius;
+ ctx.moveTo(x - xOffset, y - yOffset);
+ ctx.lineTo(x + xOffset, y + yOffset);
+ ctx.moveTo(x - xOffset, y + yOffset);
+ ctx.lineTo(x + xOffset, y - yOffset);
+ ctx.closePath();
+ break;
+ case 'line':
+ ctx.beginPath();
+ ctx.moveTo(x - radius, y);
+ ctx.lineTo(x + radius, y);
+ ctx.closePath();
+ break;
+ case 'dash':
+ ctx.beginPath();
+ ctx.moveTo(x, y);
+ ctx.lineTo(x + radius, y);
+ ctx.closePath();
+ break;
+ }
+
+ ctx.stroke();
+ },
+
+ clipArea: function(ctx, area) {
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);
+ ctx.clip();
+ },
+
+ unclipArea: function(ctx) {
+ ctx.restore();
+ },
+
+ lineTo: function(ctx, previous, target, flip) {
+ if (target.steppedLine) {
+ if ((target.steppedLine === 'after' && !flip) || (target.steppedLine !== 'after' && flip)) {
+ ctx.lineTo(previous.x, target.y);
+ } else {
+ ctx.lineTo(target.x, previous.y);
+ }
+ ctx.lineTo(target.x, target.y);
+ return;
+ }
+
+ if (!target.tension) {
+ ctx.lineTo(target.x, target.y);
+ return;
+ }
+
+ ctx.bezierCurveTo(
+ flip ? previous.controlPointPreviousX : previous.controlPointNextX,
+ flip ? previous.controlPointPreviousY : previous.controlPointNextY,
+ flip ? target.controlPointNextX : target.controlPointPreviousX,
+ flip ? target.controlPointNextY : target.controlPointPreviousY,
+ target.x,
+ target.y);
+ }
+};
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.canvas.clear instead.
+ * @namespace Chart.helpers.clear
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.clear = exports.clear;
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead.
+ * @namespace Chart.helpers.drawRoundedRectangle
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.drawRoundedRectangle = function(ctx) {
+ ctx.beginPath();
+ exports.roundedRect.apply(exports, arguments);
+ ctx.closePath();
+};
+
+},{"42":42}],42:[function(require,module,exports){
+'use strict';
+
+/**
+ * @namespace Chart.helpers
+ */
+var helpers = {
+ /**
+ * An empty function that can be used, for example, for optional callback.
+ */
+ noop: function() {},
+
+ /**
+ * Returns a unique id, sequentially generated from a global variable.
+ * @returns {Number}
+ * @function
+ */
+ uid: (function() {
+ var id = 0;
+ return function() {
+ return id++;
+ };
+ }()),
+
+ /**
+ * Returns true if `value` is neither null nor undefined, else returns false.
+ * @param {*} value - The value to test.
+ * @returns {Boolean}
+ * @since 2.7.0
+ */
+ isNullOrUndef: function(value) {
+ return value === null || typeof value === 'undefined';
+ },
+
+ /**
+ * Returns true if `value` is an array, else returns false.
+ * @param {*} value - The value to test.
+ * @returns {Boolean}
+ * @function
+ */
+ isArray: Array.isArray ? Array.isArray : function(value) {
+ return Object.prototype.toString.call(value) === '[object Array]';
+ },
+
+ /**
+ * Returns true if `value` is an object (excluding null), else returns false.
+ * @param {*} value - The value to test.
+ * @returns {Boolean}
+ * @since 2.7.0
+ */
+ isObject: function(value) {
+ return value !== null && Object.prototype.toString.call(value) === '[object Object]';
+ },
+
+ /**
+ * Returns `value` if defined, else returns `defaultValue`.
+ * @param {*} value - The value to return if defined.
+ * @param {*} defaultValue - The value to return if `value` is undefined.
+ * @returns {*}
+ */
+ valueOrDefault: function(value, defaultValue) {
+ return typeof value === 'undefined' ? defaultValue : value;
+ },
+
+ /**
+ * Returns value at the given `index` in array if defined, else returns `defaultValue`.
+ * @param {Array} value - The array to lookup for value at `index`.
+ * @param {Number} index - The index in `value` to lookup for value.
+ * @param {*} defaultValue - The value to return if `value[index]` is undefined.
+ * @returns {*}
+ */
+ valueAtIndexOrDefault: function(value, index, defaultValue) {
+ return helpers.valueOrDefault(helpers.isArray(value) ? value[index] : value, defaultValue);
+ },
+
+ /**
+ * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the
+ * value returned by `fn`. If `fn` is not a function, this method returns undefined.
+ * @param {Function} fn - The function to call.
+ * @param {Array|undefined|null} args - The arguments with which `fn` should be called.
+ * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`.
+ * @returns {*}
+ */
+ callback: function(fn, args, thisArg) {
+ if (fn && typeof fn.call === 'function') {
+ return fn.apply(thisArg, args);
+ }
+ },
+
+ /**
+ * Note(SB) for performance sake, this method should only be used when loopable type
+ * is unknown or in none intensive code (not called often and small loopable). Else
+ * it's preferable to use a regular for() loop and save extra function calls.
+ * @param {Object|Array} loopable - The object or array to be iterated.
+ * @param {Function} fn - The function to call for each item.
+ * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`.
+ * @param {Boolean} [reverse] - If true, iterates backward on the loopable.
+ */
+ each: function(loopable, fn, thisArg, reverse) {
+ var i, len, keys;
+ if (helpers.isArray(loopable)) {
+ len = loopable.length;
+ if (reverse) {
+ for (i = len - 1; i >= 0; i--) {
+ fn.call(thisArg, loopable[i], i);
+ }
+ } else {
+ for (i = 0; i < len; i++) {
+ fn.call(thisArg, loopable[i], i);
+ }
+ }
+ } else if (helpers.isObject(loopable)) {
+ keys = Object.keys(loopable);
+ len = keys.length;
+ for (i = 0; i < len; i++) {
+ fn.call(thisArg, loopable[keys[i]], keys[i]);
+ }
+ }
+ },
+
+ /**
+ * Returns true if the `a0` and `a1` arrays have the same content, else returns false.
+ * @see http://stackoverflow.com/a/14853974
+ * @param {Array} a0 - The array to compare
+ * @param {Array} a1 - The array to compare
+ * @returns {Boolean}
+ */
+ arrayEquals: function(a0, a1) {
+ var i, ilen, v0, v1;
+
+ if (!a0 || !a1 || a0.length !== a1.length) {
+ return false;
+ }
+
+ for (i = 0, ilen = a0.length; i < ilen; ++i) {
+ v0 = a0[i];
+ v1 = a1[i];
+
+ if (v0 instanceof Array && v1 instanceof Array) {
+ if (!helpers.arrayEquals(v0, v1)) {
+ return false;
+ }
+ } else if (v0 !== v1) {
+ // NOTE: two different object instances will never be equal: {x:20} != {x:20}
+ return false;
+ }
+ }
+
+ return true;
+ },
+
+ /**
+ * Returns a deep copy of `source` without keeping references on objects and arrays.
+ * @param {*} source - The value to clone.
+ * @returns {*}
+ */
+ clone: function(source) {
+ if (helpers.isArray(source)) {
+ return source.map(helpers.clone);
+ }
+
+ if (helpers.isObject(source)) {
+ var target = {};
+ var keys = Object.keys(source);
+ var klen = keys.length;
+ var k = 0;
+
+ for (; k < klen; ++k) {
+ target[keys[k]] = helpers.clone(source[keys[k]]);
+ }
+
+ return target;
+ }
+
+ return source;
+ },
+
+ /**
+ * The default merger when Chart.helpers.merge is called without merger option.
+ * Note(SB): this method is also used by configMerge and scaleMerge as fallback.
+ * @private
+ */
+ _merger: function(key, target, source, options) {
+ var tval = target[key];
+ var sval = source[key];
+
+ if (helpers.isObject(tval) && helpers.isObject(sval)) {
+ helpers.merge(tval, sval, options);
+ } else {
+ target[key] = helpers.clone(sval);
+ }
+ },
+
+ /**
+ * Merges source[key] in target[key] only if target[key] is undefined.
+ * @private
+ */
+ _mergerIf: function(key, target, source) {
+ var tval = target[key];
+ var sval = source[key];
+
+ if (helpers.isObject(tval) && helpers.isObject(sval)) {
+ helpers.mergeIf(tval, sval);
+ } else if (!target.hasOwnProperty(key)) {
+ target[key] = helpers.clone(sval);
+ }
+ },
+
+ /**
+ * Recursively deep copies `source` properties into `target` with the given `options`.
+ * IMPORTANT: `target` is not cloned and will be updated with `source` properties.
+ * @param {Object} target - The target object in which all sources are merged into.
+ * @param {Object|Array(Object)} source - Object(s) to merge into `target`.
+ * @param {Object} [options] - Merging options:
+ * @param {Function} [options.merger] - The merge method (key, target, source, options)
+ * @returns {Object} The `target` object.
+ */
+ merge: function(target, source, options) {
+ var sources = helpers.isArray(source) ? source : [source];
+ var ilen = sources.length;
+ var merge, i, keys, klen, k;
+
+ if (!helpers.isObject(target)) {
+ return target;
+ }
+
+ options = options || {};
+ merge = options.merger || helpers._merger;
+
+ for (i = 0; i < ilen; ++i) {
+ source = sources[i];
+ if (!helpers.isObject(source)) {
+ continue;
+ }
+
+ keys = Object.keys(source);
+ for (k = 0, klen = keys.length; k < klen; ++k) {
+ merge(keys[k], target, source, options);
+ }
+ }
+
+ return target;
+ },
+
+ /**
+ * Recursively deep copies `source` properties into `target` *only* if not defined in target.
+ * IMPORTANT: `target` is not cloned and will be updated with `source` properties.
+ * @param {Object} target - The target object in which all sources are merged into.
+ * @param {Object|Array(Object)} source - Object(s) to merge into `target`.
+ * @returns {Object} The `target` object.
+ */
+ mergeIf: function(target, source) {
+ return helpers.merge(target, source, {merger: helpers._mergerIf});
+ },
+
+ /**
+ * Applies the contents of two or more objects together into the first object.
+ * @param {Object} target - The target object in which all objects are merged into.
+ * @param {Object} arg1 - Object containing additional properties to merge in target.
+ * @param {Object} argN - Additional objects containing properties to merge in target.
+ * @returns {Object} The `target` object.
+ */
+ extend: function(target) {
+ var setFn = function(value, key) {
+ target[key] = value;
+ };
+ for (var i = 1, ilen = arguments.length; i < ilen; ++i) {
+ helpers.each(arguments[i], setFn);
+ }
+ return target;
+ },
+
+ /**
+ * Basic javascript inheritance based on the model created in Backbone.js
+ */
+ inherits: function(extensions) {
+ var me = this;
+ var ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() {
+ return me.apply(this, arguments);
+ };
+
+ var Surrogate = function() {
+ this.constructor = ChartElement;
+ };
+
+ Surrogate.prototype = me.prototype;
+ ChartElement.prototype = new Surrogate();
+ ChartElement.extend = helpers.inherits;
+
+ if (extensions) {
+ helpers.extend(ChartElement.prototype, extensions);
+ }
+
+ ChartElement.__super__ = me.prototype;
+ return ChartElement;
+ }
+};
+
+module.exports = helpers;
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.callback instead.
+ * @function Chart.helpers.callCallback
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.callCallback = helpers.callback;
+
+/**
+ * Provided for backward compatibility, use Array.prototype.indexOf instead.
+ * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+
+ * @function Chart.helpers.indexOf
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.indexOf = function(array, item, fromIndex) {
+ return Array.prototype.indexOf.call(array, item, fromIndex);
+};
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead.
+ * @function Chart.helpers.getValueOrDefault
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.getValueOrDefault = helpers.valueOrDefault;
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead.
+ * @function Chart.helpers.getValueAtIndexOrDefault
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
+
+},{}],43:[function(require,module,exports){
+'use strict';
+
+var helpers = require(42);
+
+/**
+ * Easing functions adapted from Robert Penner's easing equations.
+ * @namespace Chart.helpers.easingEffects
+ * @see http://www.robertpenner.com/easing/
+ */
+var effects = {
+ linear: function(t) {
+ return t;
+ },
+
+ easeInQuad: function(t) {
+ return t * t;
+ },
+
+ easeOutQuad: function(t) {
+ return -t * (t - 2);
+ },
+
+ easeInOutQuad: function(t) {
+ if ((t /= 0.5) < 1) {
+ return 0.5 * t * t;
+ }
+ return -0.5 * ((--t) * (t - 2) - 1);
+ },
+
+ easeInCubic: function(t) {
+ return t * t * t;
+ },
+
+ easeOutCubic: function(t) {
+ return (t = t - 1) * t * t + 1;
+ },
+
+ easeInOutCubic: function(t) {
+ if ((t /= 0.5) < 1) {
+ return 0.5 * t * t * t;
+ }
+ return 0.5 * ((t -= 2) * t * t + 2);
+ },
+
+ easeInQuart: function(t) {
+ return t * t * t * t;
+ },
+
+ easeOutQuart: function(t) {
+ return -((t = t - 1) * t * t * t - 1);
+ },
+
+ easeInOutQuart: function(t) {
+ if ((t /= 0.5) < 1) {
+ return 0.5 * t * t * t * t;
+ }
+ return -0.5 * ((t -= 2) * t * t * t - 2);
+ },
+
+ easeInQuint: function(t) {
+ return t * t * t * t * t;
+ },
+
+ easeOutQuint: function(t) {
+ return (t = t - 1) * t * t * t * t + 1;
+ },
+
+ easeInOutQuint: function(t) {
+ if ((t /= 0.5) < 1) {
+ return 0.5 * t * t * t * t * t;
+ }
+ return 0.5 * ((t -= 2) * t * t * t * t + 2);
+ },
+
+ easeInSine: function(t) {
+ return -Math.cos(t * (Math.PI / 2)) + 1;
+ },
+
+ easeOutSine: function(t) {
+ return Math.sin(t * (Math.PI / 2));
+ },
+
+ easeInOutSine: function(t) {
+ return -0.5 * (Math.cos(Math.PI * t) - 1);
+ },
+
+ easeInExpo: function(t) {
+ return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1));
+ },
+
+ easeOutExpo: function(t) {
+ return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1;
+ },
+
+ easeInOutExpo: function(t) {
+ if (t === 0) {
+ return 0;
+ }
+ if (t === 1) {
+ return 1;
+ }
+ if ((t /= 0.5) < 1) {
+ return 0.5 * Math.pow(2, 10 * (t - 1));
+ }
+ return 0.5 * (-Math.pow(2, -10 * --t) + 2);
+ },
+
+ easeInCirc: function(t) {
+ if (t >= 1) {
+ return t;
+ }
+ return -(Math.sqrt(1 - t * t) - 1);
+ },
+
+ easeOutCirc: function(t) {
+ return Math.sqrt(1 - (t = t - 1) * t);
+ },
+
+ easeInOutCirc: function(t) {
+ if ((t /= 0.5) < 1) {
+ return -0.5 * (Math.sqrt(1 - t * t) - 1);
+ }
+ return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1);
+ },
+
+ easeInElastic: function(t) {
+ var s = 1.70158;
+ var p = 0;
+ var a = 1;
+ if (t === 0) {
+ return 0;
+ }
+ if (t === 1) {
+ return 1;
+ }
+ if (!p) {
+ p = 0.3;
+ }
+ if (a < 1) {
+ a = 1;
+ s = p / 4;
+ } else {
+ s = p / (2 * Math.PI) * Math.asin(1 / a);
+ }
+ return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));
+ },
+
+ easeOutElastic: function(t) {
+ var s = 1.70158;
+ var p = 0;
+ var a = 1;
+ if (t === 0) {
+ return 0;
+ }
+ if (t === 1) {
+ return 1;
+ }
+ if (!p) {
+ p = 0.3;
+ }
+ if (a < 1) {
+ a = 1;
+ s = p / 4;
+ } else {
+ s = p / (2 * Math.PI) * Math.asin(1 / a);
+ }
+ return a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1;
+ },
+
+ easeInOutElastic: function(t) {
+ var s = 1.70158;
+ var p = 0;
+ var a = 1;
+ if (t === 0) {
+ return 0;
+ }
+ if ((t /= 0.5) === 2) {
+ return 1;
+ }
+ if (!p) {
+ p = 0.45;
+ }
+ if (a < 1) {
+ a = 1;
+ s = p / 4;
+ } else {
+ s = p / (2 * Math.PI) * Math.asin(1 / a);
+ }
+ if (t < 1) {
+ return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));
+ }
+ return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1;
+ },
+ easeInBack: function(t) {
+ var s = 1.70158;
+ return t * t * ((s + 1) * t - s);
+ },
+
+ easeOutBack: function(t) {
+ var s = 1.70158;
+ return (t = t - 1) * t * ((s + 1) * t + s) + 1;
+ },
+
+ easeInOutBack: function(t) {
+ var s = 1.70158;
+ if ((t /= 0.5) < 1) {
+ return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s));
+ }
+ return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
+ },
+
+ easeInBounce: function(t) {
+ return 1 - effects.easeOutBounce(1 - t);
+ },
+
+ easeOutBounce: function(t) {
+ if (t < (1 / 2.75)) {
+ return 7.5625 * t * t;
+ }
+ if (t < (2 / 2.75)) {
+ return 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75;
+ }
+ if (t < (2.5 / 2.75)) {
+ return 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375;
+ }
+ return 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375;
+ },
+
+ easeInOutBounce: function(t) {
+ if (t < 0.5) {
+ return effects.easeInBounce(t * 2) * 0.5;
+ }
+ return effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5;
+ }
+};
+
+module.exports = {
+ effects: effects
+};
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.easing.effects instead.
+ * @function Chart.helpers.easingEffects
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.easingEffects = effects;
+
+},{"42":42}],44:[function(require,module,exports){
+'use strict';
+
+var helpers = require(42);
+
+/**
+ * @alias Chart.helpers.options
+ * @namespace
+ */
+module.exports = {
+ /**
+ * Converts the given line height `value` in pixels for a specific font `size`.
+ * @param {Number|String} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em').
+ * @param {Number} size - The font size (in pixels) used to resolve relative `value`.
+ * @returns {Number} The effective line height in pixels (size * 1.2 if value is invalid).
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height
+ * @since 2.7.0
+ */
+ toLineHeight: function(value, size) {
+ var matches = ('' + value).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);
+ if (!matches || matches[1] === 'normal') {
+ return size * 1.2;
+ }
+
+ value = +matches[2];
+
+ switch (matches[3]) {
+ case 'px':
+ return value;
+ case '%':
+ value /= 100;
+ break;
+ default:
+ break;
+ }
+
+ return size * value;
+ },
+
+ /**
+ * Converts the given value into a padding object with pre-computed width/height.
+ * @param {Number|Object} value - If a number, set the value to all TRBL component,
+ * else, if and object, use defined properties and sets undefined ones to 0.
+ * @returns {Object} The padding values (top, right, bottom, left, width, height)
+ * @since 2.7.0
+ */
+ toPadding: function(value) {
+ var t, r, b, l;
+
+ if (helpers.isObject(value)) {
+ t = +value.top || 0;
+ r = +value.right || 0;
+ b = +value.bottom || 0;
+ l = +value.left || 0;
+ } else {
+ t = r = b = l = +value || 0;
+ }
+
+ return {
+ top: t,
+ right: r,
+ bottom: b,
+ left: l,
+ height: t + b,
+ width: l + r
+ };
+ },
+
+ /**
+ * Evaluates the given `inputs` sequentially and returns the first defined value.
+ * @param {Array[]} inputs - An array of values, falling back to the last value.
+ * @param {Object} [context] - If defined and the current value is a function, the value
+ * is called with `context` as first argument and the result becomes the new input.
+ * @param {Number} [index] - If defined and the current value is an array, the value
+ * at `index` become the new input.
+ * @since 2.7.0
+ */
+ resolve: function(inputs, context, index) {
+ var i, ilen, value;
+
+ for (i = 0, ilen = inputs.length; i < ilen; ++i) {
+ value = inputs[i];
+ if (value === undefined) {
+ continue;
+ }
+ if (context !== undefined && typeof value === 'function') {
+ value = value(context);
+ }
+ if (index !== undefined && helpers.isArray(value)) {
+ value = value[index];
+ }
+ if (value !== undefined) {
+ return value;
+ }
+ }
+ }
+};
+
+},{"42":42}],45:[function(require,module,exports){
+'use strict';
+
+module.exports = require(42);
+module.exports.easing = require(43);
+module.exports.canvas = require(41);
+module.exports.options = require(44);
+
+},{"41":41,"42":42,"43":43,"44":44}],46:[function(require,module,exports){
+/**
+ * Platform fallback implementation (minimal).
+ * @see https://github.com/chartjs/Chart.js/pull/4591#issuecomment-319575939
+ */
+
+module.exports = {
+ acquireContext: function(item) {
+ if (item && item.canvas) {
+ // Support for any object associated to a canvas (including a context2d)
+ item = item.canvas;
+ }
+
+ return item && item.getContext('2d') || null;
+ }
+};
+
+},{}],47:[function(require,module,exports){
+/**
+ * Chart.Platform implementation for targeting a web browser
+ */
+
+'use strict';
+
+var helpers = require(45);
+
+var EXPANDO_KEY = '$chartjs';
+var CSS_PREFIX = 'chartjs-';
+var CSS_RENDER_MONITOR = CSS_PREFIX + 'render-monitor';
+var CSS_RENDER_ANIMATION = CSS_PREFIX + 'render-animation';
+var ANIMATION_START_EVENTS = ['animationstart', 'webkitAnimationStart'];
+
+/**
+ * DOM event types -> Chart.js event types.
+ * Note: only events with different types are mapped.
+ * @see https://developer.mozilla.org/en-US/docs/Web/Events
+ */
+var EVENT_TYPES = {
+ touchstart: 'mousedown',
+ touchmove: 'mousemove',
+ touchend: 'mouseup',
+ pointerenter: 'mouseenter',
+ pointerdown: 'mousedown',
+ pointermove: 'mousemove',
+ pointerup: 'mouseup',
+ pointerleave: 'mouseout',
+ pointerout: 'mouseout'
+};
+
+/**
+ * The "used" size is the final value of a dimension property after all calculations have
+ * been performed. This method uses the computed style of `element` but returns undefined
+ * if the computed style is not expressed in pixels. That can happen in some cases where
+ * `element` has a size relative to its parent and this last one is not yet displayed,
+ * for example because of `display: none` on a parent node.
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
+ * @returns {Number} Size in pixels or undefined if unknown.
+ */
+function readUsedSize(element, property) {
+ var value = helpers.getStyle(element, property);
+ var matches = value && value.match(/^(\d+)(\.\d+)?px$/);
+ return matches ? Number(matches[1]) : undefined;
+}
+
+/**
+ * Initializes the canvas style and render size without modifying the canvas display size,
+ * since responsiveness is handled by the controller.resize() method. The config is used
+ * to determine the aspect ratio to apply in case no explicit height has been specified.
+ */
+function initCanvas(canvas, config) {
+ var style = canvas.style;
+
+ // NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it
+ // returns null or '' if no explicit value has been set to the canvas attribute.
+ var renderHeight = canvas.getAttribute('height');
+ var renderWidth = canvas.getAttribute('width');
+
+ // Chart.js modifies some canvas values that we want to restore on destroy
+ canvas[EXPANDO_KEY] = {
+ initial: {
+ height: renderHeight,
+ width: renderWidth,
+ style: {
+ display: style.display,
+ height: style.height,
+ width: style.width
+ }
+ }
+ };
+
+ // Force canvas to display as block to avoid extra space caused by inline
+ // elements, which would interfere with the responsive resize process.
+ // https://github.com/chartjs/Chart.js/issues/2538
+ style.display = style.display || 'block';
+
+ if (renderWidth === null || renderWidth === '') {
+ var displayWidth = readUsedSize(canvas, 'width');
+ if (displayWidth !== undefined) {
+ canvas.width = displayWidth;
+ }
+ }
+
+ if (renderHeight === null || renderHeight === '') {
+ if (canvas.style.height === '') {
+ // If no explicit render height and style height, let's apply the aspect ratio,
+ // which one can be specified by the user but also by charts as default option
+ // (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2.
+ canvas.height = canvas.width / (config.options.aspectRatio || 2);
+ } else {
+ var displayHeight = readUsedSize(canvas, 'height');
+ if (displayWidth !== undefined) {
+ canvas.height = displayHeight;
+ }
+ }
+ }
+
+ return canvas;
+}
+
+/**
+ * Detects support for options object argument in addEventListener.
+ * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
+ * @private
+ */
+var supportsEventListenerOptions = (function() {
+ var supports = false;
+ try {
+ var options = Object.defineProperty({}, 'passive', {
+ get: function() {
+ supports = true;
+ }
+ });
+ window.addEventListener('e', null, options);
+ } catch (e) {
+ // continue regardless of error
+ }
+ return supports;
+}());
+
+// Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events.
+// https://github.com/chartjs/Chart.js/issues/4287
+var eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false;
+
+function addEventListener(node, type, listener) {
+ node.addEventListener(type, listener, eventListenerOptions);
+}
+
+function removeEventListener(node, type, listener) {
+ node.removeEventListener(type, listener, eventListenerOptions);
+}
+
+function createEvent(type, chart, x, y, nativeEvent) {
+ return {
+ type: type,
+ chart: chart,
+ native: nativeEvent || null,
+ x: x !== undefined ? x : null,
+ y: y !== undefined ? y : null,
+ };
+}
+
+function fromNativeEvent(event, chart) {
+ var type = EVENT_TYPES[event.type] || event.type;
+ var pos = helpers.getRelativePosition(event, chart);
+ return createEvent(type, chart, pos.x, pos.y, event);
+}
+
+function throttled(fn, thisArg) {
+ var ticking = false;
+ var args = [];
+
+ return function() {
+ args = Array.prototype.slice.call(arguments);
+ thisArg = thisArg || this;
+
+ if (!ticking) {
+ ticking = true;
+ helpers.requestAnimFrame.call(window, function() {
+ ticking = false;
+ fn.apply(thisArg, args);
+ });
+ }
+ };
+}
+
+// Implementation based on https://github.com/marcj/css-element-queries
+function createResizer(handler) {
+ var resizer = document.createElement('div');
+ var cls = CSS_PREFIX + 'size-monitor';
+ var maxSize = 1000000;
+ var style =
+ 'position:absolute;' +
+ 'left:0;' +
+ 'top:0;' +
+ 'right:0;' +
+ 'bottom:0;' +
+ 'overflow:hidden;' +
+ 'pointer-events:none;' +
+ 'visibility:hidden;' +
+ 'z-index:-1;';
+
+ resizer.style.cssText = style;
+ resizer.className = cls;
+ resizer.innerHTML =
+ '' +
+ '';
+
+ var expand = resizer.childNodes[0];
+ var shrink = resizer.childNodes[1];
+
+ resizer._reset = function() {
+ expand.scrollLeft = maxSize;
+ expand.scrollTop = maxSize;
+ shrink.scrollLeft = maxSize;
+ shrink.scrollTop = maxSize;
+ };
+ var onScroll = function() {
+ resizer._reset();
+ handler();
+ };
+
+ addEventListener(expand, 'scroll', onScroll.bind(expand, 'expand'));
+ addEventListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink'));
+
+ return resizer;
+}
+
+// https://davidwalsh.name/detect-node-insertion
+function watchForRender(node, handler) {
+ var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});
+ var proxy = expando.renderProxy = function(e) {
+ if (e.animationName === CSS_RENDER_ANIMATION) {
+ handler();
+ }
+ };
+
+ helpers.each(ANIMATION_START_EVENTS, function(type) {
+ addEventListener(node, type, proxy);
+ });
+
+ // #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class
+ // is removed then added back immediately (same animation frame?). Accessing the
+ // `offsetParent` property will force a reflow and re-evaluate the CSS animation.
+ // https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics
+ // https://github.com/chartjs/Chart.js/issues/4737
+ expando.reflow = !!node.offsetParent;
+
+ node.classList.add(CSS_RENDER_MONITOR);
+}
+
+function unwatchForRender(node) {
+ var expando = node[EXPANDO_KEY] || {};
+ var proxy = expando.renderProxy;
+
+ if (proxy) {
+ helpers.each(ANIMATION_START_EVENTS, function(type) {
+ removeEventListener(node, type, proxy);
+ });
+
+ delete expando.renderProxy;
+ }
+
+ node.classList.remove(CSS_RENDER_MONITOR);
+}
+
+function addResizeListener(node, listener, chart) {
+ var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});
+
+ // Let's keep track of this added resizer and thus avoid DOM query when removing it.
+ var resizer = expando.resizer = createResizer(throttled(function() {
+ if (expando.resizer) {
+ return listener(createEvent('resize', chart));
+ }
+ }));
+
+ // The resizer needs to be attached to the node parent, so we first need to be
+ // sure that `node` is attached to the DOM before injecting the resizer element.
+ watchForRender(node, function() {
+ if (expando.resizer) {
+ var container = node.parentNode;
+ if (container && container !== resizer.parentNode) {
+ container.insertBefore(resizer, container.firstChild);
+ }
+
+ // The container size might have changed, let's reset the resizer state.
+ resizer._reset();
+ }
+ });
+}
+
+function removeResizeListener(node) {
+ var expando = node[EXPANDO_KEY] || {};
+ var resizer = expando.resizer;
+
+ delete expando.resizer;
+ unwatchForRender(node);
+
+ if (resizer && resizer.parentNode) {
+ resizer.parentNode.removeChild(resizer);
+ }
+}
+
+function injectCSS(platform, css) {
+ // http://stackoverflow.com/q/3922139
+ var style = platform._style || document.createElement('style');
+ if (!platform._style) {
+ platform._style = style;
+ css = '/* Chart.js */\n' + css;
+ style.setAttribute('type', 'text/css');
+ document.getElementsByTagName('head')[0].appendChild(style);
+ }
+
+ style.appendChild(document.createTextNode(css));
+}
+
+module.exports = {
+ /**
+ * This property holds whether this platform is enabled for the current environment.
+ * Currently used by platform.js to select the proper implementation.
+ * @private
+ */
+ _enabled: typeof window !== 'undefined' && typeof document !== 'undefined',
+
+ initialize: function() {
+ var keyframes = 'from{opacity:0.99}to{opacity:1}';
+
+ injectCSS(this,
+ // DOM rendering detection
+ // https://davidwalsh.name/detect-node-insertion
+ '@-webkit-keyframes ' + CSS_RENDER_ANIMATION + '{' + keyframes + '}' +
+ '@keyframes ' + CSS_RENDER_ANIMATION + '{' + keyframes + '}' +
+ '.' + CSS_RENDER_MONITOR + '{' +
+ '-webkit-animation:' + CSS_RENDER_ANIMATION + ' 0.001s;' +
+ 'animation:' + CSS_RENDER_ANIMATION + ' 0.001s;' +
+ '}'
+ );
+ },
+
+ acquireContext: function(item, config) {
+ if (typeof item === 'string') {
+ item = document.getElementById(item);
+ } else if (item.length) {
+ // Support for array based queries (such as jQuery)
+ item = item[0];
+ }
+
+ if (item && item.canvas) {
+ // Support for any object associated to a canvas (including a context2d)
+ item = item.canvas;
+ }
+
+ // To prevent canvas fingerprinting, some add-ons undefine the getContext
+ // method, for example: https://github.com/kkapsner/CanvasBlocker
+ // https://github.com/chartjs/Chart.js/issues/2807
+ var context = item && item.getContext && item.getContext('2d');
+
+ // `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is
+ // inside an iframe or when running in a protected environment. We could guess the
+ // types from their toString() value but let's keep things flexible and assume it's
+ // a sufficient condition if the item has a context2D which has item as `canvas`.
+ // https://github.com/chartjs/Chart.js/issues/3887
+ // https://github.com/chartjs/Chart.js/issues/4102
+ // https://github.com/chartjs/Chart.js/issues/4152
+ if (context && context.canvas === item) {
+ initCanvas(item, config);
+ return context;
+ }
+
+ return null;
+ },
+
+ releaseContext: function(context) {
+ var canvas = context.canvas;
+ if (!canvas[EXPANDO_KEY]) {
+ return;
+ }
+
+ var initial = canvas[EXPANDO_KEY].initial;
+ ['height', 'width'].forEach(function(prop) {
+ var value = initial[prop];
+ if (helpers.isNullOrUndef(value)) {
+ canvas.removeAttribute(prop);
+ } else {
+ canvas.setAttribute(prop, value);
+ }
+ });
+
+ helpers.each(initial.style || {}, function(value, key) {
+ canvas.style[key] = value;
+ });
+
+ // The canvas render size might have been changed (and thus the state stack discarded),
+ // we can't use save() and restore() to restore the initial state. So make sure that at
+ // least the canvas context is reset to the default state by setting the canvas width.
+ // https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html
+ canvas.width = canvas.width;
+
+ delete canvas[EXPANDO_KEY];
+ },
+
+ addEventListener: function(chart, type, listener) {
+ var canvas = chart.canvas;
+ if (type === 'resize') {
+ // Note: the resize event is not supported on all browsers.
+ addResizeListener(canvas, listener, chart);
+ return;
+ }
+
+ var expando = listener[EXPANDO_KEY] || (listener[EXPANDO_KEY] = {});
+ var proxies = expando.proxies || (expando.proxies = {});
+ var proxy = proxies[chart.id + '_' + type] = function(event) {
+ listener(fromNativeEvent(event, chart));
+ };
+
+ addEventListener(canvas, type, proxy);
+ },
+
+ removeEventListener: function(chart, type, listener) {
+ var canvas = chart.canvas;
+ if (type === 'resize') {
+ // Note: the resize event is not supported on all browsers.
+ removeResizeListener(canvas, listener);
+ return;
+ }
+
+ var expando = listener[EXPANDO_KEY] || {};
+ var proxies = expando.proxies || {};
+ var proxy = proxies[chart.id + '_' + type];
+ if (!proxy) {
+ return;
+ }
+
+ removeEventListener(canvas, type, proxy);
+ }
+};
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use EventTarget.addEventListener instead.
+ * EventTarget.addEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
+ * @function Chart.helpers.addEvent
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.addEvent = addEventListener;
+
+/**
+ * Provided for backward compatibility, use EventTarget.removeEventListener instead.
+ * EventTarget.removeEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener
+ * @function Chart.helpers.removeEvent
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.removeEvent = removeEventListener;
+
+},{"45":45}],48:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+var basic = require(46);
+var dom = require(47);
+
+// @TODO Make possible to select another platform at build time.
+var implementation = dom._enabled ? dom : basic;
+
+/**
+ * @namespace Chart.platform
+ * @see https://chartjs.gitbooks.io/proposals/content/Platform.html
+ * @since 2.4.0
+ */
+module.exports = helpers.extend({
+ /**
+ * @since 2.7.0
+ */
+ initialize: function() {},
+
+ /**
+ * Called at chart construction time, returns a context2d instance implementing
+ * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}.
+ * @param {*} item - The native item from which to acquire context (platform specific)
+ * @param {Object} options - The chart options
+ * @returns {CanvasRenderingContext2D} context2d instance
+ */
+ acquireContext: function() {},
+
+ /**
+ * Called at chart destruction time, releases any resources associated to the context
+ * previously returned by the acquireContext() method.
+ * @param {CanvasRenderingContext2D} context - The context2d instance
+ * @returns {Boolean} true if the method succeeded, else false
+ */
+ releaseContext: function() {},
+
+ /**
+ * Registers the specified listener on the given chart.
+ * @param {Chart} chart - Chart from which to listen for event
+ * @param {String} type - The ({@link IEvent}) type to listen for
+ * @param {Function} listener - Receives a notification (an object that implements
+ * the {@link IEvent} interface) when an event of the specified type occurs.
+ */
+ addEventListener: function() {},
+
+ /**
+ * Removes the specified listener previously registered with addEventListener.
+ * @param {Chart} chart -Chart from which to remove the listener
+ * @param {String} type - The ({@link IEvent}) type to remove
+ * @param {Function} listener - The listener function to remove from the event target.
+ */
+ removeEventListener: function() {}
+
+}, implementation);
+
+/**
+ * @interface IPlatform
+ * Allows abstracting platform dependencies away from the chart
+ * @borrows Chart.platform.acquireContext as acquireContext
+ * @borrows Chart.platform.releaseContext as releaseContext
+ * @borrows Chart.platform.addEventListener as addEventListener
+ * @borrows Chart.platform.removeEventListener as removeEventListener
+ */
+
+/**
+ * @interface IEvent
+ * @prop {String} type - The event type name, possible values are:
+ * 'contextmenu', 'mouseenter', 'mousedown', 'mousemove', 'mouseup', 'mouseout',
+ * 'click', 'dblclick', 'keydown', 'keypress', 'keyup' and 'resize'
+ * @prop {*} native - The original native event (null for emulated events, e.g. 'resize')
+ * @prop {Number} x - The mouse x position, relative to the canvas (null for incompatible events)
+ * @prop {Number} y - The mouse y position, relative to the canvas (null for incompatible events)
+ */
+
+},{"45":45,"46":46,"47":47}],49:[function(require,module,exports){
+'use strict';
+
+module.exports = {};
+module.exports.filler = require(50);
+module.exports.legend = require(51);
+module.exports.title = require(52);
+
+},{"50":50,"51":51,"52":52}],50:[function(require,module,exports){
+/**
+ * Plugin based on discussion from the following Chart.js issues:
+ * @see https://github.com/chartjs/Chart.js/issues/2380#issuecomment-279961569
+ * @see https://github.com/chartjs/Chart.js/issues/2440#issuecomment-256461897
+ */
+
+'use strict';
+
+var defaults = require(25);
+var elements = require(40);
+var helpers = require(45);
+
+defaults._set('global', {
+ plugins: {
+ filler: {
+ propagate: true
+ }
+ }
+});
+
+var mappers = {
+ dataset: function(source) {
+ var index = source.fill;
+ var chart = source.chart;
+ var meta = chart.getDatasetMeta(index);
+ var visible = meta && chart.isDatasetVisible(index);
+ var points = (visible && meta.dataset._children) || [];
+ var length = points.length || 0;
+
+ return !length ? null : function(point, i) {
+ return (i < length && points[i]._view) || null;
+ };
+ },
+
+ boundary: function(source) {
+ var boundary = source.boundary;
+ var x = boundary ? boundary.x : null;
+ var y = boundary ? boundary.y : null;
+
+ return function(point) {
+ return {
+ x: x === null ? point.x : x,
+ y: y === null ? point.y : y,
+ };
+ };
+ }
+};
+
+// @todo if (fill[0] === '#')
+function decodeFill(el, index, count) {
+ var model = el._model || {};
+ var fill = model.fill;
+ var target;
+
+ if (fill === undefined) {
+ fill = !!model.backgroundColor;
+ }
+
+ if (fill === false || fill === null) {
+ return false;
+ }
+
+ if (fill === true) {
+ return 'origin';
+ }
+
+ target = parseFloat(fill, 10);
+ if (isFinite(target) && Math.floor(target) === target) {
+ if (fill[0] === '-' || fill[0] === '+') {
+ target = index + target;
+ }
+
+ if (target === index || target < 0 || target >= count) {
+ return false;
+ }
+
+ return target;
+ }
+
+ switch (fill) {
+ // compatibility
+ case 'bottom':
+ return 'start';
+ case 'top':
+ return 'end';
+ case 'zero':
+ return 'origin';
+ // supported boundaries
+ case 'origin':
+ case 'start':
+ case 'end':
+ return fill;
+ // invalid fill values
+ default:
+ return false;
+ }
+}
+
+function computeBoundary(source) {
+ var model = source.el._model || {};
+ var scale = source.el._scale || {};
+ var fill = source.fill;
+ var target = null;
+ var horizontal;
+
+ if (isFinite(fill)) {
+ return null;
+ }
+
+ // Backward compatibility: until v3, we still need to support boundary values set on
+ // the model (scaleTop, scaleBottom and scaleZero) because some external plugins and
+ // controllers might still use it (e.g. the Smith chart).
+
+ if (fill === 'start') {
+ target = model.scaleBottom === undefined ? scale.bottom : model.scaleBottom;
+ } else if (fill === 'end') {
+ target = model.scaleTop === undefined ? scale.top : model.scaleTop;
+ } else if (model.scaleZero !== undefined) {
+ target = model.scaleZero;
+ } else if (scale.getBasePosition) {
+ target = scale.getBasePosition();
+ } else if (scale.getBasePixel) {
+ target = scale.getBasePixel();
+ }
+
+ if (target !== undefined && target !== null) {
+ if (target.x !== undefined && target.y !== undefined) {
+ return target;
+ }
+
+ if (typeof target === 'number' && isFinite(target)) {
+ horizontal = scale.isHorizontal();
+ return {
+ x: horizontal ? target : null,
+ y: horizontal ? null : target
+ };
+ }
+ }
+
+ return null;
+}
+
+function resolveTarget(sources, index, propagate) {
+ var source = sources[index];
+ var fill = source.fill;
+ var visited = [index];
+ var target;
+
+ if (!propagate) {
+ return fill;
+ }
+
+ while (fill !== false && visited.indexOf(fill) === -1) {
+ if (!isFinite(fill)) {
+ return fill;
+ }
+
+ target = sources[fill];
+ if (!target) {
+ return false;
+ }
+
+ if (target.visible) {
+ return fill;
+ }
+
+ visited.push(fill);
+ fill = target.fill;
+ }
+
+ return false;
+}
+
+function createMapper(source) {
+ var fill = source.fill;
+ var type = 'dataset';
+
+ if (fill === false) {
+ return null;
+ }
+
+ if (!isFinite(fill)) {
+ type = 'boundary';
+ }
+
+ return mappers[type](source);
+}
+
+function isDrawable(point) {
+ return point && !point.skip;
+}
+
+function drawArea(ctx, curve0, curve1, len0, len1) {
+ var i;
+
+ if (!len0 || !len1) {
+ return;
+ }
+
+ // building first area curve (normal)
+ ctx.moveTo(curve0[0].x, curve0[0].y);
+ for (i = 1; i < len0; ++i) {
+ helpers.canvas.lineTo(ctx, curve0[i - 1], curve0[i]);
+ }
+
+ // joining the two area curves
+ ctx.lineTo(curve1[len1 - 1].x, curve1[len1 - 1].y);
+
+ // building opposite area curve (reverse)
+ for (i = len1 - 1; i > 0; --i) {
+ helpers.canvas.lineTo(ctx, curve1[i], curve1[i - 1], true);
+ }
+}
+
+function doFill(ctx, points, mapper, view, color, loop) {
+ var count = points.length;
+ var span = view.spanGaps;
+ var curve0 = [];
+ var curve1 = [];
+ var len0 = 0;
+ var len1 = 0;
+ var i, ilen, index, p0, p1, d0, d1;
+
+ ctx.beginPath();
+
+ for (i = 0, ilen = (count + !!loop); i < ilen; ++i) {
+ index = i % count;
+ p0 = points[index]._view;
+ p1 = mapper(p0, index, view);
+ d0 = isDrawable(p0);
+ d1 = isDrawable(p1);
+
+ if (d0 && d1) {
+ len0 = curve0.push(p0);
+ len1 = curve1.push(p1);
+ } else if (len0 && len1) {
+ if (!span) {
+ drawArea(ctx, curve0, curve1, len0, len1);
+ len0 = len1 = 0;
+ curve0 = [];
+ curve1 = [];
+ } else {
+ if (d0) {
+ curve0.push(p0);
+ }
+ if (d1) {
+ curve1.push(p1);
+ }
+ }
+ }
+ }
+
+ drawArea(ctx, curve0, curve1, len0, len1);
+
+ ctx.closePath();
+ ctx.fillStyle = color;
+ ctx.fill();
+}
+
+module.exports = {
+ id: 'filler',
+
+ afterDatasetsUpdate: function(chart, options) {
+ var count = (chart.data.datasets || []).length;
+ var propagate = options.propagate;
+ var sources = [];
+ var meta, i, el, source;
+
+ for (i = 0; i < count; ++i) {
+ meta = chart.getDatasetMeta(i);
+ el = meta.dataset;
+ source = null;
+
+ if (el && el._model && el instanceof elements.Line) {
+ source = {
+ visible: chart.isDatasetVisible(i),
+ fill: decodeFill(el, i, count),
+ chart: chart,
+ el: el
+ };
+ }
+
+ meta.$filler = source;
+ sources.push(source);
+ }
+
+ for (i = 0; i < count; ++i) {
+ source = sources[i];
+ if (!source) {
+ continue;
+ }
+
+ source.fill = resolveTarget(sources, i, propagate);
+ source.boundary = computeBoundary(source);
+ source.mapper = createMapper(source);
+ }
+ },
+
+ beforeDatasetDraw: function(chart, args) {
+ var meta = args.meta.$filler;
+ if (!meta) {
+ return;
+ }
+
+ var ctx = chart.ctx;
+ var el = meta.el;
+ var view = el._view;
+ var points = el._children || [];
+ var mapper = meta.mapper;
+ var color = view.backgroundColor || defaults.global.defaultColor;
+
+ if (mapper && color && points.length) {
+ helpers.canvas.clipArea(ctx, chart.chartArea);
+ doFill(ctx, points, mapper, view, color, el._loop);
+ helpers.canvas.unclipArea(ctx);
+ }
+ }
+};
+
+},{"25":25,"40":40,"45":45}],51:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+var layouts = require(30);
+
+var noop = helpers.noop;
+
+defaults._set('global', {
+ legend: {
+ display: true,
+ position: 'top',
+ fullWidth: true,
+ reverse: false,
+ weight: 1000,
+
+ // a callback that will handle
+ onClick: function(e, legendItem) {
+ var index = legendItem.datasetIndex;
+ var ci = this.chart;
+ var meta = ci.getDatasetMeta(index);
+
+ // See controller.isDatasetVisible comment
+ meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
+
+ // We hid a dataset ... rerender the chart
+ ci.update();
+ },
+
+ onHover: null,
+
+ labels: {
+ boxWidth: 40,
+ padding: 10,
+ // Generates labels shown in the legend
+ // Valid properties to return:
+ // text : text to display
+ // fillStyle : fill of coloured box
+ // strokeStyle: stroke of coloured box
+ // hidden : if this legend item refers to a hidden item
+ // lineCap : cap style for line
+ // lineDash
+ // lineDashOffset :
+ // lineJoin :
+ // lineWidth :
+ generateLabels: function(chart) {
+ var data = chart.data;
+ return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {
+ return {
+ text: dataset.label,
+ fillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]),
+ hidden: !chart.isDatasetVisible(i),
+ lineCap: dataset.borderCapStyle,
+ lineDash: dataset.borderDash,
+ lineDashOffset: dataset.borderDashOffset,
+ lineJoin: dataset.borderJoinStyle,
+ lineWidth: dataset.borderWidth,
+ strokeStyle: dataset.borderColor,
+ pointStyle: dataset.pointStyle,
+
+ // Below is extra data used for toggling the datasets
+ datasetIndex: i
+ };
+ }, this) : [];
+ }
+ }
+ },
+
+ legendCallback: function(chart) {
+ var text = [];
+ text.push('');
+ for (var i = 0; i < chart.data.datasets.length; i++) {
+ text.push(' ');
+ if (chart.data.datasets[i].label) {
+ text.push(chart.data.datasets[i].label);
+ }
+ text.push(' ');
+ }
+ text.push(' ');
+ return text.join('');
+ }
+});
+
+/**
+ * Helper function to get the box width based on the usePointStyle option
+ * @param labelopts {Object} the label options on the legend
+ * @param fontSize {Number} the label font size
+ * @return {Number} width of the color box area
+ */
+function getBoxWidth(labelOpts, fontSize) {
+ return labelOpts.usePointStyle ?
+ fontSize * Math.SQRT2 :
+ labelOpts.boxWidth;
+}
+
+/**
+ * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required!
+ */
+var Legend = Element.extend({
+
+ initialize: function(config) {
+ helpers.extend(this, config);
+
+ // Contains hit boxes for each dataset (in dataset order)
+ this.legendHitBoxes = [];
+
+ // Are we in doughnut mode which has a different data type
+ this.doughnutMode = false;
+ },
+
+ // These methods are ordered by lifecycle. Utilities then follow.
+ // Any function defined here is inherited by all legend types.
+ // Any function can be extended by the legend type
+
+ beforeUpdate: noop,
+ update: function(maxWidth, maxHeight, margins) {
+ var me = this;
+
+ // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
+ me.beforeUpdate();
+
+ // Absorb the master measurements
+ me.maxWidth = maxWidth;
+ me.maxHeight = maxHeight;
+ me.margins = margins;
+
+ // Dimensions
+ me.beforeSetDimensions();
+ me.setDimensions();
+ me.afterSetDimensions();
+ // Labels
+ me.beforeBuildLabels();
+ me.buildLabels();
+ me.afterBuildLabels();
+
+ // Fit
+ me.beforeFit();
+ me.fit();
+ me.afterFit();
+ //
+ me.afterUpdate();
+
+ return me.minSize;
+ },
+ afterUpdate: noop,
+
+ //
+
+ beforeSetDimensions: noop,
+ setDimensions: function() {
+ var me = this;
+ // Set the unconstrained dimension before label rotation
+ if (me.isHorizontal()) {
+ // Reset position before calculating rotation
+ me.width = me.maxWidth;
+ me.left = 0;
+ me.right = me.width;
+ } else {
+ me.height = me.maxHeight;
+
+ // Reset position before calculating rotation
+ me.top = 0;
+ me.bottom = me.height;
+ }
+
+ // Reset padding
+ me.paddingLeft = 0;
+ me.paddingTop = 0;
+ me.paddingRight = 0;
+ me.paddingBottom = 0;
+
+ // Reset minSize
+ me.minSize = {
+ width: 0,
+ height: 0
+ };
+ },
+ afterSetDimensions: noop,
+
+ //
+
+ beforeBuildLabels: noop,
+ buildLabels: function() {
+ var me = this;
+ var labelOpts = me.options.labels || {};
+ var legendItems = helpers.callback(labelOpts.generateLabels, [me.chart], me) || [];
+
+ if (labelOpts.filter) {
+ legendItems = legendItems.filter(function(item) {
+ return labelOpts.filter(item, me.chart.data);
+ });
+ }
+
+ if (me.options.reverse) {
+ legendItems.reverse();
+ }
+
+ me.legendItems = legendItems;
+ },
+ afterBuildLabels: noop,
+
+ //
+
+ beforeFit: noop,
+ fit: function() {
+ var me = this;
+ var opts = me.options;
+ var labelOpts = opts.labels;
+ var display = opts.display;
+
+ var ctx = me.ctx;
+
+ var globalDefault = defaults.global;
+ var valueOrDefault = helpers.valueOrDefault;
+ var fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize);
+ var fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle);
+ var fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily);
+ var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
+
+ // Reset hit boxes
+ var hitboxes = me.legendHitBoxes = [];
+
+ var minSize = me.minSize;
+ var isHorizontal = me.isHorizontal();
+
+ if (isHorizontal) {
+ minSize.width = me.maxWidth; // fill all the width
+ minSize.height = display ? 10 : 0;
+ } else {
+ minSize.width = display ? 10 : 0;
+ minSize.height = me.maxHeight; // fill all the height
+ }
+
+ // Increase sizes here
+ if (display) {
+ ctx.font = labelFont;
+
+ if (isHorizontal) {
+ // Labels
+
+ // Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one
+ var lineWidths = me.lineWidths = [0];
+ var totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0;
+
+ ctx.textAlign = 'left';
+ ctx.textBaseline = 'top';
+
+ helpers.each(me.legendItems, function(legendItem, i) {
+ var boxWidth = getBoxWidth(labelOpts, fontSize);
+ var width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
+
+ if (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {
+ totalHeight += fontSize + (labelOpts.padding);
+ lineWidths[lineWidths.length] = me.left;
+ }
+
+ // Store the hitbox width and height here. Final position will be updated in `draw`
+ hitboxes[i] = {
+ left: 0,
+ top: 0,
+ width: width,
+ height: fontSize
+ };
+
+ lineWidths[lineWidths.length - 1] += width + labelOpts.padding;
+ });
+
+ minSize.height += totalHeight;
+
+ } else {
+ var vPadding = labelOpts.padding;
+ var columnWidths = me.columnWidths = [];
+ var totalWidth = labelOpts.padding;
+ var currentColWidth = 0;
+ var currentColHeight = 0;
+ var itemHeight = fontSize + vPadding;
+
+ helpers.each(me.legendItems, function(legendItem, i) {
+ var boxWidth = getBoxWidth(labelOpts, fontSize);
+ var itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
+
+ // If too tall, go to new column
+ if (currentColHeight + itemHeight > minSize.height) {
+ totalWidth += currentColWidth + labelOpts.padding;
+ columnWidths.push(currentColWidth); // previous column width
+
+ currentColWidth = 0;
+ currentColHeight = 0;
+ }
+
+ // Get max width
+ currentColWidth = Math.max(currentColWidth, itemWidth);
+ currentColHeight += itemHeight;
+
+ // Store the hitbox width and height here. Final position will be updated in `draw`
+ hitboxes[i] = {
+ left: 0,
+ top: 0,
+ width: itemWidth,
+ height: fontSize
+ };
+ });
+
+ totalWidth += currentColWidth;
+ columnWidths.push(currentColWidth);
+ minSize.width += totalWidth;
+ }
+ }
+
+ me.width = minSize.width;
+ me.height = minSize.height;
+ },
+ afterFit: noop,
+
+ // Shared Methods
+ isHorizontal: function() {
+ return this.options.position === 'top' || this.options.position === 'bottom';
+ },
+
+ // Actually draw the legend on the canvas
+ draw: function() {
+ var me = this;
+ var opts = me.options;
+ var labelOpts = opts.labels;
+ var globalDefault = defaults.global;
+ var lineDefault = globalDefault.elements.line;
+ var legendWidth = me.width;
+ var lineWidths = me.lineWidths;
+
+ if (opts.display) {
+ var ctx = me.ctx;
+ var valueOrDefault = helpers.valueOrDefault;
+ var fontColor = valueOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor);
+ var fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize);
+ var fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle);
+ var fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily);
+ var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
+ var cursor;
+
+ // Canvas setup
+ ctx.textAlign = 'left';
+ ctx.textBaseline = 'middle';
+ ctx.lineWidth = 0.5;
+ ctx.strokeStyle = fontColor; // for strikethrough effect
+ ctx.fillStyle = fontColor; // render in correct colour
+ ctx.font = labelFont;
+
+ var boxWidth = getBoxWidth(labelOpts, fontSize);
+ var hitboxes = me.legendHitBoxes;
+
+ // current position
+ var drawLegendBox = function(x, y, legendItem) {
+ if (isNaN(boxWidth) || boxWidth <= 0) {
+ return;
+ }
+
+ // Set the ctx for the box
+ ctx.save();
+
+ ctx.fillStyle = valueOrDefault(legendItem.fillStyle, globalDefault.defaultColor);
+ ctx.lineCap = valueOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);
+ ctx.lineDashOffset = valueOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);
+ ctx.lineJoin = valueOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);
+ ctx.lineWidth = valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth);
+ ctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);
+ var isLineWidthZero = (valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth) === 0);
+
+ if (ctx.setLineDash) {
+ // IE 9 and 10 do not support line dash
+ ctx.setLineDash(valueOrDefault(legendItem.lineDash, lineDefault.borderDash));
+ }
+
+ if (opts.labels && opts.labels.usePointStyle) {
+ // Recalculate x and y for drawPoint() because its expecting
+ // x and y to be center of figure (instead of top left)
+ var radius = fontSize * Math.SQRT2 / 2;
+ var offSet = radius / Math.SQRT2;
+ var centerX = x + offSet;
+ var centerY = y + offSet;
+
+ // Draw pointStyle as legend symbol
+ helpers.canvas.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);
+ } else {
+ // Draw box as legend symbol
+ if (!isLineWidthZero) {
+ ctx.strokeRect(x, y, boxWidth, fontSize);
+ }
+ ctx.fillRect(x, y, boxWidth, fontSize);
+ }
+
+ ctx.restore();
+ };
+ var fillText = function(x, y, legendItem, textWidth) {
+ var halfFontSize = fontSize / 2;
+ var xLeft = boxWidth + halfFontSize + x;
+ var yMiddle = y + halfFontSize;
+
+ ctx.fillText(legendItem.text, xLeft, yMiddle);
+
+ if (legendItem.hidden) {
+ // Strikethrough the text if hidden
+ ctx.beginPath();
+ ctx.lineWidth = 2;
+ ctx.moveTo(xLeft, yMiddle);
+ ctx.lineTo(xLeft + textWidth, yMiddle);
+ ctx.stroke();
+ }
+ };
+
+ // Horizontal
+ var isHorizontal = me.isHorizontal();
+ if (isHorizontal) {
+ cursor = {
+ x: me.left + ((legendWidth - lineWidths[0]) / 2),
+ y: me.top + labelOpts.padding,
+ line: 0
+ };
+ } else {
+ cursor = {
+ x: me.left + labelOpts.padding,
+ y: me.top + labelOpts.padding,
+ line: 0
+ };
+ }
+
+ var itemHeight = fontSize + labelOpts.padding;
+ helpers.each(me.legendItems, function(legendItem, i) {
+ var textWidth = ctx.measureText(legendItem.text).width;
+ var width = boxWidth + (fontSize / 2) + textWidth;
+ var x = cursor.x;
+ var y = cursor.y;
+
+ if (isHorizontal) {
+ if (x + width >= legendWidth) {
+ y = cursor.y += itemHeight;
+ cursor.line++;
+ x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);
+ }
+ } else if (y + itemHeight > me.bottom) {
+ x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;
+ y = cursor.y = me.top + labelOpts.padding;
+ cursor.line++;
+ }
+
+ drawLegendBox(x, y, legendItem);
+
+ hitboxes[i].left = x;
+ hitboxes[i].top = y;
+
+ // Fill the actual label
+ fillText(x, y, legendItem, textWidth);
+
+ if (isHorizontal) {
+ cursor.x += width + (labelOpts.padding);
+ } else {
+ cursor.y += itemHeight;
+ }
+
+ });
+ }
+ },
+
+ /**
+ * Handle an event
+ * @private
+ * @param {IEvent} event - The event to handle
+ * @return {Boolean} true if a change occured
+ */
+ handleEvent: function(e) {
+ var me = this;
+ var opts = me.options;
+ var type = e.type === 'mouseup' ? 'click' : e.type;
+ var changed = false;
+
+ if (type === 'mousemove') {
+ if (!opts.onHover) {
+ return;
+ }
+ } else if (type === 'click') {
+ if (!opts.onClick) {
+ return;
+ }
+ } else {
+ return;
+ }
+
+ // Chart event already has relative position in it
+ var x = e.x;
+ var y = e.y;
+
+ if (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) {
+ // See if we are touching one of the dataset boxes
+ var lh = me.legendHitBoxes;
+ for (var i = 0; i < lh.length; ++i) {
+ var hitBox = lh[i];
+
+ if (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {
+ // Touching an element
+ if (type === 'click') {
+ // use e.native for backwards compatibility
+ opts.onClick.call(me, e.native, me.legendItems[i]);
+ changed = true;
+ break;
+ } else if (type === 'mousemove') {
+ // use e.native for backwards compatibility
+ opts.onHover.call(me, e.native, me.legendItems[i]);
+ changed = true;
+ break;
+ }
+ }
+ }
+ }
+
+ return changed;
+ }
+});
+
+function createNewLegendAndAttach(chart, legendOpts) {
+ var legend = new Legend({
+ ctx: chart.ctx,
+ options: legendOpts,
+ chart: chart
+ });
+
+ layouts.configure(chart, legend, legendOpts);
+ layouts.addBox(chart, legend);
+ chart.legend = legend;
+}
+
+module.exports = {
+ id: 'legend',
+
+ /**
+ * Backward compatibility: since 2.1.5, the legend is registered as a plugin, making
+ * Chart.Legend obsolete. To avoid a breaking change, we export the Legend as part of
+ * the plugin, which one will be re-exposed in the chart.js file.
+ * https://github.com/chartjs/Chart.js/pull/2640
+ * @private
+ */
+ _element: Legend,
+
+ beforeInit: function(chart) {
+ var legendOpts = chart.options.legend;
+
+ if (legendOpts) {
+ createNewLegendAndAttach(chart, legendOpts);
+ }
+ },
+
+ beforeUpdate: function(chart) {
+ var legendOpts = chart.options.legend;
+ var legend = chart.legend;
+
+ if (legendOpts) {
+ helpers.mergeIf(legendOpts, defaults.global.legend);
+
+ if (legend) {
+ layouts.configure(chart, legend, legendOpts);
+ legend.options = legendOpts;
+ } else {
+ createNewLegendAndAttach(chart, legendOpts);
+ }
+ } else if (legend) {
+ layouts.removeBox(chart, legend);
+ delete chart.legend;
+ }
+ },
+
+ afterEvent: function(chart, e) {
+ var legend = chart.legend;
+ if (legend) {
+ legend.handleEvent(e);
+ }
+ }
+};
+
+},{"25":25,"26":26,"30":30,"45":45}],52:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var Element = require(26);
+var helpers = require(45);
+var layouts = require(30);
+
+var noop = helpers.noop;
+
+defaults._set('global', {
+ title: {
+ display: false,
+ fontStyle: 'bold',
+ fullWidth: true,
+ lineHeight: 1.2,
+ padding: 10,
+ position: 'top',
+ text: '',
+ weight: 2000 // by default greater than legend (1000) to be above
+ }
+});
+
+/**
+ * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required!
+ */
+var Title = Element.extend({
+ initialize: function(config) {
+ var me = this;
+ helpers.extend(me, config);
+
+ // Contains hit boxes for each dataset (in dataset order)
+ me.legendHitBoxes = [];
+ },
+
+ // These methods are ordered by lifecycle. Utilities then follow.
+
+ beforeUpdate: noop,
+ update: function(maxWidth, maxHeight, margins) {
+ var me = this;
+
+ // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
+ me.beforeUpdate();
+
+ // Absorb the master measurements
+ me.maxWidth = maxWidth;
+ me.maxHeight = maxHeight;
+ me.margins = margins;
+
+ // Dimensions
+ me.beforeSetDimensions();
+ me.setDimensions();
+ me.afterSetDimensions();
+ // Labels
+ me.beforeBuildLabels();
+ me.buildLabels();
+ me.afterBuildLabels();
+
+ // Fit
+ me.beforeFit();
+ me.fit();
+ me.afterFit();
+ //
+ me.afterUpdate();
+
+ return me.minSize;
+
+ },
+ afterUpdate: noop,
+
+ //
+
+ beforeSetDimensions: noop,
+ setDimensions: function() {
+ var me = this;
+ // Set the unconstrained dimension before label rotation
+ if (me.isHorizontal()) {
+ // Reset position before calculating rotation
+ me.width = me.maxWidth;
+ me.left = 0;
+ me.right = me.width;
+ } else {
+ me.height = me.maxHeight;
+
+ // Reset position before calculating rotation
+ me.top = 0;
+ me.bottom = me.height;
+ }
+
+ // Reset padding
+ me.paddingLeft = 0;
+ me.paddingTop = 0;
+ me.paddingRight = 0;
+ me.paddingBottom = 0;
+
+ // Reset minSize
+ me.minSize = {
+ width: 0,
+ height: 0
+ };
+ },
+ afterSetDimensions: noop,
+
+ //
+
+ beforeBuildLabels: noop,
+ buildLabels: noop,
+ afterBuildLabels: noop,
+
+ //
+
+ beforeFit: noop,
+ fit: function() {
+ var me = this;
+ var valueOrDefault = helpers.valueOrDefault;
+ var opts = me.options;
+ var display = opts.display;
+ var fontSize = valueOrDefault(opts.fontSize, defaults.global.defaultFontSize);
+ var minSize = me.minSize;
+ var lineCount = helpers.isArray(opts.text) ? opts.text.length : 1;
+ var lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize);
+ var textSize = display ? (lineCount * lineHeight) + (opts.padding * 2) : 0;
+
+ if (me.isHorizontal()) {
+ minSize.width = me.maxWidth; // fill all the width
+ minSize.height = textSize;
+ } else {
+ minSize.width = textSize;
+ minSize.height = me.maxHeight; // fill all the height
+ }
+
+ me.width = minSize.width;
+ me.height = minSize.height;
+
+ },
+ afterFit: noop,
+
+ // Shared Methods
+ isHorizontal: function() {
+ var pos = this.options.position;
+ return pos === 'top' || pos === 'bottom';
+ },
+
+ // Actually draw the title block on the canvas
+ draw: function() {
+ var me = this;
+ var ctx = me.ctx;
+ var valueOrDefault = helpers.valueOrDefault;
+ var opts = me.options;
+ var globalDefaults = defaults.global;
+
+ if (opts.display) {
+ var fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize);
+ var fontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle);
+ var fontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily);
+ var titleFont = helpers.fontString(fontSize, fontStyle, fontFamily);
+ var lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize);
+ var offset = lineHeight / 2 + opts.padding;
+ var rotation = 0;
+ var top = me.top;
+ var left = me.left;
+ var bottom = me.bottom;
+ var right = me.right;
+ var maxWidth, titleX, titleY;
+
+ ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour
+ ctx.font = titleFont;
+
+ // Horizontal
+ if (me.isHorizontal()) {
+ titleX = left + ((right - left) / 2); // midpoint of the width
+ titleY = top + offset;
+ maxWidth = right - left;
+ } else {
+ titleX = opts.position === 'left' ? left + offset : right - offset;
+ titleY = top + ((bottom - top) / 2);
+ maxWidth = bottom - top;
+ rotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);
+ }
+
+ ctx.save();
+ ctx.translate(titleX, titleY);
+ ctx.rotate(rotation);
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'middle';
+
+ var text = opts.text;
+ if (helpers.isArray(text)) {
+ var y = 0;
+ for (var i = 0; i < text.length; ++i) {
+ ctx.fillText(text[i], 0, y, maxWidth);
+ y += lineHeight;
+ }
+ } else {
+ ctx.fillText(text, 0, 0, maxWidth);
+ }
+
+ ctx.restore();
+ }
+ }
+});
+
+function createNewTitleBlockAndAttach(chart, titleOpts) {
+ var title = new Title({
+ ctx: chart.ctx,
+ options: titleOpts,
+ chart: chart
+ });
+
+ layouts.configure(chart, title, titleOpts);
+ layouts.addBox(chart, title);
+ chart.titleBlock = title;
+}
+
+module.exports = {
+ id: 'title',
+
+ /**
+ * Backward compatibility: since 2.1.5, the title is registered as a plugin, making
+ * Chart.Title obsolete. To avoid a breaking change, we export the Title as part of
+ * the plugin, which one will be re-exposed in the chart.js file.
+ * https://github.com/chartjs/Chart.js/pull/2640
+ * @private
+ */
+ _element: Title,
+
+ beforeInit: function(chart) {
+ var titleOpts = chart.options.title;
+
+ if (titleOpts) {
+ createNewTitleBlockAndAttach(chart, titleOpts);
+ }
+ },
+
+ beforeUpdate: function(chart) {
+ var titleOpts = chart.options.title;
+ var titleBlock = chart.titleBlock;
+
+ if (titleOpts) {
+ helpers.mergeIf(titleOpts, defaults.global.title);
+
+ if (titleBlock) {
+ layouts.configure(chart, titleBlock, titleOpts);
+ titleBlock.options = titleOpts;
+ } else {
+ createNewTitleBlockAndAttach(chart, titleOpts);
+ }
+ } else if (titleBlock) {
+ layouts.removeBox(chart, titleBlock);
+ delete chart.titleBlock;
+ }
+ }
+};
+
+},{"25":25,"26":26,"30":30,"45":45}],53:[function(require,module,exports){
+'use strict';
+
+module.exports = function(Chart) {
+
+ // Default config for a category scale
+ var defaultConfig = {
+ position: 'bottom'
+ };
+
+ var DatasetScale = Chart.Scale.extend({
+ /**
+ * Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use those
+ * else fall back to data.labels
+ * @private
+ */
+ getLabels: function() {
+ var data = this.chart.data;
+ return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;
+ },
+
+ determineDataLimits: function() {
+ var me = this;
+ var labels = me.getLabels();
+ me.minIndex = 0;
+ me.maxIndex = labels.length - 1;
+ var findIndex;
+
+ if (me.options.ticks.min !== undefined) {
+ // user specified min value
+ findIndex = labels.indexOf(me.options.ticks.min);
+ me.minIndex = findIndex !== -1 ? findIndex : me.minIndex;
+ }
+
+ if (me.options.ticks.max !== undefined) {
+ // user specified max value
+ findIndex = labels.indexOf(me.options.ticks.max);
+ me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;
+ }
+
+ me.min = labels[me.minIndex];
+ me.max = labels[me.maxIndex];
+ },
+
+ buildTicks: function() {
+ var me = this;
+ var labels = me.getLabels();
+ // If we are viewing some subset of labels, slice the original array
+ me.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1);
+ },
+
+ getLabelForIndex: function(index, datasetIndex) {
+ var me = this;
+ var data = me.chart.data;
+ var isHorizontal = me.isHorizontal();
+
+ if (data.yLabels && !isHorizontal) {
+ return me.getRightValue(data.datasets[datasetIndex].data[index]);
+ }
+ return me.ticks[index - me.minIndex];
+ },
+
+ // Used to get data value locations. Value can either be an index or a numerical value
+ getPixelForValue: function(value, index) {
+ var me = this;
+ var offset = me.options.offset;
+ // 1 is added because we need the length but we have the indexes
+ var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - (offset ? 0 : 1)), 1);
+
+ // If value is a data object, then index is the index in the data array,
+ // not the index of the scale. We need to change that.
+ var valueCategory;
+ if (value !== undefined && value !== null) {
+ valueCategory = me.isHorizontal() ? value.x : value.y;
+ }
+ if (valueCategory !== undefined || (value !== undefined && isNaN(index))) {
+ var labels = me.getLabels();
+ value = valueCategory || value;
+ var idx = labels.indexOf(value);
+ index = idx !== -1 ? idx : index;
+ }
+
+ if (me.isHorizontal()) {
+ var valueWidth = me.width / offsetAmt;
+ var widthOffset = (valueWidth * (index - me.minIndex));
+
+ if (offset) {
+ widthOffset += (valueWidth / 2);
+ }
+
+ return me.left + Math.round(widthOffset);
+ }
+ var valueHeight = me.height / offsetAmt;
+ var heightOffset = (valueHeight * (index - me.minIndex));
+
+ if (offset) {
+ heightOffset += (valueHeight / 2);
+ }
+
+ return me.top + Math.round(heightOffset);
+ },
+ getPixelForTick: function(index) {
+ return this.getPixelForValue(this.ticks[index], index + this.minIndex, null);
+ },
+ getValueForPixel: function(pixel) {
+ var me = this;
+ var offset = me.options.offset;
+ var value;
+ var offsetAmt = Math.max((me._ticks.length - (offset ? 0 : 1)), 1);
+ var horz = me.isHorizontal();
+ var valueDimension = (horz ? me.width : me.height) / offsetAmt;
+
+ pixel -= horz ? me.left : me.top;
+
+ if (offset) {
+ pixel -= (valueDimension / 2);
+ }
+
+ if (pixel <= 0) {
+ value = 0;
+ } else {
+ value = Math.round(pixel / valueDimension);
+ }
+
+ return value + me.minIndex;
+ },
+ getBasePixel: function() {
+ return this.bottom;
+ }
+ });
+
+ Chart.scaleService.registerScaleType('category', DatasetScale, defaultConfig);
+
+};
+
+},{}],54:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var helpers = require(45);
+var Ticks = require(34);
+
+module.exports = function(Chart) {
+
+ var defaultConfig = {
+ position: 'left',
+ ticks: {
+ callback: Ticks.formatters.linear
+ }
+ };
+
+ var LinearScale = Chart.LinearScaleBase.extend({
+
+ determineDataLimits: function() {
+ var me = this;
+ var opts = me.options;
+ var chart = me.chart;
+ var data = chart.data;
+ var datasets = data.datasets;
+ var isHorizontal = me.isHorizontal();
+ var DEFAULT_MIN = 0;
+ var DEFAULT_MAX = 1;
+
+ function IDMatches(meta) {
+ return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
+ }
+
+ // First Calculate the range
+ me.min = null;
+ me.max = null;
+
+ var hasStacks = opts.stacked;
+ if (hasStacks === undefined) {
+ helpers.each(datasets, function(dataset, datasetIndex) {
+ if (hasStacks) {
+ return;
+ }
+
+ var meta = chart.getDatasetMeta(datasetIndex);
+ if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
+ meta.stack !== undefined) {
+ hasStacks = true;
+ }
+ });
+ }
+
+ if (opts.stacked || hasStacks) {
+ var valuesPerStack = {};
+
+ helpers.each(datasets, function(dataset, datasetIndex) {
+ var meta = chart.getDatasetMeta(datasetIndex);
+ var key = [
+ meta.type,
+ // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
+ ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),
+ meta.stack
+ ].join('.');
+
+ if (valuesPerStack[key] === undefined) {
+ valuesPerStack[key] = {
+ positiveValues: [],
+ negativeValues: []
+ };
+ }
+
+ // Store these per type
+ var positiveValues = valuesPerStack[key].positiveValues;
+ var negativeValues = valuesPerStack[key].negativeValues;
+
+ if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
+ helpers.each(dataset.data, function(rawValue, index) {
+ var value = +me.getRightValue(rawValue);
+ if (isNaN(value) || meta.data[index].hidden) {
+ return;
+ }
+
+ positiveValues[index] = positiveValues[index] || 0;
+ negativeValues[index] = negativeValues[index] || 0;
+
+ if (opts.relativePoints) {
+ positiveValues[index] = 100;
+ } else if (value < 0) {
+ negativeValues[index] += value;
+ } else {
+ positiveValues[index] += value;
+ }
+ });
+ }
+ });
+
+ helpers.each(valuesPerStack, function(valuesForType) {
+ var values = valuesForType.positiveValues.concat(valuesForType.negativeValues);
+ var minVal = helpers.min(values);
+ var maxVal = helpers.max(values);
+ me.min = me.min === null ? minVal : Math.min(me.min, minVal);
+ me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
+ });
+
+ } else {
+ helpers.each(datasets, function(dataset, datasetIndex) {
+ var meta = chart.getDatasetMeta(datasetIndex);
+ if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
+ helpers.each(dataset.data, function(rawValue, index) {
+ var value = +me.getRightValue(rawValue);
+ if (isNaN(value) || meta.data[index].hidden) {
+ return;
+ }
+
+ if (me.min === null) {
+ me.min = value;
+ } else if (value < me.min) {
+ me.min = value;
+ }
+
+ if (me.max === null) {
+ me.max = value;
+ } else if (value > me.max) {
+ me.max = value;
+ }
+ });
+ }
+ });
+ }
+
+ me.min = isFinite(me.min) && !isNaN(me.min) ? me.min : DEFAULT_MIN;
+ me.max = isFinite(me.max) && !isNaN(me.max) ? me.max : DEFAULT_MAX;
+
+ // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
+ this.handleTickRangeOptions();
+ },
+ getTickLimit: function() {
+ var maxTicks;
+ var me = this;
+ var tickOpts = me.options.ticks;
+
+ if (me.isHorizontal()) {
+ maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50));
+ } else {
+ // The factor of 2 used to scale the font size has been experimentally determined.
+ var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, defaults.global.defaultFontSize);
+ maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize)));
+ }
+
+ return maxTicks;
+ },
+ // Called after the ticks are built. We need
+ handleDirectionalChanges: function() {
+ if (!this.isHorizontal()) {
+ // We are in a vertical orientation. The top value is the highest. So reverse the array
+ this.ticks.reverse();
+ }
+ },
+ getLabelForIndex: function(index, datasetIndex) {
+ return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
+ },
+ // Utils
+ getPixelForValue: function(value) {
+ // This must be called after fit has been run so that
+ // this.left, this.top, this.right, and this.bottom have been defined
+ var me = this;
+ var start = me.start;
+
+ var rightValue = +me.getRightValue(value);
+ var pixel;
+ var range = me.end - start;
+
+ if (me.isHorizontal()) {
+ pixel = me.left + (me.width / range * (rightValue - start));
+ } else {
+ pixel = me.bottom - (me.height / range * (rightValue - start));
+ }
+ return pixel;
+ },
+ getValueForPixel: function(pixel) {
+ var me = this;
+ var isHorizontal = me.isHorizontal();
+ var innerDimension = isHorizontal ? me.width : me.height;
+ var offset = (isHorizontal ? pixel - me.left : me.bottom - pixel) / innerDimension;
+ return me.start + ((me.end - me.start) * offset);
+ },
+ getPixelForTick: function(index) {
+ return this.getPixelForValue(this.ticksAsNumbers[index]);
+ }
+ });
+ Chart.scaleService.registerScaleType('linear', LinearScale, defaultConfig);
+
+};
+
+},{"25":25,"34":34,"45":45}],55:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+
+/**
+ * Generate a set of linear ticks
+ * @param generationOptions the options used to generate the ticks
+ * @param dataRange the range of the data
+ * @returns {Array} array of tick values
+ */
+function generateTicks(generationOptions, dataRange) {
+ var ticks = [];
+ // To get a "nice" value for the tick spacing, we will use the appropriately named
+ // "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks
+ // for details.
+
+ var spacing;
+ if (generationOptions.stepSize && generationOptions.stepSize > 0) {
+ spacing = generationOptions.stepSize;
+ } else {
+ var niceRange = helpers.niceNum(dataRange.max - dataRange.min, false);
+ spacing = helpers.niceNum(niceRange / (generationOptions.maxTicks - 1), true);
+ }
+ var niceMin = Math.floor(dataRange.min / spacing) * spacing;
+ var niceMax = Math.ceil(dataRange.max / spacing) * spacing;
+
+ // If min, max and stepSize is set and they make an evenly spaced scale use it.
+ if (generationOptions.min && generationOptions.max && generationOptions.stepSize) {
+ // If very close to our whole number, use it.
+ if (helpers.almostWhole((generationOptions.max - generationOptions.min) / generationOptions.stepSize, spacing / 1000)) {
+ niceMin = generationOptions.min;
+ niceMax = generationOptions.max;
+ }
+ }
+
+ var numSpaces = (niceMax - niceMin) / spacing;
+ // If very close to our rounded value, use it.
+ if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {
+ numSpaces = Math.round(numSpaces);
+ } else {
+ numSpaces = Math.ceil(numSpaces);
+ }
+
+ var precision = 1;
+ if (spacing < 1) {
+ precision = Math.pow(10, spacing.toString().length - 2);
+ niceMin = Math.round(niceMin * precision) / precision;
+ niceMax = Math.round(niceMax * precision) / precision;
+ }
+ ticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin);
+ for (var j = 1; j < numSpaces; ++j) {
+ ticks.push(Math.round((niceMin + j * spacing) * precision) / precision);
+ }
+ ticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax);
+
+ return ticks;
+}
+
+
+module.exports = function(Chart) {
+
+ var noop = helpers.noop;
+
+ Chart.LinearScaleBase = Chart.Scale.extend({
+ getRightValue: function(value) {
+ if (typeof value === 'string') {
+ return +value;
+ }
+ return Chart.Scale.prototype.getRightValue.call(this, value);
+ },
+
+ handleTickRangeOptions: function() {
+ var me = this;
+ var opts = me.options;
+ var tickOpts = opts.ticks;
+
+ // If we are forcing it to begin at 0, but 0 will already be rendered on the chart,
+ // do nothing since that would make the chart weird. If the user really wants a weird chart
+ // axis, they can manually override it
+ if (tickOpts.beginAtZero) {
+ var minSign = helpers.sign(me.min);
+ var maxSign = helpers.sign(me.max);
+
+ if (minSign < 0 && maxSign < 0) {
+ // move the top up to 0
+ me.max = 0;
+ } else if (minSign > 0 && maxSign > 0) {
+ // move the bottom down to 0
+ me.min = 0;
+ }
+ }
+
+ var setMin = tickOpts.min !== undefined || tickOpts.suggestedMin !== undefined;
+ var setMax = tickOpts.max !== undefined || tickOpts.suggestedMax !== undefined;
+
+ if (tickOpts.min !== undefined) {
+ me.min = tickOpts.min;
+ } else if (tickOpts.suggestedMin !== undefined) {
+ if (me.min === null) {
+ me.min = tickOpts.suggestedMin;
+ } else {
+ me.min = Math.min(me.min, tickOpts.suggestedMin);
+ }
+ }
+
+ if (tickOpts.max !== undefined) {
+ me.max = tickOpts.max;
+ } else if (tickOpts.suggestedMax !== undefined) {
+ if (me.max === null) {
+ me.max = tickOpts.suggestedMax;
+ } else {
+ me.max = Math.max(me.max, tickOpts.suggestedMax);
+ }
+ }
+
+ if (setMin !== setMax) {
+ // We set the min or the max but not both.
+ // So ensure that our range is good
+ // Inverted or 0 length range can happen when
+ // ticks.min is set, and no datasets are visible
+ if (me.min >= me.max) {
+ if (setMin) {
+ me.max = me.min + 1;
+ } else {
+ me.min = me.max - 1;
+ }
+ }
+ }
+
+ if (me.min === me.max) {
+ me.max++;
+
+ if (!tickOpts.beginAtZero) {
+ me.min--;
+ }
+ }
+ },
+ getTickLimit: noop,
+ handleDirectionalChanges: noop,
+
+ buildTicks: function() {
+ var me = this;
+ var opts = me.options;
+ var tickOpts = opts.ticks;
+
+ // Figure out what the max number of ticks we can support it is based on the size of
+ // the axis area. For now, we say that the minimum tick spacing in pixels must be 50
+ // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on
+ // the graph. Make sure we always have at least 2 ticks
+ var maxTicks = me.getTickLimit();
+ maxTicks = Math.max(2, maxTicks);
+
+ var numericGeneratorOptions = {
+ maxTicks: maxTicks,
+ min: tickOpts.min,
+ max: tickOpts.max,
+ stepSize: helpers.valueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize)
+ };
+ var ticks = me.ticks = generateTicks(numericGeneratorOptions, me);
+
+ me.handleDirectionalChanges();
+
+ // At this point, we need to update our max and min given the tick values since we have expanded the
+ // range of the scale
+ me.max = helpers.max(ticks);
+ me.min = helpers.min(ticks);
+
+ if (tickOpts.reverse) {
+ ticks.reverse();
+
+ me.start = me.max;
+ me.end = me.min;
+ } else {
+ me.start = me.min;
+ me.end = me.max;
+ }
+ },
+ convertTicksToLabels: function() {
+ var me = this;
+ me.ticksAsNumbers = me.ticks.slice();
+ me.zeroLineIndex = me.ticks.indexOf(0);
+
+ Chart.Scale.prototype.convertTicksToLabels.call(me);
+ }
+ });
+};
+
+},{"45":45}],56:[function(require,module,exports){
+'use strict';
+
+var helpers = require(45);
+var Ticks = require(34);
+
+/**
+ * Generate a set of logarithmic ticks
+ * @param generationOptions the options used to generate the ticks
+ * @param dataRange the range of the data
+ * @returns {Array} array of tick values
+ */
+function generateTicks(generationOptions, dataRange) {
+ var ticks = [];
+ var valueOrDefault = helpers.valueOrDefault;
+
+ // Figure out what the max number of ticks we can support it is based on the size of
+ // the axis area. For now, we say that the minimum tick spacing in pixels must be 50
+ // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on
+ // the graph
+ var tickVal = valueOrDefault(generationOptions.min, Math.pow(10, Math.floor(helpers.log10(dataRange.min))));
+
+ var endExp = Math.floor(helpers.log10(dataRange.max));
+ var endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));
+ var exp, significand;
+
+ if (tickVal === 0) {
+ exp = Math.floor(helpers.log10(dataRange.minNotZero));
+ significand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));
+
+ ticks.push(tickVal);
+ tickVal = significand * Math.pow(10, exp);
+ } else {
+ exp = Math.floor(helpers.log10(tickVal));
+ significand = Math.floor(tickVal / Math.pow(10, exp));
+ }
+ var precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1;
+
+ do {
+ ticks.push(tickVal);
+
+ ++significand;
+ if (significand === 10) {
+ significand = 1;
+ ++exp;
+ precision = exp >= 0 ? 1 : precision;
+ }
+
+ tickVal = Math.round(significand * Math.pow(10, exp) * precision) / precision;
+ } while (exp < endExp || (exp === endExp && significand < endSignificand));
+
+ var lastTick = valueOrDefault(generationOptions.max, tickVal);
+ ticks.push(lastTick);
+
+ return ticks;
+}
+
+
+module.exports = function(Chart) {
+
+ var defaultConfig = {
+ position: 'left',
+
+ // label settings
+ ticks: {
+ callback: Ticks.formatters.logarithmic
+ }
+ };
+
+ var LogarithmicScale = Chart.Scale.extend({
+ determineDataLimits: function() {
+ var me = this;
+ var opts = me.options;
+ var chart = me.chart;
+ var data = chart.data;
+ var datasets = data.datasets;
+ var isHorizontal = me.isHorizontal();
+ function IDMatches(meta) {
+ return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
+ }
+
+ // Calculate Range
+ me.min = null;
+ me.max = null;
+ me.minNotZero = null;
+
+ var hasStacks = opts.stacked;
+ if (hasStacks === undefined) {
+ helpers.each(datasets, function(dataset, datasetIndex) {
+ if (hasStacks) {
+ return;
+ }
+
+ var meta = chart.getDatasetMeta(datasetIndex);
+ if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
+ meta.stack !== undefined) {
+ hasStacks = true;
+ }
+ });
+ }
+
+ if (opts.stacked || hasStacks) {
+ var valuesPerStack = {};
+
+ helpers.each(datasets, function(dataset, datasetIndex) {
+ var meta = chart.getDatasetMeta(datasetIndex);
+ var key = [
+ meta.type,
+ // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
+ ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),
+ meta.stack
+ ].join('.');
+
+ if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
+ if (valuesPerStack[key] === undefined) {
+ valuesPerStack[key] = [];
+ }
+
+ helpers.each(dataset.data, function(rawValue, index) {
+ var values = valuesPerStack[key];
+ var value = +me.getRightValue(rawValue);
+ // invalid, hidden and negative values are ignored
+ if (isNaN(value) || meta.data[index].hidden || value < 0) {
+ return;
+ }
+ values[index] = values[index] || 0;
+ values[index] += value;
+ });
+ }
+ });
+
+ helpers.each(valuesPerStack, function(valuesForType) {
+ if (valuesForType.length > 0) {
+ var minVal = helpers.min(valuesForType);
+ var maxVal = helpers.max(valuesForType);
+ me.min = me.min === null ? minVal : Math.min(me.min, minVal);
+ me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
+ }
+ });
+
+ } else {
+ helpers.each(datasets, function(dataset, datasetIndex) {
+ var meta = chart.getDatasetMeta(datasetIndex);
+ if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
+ helpers.each(dataset.data, function(rawValue, index) {
+ var value = +me.getRightValue(rawValue);
+ // invalid, hidden and negative values are ignored
+ if (isNaN(value) || meta.data[index].hidden || value < 0) {
+ return;
+ }
+
+ if (me.min === null) {
+ me.min = value;
+ } else if (value < me.min) {
+ me.min = value;
+ }
+
+ if (me.max === null) {
+ me.max = value;
+ } else if (value > me.max) {
+ me.max = value;
+ }
+
+ if (value !== 0 && (me.minNotZero === null || value < me.minNotZero)) {
+ me.minNotZero = value;
+ }
+ });
+ }
+ });
+ }
+
+ // Common base implementation to handle ticks.min, ticks.max
+ this.handleTickRangeOptions();
+ },
+ handleTickRangeOptions: function() {
+ var me = this;
+ var opts = me.options;
+ var tickOpts = opts.ticks;
+ var valueOrDefault = helpers.valueOrDefault;
+ var DEFAULT_MIN = 1;
+ var DEFAULT_MAX = 10;
+
+ me.min = valueOrDefault(tickOpts.min, me.min);
+ me.max = valueOrDefault(tickOpts.max, me.max);
+
+ if (me.min === me.max) {
+ if (me.min !== 0 && me.min !== null) {
+ me.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1);
+ me.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1);
+ } else {
+ me.min = DEFAULT_MIN;
+ me.max = DEFAULT_MAX;
+ }
+ }
+ if (me.min === null) {
+ me.min = Math.pow(10, Math.floor(helpers.log10(me.max)) - 1);
+ }
+ if (me.max === null) {
+ me.max = me.min !== 0
+ ? Math.pow(10, Math.floor(helpers.log10(me.min)) + 1)
+ : DEFAULT_MAX;
+ }
+ if (me.minNotZero === null) {
+ if (me.min > 0) {
+ me.minNotZero = me.min;
+ } else if (me.max < 1) {
+ me.minNotZero = Math.pow(10, Math.floor(helpers.log10(me.max)));
+ } else {
+ me.minNotZero = DEFAULT_MIN;
+ }
+ }
+ },
+ buildTicks: function() {
+ var me = this;
+ var opts = me.options;
+ var tickOpts = opts.ticks;
+ var reverse = !me.isHorizontal();
+
+ var generationOptions = {
+ min: tickOpts.min,
+ max: tickOpts.max
+ };
+ var ticks = me.ticks = generateTicks(generationOptions, me);
+
+ // At this point, we need to update our max and min given the tick values since we have expanded the
+ // range of the scale
+ me.max = helpers.max(ticks);
+ me.min = helpers.min(ticks);
+
+ if (tickOpts.reverse) {
+ reverse = !reverse;
+ me.start = me.max;
+ me.end = me.min;
+ } else {
+ me.start = me.min;
+ me.end = me.max;
+ }
+ if (reverse) {
+ ticks.reverse();
+ }
+ },
+ convertTicksToLabels: function() {
+ this.tickValues = this.ticks.slice();
+
+ Chart.Scale.prototype.convertTicksToLabels.call(this);
+ },
+ // Get the correct tooltip label
+ getLabelForIndex: function(index, datasetIndex) {
+ return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
+ },
+ getPixelForTick: function(index) {
+ return this.getPixelForValue(this.tickValues[index]);
+ },
+ /**
+ * Returns the value of the first tick.
+ * @param {Number} value - The minimum not zero value.
+ * @return {Number} The first tick value.
+ * @private
+ */
+ _getFirstTickValue: function(value) {
+ var exp = Math.floor(helpers.log10(value));
+ var significand = Math.floor(value / Math.pow(10, exp));
+
+ return significand * Math.pow(10, exp);
+ },
+ getPixelForValue: function(value) {
+ var me = this;
+ var reverse = me.options.ticks.reverse;
+ var log10 = helpers.log10;
+ var firstTickValue = me._getFirstTickValue(me.minNotZero);
+ var offset = 0;
+ var innerDimension, pixel, start, end, sign;
+
+ value = +me.getRightValue(value);
+ if (reverse) {
+ start = me.end;
+ end = me.start;
+ sign = -1;
+ } else {
+ start = me.start;
+ end = me.end;
+ sign = 1;
+ }
+ if (me.isHorizontal()) {
+ innerDimension = me.width;
+ pixel = reverse ? me.right : me.left;
+ } else {
+ innerDimension = me.height;
+ sign *= -1; // invert, since the upper-left corner of the canvas is at pixel (0, 0)
+ pixel = reverse ? me.top : me.bottom;
+ }
+ if (value !== start) {
+ if (start === 0) { // include zero tick
+ offset = helpers.getValueOrDefault(
+ me.options.ticks.fontSize,
+ Chart.defaults.global.defaultFontSize
+ );
+ innerDimension -= offset;
+ start = firstTickValue;
+ }
+ if (value !== 0) {
+ offset += innerDimension / (log10(end) - log10(start)) * (log10(value) - log10(start));
+ }
+ pixel += sign * offset;
+ }
+ return pixel;
+ },
+ getValueForPixel: function(pixel) {
+ var me = this;
+ var reverse = me.options.ticks.reverse;
+ var log10 = helpers.log10;
+ var firstTickValue = me._getFirstTickValue(me.minNotZero);
+ var innerDimension, start, end, value;
+
+ if (reverse) {
+ start = me.end;
+ end = me.start;
+ } else {
+ start = me.start;
+ end = me.end;
+ }
+ if (me.isHorizontal()) {
+ innerDimension = me.width;
+ value = reverse ? me.right - pixel : pixel - me.left;
+ } else {
+ innerDimension = me.height;
+ value = reverse ? pixel - me.top : me.bottom - pixel;
+ }
+ if (value !== start) {
+ if (start === 0) { // include zero tick
+ var offset = helpers.getValueOrDefault(
+ me.options.ticks.fontSize,
+ Chart.defaults.global.defaultFontSize
+ );
+ value -= offset;
+ innerDimension -= offset;
+ start = firstTickValue;
+ }
+ value *= log10(end) - log10(start);
+ value /= innerDimension;
+ value = Math.pow(10, log10(start) + value);
+ }
+ return value;
+ }
+ });
+ Chart.scaleService.registerScaleType('logarithmic', LogarithmicScale, defaultConfig);
+
+};
+
+},{"34":34,"45":45}],57:[function(require,module,exports){
+'use strict';
+
+var defaults = require(25);
+var helpers = require(45);
+var Ticks = require(34);
+
+module.exports = function(Chart) {
+
+ var globalDefaults = defaults.global;
+
+ var defaultConfig = {
+ display: true,
+
+ // Boolean - Whether to animate scaling the chart from the centre
+ animate: true,
+ position: 'chartArea',
+
+ angleLines: {
+ display: true,
+ color: 'rgba(0, 0, 0, 0.1)',
+ lineWidth: 1
+ },
+
+ gridLines: {
+ circular: false
+ },
+
+ // label settings
+ ticks: {
+ // Boolean - Show a backdrop to the scale label
+ showLabelBackdrop: true,
+
+ // String - The colour of the label backdrop
+ backdropColor: 'rgba(255,255,255,0.75)',
+
+ // Number - The backdrop padding above & below the label in pixels
+ backdropPaddingY: 2,
+
+ // Number - The backdrop padding to the side of the label in pixels
+ backdropPaddingX: 2,
+
+ callback: Ticks.formatters.linear
+ },
+
+ pointLabels: {
+ // Boolean - if true, show point labels
+ display: true,
+
+ // Number - Point label font size in pixels
+ fontSize: 10,
+
+ // Function - Used to convert point labels
+ callback: function(label) {
+ return label;
+ }
+ }
+ };
+
+ function getValueCount(scale) {
+ var opts = scale.options;
+ return opts.angleLines.display || opts.pointLabels.display ? scale.chart.data.labels.length : 0;
+ }
+
+ function getPointLabelFontOptions(scale) {
+ var pointLabelOptions = scale.options.pointLabels;
+ var fontSize = helpers.valueOrDefault(pointLabelOptions.fontSize, globalDefaults.defaultFontSize);
+ var fontStyle = helpers.valueOrDefault(pointLabelOptions.fontStyle, globalDefaults.defaultFontStyle);
+ var fontFamily = helpers.valueOrDefault(pointLabelOptions.fontFamily, globalDefaults.defaultFontFamily);
+ var font = helpers.fontString(fontSize, fontStyle, fontFamily);
+
+ return {
+ size: fontSize,
+ style: fontStyle,
+ family: fontFamily,
+ font: font
+ };
+ }
+
+ function measureLabelSize(ctx, fontSize, label) {
+ if (helpers.isArray(label)) {
+ return {
+ w: helpers.longestText(ctx, ctx.font, label),
+ h: (label.length * fontSize) + ((label.length - 1) * 1.5 * fontSize)
+ };
+ }
+
+ return {
+ w: ctx.measureText(label).width,
+ h: fontSize
+ };
+ }
+
+ function determineLimits(angle, pos, size, min, max) {
+ if (angle === min || angle === max) {
+ return {
+ start: pos - (size / 2),
+ end: pos + (size / 2)
+ };
+ } else if (angle < min || angle > max) {
+ return {
+ start: pos - size - 5,
+ end: pos
+ };
+ }
+
+ return {
+ start: pos,
+ end: pos + size + 5
+ };
+ }
+
+ /**
+ * Helper function to fit a radial linear scale with point labels
+ */
+ function fitWithPointLabels(scale) {
+ /*
+ * Right, this is really confusing and there is a lot of maths going on here
+ * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9
+ *
+ * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif
+ *
+ * Solution:
+ *
+ * We assume the radius of the polygon is half the size of the canvas at first
+ * at each index we check if the text overlaps.
+ *
+ * Where it does, we store that angle and that index.
+ *
+ * After finding the largest index and angle we calculate how much we need to remove
+ * from the shape radius to move the point inwards by that x.
+ *
+ * We average the left and right distances to get the maximum shape radius that can fit in the box
+ * along with labels.
+ *
+ * Once we have that, we can find the centre point for the chart, by taking the x text protrusion
+ * on each side, removing that from the size, halving it and adding the left x protrusion width.
+ *
+ * This will mean we have a shape fitted to the canvas, as large as it can be with the labels
+ * and position it in the most space efficient manner
+ *
+ * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif
+ */
+
+ var plFont = getPointLabelFontOptions(scale);
+
+ // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.
+ // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points
+ var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);
+ var furthestLimits = {
+ r: scale.width,
+ l: 0,
+ t: scale.height,
+ b: 0
+ };
+ var furthestAngles = {};
+ var i, textSize, pointPosition;
+
+ scale.ctx.font = plFont.font;
+ scale._pointLabelSizes = [];
+
+ var valueCount = getValueCount(scale);
+ for (i = 0; i < valueCount; i++) {
+ pointPosition = scale.getPointPosition(i, largestPossibleRadius);
+ textSize = measureLabelSize(scale.ctx, plFont.size, scale.pointLabels[i] || '');
+ scale._pointLabelSizes[i] = textSize;
+
+ // Add quarter circle to make degree 0 mean top of circle
+ var angleRadians = scale.getIndexAngle(i);
+ var angle = helpers.toDegrees(angleRadians) % 360;
+ var hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);
+ var vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);
+
+ if (hLimits.start < furthestLimits.l) {
+ furthestLimits.l = hLimits.start;
+ furthestAngles.l = angleRadians;
+ }
+
+ if (hLimits.end > furthestLimits.r) {
+ furthestLimits.r = hLimits.end;
+ furthestAngles.r = angleRadians;
+ }
+
+ if (vLimits.start < furthestLimits.t) {
+ furthestLimits.t = vLimits.start;
+ furthestAngles.t = angleRadians;
+ }
+
+ if (vLimits.end > furthestLimits.b) {
+ furthestLimits.b = vLimits.end;
+ furthestAngles.b = angleRadians;
+ }
+ }
+
+ scale.setReductions(largestPossibleRadius, furthestLimits, furthestAngles);
+ }
+
+ /**
+ * Helper function to fit a radial linear scale with no point labels
+ */
+ function fit(scale) {
+ var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);
+ scale.drawingArea = Math.round(largestPossibleRadius);
+ scale.setCenterPoint(0, 0, 0, 0);
+ }
+
+ function getTextAlignForAngle(angle) {
+ if (angle === 0 || angle === 180) {
+ return 'center';
+ } else if (angle < 180) {
+ return 'left';
+ }
+
+ return 'right';
+ }
+
+ function fillText(ctx, text, position, fontSize) {
+ if (helpers.isArray(text)) {
+ var y = position.y;
+ var spacing = 1.5 * fontSize;
+
+ for (var i = 0; i < text.length; ++i) {
+ ctx.fillText(text[i], position.x, y);
+ y += spacing;
+ }
+ } else {
+ ctx.fillText(text, position.x, position.y);
+ }
+ }
+
+ function adjustPointPositionForLabelHeight(angle, textSize, position) {
+ if (angle === 90 || angle === 270) {
+ position.y -= (textSize.h / 2);
+ } else if (angle > 270 || angle < 90) {
+ position.y -= textSize.h;
+ }
+ }
+
+ function drawPointLabels(scale) {
+ var ctx = scale.ctx;
+ var opts = scale.options;
+ var angleLineOpts = opts.angleLines;
+ var pointLabelOpts = opts.pointLabels;
+
+ ctx.lineWidth = angleLineOpts.lineWidth;
+ ctx.strokeStyle = angleLineOpts.color;
+
+ var outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max);
+
+ // Point Label Font
+ var plFont = getPointLabelFontOptions(scale);
+
+ ctx.textBaseline = 'top';
+
+ for (var i = getValueCount(scale) - 1; i >= 0; i--) {
+ if (angleLineOpts.display) {
+ var outerPosition = scale.getPointPosition(i, outerDistance);
+ ctx.beginPath();
+ ctx.moveTo(scale.xCenter, scale.yCenter);
+ ctx.lineTo(outerPosition.x, outerPosition.y);
+ ctx.stroke();
+ ctx.closePath();
+ }
+
+ if (pointLabelOpts.display) {
+ // Extra 3px out for some label spacing
+ var pointLabelPosition = scale.getPointPosition(i, outerDistance + 5);
+
+ // Keep this in loop since we may support array properties here
+ var pointLabelFontColor = helpers.valueAtIndexOrDefault(pointLabelOpts.fontColor, i, globalDefaults.defaultFontColor);
+ ctx.font = plFont.font;
+ ctx.fillStyle = pointLabelFontColor;
+
+ var angleRadians = scale.getIndexAngle(i);
+ var angle = helpers.toDegrees(angleRadians);
+ ctx.textAlign = getTextAlignForAngle(angle);
+ adjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition);
+ fillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.size);
+ }
+ }
+ }
+
+ function drawRadiusLine(scale, gridLineOpts, radius, index) {
+ var ctx = scale.ctx;
+ ctx.strokeStyle = helpers.valueAtIndexOrDefault(gridLineOpts.color, index - 1);
+ ctx.lineWidth = helpers.valueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);
+
+ if (scale.options.gridLines.circular) {
+ // Draw circular arcs between the points
+ ctx.beginPath();
+ ctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2);
+ ctx.closePath();
+ ctx.stroke();
+ } else {
+ // Draw straight lines connecting each index
+ var valueCount = getValueCount(scale);
+
+ if (valueCount === 0) {
+ return;
+ }
+
+ ctx.beginPath();
+ var pointPosition = scale.getPointPosition(0, radius);
+ ctx.moveTo(pointPosition.x, pointPosition.y);
+
+ for (var i = 1; i < valueCount; i++) {
+ pointPosition = scale.getPointPosition(i, radius);
+ ctx.lineTo(pointPosition.x, pointPosition.y);
+ }
+
+ ctx.closePath();
+ ctx.stroke();
+ }
+ }
+
+ function numberOrZero(param) {
+ return helpers.isNumber(param) ? param : 0;
+ }
+
+ var LinearRadialScale = Chart.LinearScaleBase.extend({
+ setDimensions: function() {
+ var me = this;
+ var opts = me.options;
+ var tickOpts = opts.ticks;
+ // Set the unconstrained dimension before label rotation
+ me.width = me.maxWidth;
+ me.height = me.maxHeight;
+ me.xCenter = Math.round(me.width / 2);
+ me.yCenter = Math.round(me.height / 2);
+
+ var minSize = helpers.min([me.height, me.width]);
+ var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
+ me.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2);
+ },
+ determineDataLimits: function() {
+ var me = this;
+ var chart = me.chart;
+ var min = Number.POSITIVE_INFINITY;
+ var max = Number.NEGATIVE_INFINITY;
+
+ helpers.each(chart.data.datasets, function(dataset, datasetIndex) {
+ if (chart.isDatasetVisible(datasetIndex)) {
+ var meta = chart.getDatasetMeta(datasetIndex);
+
+ helpers.each(dataset.data, function(rawValue, index) {
+ var value = +me.getRightValue(rawValue);
+ if (isNaN(value) || meta.data[index].hidden) {
+ return;
+ }
+
+ min = Math.min(value, min);
+ max = Math.max(value, max);
+ });
+ }
+ });
+
+ me.min = (min === Number.POSITIVE_INFINITY ? 0 : min);
+ me.max = (max === Number.NEGATIVE_INFINITY ? 0 : max);
+
+ // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
+ me.handleTickRangeOptions();
+ },
+ getTickLimit: function() {
+ var tickOpts = this.options.ticks;
+ var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
+ return Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize)));
+ },
+ convertTicksToLabels: function() {
+ var me = this;
+
+ Chart.LinearScaleBase.prototype.convertTicksToLabels.call(me);
+
+ // Point labels
+ me.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me);
+ },
+ getLabelForIndex: function(index, datasetIndex) {
+ return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
+ },
+ fit: function() {
+ if (this.options.pointLabels.display) {
+ fitWithPointLabels(this);
+ } else {
+ fit(this);
+ }
+ },
+ /**
+ * Set radius reductions and determine new radius and center point
+ * @private
+ */
+ setReductions: function(largestPossibleRadius, furthestLimits, furthestAngles) {
+ var me = this;
+ var radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l);
+ var radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r);
+ var radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t);
+ var radiusReductionBottom = -Math.max(furthestLimits.b - me.height, 0) / Math.cos(furthestAngles.b);
+
+ radiusReductionLeft = numberOrZero(radiusReductionLeft);
+ radiusReductionRight = numberOrZero(radiusReductionRight);
+ radiusReductionTop = numberOrZero(radiusReductionTop);
+ radiusReductionBottom = numberOrZero(radiusReductionBottom);
+
+ me.drawingArea = Math.min(
+ Math.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2),
+ Math.round(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2));
+ me.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom);
+ },
+ setCenterPoint: function(leftMovement, rightMovement, topMovement, bottomMovement) {
+ var me = this;
+ var maxRight = me.width - rightMovement - me.drawingArea;
+ var maxLeft = leftMovement + me.drawingArea;
+ var maxTop = topMovement + me.drawingArea;
+ var maxBottom = me.height - bottomMovement - me.drawingArea;
+
+ me.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left);
+ me.yCenter = Math.round(((maxTop + maxBottom) / 2) + me.top);
+ },
+
+ getIndexAngle: function(index) {
+ var angleMultiplier = (Math.PI * 2) / getValueCount(this);
+ var startAngle = this.chart.options && this.chart.options.startAngle ?
+ this.chart.options.startAngle :
+ 0;
+
+ var startAngleRadians = startAngle * Math.PI * 2 / 360;
+
+ // Start from the top instead of right, so remove a quarter of the circle
+ return index * angleMultiplier + startAngleRadians;
+ },
+ getDistanceFromCenterForValue: function(value) {
+ var me = this;
+
+ if (value === null) {
+ return 0; // null always in center
+ }
+
+ // Take into account half font size + the yPadding of the top value
+ var scalingFactor = me.drawingArea / (me.max - me.min);
+ if (me.options.ticks.reverse) {
+ return (me.max - value) * scalingFactor;
+ }
+ return (value - me.min) * scalingFactor;
+ },
+ getPointPosition: function(index, distanceFromCenter) {
+ var me = this;
+ var thisAngle = me.getIndexAngle(index) - (Math.PI / 2);
+ return {
+ x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter,
+ y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter
+ };
+ },
+ getPointPositionForValue: function(index, value) {
+ return this.getPointPosition(index, this.getDistanceFromCenterForValue(value));
+ },
+
+ getBasePosition: function() {
+ var me = this;
+ var min = me.min;
+ var max = me.max;
+
+ return me.getPointPositionForValue(0,
+ me.beginAtZero ? 0 :
+ min < 0 && max < 0 ? max :
+ min > 0 && max > 0 ? min :
+ 0);
+ },
+
+ draw: function() {
+ var me = this;
+ var opts = me.options;
+ var gridLineOpts = opts.gridLines;
+ var tickOpts = opts.ticks;
+ var valueOrDefault = helpers.valueOrDefault;
+
+ if (opts.display) {
+ var ctx = me.ctx;
+ var startAngle = this.getIndexAngle(0);
+
+ // Tick Font
+ var tickFontSize = valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
+ var tickFontStyle = valueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);
+ var tickFontFamily = valueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);
+ var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
+
+ helpers.each(me.ticks, function(label, index) {
+ // Don't draw a centre value (if it is minimum)
+ if (index > 0 || tickOpts.reverse) {
+ var yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);
+
+ // Draw circular lines around the scale
+ if (gridLineOpts.display && index !== 0) {
+ drawRadiusLine(me, gridLineOpts, yCenterOffset, index);
+ }
+
+ if (tickOpts.display) {
+ var tickFontColor = valueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor);
+ ctx.font = tickLabelFont;
+
+ ctx.save();
+ ctx.translate(me.xCenter, me.yCenter);
+ ctx.rotate(startAngle);
+
+ if (tickOpts.showLabelBackdrop) {
+ var labelWidth = ctx.measureText(label).width;
+ ctx.fillStyle = tickOpts.backdropColor;
+ ctx.fillRect(
+ -labelWidth / 2 - tickOpts.backdropPaddingX,
+ -yCenterOffset - tickFontSize / 2 - tickOpts.backdropPaddingY,
+ labelWidth + tickOpts.backdropPaddingX * 2,
+ tickFontSize + tickOpts.backdropPaddingY * 2
+ );
+ }
+
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'middle';
+ ctx.fillStyle = tickFontColor;
+ ctx.fillText(label, 0, -yCenterOffset);
+ ctx.restore();
+ }
+ }
+ });
+
+ if (opts.angleLines.display || opts.pointLabels.display) {
+ drawPointLabels(me);
+ }
+ }
+ }
+ });
+ Chart.scaleService.registerScaleType('radialLinear', LinearRadialScale, defaultConfig);
+
+};
+
+},{"25":25,"34":34,"45":45}],58:[function(require,module,exports){
+/* global window: false */
+'use strict';
+
+var moment = require(1);
+moment = typeof moment === 'function' ? moment : window.moment;
+
+var defaults = require(25);
+var helpers = require(45);
+
+// Integer constants are from the ES6 spec.
+var MIN_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991;
+var MAX_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
+
+var INTERVALS = {
+ millisecond: {
+ common: true,
+ size: 1,
+ steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]
+ },
+ second: {
+ common: true,
+ size: 1000,
+ steps: [1, 2, 5, 10, 30]
+ },
+ minute: {
+ common: true,
+ size: 60000,
+ steps: [1, 2, 5, 10, 30]
+ },
+ hour: {
+ common: true,
+ size: 3600000,
+ steps: [1, 2, 3, 6, 12]
+ },
+ day: {
+ common: true,
+ size: 86400000,
+ steps: [1, 2, 5]
+ },
+ week: {
+ common: false,
+ size: 604800000,
+ steps: [1, 2, 3, 4]
+ },
+ month: {
+ common: true,
+ size: 2.628e9,
+ steps: [1, 2, 3]
+ },
+ quarter: {
+ common: false,
+ size: 7.884e9,
+ steps: [1, 2, 3, 4]
+ },
+ year: {
+ common: true,
+ size: 3.154e10
+ }
+};
+
+var UNITS = Object.keys(INTERVALS);
+
+function sorter(a, b) {
+ return a - b;
+}
+
+function arrayUnique(items) {
+ var hash = {};
+ var out = [];
+ var i, ilen, item;
+
+ for (i = 0, ilen = items.length; i < ilen; ++i) {
+ item = items[i];
+ if (!hash[item]) {
+ hash[item] = true;
+ out.push(item);
+ }
+ }
+
+ return out;
+}
+
+/**
+ * Returns an array of {time, pos} objects used to interpolate a specific `time` or position
+ * (`pos`) on the scale, by searching entries before and after the requested value. `pos` is
+ * a decimal between 0 and 1: 0 being the start of the scale (left or top) and 1 the other
+ * extremity (left + width or top + height). Note that it would be more optimized to directly
+ * store pre-computed pixels, but the scale dimensions are not guaranteed at the time we need
+ * to create the lookup table. The table ALWAYS contains at least two items: min and max.
+ *
+ * @param {Number[]} timestamps - timestamps sorted from lowest to highest.
+ * @param {String} distribution - If 'linear', timestamps will be spread linearly along the min
+ * and max range, so basically, the table will contains only two items: {min, 0} and {max, 1}.
+ * If 'series', timestamps will be positioned at the same distance from each other. In this
+ * case, only timestamps that break the time linearity are registered, meaning that in the
+ * best case, all timestamps are linear, the table contains only min and max.
+ */
+function buildLookupTable(timestamps, min, max, distribution) {
+ if (distribution === 'linear' || !timestamps.length) {
+ return [
+ {time: min, pos: 0},
+ {time: max, pos: 1}
+ ];
+ }
+
+ var table = [];
+ var items = [min];
+ var i, ilen, prev, curr, next;
+
+ for (i = 0, ilen = timestamps.length; i < ilen; ++i) {
+ curr = timestamps[i];
+ if (curr > min && curr < max) {
+ items.push(curr);
+ }
+ }
+
+ items.push(max);
+
+ for (i = 0, ilen = items.length; i < ilen; ++i) {
+ next = items[i + 1];
+ prev = items[i - 1];
+ curr = items[i];
+
+ // only add points that breaks the scale linearity
+ if (prev === undefined || next === undefined || Math.round((next + prev) / 2) !== curr) {
+ table.push({time: curr, pos: i / (ilen - 1)});
+ }
+ }
+
+ return table;
+}
+
+// @see adapted from http://www.anujgakhar.com/2014/03/01/binary-search-in-javascript/
+function lookup(table, key, value) {
+ var lo = 0;
+ var hi = table.length - 1;
+ var mid, i0, i1;
+
+ while (lo >= 0 && lo <= hi) {
+ mid = (lo + hi) >> 1;
+ i0 = table[mid - 1] || null;
+ i1 = table[mid];
+
+ if (!i0) {
+ // given value is outside table (before first item)
+ return {lo: null, hi: i1};
+ } else if (i1[key] < value) {
+ lo = mid + 1;
+ } else if (i0[key] > value) {
+ hi = mid - 1;
+ } else {
+ return {lo: i0, hi: i1};
+ }
+ }
+
+ // given value is outside table (after last item)
+ return {lo: i1, hi: null};
+}
+
+/**
+ * Linearly interpolates the given source `value` using the table items `skey` values and
+ * returns the associated `tkey` value. For example, interpolate(table, 'time', 42, 'pos')
+ * returns the position for a timestamp equal to 42. If value is out of bounds, values at
+ * index [0, 1] or [n - 1, n] are used for the interpolation.
+ */
+function interpolate(table, skey, sval, tkey) {
+ var range = lookup(table, skey, sval);
+
+ // Note: the lookup table ALWAYS contains at least 2 items (min and max)
+ var prev = !range.lo ? table[0] : !range.hi ? table[table.length - 2] : range.lo;
+ var next = !range.lo ? table[1] : !range.hi ? table[table.length - 1] : range.hi;
+
+ var span = next[skey] - prev[skey];
+ var ratio = span ? (sval - prev[skey]) / span : 0;
+ var offset = (next[tkey] - prev[tkey]) * ratio;
+
+ return prev[tkey] + offset;
+}
+
+/**
+ * Convert the given value to a moment object using the given time options.
+ * @see http://momentjs.com/docs/#/parsing/
+ */
+function momentify(value, options) {
+ var parser = options.parser;
+ var format = options.parser || options.format;
+
+ if (typeof parser === 'function') {
+ return parser(value);
+ }
+
+ if (typeof value === 'string' && typeof format === 'string') {
+ return moment(value, format);
+ }
+
+ if (!(value instanceof moment)) {
+ value = moment(value);
+ }
+
+ if (value.isValid()) {
+ return value;
+ }
+
+ // Labels are in an incompatible moment format and no `parser` has been provided.
+ // The user might still use the deprecated `format` option to convert his inputs.
+ if (typeof format === 'function') {
+ return format(value);
+ }
+
+ return value;
+}
+
+function parse(input, scale) {
+ if (helpers.isNullOrUndef(input)) {
+ return null;
+ }
+
+ var options = scale.options.time;
+ var value = momentify(scale.getRightValue(input), options);
+ if (!value.isValid()) {
+ return null;
+ }
+
+ if (options.round) {
+ value.startOf(options.round);
+ }
+
+ return value.valueOf();
+}
+
+/**
+ * Returns the number of unit to skip to be able to display up to `capacity` number of ticks
+ * in `unit` for the given `min` / `max` range and respecting the interval steps constraints.
+ */
+function determineStepSize(min, max, unit, capacity) {
+ var range = max - min;
+ var interval = INTERVALS[unit];
+ var milliseconds = interval.size;
+ var steps = interval.steps;
+ var i, ilen, factor;
+
+ if (!steps) {
+ return Math.ceil(range / (capacity * milliseconds));
+ }
+
+ for (i = 0, ilen = steps.length; i < ilen; ++i) {
+ factor = steps[i];
+ if (Math.ceil(range / (milliseconds * factor)) <= capacity) {
+ break;
+ }
+ }
+
+ return factor;
+}
+
+/**
+ * Figures out what unit results in an appropriate number of auto-generated ticks
+ */
+function determineUnitForAutoTicks(minUnit, min, max, capacity) {
+ var ilen = UNITS.length;
+ var i, interval, factor;
+
+ for (i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) {
+ interval = INTERVALS[UNITS[i]];
+ factor = interval.steps ? interval.steps[interval.steps.length - 1] : MAX_INTEGER;
+
+ if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) {
+ return UNITS[i];
+ }
+ }
+
+ return UNITS[ilen - 1];
+}
+
+/**
+ * Figures out what unit to format a set of ticks with
+ */
+function determineUnitForFormatting(ticks, minUnit, min, max) {
+ var duration = moment.duration(moment(max).diff(moment(min)));
+ var ilen = UNITS.length;
+ var i, unit;
+
+ for (i = ilen - 1; i >= UNITS.indexOf(minUnit); i--) {
+ unit = UNITS[i];
+ if (INTERVALS[unit].common && duration.as(unit) >= ticks.length) {
+ return unit;
+ }
+ }
+
+ return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0];
+}
+
+function determineMajorUnit(unit) {
+ for (var i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i) {
+ if (INTERVALS[UNITS[i]].common) {
+ return UNITS[i];
+ }
+ }
+}
+
+/**
+ * Generates a maximum of `capacity` timestamps between min and max, rounded to the
+ * `minor` unit, aligned on the `major` unit and using the given scale time `options`.
+ * Important: this method can return ticks outside the min and max range, it's the
+ * responsibility of the calling code to clamp values if needed.
+ */
+function generate(min, max, capacity, options) {
+ var timeOpts = options.time;
+ var minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, capacity);
+ var major = determineMajorUnit(minor);
+ var stepSize = helpers.valueOrDefault(timeOpts.stepSize, timeOpts.unitStepSize);
+ var weekday = minor === 'week' ? timeOpts.isoWeekday : false;
+ var majorTicksEnabled = options.ticks.major.enabled;
+ var interval = INTERVALS[minor];
+ var first = moment(min);
+ var last = moment(max);
+ var ticks = [];
+ var time;
+
+ if (!stepSize) {
+ stepSize = determineStepSize(min, max, minor, capacity);
+ }
+
+ // For 'week' unit, handle the first day of week option
+ if (weekday) {
+ first = first.isoWeekday(weekday);
+ last = last.isoWeekday(weekday);
+ }
+
+ // Align first/last ticks on unit
+ first = first.startOf(weekday ? 'day' : minor);
+ last = last.startOf(weekday ? 'day' : minor);
+
+ // Make sure that the last tick include max
+ if (last < max) {
+ last.add(1, minor);
+ }
+
+ time = moment(first);
+
+ if (majorTicksEnabled && major && !weekday && !timeOpts.round) {
+ // Align the first tick on the previous `minor` unit aligned on the `major` unit:
+ // we first aligned time on the previous `major` unit then add the number of full
+ // stepSize there is between first and the previous major time.
+ time.startOf(major);
+ time.add(~~((first - time) / (interval.size * stepSize)) * stepSize, minor);
+ }
+
+ for (; time < last; time.add(stepSize, minor)) {
+ ticks.push(+time);
+ }
+
+ ticks.push(+time);
+
+ return ticks;
+}
+
+/**
+ * Returns the right and left offsets from edges in the form of {left, right}.
+ * Offsets are added when the `offset` option is true.
+ */
+function computeOffsets(table, ticks, min, max, options) {
+ var left = 0;
+ var right = 0;
+ var upper, lower;
+
+ if (options.offset && ticks.length) {
+ if (!options.time.min) {
+ upper = ticks.length > 1 ? ticks[1] : max;
+ lower = ticks[0];
+ left = (
+ interpolate(table, 'time', upper, 'pos') -
+ interpolate(table, 'time', lower, 'pos')
+ ) / 2;
+ }
+ if (!options.time.max) {
+ upper = ticks[ticks.length - 1];
+ lower = ticks.length > 1 ? ticks[ticks.length - 2] : min;
+ right = (
+ interpolate(table, 'time', upper, 'pos') -
+ interpolate(table, 'time', lower, 'pos')
+ ) / 2;
+ }
+ }
+
+ return {left: left, right: right};
+}
+
+function ticksFromTimestamps(values, majorUnit) {
+ var ticks = [];
+ var i, ilen, value, major;
+
+ for (i = 0, ilen = values.length; i < ilen; ++i) {
+ value = values[i];
+ major = majorUnit ? value === +moment(value).startOf(majorUnit) : false;
+
+ ticks.push({
+ value: value,
+ major: major
+ });
+ }
+
+ return ticks;
+}
+
+function determineLabelFormat(data, timeOpts) {
+ var i, momentDate, hasTime;
+ var ilen = data.length;
+
+ // find the label with the most parts (milliseconds, minutes, etc.)
+ // format all labels with the same level of detail as the most specific label
+ for (i = 0; i < ilen; i++) {
+ momentDate = momentify(data[i], timeOpts);
+ if (momentDate.millisecond() !== 0) {
+ return 'MMM D, YYYY h:mm:ss.SSS a';
+ }
+ if (momentDate.second() !== 0 || momentDate.minute() !== 0 || momentDate.hour() !== 0) {
+ hasTime = true;
+ }
+ }
+ if (hasTime) {
+ return 'MMM D, YYYY h:mm:ss a';
+ }
+ return 'MMM D, YYYY';
+}
+
+module.exports = function(Chart) {
+
+ var defaultConfig = {
+ position: 'bottom',
+
+ /**
+ * Data distribution along the scale:
+ * - 'linear': data are spread according to their time (distances can vary),
+ * - 'series': data are spread at the same distance from each other.
+ * @see https://github.com/chartjs/Chart.js/pull/4507
+ * @since 2.7.0
+ */
+ distribution: 'linear',
+
+ /**
+ * Scale boundary strategy (bypassed by min/max time options)
+ * - `data`: make sure data are fully visible, ticks outside are removed
+ * - `ticks`: make sure ticks are fully visible, data outside are truncated
+ * @see https://github.com/chartjs/Chart.js/pull/4556
+ * @since 2.7.0
+ */
+ bounds: 'data',
+
+ time: {
+ parser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment
+ format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/
+ unit: false, // false == automatic or override with week, month, year, etc.
+ round: false, // none, or override with week, month, year, etc.
+ displayFormat: false, // DEPRECATED
+ isoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/
+ minUnit: 'millisecond',
+
+ // defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/
+ displayFormats: {
+ millisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM,
+ second: 'h:mm:ss a', // 11:20:01 AM
+ minute: 'h:mm a', // 11:20 AM
+ hour: 'hA', // 5PM
+ day: 'MMM D', // Sep 4
+ week: 'll', // Week 46, or maybe "[W]WW - YYYY" ?
+ month: 'MMM YYYY', // Sept 2015
+ quarter: '[Q]Q - YYYY', // Q3
+ year: 'YYYY' // 2015
+ },
+ },
+ ticks: {
+ autoSkip: false,
+
+ /**
+ * Ticks generation input values:
+ * - 'auto': generates "optimal" ticks based on scale size and time options.
+ * - 'data': generates ticks from data (including labels from data {t|x|y} objects).
+ * - 'labels': generates ticks from user given `data.labels` values ONLY.
+ * @see https://github.com/chartjs/Chart.js/pull/4507
+ * @since 2.7.0
+ */
+ source: 'auto',
+
+ major: {
+ enabled: false
+ }
+ }
+ };
+
+ var TimeScale = Chart.Scale.extend({
+ initialize: function() {
+ if (!moment) {
+ throw new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com');
+ }
+
+ this.mergeTicksOptions();
+
+ Chart.Scale.prototype.initialize.call(this);
+ },
+
+ update: function() {
+ var me = this;
+ var options = me.options;
+
+ // DEPRECATIONS: output a message only one time per update
+ if (options.time && options.time.format) {
+ console.warn('options.time.format is deprecated and replaced by options.time.parser.');
+ }
+
+ return Chart.Scale.prototype.update.apply(me, arguments);
+ },
+
+ /**
+ * Allows data to be referenced via 't' attribute
+ */
+ getRightValue: function(rawValue) {
+ if (rawValue && rawValue.t !== undefined) {
+ rawValue = rawValue.t;
+ }
+ return Chart.Scale.prototype.getRightValue.call(this, rawValue);
+ },
+
+ determineDataLimits: function() {
+ var me = this;
+ var chart = me.chart;
+ var timeOpts = me.options.time;
+ var unit = timeOpts.unit || 'day';
+ var min = MAX_INTEGER;
+ var max = MIN_INTEGER;
+ var timestamps = [];
+ var datasets = [];
+ var labels = [];
+ var i, j, ilen, jlen, data, timestamp;
+
+ // Convert labels to timestamps
+ for (i = 0, ilen = chart.data.labels.length; i < ilen; ++i) {
+ labels.push(parse(chart.data.labels[i], me));
+ }
+
+ // Convert data to timestamps
+ for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
+ if (chart.isDatasetVisible(i)) {
+ data = chart.data.datasets[i].data;
+
+ // Let's consider that all data have the same format.
+ if (helpers.isObject(data[0])) {
+ datasets[i] = [];
+
+ for (j = 0, jlen = data.length; j < jlen; ++j) {
+ timestamp = parse(data[j], me);
+ timestamps.push(timestamp);
+ datasets[i][j] = timestamp;
+ }
+ } else {
+ timestamps.push.apply(timestamps, labels);
+ datasets[i] = labels.slice(0);
+ }
+ } else {
+ datasets[i] = [];
+ }
+ }
+
+ if (labels.length) {
+ // Sort labels **after** data have been converted
+ labels = arrayUnique(labels).sort(sorter);
+ min = Math.min(min, labels[0]);
+ max = Math.max(max, labels[labels.length - 1]);
+ }
+
+ if (timestamps.length) {
+ timestamps = arrayUnique(timestamps).sort(sorter);
+ min = Math.min(min, timestamps[0]);
+ max = Math.max(max, timestamps[timestamps.length - 1]);
+ }
+
+ min = parse(timeOpts.min, me) || min;
+ max = parse(timeOpts.max, me) || max;
+
+ // In case there is no valid min/max, set limits based on unit time option
+ min = min === MAX_INTEGER ? +moment().startOf(unit) : min;
+ max = max === MIN_INTEGER ? +moment().endOf(unit) + 1 : max;
+
+ // Make sure that max is strictly higher than min (required by the lookup table)
+ me.min = Math.min(min, max);
+ me.max = Math.max(min + 1, max);
+
+ // PRIVATE
+ me._horizontal = me.isHorizontal();
+ me._table = [];
+ me._timestamps = {
+ data: timestamps,
+ datasets: datasets,
+ labels: labels
+ };
+ },
+
+ buildTicks: function() {
+ var me = this;
+ var min = me.min;
+ var max = me.max;
+ var options = me.options;
+ var timeOpts = options.time;
+ var timestamps = [];
+ var ticks = [];
+ var i, ilen, timestamp;
+
+ switch (options.ticks.source) {
+ case 'data':
+ timestamps = me._timestamps.data;
+ break;
+ case 'labels':
+ timestamps = me._timestamps.labels;
+ break;
+ case 'auto':
+ default:
+ timestamps = generate(min, max, me.getLabelCapacity(min), options);
+ }
+
+ if (options.bounds === 'ticks' && timestamps.length) {
+ min = timestamps[0];
+ max = timestamps[timestamps.length - 1];
+ }
+
+ // Enforce limits with user min/max options
+ min = parse(timeOpts.min, me) || min;
+ max = parse(timeOpts.max, me) || max;
+
+ // Remove ticks outside the min/max range
+ for (i = 0, ilen = timestamps.length; i < ilen; ++i) {
+ timestamp = timestamps[i];
+ if (timestamp >= min && timestamp <= max) {
+ ticks.push(timestamp);
+ }
+ }
+
+ me.min = min;
+ me.max = max;
+
+ // PRIVATE
+ me._unit = timeOpts.unit || determineUnitForFormatting(ticks, timeOpts.minUnit, me.min, me.max);
+ me._majorUnit = determineMajorUnit(me._unit);
+ me._table = buildLookupTable(me._timestamps.data, min, max, options.distribution);
+ me._offsets = computeOffsets(me._table, ticks, min, max, options);
+ me._labelFormat = determineLabelFormat(me._timestamps.data, timeOpts);
+
+ return ticksFromTimestamps(ticks, me._majorUnit);
+ },
+
+ getLabelForIndex: function(index, datasetIndex) {
+ var me = this;
+ var data = me.chart.data;
+ var timeOpts = me.options.time;
+ var label = data.labels && index < data.labels.length ? data.labels[index] : '';
+ var value = data.datasets[datasetIndex].data[index];
+
+ if (helpers.isObject(value)) {
+ label = me.getRightValue(value);
+ }
+ if (timeOpts.tooltipFormat) {
+ return momentify(label, timeOpts).format(timeOpts.tooltipFormat);
+ }
+ if (typeof label === 'string') {
+ return label;
+ }
+
+ return momentify(label, timeOpts).format(me._labelFormat);
+ },
+
+ /**
+ * Function to format an individual tick mark
+ * @private
+ */
+ tickFormatFunction: function(tick, index, ticks, formatOverride) {
+ var me = this;
+ var options = me.options;
+ var time = tick.valueOf();
+ var formats = options.time.displayFormats;
+ var minorFormat = formats[me._unit];
+ var majorUnit = me._majorUnit;
+ var majorFormat = formats[majorUnit];
+ var majorTime = tick.clone().startOf(majorUnit).valueOf();
+ var majorTickOpts = options.ticks.major;
+ var major = majorTickOpts.enabled && majorUnit && majorFormat && time === majorTime;
+ var label = tick.format(formatOverride ? formatOverride : major ? majorFormat : minorFormat);
+ var tickOpts = major ? majorTickOpts : options.ticks.minor;
+ var formatter = helpers.valueOrDefault(tickOpts.callback, tickOpts.userCallback);
+
+ return formatter ? formatter(label, index, ticks) : label;
+ },
+
+ convertTicksToLabels: function(ticks) {
+ var labels = [];
+ var i, ilen;
+
+ for (i = 0, ilen = ticks.length; i < ilen; ++i) {
+ labels.push(this.tickFormatFunction(moment(ticks[i].value), i, ticks));
+ }
+
+ return labels;
+ },
+
+ /**
+ * @private
+ */
+ getPixelForOffset: function(time) {
+ var me = this;
+ var size = me._horizontal ? me.width : me.height;
+ var start = me._horizontal ? me.left : me.top;
+ var pos = interpolate(me._table, 'time', time, 'pos');
+
+ return start + size * (me._offsets.left + pos) / (me._offsets.left + 1 + me._offsets.right);
+ },
+
+ getPixelForValue: function(value, index, datasetIndex) {
+ var me = this;
+ var time = null;
+
+ if (index !== undefined && datasetIndex !== undefined) {
+ time = me._timestamps.datasets[datasetIndex][index];
+ }
+
+ if (time === null) {
+ time = parse(value, me);
+ }
+
+ if (time !== null) {
+ return me.getPixelForOffset(time);
+ }
+ },
+
+ getPixelForTick: function(index) {
+ var ticks = this.getTicks();
+ return index >= 0 && index < ticks.length ?
+ this.getPixelForOffset(ticks[index].value) :
+ null;
+ },
+
+ getValueForPixel: function(pixel) {
+ var me = this;
+ var size = me._horizontal ? me.width : me.height;
+ var start = me._horizontal ? me.left : me.top;
+ var pos = (size ? (pixel - start) / size : 0) * (me._offsets.left + 1 + me._offsets.left) - me._offsets.right;
+ var time = interpolate(me._table, 'pos', pos, 'time');
+
+ return moment(time);
+ },
+
+ /**
+ * Crude approximation of what the label width might be
+ * @private
+ */
+ getLabelWidth: function(label) {
+ var me = this;
+ var ticksOpts = me.options.ticks;
+ var tickLabelWidth = me.ctx.measureText(label).width;
+ var angle = helpers.toRadians(ticksOpts.maxRotation);
+ var cosRotation = Math.cos(angle);
+ var sinRotation = Math.sin(angle);
+ var tickFontSize = helpers.valueOrDefault(ticksOpts.fontSize, defaults.global.defaultFontSize);
+
+ return (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);
+ },
+
+ /**
+ * @private
+ */
+ getLabelCapacity: function(exampleTime) {
+ var me = this;
+
+ var formatOverride = me.options.time.displayFormats.millisecond; // Pick the longest format for guestimation
+
+ var exampleLabel = me.tickFormatFunction(moment(exampleTime), 0, [], formatOverride);
+ var tickLabelWidth = me.getLabelWidth(exampleLabel);
+ var innerWidth = me.isHorizontal() ? me.width : me.height;
+
+ var capacity = Math.floor(innerWidth / tickLabelWidth);
+ return capacity > 0 ? capacity : 1;
+ }
+ });
+
+ Chart.scaleService.registerScaleType('time', TimeScale, defaultConfig);
+};
+
+},{"1":1,"25":25,"45":45}]},{},[7])(7)
+});
\ No newline at end of file
diff --git a/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/chart/Chart.min.js b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/chart/Chart.min.js
new file mode 100644
index 0000000..875689e
--- /dev/null
+++ b/IoTDashboardWithSignalR/src/IoTDashboardWithSignalR.Web/wwwroot/lib/chart/Chart.min.js
@@ -0,0 +1,10 @@
+/*!
+ * Chart.js
+ * http://chartjs.org/
+ * Version: 2.7.2
+ *
+ * Copyright 2018 Chart.js Contributors
+ * Released under the MIT license
+ * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
+ */
+!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Chart=t()}}(function(){return function t(e,i,n){function a(r,s){if(!i[r]){if(!e[r]){var l="function"==typeof require&&require;if(!s&&l)return l(r,!0);if(o)return o(r,!0);var u=new Error("Cannot find module '"+r+"'");throw u.code="MODULE_NOT_FOUND",u}var d=i[r]={exports:{}};e[r][0].call(d.exports,function(t){var i=e[r][1][t];return a(i||t)},d,d.exports,t,e,i,n)}return i[r].exports}for(var o="function"==typeof require&&require,r=0;ri?(e+.05)/(i+.05):(i+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,i=(e[0]+t)%360;return e[0]=i<0?360+i:i,this.setValues("hsl",e),this},mix:function(t,e){var i=this,n=t,a=void 0===e?.5:e,o=2*a-1,r=i.alpha()-n.alpha(),s=((o*r==-1?o:(o+r)/(1+o*r))+1)/2,l=1-s;return this.rgb(s*i.red()+l*n.red(),s*i.green()+l*n.green(),s*i.blue()+l*n.blue()).alpha(i.alpha()*a+n.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,i=new o,n=this.values,a=i.values;for(var r in n)n.hasOwnProperty(r)&&(t=n[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return i}},o.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},o.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},o.prototype.getValues=function(t){for(var e=this.values,i={},n=0;n.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)+.1805*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)),100*(.2126*e+.7152*i+.0722*n),100*(.0193*e+.1192*i+.9505*n)]}function d(t){var e=u(t),i=e[0],n=e[1],a=e[2];return n/=100,a/=108.883,i=(i/=95.047)>.008856?Math.pow(i,1/3):7.787*i+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(i-n),200*(n-(a=a>.008856?Math.pow(a,1/3):7.787*a+16/116))]}function c(t){var e,i,n,a,o,r=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return[o=255*l,o,o];e=2*l-(i=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(n=r+1/3*-(u-1))<0&&n++,n>1&&n--,o=6*n<1?e+6*(i-e)*n:2*n<1?i:3*n<2?e+(i-e)*(2/3-n)*6:e,a[u]=255*o;return a}function h(t){var e=t[0]/60,i=t[1]/100,n=t[2]/100,a=Math.floor(e)%6,o=e-Math.floor(e),r=255*n*(1-i),s=255*n*(1-i*o),l=255*n*(1-i*(1-o));n*=255;switch(a){case 0:return[n,l,r];case 1:return[s,n,r];case 2:return[r,n,l];case 3:return[r,s,n];case 4:return[l,r,n];case 5:return[n,r,s]}}function f(t){var e,i,n,a,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),n=6*o-(e=Math.floor(6*o)),0!=(1&e)&&(n=1-n),a=s+n*((i=1-l)-s),e){default:case 6:case 0:r=i,g=a,b=s;break;case 1:r=a,g=i,b=s;break;case 2:r=s,g=i,b=a;break;case 3:r=s,g=a,b=i;break;case 4:r=a,g=s,b=i;break;case 5:r=i,g=s,b=a}return[255*r,255*g,255*b]}function p(t){var e=t[0]/100,i=t[1]/100,n=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a))]}function m(t){var e,i,n,a=t[0]/100,o=t[1]/100,r=t[2]/100;return i=-.9689*a+1.8758*o+.0415*r,n=.0557*a+-.204*o+1.057*r,e=(e=3.2406*a+-1.5372*o+-.4986*r)>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n*=12.92,[255*(e=Math.min(Math.max(0,e),1)),255*(i=Math.min(Math.max(0,i),1)),255*(n=Math.min(Math.max(0,n),1))]}function v(t){var e=t[0],i=t[1],n=t[2];return i/=100,n/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(e-i),200*(i-(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116))]}function x(t){var e,i,n,a,o=t[0],r=t[1],s=t[2];return o<=8?a=(i=100*o/903.3)/100*7.787+16/116:(i=100*Math.pow((o+16)/116,3),a=Math.pow(i/100,1/3)),[e=e/95.047<=.008856?e=95.047*(r/500+a-16/116)/7.787:95.047*Math.pow(r/500+a,3),i,n=n/108.883<=.008859?n=108.883*(a-s/200-16/116)/7.787:108.883*Math.pow(a-s/200,3)]}function y(t){var e,i=t[0],n=t[1],a=t[2];return(e=360*Math.atan2(a,n)/2/Math.PI)<0&&(e+=360),[i,Math.sqrt(n*n+a*a),e]}function k(t){return m(x(t))}function M(t){var e,i=t[0],n=t[1];return e=t[2]/360*2*Math.PI,[i,n*Math.cos(e),n*Math.sin(e)]}function w(t){return S[t]}e.exports={rgb2hsl:n,rgb2hsv:a,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:function(t){return y(d(t))},hsl2rgb:c,hsl2hsv:function(t){var e=t[0],i=t[1]/100,n=t[2]/100;if(0===n)return[0,0,0];return[e,100*(2*(i*=(n*=2)<=1?n:2-n)/(n+i)),100*((n+i)/2)]},hsl2hwb:function(t){return o(c(t))},hsl2cmyk:function(t){return s(c(t))},hsl2keyword:function(t){return l(c(t))},hsv2rgb:h,hsv2hsl:function(t){var e,i,n=t[0],a=t[1]/100,o=t[2]/100;return e=a*o,[n,100*(e=(e/=(i=(2-a)*o)<=1?i:2-i)||0),100*(i/=2)]},hsv2hwb:function(t){return o(h(t))},hsv2cmyk:function(t){return s(h(t))},hsv2keyword:function(t){return l(h(t))},hwb2rgb:f,hwb2hsl:function(t){return n(f(t))},hwb2hsv:function(t){return a(f(t))},hwb2cmyk:function(t){return s(f(t))},hwb2keyword:function(t){return l(f(t))},cmyk2rgb:p,cmyk2hsl:function(t){return n(p(t))},cmyk2hsv:function(t){return a(p(t))},cmyk2hwb:function(t){return o(p(t))},cmyk2keyword:function(t){return l(p(t))},keyword2rgb:w,keyword2hsl:function(t){return n(w(t))},keyword2hsv:function(t){return a(w(t))},keyword2hwb:function(t){return o(w(t))},keyword2cmyk:function(t){return s(w(t))},keyword2lab:function(t){return d(w(t))},keyword2xyz:function(t){return u(w(t))},xyz2rgb:m,xyz2lab:v,xyz2lch:function(t){return y(v(t))},lab2xyz:x,lab2rgb:k,lab2lch:y,lch2lab:M,lch2xyz:function(t){return x(M(t))},lch2rgb:function(t){return k(M(t))}};var S={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},C={};for(var _ in S)C[JSON.stringify(S[_])]=_},{}],5:[function(t,e,i){var n=t(4),a=function(){return new u};for(var o in n){a[o+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),n[t](e)}}(o);var r=/(\w+)2(\w+)/.exec(o),s=r[1],l=r[2];(a[s]=a[s]||{})[l]=a[o]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var i=n[t](e);if("string"==typeof i||void 0===i)return i;for(var a=0;a0&&(t[0].yLabel?i=t[0].yLabel:e.labels.length>0&&t[0].index0?Math.min(r,n-i):r,i=n;return r}(i,u):-1,pixels:u,start:s,end:l,stackCount:n,scale:i}},calculateBarValuePixels:function(t,e){var i,n,a,o,r,s,l=this.chart,u=this.getMeta(),d=this.getValueScale(),c=l.data.datasets,h=d.getRightValue(c[t].data[e]),f=d.options.stacked,g=u.stack,p=0;if(f||void 0===f&&void 0!==g)for(i=0;i=0&&a>0)&&(p+=a));return o=d.getPixelForValue(p),{size:s=((r=d.getPixelForValue(p+h))-o)/2,base:o,head:r,center:r+s/2}},calculateBarIndexPixels:function(t,e,i){var n,a,r,s,l,u,d,c,h,f,g,p,m,v,b,x,y,k=i.scale.options,M="flex"===k.barThickness?(h=e,g=k,m=(f=i).pixels,v=m[h],b=h>0?m[h-1]:null,x=h');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var o=0;o '),a[o]&&e.push(a[o]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(i,n){var a=t.getDatasetMeta(0),r=e.datasets[0],s=a.data[n],l=s&&s.custom||{},u=o.valueAtIndexOrDefault,d=t.options.elements.arc;return{text:i,fillStyle:l.backgroundColor?l.backgroundColor:u(r.backgroundColor,n,d.backgroundColor),strokeStyle:l.borderColor?l.borderColor:u(r.borderColor,n,d.borderColor),lineWidth:l.borderWidth?l.borderWidth:u(r.borderWidth,n,d.borderWidth),hidden:isNaN(r.data[n])||a.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var i,n,a,o=e.index,r=this.chart;for(i=0,n=(r.data.datasets||[]).length;i=Math.PI?-1:g<-Math.PI?1:0))+f,m=Math.cos(g),v=Math.sin(g),b=Math.cos(p),x=Math.sin(p),y=g<=0&&p>=0||g<=2*Math.PI&&2*Math.PI<=p,k=g<=.5*Math.PI&&.5*Math.PI<=p||g<=2.5*Math.PI&&2.5*Math.PI<=p,M=g<=-Math.PI&&-Math.PI<=p||g<=Math.PI&&Math.PI<=p,w=g<=.5*-Math.PI&&.5*-Math.PI<=p||g<=1.5*Math.PI&&1.5*Math.PI<=p,S=h/100,C=M?-1:Math.min(m*(m<0?1:S),b*(b<0?1:S)),_=w?-1:Math.min(v*(v<0?1:S),x*(x<0?1:S)),D=y?1:Math.max(m*(m>0?1:S),b*(b>0?1:S)),I=k?1:Math.max(v*(v>0?1:S),x*(x>0?1:S)),P=.5*(D-C),A=.5*(I-_);u=Math.min(s/P,l/A),d={x:-.5*(D+C),y:-.5*(I+_)}}i.borderWidth=e.getMaxBorderWidth(c.data),i.outerRadius=Math.max((u-i.borderWidth)/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:0,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=d.x*i.outerRadius,i.offsetY=d.y*i.outerRadius,c.total=e.calculateTotal(),e.outerRadius=i.outerRadius-i.radiusLength*e.getRingIndex(e.index),e.innerRadius=Math.max(e.outerRadius-i.radiusLength,0),o.each(c.data,function(i,n){e.updateElement(i,n,t)})},updateElement:function(t,e,i){var n=this,a=n.chart,r=a.chartArea,s=a.options,l=s.animation,u=(r.left+r.right)/2,d=(r.top+r.bottom)/2,c=s.rotation,h=s.rotation,f=n.getDataset(),g=i&&l.animateRotate?0:t.hidden?0:n.calculateCircumference(f.data[e])*(s.circumference/(2*Math.PI)),p=i&&l.animateScale?0:n.innerRadius,m=i&&l.animateScale?0:n.outerRadius,v=o.valueAtIndexOrDefault;o.extend(t,{_datasetIndex:n.index,_index:e,_model:{x:u+a.offsetX,y:d+a.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:m,innerRadius:p,label:v(f.label,e,a.data.labels[e])}});var b=t._model;this.removeHoverStyle(t),i&&l.animateRotate||(b.startAngle=0===e?s.rotation:n.getMeta().data[e-1]._model.endAngle,b.endAngle=b.startAngle+b.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,e=this.getDataset(),i=this.getMeta(),n=0;return o.each(i.data,function(i,a){t=e.data[a],isNaN(t)||i.hidden||(n+=Math.abs(t))}),n},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){for(var e,i,n=0,a=this.index,o=t.length,r=0;r(n=e>n?e:n)?i:n;return n}})}},{25:25,40:40,45:45}],18:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}}),e.exports=function(t){function e(t,e){return o.valueOrDefault(t.showLine,e.showLines)}t.controllers.line=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,update:function(t){var i,n,a,r=this,s=r.getMeta(),l=s.dataset,u=s.data||[],d=r.chart.options,c=d.elements.line,h=r.getScaleForId(s.yAxisID),f=r.getDataset(),g=e(f,d);for(g&&(a=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=h,l._datasetIndex=r.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:a.tension?a.tension:o.valueOrDefault(f.lineTension,c.tension),backgroundColor:a.backgroundColor?a.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:a.borderWidth?a.borderWidth:f.borderWidth||c.borderWidth,borderColor:a.borderColor?a.borderColor:f.borderColor||c.borderColor,borderCapStyle:a.borderCapStyle?a.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:a.borderDash?a.borderDash:f.borderDash||c.borderDash,borderDashOffset:a.borderDashOffset?a.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:a.borderJoinStyle?a.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:a.fill?a.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:a.steppedLine?a.steppedLine:o.valueOrDefault(f.steppedLine,c.stepped),cubicInterpolationMode:a.cubicInterpolationMode?a.cubicInterpolationMode:o.valueOrDefault(f.cubicInterpolationMode,c.cubicInterpolationMode)},l.pivot()),i=0,n=u.length;i');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var o=0;o '),a[o]&&e.push(a[o]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(i,n){var a=t.getDatasetMeta(0),r=e.datasets[0],s=a.data[n].custom||{},l=o.valueAtIndexOrDefault,u=t.options.elements.arc;return{text:i,fillStyle:s.backgroundColor?s.backgroundColor:l(r.backgroundColor,n,u.backgroundColor),strokeStyle:s.borderColor?s.borderColor:l(r.borderColor,n,u.borderColor),lineWidth:s.borderWidth?s.borderWidth:l(r.borderWidth,n,u.borderWidth),hidden:isNaN(r.data[n])||a.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var i,n,a,o=e.index,r=this.chart;for(i=0,n=(r.data.datasets||[]).length;i0&&!isNaN(t)?2*Math.PI/e:0}})}},{25:25,40:40,45:45}],20:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("radar",{scale:{type:"radialLinear"},elements:{line:{tension:0}}}),e.exports=function(t){t.controllers.radar=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,linkScales:o.noop,update:function(t){var e=this,i=e.getMeta(),n=i.dataset,a=i.data,r=n.custom||{},s=e.getDataset(),l=e.chart.options.elements.line,u=e.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),o.extend(i.dataset,{_datasetIndex:e.index,_scale:u,_children:a,_loop:!0,_model:{tension:r.tension?r.tension:o.valueOrDefault(s.lineTension,l.tension),backgroundColor:r.backgroundColor?r.backgroundColor:s.backgroundColor||l.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:s.borderWidth||l.borderWidth,borderColor:r.borderColor?r.borderColor:s.borderColor||l.borderColor,fill:r.fill?r.fill:void 0!==s.fill?s.fill:l.fill,borderCapStyle:r.borderCapStyle?r.borderCapStyle:s.borderCapStyle||l.borderCapStyle,borderDash:r.borderDash?r.borderDash:s.borderDash||l.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:s.borderDashOffset||l.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:s.borderJoinStyle||l.borderJoinStyle}}),i.dataset.pivot(),o.each(a,function(i,n){e.updateElement(i,n,t)},e),e.updateBezierControlPoints()},updateElement:function(t,e,i){var n=this,a=t.custom||{},r=n.getDataset(),s=n.chart.scale,l=n.chart.options.elements.point,u=s.getPointPositionForValue(e,r.data[e]);void 0!==r.radius&&void 0===r.pointRadius&&(r.pointRadius=r.radius),void 0!==r.hitRadius&&void 0===r.pointHitRadius&&(r.pointHitRadius=r.hitRadius),o.extend(t,{_datasetIndex:n.index,_index:e,_scale:s,_model:{x:i?s.xCenter:u.x,y:i?s.yCenter:u.y,tension:a.tension?a.tension:o.valueOrDefault(r.lineTension,n.chart.options.elements.line.tension),radius:a.radius?a.radius:o.valueAtIndexOrDefault(r.pointRadius,e,l.radius),backgroundColor:a.backgroundColor?a.backgroundColor:o.valueAtIndexOrDefault(r.pointBackgroundColor,e,l.backgroundColor),borderColor:a.borderColor?a.borderColor:o.valueAtIndexOrDefault(r.pointBorderColor,e,l.borderColor),borderWidth:a.borderWidth?a.borderWidth:o.valueAtIndexOrDefault(r.pointBorderWidth,e,l.borderWidth),pointStyle:a.pointStyle?a.pointStyle:o.valueAtIndexOrDefault(r.pointStyle,e,l.pointStyle),hitRadius:a.hitRadius?a.hitRadius:o.valueAtIndexOrDefault(r.pointHitRadius,e,l.hitRadius)}}),t._model.skip=a.skip?a.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,e=this.getMeta();o.each(e.data,function(i,n){var a=i._model,r=o.splineCurve(o.previousItem(e.data,n,!0)._model,a,o.nextItem(e.data,n,!0)._model,a.tension);a.controlPointPreviousX=Math.max(Math.min(r.previous.x,t.right),t.left),a.controlPointPreviousY=Math.max(Math.min(r.previous.y,t.bottom),t.top),a.controlPointNextX=Math.max(Math.min(r.next.x,t.right),t.left),a.controlPointNextY=Math.max(Math.min(r.next.y,t.bottom),t.top),i.pivot()})},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,a=t._model;a.radius=i.hoverRadius?i.hoverRadius:o.valueAtIndexOrDefault(e.pointHoverRadius,n,this.chart.options.elements.point.hoverRadius),a.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:o.valueAtIndexOrDefault(e.pointHoverBackgroundColor,n,o.getHoverColor(a.backgroundColor)),a.borderColor=i.hoverBorderColor?i.hoverBorderColor:o.valueAtIndexOrDefault(e.pointHoverBorderColor,n,o.getHoverColor(a.borderColor)),a.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:o.valueAtIndexOrDefault(e.pointHoverBorderWidth,n,a.borderWidth)},removeHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,a=t._model,r=this.chart.options.elements.point;a.radius=i.radius?i.radius:o.valueAtIndexOrDefault(e.pointRadius,n,r.radius),a.backgroundColor=i.backgroundColor?i.backgroundColor:o.valueAtIndexOrDefault(e.pointBackgroundColor,n,r.backgroundColor),a.borderColor=i.borderColor?i.borderColor:o.valueAtIndexOrDefault(e.pointBorderColor,n,r.borderColor),a.borderWidth=i.borderWidth?i.borderWidth:o.valueAtIndexOrDefault(e.pointBorderWidth,n,r.borderWidth)}})}},{25:25,40:40,45:45}],21:[function(t,e,i){"use strict";t(25)._set("scatter",{hover:{mode:"single"},scales:{xAxes:[{id:"x-axis-1",type:"linear",position:"bottom"}],yAxes:[{id:"y-axis-1",type:"linear",position:"left"}]},showLines:!1,tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}}),e.exports=function(t){t.controllers.scatter=t.controllers.line}},{25:25}],22:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45);n._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:o.noop,onComplete:o.noop}}),e.exports=function(t){t.Animation=a.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,i,n){var a,o,r=this.animations;for(e.chart=t,n||(t.animating=!0),a=0,o=r.length;a1&&(i=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1),t.advance(1+i);var n=Date.now();t.dropFrames+=(n-e)/t.frameDuration,t.animations.length>0&&t.requestAnimationFrame()},advance:function(t){for(var e,i,n=this.animations,a=0;a=e.numSteps?(o.callback(e.onAnimationComplete,[e],i),i.animating=!1,n.splice(a,1)):++a}},Object.defineProperty(t.Animation.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(t.Animation.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}})}},{25:25,26:26,45:45}],23:[function(t,e,i){"use strict";var n=t(25),a=t(45),o=t(28),r=t(30),s=t(48),l=t(31);e.exports=function(t){function e(t){return"top"===t||"bottom"===t}t.types={},t.instances={},t.controllers={},a.extend(t.prototype,{construct:function(e,i){var o,r,l=this;(r=(o=(o=i)||{}).data=o.data||{}).datasets=r.datasets||[],r.labels=r.labels||[],o.options=a.configMerge(n.global,n[o.type],o.options||{}),i=o;var u=s.acquireContext(e,i),d=u&&u.canvas,c=d&&d.height,h=d&&d.width;l.id=a.uid(),l.ctx=u,l.canvas=d,l.config=i,l.width=h,l.height=c,l.aspectRatio=c?h/c:null,l.options=i.options,l._bufferedRender=!1,l.chart=l,l.controller=l,t.instances[l.id]=l,Object.defineProperty(l,"data",{get:function(){return l.config.data},set:function(t){l.config.data=t}}),u&&d?(l.initialize(),l.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return l.notify(t,"beforeInit"),a.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.initToolTip(),l.notify(t,"afterInit"),t},clear:function(){return a.canvas.clear(this),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(t){var e=this,i=e.options,n=e.canvas,o=i.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(a.getMaximumWidth(n))),s=Math.max(0,Math.floor(o?r/o:a.getMaximumHeight(n)));if((e.width!==r||e.height!==s)&&(n.width=e.width=r,n.height=e.height=s,n.style.width=r+"px",n.style.height=s+"px",a.retinaScale(e,i.devicePixelRatio),!t)){var u={width:r,height:s};l.notify(e,"resize",[u]),e.options.onResize&&e.options.onResize(e,u),e.stop(),e.update(e.options.responsiveAnimationDuration)}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},i=t.scale;a.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),a.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),i&&(i.id=i.id||"scale")},buildOrUpdateScales:function(){var i=this,n=i.options,o=i.scales||{},r=[],s=Object.keys(o).reduce(function(t,e){return t[e]=!1,t},{});n.scales&&(r=r.concat((n.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(n.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),n.scale&&r.push({options:n.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),a.each(r,function(n){var r=n.options,l=r.id,u=a.valueOrDefault(r.type,n.dtype);e(r.position)!==e(n.dposition)&&(r.position=n.dposition),s[l]=!0;var d=null;if(l in o&&o[l].type===u)(d=o[l]).options=r,d.ctx=i.ctx,d.chart=i;else{var c=t.scaleService.getScaleConstructor(u);if(!c)return;d=new c({id:l,type:u,options:r,ctx:i.ctx,chart:i}),o[d.id]=d}d.mergeTicksOptions(),n.isDefault&&(i.scale=d)}),a.each(s,function(t,e){t||delete o[e]}),i.scales=o,t.scaleService.addScalesToLayout(this)},buildOrUpdateControllers:function(){var e=this,i=[],n=[];return a.each(e.data.datasets,function(a,o){var r=e.getDatasetMeta(o),s=a.type||e.config.type;if(r.type&&r.type!==s&&(e.destroyDatasetMeta(o),r=e.getDatasetMeta(o)),r.type=s,i.push(r.type),r.controller)r.controller.updateIndex(o),r.controller.linkScales();else{var l=t.controllers[r.type];if(void 0===l)throw new Error('"'+r.type+'" is not a chart type.');r.controller=new l(e,o),n.push(r.controller)}},e),n},resetElements:function(){var t=this;a.each(t.data.datasets,function(e,i){t.getDatasetMeta(i).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(e){var i,n,o=this;if(e&&"object"==typeof e||(e={duration:e,lazy:arguments[1]}),n=(i=o).options,a.each(i.scales,function(t){r.removeBox(i,t)}),n=a.configMerge(t.defaults.global,t.defaults[i.config.type],n),i.options=i.config.options=n,i.ensureScalesHaveIDs(),i.buildOrUpdateScales(),i.tooltip._options=n.tooltips,i.tooltip.initialize(),l._invalidate(o),!1!==l.notify(o,"beforeUpdate")){o.tooltip._data=o.data;var s=o.buildOrUpdateControllers();a.each(o.data.datasets,function(t,e){o.getDatasetMeta(e).controller.buildOrUpdateElements()},o),o.updateLayout(),o.options.animation&&o.options.animation.duration&&a.each(s,function(t){t.reset()}),o.updateDatasets(),o.tooltip.initialize(),o.lastActive=[],l.notify(o,"afterUpdate"),o._bufferedRender?o._bufferedRequest={duration:e.duration,easing:e.easing,lazy:e.lazy}:o.render(e)}},updateLayout:function(){!1!==l.notify(this,"beforeLayout")&&(r.update(this,this.width,this.height),l.notify(this,"afterScaleUpdate"),l.notify(this,"afterLayout"))},updateDatasets:function(){if(!1!==l.notify(this,"beforeDatasetsUpdate")){for(var t=0,e=this.data.datasets.length;t=0;--i)e.isDatasetVisible(i)&&e.drawDataset(i,t);l.notify(e,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var i=this.getDatasetMeta(t),n={meta:i,index:t,easingValue:e};!1!==l.notify(this,"beforeDatasetDraw",[n])&&(i.controller.draw(e),l.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,i={tooltip:e,easingValue:t};!1!==l.notify(this,"beforeTooltipDraw",[i])&&(e.draw(),l.notify(this,"afterTooltipDraw",[i]))},getElementAtEvent:function(t){return o.modes.single(this,t)},getElementsAtEvent:function(t){return o.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return o.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,i){var n=o.modes[e];return"function"==typeof n?n(this,t,i):[]},getDatasetAtEvent:function(t){return o.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var i=e._meta[this.id];return i||(i=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,i=this.data.datasets.length;e0||(e.forEach(function(e){delete t[e]}),delete t._chartjs)}}t.DatasetController=function(t,e){this.initialize(t,e)},n.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){this.chart=t,this.index=e,this.linkScales(),this.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),i=t.getDataset();null!==e.xAxisID&&e.xAxisID in t.chart.scales||(e.xAxisID=i.xAxisID||t.chart.options.scales.xAxes[0].id),null!==e.yAxisID&&e.yAxisID in t.chart.scales||(e.yAxisID=i.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},destroy:function(){this._data&&i(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,i=this.getMeta(),n=this.getDataset().data||[],a=i.data;for(t=0,e=n.length;ti&&this.insertElements(i,n-i)},insertElements:function(t,e){for(var i=0;i=i[e].length&&i[e].push({}),!i[e][r].type||l.type&&l.type!==i[e][r].type?o.merge(i[e][r],[t.scaleService.getScaleDefaults(s),l]):o.merge(i[e][r],l)}else o._merger(e,i,n,a)}})},o.where=function(t,e){if(o.isArray(t)&&Array.prototype.filter)return t.filter(e);var i=[];return o.each(t,function(t){e(t)&&i.push(t)}),i},o.findIndex=Array.prototype.findIndex?function(t,e,i){return t.findIndex(e,i)}:function(t,e,i){i=void 0===i?t:i;for(var n=0,a=t.length;n=0;n--){var a=t[n];if(e(a))return a}},o.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},o.almostEquals=function(t,e,i){return Math.abs(t-e)t},o.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},o.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},o.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},o.log10=Math.log10?function(t){return Math.log10(t)}:function(t){var e=Math.log(t)*Math.LOG10E,i=Math.round(e);return t===Math.pow(10,i)?i:e},o.toRadians=function(t){return t*(Math.PI/180)},o.toDegrees=function(t){return t*(180/Math.PI)},o.getAngleFromPoint=function(t,e){var i=e.x-t.x,n=e.y-t.y,a=Math.sqrt(i*i+n*n),o=Math.atan2(n,i);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:a}},o.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},o.aliasPixel=function(t){return t%2==0?0:.5},o.splineCurve=function(t,e,i,n){var a=t.skip?e:t,o=e,r=i.skip?e:i,s=Math.sqrt(Math.pow(o.x-a.x,2)+Math.pow(o.y-a.y,2)),l=Math.sqrt(Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)),u=s/(s+l),d=l/(s+l),c=n*(u=isNaN(u)?0:u),h=n*(d=isNaN(d)?0:d);return{previous:{x:o.x-c*(r.x-a.x),y:o.y-c*(r.y-a.y)},next:{x:o.x+h*(r.x-a.x),y:o.y+h*(r.y-a.y)}}},o.EPSILON=Number.EPSILON||1e-14,o.splineCurveMonotone=function(t){var e,i,n,a,r,s,l,u,d,c=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),h=c.length;for(e=0;e0?c[e-1]:null,(a=e0?c[e-1]:null,a=e=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},o.previousItem=function(t,e,i){return i?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},o.niceNum=function(t,e){var i=Math.floor(o.log10(t)),n=t/Math.pow(10,i);return(e?n<1.5?1:n<3?2:n<7?5:10:n<=1?1:n<=2?2:n<=5?5:10)*Math.pow(10,i)},o.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},o.getRelativePosition=function(t,e){var i,n,a=t.originalEvent||t,r=t.currentTarget||t.srcElement,s=r.getBoundingClientRect(),l=a.touches;l&&l.length>0?(i=l[0].clientX,n=l[0].clientY):(i=a.clientX,n=a.clientY);var u=parseFloat(o.getStyle(r,"padding-left")),d=parseFloat(o.getStyle(r,"padding-top")),c=parseFloat(o.getStyle(r,"padding-right")),h=parseFloat(o.getStyle(r,"padding-bottom")),f=s.right-s.left-u-c,g=s.bottom-s.top-d-h;return{x:i=Math.round((i-s.left-u)/f*r.width/e.currentDevicePixelRatio),y:n=Math.round((n-s.top-d)/g*r.height/e.currentDevicePixelRatio)}},o.getConstraintWidth=function(t){return r(t,"max-width","clientWidth")},o.getConstraintHeight=function(t){return r(t,"max-height","clientHeight")},o.getMaximumWidth=function(t){var e=t.parentNode;if(!e)return t.clientWidth;var i=parseInt(o.getStyle(e,"padding-left"),10),n=parseInt(o.getStyle(e,"padding-right"),10),a=e.clientWidth-i-n,r=o.getConstraintWidth(t);return isNaN(r)?a:Math.min(a,r)},o.getMaximumHeight=function(t){var e=t.parentNode;if(!e)return t.clientHeight;var i=parseInt(o.getStyle(e,"padding-top"),10),n=parseInt(o.getStyle(e,"padding-bottom"),10),a=e.clientHeight-i-n,r=o.getConstraintHeight(t);return isNaN(r)?a:Math.min(a,r)},o.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},o.retinaScale=function(t,e){var i=t.currentDevicePixelRatio=e||window.devicePixelRatio||1;if(1!==i){var n=t.canvas,a=t.height,o=t.width;n.height=a*i,n.width=o*i,t.ctx.scale(i,i),n.style.height||n.style.width||(n.style.height=a+"px",n.style.width=o+"px")}},o.fontString=function(t,e,i){return e+" "+t+"px "+i},o.longestText=function(t,e,i,n){var a=(n=n||{}).data=n.data||{},r=n.garbageCollect=n.garbageCollect||[];n.font!==e&&(a=n.data={},r=n.garbageCollect=[],n.font=e),t.font=e;var s=0;o.each(i,function(e){null!=e&&!0!==o.isArray(e)?s=o.measureText(t,a,r,s,e):o.isArray(e)&&o.each(e,function(e){null==e||o.isArray(e)||(s=o.measureText(t,a,r,s,e))})});var l=r.length/2;if(l>i.length){for(var u=0;un&&(n=o),n},o.numberOfLabelLines=function(t){var e=1;return o.each(t,function(t){o.isArray(t)&&t.length>e&&(e=t.length)}),e},o.color=n?function(t){return t instanceof CanvasGradient&&(t=a.global.defaultColor),n(t)}:function(t){return console.error("Color.js not found!"),t},o.getHoverColor=function(t){return t instanceof CanvasPattern?t:o.color(t).saturate(.5).darken(.1).rgbString()}}},{25:25,3:3,45:45}],28:[function(t,e,i){"use strict";var n=t(45);function a(t,e){return t.native?{x:t.x,y:t.y}:n.getRelativePosition(t,e)}function o(t,e){var i,n,a,o,r;for(n=0,o=t.data.datasets.length;n0&&(u=t.getDatasetMeta(u[0]._datasetIndex).data),u},"x-axis":function(t,e){return u(t,e,{intersect:!1})},point:function(t,e){return r(t,a(e,t))},nearest:function(t,e,i){var n=a(e,t);i.axis=i.axis||"xy";var o=l(i.axis),r=s(t,n,i.intersect,o);return r.length>1&&r.sort(function(t,e){var i=t.getArea()-e.getArea();return 0===i&&(i=t._datasetIndex-e._datasetIndex),i}),r.slice(0,1)},x:function(t,e,i){var n=a(e,t),r=[],s=!1;return o(t,function(t){t.inXRange(n.x)&&r.push(t),t.inRange(n.x,n.y)&&(s=!0)}),i.intersect&&!s&&(r=[]),r},y:function(t,e,i){var n=a(e,t),r=[],s=!1;return o(t,function(t){t.inYRange(n.y)&&r.push(t),t.inRange(n.x,n.y)&&(s=!0)}),i.intersect&&!s&&(r=[]),r}}}},{45:45}],29:[function(t,e,i){"use strict";t(25)._set("global",{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},layout:{padding:{top:0,right:0,bottom:0,left:0}}}),e.exports=function(){var t=function(t,e){return this.construct(t,e),this};return t.Chart=t,t}},{25:25}],30:[function(t,e,i){"use strict";var n=t(45);function a(t,e){return n.where(t,function(t){return t.position===e})}function o(t,e){t.forEach(function(t,e){return t._tmpIndex_=e,t}),t.sort(function(t,i){var n=e?i:t,a=e?t:i;return n.weight===a.weight?n._tmpIndex_-a._tmpIndex_:n.weight-a.weight}),t.forEach(function(t){delete t._tmpIndex_})}e.exports={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,t.boxes.push(e)},removeBox:function(t,e){var i=t.boxes?t.boxes.indexOf(e):-1;-1!==i&&t.boxes.splice(i,1)},configure:function(t,e,i){for(var n,a=["fullWidth","position","weight"],o=a.length,r=0;rh&<.maxHeight){l--;break}l++,c=u*d}t.labelRotation=l},afterCalculateTickRotation:function(){o.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){o.callback(this.options.beforeFit,[this])},fit:function(){var t=this,n=t.minSize={width:0,height:0},a=s(t._ticks),l=t.options,u=l.ticks,d=l.scaleLabel,c=l.gridLines,h=l.display,f=t.isHorizontal(),g=i(u),p=l.gridLines.tickMarkLength;if(n.width=f?t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:h&&c.drawTicks?p:0,n.height=f?h&&c.drawTicks?p:0:t.maxHeight,d.display&&h){var m=r(d)+o.options.toPadding(d.padding).height;f?n.height+=m:n.width+=m}if(u.display&&h){var v=o.longestText(t.ctx,g.font,a,t.longestTextCache),b=o.numberOfLabelLines(a),x=.5*g.size,y=t.options.ticks.padding;if(f){t.longestLabelWidth=v;var k=o.toRadians(t.labelRotation),M=Math.cos(k),w=Math.sin(k)*v+g.size*b+x*(b-1)+x;n.height=Math.min(t.maxHeight,n.height+w+y),t.ctx.font=g.font;var S=e(t.ctx,a[0],g.font),C=e(t.ctx,a[a.length-1],g.font);0!==t.labelRotation?(t.paddingLeft="bottom"===l.position?M*S+3:M*x+3,t.paddingRight="bottom"===l.position?M*x+3:M*C+3):(t.paddingLeft=S/2+3,t.paddingRight=C/2+3)}else u.mirror?v=0:v+=y+x,n.width=Math.min(t.maxWidth,n.width+v),t.paddingTop=g.size/2,t.paddingBottom=g.size/2}t.handleMargins(),t.width=n.width,t.height=n.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){o.callback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(o.isNullOrUndef(t))return NaN;if("number"==typeof t&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},getLabelForIndex:o.noop,getPixelForValue:o.noop,getValueForPixel:o.noop,getPixelForTick:function(t){var e=this,i=e.options.offset;if(e.isHorizontal()){var n=(e.width-(e.paddingLeft+e.paddingRight))/Math.max(e._ticks.length-(i?0:1),1),a=n*t+e.paddingLeft;i&&(a+=n/2);var o=e.left+Math.round(a);return o+=e.isFullWidth()?e.margins.left:0}var r=e.height-(e.paddingTop+e.paddingBottom);return e.top+t*(r/(e._ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var i=(e.width-(e.paddingLeft+e.paddingRight))*t+e.paddingLeft,n=e.left+Math.round(i);return n+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,i,n,a,r=this,s=r.isHorizontal(),l=r.options.ticks.minor,u=t.length,d=o.toRadians(r.labelRotation),c=Math.cos(d),h=r.longestLabelWidth*c,f=[];for(l.maxTicksLimit&&(a=l.maxTicksLimit),s&&(e=!1,(h+l.autoSkipPadding)*u>r.width-(r.paddingLeft+r.paddingRight)&&(e=1+Math.floor((h+l.autoSkipPadding)*u/(r.width-(r.paddingLeft+r.paddingRight)))),a&&u>a&&(e=Math.max(e,Math.floor(u/a)))),i=0;i1&&i%e>0||i%e==0&&i+e>=u)&&i!==u-1&&delete n.label,f.push(n);return f},draw:function(t){var e=this,a=e.options;if(a.display){var s=e.ctx,u=n.global,d=a.ticks.minor,c=a.ticks.major||d,h=a.gridLines,f=a.scaleLabel,g=0!==e.labelRotation,p=e.isHorizontal(),m=d.autoSkip?e._autoSkip(e.getTicks()):e.getTicks(),v=o.valueOrDefault(d.fontColor,u.defaultFontColor),b=i(d),x=o.valueOrDefault(c.fontColor,u.defaultFontColor),y=i(c),k=h.drawTicks?h.tickMarkLength:0,M=o.valueOrDefault(f.fontColor,u.defaultFontColor),w=i(f),S=o.options.toPadding(f.padding),C=o.toRadians(e.labelRotation),_=[],D=e.options.gridLines.lineWidth,I="right"===a.position?e.right:e.right-D-k,P="right"===a.position?e.right+k:e.right,A="bottom"===a.position?e.top+D:e.bottom-k-D,T="bottom"===a.position?e.top+D+k:e.bottom+D;if(o.each(m,function(i,n){if(!o.isNullOrUndef(i.label)){var r,s,c,f,v,b,x,y,M,w,S,F,O,R,L=i.label;n===e.zeroLineIndex&&a.offset===h.offsetGridLines?(r=h.zeroLineWidth,s=h.zeroLineColor,c=h.zeroLineBorderDash,f=h.zeroLineBorderDashOffset):(r=o.valueAtIndexOrDefault(h.lineWidth,n),s=o.valueAtIndexOrDefault(h.color,n),c=o.valueOrDefault(h.borderDash,u.borderDash),f=o.valueOrDefault(h.borderDashOffset,u.borderDashOffset));var z="middle",B="middle",W=d.padding;if(p){var N=k+W;"bottom"===a.position?(B=g?"middle":"top",z=g?"right":"center",R=e.top+N):(B=g?"middle":"bottom",z=g?"left":"center",R=e.bottom-N);var V=l(e,n,h.offsetGridLines&&m.length>1);V1);j3?i[2]-i[1]:i[1]-i[0];Math.abs(a)>1&&t!==Math.floor(t)&&(a=t-Math.floor(t));var o=n.log10(Math.abs(a)),r="";if(0!==t){var s=-1*Math.floor(o);s=Math.max(Math.min(s,20),0),r=t.toFixed(s)}else r="0";return r},logarithmic:function(t,e,i){var a=t/Math.pow(10,Math.floor(n.log10(t)));return 0===t?"0":1===a||2===a||5===a||0===e||e===i.length-1?t.toExponential():""}}}},{45:45}],35:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45);n._set("global",{tooltips:{enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:o.noop,title:function(t,e){var i="",n=e.labels,a=n?n.length:0;if(t.length>0){var o=t[0];o.xLabel?i=o.xLabel:a>0&&o.indexl.height-e.height&&(c="bottom");var h=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===c?(i=function(t){return t<=h},n=function(t){return t>h}):(i=function(t){return t<=e.width/2},n=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},o=function(t){return t-e.width-s.caretSize-s.caretPadding<0},r=function(t){return t<=f?"top":"bottom"},i(s.x)?(d="left",a(s.x)&&(d="center",c=r(s.y))):n(s.x)&&(d="right",o(s.x)&&(d="center",c=r(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:c}}(this,F=function(t,e){var i=t._chart.ctx,n=2*e.yPadding,a=0,r=e.body,s=r.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);s+=e.beforeBody.length+e.afterBody.length;var l=e.title.length,u=e.footer.length,d=e.titleFontSize,c=e.bodyFontSize,h=e.footerFontSize;n+=l*d,n+=l?(l-1)*e.titleSpacing:0,n+=l?e.titleMarginBottom:0,n+=s*c,n+=s?(s-1)*e.bodySpacing:0,n+=u?e.footerMarginTop:0,n+=u*h,n+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){a=Math.max(a,i.measureText(t).width+f)};return i.font=o.fontString(d,e._titleFontStyle,e._titleFontFamily),o.each(e.title,g),i.font=o.fontString(c,e._bodyFontStyle,e._bodyFontFamily),o.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?c+2:0,o.each(r,function(t){o.each(t.before,g),o.each(t.lines,g),o.each(t.after,g)}),f=0,i.font=o.fontString(h,e._footerFontStyle,e._footerFontFamily),o.each(e.footer,g),{width:a+=2*e.xPadding,height:n}}(this,D)),a=D,s=F,l=A,u=S._chart,d=a.x,c=a.y,h=a.caretSize,f=a.caretPadding,g=a.cornerRadius,p=l.xAlign,m=l.yAlign,v=h+f,b=g+f,"right"===p?d-=s.width:"center"===p&&((d-=s.width/2)+s.width>u.width&&(d=u.width-s.width),d<0&&(d=0)),"top"===m?c+=v:c-="bottom"===m?s.height+v:s.height/2,"center"===m?"left"===p?d+=v:"right"===p&&(d-=v):"left"===p?d-=b:"right"===p&&(d+=b),T={x:d,y:c}}else D.opacity=0;return D.xAlign=A.xAlign,D.yAlign=A.yAlign,D.x=T.x,D.y=T.y,D.width=F.width,D.height=F.height,D.caretX=O.x,D.caretY=O.y,S._model=D,e&&C.custom&&C.custom.call(S,D),S},drawCaret:function(t,e){var i=this._chart.ctx,n=this._view,a=this.getCaretPosition(t,e,n);i.lineTo(a.x1,a.y1),i.lineTo(a.x2,a.y2),i.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,i){var n,a,o,r,s,l,u=i.caretSize,d=i.cornerRadius,c=i.xAlign,h=i.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===h)s=g+m/2,"left"===c?(a=(n=f)-u,o=n,r=s+u,l=s-u):(a=(n=f+p)+u,o=n,r=s-u,l=s+u);else if("left"===c?(n=(a=f+d+u)-u,o=a+u):"right"===c?(n=(a=f+p-d-u)-u,o=a+u):(n=(a=i.caretX)-u,o=a+u),"top"===h)s=(r=g)-u,l=r;else{s=(r=g+m)+u,l=r;var v=o;o=n,n=v}return{x1:n,x2:a,x3:o,y1:r,y2:s,y3:l}},drawTitle:function(t,i,n,a){var r=i.title;if(r.length){n.textAlign=i._titleAlign,n.textBaseline="top";var s,l,u=i.titleFontSize,d=i.titleSpacing;for(n.fillStyle=e(i.titleFontColor,a),n.font=o.fontString(u,i._titleFontStyle,i._titleFontFamily),s=0,l=r.length;s0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var i={width:e.width,height:e.height},n={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,o=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&o&&(this.drawBackground(n,e,t,i,a),n.x+=e.xPadding,n.y+=e.yPadding,this.drawTitle(n,e,t,a),this.drawBody(n,e,t,a),this.drawFooter(n,e,t,a))}},handleEvent:function(t){var e,i=this,n=i._options;return i._lastActive=i._lastActive||[],"mouseout"===t.type?i._active=[]:i._active=i._chart.getElementsAtEventForMode(t,n.mode,n),(e=!o.arrayEquals(i._active,i._lastActive))&&(i._lastActive=i._active,(n.enabled||n.custom)&&(i._eventPosition={x:t.x,y:t.y},i.update(!0),i.pivot())),e}}),t.Tooltip.positioners={average:function(t){if(!t.length)return!1;var e,i,n=0,a=0,o=0;for(e=0,i=t.length;el;)a-=2*Math.PI;for(;a=s&&a<=l,d=r>=i.innerRadius&&r<=i.outerRadius;return u&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,i=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,i=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},draw:function(){var t=this._chart.ctx,e=this._view,i=e.startAngle,n=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,i,n),t.arc(e.x,e.y,e.innerRadius,n,i,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})},{25:25,26:26,45:45}],37:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=n.global;n._set("global",{elements:{line:{tension:.4,backgroundColor:r.defaultColor,borderWidth:3,borderColor:r.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}}),e.exports=a.extend({draw:function(){var t,e,i,n,a=this._view,s=this._chart.ctx,l=a.spanGaps,u=this._children.slice(),d=r.elements.line,c=-1;for(this._loop&&u.length&&u.push(u[0]),s.save(),s.lineCap=a.borderCapStyle||d.borderCapStyle,s.setLineDash&&s.setLineDash(a.borderDash||d.borderDash),s.lineDashOffset=a.borderDashOffset||d.borderDashOffset,s.lineJoin=a.borderJoinStyle||d.borderJoinStyle,s.lineWidth=a.borderWidth||d.borderWidth,s.strokeStyle=a.borderColor||r.defaultColor,s.beginPath(),c=-1,t=0;tt?1:-1,o=1,r=l.borderSkipped||"left"):(t=l.x-l.width/2,e=l.x+l.width/2,i=l.y,a=1,o=(n=l.base)>i?1:-1,r=l.borderSkipped||"bottom"),u){var d=Math.min(Math.abs(t-e),Math.abs(i-n)),c=(u=u>d?d:u)/2,h=t+("left"!==r?c*a:0),f=e+("right"!==r?-c*a:0),g=i+("top"!==r?c*o:0),p=n+("bottom"!==r?-c*o:0);h!==f&&(i=g,n=p),g!==p&&(t=h,e=f)}s.beginPath(),s.fillStyle=l.backgroundColor,s.strokeStyle=l.borderColor,s.lineWidth=u;var m=[[t,n],[t,i],[e,i],[e,n]],v=["bottom","left","top","right"].indexOf(r,0);function b(t){return m[(v+t)%4]}-1===v&&(v=0);var x=b(0);s.moveTo(x[0],x[1]);for(var y=1;y<4;y++)x=b(y),s.lineTo(x[0],x[1]);s.fill(),u&&s.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var i=!1;if(this._view){var n=r(this);i=t>=n.left&&t<=n.right&&e>=n.top&&e<=n.bottom}return i},inLabelRange:function(t,e){if(!this._view)return!1;var i=r(this);return o(this)?t>=i.left&&t<=i.right:e>=i.top&&e<=i.bottom},inXRange:function(t){var e=r(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=r(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,e,i=this._view;return o(this)?(t=i.x,e=(i.y+i.base)/2):(t=(i.x+i.base)/2,e=i.y),{x:t,y:e}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})},{25:25,26:26}],40:[function(t,e,i){"use strict";e.exports={},e.exports.Arc=t(36),e.exports.Line=t(37),e.exports.Point=t(38),e.exports.Rectangle=t(39)},{36:36,37:37,38:38,39:39}],41:[function(t,e,i){"use strict";var n=t(42);i=e.exports={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,i,n,a,o){if(o){var r=Math.min(o,n/2),s=Math.min(o,a/2);t.moveTo(e+r,i),t.lineTo(e+n-r,i),t.quadraticCurveTo(e+n,i,e+n,i+s),t.lineTo(e+n,i+a-s),t.quadraticCurveTo(e+n,i+a,e+n-r,i+a),t.lineTo(e+r,i+a),t.quadraticCurveTo(e,i+a,e,i+a-s),t.lineTo(e,i+s),t.quadraticCurveTo(e,i,e+r,i)}else t.rect(e,i,n,a)},drawPoint:function(t,e,i,n,a){var o,r,s,l,u,d;if(!e||"object"!=typeof e||"[object HTMLImageElement]"!==(o=e.toString())&&"[object HTMLCanvasElement]"!==o){if(!(isNaN(i)||i<=0)){switch(e){default:t.beginPath(),t.arc(n,a,i,0,2*Math.PI),t.closePath(),t.fill();break;case"triangle":t.beginPath(),u=(r=3*i/Math.sqrt(3))*Math.sqrt(3)/2,t.moveTo(n-r/2,a+u/3),t.lineTo(n+r/2,a+u/3),t.lineTo(n,a-2*u/3),t.closePath(),t.fill();break;case"rect":d=1/Math.SQRT2*i,t.beginPath(),t.fillRect(n-d,a-d,2*d,2*d),t.strokeRect(n-d,a-d,2*d,2*d);break;case"rectRounded":var c=i/Math.SQRT2,h=n-c,f=a-c,g=Math.SQRT2*i;t.beginPath(),this.roundedRect(t,h,f,g,g,i/2),t.closePath(),t.fill();break;case"rectRot":d=1/Math.SQRT2*i,t.beginPath(),t.moveTo(n-d,a),t.lineTo(n,a+d),t.lineTo(n+d,a),t.lineTo(n,a-d),t.closePath(),t.fill();break;case"cross":t.beginPath(),t.moveTo(n,a+i),t.lineTo(n,a-i),t.moveTo(n-i,a),t.lineTo(n+i,a),t.closePath();break;case"crossRot":t.beginPath(),s=Math.cos(Math.PI/4)*i,l=Math.sin(Math.PI/4)*i,t.moveTo(n-s,a-l),t.lineTo(n+s,a+l),t.moveTo(n-s,a+l),t.lineTo(n+s,a-l),t.closePath();break;case"star":t.beginPath(),t.moveTo(n,a+i),t.lineTo(n,a-i),t.moveTo(n-i,a),t.lineTo(n+i,a),s=Math.cos(Math.PI/4)*i,l=Math.sin(Math.PI/4)*i,t.moveTo(n-s,a-l),t.lineTo(n+s,a+l),t.moveTo(n-s,a+l),t.lineTo(n+s,a-l),t.closePath();break;case"line":t.beginPath(),t.moveTo(n-i,a),t.lineTo(n+i,a),t.closePath();break;case"dash":t.beginPath(),t.moveTo(n,a),t.lineTo(n+i,a),t.closePath()}t.stroke()}}else t.drawImage(e,n-e.width/2,a-e.height/2,e.width,e.height)},clipArea:function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},unclipArea:function(t){t.restore()},lineTo:function(t,e,i,n){if(i.steppedLine)return"after"===i.steppedLine&&!n||"after"!==i.steppedLine&&n?t.lineTo(e.x,i.y):t.lineTo(i.x,e.y),void t.lineTo(i.x,i.y);i.tension?t.bezierCurveTo(n?e.controlPointPreviousX:e.controlPointNextX,n?e.controlPointPreviousY:e.controlPointNextY,n?i.controlPointNextX:i.controlPointPreviousX,n?i.controlPointNextY:i.controlPointPreviousY,i.x,i.y):t.lineTo(i.x,i.y)}};n.clear=i.clear,n.drawRoundedRectangle=function(t){t.beginPath(),i.roundedRect.apply(i,arguments),t.closePath()}},{42:42}],42:[function(t,e,i){"use strict";var n,a={noop:function(){},uid:(n=0,function(){return n++}),isNullOrUndef:function(t){return null==t},isArray:Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},isObject:function(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)},valueOrDefault:function(t,e){return void 0===t?e:t},valueAtIndexOrDefault:function(t,e,i){return a.valueOrDefault(a.isArray(t)?t[e]:t,i)},callback:function(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)},each:function(t,e,i,n){var o,r,s;if(a.isArray(t))if(r=t.length,n)for(o=r-1;o>=0;o--)e.call(i,t[o],o);else for(o=0;o=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:1===t?1:(i||(i=.3),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),-n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i))},easeOutElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:1===t?1:(i||(i=.3),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),n*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/i)+1)},easeInOutElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:2==(t/=.5)?1:(i||(i=.45),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),t<1?n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*-.5:n*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*.5+1)},easeInBack:function(t){return t*t*(2.70158*t-1.70158)},easeOutBack:function(t){return(t-=1)*t*(2.70158*t+1.70158)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-a.easeOutBounce(1-t)},easeOutBounce:function(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},easeInOutBounce:function(t){return t<.5?.5*a.easeInBounce(2*t):.5*a.easeOutBounce(2*t-1)+.5}};e.exports={effects:a},n.easingEffects=a},{42:42}],44:[function(t,e,i){"use strict";var n=t(42);e.exports={toLineHeight:function(t,e){var i=(""+t).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t},toPadding:function(t){var e,i,a,o;return n.isObject(t)?(e=+t.top||0,i=+t.right||0,a=+t.bottom||0,o=+t.left||0):e=i=a=o=+t||0,{top:e,right:i,bottom:a,left:o,height:e+a,width:o+i}},resolve:function(t,e,i){var a,o,r;for(a=0,o=t.length;a