From f3fc531a532ea58493c87ff70391baf3f75cd7f8 Mon Sep 17 00:00:00 2001 From: sinthuja Date: Thu, 17 Nov 2016 22:51:50 +0530 Subject: [PATCH] Adding the new version of android analytics carbon apps. --- .../build.xml | 38 + .../pom.xml | 75 + .../src/assembly/src.xml | 36 + .../Android_Active_Stack_Chart/conf.json | 17 + .../gadget-controller.jag | 42 + .../Android_Active_Stack_Chart/gadget.json | 14 + .../Android_Active_Stack_Chart/gadget.xml | 56 + .../js/core/bar-chart-api.js | 147 + .../js/core/batch-provider-api.js | 195 + .../js/core/gadget-core.js | 85 + .../js/core/gadget-util.js | 35 + .../Android_Active_Stack_Chart/thumbnail.png | Bin 0 -> 10026 bytes .../artifact.xml | 23 + .../Android_Active_Time_Chart/conf.json | 18 + .../gadget-controller.jag | 42 + .../Android_Active_Time_Chart/gadget.json | 9 + .../Android_Active_Time_Chart/gadget.xml | 56 + .../js/core/batch-provider-api.js | 190 + .../js/core/gadget-core.js | 88 + .../js/core/gadget-util.js | 35 + .../js/core/line-chart-api.js | 132 + .../Android_Active_Time_Chart/thumbnail.png | Bin 0 -> 17872 bytes .../artifact.xml | 23 + .../Android_Activity_Chart/conf.json | 15 + .../gadget-controller.jag | 42 + .../Android_Activity_Chart/gadget.json | 9 + .../Android_Activity_Chart/gadget.xml | 56 + .../js/core/batch-provider-api.js | 190 + .../js/core/donut-chart-api.js | 111 + .../js/core/gadget-core.js | 101 + .../js/core/gadget-util.js | 35 + .../Android_Activity_Chart/thumbnail.png | Bin 0 -> 15590 bytes .../artifact.xml | 23 + .../AndroidActivityScript.xml | 30 + .../android_activity_script/artifact.xml | 23 + .../artifact.xml | 23 + .../org_wso2_iot_android_activity_stats.xml | 90 + .../artifact.xml | 23 + ...wso2.iot.android.activity.stats_1.0.0.json | 50 + .../android_activity_streams/artifact.xml | 23 + .../org.wso2.iot.android.activity_1.0.0.json | 26 + ...ndriod-Audio-Filter-ExecutionPlan.siddhiql | 16 + .../artifact.xml | 23 + .../Android-Activity-ExecutionPlan.siddhiql | 22 + .../artifact.xml | 23 + .../Android-Audio-ExecutionPlan.siddhiql | 27 + .../artifact.xml | 23 + .../Android-Call-ExecutionPlan.siddhiql | 17 + .../artifact.xml | 23 + .../Android-Data-ExecutionPlan.siddhiql | 16 + .../artifact.xml | 23 + .../Android-Location-ExecutionPlan.siddhiql | 16 + .../artifact.xml | 23 + .../Android-Screen-ExecutionPlan.siddhiql | 19 + .../artifact.xml | 23 + .../Android-Sense-ExecutionPlan.siddhiql | 63 + .../artifact.xml | 23 + .../Android-SMS-ExecutionPlan.siddhiql | 16 + .../artifact.xml | 23 + .../AndroidAudioScript.xml | 19 + .../android_audio_script/artifact.xml | 23 + .../android_audio_streams/artifact.xml | 23 + .../org.wso2.iot.android.audio_1.0.0.json | 34 + .../Android_Battery_Level_Chart/conf.json | 17 + .../gadget-controller.jag | 42 + .../Android_Battery_Level_Chart/gadget.json | 9 + .../Android_Battery_Level_Chart/gadget.xml | 60 + .../js/core/area-chart-api.js | 135 + .../js/core/gadget-core.js | 64 + .../js/core/gadget-util.js | 35 + .../js/core/provider-client.js | 51 + .../js/core/realtime-provider-api.js | 154 + .../js/provider-libs/ws-client.js | 262 + .../Android_Battery_Level_Chart/thumbnail.png | Bin 0 -> 10532 bytes .../artifact.xml | 23 + .../conf.json | 13 + .../gadget-controller.jag | 42 + .../gadget.json | 9 + .../gadget.xml | 60 + .../js/core/donut-chart-api.js | 115 + .../js/core/gadget-core.js | 69 + .../js/core/gadget-util.js | 35 + .../js/core/provider-client.js | 51 + .../js/core/realtime-provider-api.js | 154 + .../js/provider-libs/ws-client.js | 261 + .../thumbnail.png | Bin 0 -> 15244 bytes .../artifact.xml | 23 + .../android_battery_streams/artifact.xml | 23 + .../org.wso2.iot.android.battery_1.0.0.json | 38 + .../artifact.xml | 23 + ....wso2.iot.android.battery.ui.publisher.xml | 7 + .../android_call_script/AndriodCallScript.xml | 19 + .../android_call_script/artifact.xml | 23 + .../artifact.xml | 23 + .../org_wso2_iot_android_call_stats.xml | 98 + .../android_call_stats_streams/artifact.xml | 23 + ...org.wso2.iot.android.call.stats_1.0.0.json | 54 + .../artifact.xml | 23 + ...o2.iot.android.call.stats.ui.publisher.xml | 7 + .../android_call_streams/artifact.xml | 23 + .../org.wso2.iot.android.call_1.0.0.json | 38 + .../Android_Call_Time_Chart/conf.json | 15 + .../gadget-controller.jag | 42 + .../Android_Call_Time_Chart/gadget.json | 9 + .../Android_Call_Time_Chart/gadget.xml | 56 + .../js/core/batch-provider-api.js | 190 + .../js/core/donut-chart-api.js | 112 + .../js/core/gadget-core.js | 99 + .../js/core/gadget-util.js | 35 + .../Android_Call_Time_Chart/thumbnail.png | Bin 0 -> 13565 bytes .../artifact.xml | 23 + .../artifact.xml | 23 + ...org.wso2.iot.android.call.ui.publisher.xml | 7 + .../android_commons_gadget/artifact.xml | 23 + .../commons/css/application.css | 3 + .../commons/css/autocomplete.css | 34 + .../commons/css/bootstrap.css | 6 + .../commons/css/dataTables.bootstrap.css | 372 + .../commons/css/daterangepicker.css | 375 + .../commons/css/font-awesome.css | 2086 ++ .../commons/css/font-awesome.min.css | 4 + .../commons/css/gadget.css | 226 + .../commons/css/jquery.dataTables.min.css | 1 + .../commons/css/nanoscroller.css | 55 + .../commons/fonts/FontAwesome.otf | Bin 0 -> 109688 bytes .../commons/fonts/fontawesome-webfont.eot | Bin 0 -> 70807 bytes .../commons/fonts/fontawesome-webfont.svg | 655 + .../commons/fonts/fontawesome-webfont.ttf | Bin 0 -> 142072 bytes .../commons/fonts/fontawesome-webfont.woff | Bin 0 -> 83588 bytes .../commons/fonts/fontawesome-webfont.woff2 | Bin 0 -> 66624 bytes .../commons/js/VizGrammar.js | 2770 ++ .../commons/js/VizGrammar.min.js | 17 + .../commons/js/VizGrammar2.min.js | 17 + .../commons/js/carbon-analytics.js | 881 + .../commons/js/d3.min.js | 5 + .../commons/js/dagre-d3.js | 17572 +++++++++++++ .../commons/js/dataTables.bootstrap.js | 206 + .../commons/js/daterangepicker.js | 1526 ++ .../commons/js/gadget-utils.js | 245 + .../commons/js/jquery-1.10.2.js | 9789 +++++++ .../commons/js/jquery.autocomplete.min.js | 8 + .../commons/js/jquery.dataTables.min.js | 166 + .../commons/js/jquery.nanoscroller.min.js | 4 + .../commons/js/moment.min.js | 7 + .../commons/js/topojson.js | 534 + .../commons/js/typeahead.bundle.js | 2451 ++ .../commons/js/utils.js | 26 + .../android_commons_gadget/commons/js/vega.js | 21813 ++++++++++++++++ .../android_data_script/AndriodDataScript.xml | 19 + .../android_data_script/artifact.xml | 23 + .../artifact.xml | 23 + .../org_wso2_iot_android_data_stats.xml | 90 + .../android_data_stats_streams/artifact.xml | 23 + ...org.wso2.iot.android.data.stats_1.0.0.json | 50 + .../android_data_streams/artifact.xml | 23 + .../org.wso2.iot.android.data_1.0.0.json | 34 + .../artifact.xml | 23 + ...org.wso2.iot.android.data.ui.publisher.xml | 7 + .../Android_Data_Usage_Chart/conf.json | 1 + .../gadget-controller.jag | 42 + .../Android_Data_Usage_Chart/gadget.json | 9 + .../Android_Data_Usage_Chart/gadget.xml | 56 + .../js/core/batch-provider-api.js | 190 + .../js/core/donut-chart-api.js | 114 + .../js/core/gadget-core.js | 95 + .../js/core/gadget-util.js | 35 + .../Android_Data_Usage_Chart/thumbnail.png | Bin 0 -> 11569 bytes .../artifact.xml | 23 + .../android_date_picker_gadget/artifact.xml | 23 + .../css/bootstrap-datepicker.min.css | 8 + .../date-picker/css/jquery-ui.css | 1225 + .../date-picker/gadget.json | 24 + .../date-picker/index.png | Bin 0 -> 12971 bytes .../date-picker/index.xml | 41 + .../js/bootstrap-datepicker.min.js | 8 + .../date-picker/js/jquery-ui.js | 16617 ++++++++++++ .../artifact.xml | 23 + .../date-picker-widget/gadget.json | 22 + .../date-picker-widget/index.png | Bin 0 -> 41250 bytes .../date-picker-widget/index.xml | 57 + .../artifact.xml | 23 + .../css/bootstrap-datepicker.min.css | 8 + .../css/daterangepicker-bs3.css | 284 + .../date-range-picker/css/jquery-ui.css | 1225 + .../date-range-picker/gadget.json | 20 + .../date-range-picker/index.png | Bin 0 -> 39609 bytes .../date-range-picker/index.xml | 66 + .../js/bootstrap-datepicker.min.js | 8 + .../date-range-picker/js/daterangepicker.js | 1109 + .../date-range-picker/js/jquery-ui.js | 16617 ++++++++++++ .../date-range-picker/js/moment.js | 2808 ++ .../Android_Details/conf.json | 15 + .../Android_Details/css/devicetable.css | 6 + .../Android_Details/gadget-controller.jag | 42 + .../Android_Details/gadget.json | 15 + .../Android_Details/gadget.xml | 60 + .../js/core/batch-provider-api.js | 189 + .../Android_Details/js/core/gadget-core.js | 119 + .../Android_Details/js/core/gadget-util.js | 35 + .../Android_Details/thumbnail.png | Bin 0 -> 7108 bytes .../android_details_gadget/artifact.xml | 23 + .../artifact.xml | 23 + .../org_wso2_iot_andriod_device_details.xml | 90 + .../artifact.xml | 23 + ...wso2.iot.andriod.device.details_1.0.0.json | 50 + .../artifact.xml | 23 + .../device-grouping/css/bootstrap.min.css | 5 + .../device-grouping/css/style.css | 38 + .../device-grouping/gadget.json | 21 + .../device-grouping/img/thumbnail.png | Bin 0 -> 12971 bytes .../device-grouping/index.xml | 88 + .../device-grouping/js/VizGrammar.min.js | 19 + .../device-grouping/js/VizGrammarSettings.js | 3 + .../device-grouping/js/analyticsUtils.js | 124 + .../device-grouping/js/d3.min.js | 5 + .../device-grouping/js/gadgetconf.js | 26 + .../device-grouping/js/jquery.js | 9789 +++++++ .../device-grouping/js/main.js | 337 + .../device-grouping/js/topojson.js | 534 + .../device-grouping/js/vega.js | 21813 ++++++++++++++++ .../css/autocomplete.css | 69 + .../Android_Device_SearchBox/gadget.json | 20 + .../Android_Device_SearchBox/index.xml | 43 + .../js/gadget-utils.js | 232 + .../Android_Device_SearchBox/js/gadgetconf.js | 3 + .../Android_Device_SearchBox/js/main.js | 73 + .../js/typeahead.bundle.js | 2451 ++ .../artifact.xml | 23 + .../artifact.xml | 23 + ...wso2.iot.andriod.filtered.audio_1.0.0.json | 34 + .../artifact.xml | 23 + ...ot.android.filtered.audio.ui.publisher.xml | 7 + .../android_filtered_by_gadget/artifact.xml | 23 + .../filtered-by/css/bootstrap.min.css | 5 + .../filtered-by/css/font-wso2.min.css | 1 + .../filtered-by/css/style.css | 77 + .../filtered-by/fonts/font-wso2.eot | Bin 0 -> 45956 bytes .../filtered-by/fonts/font-wso2.svg | 1462 ++ .../filtered-by/fonts/font-wso2.ttf | Bin 0 -> 45780 bytes .../filtered-by/fonts/font-wso2.woff | Bin 0 -> 87880 bytes .../filtered-by/fonts/font-wso2.woff2 | Bin 0 -> 23408 bytes .../filtered-by/gadget.json | 21 + .../filtered-by/img/thumbnail.png | Bin 0 -> 12971 bytes .../filtered-by/index.xml | 81 + .../filtered-by/js/VizGrammar.min.js | 19 + .../filtered-by/js/VizGrammarSettings.js | 3 + .../filtered-by/js/analyticsUtils.js | 109 + .../filtered-by/js/d3.min.js | 5 + .../filtered-by/js/gadgetconf.js | 26 + .../filtered-by/js/jquery.js | 9789 +++++++ .../filtered-by/js/main.js | 239 + .../filtered-by/js/mustache.min.js | 1 + .../filtered-by/js/topojson.js | 534 + .../filtered-by/js/vega.js | 20654 +++++++++++++++ .../Android_Frequent_Contacts_List/conf.json | 16 + .../css/dataTables.bootstrap.min.css | 1 + .../gadget-controller.jag | 42 + .../gadget.json | 9 + .../Android_Frequent_Contacts_List/gadget.xml | 62 + .../js/core/batch-provider-api.js | 190 + .../js/core/gadget-core.js | 85 + .../js/core/gadget-util.js | 35 + .../js/core/table-chart-api.js | 182 + .../js/jquery.dataTables.min.js | 164 + .../thumbnail.png | Bin 0 -> 7475 bytes .../artifact.xml | 23 + .../AndriodFrequentContactsScript.xml | 53 + .../artifact.xml | 23 + .../artifact.xml | 23 + .../org_wso2_iot_android_headset_stats.xml | 82 + .../artifact.xml | 23 + ....wso2.iot.android.headset.stats_1.0.0.json | 46 + .../Android_Headset_Usage_Chart/conf.json | 15 + .../gadget-controller.jag | 42 + .../Android_Headset_Usage_Chart/gadget.json | 9 + .../Android_Headset_Usage_Chart/gadget.xml | 57 + .../js/core/batch-provider-api.js | 191 + .../js/core/donut-chart-api.js | 113 + .../js/core/gadget-core.js | 100 + .../js/core/gadget-util.js | 35 + .../Android_Headset_Usage_Chart/thumbnail.png | Bin 0 -> 11861 bytes .../artifact.xml | 23 + .../android_location_event_sink/artifact.xml | 23 + .../org_wso2_iot_android_location.xml | 50 + .../Android_Location_Map/conf.json | 13 + .../Android_Location_Map/css/map-style.css | 37 + .../Android_Location_Map/css/number-chart.css | 35 + .../Android_Location_Map/data/demo-tracks.js | 10135 +++++++ .../gadget-controller.jag | 42 + .../Android_Location_Map/gadget.json | 9 + .../Android_Location_Map/gadget.xml | 91 + .../img/marker/marker-icon-2x.png | Bin 0 -> 1747 bytes .../img/marker/marker-icon.png | Bin 0 -> 1747 bytes .../img/marker/marker-shadow.png | Bin 0 -> 797 bytes .../js/LeafletPlayback.min.js | 1 + .../Android_Location_Map/js/android-geo.js | 153 + .../js/angular-leaflet-directive.min.js | 40 + .../js/core/_number-chart-api.js | 80 + .../js/core/batch-provider-api.js | 190 + .../js/core/gadget-core.js | 123 + .../js/core/gadget-util.js | 35 + .../js/core/provider-client.js | 51 + .../js/core/realtime-provider-api.js | 154 + .../Android_Location_Map/js/leaflet-heat.js | 11 + .../js/provider-libs/ws-client.js | 263 + .../Android_Location_Map/thumbnail.png | Bin 0 -> 12784 bytes .../android_location_map_gadget/artifact.xml | 23 + .../LocationScript.xml | 43 + .../android_location_script/artifact.xml | 23 + .../artifact.xml | 23 + .../org_wso2_iot_android_location_stats.xml | 98 + .../artifact.xml | 23 + ...wso2.iot.android.location.stats_1.0.0.json | 54 + .../android_location_streams/artifact.xml | 23 + .../org.wso2.iot.android.location_1.0.0.json | 30 + .../artifact.xml | 23 + ...wso2.iot.android.location.ui.publisher.xml | 7 + .../artifact.xml | 23 + .../css/bootstrap.min.css | 9 + .../non-compliant-features/css/style.css | 156 + .../non-compliant-features/gadget.json | 21 + .../non-compliant-features/img/thumbnail.png | Bin 0 -> 12971 bytes .../non-compliant-features/index.xml | 102 + .../js/VizGrammar.min.js | 17 + .../js/VizGrammarSettings.js | 3 + .../js/analyticsUtils.js | 106 + .../js/bootstrap-paginator.min.js | 1 + .../non-compliant-features/js/d3.min.js | 5 + .../non-compliant-features/js/gadgetconf.js | 25 + .../non-compliant-features/js/jquery.js | 9789 +++++++ .../non-compliant-features/js/main.js | 225 + .../non-compliant-features/js/topojson.js | 534 + .../non-compliant-features/js/vega.js | 20654 +++++++++++++++ .../Android_Realtime_Audio/conf.json | 14 + .../css/dataTables.bootstrap.min.css | 1 + .../gadget-controller.jag | 42 + .../Android_Realtime_Audio/gadget.json | 9 + .../Android_Realtime_Audio/gadget.xml | 68 + .../js/core/gadget-core.js | 64 + .../js/core/gadget-util.js | 35 + .../js/core/provider-client.js | 51 + .../js/core/realtime-provider-api.js | 154 + .../js/core/table-chart-api.js | 146 + .../js/jquery.dataTables.min.js | 164 + .../js/provider-libs/ws-client.js | 262 + .../Android_Realtime_Audio/thumbnail.png | Bin 0 -> 12971 bytes .../artifact.xml | 23 + .../Android_Realtime_Battery/conf.json | 14 + .../css/dataTables.bootstrap.min.css | 1 + .../gadget-controller.jag | 42 + .../Android_Realtime_Battery/gadget.json | 9 + .../Android_Realtime_Battery/gadget.xml | 66 + .../js/core/gadget-core.js | 62 + .../js/core/gadget-util.js | 35 + .../js/core/provider-client.js | 51 + .../js/core/realtime-provider-api.js | 154 + .../js/core/table-chart-api.js | 152 + .../js/jquery.dataTables.min.js | 164 + .../js/provider-libs/ws-client.js | 262 + .../Android_Realtime_Battery/thumbnail.png | Bin 0 -> 12971 bytes .../artifact.xml | 23 + .../Android_Realtime_Call/conf.json | 14 + .../css/dataTables.bootstrap.min.css | 1 + .../gadget-controller.jag | 42 + .../Android_Realtime_Call/gadget.json | 9 + .../Android_Realtime_Call/gadget.xml | 68 + .../js/core/gadget-core.js | 64 + .../js/core/gadget-util.js | 35 + .../js/core/provider-client.js | 51 + .../js/core/realtime-provider-api.js | 154 + .../js/core/table-chart-api.js | 149 + .../js/jquery.dataTables.min.js | 164 + .../js/provider-libs/ws-client.js | 262 + .../Android_Realtime_Call/thumbnail.png | Bin 0 -> 12971 bytes .../android_realtime_call_gadget/artifact.xml | 23 + .../Android_Realtime_Data/conf.json | 1 + .../css/dataTables.bootstrap.min.css | 1 + .../gadget-controller.jag | 42 + .../Android_Realtime_Data/gadget.json | 9 + .../Android_Realtime_Data/gadget.xml | 66 + .../js/core/gadget-core.js | 64 + .../js/core/gadget-util.js | 35 + .../js/core/provider-client.js | 51 + .../js/core/realtime-provider-api.js | 154 + .../js/core/table-chart-api.js | 150 + .../js/jquery.dataTables.min.js | 164 + .../js/provider-libs/ws-client.js | 262 + .../Android_Realtime_Data/thumbnail.png | Bin 0 -> 12971 bytes .../android_realtime_data_gadget/artifact.xml | 23 + .../Android_Realtime_Screen/conf.json | 14 + .../css/dataTables.bootstrap.min.css | 1 + .../gadget-controller.jag | 42 + .../Android_Realtime_Screen/gadget.json | 9 + .../Android_Realtime_Screen/gadget.xml | 66 + .../js/core/gadget-core.js | 62 + .../js/core/gadget-util.js | 35 + .../js/core/provider-client.js | 51 + .../js/core/realtime-provider-api.js | 154 + .../js/core/table-chart-api.js | 148 + .../js/jquery.dataTables.min.js | 164 + .../js/provider-libs/ws-client.js | 262 + .../Android_Realtime_Screen/thumbnail.png | Bin 0 -> 12971 bytes .../artifact.xml | 23 + .../Android_Realtime_SMS/conf.json | 14 + .../css/dataTables.bootstrap.min.css | 1 + .../gadget-controller.jag | 42 + .../Android_Realtime_SMS/gadget.json | 9 + .../Android_Realtime_SMS/gadget.xml | 68 + .../js/core/gadget-core.js | 64 + .../js/core/gadget-util.js | 35 + .../js/core/provider-client.js | 51 + .../js/core/realtime-provider-api.js | 154 + .../js/core/table-chart-api.js | 153 + .../js/jquery.dataTables.min.js | 164 + .../js/provider-libs/ws-client.js | 263 + .../Android_Realtime_SMS/thumbnail.png | Bin 0 -> 12971 bytes .../android_realtime_sms_gadget/artifact.xml | 23 + .../Android_Screen_On_Chart/conf.json | 15 + .../gadget-controller.jag | 42 + .../Android_Screen_On_Chart/gadget.json | 9 + .../Android_Screen_On_Chart/gadget.xml | 57 + .../js/core/batch-provider-api.js | 191 + .../js/core/donut-chart-api.js | 111 + .../js/core/gadget-core.js | 98 + .../js/core/gadget-util.js | 35 + .../Android_Screen_On_Chart/thumbnail.png | Bin 0 -> 16961 bytes .../artifact.xml | 23 + .../AndriodScreenScript.xml | 19 + .../android_screen_script/artifact.xml | 23 + .../artifact.xml | 23 + .../org_wso2_iot_android_screen_stats.xml | 82 + .../android_screen_stats_streams/artifact.xml | 23 + ...g.wso2.iot.android.screen.stats_1.0.0.json | 46 + .../android_screen_streams/artifact.xml | 23 + .../org.wso2.iot.android.screen_1.0.0.json | 26 + .../artifact.xml | 23 + ...g.wso2.iot.android.screen.ui.publisher.xml | 7 + .../android_sense_dashboard/android-iot.json | 1253 + .../android_sense_dashboard/artifact.xml | 22 + .../Android_Sense_Script.xml | 20 + .../android_sense_script/artifact.xml | 23 + .../android_sense_streams/artifact.xml | 23 + .../org.wso2.iot.android.sense_1.0.0.json | 63 + .../Android_SMS_Chart/conf.json | 15 + .../Android_SMS_Chart/gadget-controller.jag | 42 + .../Android_SMS_Chart/gadget.json | 9 + .../Android_SMS_Chart/gadget.xml | 56 + .../js/core/batch-provider-api.js | 190 + .../js/core/donut-chart-api.js | 112 + .../Android_SMS_Chart/js/core/gadget-core.js | 95 + .../Android_SMS_Chart/js/core/gadget-util.js | 35 + .../Android_SMS_Chart/thumbnail.png | Bin 0 -> 10573 bytes .../android_sms_chart_gadget/artifact.xml | 23 + .../android_sms_script/AndriodSmsScript.xml | 19 + .../android_sms_script/artifact.xml | 23 + .../android_sms_stats_event_sink/artifact.xml | 23 + .../org_wso2_iot_android_sms_stats.xml | 90 + .../android_sms_stats_streams/artifact.xml | 23 + .../org.wso2.iot.android.sms.stats_1.0.0.json | 50 + .../android_sms_streams/artifact.xml | 23 + .../org.wso2.iot.android.sms_1.0.0.json | 34 + .../artifact.xml | 23 + .../org.wso2.iot.android.sms.ui.publisher.xml | 7 + .../artifact.xml | 23 + .../un-secured-devices/css/bootstrap.min.css | 9 + .../un-secured-devices/css/style.css | 128 + .../un-secured-devices/gadget.json | 21 + .../un-secured-devices/img/phone.png | Bin 0 -> 3915 bytes .../un-secured-devices/img/thumbnail.png | Bin 0 -> 12971 bytes .../un-secured-devices/index.xml | 94 + .../un-secured-devices/js/VizGrammar.min.js | 17 + .../js/VizGrammarSettings.js | 3 + .../un-secured-devices/js/analyticsUtils.js | 106 + .../js/bootstrap-paginator.min.js | 1 + .../un-secured-devices/js/d3.min.js | 5 + .../un-secured-devices/js/gadgetconf.js | 25 + .../un-secured-devices/js/jquery.js | 9789 +++++++ .../un-secured-devices/js/main.js | 117 + .../un-secured-devices/js/topojson.js | 534 + .../un-secured-devices/js/vega.js | 20654 +++++++++++++++ .../android_analytics/artifacts.xml | 169 + 481 files changed, 264284 insertions(+) create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/build.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/pom.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/assembly/src.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/bar-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/batch-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/batch-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/line-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/batch-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/donut-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_script/AndroidActivityScript.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_script/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_event_sink/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_event_sink/org_wso2_iot_android_activity_stats.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_streams/org.wso2.iot.android.activity.stats_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_streams/org.wso2.iot.android.activity_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_andriod_audio_filter_executionplan/Andriod-Audio-Filter-ExecutionPlan.siddhiql create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_andriod_audio_filter_executionplan/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_activity_executionplan/Android-Activity-ExecutionPlan.siddhiql create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_activity_executionplan/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_audio_executionplan/Android-Audio-ExecutionPlan.siddhiql create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_audio_executionplan/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_call_executionplan/Android-Call-ExecutionPlan.siddhiql create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_call_executionplan/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_data_executionplan/Android-Data-ExecutionPlan.siddhiql create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_data_executionplan/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_location_executionplan/Android-Location-ExecutionPlan.siddhiql create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_location_executionplan/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_screen_executionplan/Android-Screen-ExecutionPlan.siddhiql create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_screen_executionplan/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sense_executionplan/Android-Sense-ExecutionPlan.siddhiql create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sense_executionplan/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sms_executionplan/Android-SMS-ExecutionPlan.siddhiql create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sms_executionplan/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_script/AndroidAudioScript.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_script/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_streams/org.wso2.iot.android.audio_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/area-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/provider-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/realtime-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/provider-libs/ws-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/donut-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/provider-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/realtime-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/provider-libs/ws-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_streams/org.wso2.iot.android.battery_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_ui_event_publisher/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_ui_event_publisher/org.wso2.iot.android.battery.ui.publisher.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_script/AndriodCallScript.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_script/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_event_sink/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_event_sink/org_wso2_iot_android_call_stats.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_streams/org.wso2.iot.android.call.stats_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_ui_event_publisher/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_ui_event_publisher/org.wso2.iot.android.call.stats.ui.publisher.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_streams/org.wso2.iot.android.call_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/batch-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/donut-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_ui_event_publisher/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_ui_event_publisher/org.wso2.iot.android.call.ui.publisher.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/application.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/autocomplete.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/bootstrap.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/dataTables.bootstrap.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/daterangepicker.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/font-awesome.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/font-awesome.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/gadget.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/jquery.dataTables.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/nanoscroller.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/fonts/FontAwesome.otf create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/fonts/fontawesome-webfont.eot create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/fonts/fontawesome-webfont.svg create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/fonts/fontawesome-webfont.ttf create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/fonts/fontawesome-webfont.woff create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/fonts/fontawesome-webfont.woff2 create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/VizGrammar.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/VizGrammar.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/VizGrammar2.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/carbon-analytics.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/d3.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/dagre-d3.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/dataTables.bootstrap.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/daterangepicker.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/gadget-utils.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/jquery-1.10.2.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/jquery.autocomplete.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/jquery.dataTables.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/jquery.nanoscroller.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/moment.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/topojson.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/typeahead.bundle.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/utils.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/vega.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_script/AndriodDataScript.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_script/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_event_sink/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_event_sink/org_wso2_iot_android_data_stats.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_streams/org.wso2.iot.android.data.stats_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_streams/org.wso2.iot.android.data_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_ui_event_publisher/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_ui_event_publisher/org.wso2.iot.android.data.ui.publisher.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/batch-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/donut-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/css/bootstrap-datepicker.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/css/jquery-ui.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/index.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/index.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/js/bootstrap-datepicker.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/js/jquery-ui.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_widget_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_widget_gadget/date-picker-widget/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_widget_gadget/date-picker-widget/index.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_widget_gadget/date-picker-widget/index.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_range_picker_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_range_picker_gadget/date-range-picker/css/bootstrap-datepicker.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_range_picker_gadget/date-range-picker/css/daterangepicker-bs3.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_range_picker_gadget/date-range-picker/css/jquery-ui.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_range_picker_gadget/date-range-picker/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_range_picker_gadget/date-range-picker/index.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_range_picker_gadget/date-range-picker/index.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_range_picker_gadget/date-range-picker/js/bootstrap-datepicker.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_range_picker_gadget/date-range-picker/js/daterangepicker.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_range_picker_gadget/date-range-picker/js/jquery-ui.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_range_picker_gadget/date-range-picker/js/moment.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_details_gadget/Android_Details/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_details_gadget/Android_Details/css/devicetable.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_details_gadget/Android_Details/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_details_gadget/Android_Details/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_details_gadget/Android_Details/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_details_gadget/Android_Details/js/core/batch-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_details_gadget/Android_Details/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_details_gadget/Android_Details/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_details_gadget/Android_Details/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_details_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_details_event_sink/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_details_event_sink/org_wso2_iot_andriod_device_details.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_details_streams/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_details_streams/org.wso2.iot.andriod.device.details_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/css/bootstrap.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/css/style.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/img/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/index.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/js/VizGrammar.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/js/VizGrammarSettings.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/js/analyticsUtils.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/js/d3.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/js/gadgetconf.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/js/jquery.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/js/main.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/js/topojson.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_grouping_gadget/device-grouping/js/vega.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_searchbox_gadget/Android_Device_SearchBox/css/autocomplete.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_searchbox_gadget/Android_Device_SearchBox/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_searchbox_gadget/Android_Device_SearchBox/index.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_searchbox_gadget/Android_Device_SearchBox/js/gadget-utils.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_searchbox_gadget/Android_Device_SearchBox/js/gadgetconf.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_searchbox_gadget/Android_Device_SearchBox/js/main.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_searchbox_gadget/Android_Device_SearchBox/js/typeahead.bundle.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_device_searchbox_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_audio_streams/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_audio_streams/org.wso2.iot.andriod.filtered.audio_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_audio_ui_event_publisher/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_audio_ui_event_publisher/org.wso2.iot.android.filtered.audio.ui.publisher.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/css/bootstrap.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/css/font-wso2.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/css/style.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/fonts/font-wso2.eot create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/fonts/font-wso2.svg create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/fonts/font-wso2.ttf create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/fonts/font-wso2.woff create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/fonts/font-wso2.woff2 create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/img/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/index.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/js/VizGrammar.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/js/VizGrammarSettings.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/js/analyticsUtils.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/js/d3.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/js/gadgetconf.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/js/jquery.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/js/main.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/js/mustache.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/js/topojson.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_filtered_by_gadget/filtered-by/js/vega.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequent_contacts_list_gadget/Android_Frequent_Contacts_List/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequent_contacts_list_gadget/Android_Frequent_Contacts_List/css/dataTables.bootstrap.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequent_contacts_list_gadget/Android_Frequent_Contacts_List/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequent_contacts_list_gadget/Android_Frequent_Contacts_List/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequent_contacts_list_gadget/Android_Frequent_Contacts_List/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequent_contacts_list_gadget/Android_Frequent_Contacts_List/js/core/batch-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequent_contacts_list_gadget/Android_Frequent_Contacts_List/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequent_contacts_list_gadget/Android_Frequent_Contacts_List/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequent_contacts_list_gadget/Android_Frequent_Contacts_List/js/core/table-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequent_contacts_list_gadget/Android_Frequent_Contacts_List/js/jquery.dataTables.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequent_contacts_list_gadget/Android_Frequent_Contacts_List/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequent_contacts_list_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequentcontacts_script/AndriodFrequentContactsScript.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_frequentcontacts_script/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_stats_event_sink/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_stats_event_sink/org_wso2_iot_android_headset_stats.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_stats_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_stats_streams/org.wso2.iot.android.headset.stats_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_usage_chart_gadget/Android_Headset_Usage_Chart/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_usage_chart_gadget/Android_Headset_Usage_Chart/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_usage_chart_gadget/Android_Headset_Usage_Chart/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_usage_chart_gadget/Android_Headset_Usage_Chart/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_usage_chart_gadget/Android_Headset_Usage_Chart/js/core/batch-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_usage_chart_gadget/Android_Headset_Usage_Chart/js/core/donut-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_usage_chart_gadget/Android_Headset_Usage_Chart/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_usage_chart_gadget/Android_Headset_Usage_Chart/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_usage_chart_gadget/Android_Headset_Usage_Chart/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_headset_usage_chart_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_event_sink/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_event_sink/org_wso2_iot_android_location.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/css/map-style.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/css/number-chart.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/data/demo-tracks.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/img/marker/marker-icon-2x.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/img/marker/marker-icon.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/img/marker/marker-shadow.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/js/LeafletPlayback.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/js/android-geo.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/js/angular-leaflet-directive.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/js/core/_number-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/js/core/batch-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/js/core/provider-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/js/core/realtime-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/js/leaflet-heat.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/js/provider-libs/ws-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/Android_Location_Map/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_map_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_script/LocationScript.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_script/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_stats_event_sink/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_stats_event_sink/org_wso2_iot_android_location_stats.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_stats_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_stats_streams/org.wso2.iot.android.location.stats_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_streams/org.wso2.iot.android.location_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_ui_event_publisher/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_location_ui_event_publisher/org.wso2.iot.android.location.ui.publisher.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/css/bootstrap.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/css/style.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/img/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/index.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/js/VizGrammar.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/js/VizGrammarSettings.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/js/analyticsUtils.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/js/bootstrap-paginator.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/js/d3.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/js/gadgetconf.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/js/jquery.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/js/main.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/js/topojson.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_non_compliant_features_gadget/non-compliant-features/js/vega.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/Android_Realtime_Audio/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/Android_Realtime_Audio/css/dataTables.bootstrap.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/Android_Realtime_Audio/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/Android_Realtime_Audio/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/Android_Realtime_Audio/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/Android_Realtime_Audio/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/Android_Realtime_Audio/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/Android_Realtime_Audio/js/core/provider-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/Android_Realtime_Audio/js/core/realtime-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/Android_Realtime_Audio/js/core/table-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/Android_Realtime_Audio/js/jquery.dataTables.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/Android_Realtime_Audio/js/provider-libs/ws-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/Android_Realtime_Audio/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_audio_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/Android_Realtime_Battery/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/Android_Realtime_Battery/css/dataTables.bootstrap.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/Android_Realtime_Battery/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/Android_Realtime_Battery/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/Android_Realtime_Battery/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/Android_Realtime_Battery/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/Android_Realtime_Battery/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/Android_Realtime_Battery/js/core/provider-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/Android_Realtime_Battery/js/core/realtime-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/Android_Realtime_Battery/js/core/table-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/Android_Realtime_Battery/js/jquery.dataTables.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/Android_Realtime_Battery/js/provider-libs/ws-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/Android_Realtime_Battery/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_battery_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/Android_Realtime_Call/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/Android_Realtime_Call/css/dataTables.bootstrap.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/Android_Realtime_Call/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/Android_Realtime_Call/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/Android_Realtime_Call/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/Android_Realtime_Call/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/Android_Realtime_Call/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/Android_Realtime_Call/js/core/provider-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/Android_Realtime_Call/js/core/realtime-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/Android_Realtime_Call/js/core/table-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/Android_Realtime_Call/js/jquery.dataTables.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/Android_Realtime_Call/js/provider-libs/ws-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/Android_Realtime_Call/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_call_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/Android_Realtime_Data/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/Android_Realtime_Data/css/dataTables.bootstrap.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/Android_Realtime_Data/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/Android_Realtime_Data/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/Android_Realtime_Data/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/Android_Realtime_Data/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/Android_Realtime_Data/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/Android_Realtime_Data/js/core/provider-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/Android_Realtime_Data/js/core/realtime-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/Android_Realtime_Data/js/core/table-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/Android_Realtime_Data/js/jquery.dataTables.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/Android_Realtime_Data/js/provider-libs/ws-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/Android_Realtime_Data/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_data_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/Android_Realtime_Screen/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/Android_Realtime_Screen/css/dataTables.bootstrap.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/Android_Realtime_Screen/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/Android_Realtime_Screen/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/Android_Realtime_Screen/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/Android_Realtime_Screen/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/Android_Realtime_Screen/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/Android_Realtime_Screen/js/core/provider-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/Android_Realtime_Screen/js/core/realtime-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/Android_Realtime_Screen/js/core/table-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/Android_Realtime_Screen/js/jquery.dataTables.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/Android_Realtime_Screen/js/provider-libs/ws-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/Android_Realtime_Screen/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_screen_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/Android_Realtime_SMS/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/Android_Realtime_SMS/css/dataTables.bootstrap.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/Android_Realtime_SMS/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/Android_Realtime_SMS/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/Android_Realtime_SMS/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/Android_Realtime_SMS/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/Android_Realtime_SMS/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/Android_Realtime_SMS/js/core/provider-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/Android_Realtime_SMS/js/core/realtime-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/Android_Realtime_SMS/js/core/table-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/Android_Realtime_SMS/js/jquery.dataTables.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/Android_Realtime_SMS/js/provider-libs/ws-client.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/Android_Realtime_SMS/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_realtime_sms_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_on_chart_gadget/Android_Screen_On_Chart/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_on_chart_gadget/Android_Screen_On_Chart/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_on_chart_gadget/Android_Screen_On_Chart/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_on_chart_gadget/Android_Screen_On_Chart/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_on_chart_gadget/Android_Screen_On_Chart/js/core/batch-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_on_chart_gadget/Android_Screen_On_Chart/js/core/donut-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_on_chart_gadget/Android_Screen_On_Chart/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_on_chart_gadget/Android_Screen_On_Chart/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_on_chart_gadget/Android_Screen_On_Chart/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_on_chart_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_script/AndriodScreenScript.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_script/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_stats_event_sink/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_stats_event_sink/org_wso2_iot_android_screen_stats.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_stats_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_stats_streams/org.wso2.iot.android.screen.stats_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_streams/org.wso2.iot.android.screen_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_ui_event_publisher/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_screen_ui_event_publisher/org.wso2.iot.android.screen.ui.publisher.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sense_dashboard/android-iot.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sense_dashboard/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sense_script/Android_Sense_Script.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sense_script/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sense_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sense_streams/org.wso2.iot.android.sense_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_chart_gadget/Android_SMS_Chart/conf.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_chart_gadget/Android_SMS_Chart/gadget-controller.jag create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_chart_gadget/Android_SMS_Chart/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_chart_gadget/Android_SMS_Chart/gadget.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_chart_gadget/Android_SMS_Chart/js/core/batch-provider-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_chart_gadget/Android_SMS_Chart/js/core/donut-chart-api.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_chart_gadget/Android_SMS_Chart/js/core/gadget-core.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_chart_gadget/Android_SMS_Chart/js/core/gadget-util.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_chart_gadget/Android_SMS_Chart/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_chart_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_script/AndriodSmsScript.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_script/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_stats_event_sink/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_stats_event_sink/org_wso2_iot_android_sms_stats.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_stats_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_stats_streams/org.wso2.iot.android.sms.stats_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_streams/artifact.xml create mode 100755 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_streams/org.wso2.iot.android.sms_1.0.0.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_ui_event_publisher/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_sms_ui_event_publisher/org.wso2.iot.android.sms.ui.publisher.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/artifact.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/css/bootstrap.min.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/css/style.css create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/gadget.json create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/img/phone.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/img/thumbnail.png create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/index.xml create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/js/VizGrammar.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/js/VizGrammarSettings.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/js/analyticsUtils.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/js/bootstrap-paginator.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/js/d3.min.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/js/gadgetconf.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/js/jquery.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/js/main.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/js/topojson.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_un_secured_devices_gadget/un-secured-devices/js/vega.js create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/artifacts.xml diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/build.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/build.xml new file mode 100644 index 0000000000..a0a04fe973 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/build.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/pom.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/pom.xml new file mode 100644 index 0000000000..54cff03dc6 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/pom.xml @@ -0,0 +1,75 @@ + + + + + + androidsense-plugin + org.wso2.carbon.devicemgt-plugins + 3.0.1-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.device.mgt.iot.androidsense.analytics + WSO2 Carbon - IoT Server Android Sense Analytics capp + pom + + + + + maven-antrun-plugin + 1.7 + + + process-resources + + + + + + + run + + + + + + maven-assembly-plugin + 2.5.5 + + ${project.artifactId}-${carbon.devicemgt.plugins.version} + false + + src/assembly/src.xml + + + + + create-archive + package + + single + + + + + + + + \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/assembly/src.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/assembly/src.xml new file mode 100644 index 0000000000..a5a375010e --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/assembly/src.xml @@ -0,0 +1,36 @@ + + + + src + + zip + + false + ${basedir}/src + + + ${basedir}/target/carbonapps + / + true + + + \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/conf.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/conf.json new file mode 100644 index 0000000000..3c8d3bd0f2 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/conf.json @@ -0,0 +1,17 @@ +{ + "chart-conf": { + "chart-name": "bar-chart", + "color": "action", + "gadget-name": "Android Active Stack Chart", + "maxLength": "45", + "mode": "stack", + "x": "timestamp", + "y": "duration" + }, + "provider-conf": { + "limit": "45", + "provider-name": "batch", + "query": "", + "tableName": "ANDROID_ACTIVE_STAT_PER_DAY" + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/gadget-controller.jag b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/gadget-controller.jag new file mode 100644 index 0000000000..f84538a40a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/gadget-controller.jag @@ -0,0 +1,42 @@ +<% +/** + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +(function () { + + response.contentType = 'application/json'; + var PROVIDER_CONF = 'provider-conf'; + var PROVIDER_NAME = 'provider-name'; + + var action = request.getParameter("action"); + var data = request.getContent(); + var providerConf = data[PROVIDER_CONF]; + var providerAPI = require('js/core/' + providerConf[PROVIDER_NAME] + '-provider-api.js'); + + if (action === 'getSchema') { + print(providerAPI.getSchema(providerConf)); + return; + } else if(action === 'getData'){ + print(providerAPI.getData(providerConf)); + return; + } + +}()); + + +%> diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/gadget.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/gadget.json new file mode 100644 index 0000000000..7435ba90f5 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/gadget.json @@ -0,0 +1,14 @@ +{ + "id": "Android_Active_Stack_Chart", + "title": "Android Active Stack Chart", + "type": "gadget", + "thumbnail": "gadget/Android_Active_Stack_Chart/thumbnail.png", + "data": { + "url": "gadget/Android_Active_Stack_Chart/gadget.xml" + }, + "toolbarButtons":{ + "default":{ + "maximize": false + } + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/gadget.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/gadget.xml new file mode 100644 index 0000000000..7515161831 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/gadget.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ]]> +
+
diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/bar-chart-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/bar-chart-api.js new file mode 100644 index 0000000000..2901cd5fe0 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/bar-chart-api.js @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, isProviderRequired, draw, update; + +(function() { + + var CHART_LOCATION = '/extensions/chart-templates/'; + + /** + * return the config to be populated in the chart configuration UI + * @param schema + */ + getConfig = function(schema) { + var chartConf = require(CHART_LOCATION + '/bar-chart/config.json').config; + /* + dynamic logic goes here + */ + + var columns = []; + + columns.push("None"); + for(var i=0; i < schema.length; i++) { + columns.push(schema[i]["fieldName"]); + } + + for(var i=0; i < chartConf.length; i++) { + if (chartConf[i]["fieldName"] == "color") { + chartConf[i]["valueSet"] = columns; + break; + } + } + + return chartConf; + }; + + /** + * validate the user inout for the chart configuration + * @param chartConfig + */ + validate = function(chartConfig) { + return true; + }; + + /** + * TO be used when provider configuration steps need to be skipped + */ + isProviderRequired = function() { + + } + + + /** + * return the gadget content + * @param chartConfig + * @param schema + * @param data + */ + draw = function(placeholder, chartConfig, _schema, data) { + var schema = toVizGrammarSchema(_schema); + var view = { + id: "chart-0", + schema: schema, + chartConfig: buildChartConfig(chartConfig), + data: function() { + if(data) { + var result = []; + data.forEach(function(item) { + var row = []; + schema[0].metadata.names.forEach(function(name) { + if(name === chartConfig.x){ + var date = new Date(item[name]); + var month = date.getMonth() + 1; + month = ("0" + month).slice(-2); + row.push(date.getDate()+'/'+month+'/'+ date.getFullYear()); +// row.push(item[name]); + } else{ + if(name === chartConfig.y){ + row.push(item[name] / (1000*60*60)); + } else{ + row.push(item[name]); + } + } + }); + result.push(row); + }); + wso2gadgets.onDataReady(result); + } + } + + }; + + try { + wso2gadgets.init(placeholder, view); + var view = wso2gadgets.load("chart-0"); + } catch (e) { + console.error(e); + } + + }; + + /** + * + * @param data + */ + update = function(data) { + wso2gadgets.onDataReady(data,"append"); + } + + buildChartConfig = function (_chartConfig) { + var conf = {}; + conf.x = _chartConfig.x; + conf.charts = []; + conf.maxLength = _chartConfig.maxLength; + conf.charts[0] = { + type : "bar", + y: _chartConfig.y + }; + + if (_chartConfig.color != "None") { + conf.charts[0].color = _chartConfig.color; + conf.charts[0].mode = _chartConfig.mode; + } + conf.legendOffset = -30; + conf.padding = {"top": 10, "left": 100, "bottom": 70, "right": 0}; + conf.xTitle = "Date"; + conf.yTitle = "Duration (Hours)"; + conf.xAxisAngle = "true"; + console.log('chart config : '); + console.log(conf); + return conf; + }; + + +}()); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/batch-provider-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/batch-provider-api.js new file mode 100644 index 0000000000..9e0f2d4435 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/batch-provider-api.js @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, getMode, getSchema, getData, registerCallBackforPush; + +(function() { + + var PROVIDERS_LOCATION = '/extensions/providers/'; + + var PROVIDER_NAME = 'batch'; + var TYPE = "type"; + var TABLE_NAME = "tableName"; + var HTTPS_TRANSPORT = "https"; + var CONTENT_TYPE_JSON = "application/json"; + var AUTHORIZATION_HEADER = "Authorization"; + var USER_TOKEN = "user"; + var TENANT_DOMAIN = "domain"; + var CONST_AT = "@"; + var USERNAME = "username"; + var HTTP_USER_NOT_AUTHENTICATED = 403; + var JS_MAX_VALUE = "9007199254740992"; + var JS_MIN_VALUE = "-9007199254740992"; + + var typeMap = { + "bool" : "string", + "boolean" : "string", + "string" : "string", + "int" : "number", + "integer" : "number", + "long" : "number", + "double" : "number", + "float" : "number", + "time": "time" + }; + + var log = new Log(); + var carbon = require('carbon'); + var configs = require('/configs/designer.json'); + var utils = require('/modules/utils.js'); + var JSUtils = Packages.org.wso2.carbon.analytics.jsservice.Utils; + var AnalyticsCachedJSServiceConnector = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector; + var AnalyticsCache = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector.AnalyticsCache; + var cacheTimeoutSeconds = 5; + var loggedInUser = null; + + if (configs.cacheTimeoutSeconds) { + cacheTimeoutSeconds = parseInt(configs.cacheTimeoutSeconds); + } + var cacheSizeBytes = 1024 * 1024 * 1024; // 1GB + if (configs.cacheSizeBytes) { + cacheSizeBytes = parseInt(configs.cacheSizeBytes); + } + response.contentType = CONTENT_TYPE_JSON; + + var authParam = request.getHeader(AUTHORIZATION_HEADER); + if (authParam != null) { + credentials = JSUtils.authenticate(authParam); + loggedInUser = credentials[0]; + } else { + var token = session.get(USER_TOKEN); + if (token != null) { + loggedInUser = token[USERNAME] + CONST_AT + token[TENANT_DOMAIN]; + } else { + log.error("user is not authenticated!"); + response.status = HTTP_USER_NOT_AUTHENTICATED; + print('{ "status": "Failed", "message": "User is not authenticated." }'); + return; + } + } + + var cache = application.get("AnalyticsWebServiceCache"); + if (cache == null) { + cache = new AnalyticsCache(cacheTimeoutSeconds, cacheSizeBytes); + application.put("AnalyticsWebServiceCache", cache); + } + var connector = new AnalyticsCachedJSServiceConnector(cache); + + /** + * require the existing config.json and push any dynamic fields that needs to be populated in the UI + */ + getConfig = function() { + var formConfig = require(PROVIDERS_LOCATION + '/' + PROVIDER_NAME + '/config.json'); + var tables; + try { + tables = JSON.parse(connector.getTableList(loggedInUser).getMessage()); + } catch (e) { + log.error(e); + } + var configs = formConfig.config; + configs.forEach(function(config) { + if (config.fieldName === TABLE_NAME) { + config.valueSet = tables; + } + }); + return formConfig; + } + + /** + * validate the user input of provider configuration + * @param providerConfig + */ + validate = function(providerConfig) { + /* + validate the form and return + + */ + return true; + } + + /** + * returns the data mode either push or pull + */ + getMode = function() { + return "PULL"; + } + + /** + * returns an array of column names & types + * @param providerConfig + */ + getSchema = function(providerConfig) { + var schema = []; + var tableName = providerConfig["tableName"]; + var result = connector.getTableSchema(loggedInUser, tableName).getMessage(); + result = JSON.parse(result); + + var columns = result.columns; + Object.getOwnPropertyNames(columns).forEach(function(name, idx, array) { + var type = "ordinal"; + // log.info(columns[name]); + if(name === 'timestamp'){ + type = 'string'; + } + else if(columns[name]['type']) { + type = columns[name]['type']; + } + schema.push({ + fieldName: name, + fieldType: typeMap[type.toLowerCase()] + }); + }); + //log.info(schema); + return schema; + }; + + /** + * returns the actual data + * @param providerConfig + * @param limit + */ + getData = function(providerConfig, limit) { + var tableName = providerConfig.tableName; + var query = providerConfig.query; + var limit = 100; + if (providerConfig.limit) { + limit = providerConfig.limit; + } + var result; + //if there's a filter present, we should perform a Lucene search instead of reading the table + if (query) { + var filter = { + "query": query, + "start": 0, + "count": limit + }; + result = connector.search(loggedInUser, tableName, stringify(filter)).getMessage(); + } else { + var from = JS_MIN_VALUE; + var to = JS_MAX_VALUE; + result = connector.getRecordsByRange(loggedInUser, tableName, from, to, 0, limit, null).getMessage(); + + } + result = JSON.parse(result); + var data = []; + for (var i = 0; i < result.length; i++) { + var values = result[i].values; + data.push(values); + } + //log.info(data); + return data; + }; + +}()); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/gadget-core.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/gadget-core.js new file mode 100644 index 0000000000..9dfe8683b8 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/gadget-core.js @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +$(function () { + var gadgetLocation; + var conf; + var schema; + var pref = new gadgets.Prefs(); + + var refreshInterval; + var providerData; + + var CHART_CONF = 'chart-conf'; + var PROVIDER_CONF = 'provider-conf'; + + var REFRESH_INTERVAL = 'refreshInterval'; + +var init = function () { + $.ajax({ + url: gadgetLocation + '/conf.json', + method: "GET", + contentType: "application/json", + async: false, + success: function (data) { + conf = JSON.parse(data); + $.ajax({ + url: gadgetLocation + '/gadget-controller.jag?action=getSchema', + method: "POST", + data: JSON.stringify(conf), + contentType: "application/json", + async: false, + success: function (data) { + schema = data; + } + }); + + getProviderData(); + + } + }); +}; + +var getProviderData = function (){ + $.ajax({ + url: gadgetLocation + '/gadget-controller.jag?action=getData', + method: "POST", + data: JSON.stringify(conf), + contentType: "application/json", + async: false, + success: function (data) { + providerData = data; + } + }); + return providerData; +}; + + +var drawGadget = function (){ + + draw('#canvas', conf[CHART_CONF], schema, providerData); + setInterval(function() { + draw('#canvas', conf[CHART_CONF], schema, getProviderData()); + },pref.getInt(REFRESH_INTERVAL)); + +}; + +getGadgetLocation(function (gadget_Location) { + gadgetLocation = gadget_Location; + init(); + drawGadget(); + +}); +}); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/gadget-util.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/gadget-util.js new file mode 100644 index 0000000000..91c5f16f42 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/js/core/gadget-util.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getGadgetLocation = function (callback) { + var gadgetLocation = "/portal/store/carbon.super/fs/gadget/Android_Active_Stack_Chart"; + var PATH_SEPERATOR = "/"; + if (gadgetLocation.search("store") != -1) { + wso2.gadgets.identity.getTenantDomain(function (tenantDomain) { + var gadgetPath = gadgetLocation.split(PATH_SEPERATOR); + var modifiedPath = ''; + for (var i = 1; i < gadgetPath.length; i++) { + if (i === 3) { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, tenantDomain); + } else { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, gadgetPath[i]) + } + } + callback(modifiedPath); + }); + } else { + callback(gadgetLocation); + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/thumbnail.png b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/Android_Active_Stack_Chart/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..5d985d6e469e913933d14c5b37c8bd4d1c5058e1 GIT binary patch literal 10026 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 literal 0 HcmV?d00001 diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/artifact.xml new file mode 100644 index 0000000000..a9b477ca5f --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_stack_chart_gadget/artifact.xml @@ -0,0 +1,23 @@ + + + + + Android_Active_Stack_Chart + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/conf.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/conf.json new file mode 100644 index 0000000000..ffdd90533a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/conf.json @@ -0,0 +1,18 @@ +{ + "chart-conf": { + "chart-name": "line-chart", + "color": "None", + "gadget-name": "Android Active Time Chart", + "maxLength": "15", + "x": "timestamp", + "xType": "time", + "y": "duration", + "yType": "default" + }, + "provider-conf": { + "limit": "15", + "provider-name": "batch", + "query": "", + "tableName": "ANDROID_ACTIVE_STAT_PER_DAY" + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/gadget-controller.jag b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/gadget-controller.jag new file mode 100644 index 0000000000..f84538a40a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/gadget-controller.jag @@ -0,0 +1,42 @@ +<% +/** + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +(function () { + + response.contentType = 'application/json'; + var PROVIDER_CONF = 'provider-conf'; + var PROVIDER_NAME = 'provider-name'; + + var action = request.getParameter("action"); + var data = request.getContent(); + var providerConf = data[PROVIDER_CONF]; + var providerAPI = require('js/core/' + providerConf[PROVIDER_NAME] + '-provider-api.js'); + + if (action === 'getSchema') { + print(providerAPI.getSchema(providerConf)); + return; + } else if(action === 'getData'){ + print(providerAPI.getData(providerConf)); + return; + } + +}()); + + +%> diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/gadget.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/gadget.json new file mode 100644 index 0000000000..fc2bcee303 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/gadget.json @@ -0,0 +1,9 @@ +{ + "id": "Android_Active_Time_Chart", + "title": "Android Active Time Chart", + "type": "gadget", + "thumbnail": "gadget/Android_Active_Time_Chart/thumbnail.png", + "data": { + "url": "gadget/Android_Active_Time_Chart/gadget.xml" + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/gadget.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/gadget.xml new file mode 100644 index 0000000000..0b480df1dc --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/gadget.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ]]> +
+
diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/batch-provider-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/batch-provider-api.js new file mode 100644 index 0000000000..d6d5102560 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/batch-provider-api.js @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, getMode, getSchema, getData, registerCallBackforPush; + +(function() { + + var PROVIDERS_LOCATION = '/extensions/providers/'; + + var PROVIDER_NAME = 'batch'; + var TYPE = "type"; + var TABLE_NAME = "tableName"; + var HTTPS_TRANSPORT = "https"; + var CONTENT_TYPE_JSON = "application/json"; + var AUTHORIZATION_HEADER = "Authorization"; + var USER_TOKEN = "user"; + var TENANT_DOMAIN = "domain"; + var CONST_AT = "@"; + var USERNAME = "username"; + var HTTP_USER_NOT_AUTHENTICATED = 403; + var JS_MAX_VALUE = "9007199254740992"; + var JS_MIN_VALUE = "-9007199254740992"; + + var typeMap = { + "bool" : "string", + "boolean" : "string", + "string" : "string", + "int" : "number", + "integer" : "number", + "long" : "number", + "double" : "number", + "float" : "number", + "time": "time" + }; + + var log = new Log(); + var carbon = require('carbon'); + var configs = require('/configs/designer.json'); + var utils = require('/modules/utils.js'); + var JSUtils = Packages.org.wso2.carbon.analytics.jsservice.Utils; + var AnalyticsCachedJSServiceConnector = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector; + var AnalyticsCache = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector.AnalyticsCache; + var cacheTimeoutSeconds = 5; + var loggedInUser = null; + + if (configs.cacheTimeoutSeconds) { + cacheTimeoutSeconds = parseInt(configs.cacheTimeoutSeconds); + } + var cacheSizeBytes = 1024 * 1024 * 1024; // 1GB + if (configs.cacheSizeBytes) { + cacheSizeBytes = parseInt(configs.cacheSizeBytes); + } + response.contentType = CONTENT_TYPE_JSON; + + var authParam = request.getHeader(AUTHORIZATION_HEADER); + if (authParam != null) { + credentials = JSUtils.authenticate(authParam); + loggedInUser = credentials[0]; + } else { + var token = session.get(USER_TOKEN); + if (token != null) { + loggedInUser = token[USERNAME] + CONST_AT + token[TENANT_DOMAIN]; + } else { + log.error("user is not authenticated!"); + response.status = HTTP_USER_NOT_AUTHENTICATED; + print('{ "status": "Failed", "message": "User is not authenticated." }'); + return; + } + } + + var cache = application.get("AnalyticsWebServiceCache"); + if (cache == null) { + cache = new AnalyticsCache(cacheTimeoutSeconds, cacheSizeBytes); + application.put("AnalyticsWebServiceCache", cache); + } + var connector = new AnalyticsCachedJSServiceConnector(cache); + + /** + * require the existing config.json and push any dynamic fields that needs to be populated in the UI + */ + getConfig = function() { + var formConfig = require(PROVIDERS_LOCATION + '/' + PROVIDER_NAME + '/config.json'); + var tables; + try { + tables = JSON.parse(connector.getTableList(loggedInUser).getMessage()); + } catch (e) { + log.error(e); + } + var configs = formConfig.config; + configs.forEach(function(config) { + if (config.fieldName === TABLE_NAME) { + config.valueSet = tables; + } + }); + return formConfig; + } + + /** + * validate the user input of provider configuration + * @param providerConfig + */ + validate = function(providerConfig) { + /* + validate the form and return + + */ + return true; + } + + /** + * returns the data mode either push or pull + */ + getMode = function() { + return "PULL"; + } + + /** + * returns an array of column names & types + * @param providerConfig + */ + getSchema = function(providerConfig) { + var schema = []; + var tableName = providerConfig["tableName"]; + var result = connector.getTableSchema(loggedInUser, tableName).getMessage(); + result = JSON.parse(result); + + var columns = result.columns; + Object.getOwnPropertyNames(columns).forEach(function(name, idx, array) { + var type = "ordinal"; + if(columns[name]['type']) { + type = columns[name]['type']; + } + schema.push({ + fieldName: name, + fieldType: typeMap[type.toLowerCase()] + }); + }); + // log.info(schema); + return schema; + }; + + /** + * returns the actual data + * @param providerConfig + * @param limit + */ + getData = function(providerConfig, limit) { + var tableName = providerConfig.tableName; + var query = providerConfig.query; + var limit = 100; + if (providerConfig.limit) { + limit = providerConfig.limit; + } + var result; + //if there's a filter present, we should perform a Lucene search instead of reading the table + if (query) { + var filter = { + "query": query, + "start": 0, + "count": limit + }; + result = connector.search(loggedInUser, tableName, stringify(filter)).getMessage(); + } else { + var from = JS_MIN_VALUE; + var to = JS_MAX_VALUE; + result = connector.getRecordsByRange(loggedInUser, tableName, from, to, 0, limit, null).getMessage(); + + } + result = JSON.parse(result); + var data = []; + for (var i = 0; i < result.length; i++) { + var values = result[i].values; + data.push(values); + } + console.log(data); + return data; + }; +}()); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/gadget-core.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/gadget-core.js new file mode 100644 index 0000000000..282e7e2285 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/gadget-core.js @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +$(function () { + var gadgetLocation; + var conf; + var schema; + var pref = new gadgets.Prefs(); + + var refreshInterval; + var providerData; + + var CHART_CONF = 'chart-conf'; + var PROVIDER_CONF = 'provider-conf'; + + var REFRESH_INTERVAL = 'refreshInterval'; + +var init = function () { + $.ajax({ + url: gadgetLocation + '/conf.json', + method: "GET", + contentType: "application/json", + async: false, + success: function (data) { + conf = JSON.parse(data); + $.ajax({ + url: gadgetLocation + '/gadget-controller.jag?action=getSchema', + method: "POST", + data: JSON.stringify(conf), + contentType: "application/json", + async: false, + success: function (data) { + schema = data; + } + }); + + getProviderData(); + + } + }); +}; + +var getProviderData = function (){ + $.ajax({ + url: gadgetLocation + '/gadget-controller.jag?action=getData', + method: "POST", + data: JSON.stringify(conf), + contentType: "application/json", + async: false, + success: function (data) { + data.forEach(function(entry) { + entry.duration = entry.duration / 3600000; // Convert to hours + }); + providerData = data; + } + }); + return providerData; +}; + + +var drawGadget = function (){ + + draw('#canvas', conf[CHART_CONF], schema, providerData); + setInterval(function() { + draw('#canvas', conf[CHART_CONF], schema, getProviderData()); + },pref.getInt(REFRESH_INTERVAL)); + +}; + +getGadgetLocation(function (gadget_Location) { + gadgetLocation = gadget_Location; + init(); + drawGadget(); + +}); +}); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/gadget-util.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/gadget-util.js new file mode 100644 index 0000000000..09654fc253 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/gadget-util.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getGadgetLocation = function (callback) { + var gadgetLocation = "/portal/store/carbon.super/fs/gadget/Android_Active_Time_Chart"; + var PATH_SEPERATOR = "/"; + if (gadgetLocation.search("store") != -1) { + wso2.gadgets.identity.getTenantDomain(function (tenantDomain) { + var gadgetPath = gadgetLocation.split(PATH_SEPERATOR); + var modifiedPath = ''; + for (var i = 1; i < gadgetPath.length; i++) { + if (i === 3) { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, tenantDomain); + } else { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, gadgetPath[i]) + } + } + callback(modifiedPath); + }); + } else { + callback(gadgetLocation); + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/line-chart-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/line-chart-api.js new file mode 100644 index 0000000000..7a42bbbf97 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/js/core/line-chart-api.js @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, isProviderRequired, draw, update; + +(function() { + + var CHART_LOCATION = '/extensions/chart-templates/'; + + /** + * return the config to be populated in the chart configuration UI + * @param schema + */ + getConfig = function(schema) { + var chartConf = require(CHART_LOCATION + '/line-chart/config.json').config; + /* + dynamic logic goes here + */ + + var columns = []; + + columns.push("None"); + for(var i=0; i < schema.length; i++) { + columns.push(schema[i]["fieldName"]); + } + + for(var i=0; i < chartConf.length; i++) { + if (chartConf[i]["fieldName"] == "color") { + chartConf[i]["valueSet"] = columns; + break; + } + } + + return chartConf; + }; + + /** + * validate the user inout for the chart configuration + * @param chartConfig + */ + validate = function(chartConfig) { + return true; + }; + + /** + * TO be used when provider configuration steps need to be skipped + */ + isProviderRequired = function() { + + } + + + /** + * return the gadget content + * @param chartConfig + * @param schema + * @param data + */ + draw = function(placeholder, chartConfig, _schema, data) { + _schema = updateUserPrefXYTypes(_schema, chartConfig); + var schema = toVizGrammarSchema(_schema); + + var view = { + id: "chart-0", + schema: schema, + chartConfig: buildChartConfig(chartConfig), + data: function() { + if(data) { + var result = []; + data.forEach(function(item) { + var row = []; + schema[0].metadata.names.forEach(function(name) { + row.push(item[name]); + }); + result.push(row); + }); + wso2gadgets.onDataReady(result); + } + } + + }; + + try { + wso2gadgets.init(placeholder, view); + var view = wso2gadgets.load("chart-0"); + } catch (e) { + console.error(e); + } + + }; + + /** + * + * @param data + */ + update = function(data) { + wso2gadgets.onDataReady(data,"append"); + }; + + buildChartConfig = function (_chartConfig) { + var conf = {}; + conf.x = _chartConfig.x; + conf.xType = _chartConfig.xType; + conf.yType = _chartConfig.yType; + conf.maxLength = _chartConfig.maxLength; + conf.charts = []; + conf.charts[0] = { + type : "line", + y: _chartConfig.y + }; + + if (_chartConfig.color != "None") { + conf.charts[0].color = _chartConfig.color; + } + + return conf; + }; + + +}()); \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/thumbnail.png b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_active_time_chart_gadget/Android_Active_Time_Chart/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..16ac3e8bdeafa6c3e568bb3791a5aef4c84d793a GIT binary patch literal 17872 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 k+`0~ + + + + Android_Active_Time_Chart + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/conf.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/conf.json new file mode 100644 index 0000000000..7c2e1c5891 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/conf.json @@ -0,0 +1,15 @@ +{ + "chart-conf": { + "chart-name": "donut-chart", + "color": "action", + "gadget-name": "Android Activity Chart", + "maxLength": "30", + "x": "duration" + }, + "provider-conf": { + "limit": "", + "provider-name": "batch", + "query": "", + "tableName": "ANDROID_ACTIVITY_STAT_PER_DAY" + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/gadget-controller.jag b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/gadget-controller.jag new file mode 100644 index 0000000000..f84538a40a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/gadget-controller.jag @@ -0,0 +1,42 @@ +<% +/** + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +(function () { + + response.contentType = 'application/json'; + var PROVIDER_CONF = 'provider-conf'; + var PROVIDER_NAME = 'provider-name'; + + var action = request.getParameter("action"); + var data = request.getContent(); + var providerConf = data[PROVIDER_CONF]; + var providerAPI = require('js/core/' + providerConf[PROVIDER_NAME] + '-provider-api.js'); + + if (action === 'getSchema') { + print(providerAPI.getSchema(providerConf)); + return; + } else if(action === 'getData'){ + print(providerAPI.getData(providerConf)); + return; + } + +}()); + + +%> diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/gadget.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/gadget.json new file mode 100644 index 0000000000..76104a278e --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/gadget.json @@ -0,0 +1,9 @@ +{ + "id": "Android_Activity_Chart", + "title": "Android Activity Chart", + "type": "gadget", + "thumbnail": "gadget/Android_Activity_Chart/thumbnail.png", + "data": { + "url": "gadget/Android_Activity_Chart/gadget.xml" + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/gadget.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/gadget.xml new file mode 100644 index 0000000000..688a06fb6a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/gadget.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ]]> +
+
diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/batch-provider-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/batch-provider-api.js new file mode 100644 index 0000000000..30c96902a5 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/batch-provider-api.js @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, getMode, getSchema, getData, registerCallBackforPush; + +(function() { + + var PROVIDERS_LOCATION = '/extensions/providers/'; + + var PROVIDER_NAME = 'batch'; + var TYPE = "type"; + var TABLE_NAME = "tableName"; + var HTTPS_TRANSPORT = "https"; + var CONTENT_TYPE_JSON = "application/json"; + var AUTHORIZATION_HEADER = "Authorization"; + var USER_TOKEN = "user"; + var TENANT_DOMAIN = "domain"; + var CONST_AT = "@"; + var USERNAME = "username"; + var HTTP_USER_NOT_AUTHENTICATED = 403; + var JS_MAX_VALUE = "9007199254740992"; + var JS_MIN_VALUE = "-9007199254740992"; + + var typeMap = { + "bool" : "string", + "boolean" : "string", + "string" : "string", + "int" : "number", + "integer" : "number", + "long" : "number", + "double" : "number", + "float" : "number", + "time": "time" + }; + + var log = new Log(); + var carbon = require('carbon'); + var configs = require('/configs/designer.json'); + var utils = require('/modules/utils.js'); + var JSUtils = Packages.org.wso2.carbon.analytics.jsservice.Utils; + var AnalyticsCachedJSServiceConnector = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector; + var AnalyticsCache = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector.AnalyticsCache; + var cacheTimeoutSeconds = 5; + var loggedInUser = null; + + if (configs.cacheTimeoutSeconds) { + cacheTimeoutSeconds = parseInt(configs.cacheTimeoutSeconds); + } + var cacheSizeBytes = 1024 * 1024 * 1024; // 1GB + if (configs.cacheSizeBytes) { + cacheSizeBytes = parseInt(configs.cacheSizeBytes); + } + response.contentType = CONTENT_TYPE_JSON; + + var authParam = request.getHeader(AUTHORIZATION_HEADER); + if (authParam != null) { + credentials = JSUtils.authenticate(authParam); + loggedInUser = credentials[0]; + } else { + var token = session.get(USER_TOKEN); + if (token != null) { + loggedInUser = token[USERNAME] + CONST_AT + token[TENANT_DOMAIN]; + } else { + log.error("user is not authenticated!"); + response.status = HTTP_USER_NOT_AUTHENTICATED; + print('{ "status": "Failed", "message": "User is not authenticated." }'); + return; + } + } + + var cache = application.get("AnalyticsWebServiceCache"); + if (cache == null) { + cache = new AnalyticsCache(cacheTimeoutSeconds, cacheSizeBytes); + application.put("AnalyticsWebServiceCache", cache); + } + var connector = new AnalyticsCachedJSServiceConnector(cache); + + /** + * require the existing config.json and push any dynamic fields that needs to be populated in the UI + */ + getConfig = function() { + var formConfig = require(PROVIDERS_LOCATION + '/' + PROVIDER_NAME + '/config.json'); + var tables; + try { + tables = JSON.parse(connector.getTableList(loggedInUser).getMessage()); + } catch (e) { + log.error(e); + } + var configs = formConfig.config; + configs.forEach(function(config) { + if (config.fieldName === TABLE_NAME) { + config.valueSet = tables; + } + }); + return formConfig; + } + + /** + * validate the user input of provider configuration + * @param providerConfig + */ + validate = function(providerConfig) { + /* + validate the form and return + + */ + return true; + } + + /** + * returns the data mode either push or pull + */ + getMode = function() { + return "PULL"; + } + + /** + * returns an array of column names & types + * @param providerConfig + */ + getSchema = function(providerConfig) { + var schema = []; + var tableName = providerConfig["tableName"]; + var result = connector.getTableSchema(loggedInUser, tableName).getMessage(); + result = JSON.parse(result); + + var columns = result.columns; + Object.getOwnPropertyNames(columns).forEach(function(name, idx, array) { + var type = "ordinal"; + if(columns[name]['type']) { + type = columns[name]['type']; + } + schema.push({ + fieldName: name, + fieldType: typeMap[type.toLowerCase()] + }); + }); + // log.info(schema); + return schema; + }; + + /** + * returns the actual data + * @param providerConfig + * @param limit + */ + getData = function(providerConfig, limit) { + var tableName = providerConfig.tableName; + var query = providerConfig.query; + var limit = 100; + if (providerConfig.limit) { + limit = providerConfig.limit; + } + var result; + //if there's a filter present, we should perform a Lucene search instead of reading the table + if (query) { + var filter = { + "query": query, + "start": 0, + "count": limit + }; + result = connector.search(loggedInUser, tableName, stringify(filter)).getMessage(); + } else { + var from = JS_MIN_VALUE; + var to = JS_MAX_VALUE; + result = connector.getRecordsByRange(loggedInUser, tableName, from, to, 0, limit, null).getMessage(); + + } + result = JSON.parse(result); + var data = []; + for (var i = 0; i < result.length; i++) { + var values = result[i].values; + data.push(values); + } + return data; + }; + +}()); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/donut-chart-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/donut-chart-api.js new file mode 100644 index 0000000000..2e19f88cbe --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/donut-chart-api.js @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, isProviderRequired, draw, update; + +(function() { + + var CHART_LOCATION = '/extensions/chart-templates/'; + + /** + * return the config to be populated in the chart configuration UI + * @param schema + */ + getConfig = function(schema) { + var chartConf = require(CHART_LOCATION + '/donut-chart/config.json').config; + /* + dynamic logic goes here + */ + return chartConf; + + }; + + /** + * validate the user inout for the chart configuration + * @param chartConfig + */ + validate = function(chartConfig) { + return true; + }; + + /** + * TO be used when provider configuration steps need to be skipped + */ + isProviderRequired = function() { + + } + + + /** + * return the gadget content + * @param chartConfig + * @param schema + * @param data + */ + draw = function(placeholder, chartConfig, _schema, data) { + var schema = toVizGrammarSchema(_schema); + var view = { + id: "chart-0", + schema: schema, + chartConfig: buildChartConfig(chartConfig), + data: function() { + if(data) { + var result = []; + data.forEach(function(item) { + var row = []; + schema[0].metadata.names.forEach(function(name) { + row.push(item[name]); + }); + result.push(row); + }); + wso2gadgets.onDataReady(result); + } + } + + }; + + try { + wso2gadgets.init(placeholder, view); + var view = wso2gadgets.load("chart-0"); + } catch (e) { + console.error(e); + } + + }; + + /** + * + * @param data + */ + update = function(data) { + wso2gadgets.onDataReady(data,"append"); + } + + buildChartConfig = function (_chartConfig) { + var conf = {}; + conf.x = _chartConfig.x; + conf.maxLength = _chartConfig.maxLength; + conf.charts = []; + conf.charts[0] = { + type : "arc", + color: _chartConfig.color, + mode: "donut" + }; + conf.legendOffset = -30; + return conf; + }; + + +}()); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/gadget-core.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/gadget-core.js new file mode 100644 index 0000000000..8831c6925e --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/gadget-core.js @@ -0,0 +1,101 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +$(function () { + var gadgetLocation; + var conf; + var schema; + var pref = new gadgets.Prefs(); + + var refreshInterval; + var providerData; + + var CHART_CONF = 'chart-conf'; + var PROVIDER_CONF = 'provider-conf'; + + var REFRESH_INTERVAL = 'refreshInterval'; + +var init = function () { + $.ajax({ + url: gadgetLocation + '/conf.json', + method: "GET", + contentType: "application/json", + async: false, + success: function (data) { + conf = JSON.parse(data); + // Update the date to yesterday + var currentTime = new Date(); + + // returns the month (from 0 to 11) + var month = currentTime.getMonth() + 1 + + // returns the day of the month (from 1 to 31) + var day = currentTime.getDate() - 1 // Yesterday + + // returns the year (four digits) + var year = currentTime.getFullYear() + + conf['provider-conf'].query = "year: " + year + " AND month: " + month + " AND day: " + day; + $.ajax({ + url: gadgetLocation + '/gadget-controller.jag?action=getSchema', + method: "POST", + data: JSON.stringify(conf), + contentType: "application/json", + async: false, + success: function (data) { + schema = data; + } + }); + + getProviderData(); + + } + }); +}; + +var getProviderData = function (){ + $.ajax({ + url: gadgetLocation + '/gadget-controller.jag?action=getData', + method: "POST", + data: JSON.stringify(conf), + contentType: "application/json", + async: false, + success: function (data) { + data.forEach(function(entry) { + entry.duration = entry.duration / 60000; // Convert to minutes + }); + providerData = data; + } + }); + return providerData; +}; + + +var drawGadget = function (){ + + draw('#canvas', conf[CHART_CONF], schema, providerData); + setInterval(function() { + draw('#canvas', conf[CHART_CONF], schema, getProviderData()); + },pref.getInt(REFRESH_INTERVAL)); + +}; + +getGadgetLocation(function (gadget_Location) { + gadgetLocation = gadget_Location; + init(); + drawGadget(); + +}); +}); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/gadget-util.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/gadget-util.js new file mode 100644 index 0000000000..fc7db2ea3b --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/js/core/gadget-util.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getGadgetLocation = function (callback) { + var gadgetLocation = "/portal/store/carbon.super/fs/gadget/Android_Activity_Chart"; + var PATH_SEPERATOR = "/"; + if (gadgetLocation.search("store") != -1) { + wso2.gadgets.identity.getTenantDomain(function (tenantDomain) { + var gadgetPath = gadgetLocation.split(PATH_SEPERATOR); + var modifiedPath = ''; + for (var i = 1; i < gadgetPath.length; i++) { + if (i === 3) { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, tenantDomain); + } else { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, gadgetPath[i]) + } + } + callback(modifiedPath); + }); + } else { + callback(gadgetLocation); + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/thumbnail.png b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/Android_Activity_Chart/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..ed88c6e59bc2bdbc1bf42237de91d49cac9dd04d GIT binary patch literal 15590 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 literal 0 HcmV?d00001 diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/artifact.xml new file mode 100644 index 0000000000..710dddd2ed --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_chart_gadget/artifact.xml @@ -0,0 +1,23 @@ + + + + + Android_Activity_Chart + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_script/AndroidActivityScript.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_script/AndroidActivityScript.xml new file mode 100644 index 0000000000..a8e82e1f17 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_script/AndroidActivityScript.xml @@ -0,0 +1,30 @@ + + + true + AndroidActivityScript + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_script/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_script/artifact.xml new file mode 100644 index 0000000000..a6e38b2ea7 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_script/artifact.xml @@ -0,0 +1,23 @@ + + + + + AndroidActivityScript.xml + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_event_sink/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_event_sink/artifact.xml new file mode 100644 index 0000000000..99a20223a6 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_event_sink/artifact.xml @@ -0,0 +1,23 @@ + + + + + org_wso2_iot_android_activity_stats.xml + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_event_sink/org_wso2_iot_android_activity_stats.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_event_sink/org_wso2_iot_android_activity_stats.xml new file mode 100755 index 0000000000..bb32f5a365 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_event_sink/org_wso2_iot_android_activity_stats.xml @@ -0,0 +1,90 @@ + + + + + meta_owner + false + false + false + false + STRING + + + meta_deviceId + false + false + false + false + STRING + + + meta_timestamp + false + false + false + false + LONG + + + action + false + false + false + false + STRING + + + duration + false + false + false + false + LONG + + + year + false + false + false + false + INTEGER + + + month + false + false + false + false + INTEGER + + + day + false + false + false + false + INTEGER + + + hour + false + false + false + false + INTEGER + + + minute + false + false + false + false + INTEGER + + + + org.wso2.iot.android.activity.stats:1.0.0 + + false + EVENT_STORE + \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_streams/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_streams/artifact.xml new file mode 100644 index 0000000000..afa78e413a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_streams/artifact.xml @@ -0,0 +1,23 @@ + + + + + org.wso2.iot.android.activity.stats_1.0.0.json + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_streams/org.wso2.iot.android.activity.stats_1.0.0.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_streams/org.wso2.iot.android.activity.stats_1.0.0.json new file mode 100755 index 0000000000..6d7ffefa2f --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_stats_streams/org.wso2.iot.android.activity.stats_1.0.0.json @@ -0,0 +1,50 @@ +{ + "name": "org.wso2.iot.android.activity.stats", + "version": "1.0.0", + "nickName": "", + "description": "", + "metaData": [ + { + "name": "owner", + "type": "STRING" + }, + { + "name": "deviceId", + "type": "STRING" + }, + { + "name": "timestamp", + "type": "LONG" + } + ], + "payloadData": [ + { + "name": "action", + "type": "STRING" + }, + { + "name": "duration", + "type": "LONG" + }, + { + "name": "year", + "type": "INT" + }, + { + "name": "month", + "type": "INT" + }, + { + "name": "day", + "type": "INT" + }, + { + "name": "hour", + "type": "INT" + }, + { + "name": "minute", + "type": "INT" + } + ] +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_streams/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_streams/artifact.xml new file mode 100644 index 0000000000..8b473dd5dc --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_streams/artifact.xml @@ -0,0 +1,23 @@ + + + + + org.wso2.iot.android.activity_1.0.0.json + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_streams/org.wso2.iot.android.activity_1.0.0.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_streams/org.wso2.iot.android.activity_1.0.0.json new file mode 100755 index 0000000000..0463c39067 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_activity_streams/org.wso2.iot.android.activity_1.0.0.json @@ -0,0 +1,26 @@ +{ + "name": "org.wso2.iot.android.activity", + "version": "1.0.0", + "nickName": "", + "description": "", + "metaData": [ + { + "name": "owner", + "type": "STRING" + }, + { + "name": "deviceId", + "type": "STRING" + }, + { + "name": "timestamp", + "type": "LONG" + } + ], + "payloadData": [ + { + "name": "action", + "type": "STRING" + } + ] +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_andriod_audio_filter_executionplan/Andriod-Audio-Filter-ExecutionPlan.siddhiql b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_andriod_audio_filter_executionplan/Andriod-Audio-Filter-ExecutionPlan.siddhiql new file mode 100644 index 0000000000..6527008cd3 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_andriod_audio_filter_executionplan/Andriod-Audio-Filter-ExecutionPlan.siddhiql @@ -0,0 +1,16 @@ +/* Enter a unique ExecutionPlan */ +@Plan:name('Andriod-Audio-Filter-ExecutionPlan') + +/* Enter a unique description for ExecutionPlan */ +@Plan:description('This converts the true/false params of the orgininal stream into ON/OFF') + +/* define streams/tables and write queries here ... */ + +@Import('org.wso2.iot.android.audio:1.0.0') +define stream AudioStream (meta_owner string, meta_deviceId string, meta_timestamp long, audio_playing bool, headset_on bool, music_volume int); + +@Export('org.wso2.iot.andriod.filtered.audio:1.0.0') +define stream FilteredAudioStream (meta_owner string, meta_deviceId string, meta_timestamp long, audio string, headset string, music_volume int); + +from AudioStream select meta_owner, meta_deviceId, meta_timestamp, ifThenElse(audio_playing, 'ON', 'OFF') as audio, +ifThenElse(headset_on, 'ON', 'OFF') as headset, music_volume insert into FilteredAudioStream; \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_andriod_audio_filter_executionplan/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_andriod_audio_filter_executionplan/artifact.xml new file mode 100644 index 0000000000..b72e4ae2d1 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_andriod_audio_filter_executionplan/artifact.xml @@ -0,0 +1,23 @@ + + + + + Andriod-Audio-Filter-ExecutionPlan.siddhiql + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_activity_executionplan/Android-Activity-ExecutionPlan.siddhiql b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_activity_executionplan/Android-Activity-ExecutionPlan.siddhiql new file mode 100755 index 0000000000..ab3edacbdc --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_activity_executionplan/Android-Activity-ExecutionPlan.siddhiql @@ -0,0 +1,22 @@ +@Plan:name('Android-Activity-ExecutionPlan') + +@Plan:description('Identify the start and end of each activities') + +@Import('org.wso2.iot.android.activity:1.0.0') +define stream ActivitySream (meta_owner string, meta_deviceId string, meta_timestamp long, action string); + +@Export('org.wso2.iot.android.activity.stats:1.0.0') +define stream ActivityStatsStream (meta_owner string, meta_deviceId string, meta_timestamp long, action string, duration long, year int, month int, day int, hour int, minute int); + +partition with (meta_deviceId of ActivitySream) +begin + from every preActivity = ActivitySream, postActivity = ActivitySream[preActivity.action != action AND preActivity.meta_timestamp <= meta_timestamp] + select preActivity.meta_owner as meta_owner, preActivity.meta_deviceId as meta_deviceId, + preActivity.action as preAction, postActivity.action as postAction, preActivity.meta_timestamp as preTimestamp, postActivity.meta_timestamp as postTimestamp + insert into #ActivityChangeEventStream; + + from every preEvent = #ActivityChangeEventStream, postEvent = #ActivityChangeEventStream[preEvent.postAction == preAction] + select preEvent.meta_owner as meta_owner, preEvent.meta_deviceId as meta_deviceId, postEvent.preTimestamp as meta_timestamp, preEvent.postAction as action, (postEvent.postTimestamp - preEvent.postTimestamp) as duration, + time:extract(postEvent.preTimestamp, 'year') as year, time:extract(postEvent.preTimestamp, 'month') as month, time:extract(postEvent.preTimestamp, 'day') as day, time:extract(postEvent.preTimestamp, 'hour') as hour, time:extract(postEvent.preTimestamp, 'minute') as minute + insert into ActivityStatsStream; +end; \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_activity_executionplan/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_activity_executionplan/artifact.xml new file mode 100644 index 0000000000..3484a055f0 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_activity_executionplan/artifact.xml @@ -0,0 +1,23 @@ + + + + + Android-Activity-ExecutionPlan.siddhiql + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_audio_executionplan/Android-Audio-ExecutionPlan.siddhiql b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_audio_executionplan/Android-Audio-ExecutionPlan.siddhiql new file mode 100755 index 0000000000..b6bce4d951 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_audio_executionplan/Android-Audio-ExecutionPlan.siddhiql @@ -0,0 +1,27 @@ +/* Enter a unique ExecutionPlan */ +@Plan:name('Android-Audio-ExecutionPlan') + +@Plan:description('Find the audio listening through head set') + + +@Import('org.wso2.iot.android.audio:1.0.0') +define stream AudioStream (meta_owner string, meta_deviceId string, meta_timestamp long, audio_playing bool, headset_on bool, music_volume int); + +@Export('org.wso2.iot.android.headset.stats:1.0.0') +define stream HeadsetStatsStream (meta_owner string, meta_deviceId string, meta_timestamp long, duration long, year int, month int, day int, hour int, minute int); + +partition with (meta_deviceId of AudioStream) +begin + from every preEvent = AudioStream[audio_playing AND headset_on], postEvent = AudioStream[(NOT audio_playing OR NOT headset_on) AND preEvent.meta_timestamp <= meta_timestamp] + select preEvent.meta_owner as meta_owner, preEvent.meta_deviceId as meta_deviceId, postEvent.meta_timestamp as timestamp, 'ACTIVE' as state + insert into #StateChangeEventStream; + + from every preEvent = AudioStream[NOT audio_playing OR NOT headset_on], postEvent = AudioStream[audio_playing AND headset_on AND preEvent.meta_timestamp <= meta_timestamp] + select preEvent.meta_owner as meta_owner, preEvent.meta_deviceId as meta_deviceId, postEvent.meta_timestamp as timestamp, 'INACTIVE' as state + insert into #StateChangeEventStream; + + from every preEvent = #StateChangeEventStream[state == 'ACTIVE'], postEvent = #StateChangeEventStream[state == 'INACTIVE'] + select preEvent.meta_owner as meta_owner, preEvent.meta_deviceId as meta_deviceId, preEvent.timestamp as meta_timestamp, (postEvent.timestamp - preEvent.timestamp) as duration, + time:extract(preEvent.timestamp, 'year') as year, time:extract(preEvent.timestamp, 'month') as month, time:extract(preEvent.timestamp, 'day') as day, time:extract(preEvent.timestamp, 'hour') as hour, time:extract(preEvent.timestamp, 'minute') as minute + insert into HeadsetStatsStream; +end; \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_audio_executionplan/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_audio_executionplan/artifact.xml new file mode 100644 index 0000000000..d666e9c511 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_audio_executionplan/artifact.xml @@ -0,0 +1,23 @@ + + + + + Android-Audio-ExecutionPlan.siddhiql + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_call_executionplan/Android-Call-ExecutionPlan.siddhiql b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_call_executionplan/Android-Call-ExecutionPlan.siddhiql new file mode 100755 index 0000000000..13f71ac3f4 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_call_executionplan/Android-Call-ExecutionPlan.siddhiql @@ -0,0 +1,17 @@ +@Plan:name('Android-Call-ExecutionPlan') + +@Plan:description('Identify the call durations of incoming and outgoing calls') + + +@Import('org.wso2.iot.android.call:1.0.0') +define stream CallStream (meta_owner string, meta_deviceId string, meta_timestamp long, number string, type string, startTime long, endTime long); + +@Export('org.wso2.iot.android.call.stats:1.0.0') +define stream CallStatsStream (meta_owner string, meta_deviceId string, meta_timestamp long, number string, type string, duration long, year int, month int, day int, hour int, minute int); + +partition with (meta_deviceId of CallStream) +begin + from CallStream[type == 'INCOMING' OR type == 'OUTGOING'] + select meta_owner, meta_deviceId, meta_timestamp, number, type, (endTime - startTime) as duration, time:extract(meta_timestamp, 'year') as year, time:extract(meta_timestamp, 'month') as month, time:extract(meta_timestamp, 'day') as day, time:extract(meta_timestamp, 'hour') as hour, time:extract(meta_timestamp, 'minute') as minute + insert into CallStatsStream; +end; \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_call_executionplan/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_call_executionplan/artifact.xml new file mode 100644 index 0000000000..517a0effd1 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_call_executionplan/artifact.xml @@ -0,0 +1,23 @@ + + + + + Android-Call-ExecutionPlan.siddhiql + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_data_executionplan/Android-Data-ExecutionPlan.siddhiql b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_data_executionplan/Android-Data-ExecutionPlan.siddhiql new file mode 100755 index 0000000000..697be11de1 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_data_executionplan/Android-Data-ExecutionPlan.siddhiql @@ -0,0 +1,16 @@ +@Plan:name('Android-Data-ExecutionPlan') + +@Plan:description('Calculate the total network usage of mobile data and others') + +@Import('org.wso2.iot.android.data:1.0.0') +define stream DataStream (meta_owner string, meta_deviceId string, meta_timestamp long, type string, received long, sent long); + +@Export('org.wso2.iot.android.data.stats:1.0.0') +define stream DataStatsStream (meta_owner string, meta_deviceId string, meta_timestamp long, type string, total long, year int, month int, day int, hour int, minute int); + +partition with (meta_deviceId of DataStream) +begin + from DataStream + select meta_owner, meta_deviceId, meta_timestamp, type, (received + sent) as total, time:extract(meta_timestamp, 'year') as year, time:extract(meta_timestamp, 'month') as month, time:extract(meta_timestamp, 'day') as day, time:extract(meta_timestamp, 'hour') as hour, time:extract(meta_timestamp, 'minute') as minute + insert into DataStatsStream; +end; \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_data_executionplan/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_data_executionplan/artifact.xml new file mode 100644 index 0000000000..26caa3bd0a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_data_executionplan/artifact.xml @@ -0,0 +1,23 @@ + + + + + Android-Data-ExecutionPlan.siddhiql + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_location_executionplan/Android-Location-ExecutionPlan.siddhiql b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_location_executionplan/Android-Location-ExecutionPlan.siddhiql new file mode 100755 index 0000000000..e88e09a138 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_location_executionplan/Android-Location-ExecutionPlan.siddhiql @@ -0,0 +1,16 @@ +@Plan:name('Android-Location-ExecutionPlan') + +@Plan:description('Find the street name of the location and add to a new stream') + +@Import('org.wso2.iot.android.location:1.0.0') +define stream LocationStream (meta_owner string, meta_deviceId string, meta_timestamp long, latitude double, longitude double); + +@Export('org.wso2.iot.android.location.stats:1.0.0') +define stream LocationStatsStream (meta_owner string, meta_deviceId string, meta_timestamp long, latitude double, longitude double, streetName string, year int, month int, day int, hour int, minute int); + +partition with (meta_deviceId of LocationStream) +begin + from LocationStream + select meta_owner, meta_deviceId, meta_timestamp, convert(math:round(latitude * 10000), 'double') / 10000.0 as latitude, convert(math:round(longitude * 10000), 'double') / 10000.0 as longitude, "" as streetName, time:extract(preState.meta_timestamp, 'year') as year, time:extract(preState.meta_timestamp, 'month') as month, time:extract(preState.meta_timestamp, 'day') as day, time:extract(preState.meta_timestamp, 'hour') as hour, time:extract(preState.meta_timestamp, 'minute') as minute + insert into LocationStatsStream; +end; \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_location_executionplan/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_location_executionplan/artifact.xml new file mode 100644 index 0000000000..c778e3a902 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_location_executionplan/artifact.xml @@ -0,0 +1,23 @@ + + + + + Android-Location-ExecutionPlan.siddhiql + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_screen_executionplan/Android-Screen-ExecutionPlan.siddhiql b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_screen_executionplan/Android-Screen-ExecutionPlan.siddhiql new file mode 100755 index 0000000000..96591d118e --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_screen_executionplan/Android-Screen-ExecutionPlan.siddhiql @@ -0,0 +1,19 @@ +/* Enter a unique ExecutionPlan */ +@Plan:name('Android-Screen-ExecutionPlan') + +@Plan:description('Identify screen on duration') + + +@Import('org.wso2.iot.android.screen:1.0.0') +define stream ScreenStream (meta_owner string, meta_deviceId string, meta_timestamp long, state string); + +@Export('org.wso2.iot.android.screen.stats:1.0.0') +define stream ScreenStatsStream (meta_owner string, meta_deviceId string, meta_timestamp long, duration long, year int, month int, day int, hour int, minute int); + +partition with (meta_deviceId of ScreenStream) +begin + from every preState = ScreenStream[state == 'on'], postState = ScreenStream[state == 'off' AND preState.meta_timestamp <= meta_timestamp] + select preState.meta_owner as meta_owner, preState.meta_deviceId as meta_deviceId, preState.meta_timestamp as meta_timestamp, (postState.meta_timestamp - preState.meta_timestamp) as duration, + time:extract(preState.meta_timestamp, 'year') as year, time:extract(preState.meta_timestamp, 'month') as month, time:extract(preState.meta_timestamp, 'day') as day, time:extract(preState.meta_timestamp, 'hour') as hour, time:extract(preState.meta_timestamp, 'minute') as minute + insert into ScreenStatsStream; +end; \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_screen_executionplan/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_screen_executionplan/artifact.xml new file mode 100644 index 0000000000..6d11b8886a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_screen_executionplan/artifact.xml @@ -0,0 +1,23 @@ + + + + + Android-Screen-ExecutionPlan.siddhiql + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sense_executionplan/Android-Sense-ExecutionPlan.siddhiql b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sense_executionplan/Android-Sense-ExecutionPlan.siddhiql new file mode 100755 index 0000000000..743ec44f31 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sense_executionplan/Android-Sense-ExecutionPlan.siddhiql @@ -0,0 +1,63 @@ +@Plan:name('Android-Sense-ExecutionPlan') + +@Plan:description('ExecutionPlan') + +@Import('org.wso2.iot.android.sense:1.0.0') +define stream AndroidSense (meta_owner string, meta_deviceId string, meta_type string, meta_timestamp long, battery int, battery_state string, battery_status string, battery_temperature int, gps_lat double, gps_long double, accelerometer_x float, accelerometer_y float, accelerometer_z float, speed_limit float, turn_way string, magnetic_x float, magnetic_y float, magnetic_z float, gyroscope_x float, gyroscope_y float, gyroscope_z float, light float, pressure float, proximity float, gravity_x float, gravity_y float, gravity_z float, rotation_x float, rotation_y float, rotation_z float, word string, word_sessionId string, word_status string, beacon_major int, beacon_minor int, beacon_proximity string, beacon_uuid int, call_number string, call_type string, call_start_time long, call_end_time long, screen_state string, audio_playing bool, headset_on bool, music_volume int, activity_type int, confidence int, sms_number string, application_name string, action string, data_type string, data_sent long, data_received long); + +@Export('org.wso2.iot.android.data:1.0.0') +define stream DataStream (meta_owner string, meta_deviceId string, meta_timestamp long, type string, received long, sent long); + +@Export('org.wso2.iot.android.activity:1.0.0') +define stream ActivityStream (meta_owner string, meta_deviceId string, meta_timestamp long, action string); + +@Export('org.wso2.iot.android.call:1.0.0') +define stream CallStream (meta_owner string, meta_deviceId string, meta_timestamp long, number string, type string, startTime long, endTime long); + +@Export('org.wso2.iot.android.screen:1.0.0') +define stream ScreenStream (meta_owner string, meta_deviceId string, meta_timestamp long, state string); + +@Export('org.wso2.iot.android.location:1.0.0') +define stream LocationStream (meta_owner string, meta_deviceId string, meta_timestamp long, latitude double, longitude double); + +@Export('org.wso2.iot.android.audio:1.0.0') +define stream AudioStream (meta_owner string, meta_deviceId string, meta_timestamp long, audio_playing bool, headset_on bool, music_volume int); + +@Export('org.wso2.iot.android.battery:1.0.0') +define stream BatteryStream (meta_owner string, meta_deviceId string, meta_timestamp long, level int, state string, status string, temperature int); + +@Export('org.wso2.iot.android.sms:1.0.0') +define stream SmsStream (meta_owner string, meta_deviceId string, meta_timestamp long, number string, type string, body string); + + +from AndroidSense[meta_type == 'sms'] +select meta_owner, meta_deviceId, meta_timestamp, sms_number as number, action as type, "" as body +insert into SmsStream; + +from AndroidSense[meta_type == 'battery'] +select meta_owner, meta_deviceId, meta_timestamp, battery as level, battery_state as state, battery_status as status, battery_temperature as temperature +insert into BatteryStream; + +from AndroidSense[meta_type == 'audio'] +select meta_owner, meta_deviceId, meta_timestamp, audio_playing, headset_on, music_volume +insert into AudioStream; + +from AndroidSense[meta_type == 'location'] +select meta_owner, meta_deviceId, meta_timestamp, gps_lat as latitude, gps_long as longitude +insert into LocationStream; + +from AndroidSense[meta_type == 'screen'] +select meta_owner, meta_deviceId, meta_timestamp, screen_state as state +insert into ScreenStream; + +from AndroidSense[meta_type == 'call'] +select meta_owner, meta_deviceId, meta_timestamp, call_number as number, call_type as type, call_start_time as startTime, call_end_time as endTime +insert into CallStream; + +from AndroidSense[meta_type == 'activity'] +select meta_owner, meta_deviceId, meta_timestamp, action +insert into ActivityStream; + +from AndroidSense[meta_type == 'data'] +select meta_owner, meta_deviceId, meta_timestamp, data_type as type, data_received as received, data_sent as sent +insert into DataStream; \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sense_executionplan/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sense_executionplan/artifact.xml new file mode 100644 index 0000000000..0dd982b0cd --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sense_executionplan/artifact.xml @@ -0,0 +1,23 @@ + + + + + Android-Sense-ExecutionPlan.siddhiql + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sms_executionplan/Android-SMS-ExecutionPlan.siddhiql b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sms_executionplan/Android-SMS-ExecutionPlan.siddhiql new file mode 100755 index 0000000000..1e44cf5582 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sms_executionplan/Android-SMS-ExecutionPlan.siddhiql @@ -0,0 +1,16 @@ +@Plan:name('Android-SMS-ExecutionPlan') + +@Plan:description('Process received and sent SMS details') + +@Import('org.wso2.iot.android.sms:1.0.0') +define stream SmsStream (meta_owner string, meta_deviceId string, meta_timestamp long, number string, type string, body string); + +@Export('org.wso2.iot.android.sms.stats:1.0.0') +define stream SmsStatsStream (meta_owner string, meta_deviceId string, meta_timestamp long, number string, type string, year int, month int, day int, hour int, minute int); + +partition with (meta_deviceId of SmsStream) +begin + from SmsStream + select meta_owner, meta_deviceId, meta_timestamp, number, type, time:extract(meta_timestamp, 'year') as year, time:extract(meta_timestamp, 'month') as month, time:extract(meta_timestamp, 'day') as day, time:extract(meta_timestamp, 'hour') as hour, time:extract(meta_timestamp, 'minute') as minute + insert into SmsStatsStream; +end; \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sms_executionplan/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sms_executionplan/artifact.xml new file mode 100644 index 0000000000..49d1a2643a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_android_sms_executionplan/artifact.xml @@ -0,0 +1,23 @@ + + + + + Android-SMS-ExecutionPlan.siddhiql + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_script/AndroidAudioScript.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_script/AndroidAudioScript.xml new file mode 100644 index 0000000000..6f1038493c --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_script/AndroidAudioScript.xml @@ -0,0 +1,19 @@ + + + true + AndroidAudioScript + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_script/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_script/artifact.xml new file mode 100644 index 0000000000..959c749fec --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_script/artifact.xml @@ -0,0 +1,23 @@ + + + + + AndroidAudioScript.xml + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_streams/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_streams/artifact.xml new file mode 100644 index 0000000000..ec5b0b2a77 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_streams/artifact.xml @@ -0,0 +1,23 @@ + + + + + org.wso2.iot.android.audio_1.0.0.json + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_streams/org.wso2.iot.android.audio_1.0.0.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_streams/org.wso2.iot.android.audio_1.0.0.json new file mode 100755 index 0000000000..bd53e88fac --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_audio_streams/org.wso2.iot.android.audio_1.0.0.json @@ -0,0 +1,34 @@ +{ + "name": "org.wso2.iot.android.audio", + "version": "1.0.0", + "nickName": "", + "description": "Intermediate stream to map Android sense stream to audio execution plan", + "metaData": [ + { + "name": "owner", + "type": "STRING" + }, + { + "name": "deviceId", + "type": "STRING" + }, + { + "name": "timestamp", + "type": "LONG" + } + ], + "payloadData": [ + { + "name": "audio_playing", + "type": "BOOL" + }, + { + "name": "headset_on", + "type": "BOOL" + }, + { + "name": "music_volume", + "type": "INT" + } + ] +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/conf.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/conf.json new file mode 100644 index 0000000000..c65b0b7d97 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/conf.json @@ -0,0 +1,17 @@ +{ + "provider-conf": { + "streamName": "org.wso2.iot.android.battery:1.0.0", + "provider-name": "realtime" + }, + "chart-conf": { + "x": "TIMESTAMP", + "xType": "time", + "y": "level", + "yType": "number", + "color": "None", + "mode": "stack", + "maxLength": "30", + "gadget-name": "Android Battery Level Chart", + "chart-name": "area-chart" + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/gadget-controller.jag b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/gadget-controller.jag new file mode 100644 index 0000000000..f84538a40a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/gadget-controller.jag @@ -0,0 +1,42 @@ +<% +/** + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +(function () { + + response.contentType = 'application/json'; + var PROVIDER_CONF = 'provider-conf'; + var PROVIDER_NAME = 'provider-name'; + + var action = request.getParameter("action"); + var data = request.getContent(); + var providerConf = data[PROVIDER_CONF]; + var providerAPI = require('js/core/' + providerConf[PROVIDER_NAME] + '-provider-api.js'); + + if (action === 'getSchema') { + print(providerAPI.getSchema(providerConf)); + return; + } else if(action === 'getData'){ + print(providerAPI.getData(providerConf)); + return; + } + +}()); + + +%> diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/gadget.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/gadget.json new file mode 100644 index 0000000000..73bd6d3560 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/gadget.json @@ -0,0 +1,9 @@ +{ + "id": "Android_Battery_Level_Chart", + "title": "Android Battery Level Chart", + "type": "gadget", + "thumbnail": "gadget/Android_Battery_Level_Chart/thumbnail.png", + "data": { + "url": "gadget/Android_Battery_Level_Chart/gadget.xml" + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/gadget.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/gadget.xml new file mode 100644 index 0000000000..236ab3a422 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/gadget.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ]]> +
+
diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/area-chart-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/area-chart-api.js new file mode 100644 index 0000000000..e6172abf3a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/area-chart-api.js @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, isProviderRequired, draw, update; + +(function() { + + var CHART_LOCATION = '/extensions/chart-templates/'; + + /** + * return the config to be populated in the chart configuration UI + * @param schema + */ + getConfig = function(schema) { + var chartConf = require(CHART_LOCATION + '/area-chart/config.json').config; + /* + dynamic logic goes here + */ + + var columns = []; + + columns.push("None"); + for(var i=0; i < schema.length; i++) { + columns.push(schema[i]["fieldName"]); + } + + for(var i=0; i < chartConf.length; i++) { + if (chartConf[i]["fieldName"] == "color") { + chartConf[i]["valueSet"] = columns; + break; + } + } + + return chartConf; + }; + + /** + * validate the user inout for the chart configuration + * @param chartConfig + */ + validate = function(chartConfig) { + return true; + }; + + /** + * TO be used when provider configuration steps need to be skipped + */ + isProviderRequired = function() { + + } + + + /** + * return the gadget content + * @param chartConfig + * @param schema + * @param data + */ + draw = function(placeholder, chartConfig, _schema, data) { + _schema = updateUserPrefXYTypes(_schema, chartConfig); + var schema = toVizGrammarSchema(_schema); + + var view = { + id: "chart-0", + schema: schema, + chartConfig: buildChartConfig(chartConfig), + data: function() { + if(data) { + var result = []; + console.log(data); + data.forEach(function(item) { + var row = []; + schema[0].metadata.names.forEach(function(name) { + row.push(item[name]); + }); + result.push(row); + }); + console.log(result); + wso2gadgets.onDataReady(result); + } + } + + }; + + try { + wso2gadgets.init(placeholder, view); + var view = wso2gadgets.load("chart-0"); + } catch (e) { + console.error(e); + } + + }; + + /** + * + * @param data + */ + update = function(data) { + wso2gadgets.onDataReady(data,"append"); + } + + buildChartConfig = function (_chartConfig) { + var conf = {}; + conf.x = _chartConfig.x; + conf.xType = _chartConfig.xType; + conf.yType = _chartConfig.yType; + conf.maxLength = _chartConfig.maxLength; + conf.charts = []; + conf.charts[0] = { + type : "area", + y: _chartConfig.y + }; + + if (_chartConfig.color != "None") { + conf.charts[0].color = _chartConfig.color; + conf.charts[0].mode = _chartConfig.mode; + } + + return conf; + }; + + +}()); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/gadget-core.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/gadget-core.js new file mode 100644 index 0000000000..8bfc5f742a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/gadget-core.js @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +$(function () { + var gadgetLocation; + var conf; + var schema; + var pref = new gadgets.Prefs(); + + var CHART_CONF = 'chart-conf'; + var PROVIDER_CONF = 'provider-conf'; + +var init = function () { + $.ajax({ + url: gadgetLocation + '/conf.json', + method: "GET", + contentType: "application/json", + async: false, + success: function (data) { + conf = JSON.parse(data); + $.ajax({ + url: gadgetLocation + '/gadget-controller.jag?action=getSchema', + method: "POST", + data: JSON.stringify(conf), + contentType: "application/json", + async: false, + success: function (data) { + schema = data; + } + }); + + } + }); +}; + + +var drawGadget = function (){ + + draw('#canvas', conf[CHART_CONF], schema, null); + registerCallBackforPush(conf[PROVIDER_CONF], schema, function(providerData) { + update(providerData); + }); + +}; + +getGadgetLocation(function (gadget_Location) { + gadgetLocation = gadget_Location; + init(); + drawGadget(); + +}); +}); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/gadget-util.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/gadget-util.js new file mode 100644 index 0000000000..7f39549495 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/gadget-util.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getGadgetLocation = function (callback) { + var gadgetLocation = "/portal/store/carbon.super/fs/gadget/Android_Battery_Level_Chart"; + var PATH_SEPERATOR = "/"; + if (gadgetLocation.search("store") != -1) { + wso2.gadgets.identity.getTenantDomain(function (tenantDomain) { + var gadgetPath = gadgetLocation.split(PATH_SEPERATOR); + var modifiedPath = ''; + for (var i = 1; i < gadgetPath.length; i++) { + if (i === 3) { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, tenantDomain); + } else { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, gadgetPath[i]) + } + } + callback(modifiedPath); + }); + } else { + callback(gadgetLocation); + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/provider-client.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/provider-client.js new file mode 100644 index 0000000000..6196677f67 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/provider-client.js @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// var registerCallBackforPush; + +(function() { + + var callback; + + /** + * TODO Need to read hostname,port, and tenantId from providerConfig + * @param providerConfig + * @param schema + */ + registerCallBackforPush = function(providerConfig, schema, _callback) { + var streamId = providerConfig['streamName']; + var hostname = window.parent.location.hostname; + var port = window.parent.location.port; + + subscribe(streamId.split(":")[0], streamId.split(":")[1], + '10', + onData, onError, + hostname, + port, + 'WEBSOCKET' + ); + callback = _callback; + }; + + function onData(streamId, data) { + callback(data); + }; + + function onError(error) { + console.error(error); + }; + +}()); + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/realtime-provider-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/realtime-provider-api.js new file mode 100644 index 0000000000..7cf59af776 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/core/realtime-provider-api.js @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, getMode, getSchema, getData, registerCallBackforPush; + +(function() { + + var PROVIDERS_LOCATION = '/extensions/providers/'; + var PROVIDER_NAME = 'realtime'; + + var log = new Log(); + var utils = require('/modules/utils.js'); + var carbon = require("carbon"); + var EventPublisherConstants = Packages.org.wso2.carbon.event.publisher.core.config.EventPublisherConstants; + var eventPublisherService = carbon.server.osgiService('org.wso2.carbon.event.publisher.core.EventPublisherService'); + var eventStreamService = carbon.server.osgiService('org.wso2.carbon.event.stream.core.EventStreamService'); + + var typeMap = { + "bool": "string", + "boolean": "string", + "string": "string", + "int": "number", + "integer": "number", + "long": "number", + "double": "number", + "float": "number", + "time": "time" + }; + + getConfig = function() { + var formConfig = require(PROVIDERS_LOCATION + '/' + PROVIDER_NAME + '/config.json'); + var datasources = []; + try { + var eventPublisherConfigurationList = eventPublisherService.getAllActiveEventPublisherConfigurations(); + for (var i = 0; i < eventPublisherConfigurationList.size(); i++) { + var eventPublisherConfiguration = eventPublisherService.getActiveEventPublisherConfiguration( + eventPublisherConfigurationList.get(i).getEventPublisherName());; + + var mappingTypeIsWso2 = eventPublisherConfiguration.getOutputMapping() + .getMappingType().equals(EventPublisherConstants.EF_WSO2EVENT_MAPPING_TYPE); + + var adapterType = null; + if (eventPublisherConfiguration.getToAdapterConfiguration() != null) { + adapterType = eventPublisherConfiguration.getToAdapterConfiguration().getType(); + } + if (mappingTypeIsWso2 && adapterType.trim() == "ui") { + var streamName = eventPublisherConfiguration.getFromStreamName(); + var streamVersion = eventPublisherConfiguration.getFromStreamVersion(); + var streamId = streamName + ":" + streamVersion; + datasources.push(streamId); + } + } + var datasourceCfg = { + "fieldLabel": "Event Stream", + "fieldName": "streamName", + "fieldType": "dropDown" + }; + datasourceCfg['valueSet'] = datasources; + } catch (e) { + log.error(e); + } + formConfig.config.push(datasourceCfg); + return formConfig; + }; + + /** + * validate the user input of provider configuration + * @param providerConfig + */ + validate = function(providerConfig) { + /* + validate the form and return + + */ + return true; + }; + + /** + * returns the data mode either push or pull + */ + getMode = function() { + return 'push'; + }; + + /** + * returns an array of column names & types + * @param providerConfig + */ + getSchema = function(providerConfig) { + var streamId = providerConfig["streamName"]; + var output = []; + + output.push({ + fieldName: "TIMESTAMP", + fieldType: "time" + }); + + if (eventStreamService != null) { + var eventStreamConfiguration = eventStreamService.getEventStreamConfiguration(streamId); + if (eventStreamConfiguration != null) { + var metaData = eventStreamConfiguration.getStreamDefinition().getMetaData(); + var correlationData = eventStreamConfiguration.getStreamDefinition().getCorrelationData(); + var payloadData = eventStreamConfiguration.getStreamDefinition().getPayloadData(); + if (metaData != null) { + for (var i = 0; i < metaData.size(); i++) { + var type = metaData.get(i).getType().toString().toLowerCase(); + output.push({ + fieldName: metaData.get(i).getName(), + fieldType: typeMap[type.toLowerCase()] + }); + } + } + if (correlationData != null) { + for (var i = 0; i < correlationData.size(); i++) { + var type = correlationData.get(i).getType().toString().toLowerCase(); + output.push({ + fieldName: correlationData.get(i).getName(), + fieldType: typeMap[type.toLowerCase()] + }); + } + } + if (payloadData != null) { + for (var i = 0; i < payloadData.size(); i++) { + var type = payloadData.get(i).getType().toString().toLowerCase(); + output.push({ + fieldName: payloadData.get(i).getName(), + fieldType: typeMap[type.toLowerCase()] + }); + } + } + } + } + return output; + }; + + getData = function(providerConfig,limit) { + var data = []; + return data; + }; + + +}()); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/provider-libs/ws-client.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/provider-libs/ws-client.js new file mode 100644 index 0000000000..4c78cf9d13 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_level_chart_gadget/Android_Battery_Level_Chart/js/provider-libs/ws-client.js @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +var CONSTANTS = { + urlSeperator: '/', + queryParamStreamName : '?streamname=', + queryParamStreamVersion : '&version=', + queryParamLastUpdatedTime : '&lastUpdatedTime=', + urlSecureTransportWebsocket : 'wss://', + urlSecureTransportHttp : 'https://', + colon : ':', + defaultIntervalTime : 10 * 1000, + defaultHostName : 'localhost', + defaultSecurePortNumber : '9443', + defaultMode : 'AUTO', + processModeHTTP : 'HTTP', + processModeWebSocket : 'WEBSOCKET', + processModeAuto : 'AUTO', + numThousand : 1000, + websocketTimeAppender : 400, + websocketSubscriptionEndpoint : 'portal/uipublisher/websocketSubscriptionEndpoint.jag', + httpEventRetrievalEndpoint : 'portal/uipublisher/httpEventRetrievalEndpoint.jag' +}; + + +var websocket = null; +var webSocketUrl; +var httpUrl; +var cepHostName; +var cepPortNumber; +var isErrorOccured = false; +var lastUpdatedtime = -1; +var polingInterval; +var stream; +var streamVersion; +var firstPollingAttempt; +var processMode; +var onSuccessFunction; +var onErrorFunction; +var terminateWebsocketInstance = false; +var pollingContinue = true; + +function subscribe(streamName,version,intervalTime, + listeningFuncSuccessData,listeningFuncErrorData,cepHost,cepPort,mode){ + stopPollingProcesses(); + stream = streamName; + streamVersion = version; + onSuccessFunction = listeningFuncSuccessData; + onErrorFunction = listeningFuncErrorData; + + if(intervalTime == null || intervalTime == ""){ + polingInterval = CONSTANTS.defaultIntervalTime; + } else{ + polingInterval = intervalTime * CONSTANTS.numThousand; + } + + if(cepHost == null || cepHost == ""){ + cepHostName = CONSTANTS.defaultHostName; + } else{ + cepHostName = cepHost; + } + + if(cepPort == null || cepPort == ""){ + cepPortNumber = CONSTANTS.defaultSecurePortNumber; + } else{ + cepPortNumber = cepPort; + } + + if(mode == null || mode == ""){ + processMode = CONSTANTS.defaultMode; + } else{ + processMode = mode; + } + + webSocketUrl = CONSTANTS.urlSecureTransportWebsocket + cepHostName + CONSTANTS.colon + cepPortNumber + + CONSTANTS.urlSeperator + CONSTANTS.websocketSubscriptionEndpoint; + + if(processMode == CONSTANTS.processModeHTTP){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } else{ + initializeWebSocket(webSocketUrl); + } +} + + +/** + * Initializing Web Socket + */ +function initializeWebSocket(webSocketUrl){ + websocket = new WebSocket(webSocketUrl); + websocket.onopen = webSocketOnOpen; + websocket.onmessage = webSocketOnMessage; + websocket.onclose = webSocketOnClose; + websocket.onerror = webSocketOnError; +} + +function getWebsocketSubscriptionMessage(streamName, streamVersion, streamProperties, streamValues) { + if (streamProperties.length === streamValues.length) { + var message = {}; + message.streamName = streamName; + message.streamVersion = streamVersion; + var i; + for (i = 0; i < streamProperties.length; i++) { + message.filterProps = []; + message.filterProps.push({ + 'name': streamProperties[i], + 'value': streamValues[i] + }); + } + return JSON.stringify(message); + } else { + console.log('stream properties and values are not in equal size'); + } +} + +/** + * Web socket On Open + */ + +var webSocketOnOpen = function () { + var filterPropNames = ["meta_deviceId"]; + var filterPropVals = ["htc"]; + var data = getWebsocketSubscriptionMessage(stream, streamVersion, filterPropNames, filterPropVals); + websocket.send(data); +}; + + +/** + * On server sends a message + */ +var webSocketOnMessage = function (evt) { + var event = evt.data; + var array = JSON.parse(event); + constructPayload(array); +}; + +/** + * On server close + */ +var webSocketOnClose =function (e) { + + if(isErrorOccured){ + if(processMode != CONSTANTS.processModeWebSocket){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } + } else{ + if(!terminateWebsocketInstance){ + waitForSocketConnection(websocket); + } else{ + terminateWebsocketInstance = false; + } + + } +}; + +/** + * On server Error + */ +var webSocketOnError = function (err) { + var error = "Error: Cannot connect to Websocket URL:" + webSocketUrl + " .Hence closing the connection!"; + + onErrorFunction(error); + isErrorOccured = true; + +}; + +/** + * Gracefully increments the connection retry + */ +var waitTime = CONSTANTS.numThousand; +function waitForSocketConnection(socket, callback){ + setTimeout( + function () { + if (socket.readyState === 1) { + initializeWebSocket(webSocketUrl); + console.log("Connection is made"); + if(callback != null){ + callback(); + } + return; + } else { + websocket = new WebSocket(webSocketUrl); + waitTime += CONSTANTS.websocketTimeAppender; + waitForSocketConnection(websocket, callback); + } + }, waitTime); +} + +/** + * Polling to retrieve events from http request periodically + */ +function startPoll(){ + + (function poll(){ + setTimeout(function(){ + httpUrl = CONSTANTS.urlSecureTransportHttp + cepHostName + CONSTANTS.colon + cepPortNumber + + CONSTANTS.urlSeperator + CONSTANTS.httpEventRetrievalEndpoint + CONSTANTS.queryParamStreamName + stream + + CONSTANTS.queryParamStreamVersion + streamVersion + CONSTANTS.queryParamLastUpdatedTime + lastUpdatedtime;; + $.getJSON(httpUrl, function(responseText) { + if(firstPollingAttempt){ + /*var data = $("textarea#idConsole").val(); + $("textarea#idConsole").val(data + "Successfully connected to HTTP.");*/ + firstPollingAttempt = false; + } + var eventList = $.parseJSON(responseText.events); + if(eventList.length != 0){ + lastUpdatedtime = responseText.lastEventTime; + for(var i=0;iGzAOJ~3 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 m`d@ZVe7$piCnu+d)Bgt_#n7}!GfHLv0000 + + + + Android_Battery_Level_Chart + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/conf.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/conf.json new file mode 100644 index 0000000000..f8111bc8e1 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/conf.json @@ -0,0 +1,13 @@ +{ + "chart-conf": { + "chart-name": "donut-chart", + "color": "owner", + "gadget-name": "Android Battery Percentage Chart", + "maxLength": "2", + "x": "level" + }, + "provider-conf": { + "provider-name": "realtime", + "streamName": "org.wso2.iot.android.battery:1.0.0" + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/gadget-controller.jag b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/gadget-controller.jag new file mode 100644 index 0000000000..f84538a40a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/gadget-controller.jag @@ -0,0 +1,42 @@ +<% +/** + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +(function () { + + response.contentType = 'application/json'; + var PROVIDER_CONF = 'provider-conf'; + var PROVIDER_NAME = 'provider-name'; + + var action = request.getParameter("action"); + var data = request.getContent(); + var providerConf = data[PROVIDER_CONF]; + var providerAPI = require('js/core/' + providerConf[PROVIDER_NAME] + '-provider-api.js'); + + if (action === 'getSchema') { + print(providerAPI.getSchema(providerConf)); + return; + } else if(action === 'getData'){ + print(providerAPI.getData(providerConf)); + return; + } + +}()); + + +%> diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/gadget.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/gadget.json new file mode 100644 index 0000000000..848a5e7402 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/gadget.json @@ -0,0 +1,9 @@ +{ + "id": "Android_Battery_Percentage_Chart", + "title": "Android Battery Percentage Chart", + "type": "gadget", + "thumbnail": "gadget/Android_Battery_Percentage_Chart/thumbnail.png", + "data": { + "url": "gadget/Android_Battery_Percentage_Chart/gadget.xml" + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/gadget.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/gadget.xml new file mode 100644 index 0000000000..7f87225af1 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/gadget.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ]]> +
+
diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/donut-chart-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/donut-chart-api.js new file mode 100644 index 0000000000..acfd684cdd --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/donut-chart-api.js @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, isProviderRequired, draw, update; + +(function() { + + var CHART_LOCATION = '/extensions/chart-templates/'; + + /** + * return the config to be populated in the chart configuration UI + * @param schema + */ + getConfig = function(schema) { + var chartConf = require(CHART_LOCATION + '/donut-chart/config.json').config; + /* + dynamic logic goes here + */ + return chartConf; + + }; + + /** + * validate the user inout for the chart configuration + * @param chartConfig + */ + validate = function(chartConfig) { + return true; + }; + + /** + * TO be used when provider configuration steps need to be skipped + */ + isProviderRequired = function() { + + } + + + /** + * return the gadget content + * @param chartConfig + * @param schema + * @param data + */ + draw = function(placeholder, chartConfig, _schema, data) { + var schema = toVizGrammarSchema(_schema); + var view = { + id: "chart-0", + schema: schema, + chartConfig: buildChartConfig(chartConfig), + data: function() { + if(data) { + var result = []; + console.log(data); + data.forEach(function(item) { + var row = []; + schema[0].metadata.names.forEach(function(name) { + row.push(item[name]); + }); + result.push(row); + }); + console.log(result); + wso2gadgets.onDataReady(result); + } + } + + }; + + try { + wso2gadgets.init(placeholder, view); + var view = wso2gadgets.load("chart-0"); + } catch (e) { + console.error(e); + } + + }; + + /** + * + * @param data + */ + update = function(data) { + wso2gadgets.onDataReady(data,"append"); + } + + buildChartConfig = function (_chartConfig) { + var conf = {}; + conf.x = _chartConfig.x; + conf.maxLength = _chartConfig.maxLength; + conf.charts = []; + conf.charts[0] = { + type : "arc", + color: _chartConfig.color + }; + conf.tooltip = {"enabled":false} + conf.legend = false; + conf.percentage = true; + conf.colorScale = ["#50B432", "#eefaeb"]; + return conf; + }; + + +}()); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/gadget-core.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/gadget-core.js new file mode 100644 index 0000000000..d87093956a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/gadget-core.js @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +$(function () { + var gadgetLocation; + var conf; + var schema; + var pref = new gadgets.Prefs(); + + var CHART_CONF = 'chart-conf'; + var PROVIDER_CONF = 'provider-conf'; + +var init = function () { + $.ajax({ + url: gadgetLocation + '/conf.json', + method: "GET", + contentType: "application/json", + async: false, + success: function (data) { + conf = JSON.parse(data); + $.ajax({ + url: gadgetLocation + '/gadget-controller.jag?action=getSchema', + method: "POST", + data: JSON.stringify(conf), + contentType: "application/json", + async: false, + success: function (data) { + schema = data; + } + }); + + } + }); +}; + + +var drawGadget = function (){ + + draw('#canvas', conf[CHART_CONF], schema, null); + registerCallBackforPush(conf[PROVIDER_CONF], schema, function(providerData) { + var dummyData = jQuery.extend(true, {}, providerData[0]); + providerData[0][1] = "YES"; + dummyData[4] = (100 - dummyData[4]); + dummyData[1] = "NO"; + providerData.push(dummyData); + update(providerData); + }); + +}; + +getGadgetLocation(function (gadget_Location) { + gadgetLocation = gadget_Location; + init(); + drawGadget(); + +}); +}); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/gadget-util.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/gadget-util.js new file mode 100644 index 0000000000..0a76ceef03 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/gadget-util.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getGadgetLocation = function (callback) { + var gadgetLocation = "/portal/store/carbon.super/fs/gadget/Android_Battery_Percentage_Chart"; + var PATH_SEPERATOR = "/"; + if (gadgetLocation.search("store") != -1) { + wso2.gadgets.identity.getTenantDomain(function (tenantDomain) { + var gadgetPath = gadgetLocation.split(PATH_SEPERATOR); + var modifiedPath = ''; + for (var i = 1; i < gadgetPath.length; i++) { + if (i === 3) { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, tenantDomain); + } else { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, gadgetPath[i]) + } + } + callback(modifiedPath); + }); + } else { + callback(gadgetLocation); + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/provider-client.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/provider-client.js new file mode 100644 index 0000000000..6196677f67 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/provider-client.js @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// var registerCallBackforPush; + +(function() { + + var callback; + + /** + * TODO Need to read hostname,port, and tenantId from providerConfig + * @param providerConfig + * @param schema + */ + registerCallBackforPush = function(providerConfig, schema, _callback) { + var streamId = providerConfig['streamName']; + var hostname = window.parent.location.hostname; + var port = window.parent.location.port; + + subscribe(streamId.split(":")[0], streamId.split(":")[1], + '10', + onData, onError, + hostname, + port, + 'WEBSOCKET' + ); + callback = _callback; + }; + + function onData(streamId, data) { + callback(data); + }; + + function onError(error) { + console.error(error); + }; + +}()); + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/realtime-provider-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/realtime-provider-api.js new file mode 100644 index 0000000000..7cf59af776 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/core/realtime-provider-api.js @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, getMode, getSchema, getData, registerCallBackforPush; + +(function() { + + var PROVIDERS_LOCATION = '/extensions/providers/'; + var PROVIDER_NAME = 'realtime'; + + var log = new Log(); + var utils = require('/modules/utils.js'); + var carbon = require("carbon"); + var EventPublisherConstants = Packages.org.wso2.carbon.event.publisher.core.config.EventPublisherConstants; + var eventPublisherService = carbon.server.osgiService('org.wso2.carbon.event.publisher.core.EventPublisherService'); + var eventStreamService = carbon.server.osgiService('org.wso2.carbon.event.stream.core.EventStreamService'); + + var typeMap = { + "bool": "string", + "boolean": "string", + "string": "string", + "int": "number", + "integer": "number", + "long": "number", + "double": "number", + "float": "number", + "time": "time" + }; + + getConfig = function() { + var formConfig = require(PROVIDERS_LOCATION + '/' + PROVIDER_NAME + '/config.json'); + var datasources = []; + try { + var eventPublisherConfigurationList = eventPublisherService.getAllActiveEventPublisherConfigurations(); + for (var i = 0; i < eventPublisherConfigurationList.size(); i++) { + var eventPublisherConfiguration = eventPublisherService.getActiveEventPublisherConfiguration( + eventPublisherConfigurationList.get(i).getEventPublisherName());; + + var mappingTypeIsWso2 = eventPublisherConfiguration.getOutputMapping() + .getMappingType().equals(EventPublisherConstants.EF_WSO2EVENT_MAPPING_TYPE); + + var adapterType = null; + if (eventPublisherConfiguration.getToAdapterConfiguration() != null) { + adapterType = eventPublisherConfiguration.getToAdapterConfiguration().getType(); + } + if (mappingTypeIsWso2 && adapterType.trim() == "ui") { + var streamName = eventPublisherConfiguration.getFromStreamName(); + var streamVersion = eventPublisherConfiguration.getFromStreamVersion(); + var streamId = streamName + ":" + streamVersion; + datasources.push(streamId); + } + } + var datasourceCfg = { + "fieldLabel": "Event Stream", + "fieldName": "streamName", + "fieldType": "dropDown" + }; + datasourceCfg['valueSet'] = datasources; + } catch (e) { + log.error(e); + } + formConfig.config.push(datasourceCfg); + return formConfig; + }; + + /** + * validate the user input of provider configuration + * @param providerConfig + */ + validate = function(providerConfig) { + /* + validate the form and return + + */ + return true; + }; + + /** + * returns the data mode either push or pull + */ + getMode = function() { + return 'push'; + }; + + /** + * returns an array of column names & types + * @param providerConfig + */ + getSchema = function(providerConfig) { + var streamId = providerConfig["streamName"]; + var output = []; + + output.push({ + fieldName: "TIMESTAMP", + fieldType: "time" + }); + + if (eventStreamService != null) { + var eventStreamConfiguration = eventStreamService.getEventStreamConfiguration(streamId); + if (eventStreamConfiguration != null) { + var metaData = eventStreamConfiguration.getStreamDefinition().getMetaData(); + var correlationData = eventStreamConfiguration.getStreamDefinition().getCorrelationData(); + var payloadData = eventStreamConfiguration.getStreamDefinition().getPayloadData(); + if (metaData != null) { + for (var i = 0; i < metaData.size(); i++) { + var type = metaData.get(i).getType().toString().toLowerCase(); + output.push({ + fieldName: metaData.get(i).getName(), + fieldType: typeMap[type.toLowerCase()] + }); + } + } + if (correlationData != null) { + for (var i = 0; i < correlationData.size(); i++) { + var type = correlationData.get(i).getType().toString().toLowerCase(); + output.push({ + fieldName: correlationData.get(i).getName(), + fieldType: typeMap[type.toLowerCase()] + }); + } + } + if (payloadData != null) { + for (var i = 0; i < payloadData.size(); i++) { + var type = payloadData.get(i).getType().toString().toLowerCase(); + output.push({ + fieldName: payloadData.get(i).getName(), + fieldType: typeMap[type.toLowerCase()] + }); + } + } + } + } + return output; + }; + + getData = function(providerConfig,limit) { + var data = []; + return data; + }; + + +}()); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/provider-libs/ws-client.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/provider-libs/ws-client.js new file mode 100644 index 0000000000..6d7f393c26 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_percentage_chart_gadget/Android_Battery_Percentage_Chart/js/provider-libs/ws-client.js @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +var CONSTANTS = { + urlSeperator: '/', + queryParamStreamName : '?streamname=', + queryParamStreamVersion : '&version=', + queryParamLastUpdatedTime : '&lastUpdatedTime=', + urlSecureTransportWebsocket : 'wss://', + urlSecureTransportHttp : 'https://', + colon : ':', + defaultIntervalTime : 10 * 1000, + defaultHostName : 'localhost', + defaultSecurePortNumber : '9443', + defaultMode : 'AUTO', + processModeHTTP : 'HTTP', + processModeWebSocket : 'WEBSOCKET', + processModeAuto : 'AUTO', + numThousand : 1000, + websocketTimeAppender : 400, + websocketSubscriptionEndpoint : 'portal/uipublisher/websocketSubscriptionEndpoint.jag', + httpEventRetrievalEndpoint : 'portal/uipublisher/httpEventRetrievalEndpoint.jag' +}; + + +var websocket = null; +var webSocketUrl; +var httpUrl; +var cepHostName; +var cepPortNumber; +var isErrorOccured = false; +var lastUpdatedtime = -1; +var polingInterval; +var stream; +var streamVersion; +var firstPollingAttempt; +var processMode; +var onSuccessFunction; +var onErrorFunction; +var terminateWebsocketInstance = false; +var pollingContinue = true; + +function subscribe(streamName,version,intervalTime, + listeningFuncSuccessData,listeningFuncErrorData,cepHost,cepPort,mode){ + stopPollingProcesses(); + stream = streamName; + streamVersion = version; + onSuccessFunction = listeningFuncSuccessData; + onErrorFunction = listeningFuncErrorData; + + if(intervalTime == null || intervalTime == ""){ + polingInterval = CONSTANTS.defaultIntervalTime; + } else{ + polingInterval = intervalTime * CONSTANTS.numThousand; + } + + if(cepHost == null || cepHost == ""){ + cepHostName = CONSTANTS.defaultHostName; + } else{ + cepHostName = cepHost; + } + + if(cepPort == null || cepPort == ""){ + cepPortNumber = CONSTANTS.defaultSecurePortNumber; + } else{ + cepPortNumber = cepPort; + } + + if(mode == null || mode == ""){ + processMode = CONSTANTS.defaultMode; + } else{ + processMode = mode; + } + + webSocketUrl = CONSTANTS.urlSecureTransportWebsocket + cepHostName + CONSTANTS.colon + cepPortNumber + + CONSTANTS.urlSeperator + CONSTANTS.websocketSubscriptionEndpoint; + + if(processMode == CONSTANTS.processModeHTTP){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } else{ + initializeWebSocket(webSocketUrl); + } +} + + +/** + * Initializing Web Socket + */ +function initializeWebSocket(webSocketUrl){ + websocket = new WebSocket(webSocketUrl); + websocket.onopen = webSocketOnOpen; + websocket.onmessage = webSocketOnMessage; + websocket.onclose = webSocketOnClose; + websocket.onerror = webSocketOnError; +} + +function getWebsocketSubscriptionMessage(streamName, streamVersion, streamProperties, streamValues) { + if (streamProperties.length === streamValues.length) { + var message = {}; + message.streamName = streamName; + message.streamVersion = streamVersion; + var i; + for (i = 0; i < streamProperties.length; i++) { + message.filterProps = []; + message.filterProps.push({ + 'name': streamProperties[i], + 'value': streamValues[i] + }); + } + return JSON.stringify(message); + } else { + console.log('stream properties and values are not in equal size'); + } +} + +/** + * Web socket On Open + */ + +var webSocketOnOpen = function () { + var filterPropNames = ["meta_deviceId"]; + var filterPropVals = ["htc"]; + var data = getWebsocketSubscriptionMessage(stream, streamVersion, filterPropNames, filterPropVals); + websocket.send(data); +}; + +/** + * On server sends a message + */ +var webSocketOnMessage = function (evt) { + var event = evt.data; + var array = JSON.parse(event); + constructPayload(array); +}; + +/** + * On server close + */ +var webSocketOnClose =function (e) { + + if(isErrorOccured){ + if(processMode != CONSTANTS.processModeWebSocket){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } + } else{ + if(!terminateWebsocketInstance){ + waitForSocketConnection(websocket); + } else{ + terminateWebsocketInstance = false; + } + + } +}; + +/** + * On server Error + */ +var webSocketOnError = function (err) { + var error = "Error: Cannot connect to Websocket URL:" + webSocketUrl + " .Hence closing the connection!"; + + onErrorFunction(error); + isErrorOccured = true; + +}; + +/** + * Gracefully increments the connection retry + */ +var waitTime = CONSTANTS.numThousand; +function waitForSocketConnection(socket, callback){ + setTimeout( + function () { + if (socket.readyState === 1) { + initializeWebSocket(webSocketUrl); + console.log("Connection is made"); + if(callback != null){ + callback(); + } + return; + } else { + websocket = new WebSocket(webSocketUrl); + waitTime += CONSTANTS.websocketTimeAppender; + waitForSocketConnection(websocket, callback); + } + }, waitTime); +} + +/** + * Polling to retrieve events from http request periodically + */ +function startPoll(){ + + (function poll(){ + setTimeout(function(){ + httpUrl = CONSTANTS.urlSecureTransportHttp + cepHostName + CONSTANTS.colon + cepPortNumber + + CONSTANTS.urlSeperator + CONSTANTS.httpEventRetrievalEndpoint + CONSTANTS.queryParamStreamName + stream + + CONSTANTS.queryParamStreamVersion + streamVersion + CONSTANTS.queryParamLastUpdatedTime + lastUpdatedtime;; + $.getJSON(httpUrl, function(responseText) { + if(firstPollingAttempt){ + /*var data = $("textarea#idConsole").val(); + $("textarea#idConsole").val(data + "Successfully connected to HTTP.");*/ + firstPollingAttempt = false; + } + var eventList = $.parseJSON(responseText.events); + if(eventList.length != 0){ + lastUpdatedtime = responseText.lastEventTime; + for(var i=0;i1pp590RX-<0D!;6x70fE0bx|u(@ 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 wzA~_K@v*Wl(Z{;}FMzeJvAL=H{{?*I + + + + Android_Battery_Percentage_Chart + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_streams/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_streams/artifact.xml new file mode 100644 index 0000000000..3719bc8507 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_streams/artifact.xml @@ -0,0 +1,23 @@ + + + + + org.wso2.iot.android.battery_1.0.0.json + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_streams/org.wso2.iot.android.battery_1.0.0.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_streams/org.wso2.iot.android.battery_1.0.0.json new file mode 100755 index 0000000000..ed7e250290 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_streams/org.wso2.iot.android.battery_1.0.0.json @@ -0,0 +1,38 @@ +{ + "name": "org.wso2.iot.android.battery", + "version": "1.0.0", + "nickName": "", + "description": "Intermediate stream to map Android sense stream to battery execution plan", + "metaData": [ + { + "name": "owner", + "type": "STRING" + }, + { + "name": "deviceId", + "type": "STRING" + }, + { + "name": "timestamp", + "type": "LONG" + } + ], + "payloadData": [ + { + "name": "level", + "type": "INT" + }, + { + "name": "state", + "type": "STRING" + }, + { + "name": "status", + "type": "STRING" + }, + { + "name": "temperature", + "type": "INT" + } + ] +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_ui_event_publisher/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_ui_event_publisher/artifact.xml new file mode 100644 index 0000000000..db31853582 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_ui_event_publisher/artifact.xml @@ -0,0 +1,23 @@ + + + + + org.wso2.iot.android.battery.ui.publisher.xml + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_ui_event_publisher/org.wso2.iot.android.battery.ui.publisher.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_ui_event_publisher/org.wso2.iot.android.battery.ui.publisher.xml new file mode 100755 index 0000000000..53b3c7963b --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_battery_ui_event_publisher/org.wso2.iot.android.battery.ui.publisher.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_script/AndriodCallScript.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_script/AndriodCallScript.xml new file mode 100644 index 0000000000..7f26e785bd --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_script/AndriodCallScript.xml @@ -0,0 +1,19 @@ + + + true + AndriodCallScript + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_script/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_script/artifact.xml new file mode 100644 index 0000000000..b2714b2722 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_script/artifact.xml @@ -0,0 +1,23 @@ + + + + + AndriodCallScript.xml + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_event_sink/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_event_sink/artifact.xml new file mode 100644 index 0000000000..a4f159907d --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_event_sink/artifact.xml @@ -0,0 +1,23 @@ + + + + + org_wso2_iot_android_call_stats.xml + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_event_sink/org_wso2_iot_android_call_stats.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_event_sink/org_wso2_iot_android_call_stats.xml new file mode 100755 index 0000000000..31efefe2b4 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_event_sink/org_wso2_iot_android_call_stats.xml @@ -0,0 +1,98 @@ + + + + + meta_owner + false + false + false + false + STRING + + + meta_deviceId + false + false + false + false + STRING + + + meta_timestamp + false + false + false + false + LONG + + + number + false + false + false + false + STRING + + + type + false + false + false + false + STRING + + + duration + false + false + false + false + LONG + + + year + false + false + false + false + INTEGER + + + month + false + false + false + false + INTEGER + + + day + false + false + false + false + INTEGER + + + hour + false + false + false + false + INTEGER + + + minute + false + false + false + false + INTEGER + + + + org.wso2.iot.android.call.stats:1.0.0 + + false + PROCESSED_DATA_STORE + \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_streams/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_streams/artifact.xml new file mode 100644 index 0000000000..16209684e9 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_streams/artifact.xml @@ -0,0 +1,23 @@ + + + + + org.wso2.iot.android.call.stats_1.0.0.json + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_streams/org.wso2.iot.android.call.stats_1.0.0.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_streams/org.wso2.iot.android.call.stats_1.0.0.json new file mode 100755 index 0000000000..e73e470913 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_streams/org.wso2.iot.android.call.stats_1.0.0.json @@ -0,0 +1,54 @@ +{ + "name": "org.wso2.iot.android.call.stats", + "version": "1.0.0", + "nickName": "", + "description": "", + "metaData": [ + { + "name": "owner", + "type": "STRING" + }, + { + "name": "deviceId", + "type": "STRING" + }, + { + "name": "timestamp", + "type": "LONG" + } + ], + "payloadData": [ + { + "name": "number", + "type": "STRING" + }, + { + "name": "type", + "type": "STRING" + }, + { + "name": "duration", + "type": "LONG" + }, + { + "name": "year", + "type": "INT" + }, + { + "name": "month", + "type": "INT" + }, + { + "name": "day", + "type": "INT" + }, + { + "name": "hour", + "type": "INT" + }, + { + "name": "minute", + "type": "INT" + } + ] +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_ui_event_publisher/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_ui_event_publisher/artifact.xml new file mode 100644 index 0000000000..2b96ad8a21 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_ui_event_publisher/artifact.xml @@ -0,0 +1,23 @@ + + + + + org.wso2.iot.android.call.stats.ui.publisher.xml + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_ui_event_publisher/org.wso2.iot.android.call.stats.ui.publisher.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_ui_event_publisher/org.wso2.iot.android.call.stats.ui.publisher.xml new file mode 100644 index 0000000000..6237873a42 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_stats_ui_event_publisher/org.wso2.iot.android.call.stats.ui.publisher.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_streams/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_streams/artifact.xml new file mode 100644 index 0000000000..46b4d77a3f --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_streams/artifact.xml @@ -0,0 +1,23 @@ + + + + + org.wso2.iot.android.call_1.0.0.json + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_streams/org.wso2.iot.android.call_1.0.0.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_streams/org.wso2.iot.android.call_1.0.0.json new file mode 100755 index 0000000000..7cd2501e47 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_streams/org.wso2.iot.android.call_1.0.0.json @@ -0,0 +1,38 @@ +{ + "name": "org.wso2.iot.android.call", + "version": "1.0.0", + "nickName": "", + "description": "", + "metaData": [ + { + "name": "owner", + "type": "STRING" + }, + { + "name": "deviceId", + "type": "STRING" + }, + { + "name": "timestamp", + "type": "LONG" + } + ], + "payloadData": [ + { + "name": "number", + "type": "STRING" + }, + { + "name": "type", + "type": "STRING" + }, + { + "name": "startTime", + "type": "LONG" + }, + { + "name": "endTime", + "type": "LONG" + } + ] +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/conf.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/conf.json new file mode 100644 index 0000000000..9ecb746d00 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/conf.json @@ -0,0 +1,15 @@ +{ + "chart-conf": { + "chart-name": "donut-chart", + "color": "type", + "gadget-name": "Android Call Time Chart", + "maxLength": "2", + "x": "duration" + }, + "provider-conf": { + "limit": "2", + "provider-name": "batch", + "query": "", + "tableName": "ANDROID_CALL_STAT_PER_DAY" + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/gadget-controller.jag b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/gadget-controller.jag new file mode 100644 index 0000000000..f84538a40a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/gadget-controller.jag @@ -0,0 +1,42 @@ +<% +/** + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +(function () { + + response.contentType = 'application/json'; + var PROVIDER_CONF = 'provider-conf'; + var PROVIDER_NAME = 'provider-name'; + + var action = request.getParameter("action"); + var data = request.getContent(); + var providerConf = data[PROVIDER_CONF]; + var providerAPI = require('js/core/' + providerConf[PROVIDER_NAME] + '-provider-api.js'); + + if (action === 'getSchema') { + print(providerAPI.getSchema(providerConf)); + return; + } else if(action === 'getData'){ + print(providerAPI.getData(providerConf)); + return; + } + +}()); + + +%> diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/gadget.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/gadget.json new file mode 100644 index 0000000000..6b7c4e52dd --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/gadget.json @@ -0,0 +1,9 @@ +{ + "id": "Android_Call_Time_Chart", + "title": "Android Call Time Chart", + "type": "gadget", + "thumbnail": "gadget/Android_Call_Time_Chart/thumbnail.png", + "data": { + "url": "gadget/Android_Call_Time_Chart/gadget.xml" + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/gadget.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/gadget.xml new file mode 100644 index 0000000000..20cba23be3 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/gadget.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ]]> +
+
diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/batch-provider-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/batch-provider-api.js new file mode 100644 index 0000000000..30c96902a5 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/batch-provider-api.js @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, getMode, getSchema, getData, registerCallBackforPush; + +(function() { + + var PROVIDERS_LOCATION = '/extensions/providers/'; + + var PROVIDER_NAME = 'batch'; + var TYPE = "type"; + var TABLE_NAME = "tableName"; + var HTTPS_TRANSPORT = "https"; + var CONTENT_TYPE_JSON = "application/json"; + var AUTHORIZATION_HEADER = "Authorization"; + var USER_TOKEN = "user"; + var TENANT_DOMAIN = "domain"; + var CONST_AT = "@"; + var USERNAME = "username"; + var HTTP_USER_NOT_AUTHENTICATED = 403; + var JS_MAX_VALUE = "9007199254740992"; + var JS_MIN_VALUE = "-9007199254740992"; + + var typeMap = { + "bool" : "string", + "boolean" : "string", + "string" : "string", + "int" : "number", + "integer" : "number", + "long" : "number", + "double" : "number", + "float" : "number", + "time": "time" + }; + + var log = new Log(); + var carbon = require('carbon'); + var configs = require('/configs/designer.json'); + var utils = require('/modules/utils.js'); + var JSUtils = Packages.org.wso2.carbon.analytics.jsservice.Utils; + var AnalyticsCachedJSServiceConnector = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector; + var AnalyticsCache = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector.AnalyticsCache; + var cacheTimeoutSeconds = 5; + var loggedInUser = null; + + if (configs.cacheTimeoutSeconds) { + cacheTimeoutSeconds = parseInt(configs.cacheTimeoutSeconds); + } + var cacheSizeBytes = 1024 * 1024 * 1024; // 1GB + if (configs.cacheSizeBytes) { + cacheSizeBytes = parseInt(configs.cacheSizeBytes); + } + response.contentType = CONTENT_TYPE_JSON; + + var authParam = request.getHeader(AUTHORIZATION_HEADER); + if (authParam != null) { + credentials = JSUtils.authenticate(authParam); + loggedInUser = credentials[0]; + } else { + var token = session.get(USER_TOKEN); + if (token != null) { + loggedInUser = token[USERNAME] + CONST_AT + token[TENANT_DOMAIN]; + } else { + log.error("user is not authenticated!"); + response.status = HTTP_USER_NOT_AUTHENTICATED; + print('{ "status": "Failed", "message": "User is not authenticated." }'); + return; + } + } + + var cache = application.get("AnalyticsWebServiceCache"); + if (cache == null) { + cache = new AnalyticsCache(cacheTimeoutSeconds, cacheSizeBytes); + application.put("AnalyticsWebServiceCache", cache); + } + var connector = new AnalyticsCachedJSServiceConnector(cache); + + /** + * require the existing config.json and push any dynamic fields that needs to be populated in the UI + */ + getConfig = function() { + var formConfig = require(PROVIDERS_LOCATION + '/' + PROVIDER_NAME + '/config.json'); + var tables; + try { + tables = JSON.parse(connector.getTableList(loggedInUser).getMessage()); + } catch (e) { + log.error(e); + } + var configs = formConfig.config; + configs.forEach(function(config) { + if (config.fieldName === TABLE_NAME) { + config.valueSet = tables; + } + }); + return formConfig; + } + + /** + * validate the user input of provider configuration + * @param providerConfig + */ + validate = function(providerConfig) { + /* + validate the form and return + + */ + return true; + } + + /** + * returns the data mode either push or pull + */ + getMode = function() { + return "PULL"; + } + + /** + * returns an array of column names & types + * @param providerConfig + */ + getSchema = function(providerConfig) { + var schema = []; + var tableName = providerConfig["tableName"]; + var result = connector.getTableSchema(loggedInUser, tableName).getMessage(); + result = JSON.parse(result); + + var columns = result.columns; + Object.getOwnPropertyNames(columns).forEach(function(name, idx, array) { + var type = "ordinal"; + if(columns[name]['type']) { + type = columns[name]['type']; + } + schema.push({ + fieldName: name, + fieldType: typeMap[type.toLowerCase()] + }); + }); + // log.info(schema); + return schema; + }; + + /** + * returns the actual data + * @param providerConfig + * @param limit + */ + getData = function(providerConfig, limit) { + var tableName = providerConfig.tableName; + var query = providerConfig.query; + var limit = 100; + if (providerConfig.limit) { + limit = providerConfig.limit; + } + var result; + //if there's a filter present, we should perform a Lucene search instead of reading the table + if (query) { + var filter = { + "query": query, + "start": 0, + "count": limit + }; + result = connector.search(loggedInUser, tableName, stringify(filter)).getMessage(); + } else { + var from = JS_MIN_VALUE; + var to = JS_MAX_VALUE; + result = connector.getRecordsByRange(loggedInUser, tableName, from, to, 0, limit, null).getMessage(); + + } + result = JSON.parse(result); + var data = []; + for (var i = 0; i < result.length; i++) { + var values = result[i].values; + data.push(values); + } + return data; + }; + +}()); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/donut-chart-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/donut-chart-api.js new file mode 100644 index 0000000000..0a4278939a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/donut-chart-api.js @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, isProviderRequired, draw, update; + +(function() { + + var CHART_LOCATION = '/extensions/chart-templates/'; + + /** + * return the config to be populated in the chart configuration UI + * @param schema + */ + getConfig = function(schema) { + var chartConf = require(CHART_LOCATION + '/donut-chart/config.json').config; + /* + dynamic logic goes here + */ + return chartConf; + + }; + + /** + * validate the user inout for the chart configuration + * @param chartConfig + */ + validate = function(chartConfig) { + return true; + }; + + /** + * TO be used when provider configuration steps need to be skipped + */ + isProviderRequired = function() { + + } + + + /** + * return the gadget content + * @param chartConfig + * @param schema + * @param data + */ + draw = function(placeholder, chartConfig, _schema, data) { + var schema = toVizGrammarSchema(_schema); + var view = { + id: "chart-0", + schema: schema, + chartConfig: buildChartConfig(chartConfig), + data: function() { + if(data) { + var result = []; + data.forEach(function(item) { + var row = []; + schema[0].metadata.names.forEach(function(name) { + row.push(item[name]); + }); + result.push(row); + }); + wso2gadgets.onDataReady(result); + } + } + + }; + + try { + wso2gadgets.init(placeholder, view); + var view = wso2gadgets.load("chart-0"); + } catch (e) { + console.error(e); + } + + }; + + /** + * + * @param data + */ + update = function(data) { + wso2gadgets.onDataReady(data,"append"); + } + + buildChartConfig = function (_chartConfig) { + var conf = {}; + conf.x = _chartConfig.x; + conf.maxLength = _chartConfig.maxLength; + conf.charts = []; + conf.charts[0] = { + type : "arc", + color: _chartConfig.color, + mode: "donut" + }; + conf.legendOffset = -30; + conf.colorScale = ["#50B432", "#6699ff"]; + return conf; + }; + + +}()); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/gadget-core.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/gadget-core.js new file mode 100644 index 0000000000..4745da79e6 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/gadget-core.js @@ -0,0 +1,99 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +$(function () { + var gadgetLocation; + var conf; + var schema; + var pref = new gadgets.Prefs(); + + var refreshInterval; + var providerData; + + var CHART_CONF = 'chart-conf'; + var PROVIDER_CONF = 'provider-conf'; + + var REFRESH_INTERVAL = 'refreshInterval'; + +var init = function () { + $.ajax({ + url: gadgetLocation + '/conf.json', + method: "GET", + contentType: "application/json", + async: false, + success: function (data) { + conf = JSON.parse(data); + $.ajax({ + url: gadgetLocation + '/gadget-controller.jag?action=getSchema', + method: "POST", + data: JSON.stringify(conf), + contentType: "application/json", + async: false, + success: function (data) { + schema = data; + } + }); + + getProviderData(); + + } + }); +}; + +var getProviderData = function (){ + $.ajax({ + url: gadgetLocation + '/gadget-controller.jag?action=getData', + method: "POST", + data: JSON.stringify(conf), + contentType: "application/json", + async: false, + success: function (data) { + if(data.length == 2) { + data[0].duration = data[0].duration / 60000; // Convert to minutes + data[1].duration = data[1].duration / 60000; // Convert to minutes + + if(data[0].timestamp == data[1].timestamp) { + providerData = data; + } else if(data[0].timestamp > data[1].timestamp) { + providerData = [data[0]]; + } else { + providerData = [data[1]]; + } + } else { + data[0].duration = data[0].duration / 60000; // Convert to minutes + providerData = data; + } + } + }); + return providerData; +}; + + +var drawGadget = function (){ + + draw('#canvas', conf[CHART_CONF], schema, providerData); + setInterval(function() { + draw('#canvas', conf[CHART_CONF], schema, getProviderData()); + },pref.getInt(REFRESH_INTERVAL)); + +}; + +getGadgetLocation(function (gadget_Location) { + gadgetLocation = gadget_Location; + init(); + drawGadget(); + +}); +}); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/gadget-util.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/gadget-util.js new file mode 100644 index 0000000000..bdf0103f36 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/js/core/gadget-util.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getGadgetLocation = function (callback) { + var gadgetLocation = "/portal/store/carbon.super/fs/gadget/Android_Call_Time_Chart"; + var PATH_SEPERATOR = "/"; + if (gadgetLocation.search("store") != -1) { + wso2.gadgets.identity.getTenantDomain(function (tenantDomain) { + var gadgetPath = gadgetLocation.split(PATH_SEPERATOR); + var modifiedPath = ''; + for (var i = 1; i < gadgetPath.length; i++) { + if (i === 3) { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, tenantDomain); + } else { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, gadgetPath[i]) + } + } + callback(modifiedPath); + }); + } else { + callback(gadgetLocation); + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/thumbnail.png b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/Android_Call_Time_Chart/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..41f8924dc0a420c495bd995e73a2cdbbd06bbf86 GIT binary patch literal 13565 zcmajGV{~NC*9MyISQFc}ZQGc5V%rl;lFr2DB$?Qn*tTuk6JuiC{{8Q#cij(nb@!>& zr`E1IXYbm2YFC7+vJ5f;J^};;1hSm0q&m1A`R@k@1HM-3RAqx3C@V1~F$jp-IK(#- zXz+hhGg);d2nZi)2nbLx1jGyY7U%>5!h;n8;?x)df?SCO-&Ho0b{BlBMI^O z-zT@TBnf;6)?H3X3U&t`9+4EwFu2|Y0)i7DCn=`swRX|zooTS>ef%!;xMcWEf#o!1 zp>i%VI9?~loWLx;H_aqQY-k4x#Z!=YSYc~oAn7~%gE{-}-(FkMM(c9+!Mb}ZUsf#9 zGGcCkxEaQ%#z^5(xt)!TK1R0HzSA558}zfX-xe1uPphg!ZTwQbnqd2Zr?ElLFlXpU~3LY*>8M&^DslSo_pa>E0e# zSs^GvkUenM*fX$%gpX^etO({1o`#-2jU;MH1?55@J<28v2HM3h6@5(tvp!_oKcveuy7i{1P;n>hxF36l) zF;}A_Dur-|bi=nmDfi)w5@onEv9h?V^bfm5(CW5w2c6B3_T~wlOC5}ZxaXgf1*WWWgz7Um(OXhIj5-yh8Ze*u9~EEb%29KVMo$#)<%*~T z?Uy?}(r2B%kR>bfI{1V;kQlE8YpEQzx)Age`KYf!R#B$3Zsag z40oUU>zgA0#ETo!4QR!A;)^9n0lhTQx_wW~gsRoQlsR@yBUaHot|QSbwF5<=>grt7 z{u#^S}oL8yEm+QiG-2OUIJ6AJ<|<3UL?~6^=+DK+{zl ze{_#t!-C`OeN!e(_<=%WShnh#vZ_y1g<88#Y?=p$D~&n+fvdM2RM{OoB7Z7I*ccb6 z(fPLRyrjwvxvN3EIYk%eSpBe4tf-_^YO(DNg*0E3bmKOAYtzsLfYbCfz$$5C8o3#8 zF-^MKNv>N+UjK>#jBsd0Nd`n}+52JW1>h%eHL`!uX&3CEGZ=rBWkA_H4tQ z_8#oa%{aHY!*n-b#HOnVC~ySE{?!S!70y}P*Pwpv4Hb^}^(Y`>-?bC!q?J06@6dFx zX#>$3rRkl`{xt{f8TC$y@D7p189J6~70K%;eVoe*3jOs+D0f1OGazteo1!j-&w3YM zlMp)d%MXkvAnI=g^0F7G=*>I3lQYQvlfI_z=nb?xs16~?-w7-;s3J?Et?4QKUkXlILMdx zIAyF^yImlcA-93t5asFQWm~}w4ydgVmED0Ot6vFZf?C4?20!Z^Z;yGuX_xm^43pM6 zZ9zKntUQERzc;>x7Q^iS?q(Z-R{@sTe~9dI#-`n;nQMKkSeevUGpvrV@WZV9gimm@ zymus6z(?@nxmM|E1hK7OE}ggO$kUBl@)X=JgQ|4j&tV!P`{;5$eLlKLb_PBMIEE^8 z<5wmh15Xf9pY`$gtXVx$fJT6+3?&BkeKy&y9aMuV#F>|~n6v^Ud^TA&1h!F}QP@ik zqNIt^|3rw;-@oJ9iBtL6MHUM~69L?U`~gV=Ex3P1$#G^%g^n7N9lB&>Q|L;d86VTL zooJ+(DQ7t_sCRefS7_)*j8u;}{vz#<<~+6FH|dSfti@-&<4E}ZY(%kDkAvMtV?9SA zSc~yYA^fdZ(N8(ZJ0?&A@Rk#J0`A7jX{lv;%o8NeL4UWAbSzY>+A==6hTs7NAbDAd zQ(|Gso*%vTIMa#j4s5H8gr|Jilp)K4ad47680XsFtPx|X zMSWt}u`ji^{NsvEnE;XFWZ|E2zP9Qwj(j9^7T66)`Ffj=h4w#vovfKR7GtjJ>$jN^ z1&{!R5jnq(MP@dLnl^8s2?~Q-JmMxNrpq`3RkCM+M|&@=~__S2x}s zTTvT|DaWxz3;Brk%vo!-f4;LP85(`P4hsv3-ri5@<3}u*hMfnP%C4kscZw|u6)~Jj z{xV%U+;4}!K%mr<1IU_x-lqdkbr!U9k58H-dQf4z?HvST;mSPqGLpP3J%&9pRyj?+ ziez4YB{Lqw8^w-{zW_Ac+2?IXE5WQuWs2XJm7q-(h;#@L3^29~f@vJUCrnVJGiFgB zRdDiylPl?6B5)atB;YKS5}v?(tV^Xr9ko>T4}hBG;Tl^ZSYSnTsnfI2PpE^+*V7j} zLm|K2wcR!ef}t7p=qYyH7AzA@*?K^Yj+LH$;ozKWL$=K!y~ZOoh|SEMFJXSBpqN9snVS1z}rLMhTK(i@(_{L?eO19?0pASV{PhP|n?hy3LSA?9T^nnQ6 zVZscv#j~0bi9qQ&{=Rbq1yVo*dyjUTncP12J^R`FUv=ad2>(ehGjx9S+*XoX`&AjA zGmWguEU_MyrioN9X!;n)EMe}_c$F^}gl7sL`^N&?w|@Xw>rhhxN4`8`O|X{h&*oeq zTev`=ENKT)3a==8Aksv{dz{a$;)_A=eSrs#!X7i*zw#@a(r7V}gP48-1w;GHXgB2Z z?z)}AiT}C2=DhSV9j()6Nk%6$uPCZ@ZN5<=N!*c(&6yckYnz@kv-WR1G zcV6mKt)I^kS6#s!4z?l1g)1jply}3Pdf3p84cH|Do7$J$`fYgs`6A)!Wt#`9BNB2WobE0>v5!Rj7wO#ZtsO7MXEp?|7CnBv?4TR z9ro=Nf|3RxJ8+(aSvfyKzDM>niIpuL=oc+e=;f}OxhlJX6!`lpY;X72Fv%5Zqi+IW z#b-EMjK$yxo{l@;DILDe-q0Dhp6*5+xfztUp`p1x2T+UPG4o_wu@G%o8p&g8_a|z` zy16V#HpP4%){+W=mjY@Oo#d1>rPjsl6jbp~WF~-cyDK1|&J!AAX zGKKVv;v+I3tXli^>G5cqSK(sRYIZ9Hl&jj~yGYPbUi-acX{S&(5F@I?Z1(zsF=fg5 zL=|%w=MMvv^-asuNh0=t<6hYy?{OECoFdE|uzP8{L1>2@m5S?BKioOR(C7>%B<2v2 zhYrQ#6*gB1eX7;~La4yDpYP-VK%)C)R3En)7Zi=MGfHpSL6C z+l$q~T&Y{RG6^7$VpGb4L%^7n-dC#P$u@<5Ur~QEh3OMplMQb+5uu;<7G+>ne;QoJ zrd+E~wS^=nS|qlhLM1iE|B)*+fTPt|FT6Lbc^J{J8ChW+>T1L8v*%>X)JL9^@m0yN zxLuqa6mcYOCcuLiH!mepb5MIH0`@oFHHobRcP z5ymcfj%5Os*)i+UG;y+M)E%u?cK@R3kzoqtKuuhpDe3Ys0OGA_xZf+Fh7l#7M}5Ch z8`$9e?aibj>CpTViX08*d?-`WoyDo|e8u&4%2Xr;8)&y}OEqY5@V*w<9% znjm^r5t@HOma#ohOM7cK5GnkF&so0osAW8{P!ZHP!o?DXMTAw#!n-nHpLRCO+qgjfZ+6*?-B_soI9RG6Li|AmW? z7~;s}oygHVP4<{%pNdEZaL1VbaK7xYqRp^WF%9M*uY9IFyIBr&%lFUz8<#|HrbH>5 z&JcavI_E_!vMM(S*cm$F-?ypa$gX;Ft7qe-SIbV-c#7=`-mEL#%TY6v1nUlA;DBQn zN&|A~{etx}I#bQa)lt&;IxhuFtSN2gOS!i6>+@(r=Xp2^5rb+b9KdrR40pm(XXhpd zH435v`PJs3MYgDpYPbwl*t}!p*N_|3i1OcdpW?37Z!7L){%x8fhzoE=b&mM~{)?r= zDj55*N!+Rk2A9y`jFk@~#X&n2(MH{c-swBW@w9d~*B&{=)EwjwI$0@@F~kc)Qa zC1Odhv}H$LlKGJotx+o)b1i(&FE-~kmf(_)G6>U{gcz+&@YhTSp`m9T@JvVh)eVS7 zYK{M&Vm&)3B`N>wvXAsdxj49#5Wt(TP{rU^qDdUHYI0?-MLcA~JmwaNiYppwlf1`J z8|7;UUiMjLojMMX&4kp~#Re`JuV?Z0$|>!tM=D*AaW{rJt0ao^XGY!?1UcR6Yy(_< zPU%)JDBdY6HiE0^ptJmWqTVkPH5eF}{}C#qBSdmuh6-k47kyJj4PQb;i_r4b)ab=F z@faB=VT_&AG|iF#ye1XAxjmi<^0+sci<#2-aL_$a%h3E#g3=RWR*r+3k*cajZLni z|Hj1lMds$H;pi~Ie=52mYbOm$>q48y8@^3Z9fJ{{-Z+>vZUkm+fff;$jv?r4kK}Y( zO=c~0i&4&SR7?^R0wc8Gf2rbv!F|=bDyQ#6eqg=03ul)3+3vS<`Dn$PQyS9%M&@w!u}PFezc4_C34_a<@-DKLl!S9^7sdG6@Sm{dL?9#&Nvl-*hZ;yCxYG zyT>nt=ubz5A%B2bq5~l(*v8(CG8|tOG5y_40}KJW4tHMLfF|UJT)tJ&`$ofMnDUm$CgC-=g0Kczi6WG?VAl%>n3b7@#1x&AClaEMUoGfZ%R}Z zh2bfHVyz|E^UA;ytw&6Nm;t*6MJxikR@PLEj1T+BOlyPF14y$FQ{Ge)s~>4@`7}oy zP}jdodGp9LwPh6A^r_R8hCHR=uj3xR{ySo*W5A

V=^NJp`jJ8Mfq>(-uFQm5L$i0gQiXW%No5T8W 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 Qm;gdfN?Ec>-1z7J1G-|v!~g&Q literal 0 HcmV?d00001 diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/artifact.xml new file mode 100644 index 0000000000..387cf39c64 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_time_chart_gadget/artifact.xml @@ -0,0 +1,23 @@ + + + + + Android_Call_Time_Chart + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_ui_event_publisher/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_ui_event_publisher/artifact.xml new file mode 100644 index 0000000000..f9399220ec --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_ui_event_publisher/artifact.xml @@ -0,0 +1,23 @@ + + + + + org.wso2.iot.android.call.ui.publisher.xml + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_ui_event_publisher/org.wso2.iot.android.call.ui.publisher.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_ui_event_publisher/org.wso2.iot.android.call.ui.publisher.xml new file mode 100755 index 0000000000..0cff1c4b0f --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_call_ui_event_publisher/org.wso2.iot.android.call.ui.publisher.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/artifact.xml new file mode 100644 index 0000000000..4eedd17861 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/artifact.xml @@ -0,0 +1,23 @@ + + + + + commons + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/application.css b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/application.css new file mode 100644 index 0000000000..8eb2fc2a29 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/application.css @@ -0,0 +1,3 @@ +.no-records { + padding-top:20px; +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/autocomplete.css b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/autocomplete.css new file mode 100644 index 0000000000..6c83b6a3a0 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/autocomplete.css @@ -0,0 +1,34 @@ +.twitter-typeahead, .twitter-typeahead:focus { + width: 100%; +} + +.tt-query { + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.tt-hint { + color: #438cad; +} + +.tt-menu { + padding: 8px; + background-color: #fff; + margin: 5px 0; + outline: 0; + border: 1px solid rgba(0,0,0,.15); + right: 0; + left: 0; +} + +.tt-highlight { + color: #438cad; + font-weight: normal; +} + +/* Date Range Picker Gadget */ +.ues-component-box.widget .gadget-body .tt-menu { + margin-left: 15px; + margin-right: 15px; +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/bootstrap.css b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/bootstrap.css new file mode 100644 index 0000000000..4cf729e434 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/bootstrap.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.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')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.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-md-1,.col-md-10,.col-md-11,.col-md-12,.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-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.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-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{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);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);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);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);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);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)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{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);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);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)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{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);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);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)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{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);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);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)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/dataTables.bootstrap.css b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/dataTables.bootstrap.css new file mode 100644 index 0000000000..2ccacaff89 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/dataTables.bootstrap.css @@ -0,0 +1,372 @@ +div.dataTables_length label { + font-weight: normal; + text-align: left; + white-space: nowrap; +} + +div.dataTables_length select { + width: 75px; + display: inline-block; +} + +div.dataTables_filter { + text-align: right; +} + +div.dataTables_filter label { + font-weight: normal; + white-space: nowrap; + text-align: left; +} + +div.dataTables_filter input { + margin-left: 0.5em; + display: inline-block; + width: auto; +} + +div.dataTables_info { + padding-top: 8px; + white-space: nowrap; +} + +div.dataTables_paginate { + margin: 0; + white-space: nowrap; + text-align: right; +} + +div.dataTables_paginate ul.pagination { + margin: 2px 0; + white-space: nowrap; +} + +@media screen and (max-width: 767px) { + div.dataTables_wrapper > div.row > div, + div.dataTables_length, + div.dataTables_filter, + div.dataTables_info, + div.dataTables_paginate { + text-align: center; + } + + div.DTTT { + margin-bottom: 0.5em; + } +} + + +table.dataTable td, +table.dataTable th { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + + +table.dataTable { + clear: both; + margin-top: 6px !important; + margin-bottom: 6px !important; + max-width: none !important; +} + +table.dataTable thead .sorting, +table.dataTable thead .sorting_asc, +table.dataTable thead .sorting_desc, +table.dataTable thead .sorting_asc_disabled, +table.dataTable thead .sorting_desc_disabled { + cursor: pointer; + position: relative; +} + +table.dataTable thead .sorting:after, +table.dataTable thead .sorting_asc:after, +table.dataTable thead .sorting_desc:after { + position: absolute; + top: 8px; + right: 8px; + display: block; + font-family: 'Glyphicons Halflings'; + opacity: 0.5; +} +table.dataTable thead .sorting:after { + opacity: 0.2; + content: "\e150"; /* sort */ +} +table.dataTable thead .sorting_asc:after { + content: "\e155"; /* sort-by-attributes */ +} +table.dataTable thead .sorting_desc:after { + content: "\e156"; /* sort-by-attributes-alt */ +} +div.dataTables_scrollBody table.dataTable thead .sorting:after, +div.dataTables_scrollBody table.dataTable thead .sorting_asc:after, +div.dataTables_scrollBody table.dataTable thead .sorting_desc:after { + display: none; +} + +table.dataTable thead .sorting_asc_disabled:after, +table.dataTable thead .sorting_desc_disabled:after { + color: #eee; +} + +table.dataTable thead > tr > th { + padding-right: 30px; +} + +table.dataTable th:active { + outline: none; +} + + +/* Condensed */ +table.dataTable.table-condensed thead > tr > th { + padding-right: 20px; +} + +table.dataTable.table-condensed thead .sorting:after, +table.dataTable.table-condensed thead .sorting_asc:after, +table.dataTable.table-condensed thead .sorting_desc:after { + top: 6px; + right: 6px; +} + +/* Scrolling */ +div.dataTables_scrollHead table { + margin-bottom: 0 !important; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.dataTables_scrollHead table thead tr:last-child th:first-child, +div.dataTables_scrollHead table thead tr:last-child td:first-child { + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} + +div.dataTables_scrollBody table { + border-top: none; + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +div.dataTables_scrollBody tbody tr:first-child th, +div.dataTables_scrollBody tbody tr:first-child td { + border-top: none; +} + +div.dataTables_scrollFoot table { + margin-top: 0 !important; + border-top: none; +} + +/* Frustratingly the border-collapse:collapse used by Bootstrap makes the column + width calculations when using scrolling impossible to align columns. We have + to use separate + */ +table.table-bordered.dataTable { + border-collapse: separate !important; +} +table.table-bordered thead th, +table.table-bordered thead td { + border-left-width: 0; + border-top-width: 0; +} +table.table-bordered tbody th, +table.table-bordered tbody td { + border-left-width: 0; + border-bottom-width: 0; +} +table.table-bordered tfoot th, +table.table-bordered tfoot td { + border-left-width: 0; + border-bottom-width: 0; +} +table.table-bordered th:last-child, +table.table-bordered td:last-child { + border-right-width: 0; +} +div.dataTables_scrollHead table.table-bordered { + border-bottom-width: 0; +} + + + + +/* + * TableTools styles + */ +.table.dataTable tbody tr.active td, +.table.dataTable tbody tr.active th { + background-color: #08C; + color: white; +} + +.table.dataTable tbody tr.active:hover td, +.table.dataTable tbody tr.active:hover th { + background-color: #0075b0 !important; +} + +.table.dataTable tbody tr.active th > a, +.table.dataTable tbody tr.active td > a { + color: white; +} + +.table-striped.dataTable tbody tr.active:nth-child(odd) td, +.table-striped.dataTable tbody tr.active:nth-child(odd) th { + background-color: #017ebc; +} + +table.DTTT_selectable tbody tr { + cursor: pointer; +} + +div.DTTT .btn:hover { + text-decoration: none !important; +} + +ul.DTTT_dropdown.dropdown-menu { + z-index: 2003; +} + +ul.DTTT_dropdown.dropdown-menu a { + color: #333 !important; /* needed only when demo_page.css is included */ +} + +ul.DTTT_dropdown.dropdown-menu li { + position: relative; +} + +ul.DTTT_dropdown.dropdown-menu li:hover a { + background-color: #0088cc; + color: white !important; +} + +div.DTTT_collection_background { + z-index: 2002; +} + +/* TableTools information display */ +div.DTTT_print_info { + position: fixed; + top: 50%; + left: 50%; + width: 400px; + height: 150px; + margin-left: -200px; + margin-top: -75px; + text-align: center; + color: #333; + padding: 10px 30px; + opacity: 0.95; + + background-color: white; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5); +} + +div.DTTT_print_info h6 { + font-weight: normal; + font-size: 28px; + line-height: 28px; + margin: 1em; +} + +div.DTTT_print_info p { + font-size: 14px; + line-height: 20px; +} + +div.dataTables_processing { + position: absolute; + top: 50%; + left: 50%; + width: 100%; + height: 60px; + margin-left: -50%; + margin-top: -25px; + padding-top: 20px; + padding-bottom: 20px; + text-align: center; + font-size: 1.2em; + background-color: white; + background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0))); + background: -webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); + background: -moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); + background: -ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); + background: -o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); + background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%); +} + + + +/* + * FixedColumns styles + */ +div.DTFC_LeftHeadWrapper table, +div.DTFC_LeftFootWrapper table, +div.DTFC_RightHeadWrapper table, +div.DTFC_RightFootWrapper table, +table.DTFC_Cloned tr.even { + background-color: white; + margin-bottom: 0; +} + +div.DTFC_RightHeadWrapper table , +div.DTFC_LeftHeadWrapper table { + border-bottom: none !important; + margin-bottom: 0 !important; + border-top-right-radius: 0 !important; + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} + +div.DTFC_RightHeadWrapper table thead tr:last-child th:first-child, +div.DTFC_RightHeadWrapper table thead tr:last-child td:first-child, +div.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child, +div.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child { + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} + +div.DTFC_RightBodyWrapper table, +div.DTFC_LeftBodyWrapper table { + border-top: none; + margin: 0 !important; +} + +div.DTFC_RightBodyWrapper tbody tr:first-child th, +div.DTFC_RightBodyWrapper tbody tr:first-child td, +div.DTFC_LeftBodyWrapper tbody tr:first-child th, +div.DTFC_LeftBodyWrapper tbody tr:first-child td { + border-top: none; +} + +div.DTFC_RightFootWrapper table, +div.DTFC_LeftFootWrapper table { + border-top: none; + margin-top: 0 !important; +} + + +div.DTFC_LeftBodyWrapper table.dataTable thead .sorting:after, +div.DTFC_LeftBodyWrapper table.dataTable thead .sorting_asc:after, +div.DTFC_LeftBodyWrapper table.dataTable thead .sorting_desc:after, +div.DTFC_RightBodyWrapper table.dataTable thead .sorting:after, +div.DTFC_RightBodyWrapper table.dataTable thead .sorting_asc:after, +div.DTFC_RightBodyWrapper table.dataTable thead .sorting_desc:after { + display: none; +} + + +/* + * FixedHeader styles + */ +div.FixedHeader_Cloned table { + margin: 0 !important +} + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/daterangepicker.css b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/daterangepicker.css new file mode 100644 index 0000000000..e525b2b7d0 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/daterangepicker.css @@ -0,0 +1,375 @@ +/** +* A stylesheet for use with Bootstrap 3.x +* @author: Dan Grossman http://www.dangrossman.info/ +* @copyright: Copyright (c) 2012-2015 Dan Grossman. All rights reserved. +* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php +* @website: https://www.improvely.com/ +*/ + +/* Container Appearance */ + +.daterangepicker { + position: absolute; + background: #fff; + top: 100px; + left: 20px; + padding: 4px; + margin-top: 1px; + border-radius: 4px; + width:278px; +} + +.daterangepicker.opensleft:before { + position: absolute; + top: -7px; + right: 9px; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.daterangepicker.opensleft:after { + position: absolute; + top: -6px; + right: 10px; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + border-left: 6px solid transparent; + content: ''; +} + +.daterangepicker.openscenter:before { + position: absolute; + top: -7px; + left: 0; + right: 0; + width: 0; + margin-left: auto; + margin-right: auto; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.daterangepicker.openscenter:after { + position: absolute; + top: -6px; + left: 0; + right: 0; + width: 0; + margin-left: auto; + margin-right: auto; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + border-left: 6px solid transparent; + content: ''; +} + +.daterangepicker.opensright:before { + position: absolute; + top: -7px; + left: 9px; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.daterangepicker.opensright:after { + position: absolute; + top: -6px; + left: 10px; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + border-left: 6px solid transparent; + content: ''; +} + +.daterangepicker.dropup{ + margin-top: -5px; +} +.daterangepicker.dropup:before{ + top: initial; + bottom:-7px; + border-bottom: initial; + border-top: 7px solid #ccc; +} +.daterangepicker.dropup:after{ + top: initial; + bottom:-6px; + border-bottom: initial; + border-top: 6px solid #fff; +} + +.daterangepicker.dropdown-menu { + max-width: none; + z-index: 3000; +} + +.daterangepicker.single .ranges, .daterangepicker.single .calendar { + float: none; +} + +.daterangepicker .calendar { + display: none; + max-width: 270px; + margin: 4px; +} + +.daterangepicker.show-calendar .calendar { + display: block; +} + +.daterangepicker .calendar.single .calendar-table { + border: none; +} + +/* Calendars */ + +.daterangepicker .calendar th, .daterangepicker .calendar td { + white-space: nowrap; + text-align: center; + min-width: 32px; +} + +.daterangepicker .calendar-table { + border: 1px solid #ddd; + padding: 4px; + border-radius: 4px; + background: #fff; +} + +.daterangepicker table { + width: 100%; + margin: 0; +} + +.daterangepicker td, .daterangepicker th { + text-align: center; + width: 20px; + height: 20px; + border-radius: 4px; + white-space: nowrap; + cursor: pointer; +} + +.daterangepicker td.off, .daterangepicker td.off.in-range, .daterangepicker td.off.start-date, .daterangepicker td.off.end-date { + color: #999; + background: #fff; +} + +.daterangepicker td.disabled, .daterangepicker option.disabled { + color: #999; + cursor: not-allowed; + text-decoration: line-through; +} + +.daterangepicker td.available:hover, .daterangepicker th.available:hover { + background: #eee; +} + +.daterangepicker td.in-range { + background: #ebf4f8; + border-radius: 0; +} + +.daterangepicker td.start-date { + border-radius: 4px 0 0 4px; +} + +.daterangepicker td.end-date { + border-radius: 0 4px 4px 0; +} + +.daterangepicker td.start-date.end-date { + border-radius: 4px; +} + +.daterangepicker td.active, .daterangepicker td.active:hover { + background-color: #357ebd; + border-color: #3071a9; + color: #fff; +} + +.daterangepicker td.week, .daterangepicker th.week { + font-size: 80%; + color: #ccc; +} + +.daterangepicker select.monthselect, .daterangepicker select.yearselect { + font-size: 12px; + padding: 1px; + height: auto; + margin: 0; + cursor: default; +} + +.daterangepicker select.monthselect { + margin-right: 2%; + width: 56%; +} + +.daterangepicker select.yearselect { + width: 40%; +} + +.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect { + width: 50px; + margin-bottom: 0; +} + +.daterangepicker th.month { + width: auto; +} + +/* Text Input Above Each Calendar */ + +.daterangepicker .input-mini { + border: 1px solid #ccc; + border-radius: 4px; + color: #555; + display: block; + height: 30px; + line-height: 30px; + vertical-align: middle; + margin: 0 0 5px 0; + padding: 0 6px 0 28px; + width: 100%; +} + +.daterangepicker .input-mini.active { + border: 1px solid #357ebd; +} + +.daterangepicker .daterangepicker_input i { + position: absolute; + left: 8px; + top: 8px; +} + +.daterangepicker .daterangepicker_input { + position: relative; +} + +/* Time Picker */ + +.daterangepicker .calendar-time { + text-align: center; + margin: 5px auto; + line-height: 30px; + position: relative; + padding-left: 28px; +} + +.daterangepicker .calendar-time select.disabled { + color: #ccc; + cursor: not-allowed; +} + +/* Predefined Ranges */ + +.daterangepicker .ranges { + font-size: 11px; + float: none; + margin: 4px; + text-align: left; +} + +.daterangepicker .ranges ul { + list-style: none; + margin: 0 auto; + padding: 0; + width: 100%; +} + +.daterangepicker .ranges li { + font-size: 13px; + background: #f5f5f5; + border: 1px solid #f5f5f5; + color: #08c; + padding: 3px 12px; + margin-bottom: 8px; + border-radius: 5px; + cursor: pointer; +} + +.daterangepicker .ranges li.active, .daterangepicker .ranges li:hover { + background: #08c; + border: 1px solid #08c; + color: #fff; +} + +/* Larger Screen Styling */ +/*@media all and (min-width: 564px) {*/ + .daterangepicker{ + width: auto; + } + + .daterangepicker .ranges ul { + width: 160px; + } + .daterangepicker.single .ranges ul { + width: 100%; + } + .daterangepicker .calendar.left .calendar-table { + border-right: none; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .daterangepicker .calendar.right .calendar-table { + border-left: none; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + + .daterangepicker .calendar.left { + clear: left; + margin-right: 0; + } + .daterangepicker.single .calendar.left { + clear: none; + } + .daterangepicker.single .ranges, + .daterangepicker.single .calendar{ + float:left; + } + + .daterangepicker .calendar.right { + margin-left: 0; + } + + .daterangepicker .left .daterangepicker_input { + padding-right: 12px; + } + + .daterangepicker .calendar.left .calendar-table { + padding-right: 12px; + } + + .daterangepicker .ranges, + .daterangepicker .calendar { + float: left; + } +/*}*/ + +/*@media all and (min-width: 730px) { + .daterangepicker .ranges { + width: auto; + float: left; + } + .daterangepicker .calendar.left { + clear: none; + } +}*/ diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/font-awesome.css b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/font-awesome.css new file mode 100644 index 0000000000..b2a5fe2f25 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/font-awesome.css @@ -0,0 +1,2086 @@ +/*! + * Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ +/* FONT PATH + * -------------------------- */ +@font-face { + font-family: 'FontAwesome'; + src: url('../fonts/fontawesome-webfont.eot?v=4.5.0'); + src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.5.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.5.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.5.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.5.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular') format('svg'); + font-weight: normal; + font-style: normal; +} +.fa { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +/* makes the font 33% larger relative to the icon container */ +.fa-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fa-2x { + font-size: 2em; +} +.fa-3x { + font-size: 3em; +} +.fa-4x { + font-size: 4em; +} +.fa-5x { + font-size: 5em; +} +.fa-fw { + width: 1.28571429em; + text-align: center; +} +.fa-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.fa-ul > li { + position: relative; +} +.fa-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fa-li.fa-lg { + left: -1.85714286em; +} +.fa-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.fa-pull-left { + float: left; +} +.fa-pull-right { + float: right; +} +.fa.fa-pull-left { + margin-right: .3em; +} +.fa.fa-pull-right { + margin-left: .3em; +} +/* Deprecated as of 4.4.0 */ +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.fa.pull-left { + margin-right: .3em; +} +.fa.pull-right { + margin-left: .3em; +} +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); +} +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +.fa-rotate-90 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.fa-rotate-180 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.fa-rotate-270 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.fa-flip-horizontal { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fa-flip-vertical { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + filter: none; +} +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fa-stack-1x { + line-height: inherit; +} +.fa-stack-2x { + font-size: 2em; +} +.fa-inverse { + color: #ffffff; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.fa-glass:before { + content: "\f000"; +} +.fa-music:before { + content: "\f001"; +} +.fa-search:before { + content: "\f002"; +} +.fa-envelope-o:before { + content: "\f003"; +} +.fa-heart:before { + content: "\f004"; +} +.fa-star:before { + content: "\f005"; +} +.fa-star-o:before { + content: "\f006"; +} +.fa-user:before { + content: "\f007"; +} +.fa-film:before { + content: "\f008"; +} +.fa-th-large:before { + content: "\f009"; +} +.fa-th:before { + content: "\f00a"; +} +.fa-th-list:before { + content: "\f00b"; +} +.fa-check:before { + content: "\f00c"; +} +.fa-remove:before, +.fa-close:before, +.fa-times:before { + content: "\f00d"; +} +.fa-search-plus:before { + content: "\f00e"; +} +.fa-search-minus:before { + content: "\f010"; +} +.fa-power-off:before { + content: "\f011"; +} +.fa-signal:before { + content: "\f012"; +} +.fa-gear:before, +.fa-cog:before { + content: "\f013"; +} +.fa-trash-o:before { + content: "\f014"; +} +.fa-home:before { + content: "\f015"; +} +.fa-file-o:before { + content: "\f016"; +} +.fa-clock-o:before { + content: "\f017"; +} +.fa-road:before { + content: "\f018"; +} +.fa-download:before { + content: "\f019"; +} +.fa-arrow-circle-o-down:before { + content: "\f01a"; +} +.fa-arrow-circle-o-up:before { + content: "\f01b"; +} +.fa-inbox:before { + content: "\f01c"; +} +.fa-play-circle-o:before { + content: "\f01d"; +} +.fa-rotate-right:before, +.fa-repeat:before { + content: "\f01e"; +} +.fa-refresh:before { + content: "\f021"; +} +.fa-list-alt:before { + content: "\f022"; +} +.fa-lock:before { + content: "\f023"; +} +.fa-flag:before { + content: "\f024"; +} +.fa-headphones:before { + content: "\f025"; +} +.fa-volume-off:before { + content: "\f026"; +} +.fa-volume-down:before { + content: "\f027"; +} +.fa-volume-up:before { + content: "\f028"; +} +.fa-qrcode:before { + content: "\f029"; +} +.fa-barcode:before { + content: "\f02a"; +} +.fa-tag:before { + content: "\f02b"; +} +.fa-tags:before { + content: "\f02c"; +} +.fa-book:before { + content: "\f02d"; +} +.fa-bookmark:before { + content: "\f02e"; +} +.fa-print:before { + content: "\f02f"; +} +.fa-camera:before { + content: "\f030"; +} +.fa-font:before { + content: "\f031"; +} +.fa-bold:before { + content: "\f032"; +} +.fa-italic:before { + content: "\f033"; +} +.fa-text-height:before { + content: "\f034"; +} +.fa-text-width:before { + content: "\f035"; +} +.fa-align-left:before { + content: "\f036"; +} +.fa-align-center:before { + content: "\f037"; +} +.fa-align-right:before { + content: "\f038"; +} +.fa-align-justify:before { + content: "\f039"; +} +.fa-list:before { + content: "\f03a"; +} +.fa-dedent:before, +.fa-outdent:before { + content: "\f03b"; +} +.fa-indent:before { + content: "\f03c"; +} +.fa-video-camera:before { + content: "\f03d"; +} +.fa-photo:before, +.fa-image:before, +.fa-picture-o:before { + content: "\f03e"; +} +.fa-pencil:before { + content: "\f040"; +} +.fa-map-marker:before { + content: "\f041"; +} +.fa-adjust:before { + content: "\f042"; +} +.fa-tint:before { + content: "\f043"; +} +.fa-edit:before, +.fa-pencil-square-o:before { + content: "\f044"; +} +.fa-share-square-o:before { + content: "\f045"; +} +.fa-check-square-o:before { + content: "\f046"; +} +.fa-arrows:before { + content: "\f047"; +} +.fa-step-backward:before { + content: "\f048"; +} +.fa-fast-backward:before { + content: "\f049"; +} +.fa-backward:before { + content: "\f04a"; +} +.fa-play:before { + content: "\f04b"; +} +.fa-pause:before { + content: "\f04c"; +} +.fa-stop:before { + content: "\f04d"; +} +.fa-forward:before { + content: "\f04e"; +} +.fa-fast-forward:before { + content: "\f050"; +} +.fa-step-forward:before { + content: "\f051"; +} +.fa-eject:before { + content: "\f052"; +} +.fa-chevron-left:before { + content: "\f053"; +} +.fa-chevron-right:before { + content: "\f054"; +} +.fa-plus-circle:before { + content: "\f055"; +} +.fa-minus-circle:before { + content: "\f056"; +} +.fa-times-circle:before { + content: "\f057"; +} +.fa-check-circle:before { + content: "\f058"; +} +.fa-question-circle:before { + content: "\f059"; +} +.fa-info-circle:before { + content: "\f05a"; +} +.fa-crosshairs:before { + content: "\f05b"; +} +.fa-times-circle-o:before { + content: "\f05c"; +} +.fa-check-circle-o:before { + content: "\f05d"; +} +.fa-ban:before { + content: "\f05e"; +} +.fa-arrow-left:before { + content: "\f060"; +} +.fa-arrow-right:before { + content: "\f061"; +} +.fa-arrow-up:before { + content: "\f062"; +} +.fa-arrow-down:before { + content: "\f063"; +} +.fa-mail-forward:before, +.fa-share:before { + content: "\f064"; +} +.fa-expand:before { + content: "\f065"; +} +.fa-compress:before { + content: "\f066"; +} +.fa-plus:before { + content: "\f067"; +} +.fa-minus:before { + content: "\f068"; +} +.fa-asterisk:before { + content: "\f069"; +} +.fa-exclamation-circle:before { + content: "\f06a"; +} +.fa-gift:before { + content: "\f06b"; +} +.fa-leaf:before { + content: "\f06c"; +} +.fa-fire:before { + content: "\f06d"; +} +.fa-eye:before { + content: "\f06e"; +} +.fa-eye-slash:before { + content: "\f070"; +} +.fa-warning:before, +.fa-exclamation-triangle:before { + content: "\f071"; +} +.fa-plane:before { + content: "\f072"; +} +.fa-calendar:before { + content: "\f073"; +} +.fa-random:before { + content: "\f074"; +} +.fa-comment:before { + content: "\f075"; +} +.fa-magnet:before { + content: "\f076"; +} +.fa-chevron-up:before { + content: "\f077"; +} +.fa-chevron-down:before { + content: "\f078"; +} +.fa-retweet:before { + content: "\f079"; +} +.fa-shopping-cart:before { + content: "\f07a"; +} +.fa-folder:before { + content: "\f07b"; +} +.fa-folder-open:before { + content: "\f07c"; +} +.fa-arrows-v:before { + content: "\f07d"; +} +.fa-arrows-h:before { + content: "\f07e"; +} +.fa-bar-chart-o:before, +.fa-bar-chart:before { + content: "\f080"; +} +.fa-twitter-square:before { + content: "\f081"; +} +.fa-facebook-square:before { + content: "\f082"; +} +.fa-camera-retro:before { + content: "\f083"; +} +.fa-key:before { + content: "\f084"; +} +.fa-gears:before, +.fa-cogs:before { + content: "\f085"; +} +.fa-comments:before { + content: "\f086"; +} +.fa-thumbs-o-up:before { + content: "\f087"; +} +.fa-thumbs-o-down:before { + content: "\f088"; +} +.fa-star-half:before { + content: "\f089"; +} +.fa-heart-o:before { + content: "\f08a"; +} +.fa-sign-out:before { + content: "\f08b"; +} +.fa-linkedin-square:before { + content: "\f08c"; +} +.fa-thumb-tack:before { + content: "\f08d"; +} +.fa-external-link:before { + content: "\f08e"; +} +.fa-sign-in:before { + content: "\f090"; +} +.fa-trophy:before { + content: "\f091"; +} +.fa-github-square:before { + content: "\f092"; +} +.fa-upload:before { + content: "\f093"; +} +.fa-lemon-o:before { + content: "\f094"; +} +.fa-phone:before { + content: "\f095"; +} +.fa-square-o:before { + content: "\f096"; +} +.fa-bookmark-o:before { + content: "\f097"; +} +.fa-phone-square:before { + content: "\f098"; +} +.fa-twitter:before { + content: "\f099"; +} +.fa-facebook-f:before, +.fa-facebook:before { + content: "\f09a"; +} +.fa-github:before { + content: "\f09b"; +} +.fa-unlock:before { + content: "\f09c"; +} +.fa-credit-card:before { + content: "\f09d"; +} +.fa-feed:before, +.fa-rss:before { + content: "\f09e"; +} +.fa-hdd-o:before { + content: "\f0a0"; +} +.fa-bullhorn:before { + content: "\f0a1"; +} +.fa-bell:before { + content: "\f0f3"; +} +.fa-certificate:before { + content: "\f0a3"; +} +.fa-hand-o-right:before { + content: "\f0a4"; +} +.fa-hand-o-left:before { + content: "\f0a5"; +} +.fa-hand-o-up:before { + content: "\f0a6"; +} +.fa-hand-o-down:before { + content: "\f0a7"; +} +.fa-arrow-circle-left:before { + content: "\f0a8"; +} +.fa-arrow-circle-right:before { + content: "\f0a9"; +} +.fa-arrow-circle-up:before { + content: "\f0aa"; +} +.fa-arrow-circle-down:before { + content: "\f0ab"; +} +.fa-globe:before { + content: "\f0ac"; +} +.fa-wrench:before { + content: "\f0ad"; +} +.fa-tasks:before { + content: "\f0ae"; +} +.fa-filter:before { + content: "\f0b0"; +} +.fa-briefcase:before { + content: "\f0b1"; +} +.fa-arrows-alt:before { + content: "\f0b2"; +} +.fa-group:before, +.fa-users:before { + content: "\f0c0"; +} +.fa-chain:before, +.fa-link:before { + content: "\f0c1"; +} +.fa-cloud:before { + content: "\f0c2"; +} +.fa-flask:before { + content: "\f0c3"; +} +.fa-cut:before, +.fa-scissors:before { + content: "\f0c4"; +} +.fa-copy:before, +.fa-files-o:before { + content: "\f0c5"; +} +.fa-paperclip:before { + content: "\f0c6"; +} +.fa-save:before, +.fa-floppy-o:before { + content: "\f0c7"; +} +.fa-square:before { + content: "\f0c8"; +} +.fa-navicon:before, +.fa-reorder:before, +.fa-bars:before { + content: "\f0c9"; +} +.fa-list-ul:before { + content: "\f0ca"; +} +.fa-list-ol:before { + content: "\f0cb"; +} +.fa-strikethrough:before { + content: "\f0cc"; +} +.fa-underline:before { + content: "\f0cd"; +} +.fa-table:before { + content: "\f0ce"; +} +.fa-magic:before { + content: "\f0d0"; +} +.fa-truck:before { + content: "\f0d1"; +} +.fa-pinterest:before { + content: "\f0d2"; +} +.fa-pinterest-square:before { + content: "\f0d3"; +} +.fa-google-plus-square:before { + content: "\f0d4"; +} +.fa-google-plus:before { + content: "\f0d5"; +} +.fa-money:before { + content: "\f0d6"; +} +.fa-caret-down:before { + content: "\f0d7"; +} +.fa-caret-up:before { + content: "\f0d8"; +} +.fa-caret-left:before { + content: "\f0d9"; +} +.fa-caret-right:before { + content: "\f0da"; +} +.fa-columns:before { + content: "\f0db"; +} +.fa-unsorted:before, +.fa-sort:before { + content: "\f0dc"; +} +.fa-sort-down:before, +.fa-sort-desc:before { + content: "\f0dd"; +} +.fa-sort-up:before, +.fa-sort-asc:before { + content: "\f0de"; +} +.fa-envelope:before { + content: "\f0e0"; +} +.fa-linkedin:before { + content: "\f0e1"; +} +.fa-rotate-left:before, +.fa-undo:before { + content: "\f0e2"; +} +.fa-legal:before, +.fa-gavel:before { + content: "\f0e3"; +} +.fa-dashboard:before, +.fa-tachometer:before { + content: "\f0e4"; +} +.fa-comment-o:before { + content: "\f0e5"; +} +.fa-comments-o:before { + content: "\f0e6"; +} +.fa-flash:before, +.fa-bolt:before { + content: "\f0e7"; +} +.fa-sitemap:before { + content: "\f0e8"; +} +.fa-umbrella:before { + content: "\f0e9"; +} +.fa-paste:before, +.fa-clipboard:before { + content: "\f0ea"; +} +.fa-lightbulb-o:before { + content: "\f0eb"; +} +.fa-exchange:before { + content: "\f0ec"; +} +.fa-cloud-download:before { + content: "\f0ed"; +} +.fa-cloud-upload:before { + content: "\f0ee"; +} +.fa-user-md:before { + content: "\f0f0"; +} +.fa-stethoscope:before { + content: "\f0f1"; +} +.fa-suitcase:before { + content: "\f0f2"; +} +.fa-bell-o:before { + content: "\f0a2"; +} +.fa-coffee:before { + content: "\f0f4"; +} +.fa-cutlery:before { + content: "\f0f5"; +} +.fa-file-text-o:before { + content: "\f0f6"; +} +.fa-building-o:before { + content: "\f0f7"; +} +.fa-hospital-o:before { + content: "\f0f8"; +} +.fa-ambulance:before { + content: "\f0f9"; +} +.fa-medkit:before { + content: "\f0fa"; +} +.fa-fighter-jet:before { + content: "\f0fb"; +} +.fa-beer:before { + content: "\f0fc"; +} +.fa-h-square:before { + content: "\f0fd"; +} +.fa-plus-square:before { + content: "\f0fe"; +} +.fa-angle-double-left:before { + content: "\f100"; +} +.fa-angle-double-right:before { + content: "\f101"; +} +.fa-angle-double-up:before { + content: "\f102"; +} +.fa-angle-double-down:before { + content: "\f103"; +} +.fa-angle-left:before { + content: "\f104"; +} +.fa-angle-right:before { + content: "\f105"; +} +.fa-angle-up:before { + content: "\f106"; +} +.fa-angle-down:before { + content: "\f107"; +} +.fa-desktop:before { + content: "\f108"; +} +.fa-laptop:before { + content: "\f109"; +} +.fa-tablet:before { + content: "\f10a"; +} +.fa-mobile-phone:before, +.fa-mobile:before { + content: "\f10b"; +} +.fa-circle-o:before { + content: "\f10c"; +} +.fa-quote-left:before { + content: "\f10d"; +} +.fa-quote-right:before { + content: "\f10e"; +} +.fa-spinner:before { + content: "\f110"; +} +.fa-circle:before { + content: "\f111"; +} +.fa-mail-reply:before, +.fa-reply:before { + content: "\f112"; +} +.fa-github-alt:before { + content: "\f113"; +} +.fa-folder-o:before { + content: "\f114"; +} +.fa-folder-open-o:before { + content: "\f115"; +} +.fa-smile-o:before { + content: "\f118"; +} +.fa-frown-o:before { + content: "\f119"; +} +.fa-meh-o:before { + content: "\f11a"; +} +.fa-gamepad:before { + content: "\f11b"; +} +.fa-keyboard-o:before { + content: "\f11c"; +} +.fa-flag-o:before { + content: "\f11d"; +} +.fa-flag-checkered:before { + content: "\f11e"; +} +.fa-terminal:before { + content: "\f120"; +} +.fa-code:before { + content: "\f121"; +} +.fa-mail-reply-all:before, +.fa-reply-all:before { + content: "\f122"; +} +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "\f123"; +} +.fa-location-arrow:before { + content: "\f124"; +} +.fa-crop:before { + content: "\f125"; +} +.fa-code-fork:before { + content: "\f126"; +} +.fa-unlink:before, +.fa-chain-broken:before { + content: "\f127"; +} +.fa-question:before { + content: "\f128"; +} +.fa-info:before { + content: "\f129"; +} +.fa-exclamation:before { + content: "\f12a"; +} +.fa-superscript:before { + content: "\f12b"; +} +.fa-subscript:before { + content: "\f12c"; +} +.fa-eraser:before { + content: "\f12d"; +} +.fa-puzzle-piece:before { + content: "\f12e"; +} +.fa-microphone:before { + content: "\f130"; +} +.fa-microphone-slash:before { + content: "\f131"; +} +.fa-shield:before { + content: "\f132"; +} +.fa-calendar-o:before { + content: "\f133"; +} +.fa-fire-extinguisher:before { + content: "\f134"; +} +.fa-rocket:before { + content: "\f135"; +} +.fa-maxcdn:before { + content: "\f136"; +} +.fa-chevron-circle-left:before { + content: "\f137"; +} +.fa-chevron-circle-right:before { + content: "\f138"; +} +.fa-chevron-circle-up:before { + content: "\f139"; +} +.fa-chevron-circle-down:before { + content: "\f13a"; +} +.fa-html5:before { + content: "\f13b"; +} +.fa-css3:before { + content: "\f13c"; +} +.fa-anchor:before { + content: "\f13d"; +} +.fa-unlock-alt:before { + content: "\f13e"; +} +.fa-bullseye:before { + content: "\f140"; +} +.fa-ellipsis-h:before { + content: "\f141"; +} +.fa-ellipsis-v:before { + content: "\f142"; +} +.fa-rss-square:before { + content: "\f143"; +} +.fa-play-circle:before { + content: "\f144"; +} +.fa-ticket:before { + content: "\f145"; +} +.fa-minus-square:before { + content: "\f146"; +} +.fa-minus-square-o:before { + content: "\f147"; +} +.fa-level-up:before { + content: "\f148"; +} +.fa-level-down:before { + content: "\f149"; +} +.fa-check-square:before { + content: "\f14a"; +} +.fa-pencil-square:before { + content: "\f14b"; +} +.fa-external-link-square:before { + content: "\f14c"; +} +.fa-share-square:before { + content: "\f14d"; +} +.fa-compass:before { + content: "\f14e"; +} +.fa-toggle-down:before, +.fa-caret-square-o-down:before { + content: "\f150"; +} +.fa-toggle-up:before, +.fa-caret-square-o-up:before { + content: "\f151"; +} +.fa-toggle-right:before, +.fa-caret-square-o-right:before { + content: "\f152"; +} +.fa-euro:before, +.fa-eur:before { + content: "\f153"; +} +.fa-gbp:before { + content: "\f154"; +} +.fa-dollar:before, +.fa-usd:before { + content: "\f155"; +} +.fa-rupee:before, +.fa-inr:before { + content: "\f156"; +} +.fa-cny:before, +.fa-rmb:before, +.fa-yen:before, +.fa-jpy:before { + content: "\f157"; +} +.fa-ruble:before, +.fa-rouble:before, +.fa-rub:before { + content: "\f158"; +} +.fa-won:before, +.fa-krw:before { + content: "\f159"; +} +.fa-bitcoin:before, +.fa-btc:before { + content: "\f15a"; +} +.fa-file:before { + content: "\f15b"; +} +.fa-file-text:before { + content: "\f15c"; +} +.fa-sort-alpha-asc:before { + content: "\f15d"; +} +.fa-sort-alpha-desc:before { + content: "\f15e"; +} +.fa-sort-amount-asc:before { + content: "\f160"; +} +.fa-sort-amount-desc:before { + content: "\f161"; +} +.fa-sort-numeric-asc:before { + content: "\f162"; +} +.fa-sort-numeric-desc:before { + content: "\f163"; +} +.fa-thumbs-up:before { + content: "\f164"; +} +.fa-thumbs-down:before { + content: "\f165"; +} +.fa-youtube-square:before { + content: "\f166"; +} +.fa-youtube:before { + content: "\f167"; +} +.fa-xing:before { + content: "\f168"; +} +.fa-xing-square:before { + content: "\f169"; +} +.fa-youtube-play:before { + content: "\f16a"; +} +.fa-dropbox:before { + content: "\f16b"; +} +.fa-stack-overflow:before { + content: "\f16c"; +} +.fa-instagram:before { + content: "\f16d"; +} +.fa-flickr:before { + content: "\f16e"; +} +.fa-adn:before { + content: "\f170"; +} +.fa-bitbucket:before { + content: "\f171"; +} +.fa-bitbucket-square:before { + content: "\f172"; +} +.fa-tumblr:before { + content: "\f173"; +} +.fa-tumblr-square:before { + content: "\f174"; +} +.fa-long-arrow-down:before { + content: "\f175"; +} +.fa-long-arrow-up:before { + content: "\f176"; +} +.fa-long-arrow-left:before { + content: "\f177"; +} +.fa-long-arrow-right:before { + content: "\f178"; +} +.fa-apple:before { + content: "\f179"; +} +.fa-windows:before { + content: "\f17a"; +} +.fa-android:before { + content: "\f17b"; +} +.fa-linux:before { + content: "\f17c"; +} +.fa-dribbble:before { + content: "\f17d"; +} +.fa-skype:before { + content: "\f17e"; +} +.fa-foursquare:before { + content: "\f180"; +} +.fa-trello:before { + content: "\f181"; +} +.fa-female:before { + content: "\f182"; +} +.fa-male:before { + content: "\f183"; +} +.fa-gittip:before, +.fa-gratipay:before { + content: "\f184"; +} +.fa-sun-o:before { + content: "\f185"; +} +.fa-moon-o:before { + content: "\f186"; +} +.fa-archive:before { + content: "\f187"; +} +.fa-bug:before { + content: "\f188"; +} +.fa-vk:before { + content: "\f189"; +} +.fa-weibo:before { + content: "\f18a"; +} +.fa-renren:before { + content: "\f18b"; +} +.fa-pagelines:before { + content: "\f18c"; +} +.fa-stack-exchange:before { + content: "\f18d"; +} +.fa-arrow-circle-o-right:before { + content: "\f18e"; +} +.fa-arrow-circle-o-left:before { + content: "\f190"; +} +.fa-toggle-left:before, +.fa-caret-square-o-left:before { + content: "\f191"; +} +.fa-dot-circle-o:before { + content: "\f192"; +} +.fa-wheelchair:before { + content: "\f193"; +} +.fa-vimeo-square:before { + content: "\f194"; +} +.fa-turkish-lira:before, +.fa-try:before { + content: "\f195"; +} +.fa-plus-square-o:before { + content: "\f196"; +} +.fa-space-shuttle:before { + content: "\f197"; +} +.fa-slack:before { + content: "\f198"; +} +.fa-envelope-square:before { + content: "\f199"; +} +.fa-wordpress:before { + content: "\f19a"; +} +.fa-openid:before { + content: "\f19b"; +} +.fa-institution:before, +.fa-bank:before, +.fa-university:before { + content: "\f19c"; +} +.fa-mortar-board:before, +.fa-graduation-cap:before { + content: "\f19d"; +} +.fa-yahoo:before { + content: "\f19e"; +} +.fa-google:before { + content: "\f1a0"; +} +.fa-reddit:before { + content: "\f1a1"; +} +.fa-reddit-square:before { + content: "\f1a2"; +} +.fa-stumbleupon-circle:before { + content: "\f1a3"; +} +.fa-stumbleupon:before { + content: "\f1a4"; +} +.fa-delicious:before { + content: "\f1a5"; +} +.fa-digg:before { + content: "\f1a6"; +} +.fa-pied-piper:before { + content: "\f1a7"; +} +.fa-pied-piper-alt:before { + content: "\f1a8"; +} +.fa-drupal:before { + content: "\f1a9"; +} +.fa-joomla:before { + content: "\f1aa"; +} +.fa-language:before { + content: "\f1ab"; +} +.fa-fax:before { + content: "\f1ac"; +} +.fa-building:before { + content: "\f1ad"; +} +.fa-child:before { + content: "\f1ae"; +} +.fa-paw:before { + content: "\f1b0"; +} +.fa-spoon:before { + content: "\f1b1"; +} +.fa-cube:before { + content: "\f1b2"; +} +.fa-cubes:before { + content: "\f1b3"; +} +.fa-behance:before { + content: "\f1b4"; +} +.fa-behance-square:before { + content: "\f1b5"; +} +.fa-steam:before { + content: "\f1b6"; +} +.fa-steam-square:before { + content: "\f1b7"; +} +.fa-recycle:before { + content: "\f1b8"; +} +.fa-automobile:before, +.fa-car:before { + content: "\f1b9"; +} +.fa-cab:before, +.fa-taxi:before { + content: "\f1ba"; +} +.fa-tree:before { + content: "\f1bb"; +} +.fa-spotify:before { + content: "\f1bc"; +} +.fa-deviantart:before { + content: "\f1bd"; +} +.fa-soundcloud:before { + content: "\f1be"; +} +.fa-database:before { + content: "\f1c0"; +} +.fa-file-pdf-o:before { + content: "\f1c1"; +} +.fa-file-word-o:before { + content: "\f1c2"; +} +.fa-file-excel-o:before { + content: "\f1c3"; +} +.fa-file-powerpoint-o:before { + content: "\f1c4"; +} +.fa-file-photo-o:before, +.fa-file-picture-o:before, +.fa-file-image-o:before { + content: "\f1c5"; +} +.fa-file-zip-o:before, +.fa-file-archive-o:before { + content: "\f1c6"; +} +.fa-file-sound-o:before, +.fa-file-audio-o:before { + content: "\f1c7"; +} +.fa-file-movie-o:before, +.fa-file-video-o:before { + content: "\f1c8"; +} +.fa-file-code-o:before { + content: "\f1c9"; +} +.fa-vine:before { + content: "\f1ca"; +} +.fa-codepen:before { + content: "\f1cb"; +} +.fa-jsfiddle:before { + content: "\f1cc"; +} +.fa-life-bouy:before, +.fa-life-buoy:before, +.fa-life-saver:before, +.fa-support:before, +.fa-life-ring:before { + content: "\f1cd"; +} +.fa-circle-o-notch:before { + content: "\f1ce"; +} +.fa-ra:before, +.fa-rebel:before { + content: "\f1d0"; +} +.fa-ge:before, +.fa-empire:before { + content: "\f1d1"; +} +.fa-git-square:before { + content: "\f1d2"; +} +.fa-git:before { + content: "\f1d3"; +} +.fa-y-combinator-square:before, +.fa-yc-square:before, +.fa-hacker-news:before { + content: "\f1d4"; +} +.fa-tencent-weibo:before { + content: "\f1d5"; +} +.fa-qq:before { + content: "\f1d6"; +} +.fa-wechat:before, +.fa-weixin:before { + content: "\f1d7"; +} +.fa-send:before, +.fa-paper-plane:before { + content: "\f1d8"; +} +.fa-send-o:before, +.fa-paper-plane-o:before { + content: "\f1d9"; +} +.fa-history:before { + content: "\f1da"; +} +.fa-circle-thin:before { + content: "\f1db"; +} +.fa-header:before { + content: "\f1dc"; +} +.fa-paragraph:before { + content: "\f1dd"; +} +.fa-sliders:before { + content: "\f1de"; +} +.fa-share-alt:before { + content: "\f1e0"; +} +.fa-share-alt-square:before { + content: "\f1e1"; +} +.fa-bomb:before { + content: "\f1e2"; +} +.fa-soccer-ball-o:before, +.fa-futbol-o:before { + content: "\f1e3"; +} +.fa-tty:before { + content: "\f1e4"; +} +.fa-binoculars:before { + content: "\f1e5"; +} +.fa-plug:before { + content: "\f1e6"; +} +.fa-slideshare:before { + content: "\f1e7"; +} +.fa-twitch:before { + content: "\f1e8"; +} +.fa-yelp:before { + content: "\f1e9"; +} +.fa-newspaper-o:before { + content: "\f1ea"; +} +.fa-wifi:before { + content: "\f1eb"; +} +.fa-calculator:before { + content: "\f1ec"; +} +.fa-paypal:before { + content: "\f1ed"; +} +.fa-google-wallet:before { + content: "\f1ee"; +} +.fa-cc-visa:before { + content: "\f1f0"; +} +.fa-cc-mastercard:before { + content: "\f1f1"; +} +.fa-cc-discover:before { + content: "\f1f2"; +} +.fa-cc-amex:before { + content: "\f1f3"; +} +.fa-cc-paypal:before { + content: "\f1f4"; +} +.fa-cc-stripe:before { + content: "\f1f5"; +} +.fa-bell-slash:before { + content: "\f1f6"; +} +.fa-bell-slash-o:before { + content: "\f1f7"; +} +.fa-trash:before { + content: "\f1f8"; +} +.fa-copyright:before { + content: "\f1f9"; +} +.fa-at:before { + content: "\f1fa"; +} +.fa-eyedropper:before { + content: "\f1fb"; +} +.fa-paint-brush:before { + content: "\f1fc"; +} +.fa-birthday-cake:before { + content: "\f1fd"; +} +.fa-area-chart:before { + content: "\f1fe"; +} +.fa-pie-chart:before { + content: "\f200"; +} +.fa-line-chart:before { + content: "\f201"; +} +.fa-lastfm:before { + content: "\f202"; +} +.fa-lastfm-square:before { + content: "\f203"; +} +.fa-toggle-off:before { + content: "\f204"; +} +.fa-toggle-on:before { + content: "\f205"; +} +.fa-bicycle:before { + content: "\f206"; +} +.fa-bus:before { + content: "\f207"; +} +.fa-ioxhost:before { + content: "\f208"; +} +.fa-angellist:before { + content: "\f209"; +} +.fa-cc:before { + content: "\f20a"; +} +.fa-shekel:before, +.fa-sheqel:before, +.fa-ils:before { + content: "\f20b"; +} +.fa-meanpath:before { + content: "\f20c"; +} +.fa-buysellads:before { + content: "\f20d"; +} +.fa-connectdevelop:before { + content: "\f20e"; +} +.fa-dashcube:before { + content: "\f210"; +} +.fa-forumbee:before { + content: "\f211"; +} +.fa-leanpub:before { + content: "\f212"; +} +.fa-sellsy:before { + content: "\f213"; +} +.fa-shirtsinbulk:before { + content: "\f214"; +} +.fa-simplybuilt:before { + content: "\f215"; +} +.fa-skyatlas:before { + content: "\f216"; +} +.fa-cart-plus:before { + content: "\f217"; +} +.fa-cart-arrow-down:before { + content: "\f218"; +} +.fa-diamond:before { + content: "\f219"; +} +.fa-ship:before { + content: "\f21a"; +} +.fa-user-secret:before { + content: "\f21b"; +} +.fa-motorcycle:before { + content: "\f21c"; +} +.fa-street-view:before { + content: "\f21d"; +} +.fa-heartbeat:before { + content: "\f21e"; +} +.fa-venus:before { + content: "\f221"; +} +.fa-mars:before { + content: "\f222"; +} +.fa-mercury:before { + content: "\f223"; +} +.fa-intersex:before, +.fa-transgender:before { + content: "\f224"; +} +.fa-transgender-alt:before { + content: "\f225"; +} +.fa-venus-double:before { + content: "\f226"; +} +.fa-mars-double:before { + content: "\f227"; +} +.fa-venus-mars:before { + content: "\f228"; +} +.fa-mars-stroke:before { + content: "\f229"; +} +.fa-mars-stroke-v:before { + content: "\f22a"; +} +.fa-mars-stroke-h:before { + content: "\f22b"; +} +.fa-neuter:before { + content: "\f22c"; +} +.fa-genderless:before { + content: "\f22d"; +} +.fa-facebook-official:before { + content: "\f230"; +} +.fa-pinterest-p:before { + content: "\f231"; +} +.fa-whatsapp:before { + content: "\f232"; +} +.fa-server:before { + content: "\f233"; +} +.fa-user-plus:before { + content: "\f234"; +} +.fa-user-times:before { + content: "\f235"; +} +.fa-hotel:before, +.fa-bed:before { + content: "\f236"; +} +.fa-viacoin:before { + content: "\f237"; +} +.fa-train:before { + content: "\f238"; +} +.fa-subway:before { + content: "\f239"; +} +.fa-medium:before { + content: "\f23a"; +} +.fa-yc:before, +.fa-y-combinator:before { + content: "\f23b"; +} +.fa-optin-monster:before { + content: "\f23c"; +} +.fa-opencart:before { + content: "\f23d"; +} +.fa-expeditedssl:before { + content: "\f23e"; +} +.fa-battery-4:before, +.fa-battery-full:before { + content: "\f240"; +} +.fa-battery-3:before, +.fa-battery-three-quarters:before { + content: "\f241"; +} +.fa-battery-2:before, +.fa-battery-half:before { + content: "\f242"; +} +.fa-battery-1:before, +.fa-battery-quarter:before { + content: "\f243"; +} +.fa-battery-0:before, +.fa-battery-empty:before { + content: "\f244"; +} +.fa-mouse-pointer:before { + content: "\f245"; +} +.fa-i-cursor:before { + content: "\f246"; +} +.fa-object-group:before { + content: "\f247"; +} +.fa-object-ungroup:before { + content: "\f248"; +} +.fa-sticky-note:before { + content: "\f249"; +} +.fa-sticky-note-o:before { + content: "\f24a"; +} +.fa-cc-jcb:before { + content: "\f24b"; +} +.fa-cc-diners-club:before { + content: "\f24c"; +} +.fa-clone:before { + content: "\f24d"; +} +.fa-balance-scale:before { + content: "\f24e"; +} +.fa-hourglass-o:before { + content: "\f250"; +} +.fa-hourglass-1:before, +.fa-hourglass-start:before { + content: "\f251"; +} +.fa-hourglass-2:before, +.fa-hourglass-half:before { + content: "\f252"; +} +.fa-hourglass-3:before, +.fa-hourglass-end:before { + content: "\f253"; +} +.fa-hourglass:before { + content: "\f254"; +} +.fa-hand-grab-o:before, +.fa-hand-rock-o:before { + content: "\f255"; +} +.fa-hand-stop-o:before, +.fa-hand-paper-o:before { + content: "\f256"; +} +.fa-hand-scissors-o:before { + content: "\f257"; +} +.fa-hand-lizard-o:before { + content: "\f258"; +} +.fa-hand-spock-o:before { + content: "\f259"; +} +.fa-hand-pointer-o:before { + content: "\f25a"; +} +.fa-hand-peace-o:before { + content: "\f25b"; +} +.fa-trademark:before { + content: "\f25c"; +} +.fa-registered:before { + content: "\f25d"; +} +.fa-creative-commons:before { + content: "\f25e"; +} +.fa-gg:before { + content: "\f260"; +} +.fa-gg-circle:before { + content: "\f261"; +} +.fa-tripadvisor:before { + content: "\f262"; +} +.fa-odnoklassniki:before { + content: "\f263"; +} +.fa-odnoklassniki-square:before { + content: "\f264"; +} +.fa-get-pocket:before { + content: "\f265"; +} +.fa-wikipedia-w:before { + content: "\f266"; +} +.fa-safari:before { + content: "\f267"; +} +.fa-chrome:before { + content: "\f268"; +} +.fa-firefox:before { + content: "\f269"; +} +.fa-opera:before { + content: "\f26a"; +} +.fa-internet-explorer:before { + content: "\f26b"; +} +.fa-tv:before, +.fa-television:before { + content: "\f26c"; +} +.fa-contao:before { + content: "\f26d"; +} +.fa-500px:before { + content: "\f26e"; +} +.fa-amazon:before { + content: "\f270"; +} +.fa-calendar-plus-o:before { + content: "\f271"; +} +.fa-calendar-minus-o:before { + content: "\f272"; +} +.fa-calendar-times-o:before { + content: "\f273"; +} +.fa-calendar-check-o:before { + content: "\f274"; +} +.fa-industry:before { + content: "\f275"; +} +.fa-map-pin:before { + content: "\f276"; +} +.fa-map-signs:before { + content: "\f277"; +} +.fa-map-o:before { + content: "\f278"; +} +.fa-map:before { + content: "\f279"; +} +.fa-commenting:before { + content: "\f27a"; +} +.fa-commenting-o:before { + content: "\f27b"; +} +.fa-houzz:before { + content: "\f27c"; +} +.fa-vimeo:before { + content: "\f27d"; +} +.fa-black-tie:before { + content: "\f27e"; +} +.fa-fonticons:before { + content: "\f280"; +} +.fa-reddit-alien:before { + content: "\f281"; +} +.fa-edge:before { + content: "\f282"; +} +.fa-credit-card-alt:before { + content: "\f283"; +} +.fa-codiepie:before { + content: "\f284"; +} +.fa-modx:before { + content: "\f285"; +} +.fa-fort-awesome:before { + content: "\f286"; +} +.fa-usb:before { + content: "\f287"; +} +.fa-product-hunt:before { + content: "\f288"; +} +.fa-mixcloud:before { + content: "\f289"; +} +.fa-scribd:before { + content: "\f28a"; +} +.fa-pause-circle:before { + content: "\f28b"; +} +.fa-pause-circle-o:before { + content: "\f28c"; +} +.fa-stop-circle:before { + content: "\f28d"; +} +.fa-stop-circle-o:before { + content: "\f28e"; +} +.fa-shopping-bag:before { + content: "\f290"; +} +.fa-shopping-basket:before { + content: "\f291"; +} +.fa-hashtag:before { + content: "\f292"; +} +.fa-bluetooth:before { + content: "\f293"; +} +.fa-bluetooth-b:before { + content: "\f294"; +} +.fa-percent:before { + content: "\f295"; +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/font-awesome.min.css b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/font-awesome.min.css new file mode 100644 index 0000000000..d0603cb4b0 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.5.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.5.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.5.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.5.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.5.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/gadget.css b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/gadget.css new file mode 100644 index 0000000000..3dfe37b73a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/gadget.css @@ -0,0 +1,226 @@ +body { + background: #fff; + color: #444; +} + +body.dark { + background: #1E2531; + color: #fff; +} + +body.widget { + background: transparent; +} + +.col-1, +.col-2, +.col-3, +.col-4, +.col-5, +.col-6, +.col-7, +.col-8, +.col-9, +.col-10, +.col-11, +.col-12 { + float: left; +} + +.col-1 { + width: 8.33333333%; +} + +.col-2 { + width: 16.66666667%; +} + +.col-3 { + width: 25%; +} + +.col-4 { + width: 33.33333333%; +} + +.col-5 { + width: 41.66666667%; +} + +.col-6 { + width: 50%; +} + +.col-7 { + width: 58.33333333%; +} + +.col-8 { + width: 66.66666667%; +} + +.col-9 { + width: 75%; +} + +.col-10 { + width: 83.33333333%; +} + +.col-11 { + width: 91.66666667%; +} + +.col-12 { + width: 100%; +} + +.status-message { + display: block; + height: 100%; + width: 100%; +} + +.status-message > .message-info, +.status-message > .message-warning, +.status-message > .message-danger, +.status-message > .message-success { + position: fixed; + z-index: 2; + width: 100%; + height: 100%; + top: 50%; + left: 50%; + margin: 0; + -webkit-transform: translate(-50%, -50%); + -moz-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + -o-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +/* Dark Theme Styles */ +body.dark .tt-hint { + background: transparent !important; +} + +body.dark .tt-input { + border: 1px solid #6B7992 !important; + color: #E3E5E6; +} + +body.dark .form-control-btn { + color: #E3E5E6; +} + +body.dark #date-select .btn-default { + background: #636C7C; + color: #fff; + border-color: #353C48; +} + +body.dark #date-select .btn-default:hover, body.dark #date-select .btn-default[aria-expanded=true] { + background: #1E2531; +} + +#date-select .btn-default[aria-expanded=true] { + background: #e6e6e6; +} + +body.dark #date-select .btn-default.active, body.dark #date-select .btn-default.active:hover { + background: #438CAD; + border-color: #353C48; +} + +body.dark .stats { + color: #E3E5E6 !important; +} + +body.dark .message { + background: #1E2531; + color: #E3E5E6 !important; +} + +.breadcrumb { + background: #1E2531; +} + +.breadcrumb a:visited { + color: #E3E5E6; +} + +#chart-tooltip { + background: #c4c4c4 !important; + color: #000; + opacity: 0.9; + font-size: 12px; +} + +body.dark #chart-tooltip { + background: #000 !important; + color: #fff; +} + +/* DataTables issue fixing */ +.table { + font-size: 14px; +} + +div.dataTables_length select { + background: transparent; +} + +body.dark div.dataTables_length select { + color: #fff; + border-color: #353C48; +} + +.dataTables_filter input { + margin: 0 0 0 14px !important; + background: transparent; + padding: 0 5px; + border: 1px solid #747F8F; +} + +div.dataTables_length select option { + color: #31383e; +} + +div.dataTables_processing { + background: transparent !important; + padding-top: 30px !important; +} + +.dataTablesBottom { + margin: 20px 0 0 0; +} + +.pagination > .active > a, +.pagination > .active > a:focus, +.pagination > .active > a:hover, +.pagination > .active > span, .pagination > +.active > span:focus, +.pagination > .active > span:hover { + background: #438CAD; + border-color: #438CAD; +} + +.pagination > li > a, +.pagination > li > span { + background: transparent; + color: #353C48; +} + +body.dark .pagination > li > a, +body.dark .pagination > li > a:focus, +body.dark .pagination > li > span, +body.dark .pagination > li.active > span:hover, +body.dark .pagination > li.active > a:hover { + color: #E3E5E6; + border-color: #353C48; +} + +.pagination > li > span:hover, +.pagination > li > a:hover { + color: #353C48; +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/jquery.dataTables.min.css b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/jquery.dataTables.min.css new file mode 100644 index 0000000000..9ec6ca31f7 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/jquery.dataTables.min.css @@ -0,0 +1 @@ +table.dataTable{width:100%;margin:0 auto;clear:both;border-collapse:separate;border-spacing:0}table.dataTable thead th,table.dataTable tfoot th{font-weight:bold}table.dataTable thead th,table.dataTable thead td{padding:10px 18px;border-bottom:1px solid #111}table.dataTable thead th:active,table.dataTable thead td:active{outline:none}table.dataTable tfoot th,table.dataTable tfoot td{padding:10px 18px 6px 18px;border-top:1px solid #111}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc{cursor:pointer;*cursor:hand}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{background-repeat:no-repeat;background-position:center right}table.dataTable thead .sorting{background-image:url("../images/sort_both.png")}table.dataTable thead .sorting_asc{background-image:url("../images/sort_asc.png")}table.dataTable thead .sorting_desc{background-image:url("../images/sort_desc.png")}table.dataTable thead .sorting_asc_disabled{background-image:url("../images/sort_asc_disabled.png")}table.dataTable thead .sorting_desc_disabled{background-image:url("../images/sort_desc_disabled.png")}table.dataTable tbody tr{background-color:#ffffff}table.dataTable tbody tr.selected{background-color:#B0BED9}table.dataTable tbody th,table.dataTable tbody td{padding:8px 10px}table.dataTable.row-border tbody th,table.dataTable.row-border tbody td,table.dataTable.display tbody th,table.dataTable.display tbody td{border-top:1px solid #ddd}table.dataTable.row-border tbody tr:first-child th,table.dataTable.row-border tbody tr:first-child td,table.dataTable.display tbody tr:first-child th,table.dataTable.display tbody tr:first-child td{border-top:none}table.dataTable.cell-border tbody th,table.dataTable.cell-border tbody td{border-top:1px solid #ddd;border-right:1px solid #ddd}table.dataTable.cell-border tbody tr th:first-child,table.dataTable.cell-border tbody tr td:first-child{border-left:1px solid #ddd}table.dataTable.cell-border tbody tr:first-child th,table.dataTable.cell-border tbody tr:first-child td{border-top:none}table.dataTable.stripe tbody tr.odd,table.dataTable.display tbody tr.odd{background-color:#f9f9f9}table.dataTable.stripe tbody tr.odd.selected,table.dataTable.display tbody tr.odd.selected{background-color:#acbad4}table.dataTable.hover tbody tr:hover,table.dataTable.display tbody tr:hover{background-color:#f6f6f6}table.dataTable.hover tbody tr:hover.selected,table.dataTable.display tbody tr:hover.selected{background-color:#aab7d1}table.dataTable.order-column tbody tr>.sorting_1,table.dataTable.order-column tbody tr>.sorting_2,table.dataTable.order-column tbody tr>.sorting_3,table.dataTable.display tbody tr>.sorting_1,table.dataTable.display tbody tr>.sorting_2,table.dataTable.display tbody tr>.sorting_3{background-color:#fafafa}table.dataTable.order-column tbody tr.selected>.sorting_1,table.dataTable.order-column tbody tr.selected>.sorting_2,table.dataTable.order-column tbody tr.selected>.sorting_3,table.dataTable.display tbody tr.selected>.sorting_1,table.dataTable.display tbody tr.selected>.sorting_2,table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad5}table.dataTable.display tbody tr.odd>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}table.dataTable.display tbody tr.odd>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}table.dataTable.display tbody tr.odd>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:whitesmoke}table.dataTable.display tbody tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody tr.even>.sorting_1,table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#fafafa}table.dataTable.display tbody tr.even>.sorting_2,table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fcfcfc}table.dataTable.display tbody tr.even>.sorting_3,table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fefefe}table.dataTable.display tbody tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ececec}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#efefef}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a5b2cb}table.dataTable.no-footer{border-bottom:1px solid #111}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.compact thead th,table.dataTable.compact thead td{padding:4px 17px 4px 4px}table.dataTable.compact tfoot th,table.dataTable.compact tfoot td{padding:4px}table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable,table.dataTable th,table.dataTable td{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both;*zoom:1;zoom:1}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{margin-left:0.5em}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:0.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:0.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:0.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;color:#333 !important;border:1px solid transparent;border-radius:2px}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333 !important;border:1px solid #979797;background-color:white;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #dcdcdc));background:-webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-moz-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-ms-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-o-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:linear-gradient(to bottom, #fff 0%, #dcdcdc 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:white;background:-webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0)));background:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%)}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:#333}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{*margin-top:-1px;-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td{vertical-align:middle}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.dataTables_wrapper.no-footer div.dataTables_scrollHead table,.dataTables_wrapper.no-footer div.dataTables_scrollBody table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:0.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:0.5em}} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/nanoscroller.css b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/nanoscroller.css new file mode 100644 index 0000000000..5b2c5229a0 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/css/nanoscroller.css @@ -0,0 +1,55 @@ +/** initial setup **/ +.nano { + position : relative; + width : 100%; + height : 100%; + overflow : hidden; +} +.nano > .nano-content { + position : absolute; + overflow : scroll; + overflow-x : hidden; + top : 0; + right : 0; + bottom : 0; + left : 0; +} +.nano > .nano-content:focus { + outline: thin dotted; +} +.nano > .nano-content::-webkit-scrollbar { + display: none; +} +.has-scrollbar > .nano-content::-webkit-scrollbar { + display: block; +} +.nano > .nano-pane { + background : rgba(0,0,0,.25); + position : absolute; + width : 10px; + right : 0; + top : 0; + bottom : 0; + visibility : hidden\9; /* Target only IE7 and IE8 with this hack */ + opacity : .01; + -webkit-transition : .2s; + -moz-transition : .2s; + -o-transition : .2s; + transition : .2s; + -moz-border-radius : 5px; + -webkit-border-radius : 5px; + border-radius : 5px; +} +.nano > .nano-pane > .nano-slider { + background: #444; + background: rgba(0,0,0,.5); + position : relative; + margin : 0 1px; + -moz-border-radius : 3px; + -webkit-border-radius : 3px; + border-radius : 3px; +} +.nano:hover > .nano-pane, .nano-pane.active, .nano-pane.flashed { + visibility : visible\9; /* Target only IE7 and IE8 with this hack */ + opacity : 0.99; +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/fonts/FontAwesome.otf b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/fonts/FontAwesome.otf new file mode 100644 index 0000000000000000000000000000000000000000..3ed7f8b48ad9bfab52eb03822fefcd6b77d2e680 GIT binary patch literal 109688 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%0D}#zSrRb8FuaocFSDv)#ldj3 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 literal 0 HcmV?d00001 diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/fonts/fontawesome-webfont.svg b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000000..d05688e9e2 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/fonts/fontawesome-webfont.svg @@ -0,0 +1,655 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/fonts/fontawesome-webfont.ttf b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..26dea7951a73079223b50653c455c5adf46a4648 GIT binary patch literal 142072 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 +|+&Vdls@0SAya!8#E9iVniRwHu0GY;H*n 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�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%0D0!#Bo^>xe$Z4SmykflG_VnkLvLv4@e#4_y4Q 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�>=olG4!T4BYNCc4f{&*Kgc`m= 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 this.config.maxLength){ + var allowedDataSet = []; + var startingPoint = dataset.length - maxValue; + for(var i = startingPoint; i < dataset.length;i++){ + allowedDataSet.push(dataset[i]); + } + this.spec.data[0].values = allowedDataSet; + } + } + + vg.parse.spec(this.spec, viewUpdateFunction); +}; + +arc.prototype.insert = function(data) { + + var color = this.metadata.names[this.config.color]; + var x = this.metadata.names[this.config.x]; + var view =this.view; + + + + var updated = false; + + for (i = 0; i < data.length; i++) { + this.view.data(this.config.title) + .update( + function(d) { + return d[color] == data[i][color]; + }, + x, + function(d) { + updated = true; + return data[i][x]; + }); + } + + if (updated == false) { + view.data(this.config.title).insert(data); + } + + this.view.update({duration: 500}); +}; + +arc.prototype.getSpec = function() { + return this.spec; +}; + + +function getPieMark(config, metadata){ + var innerRadius; + if (config.mode == "donut") { + var innerRadius = config.width / 5 * ( 1 + config.innerRadius); + } else if (config.mode == "pie") { + var innerRadius = 0; + } else { + config.innerRadius += 0.5; + var innerRadius = config.width / 5 * ( 1 + config.innerRadius); + } + + var mark = { + "type": "arc", + "from": {"data": config.title}, + "properties": { + "update": { + "x": {"field": {"group": "width"}, "mult": 0.5}, + "y": {"field": {"group": "height"}, "mult": 0.5}, + "startAngle": {"field": "layout_start"}, + "endAngle": {"field": "layout_end"}, + "innerRadius": {"value": innerRadius}, + "outerRadius": {"value": config.width * 0.4}, + "fill": {"scale": "color", "field": metadata.names[config.color]}, + "fillOpacity": {"value": 1} + }, + + "hover": { + "fillOpacity": {"value": 0.8} + } + } + }; + + return mark; +}; +function getPieMidText(config, metadata){ + var mark = { + "type": "text", + "from": {"data": config.title}, + "properties": { + "update": { + "x": {"field": {"group": "width"}, "mult": 0.5}, + "y": {"field": {"group": "height"}, "mult": 0.5}, + "radius": { "value": 0}, + "theta": {"field": "layout_mid"}, + "fill": [ + { + "test": "indata('arc', datum.EngineType, 'type')", + "scale": "color", "field": metadata.names[config.color] + }, + {} + ], + "align": {"value": "center"}, + "baseline": {"value": "middle"}, + "fontSize":{"value": config.width/8}, + "text": {"template": "{{datum.percentage | number:'.2f'}}%"} + + } + } + }; + return mark; +}; + + +function getPieText(config, metadata){ + var mark = { + "type": "text", + "from": {"data": config.title}, + "properties": { + "update": { + "x": {"field": {"group": "width"}, "mult": 0.5}, + "y": {"field": {"group": "height"}, "mult": 0.5}, + "radius": { "value": config.width * 0.5}, + "theta": {"field": "layout_mid"}, + "fill": {"value": "#000"}, + "align": {"value": "center"}, + "baseline": {"value": "middle"}, + "text": {"template": "{{datum.percentage | number:'.2f'}}%"} + + } + } + }; + + return mark; +}; +; +var area = function(dataTable, config) { + this.metadata = dataTable[0].metadata; + var marks =[]; + var signals = []; + this.spec = {}; + + config = checkConfig(config, this.metadata); + this.config = config; + dataTable[0].name= config.title; + + var xScale = { + "name": "x", + "type": this.metadata.types[config.x], + "range": "width", + "zero": config.zero, + "domain": {"data": config.title, "field": this.metadata.names[config.x]} + }; + + var yScale = { + "name": "y", + "type": this.metadata.types[config.y], + "range": "height", + "zero": "false", + "domain": {"data": config.title, "field": this.metadata.names[config.y]} + }; + + var scales = [xScale, yScale]; + + if (config.color != -1) { + + if (config.colorDomain == -1) { + config.colorDomain = {"data": config.title, "field": this.metadata.names[config.color]}; + } + + var colorScale = { + "name": "color", + "type": "ordinal", + "domain": config.colorDomain, + "range": config.colorScale + }; + scales.push(colorScale); + + var legendTitle = "Legend"; + + if (config.title != "table") { + legendTitle = config.title; + } + + if (this.config.legend) { + this.spec.legends = getLegend(this.config); + } + } + + + var axes = getXYAxes(config, "x", "x", "y", "y"); + + marks.push(getAreaMark(config, this.metadata)); + config.fillOpacity = 0; + config.markSize = 1000; + marks.push(getSymbolMark(config, this.metadata)); + + if (config.range) { + signals = getRangeSignals(config, signals); + marks = getRangeMark(config, marks); + } + + this.spec.width = config.width; + this.spec.height = config.height; + this.spec.axes = axes; + this.spec.data = dataTable; + this.spec.scales = scales; + this.spec.padding = config.padding; + this.spec.marks = marks; + this.spec.signals = signals; +}; + +area.prototype.draw = function(div, callbacks) { + + if(this.config.maxLength != -1){ + var dataset = this.spec.data[0].values; + var maxValue = this.config.maxLength; + if(dataset.length >= this.config.maxLength){ + var allowedDataSet = []; + var startingPoint = dataset.length - maxValue; + for(var i = startingPoint; i < dataset.length;i++){ + allowedDataSet.push(dataset[i]); + } + this.spec.data[0].values = allowedDataSet; + } + } + + drawChart(div, this, callbacks); + +}; + +area.prototype.insert = function(data) { + //Removing events when max value is enabled + if (this.config.maxLength != -1 && this.config.maxLength < (this.view.data(this.config.title).values().length + data.length)) { + var removeFunction = (function(d) { + return d[this.metadata.names[this.config.x]] == oldData; + }).bind(this); + + for (i = 0; i < data.length; i++) { + var oldData = this.view.data(this.config.title).values()[i][this.metadata.names[this.config.x]]; + this.view.data(this.config.title).remove(removeFunction); + } + } + + this.view.data(this.config.title).insert(data); + this.view.update(); +}; + +area.prototype.getSpec = function() { + return this.spec; +}; + + +function getAreaMark(config, metadata){ + + var mark; + if (config.color != -1) { + mark = { + "type": "group", + "from": { + "data": config.title, + "transform": [{"type": "facet", "groupby": [metadata.names[config.color]]}] + }, + "marks": [ + { + "type": "area", + "properties": { + "update": { + "x": {"scale": "x", "field": metadata.names[config.x]}, + "y": {"scale": "y", "field": metadata.names[config.y]}, + "y2": {"scale": "y", "value": 0}, + "fill": {"scale": "color", "field": metadata.names[config.color]}, + "strokeWidth": {"value": 2}, + "strokeOpacity": {"value": 1} + }, + "hover": { + "strokeOpacity": {"value": 0.5} + } + } + } + ] + }; + }else{ + mark = { + "type": "area", + "from": {"data": config.title}, + "properties": { + "update": { + + "x": {"scale": "x", "field": metadata.names[config.x]}, + "y": {"scale": "y", "field": metadata.names[config.y]}, + "y2": {"scale": "y", "value": 0}, + "fill": { "value": config.markColor}, + "strokeWidth": {"value": 2}, + "fillOpacity": {"value": 1} + }, + "hover": { + "fillOpacity": {"value": 0.5} + } + } + }; + } + + + return mark; +} + +; +var bar = function(dataTable, config) { + this.metadata = dataTable[0].metadata; + var marks =[]; + var scales =[]; + this.spec = {}; + var yColumn; + var yDomain; + + var xRange; + var yRange; + var xAxesType; + var yAxesType; + var signals = []; + + config = checkConfig(config, this.metadata); + this.config = config; + dataTable[0].name= config.title; + + if (config.orientation == "left") { + xRange = "height"; + yRange = "width"; + xAxesType = "y"; + yAxesType = "x"; + } else { + xRange = "width"; + yRange = "height"; + xAxesType = "x"; + yAxesType = "y"; + } + + if (config.color != -1) { + var legendTitle = "Legend"; + if (config.title != "table") { + legendTitle = config.title; + } + if (config.colorDomain == -1) { + config.colorDomain = {"data": config.title, "field": this.metadata.names[config.color]}; + } + + var colorScale = { + "name": "color", + "type": "ordinal", + "domain": config.colorDomain, + "range": config.colorScale + }; + + scales.push(colorScale); + + + + if (config.mode == "stack") { + var aggregateData = { + "name": "stack", + "source": config.title, + "transform": [ + { + "type": "aggregate", + "groupby": [this.metadata.names[config.x]], + "summarize": [{"field": this.metadata.names[config.y], "ops": ["sum"]}] + } + ] + }; + + dataTable.push(aggregateData); + yColumn = "sum_"+ this.metadata.names[config.y]; + yDomain = "stack"; + + } else { + yColumn = this.metadata.names[config.y]; + yDomain = config.title; + } + + if (this.config.legend) { + this.spec.legends = getLegend(this.config); + } + } else { + yColumn = this.metadata.names[config.y]; + yDomain = config.title; + } + + var xScale = { + "name": "x", + "type": "ordinal", + "range": xRange, + "domain": {"data": config.title, "field": this.metadata.names[config.x]} + }; + + if (config.mode == "group") { + xScale.padding = 0.2; + } + + var yScale = { + "name": "y", + "type": this.metadata.types[config.y], + "range": yRange, + "domain": {"data": yDomain, "field": yColumn} + }; + + + + scales.push(xScale); + scales.push(yScale); + + var axes = getXYAxes(config, xAxesType, "x", yAxesType, "y"); + + if (config.color != -1 && config.mode == "stack") { + marks.push(getStackBarMark(config, this.metadata)); + } else if (config.color != -1 && config.mode == "group") { + marks.push(getGroupBarMark(config, this.metadata)); + } else { + marks.push(getBarMark(config, this.metadata)); + } + + if (config.range) { + signals = getRangeSignals(config, signals); + marks = getRangeMark(config, marks); + } + + this.spec.width = config.width; + this.spec.height = config.height; + this.spec.axes = axes; + this.spec.data = dataTable; + this.spec.scales = scales; + this.spec.padding = config.padding; + this.spec.marks = marks; + this.spec.signals = signals; + + var specc = JSON.stringify(this.spec); +}; + +bar.prototype.draw = function(div, callbacks) { + if(this.config.maxLength != -1){ + var dataset = this.spec.data[0].values; + var maxValue = this.config.maxLength; + if(dataset.length >= this.config.maxLength){ + var allowedDataSet = []; + var startingPoint = dataset.length - maxValue; + for(var i = startingPoint; i < dataset.length;i++){ + allowedDataSet.push(dataset[i]); + } + this.spec.data[0].values = allowedDataSet; + } + } + this.config.tooltip.type = "rect"; + drawChart(div, this, callbacks); +}; + +bar.prototype.insert = function(data) { + + var xAxis = this.metadata.names[this.config.x]; + var yAxis = this.metadata.names[this.config.y]; + var size = this.metadata.names[this.config.size]; + var color = this.metadata.names[this.config.color]; + + if (this.config.maxLength != -1 && this.config.maxLength < (this.view.data(this.config.title).values().length + data.length)) { + + var allDataSet = this.view.data(this.config.title).values().concat(data); + var allowedRemovableDataSet = []; + for (i = 0; i < allDataSet.length - this.config.maxLength; i++) { + allowedRemovableDataSet.push(this.view.data(this.config.title).values()[i][xAxis]); + } + + for (i = 0; i < data.length; i++) { + var isValueMatched = false; + this.view.data(this.config.title).update(function(d) { + if (color == null) { + return d[xAxis] == data[i][xAxis]; + } else { + return d[xAxis] == data[i][xAxis] && d[color] == data[i][color]; + } + }, + yAxis, + function(d) { + isValueMatched = true; + return data[i][yAxis]; + }); + + if(isValueMatched){ + var isIndexRemoved = false; + + var index = allowedRemovableDataSet.indexOf(data[i][xAxis]); + if (index > -1) { + // updated value matched in allowed removable values + isIndexRemoved = true; + allowedRemovableDataSet.splice(index, 1); + } + + if(!isIndexRemoved){ + // updated value NOT matched in allowed removable values + allowedRemovableDataSet.splice((allowedRemovableDataSet.length - 1), 1); + } + + } else { + //insert the new data + this.view.data(this.config.title).insert([data[i]]); + this.view.update(); + } + } + + var oldData; + var removeFunction = function(d) { + return d[xAxis] == oldData; + }; + + for (i = 0; i < allowedRemovableDataSet.length; i++) { + oldData = allowedRemovableDataSet[i]; + this.view.data(this.config.title).remove(removeFunction); + } + } else{ + for (i = 0; i < data.length; i++) { + var isValueMatched = false; + this.view.data(this.config.title).update(function(d) { + if (color == null) { + return d[xAxis] == data[i][xAxis]; + } else { + return d[xAxis] == data[i][xAxis] && d[color] == data[i][color]; + } + }, + yAxis, + function(d) { + isValueMatched = true; + return data[i][yAxis]; + }); + + if(!isValueMatched){ + this.view.data(this.config.title).insert([data[i]]); + } + } + } + + //Group does not support duration update animation + if (this.config.mode == "group") { + this.view.update(); + } else { + this.view.update({duration: 200}); + } +}; + +bar.prototype.getSpec = function() { + return this.spec; +}; + + +function getBarMark(config, metadata){ + var markContent; + if (config.orientation == "left") { + markContent = { + "y": {"scale": "x", "field": metadata.names[config.x]}, + "height": {"scale": "x", "band": true, "offset": -10}, + "x": {"scale": "y", "field": metadata.names[config.y]}, + "x2": {"scale": "y", "value": 0}, + "fill": {"value": config.markColor}, + "fillOpacity": {"value": 1} + }; + } else { + markContent = { + "x": {"scale": "x", "field": metadata.names[config.x]}, + "width": {"scale": "x", "band": true, "offset": -10}, + "y": {"scale": "y", "field": metadata.names[config.y]}, + "y2": {"scale": "y", "value": 0}, + "fill": {"value": config.markColor}, + "fillOpacity": {"value": 1} + }; + } + + var mark = { + "type": "rect", + "from": {"data": config.title}, + "properties": { + "update": markContent, + "hover": { + "fillOpacity": {"value": 0.5} + } + } + }; + + + return mark; +} + +function getStackBarMark(config, metadata){ + + var markContent; + if (config.orientation == "left") { + mark = { + "type": "rect", + "from": { + "data": config.title, + "transform": [ + { "type": "stack", + "groupby": [metadata.names[config.x]], + "sortby": [metadata.names[config.color]], + "field":metadata.names[config.y]} + ] + }, + "properties": { + "update": { + "y": {"scale": "x", "field": metadata.names[config.x]}, + "height": {"scale": "x", "band": true, "offset": -10}, + "x": {"scale": "y", "field": "layout_start"}, + "x2": {"scale": "y", "field": "layout_end"}, + "fill": {"scale": "color", "field": metadata.names[config.color]}, + "fillOpacity": {"value": 1} + }, + "hover": { + "fillOpacity": {"value": 0.5} + } + } + }; + } else { + mark = { + "type": "rect", + "from": { + "data": config.title, + "transform": [ + { "type": "stack", + "groupby": [metadata.names[config.x]], + "sortby": [metadata.names[config.color]], + "field":metadata.names[config.y]} + ] + }, + "properties": { + "update": { + "x": {"scale": "x", "field": metadata.names[config.x]}, + "width": {"scale": "x", "band": true, "offset": -10}, + "y": {"scale": "y", "field": "layout_start"}, + "y2": {"scale": "y", "field": "layout_end"}, + "fill": {"scale": "color", "field": metadata.names[config.color]}, + "fillOpacity": {"value": 1} + }, + "hover": { + "fillOpacity": {"value": 0.5} + } + } + }; + } + + + + + return mark; +} + +function getGroupBarMark(config, metadata){ + var mark; + if (config.orientation == "left") { + mark = { + "type": "group", + "from": { + "data": config.title, + "transform": [{"type":"facet", "groupby": [metadata.names[config.x]]}] + }, + "properties": { + "update": { + "y": {"scale": "x", "field": "key"}, + "height": {"scale": "x", "band": true} + } + }, + "scales": [ + { + "name": "pos", + "type": "ordinal", + "range": "height", + "domain": {"field": metadata.names[config.color]} + } + ], + "marks": [ + { + "name": "bars", + "type": "rect", + "properties": { + "update": { + "y": {"scale": "pos", "field": metadata.names[config.color]}, + "height": {"scale": "pos", "band": true}, + "x": {"scale": "y", "field": metadata.names[config.y]}, + "x2": {"scale": "y", "value": 0}, + "fill": {"scale": "color", "field": metadata.names[config.color]}, + "fillOpacity": {"value": 1} + }, + "hover": { + "fillOpacity": {"value": 0.5} + } + } + } + ] + }; + } else { + mark = { + "type": "group", + "from": { + "data": config.title, + "transform": [{"type":"facet", "groupby": [metadata.names[config.x]]}] + }, + "properties": { + "update": { + "x": {"scale": "x", "field": "key"}, + "width": {"scale": "x", "band": true} + } + }, + "scales": [ + { + "name": "pos", + "type": "ordinal", + "range": "width", + "domain": {"field": metadata.names[config.color]} + } + ], + "marks": [ + { + "name": "bars", + "type": "rect", + "properties": { + "update": { + "x": {"scale": "pos", "field": metadata.names[config.color]}, + "width": {"scale": "pos", "band": true}, + "y": {"scale": "y", "field": metadata.names[config.y]}, + "y2": {"scale": "y", "value": 0}, + "fill": {"scale": "color", "field": metadata.names[config.color]}, + "fillOpacity": {"value": 1} + }, + "hover": { + "fillOpacity": {"value": 0.5} + } + } + } + ] + }; + } + return mark; +} + +;var vizg = function(dataTable, config) { + dataTable = buildTable(dataTable); + if (typeof config.charts !== "undefined" && config.charts.length == 1) { + //Set chart config properties for main + for (var property in config.charts[0]) { + if (config.charts[0].hasOwnProperty(property)) { + config[property] = config.charts[0][property]; + } + } + + this.chart = new window[config.type]([dataTable], config); + } +}; + +vizg.prototype.draw = function(div, callback) { + this.chart.draw(div, callback); +}; + +vizg.prototype.insert = function(data) { + this.chart.insert(buildData(data, this.chart.metadata)); +}; + +vizg.prototype.getSpec = function() { + return this.chart.getSpec(); +};;var line = function(dataTable, config) { + this.metadata = dataTable[0].metadata; + var marks =[]; + var signals = []; + this.spec = {}; + + config = checkConfig(config, this.metadata); + this.config = config; + dataTable[0].name= config.title; + + var xScale = { + "name": "x", + "type": this.metadata.types[config.x], + "range": "width", + "zero": config.zero, + "domain": {"data": config.title, "field": this.metadata.names[config.x]} + }; + + var yScale = { + "name": "y", + "type": this.metadata.types[config.y], + "range": "height", + "zero": config.zero, + "domain": {"data": config.title, "field": this.metadata.names[config.y]} + }; + + var scales = [xScale, yScale]; + + if (config.color != -1) { + + if (config.colorDomain == -1) { + config.colorDomain = {"data": config.title, "field": this.metadata.names[config.color]}; + } + + var colorScale = { + "name": "color", + "type": "ordinal", + "domain": config.colorDomain, + "range": config.colorScale + }; + scales.push(colorScale); + } + + var axes = getXYAxes(config, "x", "x", "y", "y"); + + marks.push(getLineMark(config, this.metadata)); + config.markSize = 20; + marks.push(getSymbolMark(config, this.metadata)); + + if (config.range) { + signals = getRangeSignals(config, signals); + marks = getRangeMark(config, marks); + } + + if (config.color != -1) { + + var legendTitle = "Legend"; + + if (config.title != "table") { + legendTitle = config.title; + } + + if (this.config.legend) { + this.spec.legends = getLegend(this.config); + } + + } + + this.spec.width = config.width; + this.spec.height = config.height; + this.spec.axes = axes; + this.spec.data = dataTable; + this.spec.scales = scales; + this.spec.padding = config.padding; + this.spec.marks = marks; + this.spec.signals = signals; + +}; + +line.prototype.draw = function(div, callbacks) { + if(this.config.maxLength != -1){ + var dataset = this.spec.data[0].values; + var maxValue = this.config.maxLength; + if(dataset.length >= this.config.maxLength){ + var allowedDataSet = []; + var startingPoint = dataset.length - maxValue; + for(var i = startingPoint; i < dataset.length;i++){ + allowedDataSet.push(dataset[i]); + } + this.spec.data[0].values = allowedDataSet; + } + } + + drawChart(div, this, callbacks); + +}; + +line.prototype.insert = function(data) { + //Removing events when max value is enabled + if (this.config.maxLength != -1 && this.config.maxLength < (this.view.data(this.config.title).values().length + data.length)) { + var removeFunction = (function(d) { + return d[this.metadata.names[this.config.x]] == oldData; + }).bind(this); + + for (i = 0; i < data.length; i++) { + var oldData = this.view.data(this.config.title).values()[i][this.metadata.names[this.config.x]]; + this.view.data(this.config.title).remove(removeFunction); + } + } + + this.view.data(this.config.title).insert(data); + this.view.update(); +}; + +line.prototype.getSpec = function() { + return this.spec; +}; + +function getLineMark(config, metadata){ + var mark; + if (config.color != -1) { + mark = { + "type": "group", + "from": { + "data": config.title, + "transform": [{"type": "facet", "groupby": [metadata.names[config.color]]}] + }, + "marks": [ + { + "type": "line", + "properties": { + "update": { + "x": {"scale": "x", "field": metadata.names[config.x]}, + "y": {"scale": "y", "field": metadata.names[config.y]}, + "stroke": {"scale": "color", "field": metadata.names[config.color]}, + "strokeWidth": {"value": 2}, + "strokeOpacity": {"value": 1} + }, + "hover": { + "strokeOpacity": {"value": 0.5} + } + } + } + ] + }; + } else { + mark = { + "type": "line", + "from": {"data": config.title}, + "properties": { + "update": { + + "x": {"scale": "x", "field": metadata.names[config.x]}, + "y": {"scale": "y", "field": metadata.names[config.y]}, + "stroke": { "value": config.markColor}, + "strokeWidth": {"value": 2}, + "strokeOpacity": {"value": 1} + }, + "hover": { + "strokeOpacity": {"value": 0.5} + } + } + }; + } + + return mark; +} + +;var map = function(dataTable, config) { + + this.metadata = dataTable[0].metadata; + var marks ; + var signals ; + var predicates = []; + var legends = []; + this.spec = {}; + var geoInfoJson ; + + geoInfoJson = loadGeoMapCodes(config.helperUrl); + config = checkConfig(config, this.metadata); + this.config = config; + this.config.geoInfoJson = geoInfoJson; + + for (i = 0; i < dataTable[0].values.length; i++) { + for (var key in dataTable[0].values[i]) { + if(key == dataTable[0].metadata.names[config.x]){ + if (dataTable[0].values[i].hasOwnProperty(key)) { + dataTable[0].values[i].unitName = dataTable[0].values[i][key]; + dataTable[0].values[i][key] = getMapCode(dataTable[0].values[i][key], config.mapType,geoInfoJson); + break; + } + } + } + }; + + dataTable[0].name = config.title; + dataTable[0].transform = [ + { + "type": "formula", + "field": "v", + "expr": "datum."+this.metadata.names[config.y] + } + ]; + + if (config.tooltip.enabled) { + marks = getMapMark(config, this.metadata); + signals = getMapSignals(); + this.spec.signals = signals; + } + + dataTable.push(getTopoJson(config,this.metadata)); + predicates.push(getMapPredicates()); + legends.push(getMapLegends(config,this.metadata)); + + var cScale = { + "name": "color", + "type": "linear", + "domain": {"data": "geoData","field": "zipped.v"}, + "domainMin": 0.0, + "zero": false, + "range": config.colorScale + }; + + var scales = [cScale]; + + this.spec.width = config.width; + this.spec.height = config.height; + this.spec.data = dataTable; + this.spec.scales = scales; + this.spec.padding = config.padding; + this.spec.marks = marks; + this.spec.predicates = predicates; + this.spec.legends = legends; + +}; + +map.prototype.draw = function(div, callbacks) { + var viewUpdateFunction = (function(chart) { + this.view = chart({el:div}).renderer(this.config.renderer).update(); + + if (callbacks != null) { + for (var i = 0; i
" + +"

" + +textContent+"

"; + + document.getElementById(div).innerHTML = divContent; + this.view = contentId; +}; + +number.prototype.insert = function(data) { + document.getElementById(this.view).innerHTML = data[data.length-1][this.metadata.names[this.config.x]]; +}; + + + +;var scatter = function(dataTable, config) { + + this.metadata = dataTable[0].metadata; + var marks = []; + var signals ; + this.spec = {}; + + config = checkConfig(config, this.metadata); + this.config = config; + dataTable[0].name = config.title; + + var xScale = { + "name": "x", + "type": this.metadata.types[config.x], + "range": "width", + "zero": config.zero, + "domain": {"data": config.title, "field": this.metadata.names[config.x]} + }; + + var yScale = { + "name": "y", + "type": this.metadata.types[config.y], + "range": "height", + "zero": config.zero, + "domain": {"data": config.title, "field": this.metadata.names[config.y]} + }; + + var rScale = { + "name": "size", + "type": "linear", + "range": [0,576], + "domain": {"data": config.title, "field": this.metadata.names[config.size]} + }; + + var cScale = { + "name": "color", + "type": this.metadata.types[config.color], + "range": config.colorScale, + "domain": {"data": config.title, "field": this.metadata.names[config.color]} + }; + + var scales = [xScale, yScale, rScale, cScale]; + var axes = getXYAxes(config, "x", "x", "y", "y"); + + marks.push(getScatterMark(config, this.metadata)); + + this.spec.width = config.width; + this.spec.height = config.height; + this.spec.axes = axes; + this.spec.data = dataTable; + this.spec.scales = scales; + this.spec.padding = config.padding; + this.spec.marks = marks; + +}; + +scatter.prototype.draw = function(div, callbacks) { + var viewUpdateFunction = (function(chart) { + if(this.config.tooltip.enabled){ + createTooltip(div); + this.view = chart({el:div}).renderer(this.config.renderer).update(); + bindTooltip(div,this.view,this.config,this.metadata); + } else { + this.view = chart({el:div}).renderer(this.config.renderer).update(); + } + if (callbacks != null) { + for (var i = 0; i= this.config.maxLength){ + var allowedDataSet = []; + var startingPoint = dataset.length - maxValue; + for(var i = startingPoint; i < dataset.length;i++){ + allowedDataSet.push(dataset[i]); + } + this.spec.data[0].values = allowedDataSet; + } + } + + vg.parse.spec(this.spec, viewUpdateFunction); +}; + +scatter.prototype.insert = function(data) { + + var xAxis = this.metadata.names[this.config.x]; + var yAxis = this.metadata.names[this.config.y]; + var size = this.metadata.names[this.config.size]; + var color = this.metadata.names[this.config.color]; + + if (this.config.maxLength != -1 && this.config.maxLength < (this.view.data(this.config.title).values().length + data.length)) { + + var allDataSet = this.view.data(this.config.title).values().concat(data); + var allowedRemovableDataSet = []; + for (i = 0; i < allDataSet.length - this.config.maxLength; i++) { + allowedRemovableDataSet.push(this.view.data(this.config.title).values()[i][xAxis]); + } + + for (i = 0; i < data.length; i++) { + var isValueMatched = false; + this.view.data(this.config.title).update(function(d) { + return d[xAxis] == data[i][xAxis]; }, + yAxis, + function(d) { + isValueMatched = true; + return data[i][yAxis]; + }); + + this.view.data(this.config.title).update(function(d) { + return d[xAxis] == data[i][xAxis]; }, + color, + function(d) { + isValueMatched = true; + return data[i][color]; + }); + + this.view.data(this.config.title).update(function(d) { + return d[xAxis] == data[i][xAxis]; }, + size, + function(d) { + isValueMatched = true; + return data[i][size]; + }); + + if(isValueMatched){ + var isIndexRemoved = false; + + var index = allowedRemovableDataSet.indexOf(data[i][xAxis]); + if (index > -1) { + // updated value matched in allowed removable values + isIndexRemoved = true; + allowedRemovableDataSet.splice(index, 1); + } + + if(!isIndexRemoved){ + // updated value NOT matched in allowed removable values + allowedRemovableDataSet.splice((allowedRemovableDataSet.length - 1), 1); + } + + } else { + //insert the new data + this.view.data(this.config.title).insert([data[i]]); + this.view.update(); + } + } + + var oldData; + var removeFunction = function(d) { + return d[xAxis] == oldData; + }; + + for (i = 0; i < allowedRemovableDataSet.length; i++) { + oldData = allowedRemovableDataSet[i]; + this.view.data(this.config.title).remove(removeFunction); + } + } else{ + for (i = 0; i < data.length; i++) { + var isValueMatched = false; + this.view.data(this.config.title).update(function(d) { + return d[xAxis] == data[i][xAxis]; }, + yAxis, + function(d) { + isValueMatched = true; + return data[i][yAxis]; + }); + + this.view.data(this.config.title).update(function(d) { + return d[xAxis] == data[i][xAxis]; }, + color, + function(d) { + isValueMatched = true; + return data[i][color]; + }); + + this.view.data(this.config.title).update(function(d) { + return d[xAxis] == data[i][xAxis]; }, + size, + function(d) { + isValueMatched = true; + return data[i][size]; + }); + + if(!isValueMatched){ + this.view.data(this.config.title).insert([data[i]]); + } + } + } + this.view.update({duration: 200}); +}; + +scatter.prototype.getSpec = function() { + return this.spec; +}; + + +function getScatterMark(config, metadata){ + var fill; + var size; + + if (config.color == -1) { + fill = {"value": config.markColor}; + } else { + fill = {"scale": "color", "field": metadata.names[config.color]}; + } + + if (config.size == -1) { + size = {"value": config.markSize * 50}; + } else { + size = {"scale":"size","field":metadata.names[config.size]}; + } + + var mark = { + + "type": "symbol", + "from": {"data": config.title}, + "properties": { + "update": { + "x": {"scale": "x", "field": metadata.names[config.x]}, + "y": {"scale": "y", "field": metadata.names[config.y]}, + "fill": fill, + "size": size, + "fillOpacity": {"value": 1} + }, + "hover": { + "fillOpacity": {"value": 0.5} + } + } + + } + ; + + + return mark; +} + +function getScatterToolTipMark(config, metadata) { + config.toolTip.height = 50; + config.toolTip.y = -50; + + var mark = getToolTipMark(config, metadata); + var sizeText = { + "type": "text", + "properties": { + "update": { + "x": {"value": 6}, + "y": {"value": 44}, + "text": {"template": "Size \t (" + metadata.names[config.size] + ") \t {{hover." + metadata.names[config.size] + "}}"}, + "fill": {"value": "black"} + } + } + }; + mark.marks.push(sizeText); + return mark; +} +; +var table = function(dataTable, config) { + this.metadata = dataTable[0].metadata; + this.data = dataTable[0].values + var marks =[]; + this.spec = {}; + config = checkConfig(config, this.metadata); + this.config = config; + dataTable[0].name= config.title; + +}; + +table.prototype.draw = function(div) { + var table = d3.select(div).append("table") + .attr( "class", "table table-bordered") + .attr("id", this.config.title); + + // set up the table header + table.append('thead').attr("align", "center") + .append('tr') + .selectAll('th') + .data(this.config.columnTitles) + .enter() + .append('th') + .html(function (d) { return d }); + + table.append('tbody').attr("id", "tableChart-"+this.config.title); + this.setupData(this.data, this.config); + + table.selectAll("thead th") + .html(function(column) { + return column.charAt(0).toUpperCase() + column.substr(1); + }); + + + }; + +table.prototype.insert = function(data) { + this.setupData(data, this.config); +}; + + +table.prototype.setupData = function (dataset, config) { + var data = []; + var allColumns = this.metadata.names; + + //Select specified columns from dataset + for (var i = 0; i < dataset.length; i++) { + var row = {}; + + for (var x = 0; x < config.columns.length; x++) { + row[config.columns[x]] = dataset[i][config.columns[x]]; + } + data.push(row); + } + + //Select Rows by x Axis + var rows = d3.select('#tableChart-'+config.title) + .selectAll('tr') + .data(data, function(d) { return d[config.key]}) + + var entertd = rows.enter() + .append('tr') + .selectAll('td') + .data(function(row) { + return config.columns.map(function(column) { + return {column: column, value: row[column]}; + }); + }) + .enter() + .append('td') + + //Color cell background + if (config.color != -1) { + d3.select('#tableChart-'+config.title) + .selectAll('td') + .attr('bgcolor', + function(d) { + var column = d.key || d.column; + + var color; + if (typeof config.colorScale == "string") { + color = window["d3"]["scale"][config.colorScale]().range(); + } else { + color = config.colorScale; + } + + var colorIndex; + for(var i = 0; i < allColumns.length; i += 1) { + if(allColumns[i] === column) { + colorIndex = i; + } + } + + if (typeof d.value == "string") { + + var colorDomain; + + if (config.colorDomain == -1) { + colorDomain = [d3.min(d3.select('#tableChart-'+config.title) .selectAll('tr') .data(), function(d) { return d[column]; }), + d3.max(d3.select('#tableChart-'+config.title) .selectAll('tr') .data(), function(d) { return d[column]; })] + + } else { + colorDomain = config.colorDomain + } + + var colorScale = d3.scale.ordinal() + .range(config.colorScale) + .domain(colorDomain); + return colorScale(d.value); + + } else if (config.color == "*" || column == allColumns[config.color]){ + + var colorScale = d3.scale.linear() + .range(['#f2f2f2', color[colorIndex]]) + .domain([d3.min(d3.select('#tableChart-'+config.title) .selectAll('tr') .data(), function(d) { return d[column]; }), + d3.max(d3.select('#tableChart-'+config.title) .selectAll('tr') .data(), function(d) { return d[column]; })] + ); + + return colorScale(d.value); + } + + }); + } + + + + entertd.append('span') + var td = rows.selectAll('td') + .style({"padding": "0px 10px 0px 10px"}) + + .data(function(d) { return d3.map(d).entries() }) + .attr('class', function (d) { return d.key }) + + + + + td.select('span') + .html(function(d) { + return d.value + }) + //Remove data items when it hits maxLength + if (config.maxLength != -1 && d3.select('tbody').selectAll('tr').data().length > config.maxLength) { + var allowedDataset = d3.select('tbody').selectAll('tr').data().slice(d3.select('tbody').selectAll('tr').data().length- config.maxLength, config.maxLength); + d3.select('tbody').selectAll('tr').data(allowedDataset, + function(d) { + return(d); + }) + .remove(); + } +};var extend = function (defaults, options) { + var extended = {}; + var prop; + for (prop in defaults) { + if (Object.prototype.hasOwnProperty.call(defaults, prop)) { + extended[prop] = defaults[prop]; + } + } + for (prop in options) { + if (Object.prototype.hasOwnProperty.call(options, prop)) { + extended[prop] = options[prop]; + } + } + return extended; +}; + +function checkConfig(config, metadata){ + + if (config.color == null) { + config.color = -1; + } else if (config.color != "*"){ + config.color = metadata.names.indexOf(config.color); + } + + if (config.size == null) { + config.size = -1; + } else { + config.size = metadata.names.indexOf(config.size); + } + + var defaults = { + title: "table", + mapType: -1, + mode: "stack", + //color hex array or string: category10, 10c, category20, category20b, category20c + colorScale: "category10", + colorDomain: -1, + maxLength: -1, + markSize: 2, + fillOpacity: 1, + innerRadius:0, + //string: canvas or svg + renderer: "svg", + padding: {"top": 10, "left": 50, "bottom": 40, "right": 100}, + dateFormat: "%x %X", + range:false, + rangeColor:"#222", + + mapColor:"#888", + + //Tool Configs + tooltip: {"enabled":true, "color":"#e5f2ff", "type":"symbol"}, + + //Legend Configs + legend:true, + legendTitle: "Legend", + legendTitleColor: "#222", + legendTitleFontSize: 13, + legendTextColor: "#888", + ledgendTextFontSize: 12, + + //Axes Configs + xTitle: config.x, + yTitle: config.y, + xAxisAngle:false, + yAxisAngle:false, + axesColor:"#222", + axesSize:1, + axesFontSize:10, + titleFontSize:12, + titleFontColor:"#222", + grid: true, + zero: false, + xTicks: 0, + yTicks: 0, + xFormat: "", + yFormat: "" + + + }; + + if (typeof vizgSettings != 'undefined'){ + defaults = extend(defaults, vizgSettings); + } + + config = extend(defaults, config); + config.height = config.height - (config.padding.top + config.padding.bottom); + config.width = config.width - (config.padding.left + config.padding.right); + + if (typeof config.colorScale == "string") { + config.markColor = window["d3"]["scale"][config.colorScale]().range()[0]; + } else { + config.markColor = config.colorScale[0]; + } + + config.x = metadata.names.indexOf(config.x); + config.y = metadata.names.indexOf(config.y); + + return config; +} + +function buildTable(datatable) { + var chartDatatable = {}; + chartDatatable.metadata = datatable[0].metadata; + chartDatatable.values = buildData(datatable[0].data, datatable[0].metadata); + return chartDatatable; +} + + +function buildData(data, metadata) { + chartData = []; + for (i = 0; i < data.length; i++) { + var row = {}; + for (x = 0; x < metadata.names.length; x++) { + row[metadata.names[x]] = data[i][x]; + } + chartData.push(row); + } + return chartData; +} + +/* + General function used to draw circle symbols graphs +*/ +function getSymbolMark(config, metadata) { + + var fill; + if (config.color != -1) { + fill = {"scale": "color", "field": metadata.names[config.color]}; + } else { + fill = {"value":config.markColor}; + } + +var mark = { + "type": "symbol", + "from": {"data": config.title}, + "properties": { + "update": { + "x": {"scale": "x", "field": metadata.names[config.x]}, + "y": {"scale": "y", "field": metadata.names[config.y]}, + "fill": fill, + "size": {"value": config.markSize}, + "fillOpacity": {"value": config.fillOpacity} + } + } + } + + return mark; +} + + + +function getSignals(config, metadata){ + + var signals = [{ + "name": "hover", + "init": {}, + "streams": [ + {"type": config.hoverType+":mouseover", "expr": "datum"}, + {"type": config.hoverType+":mouseout", "expr": "{}"} + ] + }]; + + return signals; + +} + +function bindTooltip(div,markType,eventObj, config, metaData, keyList){ + + eventObj.on("mouseover", function(event, item) { + + if (item != null && item.status != "exit" && item.mark.marktype == markType) { + var canvas = $(".marks")[0]; + if($("#wrapper #tip").length) { + $tip.remove(); + } + + $(div).wrap( "
" ); + + $("#wrapper").append("
"); + $tip=$('#tip'); + $tip.empty(); + + var dataObj = item.datum; + var dynamicContent = ""; + for (var key in dataObj) { + if (dataObj.hasOwnProperty(key)) { + if(keyList != undefined){ + for(var z=0;z"; + break; + } + } + } + }else{ + if(metaData.names[config.x] == key){ + dynamicContent += "

X ("+key+"):"+dataObj[key]+"

"; + } + if(metaData.names[config.y] == key){ + dynamicContent += "

Y ("+key+"):"+dataObj[key]+"

"; + } + } + } + } + + $tip.append(dynamicContent); + + var canvasWidth = canvas.width; + var canvasHeight = canvas.height; + + var el = $('.marks[style*="width"]'); + + if(el.length > 0){ + canvasWidth = parseFloat($(".marks")[0].style.width); + canvasHeight = parseFloat($(".marks")[0].style.height); + } + var dynamicWidth = $tip.width(); + var dynamicHeight = $tip.height(); + + var toolTipWidth = item.bounds.x2 + config.padding.left + dynamicWidth; + var toolTipHeight = (canvasHeight - item.bounds.y2) - config.padding.top + dynamicHeight; + var toolTipCalculatedXPosition; + var toolTipCalculatedYPosition = ((item.bounds.y2 + config.padding.top) - dynamicHeight); + + if(toolTipWidth > canvasWidth){ + toolTipCalculatedXPosition = ((item.bounds.x2 + config.padding.left) - dynamicWidth); + }else{ + toolTipCalculatedXPosition = (item.bounds.x2 + config.padding.left); + } + + if(toolTipHeight > canvasHeight){ + toolTipCalculatedYPosition = item.bounds.y2 + config.padding.top; + } + + $tip.css({left:toolTipCalculatedXPosition,top:toolTipCalculatedYPosition}).show(); + }else{ + + if($("#wrapper #tip").length) { + $tip.remove(); + } + if($(div).closest("#wrapper").length) { + $(div).unwrap(); + } + } + }) +}; + + + +function createTooltip(div) { + document.getElementById(div.replace("#", "")).innerHTML = document.getElementById(div.replace("#", "")).innerHTML + + "
"; +} + +function bindTooltip(div, view, config, metadata){ + + view.on("mouseover", function(event, item) { + if (item != null && item.mark.marktype == config.tooltip.type) { + var tooltipDiv = document.getElementById(div.replace("#", "")+"-tooltip"); + var tooltipContent = ""; + + if (item.datum[metadata.names[config.x]]!= null) { + var content; + + //Default tooltip content if tooltip content is not defined + if (config.tooltip.content == null) { + if (metadata.types[config.x]== "time") { + var dFormat = d3.time.format(config.dateFormat); + content = dFormat(new Date(parseInt(item.datum[metadata.names[config.x]]))); + } else { + content = item.datum[metadata.names[config.x]]; + } + + tooltipContent += ""+ metadata.names[config.x] +" : "+content+"
" ; + + if (item.datum[metadata.names[config.y]] != null) { + tooltipContent += ""+ metadata.names[config.y] + " : "+item.datum[metadata.names[config.y]]+"
" + } + + } else { + //check all specified column and add them as tooltip content + for (var i = 0; i < config.tooltip.content.length; i++) { + if (metadata.types[metadata.names.indexOf(config.tooltip.content[i])]=== "time") { + var dFormat = d3.time.format(config.dateFormat); + content = dFormat(new Date(parseInt(item.datum[metadata.names[config.x]]))); + } else { + content = item.datum[config.tooltip.content[i]]; + } + + if (config.tooltip.label != false) { + tooltipContent += ""+ config.tooltip.content[i] +" : "+content+"
" ; + } else { + tooltipContent += content+"
" ; + } + }; + + } + + + } + + + if (tooltipContent != "") { + tooltipDiv.innerHTML = tooltipContent; + tooltipDiv.style.padding = "5px 5px 5px 5px"; + } + + window.onmousemove = function (e) { + tooltipDiv.style.top = (e.clientY + 15) + 'px'; + tooltipDiv.style.left = (e.clientX + 10) + 'px'; + tooltipDiv.style.zIndex = 1000; + tooltipDiv.style.backgroundColor = config.tooltip.color; + tooltipDiv.style.position = "fixed"; + + if (tooltipDiv.offsetWidth + e.clientX - (cumulativeOffset(document.getElementById(div.replace("#", ""))).left + config.padding.left) > document.getElementById(div.replace("#", "")).offsetWidth) { + tooltipDiv.style.left = (e.clientX - tooltipDiv.offsetWidth) + 'px'; + } + + if (e.clientY - (cumulativeOffset(document.getElementById(div.replace("#", ""))).top + 500) > document.getElementById(div.replace("#", "")).offsetHeight) { + tooltipDiv.style.top = (e.clientY - 400) + 'px'; + } + + }; + } + }) + .on("mouseout", function(event, item) { + var tooltipDiv = document.getElementById(div.replace("#", "")+"-tooltip"); + tooltipDiv.style.padding = "0px 0px 0px 0px"; + tooltipDiv.innerHTML = ""; + }).update(); +} + + +function cumulativeOffset(element) { + var top = 0, left = 0; + do { + top += element.offsetTop || 0; + left += element.offsetLeft || 0; + element = element.offsetParent; + } while(element); + + return { + top: top, + left: left + }; +}; + +function getXYAxes(config, xAxesType, xScale, yAxesType, yScale) { + var xProp = {"ticks": { + "stroke": {"value": config.axesColor}, + "strokeWidth":{"value":config.axesSize} + }, + "labels": { + "fill": {"value": config.axesColor}, + "fontSize": {"value": config.axesFontSize} + }, + "title": { + "fontSize": {"value": config.titleFontSize}, + "fill": {"value": config.titleFontColor} + }, + "axis": { + "stroke": {"value": config.axesColor}, + "strokeWidth": {"value": config.axesSize} + }}; + var yProp = {"ticks": { + "stroke": {"value": config.axesColor}, + "strokeWidth":{"value":config.axesSize} + }, + "labels": { + "fill": {"value": config.axesColor}, + "fontSize": {"value": config.axesFontSize} + }, + "title": { + "fontSize": {"value": config.titleFontSize}, + "fill": {"value": config.titleFontColor} + }, + "axis": { + "stroke": {"value": config.axesColor}, + "strokeWidth": {"value": config.axesSize} + }}; + + if (config.xAxisAngle) { + xProp.labels.angle = {"value": 45}; + xProp.labels.align = {"value": "left"}; + xProp.labels.baseline = {"value": "middle"}; + } + + if (config.yAxisAngle) { + yProp.labels.angle = {"value": 45}; + yProp.labels.align = {"value": "left"}; + yProp.labels.baseline = {"value": "middle"}; + } + + var axes = [ + { "type": xAxesType, + "scale": xScale, + "grid": config.grid, + "format" : config.xFormat, + "ticks" : config.xTicks, + "title": config.xTitle, + "properties": xProp + }, + { + "type": yAxesType, + "scale": yScale, + "grid": config.grid, + "format" : config.yFormat, + "ticks" : config.yTicks, + "title": config.yTitle, + "properties": yProp + } + ]; + + return axes; +} + +function getRangeSignals(config, signals) { + signals.push({ + "name": "range_start", + "streams": [{ + "type": "mousedown", + "expr": "eventX()", + "scale": {"name": "x", "invert": true} + }] + }); + signals.push( { + "name": "range_end", + "streams": [{ + "type": "mousedown, [mousedown, window:mouseup] > window:mousemove", + "expr": "clamp(eventX(), 0, "+config.width+")", + "scale": {"name": "x", "invert": true} + }] + }); + return signals; +} + +function getRangeMark(config, marks) { + marks.push( { + "type": "rect", + "properties":{ + "enter":{ + "y": {"value": 0}, + "height": {"value":config.height}, + "fill": {"value": config.rangeColor}, + "fillOpacity": {"value":0.3} + }, + "update":{ + "x": {"scale": "x", "signal": "range_start"}, + "x2": {"scale": "x", "signal": "range_end"} + } + } + }); + + return marks; +} + +function getLegend(config) { + var legends = [ + { + "fill": "color", + "title": config.legendTitle, + "offset": 0, + "properties": { + "symbols": { + "stroke": {"value": "transparent"} + }, + "title": { + "fill": {"value": config.legendTitleColor}, + "fontSize": {"value": config.legendTitleFontSize} + }, + "labels": { + "fill": {"value": config.legendTextColor}, + "fontSize": {"value": config.ledgendTextFontSize} + } + } + } + ]; + + return legends; +} + +function drawChart(div, obj, callbacks) { + var viewUpdateFunction = (function(chart) { + if(obj.config.tooltip.enabled){ + createTooltip(div); + obj.view = chart({el:div}).renderer(obj.config.renderer).update(); + bindTooltip(div,obj.view,obj.config,obj.metadata); + } else { + obj.view = chart({el:div}).renderer(obj.config.renderer).update(); + } + + if (callbacks != null) { + for (var i = 0; i= this.config.maxLength){ + var allowedDataSet = []; + var startingPoint = dataset.length - maxValue; + for(var i = startingPoint; i < dataset.length;i++){ + allowedDataSet.push(dataset[i]); + } + this.spec.data[0].values = allowedDataSet; + } + } + this.config.tooltip.type = "rect"; + drawChart(div, this, callbacks); +}; + +bar.prototype.insert = function(data) { + + var xAxis = this.metadata.names[this.config.x]; + var yAxis = this.metadata.names[this.config.y]; + var size = this.metadata.names[this.config.size]; + var color = this.metadata.names[this.config.color]; + + if (this.config.maxLength != -1 && this.config.maxLength < (this.view.data(this.config.title).values().length + data.length)) { + + var allDataSet = this.view.data(this.config.title).values().concat(data); + var allowedRemovableDataSet = []; + for (i = 0; i < allDataSet.length - this.config.maxLength; i++) { + allowedRemovableDataSet.push(this.view.data(this.config.title).values()[i][xAxis]); + } + + for (i = 0; i < data.length; i++) { + var isValueMatched = false; + this.view.data(this.config.title).update(function(d) { + if (color == null) { + return d[xAxis] == data[i][xAxis]; + } else { + return d[xAxis] == data[i][xAxis] && d[color] == data[i][color]; + } + }, + yAxis, + function(d) { + isValueMatched = true; + return data[i][yAxis]; + }); + + if(isValueMatched){ + var isIndexRemoved = false; + + var index = allowedRemovableDataSet.indexOf(data[i][xAxis]); + if (index > -1) { + // updated value matched in allowed removable values + isIndexRemoved = true; + allowedRemovableDataSet.splice(index, 1); + } + + if(!isIndexRemoved){ + // updated value NOT matched in allowed removable values + allowedRemovableDataSet.splice((allowedRemovableDataSet.length - 1), 1); + } + + } else { + //insert the new data + this.view.data(this.config.title).insert([data[i]]); + this.view.update(); + } + } + + var oldData; + var removeFunction = function(d) { + return d[xAxis] == oldData; + }; + + for (i = 0; i < allowedRemovableDataSet.length; i++) { + oldData = allowedRemovableDataSet[i]; + this.view.data(this.config.title).remove(removeFunction); + } + } else{ + for (i = 0; i < data.length; i++) { + var isValueMatched = false; + this.view.data(this.config.title).update(function(d) { + if (color == null) { + return d[xAxis] == data[i][xAxis]; + } else { + return d[xAxis] == data[i][xAxis] && d[color] == data[i][color]; + } + }, + yAxis, + function(d) { + isValueMatched = true; + return data[i][yAxis]; + }); + + if(!isValueMatched){ + this.view.data(this.config.title).insert([data[i]]); + } + } + } + + //Group does not support duration update animation + if (this.config.mode == "group") { + this.view.update(); + } else { + this.view.update({duration: 200}); + } +}; + +bar.prototype.getSpec = function() { + return this.spec; +}; + + +function getBarMark(config, metadata){ + var markContent; + if (config.orientation == "left") { + markContent = { + "y": {"scale": "x", "field": metadata.names[config.x]}, + "height": {"scale": "x", "band": true, "offset": -10}, + "x": {"scale": "y", "field": metadata.names[config.y]}, + "x2": {"scale": "y", "value": 0}, + "fill": {"value": config.markColor}, + "fillOpacity": {"value": 1} + }; + } else { + markContent = { + "x": {"scale": "x", "field": metadata.names[config.x]}, + "width": {"scale": "x", "band": true, "offset": -10}, + "y": {"scale": "y", "field": metadata.names[config.y]}, + "y2": {"scale": "y", "value": 0}, + "fill": {"value": config.markColor}, + "fillOpacity": {"value": 1} + }; + } + + var mark = { + "type": "rect", + "from": {"data": config.title}, + "properties": { + "update": markContent, + "hover": { + "fillOpacity": {"value": 0.5} + } + } + }; + + + return mark; +} + +function getStackBarMark(config, metadata){ + + var markContent; + if (config.orientation == "left") { + mark = { + "type": "rect", + "from": { + "data": config.title, + "transform": [ + { "type": "stack", + "groupby": [metadata.names[config.x]], + "sortby": [metadata.names[config.color]], + "field":metadata.names[config.y]} + ] + }, + "properties": { + "update": { + "y": {"scale": "x", "field": metadata.names[config.x]}, + "height": {"scale": "x", "band": true, "offset": -10}, + "x": {"scale": "y", "field": "layout_start"}, + "x2": {"scale": "y", "field": "layout_end"}, + "fill": {"scale": "color", "field": metadata.names[config.color]}, + "fillOpacity": {"value": 1} + }, + "hover": { + "fillOpacity": {"value": 0.5} + } + } + }; + } else { + mark = { + "type": "rect", + "from": { + "data": config.title, + "transform": [ + { "type": "stack", + "groupby": [metadata.names[config.x]], + "sortby": [metadata.names[config.color]], + "field":metadata.names[config.y]} + ] + }, + "properties": { + "update": { + "x": {"scale": "x", "field": metadata.names[config.x]}, + "width": {"scale": "x", "band": true, "offset": -10}, + "y": {"scale": "y", "field": "layout_start"}, + "y2": {"scale": "y", "field": "layout_end"}, + "fill": {"scale": "color", "field": metadata.names[config.color]}, + "fillOpacity": {"value": 1} + }, + "hover": { + "fillOpacity": {"value": 0.5} + } + } + }; + } + + + + + return mark; +} + +function getGroupBarMark(config, metadata){ + var mark; + if (config.orientation == "left") { + mark = { + "type": "group", + "from": { + "data": config.title, + "transform": [{"type":"facet", "groupby": [metadata.names[config.x]]}] + }, + "properties": { + "update": { + "y": {"scale": "x", "field": "key"}, + "height": {"scale": "x", "band": true} + } + }, + "scales": [ + { + "name": "pos", + "type": "ordinal", + "range": "height", + "domain": {"field": metadata.names[config.color]} + } + ], + "marks": [ + { + "name": "bars", + "type": "rect", + "properties": { + "update": { + "y": {"scale": "pos", "field": metadata.names[config.color]}, + "height": {"scale": "pos", "band": true}, + "x": {"scale": "y", "field": metadata.names[config.y]}, + "x2": {"scale": "y", "value": 0}, + "fill": {"scale": "color", "field": metadata.names[config.color]}, + "fillOpacity": {"value": 1} + }, + "hover": { + "fillOpacity": {"value": 0.5} + } + } + } + ] + }; + } else { + mark = { + "type": "group", + "from": { + "data": config.title, + "transform": [{"type":"facet", "groupby": [metadata.names[config.x]]}] + }, + "properties": { + "update": { + "x": {"scale": "x", "field": "key"}, + "width": {"scale": "x", "band": true} + } + }, + "scales": [ + { + "name": "pos", + "type": "ordinal", + "range": "width", + "domain": {"field": metadata.names[config.color]} + } + ], + "marks": [ + { + "name": "bars", + "type": "rect", + "properties": { + "update": { + "x": {"scale": "pos", "field": metadata.names[config.color]}, + "width": {"scale": "pos", "band": true}, + "y": {"scale": "y", "field": metadata.names[config.y]}, + "y2": {"scale": "y", "value": 0}, + "fill": {"scale": "color", "field": metadata.names[config.color]}, + "fillOpacity": {"value": 1} + }, + "hover": { + "fillOpacity": {"value": 0.5} + } + } + } + ] + }; + } + return mark; +} + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/VizGrammar.min.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/VizGrammar.min.js new file mode 100644 index 0000000000..9c3da1bff7 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/VizGrammar.min.js @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License./ + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +function getPieMark(a,b){var c;if("donut"==a.mode)var c=a.width/5*(1+a.innerRadius);else if("pie"==a.mode)var c=0;else{a.innerRadius+=.5;var c=a.width/5*(1+a.innerRadius)}var d=a.title,e="";null!=a.type&&(d="layout",e="a.");var f={type:"arc",from:{data:d},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},startAngle:{field:"layout_start"},endAngle:{field:"layout_end"},innerRadius:{value:c},outerRadius:{value:.4*a.width},fill:{scale:"color",field:e+b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.8},cursor:{value:a.hoverCursor}}}};return f}function getPieMidText(a,b){var c={type:"text",from:{data:"layout"},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},radius:{value:0},theta:{field:"layout_mid"},fill:[{test:"indata('arc', datum.a."+b.names[a.color]+", 'type')",scale:"color",field:b.names[a.color]},{}],align:{value:"center"},baseline:{value:"middle"},fontSize:{value:a.width/9},text:{template:"{{datum.percentage | number:'.2f'}}%"}}}};return c}function getPieText(a,b){var c={type:"text",from:{data:"layout"},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},radius:{value:.5*a.width},theta:{field:"layout_mid"},fill:{value:"#000"},align:{value:"center"},baseline:{value:"middle"},text:{template:"{{datum.percentage | number:'.2f'}}%"}}}};return c}function getAreaMark(a,b){var c;return c=-1!=a.color?{type:"group",from:{data:a.title,transform:[{type:"facet",groupby:[b.names[a.color]]}]},marks:[{type:"area",properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{scale:"color",field:b.names[a.color]},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5}}}}]}:{type:"area",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{value:a.markColor},strokeWidth:{value:2},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}}}function getBarMark(a,b){var c;c="left"==a.orientation?{y:{scale:"x",field:b.names[a.x]},height:{scale:"x",band:!0,offset:calculateBarGap(a)},x:{scale:"y",field:b.names[a.y]},x2:{scale:"y",value:0},fill:{value:a.markColor},fillOpacity:{value:1}}:{x:{scale:"x",field:b.names[a.x]},width:{scale:"x",band:!0,offset:calculateBarGap(a)},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{value:a.markColor},fillOpacity:{value:1}};var d={type:"rect",from:{data:a.title},properties:{update:c,hover:{fillOpacity:{value:.5},cursor:{value:a.hoverCursor}}}};return d}function getStackBarMark(a,b){return"left"==a.orientation?mark={type:"rect",from:{data:a.title,transform:[{type:"stack",groupby:[b.names[a.x]],sortby:[b.names[a.color]],field:b.names[a.y]}]},properties:{update:{y:{scale:"x",field:b.names[a.x]},height:{scale:"x",band:!0,offset:calculateBarGap(a)},x:{scale:"y",field:"layout_start"},x2:{scale:"y",field:"layout_end"},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5},cursor:{value:a.hoverCursor}}}}:mark={type:"rect",from:{data:a.title,transform:[{type:"stack",groupby:[b.names[a.x]],sortby:[b.names[a.color]],field:b.names[a.y]}]},properties:{update:{x:{scale:"x",field:b.names[a.x]},width:{scale:"x",band:!0,offset:calculateBarGap(a)},y:{scale:"y",field:"layout_start"},y2:{scale:"y",field:"layout_end"},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5},cursor:{value:a.hoverCursor}}}},mark}function getGroupBarMark(a,b){var c;return c="left"==a.orientation?{type:"group",from:{data:a.title,transform:[{type:"facet",groupby:[b.names[a.x]]}]},properties:{update:{y:{scale:"x",field:"key"},height:{scale:"x",band:!0}}},scales:[{name:"pos",type:"ordinal",range:"height",domain:{field:b.names[a.color]}}],marks:[{name:"bars",type:"rect",properties:{update:{y:{scale:"pos",field:b.names[a.color]},height:{scale:"pos",band:!0},x:{scale:"y",field:b.names[a.y]},x2:{scale:"y",value:0},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5},cursor:{value:a.hoverCursor}}}}]}:{type:"group",from:{data:a.title,transform:[{type:"facet",groupby:[b.names[a.x]]}]},properties:{update:{x:{scale:"x",field:"key"},width:{scale:"x",band:!0}}},scales:[{name:"pos",type:"ordinal",range:"width",domain:{field:b.names[a.color]}}],marks:[{name:"bars",type:"rect",properties:{update:{x:{scale:"pos",field:b.names[a.color]},width:{scale:"pos",band:!0},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5},cursor:{value:a.hoverCursor}}}}]}}function calculateBarGap(a){var b;return b="left"==a.orientation?a.height:a.width,-a.barGap*(b/30)}function getLineMark(a,b){var c;return c=-1!=a.color?{name:"line-group",type:"group",from:{data:a.title,transform:[{type:"facet",groupby:[b.names[a.color]]}]},marks:[{type:"line",properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},stroke:{scale:"color",field:b.names[a.color]},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5},cursor:{value:a.hoverCursor}}}}]}:{type:"line",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},stroke:{value:a.markColor},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5}}}}}function getTopoJson(a,b){var c,d=a.width,e=a.height,f=a.charts[0].mapType,g="mercator";"usa"==f?(d=a.width-160,e=a.height-130,c=a.height+270,g="albersUsa"):"europe"==f?(d=(a.width/2+100)/2,e=a.height+150,c=a.height+50):(c=a.width/640*120,d=a.width/2+10,e=a.height/2+40);var h=a.geoCodesUrl,i={name:"geoData",url:h,format:{type:"topojson",feature:"units"},transform:[{type:"geopath",value:"data",scale:c,translate:[d,e],projection:g},{type:"lookup",keys:["id"],on:a.title,onKey:b.names[a.x],as:["zipped"],"default":{v:null,country:"No data"}}]};return i}function getMapMark(a,b){var c=[{name:"map",type:"path",from:{data:"geoData"},properties:{enter:{path:{field:"layout_path"}},update:{fillOpacity:{value:1},fill:{rule:[{predicate:{name:"isNotNull",id:{field:"zipped.v"}},scale:"color",field:"zipped.v"},{value:a.mapColor}]}},hover:{fillOpacity:{value:.5},cursor:{value:a.hoverCursor}}}},{type:"group",from:{data:a.title,transform:[{type:"filter",test:"datum."+b.names[a.x]+" == tooltipSignal.datum."+b.names[a.x]}]},properties:{update:{x:{signal:"tooltipSignal.x",offset:-5},y:{signal:"tooltipSignal.y",offset:20},width:{value:100},height:{value:20},fill:{value:a.tooltip.color}}},marks:[{type:"text",properties:{update:{x:{value:6},y:{value:14},text:{template:"{{tooltipSignal.datum.unitName}} {{tooltipSignal.datum.v}}"},fill:{value:"black"}}}}]}];return c}function getMapSignals(){var a=[{name:"tooltipSignal",init:{expr:"{x: 0, y: 0, datum: {} }"},streams:[{type:"@map:mouseover",expr:"{x: eventX(), y: eventY(), datum: eventItem().datum.zipped}"},{type:"@map:mouseout",expr:"{x: 0, y: 0, datum: {} }"}]}];return a}function getMapPredicates(){var a={name:"isNotNull",type:"!=",operands:[{value:null},{arg:"id"}]};return a}function getMapLegends(a,b){var c={fill:"color",title:b.names[a.y],properties:{gradient:{stroke:{value:"transparent"}},title:{fontSize:{value:14}},legend:{x:{value:0},y:{value:a.height-40}}}};return c}function loadGeoMapCodes(a){var b,c=new XMLHttpRequest;return c.overrideMimeType("application/json"),c.open("GET",a,!1),c.onreadystatechange=function(){4==c.readyState&&"200"==c.status&&(b=JSON.parse(c.responseText))},c.send(null),b}function getMapCode(a,b,c){if("world"==b||"europe"==b)for(d=0;d"),$("#wrapper").append("
"),$tip=$("#tip"),$tip.empty();var i=g.datum,j="";for(var k in i)if(i.hasOwnProperty(k))if(void 0!=f){for(var l=0;l"+f[l]+" ("+k+"):"+i[k]+"

";break}}else e.names[d.x]==k&&(j+="

X ("+k+"):"+i[k]+"

"),e.names[d.y]==k&&(j+="

Y ("+k+"):"+i[k]+"

");$tip.append(j);var n=h.width,o=h.height,p=$('.marks[style*="width"]');p.length>0&&(n=parseFloat($(".marks")[0].style.width),o=parseFloat($(".marks")[0].style.height));var q,r=$tip.width(),s=$tip.height(),t=g.bounds.x2+d.padding.left+r,u=o-g.bounds.y2-d.padding.top+s,v=g.bounds.y2+d.padding.top-s;q=t>n?g.bounds.x2+d.padding.left-r:g.bounds.x2+d.padding.left,u>o&&(v=g.bounds.y2+d.padding.top),$tip.css({left:q,top:v}).show()}else $("#wrapper #tip").length&&$tip.remove(),$(a).closest("#wrapper").length&&$(a).unwrap()})}function createTooltip(a){document.getElementById(a.replace("#","")).innerHTML=document.getElementById(a.replace("#","")).innerHTML+"
"}function bindTooltip(a,b,c,d){b.on("mouseover",function(b,e){if(null!=e&&e.mark.marktype==c.tooltip.type){var f=e.datum;null!=e.datum&&null!=e.datum.a&&(f=e.datum.a);var g=document.getElementById(a.replace("#","")+"-tooltip"),h="";if(null!=f[d.names[c.x]]){var i;if(null==c.tooltip.content){if("time"==d.types[c.x]){var j=d3.time.format(c.dateFormat);i=j(new Date(parseInt(f[d.names[c.x]])))}else i=f[d.names[c.x]];h+=""+d.names[c.x]+" : "+i+"
",null!=f[d.names[c.y]]&&(h+=""+d.names[c.y]+" : "+f[d.names[c.y]]+"
")}else for(var k=0;k"+c.tooltip.content[k]+"
: "+i+"
":i+"
"}}""!=h&&(g.innerHTML=h,g.style.padding="5px 5px 5px 5px"),window.onmousemove=function(b){g.style.top=b.clientY+15+"px",g.style.left=b.clientX+10+"px",g.style.zIndex=1e3,g.style.backgroundColor=c.tooltip.color,g.style.position="fixed",g.offsetWidth+b.clientX-(cumulativeOffset(document.getElementById(a.replace("#",""))).left+c.padding.left)>document.getElementById(a.replace("#","")).offsetWidth&&(g.style.left=b.clientX-g.offsetWidth+"px"),b.clientY-(cumulativeOffset(document.getElementById(a.replace("#",""))).top+500)>document.getElementById(a.replace("#","")).offsetHeight&&(g.style.top=b.clientY-400+"px")}}}).on("mouseout",function(b,c){var d=document.getElementById(a.replace("#","")+"-tooltip");d.style.padding="0px 0px 0px 0px",d.innerHTML=""}).update()}function cumulativeOffset(a){var b=0,c=0;do b+=a.offsetTop||0,c+=a.offsetLeft||0,a=a.offsetParent;while(a);return{top:b,left:c}}function getXYAxes(a,b,c,d,e){var f={ticks:{stroke:{value:a.xAxisColor},strokeWidth:{value:a.xAxisStrokeSize}},labels:{fill:{value:a.xAxisColor},fontSize:{value:a.xAxisFontSize}},title:{fontSize:{value:a.xAxisTitleFontSize},fill:{value:a.xAxisTitleFontColor}},axis:{stroke:{value:a.xAxisColor},strokeWidth:{value:a.xAxisSize}}},g={ticks:{stroke:{value:a.yAxisColor},strokeWidth:{value:a.yAxisStrokeSize}},labels:{fill:{value:a.yAxisColor},fontSize:{value:a.yAxisFontSize}},title:{fontSize:{value:a.yAxisTitleFontSize},fill:{value:a.yAxisTitleFontColor}},axis:{stroke:{value:a.yAxisColor},strokeWidth:{value:a.yAxisSize}}};a.xAxisAngle&&(f.labels.angle={value:45},f.labels.align={value:"left"},f.labels.baseline={value:"middle"}),a.yAxisAngle&&(g.labels.angle={value:45},g.labels.align={value:"left"},g.labels.baseline={value:"middle"});var h=[{type:b,scale:c,grid:a.grid,format:a.xFormat,ticks:a.xTicks,title:a.xTitle,properties:f},{type:d,scale:e,grid:a.grid,format:a.yFormat,ticks:a.yTicks,title:a.yTitle,properties:g}];return h}function getXYScales(a,b){var c={name:"x",type:b.types[a.x],range:"width",zero:a.zero,domain:a.xScaleDomain},d={name:"y",type:b.types[a.y],range:"height",zero:a.zero,domain:a.yScaleDomain};return[c,d]}function getRangeSignals(a,b){return b.push({name:"range_start",streams:[{type:"mousedown",expr:"eventX()",scale:{name:"x",invert:!0}}]}),b.push({name:"range_end",streams:[{type:"mousedown, [mousedown, window:mouseup] > window:mousemove",expr:"clamp(eventX(), 0, "+a.width+")",scale:{name:"x",invert:!0}}]}),b}function getRangeMark(a,b){return b.push({type:"rect",properties:{enter:{y:{value:0},height:{value:a.height},fill:{value:a.rangeColor},fillOpacity:{value:.3}},update:{x:{scale:"x",signal:"range_start"},x2:{scale:"x",signal:"range_end"}}}}),b}function getLegend(a){var b=[{name:"legend",fill:"color",title:a.legendTitle,offset:0,properties:{symbols:{stroke:{value:"transparent"}},title:{fill:{value:a.legendTitleColor},fontSize:{value:a.legendTitleFontSize}},labels:{fill:{value:a.legendTextColor},fontSize:{value:a.ledgendTextFontSize}}}}];return b}function drawChart(a,b,c){var d=function(d){if(b.config.tooltip.enabled?(createTooltip(a),b.view=d({el:a}).renderer(b.config.renderer).update(),bindTooltip(a,b.view,b.config,b.metadata)):b.view=d({el:a}).renderer(b.config.renderer).update(),null!=c)for(var e=0;e=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h=this.config.maxLength){for(var e=[],f=c.length-d,g=f;g=this.config.maxLength){for(var e=[],f=c.length-d,g=f;g-1&&(h=!0,f.splice(j,1)),h||f.splice(f.length-1,1)}else this.view.data(this.config.title).insert([a[i]]),this.view.update()}var k,l=function(a){return a[b]==k};for(i=0;i=this.config.maxLength){for(var e=[],f=c.length-d,g=f;g

"+c+"

";document.getElementById(a).innerHTML=d,this.view=b},number.prototype.insert=function(a){document.getElementById(this.view).innerHTML=a[a.length-1][this.metadata.names[this.config.x]]};var scatter=function(a,b){this.metadata=a[0].metadata;var c=[];this.spec={},b=checkConfig(b,this.metadata),this.config=b,a[0].name=b.title;var d={name:"size",type:"linear",range:[0,576],domain:{data:b.title,field:this.metadata.names[b.size]}},e={name:"color",type:this.metadata.types[b.color],range:b.colorScale,domain:{data:b.title,field:this.metadata.names[b.color]}},f=getXYScales(b,this.metadata);f.push(d),f.push(e);var g=getXYAxes(b,"x","x","y","y");c.push(getScatterMark(b,this.metadata)),this.config.legend&&"linear"!=this.metadata.types[b.color]&&(this.spec.legends=getLegend(this.config)),this.spec.width=b.width,this.spec.height=b.height,this.spec.axes=g,this.spec.data=a,this.spec.scales=f,this.spec.padding=b.padding,this.spec.marks=c};scatter.prototype.draw=function(a,b){var c=function(c){if(this.config.tooltip.enabled?(createTooltip(a),this.view=c({el:a}).renderer(this.config.renderer).update(),bindTooltip(a,this.view,this.config,this.metadata)):this.view=c({el:a}).renderer(this.config.renderer).update(),null!=b)for(var d=0;d=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h-1&&(j=!0,g.splice(k,1)),j||g.splice(g.length-1,1)}else this.view.data(this.config.title).insert([a[i]]),this.view.update()}var l,m=function(a){return a[b]==l};for(i=0;ib.maxLength){var k=d3.select("tbody").selectAll("tr").data().slice(d3.select("tbody").selectAll("tr").data().length-b.maxLength,b.maxLength);d3.select("tbody").selectAll("tr").data(k,function(a){return a}).remove()}};var extend=function(a,b){var c,d={};for(c in a)Object.prototype.hasOwnProperty.call(a,c)&&(d[c]=a[c]);for(c in b)Object.prototype.hasOwnProperty.call(b,c)&&(d[c]=b[c]);return d},stack=function(a,b){this.barChart=new bar(a,b),this.metadata=this.barChart.metadata;var c=this.barChart.getSpec();c.axes=[c.axes[0]],c.axes[0].grid=!1,c.data.push({name:"selectedPoints",modify:[{type:"clear",test:"!multi"},{type:"toggle",signal:"clickedPoint",field:"id"}]}),c.signals.push({name:"clickedPoint",init:0,verbose:!0,streams:[{type:"click",expr:"datum._id"}]},{name:"multi",init:!1,verbose:!0,streams:[{type:"click",expr:"datum._id"}]});var d=JSON.parse(JSON.stringify(c.marks[0]));d.type="text",d.properties.update.text={field:c.marks[0].properties.update.fill.field},d.properties.update.x.offset=10,d.properties.update.y.offset=-5,d.properties.update.fill={value:b.legendTitleColor},delete d.properties.update.y2,delete d.properties.hover,c.marks.push(d),delete c.marks[0].properties.hover,c.marks[0].properties.update.fill=[{test:"indata('selectedPoints', datum._id, 'id')",value:b.selectionColor},c.marks[0].properties.update.fill],this.barChart.setSpec(c)};stack.prototype.draw=function(a,b){this.barChart.draw(a,b)},stack.prototype.insert=function(a){this.barChart.insert(a)},stack.prototype.getSpec=function(){return this.barChart.getSpec()}; \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/VizGrammar2.min.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/VizGrammar2.min.js new file mode 100644 index 0000000000..222168b488 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/VizGrammar2.min.js @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License./ + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +function getPieMark(a,b){var c;if("donut"==a.mode)var c=a.width/5*(1+a.innerRadius);else if("pie"==a.mode)var c=0;else{a.innerRadius+=.5;var c=a.width/5*(1+a.innerRadius)}var d={type:"arc",from:{data:a.title},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},startAngle:{field:"layout_start"},endAngle:{field:"layout_end"},innerRadius:{value:c},outerRadius:{value:.4*a.width},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.8}}}};return d}function getPieMidText(a,b){var c={type:"text",from:{data:a.title},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},radius:{value:0},theta:{field:"layout_mid"},fill:[{test:"indata('arc', datum.EngineType, 'type')",scale:"color",field:b.names[a.color]},{}],align:{value:"center"},baseline:{value:"middle"},fontSize:{value:a.width/8},text:{template:"{{datum.percentage | number:'.2f'}}%"}}}};return c}function getPieText(a,b){var c={type:"text",from:{data:a.title},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},radius:{value:.5*a.width},theta:{field:"layout_mid"},fill:{value:"#000"},align:{value:"center"},baseline:{value:"middle"},text:{template:"{{datum.percentage | number:'.2f'}}%"}}}};return c}function getAreaMark(a,b){var c;return c=-1!=a.color?{type:"group",from:{data:a.title,transform:[{type:"facet",groupby:[b.names[a.color]]}]},marks:[{type:"area",properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{scale:"color",field:b.names[a.color]},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5}}}}]}:{type:"area",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{value:a.markColor},strokeWidth:{value:2},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}}}function getBarMark(a,b){var c;c="left"==a.orientation?{y:{scale:"x",field:b.names[a.x]},height:{scale:"x",band:!0,offset:-10},x:{scale:"y",field:b.names[a.y]},x2:{scale:"y",value:0},fill:{value:a.markColor},fillOpacity:{value:1}}:{x:{scale:"x",field:b.names[a.x]},width:{scale:"x",band:!0,offset:-10},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{value:a.markColor},fillOpacity:{value:1}};var d={type:"rect",from:{data:a.title},properties:{update:c,hover:{fillOpacity:{value:.5}}}};return d}function getStackBarMark(a,b){return"left"==a.orientation?mark={type:"rect",from:{data:a.title,transform:[{type:"stack",groupby:[b.names[a.x]],sortby:[b.names[a.color]],field:b.names[a.y]}]},properties:{update:{y:{scale:"x",field:b.names[a.x]},height:{scale:"x",band:!0,offset:-10},x:{scale:"y",field:"layout_start"},x2:{scale:"y",field:"layout_end"},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}}:mark={type:"rect",from:{data:a.title,transform:[{type:"stack",groupby:[b.names[a.x]],sortby:[b.names[a.color]],field:b.names[a.y]}]},properties:{update:{x:{scale:"x",field:b.names[a.x]},width:{scale:"x",band:!0,offset:-10},y:{scale:"y",field:"layout_start"},y2:{scale:"y",field:"layout_end"},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}},mark}function getGroupBarMark(a,b){var c;return c="left"==a.orientation?{type:"group",from:{data:a.title,transform:[{type:"facet",groupby:[b.names[a.x]]}]},properties:{update:{y:{scale:"x",field:"key"},height:{scale:"x",band:!0}}},scales:[{name:"pos",type:"ordinal",range:"height",domain:{field:b.names[a.color]}}],marks:[{name:"bars",type:"rect",properties:{update:{y:{scale:"pos",field:b.names[a.color]},height:{scale:"pos",band:!0},x:{scale:"y",field:b.names[a.y]},x2:{scale:"y",value:0},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}}]}:{type:"group",from:{data:a.title,transform:[{type:"facet",groupby:[b.names[a.x]]}]},properties:{update:{x:{scale:"x",field:"key"},width:{scale:"x",band:!0}}},scales:[{name:"pos",type:"ordinal",range:"width",domain:{field:b.names[a.color]}}],marks:[{name:"bars",type:"rect",properties:{update:{x:{scale:"pos",field:b.names[a.color]},width:{scale:"pos",band:!0},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}}]}}function getLineMark(a,b){var c;return c=-1!=a.color?{type:"group",from:{data:a.title,transform:[{type:"facet",groupby:[b.names[a.color]]}]},marks:[{type:"line",properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},stroke:{scale:"color",field:b.names[a.color]},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5}}}}]}:{type:"line",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},stroke:{value:a.markColor},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5}}}}}function getTopoJson(a,b){var c,d=a.width,e=a.height,f=a.charts[0].mapType,g="mercator";"usa"==f?(d=a.width-160,e=a.height-130,c=a.height+270,g="albersUsa"):"europe"==f?(d=(a.width/2+100)/2,e=a.height+150,c=a.height+50):(c=a.width/640*120,d=a.width/2+10,e=a.height/2+40);var h=a.geoCodesUrl,i={name:"geoData",url:h,format:{type:"topojson",feature:"units"},transform:[{type:"geopath",value:"data",scale:c,translate:[d,e],projection:g},{type:"lookup",keys:["id"],on:a.title,onKey:b.names[a.x],as:["zipped"],"default":{v:null,country:"No data"}}]};return i}function getMapMark(a,b){var c=[{name:"map",type:"path",from:{data:"geoData"},properties:{enter:{path:{field:"layout_path"}},update:{fill:{rule:[{predicate:{name:"isNotNull",id:{field:"zipped.v"}},scale:"color",field:"zipped.v"},{value:a.mapColor}]}},hover:{fill:{value:"#989898"}}}},{type:"group",from:{data:a.title,transform:[{type:"filter",test:"datum."+b.names[a.x]+" == tooltipSignal.datum."+b.names[a.x]}]},properties:{update:{x:{signal:"tooltipSignal.x",offset:-5},y:{signal:"tooltipSignal.y",offset:20},width:{value:100},height:{value:20},fill:{value:a.tooltip.color}}},marks:[{type:"text",properties:{update:{x:{value:6},y:{value:14},text:{template:"{{tooltipSignal.datum.unitName}} {{tooltipSignal.datum.v}}"},fill:{value:"black"}}}}]}];return c}function getMapSignals(){var a=[{name:"tooltipSignal",init:{expr:"{x: 0, y: 0, datum: {} }"},streams:[{type:"@map:mouseover",expr:"{x: eventX(), y: eventY(), datum: eventItem().datum.zipped}"},{type:"@map:mouseout",expr:"{x: 0, y: 0, datum: {} }"}]}];return a}function getMapPredicates(){var a={name:"isNotNull",type:"!=",operands:[{value:null},{arg:"id"}]};return a}function getMapLegends(a,b){var c={fill:"color",title:b.names[a.y],properties:{gradient:{stroke:{value:"transparent"}},title:{fontSize:{value:14}},legend:{x:{value:0},y:{value:a.height-40}}}};return c}function loadGeoMapCodes(a){var b,c=new XMLHttpRequest;return c.overrideMimeType("application/json"),c.open("GET",a,!1),c.onreadystatechange=function(){4==c.readyState&&"200"==c.status&&(b=JSON.parse(c.responseText))},c.send(null),b}function getMapCode(a,b,c){if("world"==b||"europe"==b)for(d=0;d"),$("#wrapper").append("
"),$tip=$("#tip"),$tip.empty();var i=g.datum,j="";for(var k in i)if(i.hasOwnProperty(k))if(void 0!=f){for(var l=0;l"+f[l]+" ("+k+"):"+i[k]+"

";break}}else e.names[d.x]==k&&(j+="

X ("+k+"):"+i[k]+"

"),e.names[d.y]==k&&(j+="

Y ("+k+"):"+i[k]+"

");$tip.append(j);var n=h.width,o=h.height,p=$('.marks[style*="width"]');p.length>0&&(n=parseFloat($(".marks")[0].style.width),o=parseFloat($(".marks")[0].style.height));var q,r=$tip.width(),s=$tip.height(),t=g.bounds.x2+d.padding.left+r,u=o-g.bounds.y2-d.padding.top+s,v=g.bounds.y2+d.padding.top-s;q=t>n?g.bounds.x2+d.padding.left-r:g.bounds.x2+d.padding.left,u>o&&(v=g.bounds.y2+d.padding.top),$tip.css({left:q,top:v}).show()}else $("#wrapper #tip").length&&$tip.remove(),$(a).closest("#wrapper").length&&$(a).unwrap()})}function createTooltip(a){document.getElementById(a.replace("#","")).innerHTML=document.getElementById(a.replace("#","")).innerHTML+"
"}function bindTooltip(a,b,c,d){b.on("mouseover",function(b,e){if(null!=e&&e.mark.marktype==c.tooltip.type){var f=document.getElementById(a.replace("#","")+"-tooltip"),g="";if(null!=e.datum[d.names[c.x]]){var h;if(null==c.tooltip.content){if("time"==d.types[c.x]){var i=d3.time.format(c.dateFormat);h=i(new Date(parseInt(e.datum[d.names[c.x]])))}else h=e.datum[d.names[c.x]];g+=""+d.names[c.x]+" : "+h+"
",null!=e.datum[d.names[c.y]]&&(g+=""+d.names[c.y]+" : "+e.datum[d.names[c.y]]+"
")}else for(var j=0;j"+c.tooltip.content[j]+"
: "+h+"
":h+"
"}}""!=g&&(f.innerHTML=g,f.style.padding="5px 5px 5px 5px"),window.onmousemove=function(b){f.style.top=b.clientY+15+"px",f.style.left=b.clientX+10+"px",f.style.zIndex=1e3,f.style.backgroundColor=c.tooltip.color,f.style.position="fixed",f.offsetWidth+b.clientX-(cumulativeOffset(document.getElementById(a.replace("#",""))).left+c.padding.left)>document.getElementById(a.replace("#","")).offsetWidth&&(f.style.left=b.clientX-f.offsetWidth+"px"),b.clientY-(cumulativeOffset(document.getElementById(a.replace("#",""))).top+500)>document.getElementById(a.replace("#","")).offsetHeight&&(f.style.top=b.clientY-400+"px")}}}).on("mouseout",function(b,c){var d=document.getElementById(a.replace("#","")+"-tooltip");d.style.padding="0px 0px 0px 0px",d.innerHTML=""}).update()}function cumulativeOffset(a){var b=0,c=0;do b+=a.offsetTop||0,c+=a.offsetLeft||0,a=a.offsetParent;while(a);return{top:b,left:c}}function getXYAxes(a,b,c,d,e){var f={ticks:{stroke:{value:a.axesColor},strokeWidth:{value:a.axesSize}},labels:{fill:{value:a.axesColor},fontSize:{value:a.axesFontSize}},title:{fontSize:{value:a.titleFontSize},fill:{value:a.titleFontColor}},axis:{stroke:{value:a.axesColor},strokeWidth:{value:a.axesSize}}},g={ticks:{stroke:{value:a.axesColor},strokeWidth:{value:a.axesSize}},labels:{fill:{value:a.axesColor},fontSize:{value:a.axesFontSize}},title:{fontSize:{value:a.titleFontSize},fill:{value:a.titleFontColor}},axis:{stroke:{value:a.axesColor},strokeWidth:{value:a.axesSize}}};a.xAxisAngle&&(f.labels.angle={value:45},f.labels.align={value:"left"},f.labels.baseline={value:"middle"}),a.yAxisAngle&&(g.labels.angle={value:45},g.labels.align={value:"left"},g.labels.baseline={value:"middle"});var h=[{type:b,scale:c,grid:a.grid,format:a.xFormat,ticks:a.xTicks,title:a.xTitle,properties:f},{type:d,scale:e,grid:a.grid,format:a.yFormat,ticks:a.yTicks,title:a.yTitle,properties:g}];return h}function getRangeSignals(a,b){return b.push({name:"range_start",streams:[{type:"mousedown",expr:"eventX()",scale:{name:"x",invert:!0}}]}),b.push({name:"range_end",streams:[{type:"mousedown, [mousedown, window:mouseup] > window:mousemove",expr:"clamp(eventX(), 0, "+a.width+")",scale:{name:"x",invert:!0}}]}),b}function getRangeMark(a,b){return b.push({type:"rect",properties:{enter:{y:{value:0},height:{value:a.height},fill:{value:a.rangeColor},fillOpacity:{value:.3}},update:{x:{scale:"x",signal:"range_start"},x2:{scale:"x",signal:"range_end"}}}}),b}function getLegend(a){var b=[{fill:"color",title:a.legendTitle,offset:0,properties:{symbols:{stroke:{value:"transparent"}},title:{fill:{value:a.legendTitleColor},fontSize:{value:a.legendTitleFontSize}},labels:{fill:{value:a.legendTextColor},fontSize:{value:a.ledgendTextFontSize}}}}];return b}function drawChart(a,b,c){var d=function(d){if(b.config.tooltip.enabled?(createTooltip(a),b.view=d({el:a}).renderer(b.config.renderer).update(),bindTooltip(a,b.view,b.config,b.metadata)):b.view=d({el:a}).renderer(b.config.renderer).update(),null!=c)for(var e=0;e=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h=this.config.maxLength){for(var e=[],f=c.length-d,g=f;g=this.config.maxLength){for(var e=[],f=c.length-d,g=f;g-1&&(h=!0,f.splice(j,1)),h||f.splice(f.length-1,1)}else this.view.data(this.config.title).insert([a[i]]),this.view.update()}var k,l=function(a){return a[b]==k};for(i=0;i=this.config.maxLength){for(var e=[],f=c.length-d,g=f;g

"+c+"

";document.getElementById(a).innerHTML=d,this.view=b},number.prototype.insert=function(a){document.getElementById(this.view).innerHTML=a[a.length-1][this.metadata.names[this.config.x]]};var scatter=function(a,b){this.metadata=a[0].metadata;var c=[];this.spec={},b=checkConfig(b,this.metadata),this.config=b,a[0].name=b.title;var d={name:"x",type:this.metadata.types[b.x],range:"width",zero:b.zero,domain:{data:b.title,field:this.metadata.names[b.x]}},e={name:"y",type:this.metadata.types[b.y],range:"height",zero:b.zero,domain:{data:b.title,field:this.metadata.names[b.y]}},f={name:"size",type:"linear",range:[0,576],domain:{data:b.title,field:this.metadata.names[b.size]}},g={name:"color",type:this.metadata.types[b.color],range:b.colorScale,domain:{data:b.title,field:this.metadata.names[b.color]}},h=[d,e,f,g],i=getXYAxes(b,"x","x","y","y");c.push(getScatterMark(b,this.metadata)),this.spec.width=b.width,this.spec.height=b.height,this.spec.axes=i,this.spec.data=a,this.spec.scales=h,this.spec.padding=b.padding,this.spec.marks=c};scatter.prototype.draw=function(a,b){var c=function(c){if(this.config.tooltip.enabled?(createTooltip(a),this.view=c({el:a}).renderer(this.config.renderer).update(),bindTooltip(a,this.view,this.config,this.metadata)):this.view=c({el:a}).renderer(this.config.renderer).update(),null!=b)for(var d=0;d=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h-1&&(j=!0,g.splice(k,1)),j||g.splice(g.length-1,1)}else this.view.data(this.config.title).insert([a[i]]),this.view.update()}var l,m=function(a){return a[b]==l};for(i=0;ib.maxLength){var k=d3.select("tbody").selectAll("tr").data().slice(d3.select("tbody").selectAll("tr").data().length-b.maxLength,b.maxLength);d3.select("tbody").selectAll("tr").data(k,function(a){return a}).remove()}};var extend=function(a,b){var c,d={};for(c in a)Object.prototype.hasOwnProperty.call(a,c)&&(d[c]=a[c]);for(c in b)Object.prototype.hasOwnProperty.call(b,c)&&(d[c]=b[c]);return d},bar=function(a,b){this.metadata=a[0].metadata;var c=[],d=[];this.spec={};var e,f,g,h,i,j,k=[];if(b=checkConfig(b,this.metadata),this.config=b,a[0].name=b.title,"left"==b.orientation?(g="height",h="width",i="y",j="x"):(g="width",h="height",i="x",j="y"),-1!=b.color){var l="Legend";"table"!=b.title&&(l=b.title),-1==b.colorDomain&&(b.colorDomain={data:b.title,field:this.metadata.names[b.color]});var m={name:"color",type:"ordinal",domain:b.colorDomain,range:b.colorScale};if(d.push(m),"stack"==b.mode){var n={name:"stack",source:b.title,transform:[{type:"aggregate",groupby:[this.metadata.names[b.x]],summarize:[{field:this.metadata.names[b.y],ops:["sum"]}]}]};a.push(n),e="sum_"+this.metadata.names[b.y],f="stack"}else e=this.metadata.names[b.y],f=b.title;this.config.legend&&(this.spec.legends=getLegend(this.config))}else e=this.metadata.names[b.y],f=b.title;var o={name:"x",type:"ordinal",range:g,domain:{data:b.title,field:this.metadata.names[b.x]}};"group"==b.mode&&(o.padding=.2);var p={name:"y",type:this.metadata.types[b.y],range:h,domain:{data:f,field:e}};d.push(o),d.push(p);var q=getXYAxes(b,i,"x",j,"y");-1!=b.color&&"stack"==b.mode?c.push(getStackBarMark(b,this.metadata)):-1!=b.color&&"group"==b.mode?c.push(getGroupBarMark(b,this.metadata)):c.push(getBarMark(b,this.metadata)),b.range&&(k=getRangeSignals(b,k),c=getRangeMark(b,c)),this.spec.width=b.width,this.spec.height=b.height,this.spec.axes=q,this.spec.data=a,this.spec.scales=d,this.spec.padding=b.padding,this.spec.marks=c,this.spec.signals=k;JSON.stringify(this.spec)};bar.prototype.draw=function(a,b){if(-1!=this.config.maxLength){var c=this.spec.data[0].values,d=this.config.maxLength;if(c.length>=this.config.maxLength){for(var e=[],f=c.length-d,g=f;g-1&&(h=!0,f.splice(j,1)),h||f.splice(f.length-1,1)}else this.view.data(this.config.title).insert([a[i]]),this.view.update()}var k,l=function(a){return a[b]==k};for(i=0;in?-1:n>t?1:n>=t?0:0/0}function t(n){return null===n?0/0:+n}function e(n){return!isNaN(n)}function r(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function u(n){return n.length}function i(n){for(var t=1;n*t%1;)t*=10;return t}function o(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function a(){this._=Object.create(null)}function c(n){return(n+="")===da||n[0]===ma?ma+n:n}function l(n){return(n+="")[0]===ma?n.slice(1):n}function s(n){return c(n)in this._}function f(n){return(n=c(n))in this._&&delete this._[n]}function h(){var n=[];for(var t in this._)n.push(l(t));return n}function g(){var n=0;for(var t in this._)++n;return n}function p(){for(var n in this._)return!1;return!0}function v(){this._=Object.create(null)}function d(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function m(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=ya.length;r>e;++e){var u=ya[e]+t;if(u in n)return u}}function y(){}function M(){}function x(n){function t(){for(var t,r=e,u=-1,i=r.length;++ue;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function O(n){return xa(n,Aa),n}function Y(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var l=Ca.get(n);return l&&(n=l,c=V),a?t?u:r:t?y:i}function Z(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function V(n,t){var e=Z(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function X(){var n=".dragsuppress-"+ ++qa,t="click"+n,e=ta.select(oa).on("touchmove"+n,b).on("dragstart"+n,b).on("selectstart"+n,b);if(za){var r=ia.style,u=r[za];r[za]="none"}return function(i){if(e.on(n,null),za&&(r[za]=u),i){var o=function(){e.on(t,null)};e.on(t,function(){b(),o()},!0),setTimeout(o,0)}}}function $(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>La&&(oa.scrollX||oa.scrollY)){e=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();La=!(u.f||u.e),e.remove()}return La?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function B(){return ta.event.changedTouches[0].identifier}function W(){return ta.event.target}function J(){return oa}function G(n){return n>0?1:0>n?-1:0}function K(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function Q(n){return n>1?0:-1>n?Da:Math.acos(n)}function nt(n){return n>1?ja:-1>n?-ja:Math.asin(n)}function tt(n){return((n=Math.exp(n))-1/n)/2}function et(n){return((n=Math.exp(n))+1/n)/2}function rt(n){return((n=Math.exp(2*n))-1)/(n+1)}function ut(n){return(n=Math.sin(n/2))*n}function it(){}function ot(n,t,e){return this instanceof ot?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ot?new ot(n.h,n.s,n.l):xt(""+n,bt,ot):new ot(n,t,e)}function at(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new dt(u(n+120),u(n),u(n-120))}function ct(n,t,e){return this instanceof ct?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof ct?new ct(n.h,n.c,n.l):n instanceof st?ht(n.l,n.a,n.b):ht((n=_t((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new ct(n,t,e)}function lt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new st(e,Math.cos(n*=Fa)*t,Math.sin(n)*t)}function st(n,t,e){return this instanceof st?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof st?new st(n.l,n.a,n.b):n instanceof ct?lt(n.h,n.c,n.l):_t((n=dt(n)).r,n.g,n.b):new st(n,t,e)}function ft(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=gt(u)*Ja,r=gt(r)*Ga,i=gt(i)*Ka,new dt(vt(3.2404542*u-1.5371385*r-.4985314*i),vt(-.969266*u+1.8760108*r+.041556*i),vt(.0556434*u-.2040259*r+1.0572252*i))}function ht(n,t,e){return n>0?new ct(Math.atan2(e,t)*Ha,Math.sqrt(t*t+e*e),n):new ct(0/0,0/0,n)}function gt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function pt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function vt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function dt(n,t,e){return this instanceof dt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof dt?new dt(n.r,n.g,n.b):xt(""+n,dt,at):new dt(n,t,e)}function mt(n){return new dt(n>>16,255&n>>8,255&n)}function yt(n){return mt(n)+""}function Mt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function xt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(St(u[0]),St(u[1]),St(u[2]))}return(i=tc.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function bt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new ot(r,u,c)}function _t(n,t,e){n=wt(n),t=wt(t),e=wt(e);var r=pt((.4124564*n+.3575761*t+.1804375*e)/Ja),u=pt((.2126729*n+.7151522*t+.072175*e)/Ga),i=pt((.0193339*n+.119192*t+.9503041*e)/Ka);return st(116*u-16,500*(r-u),200*(u-i))}function wt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function St(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function kt(n){return"function"==typeof n?n:function(){return n}}function Et(n){return n}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!oa.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(ic),ic=setTimeout(qt,t)),uc=0):(uc=1,ac(qt))}function Lt(){var n=Date.now();for(oc=ec;oc;)n>=oc.t&&(oc.f=oc.c(n-oc.t)),oc=oc.n;return n}function Tt(){for(var n,t=ec,e=1/0;t;)t.f?t=n?n.n=t.n:ec=t.n:(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:Et;return function(n){var e=lc.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=sc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new hc(e-1)),1),e}function i(n,e){return t(n=new hc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{hc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{hc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{hc=jt;var r=new jt;return r._=t,n(r,e)._}finally{hc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++aa;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in pc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{hc=jt;var t=new hc;return t._=n,r(t)}finally{hc=Date}}var r=t(n);return e.parse=function(n){try{hc=jt;var t=r.parse(n);return t&&t._}finally{hc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=It(v),b=Zt(v),_=It(d),w=Zt(d),S=It(m),k=Zt(m),E=It(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Yt(n.getDate(),t,2)},e:function(n,t){return Yt(n.getDate(),t,2)},H:function(n,t){return Yt(n.getHours(),t,2)},I:function(n,t){return Yt(n.getHours()%12||12,t,2)},j:function(n,t){return Yt(1+fc.dayOfYear(n),t,3)},L:function(n,t){return Yt(n.getMilliseconds(),t,3)},m:function(n,t){return Yt(n.getMonth()+1,t,2)},M:function(n,t){return Yt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Yt(n.getSeconds(),t,2)},U:function(n,t){return Yt(fc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Yt(fc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Yt(n.getFullYear()%100,t,2)},Y:function(n,t){return Yt(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function Yt(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function It(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new a,e=-1,r=n.length;++e68?1900:2e3)}function Kt(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=0|va(t)/60,u=va(t)%60;return e+Yt(r,"0",2)+Yt(u,"0",2)}function oe(n,t,e){dc.lastIndex=0;var r=dc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);_c.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;wc.point=function(o,a){wc.point=n,r=(t=o)*Fa,u=Math.cos(a=(e=a)*Fa/2+Da/4),i=Math.sin(a)},wc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),nt(n[2])]}function be(n,t){return va(n[0]-t[0])a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:y,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-ja-Ta:ja-n[1])-((t=t.x)[0]<0?t[1]-ja-Ta:ja-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Da:-Da,c=va(i-e);va(c-Da)0?ja:-ja),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Da&&(va(e-u)Ta?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*ja,r.point(-Da,u),r.point(0,u),r.point(Da,u),r.point(Da,0),r.point(Da,-u),r.point(0,-u),r.point(-Da,-u),r.point(-Da,0),r.point(-Da,u);else if(va(n[0]-t[0])>Ta){var i=n[0]a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+Da/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+Da/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>Da,k=p*M;if(_c.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*Pa:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*nt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ta>i||Ta>i&&0>_c)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Da:-Da),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ta,p[1]+=Ta,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=va(A-Da)A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(va(b[0]-w)Da^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:Da-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=va(i)>Ta,c=gr(n,6*Fa);return Le(t,e,c,o?[0,-n]:[-Da,n-Da])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ye(n,t,e,r){function u(r,u){return va(r[0]-n)0?0:3:va(r[0]-e)0?2:1:va(r[1]-t)0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&K(l,i,n)>0&&++t:i[1]<=r&&K(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Uc,Math.min(Uc,n)),t=Math.max(-Uc,Math.min(Uc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ie(n){var t=0,e=Da/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Da/180,e=n[1]*Da/180):[180*(t/Da),180*(e/Da)]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,nt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Fc+=u*n-r*t,r=n,u=t}var t,e,r,u;Zc.point=function(i,o){Zc.point=n,t=r=i,e=u=o},Zc.lineEnd=function(){n(t,e)}}function Xe(n,t){Hc>n&&(Hc=n),n>Yc&&(Yc=n),Oc>t&&(Oc=t),t>Ic&&(Ic=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){Ec+=n,Ac+=t,++Nc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);Cc+=o*(t+n)/2,zc+=o*(e+r)/2,qc+=o,We(t=n,e=r)}var t,e;Xc.point=function(r,u){Xc.point=n,We(t=r,e=u)}}function Ge(){Xc.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);Cc+=o*(r+n)/2,zc+=o*(u+t)/2,qc+=o,o=u*n-r*t,Lc+=o*(r+n),Tc+=o*(u+t),Rc+=3*o,We(r=n,u=t)}var t,e,r,u;Xc.point=function(i,o){Xc.point=n,We(t=r=i,e=u=o)},Xc.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Pa)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:y};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=va(va(w)-1)i||va((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Fa),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Ha,e*Ha])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Fa,n[1]*Fa),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Ha,n[1]*Ha]}function r(){a=Ae(o=lr(m,y,M),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,M=0,x=Pc,b=Et,_=null,w=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(x(o,f(b(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(x=null==n?(_=n,Pc):He((_=+n)*Fa),u()):_},t.clipExtent=function(n){return arguments.length?(w=n,b=n?Ye(n[0][0],n[0][1],n[1][0],n[1][1]):Et,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Fa,d=n[1]%360*Fa,r()):[v*Ha,d*Ha]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Fa,y=n[1]%360*Fa,M=n.length>2?n[2]%360*Fa:0,r()):[m*Ha,y*Ha,M*Ha]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Fa,e*Fa)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>Da?n-Pa:-Da>n?n+Pa:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>Da?t-Pa:-Da>t?t+Pa:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),nt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),nt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*Pa)):(u=n+o*Pa,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=Q(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ta)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ta,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ta,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(ut(r-t)+u*o*ut(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ha,Math.atan2(o,Math.sqrt(r*r+u*u))*Ha]}:function(){return[n*Ha,t*Ha]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Fa),o=Math.cos(u),a=va((n*=Fa)-t),c=Math.cos(a);$c+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Bc.point=function(u,i){t=u*Fa,e=Math.sin(i*=Fa),r=Math.cos(i),Bc.point=n},Bc.lineEnd=function(){Bc.point=Bc.lineEnd=y}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-ja+Ta>t&&(t=-ja+Ta):t>ja-Ta&&(t=ja-Ta);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Da/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=G(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-ja]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return va(u)u;u++){for(;r>1&&K(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=ol.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),rl.remove(n),ol.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&va(e-c.circle.x)s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=rl._;a;)if(r=Fr(a,o)-i,r>Ta)a=a.L;else{if(u=i-Hr(a,o),!(u>Ta)){r>-Ta?(t=a.P,e=a):u>-Ta?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(rl.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),rl.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),Vr(e),void 0;if(!e)return c.edge=Jr(t.site,c.site),void 0;Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Yr(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=el,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(va(r-t)>Ta||va(u-e)>Ta)&&(a.splice(o,0,new Qr(Gr(i.site,s,va(r-f)Ta?{x:f,y:va(t-f)Ta?{x:va(e-p)Ta?{x:h,y:va(t-h)Ta?{x:va(e-g)=-Ra)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=al.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=il._;M;)if(m.yd||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.yr||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.yg){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.xi||f>o||r>h||u>g)){if(p=n.point){var p,v=t-p[0],d=e-p[1],m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+Mt(Math.round(e+i*n))+Mt(Math.round(r+o*n))+Mt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=ll.lastIndex=sl.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=ll.exec(n))&&(r=sl.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=sl.lastIndex;return ir;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*ja)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Pa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Pa/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return lt(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return at(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ft(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++oe;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.ro;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:bl}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Oi:ji,c=r?Yu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Yi(n,t,e,r)},u()}function Ii(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=lc.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(va(r[0]),va(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in _l?Math.abs(e-Bi(Math.max(va(t[0]),va(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:Sl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++0;h--)o.push(i(l)*h);for(l=0;o[l]c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return wl;arguments.length<2?t=wl:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Ii(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Ii(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new a;for(var i,o=-1,c=r.length;++on?[0/0,0/0]:[n>0?a[n-1]:r[0],nt?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=kt(e),p=kt(r);++f1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++ur)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,c)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=oc,v=[];return p.t=g+c,u>=g?a(u-g):(p.c=a,void 0)},0,c)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Wl,u);return i==Wl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Wl[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Ii(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.3"};Date.now||(Date.now=function(){return+new Date});var ea=[].slice,ra=function(n){return ea.call(n)},ua=document,ia=ua.documentElement,oa=window;try{ra(ia.childNodes)[0].nodeType}catch(aa){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{ua.createElement("div").style.setProperty("opacity",0,"")}catch(ca){var la=oa.Element.prototype,sa=la.setAttribute,fa=la.setAttributeNS,ha=oa.CSSStyleDeclaration.prototype,ga=ha.setProperty;la.setAttribute=function(n,t){sa.call(this,n,t+"")},la.setAttributeNS=function(n,t,e){fa.call(this,n,t,e+"")},ha.setProperty=function(n,t,e){ga.call(this,n,t+"",e)}}ta.ascending=n,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ur&&(e=r)}else{for(;++u=r){e=r;break}for(;++ur&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ue&&(e=r)}else{for(;++u=r){e=r;break}for(;++ue&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var r,u=0,i=n.length,o=-1;if(1===arguments.length)for(;++o1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var pa=r(n);ta.bisectLeft=pa.left,ta.bisect=ta.bisectRight=pa.right,ta.bisector=function(t){return r(1===t.length?function(e,r){return n(t(e),r)}:t)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=0|Math.random()*i--,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,u),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var va=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,u=[],o=i(va(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)u.push(r/o);else for(;(r=n+e*++a)=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var l,s,f,h,g=-1,p=o.length,v=i[c++],d=new a;++g=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new v;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},o(v,{has:s,add:function(n){return this._[c(n+="")]=!0,n},remove:f,values:h,size:g,empty:p,forEach:function(n){for(var t in this._)n.call(this,l(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(Ma,"\\$&")};var Ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,xa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ba=function(n,t){return t.querySelector(n)},_a=function(n,t){return t.querySelectorAll(n)},wa=ia.matches||ia[m(ia,"matchesSelector")],Sa=function(n,t){return wa.call(n,t)};"function"==typeof Sizzle&&(ba=function(n,t){return Sizzle(n,t)[0]||null},_a=Sizzle,Sa=Sizzle.matchesSelector),ta.selection=function(){return Na};var ka=ta.selection.prototype=[];ka.select=function(n){var t,e,r,u,i=[];n=k(n);for(var o=-1,a=this.length;++o=0&&(e=n.slice(0,t),n=n.slice(t+1)),Ea.hasOwnProperty(e)?{space:Ea[e],local:n}:n}},ka.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(A(t,n[t]));return this}return this.each(A(n,t))},ka.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=z(n)).length,u=-1;if(t=e.classList){for(;++ur){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(T(e,n[e],t));return this}if(2>r)return oa.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(T(n,t,e))},ka.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},ka.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},ka.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},ka.append=function(n){return n=D(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},ka.insert=function(n,t){return n=D(n),t=k(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},ka.remove=function(){return this.each(P)},ka.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new a,y=new Array(o);for(r=-1;++rr;++r)p[r]=U(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),l.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++ii;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return S(u)},ka.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},ka.sort=function(n){n=F.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},ka.size=function(){var n=0;return H(this,function(){++n}),n};var Aa=[];ta.selection.enter=O,ta.selection.enter.prototype=Aa,Aa.append=ka.append,Aa.empty=ka.empty,Aa.node=ka.node,Aa.call=ka.call,Aa.size=ka.size,Aa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(I(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(I(n,t,e))};var Ca=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ca.forEach(function(n){"on"+n in ua&&Ca.remove(n)});var za="onselectstart"in ua?null:m(ia.style,"userSelect"),qa=0;ta.mouse=function(n){return $(n,_())};var La=/WebKit/.test(oa.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=_().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return $(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=e.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(u()).on(i+d,a).on(o+d,c),y=X(),M=t(h,v);r?(l=r.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var e=w(n,"drag","dragstart","dragend"),r=null,u=t(y,ta.mouse,J,"mousemove","mouseup"),i=t(B,ta.touch,W,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},ta.rebind(n,e,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=_().touches),t?ra(t).map(function(t){var e=$(n,t);return e.identifier=t.identifier,e}):[]};var Ta=1e-6,Ra=Ta*Ta,Da=Math.PI,Pa=2*Da,Ua=Pa-Ta,ja=Da/2,Fa=Da/180,Ha=180/Da,Oa=Math.SQRT2,Ya=2,Ia=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=et(v),o=i/(Ya*h)*(e*rt(Oa*t+v)-tt(v));return[r+o*l,u+o*s,i*e/et(Oa*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Oa*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Ia*f)/(2*i*Ya*h),p=(c*c-i*i-Ia*f)/(2*c*Ya*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Oa;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(z,s).on(Xa+".zoom",h).on("dblclick.zoom",g).on(T,f)}function t(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function e(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function r(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=e(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function i(t,e,i,o){t.__chart__={x:k.x,y:k.y,k:k.k},r(Math.pow(2,o)),u(v=e,i),t=ta.select(t),N>0&&(t=t.transition().duration(N)),t.call(n.event)}function o(){x&&x.domain(M.range().map(function(n){return(n-k.x)/k.k}).map(M.invert)),S&&S.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function a(n){C++||n({type:"zoomstart"})}function c(n){o(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function l(n){--C||n({type:"zoomend"}),v=null}function s(){function n(){s=1,u(ta.mouse(r),h),c(o)}function e(){f.on(q,null).on(L,null),g(s&&ta.event.target===i),l(o)}var r=this,i=ta.event.target,o=R.of(r,arguments),s=0,f=ta.select(oa).on(q,n).on(L,e),h=t(ta.mouse(r)),g=X();Fl.call(r),a(o)}function f(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=t(n))}),n}function e(){var t=ta.event.target;ta.select(t).on(x,o).on(_,h),w.push(t);for(var e=ta.event.changedTouches,r=0,u=e.length;u>r;++r)d[e[r].identifier]=null;var a=n(),c=Date.now();if(1===a.length){if(500>c-y){var l=a[0];i(p,l,d[l.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),b()}y=c}else if(a.length>1){var l=a[0],s=a[1],f=l[0]-s[0],g=l[1]-s[1];m=f*f+g*g}}function o(){var n,t,e,i,o=ta.touches(p);Fl.call(p);for(var a=0,l=o.length;l>a;++a,i=null)if(e=o[a],i=d[e.identifier]){if(t)break;n=e,t=i}if(i){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*g)}y=null,u(n,t),c(v)}function h(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(w).on(M,null),S.on(z,s).on(T,f),E(),l(v)}var g,p=this,v=R.of(p,arguments),d={},m=0,M=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+M,_="touchend"+M,w=[],S=ta.select(p),E=X();e(),a(v),S.on(z,null).on(T,e)}function h(){var n=R.of(this,arguments);m?clearTimeout(m):(p=t(v=d||ta.mouse(this)),Fl.call(this),a(n)),m=setTimeout(function(){m=null,l(n)},50),b(),r(Math.pow(2,.002*Za())*k.k),u(v,p),c(n)}function g(){var n=ta.mouse(this),e=Math.log(k.k)/Math.LN2;i(this,n,t(n),ta.event.shiftKey?Math.ceil(e)-1:Math.floor(e)+1)}var p,v,d,m,y,M,x,_,S,k={x:0,y:0,k:1},E=[960,500],A=Va,N=250,C=0,z="mousedown.zoom",q="mousemove.zoom",L="mouseup.zoom",T="touchstart.zoom",R=w(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=R.of(this,arguments),t=k;Ul?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},a(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],u=v?v[0]:e/2,i=v?v[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){l(n)}).each("end.zoom",function(){l(n)}):(this.__chart__=k,a(n),c(n),l(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},o(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},o(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Va:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(d=t&&[+t[0],+t[1]],n):d},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(N=+t,n):N},n.x=function(t){return arguments.length?(x=t,M=t.copy(),k={x:0,y:0,k:1},n):x},n.y=function(t){return arguments.length?(S=t,_=t.copy(),k={x:0,y:0,k:1},n):S},ta.rebind(n,R,"on")};var Za,Va=[0,1/0],Xa="onwheel"in ua?(Za=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Za=function(){return ta.event.wheelDelta},"mousewheel"):(Za=function(){return-ta.event.detail},"MozMousePixelScroll");ta.color=it,it.prototype.toString=function(){return this.rgb()+""},ta.hsl=ot;var $a=ot.prototype=new it;$a.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,this.l/n)},$a.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,n*this.l)},$a.rgb=function(){return at(this.h,this.s,this.l)},ta.hcl=ct;var Ba=ct.prototype=new it;Ba.brighter=function(n){return new ct(this.h,this.c,Math.min(100,this.l+Wa*(arguments.length?n:1)))},Ba.darker=function(n){return new ct(this.h,this.c,Math.max(0,this.l-Wa*(arguments.length?n:1)))},Ba.rgb=function(){return lt(this.h,this.c,this.l).rgb()},ta.lab=st;var Wa=18,Ja=.95047,Ga=1,Ka=1.08883,Qa=st.prototype=new it;Qa.brighter=function(n){return new st(Math.min(100,this.l+Wa*(arguments.length?n:1)),this.a,this.b)},Qa.darker=function(n){return new st(Math.max(0,this.l-Wa*(arguments.length?n:1)),this.a,this.b)},Qa.rgb=function(){return ft(this.l,this.a,this.b)},ta.rgb=dt;var nc=dt.prototype=new it;nc.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new dt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new dt(u,u,u)},nc.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new dt(n*this.r,n*this.g,n*this.b)},nc.hsl=function(){return bt(this.r,this.g,this.b)},nc.toString=function(){return"#"+Mt(this.r)+Mt(this.g)+Mt(this.b)};var tc=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});tc.forEach(function(n,t){tc.set(n,mt(t))}),ta.functor=kt,ta.xhr=At(Et),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new v,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var ec,rc,uc,ic,oc,ac=oa[m(oa,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};rc?rc.n=i:ec=i,rc=i,uc||(ic=clearTimeout(ic),uc=1,ac(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var cc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),cc[8+e/3]};var lc=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,sc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),fc=ta.time={},hc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){gc.setUTCDate.apply(this._,arguments)},setDay:function(){gc.setUTCDay.apply(this._,arguments)},setFullYear:function(){gc.setUTCFullYear.apply(this._,arguments)},setHours:function(){gc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){gc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){gc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){gc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){gc.setUTCSeconds.apply(this._,arguments)},setTime:function(){gc.setTime.apply(this._,arguments)}};var gc=Date.prototype;fc.year=Ft(function(n){return n=fc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),fc.years=fc.year.range,fc.years.utc=fc.year.utc.range,fc.day=Ft(function(n){var t=new hc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),fc.days=fc.day.range,fc.days.utc=fc.day.utc.range,fc.dayOfYear=function(n){var t=fc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=fc[n]=Ft(function(n){return(n=fc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=fc.year(n).getDay();return Math.floor((fc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});fc[n+"s"]=e.range,fc[n+"s"].utc=e.utc.range,fc[n+"OfYear"]=function(n){var e=fc.year(n).getDay();return Math.floor((fc.dayOfYear(n)+(e+t)%7)/7)}}),fc.week=fc.sunday,fc.weeks=fc.sunday.range,fc.weeks.utc=fc.sunday.utc.range,fc.weekOfYear=fc.sundayOfYear;var pc={"-":"",_:" ",0:"0"},vc=/^\s*\d+/,dc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var mc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=mc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,yc),le(yc.s,this.s,this),this.s?this.t+=yc.t:this.s=yc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var yc=new ce;ta.geo.stream=function(n,t){n&&Mc.hasOwnProperty(n.type)?Mc[n.type](n,t):se(n,t)};var Mc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*Da+n:n,wc.lineStart=wc.lineEnd=wc.point=y}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Fa,e*Fa]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Ha*l,d=va(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Ha;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Ha;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=va(r)>180?r+(r>0?360:-360):r}else v=n,d=e;wc.point(n,e),t(n,e)}function i(){wc.lineStart()}function o(){u(v,d),wc.lineEnd(),va(y)>Ta&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n_c?(s=-(h=180),f=-(g=90)):y>Ta?g=90:-Ta>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){Sc=kc=Ec=Ac=Nc=Cc=zc=qc=Lc=Tc=Rc=0,ta.geo.stream(n,Dc);var t=Lc,e=Tc,r=Rc,u=t*t+e*e+r*r;return Ra>u&&(t=Cc,e=zc,r=qc,Ta>kc&&(t=Ec,e=Ac,r=Nc),u=t*t+e*e+r*r,Ra>u)?[0/0,0/0]:[Math.atan2(e,t)*Ha,nt(r/Math.sqrt(u))*Ha]};var Sc,kc,Ec,Ac,Nc,Cc,zc,qc,Lc,Tc,Rc,Dc={sphere:y,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){Dc.lineStart=Ee},polygonEnd:function(){Dc.lineStart=Se}},Pc=Le(Ne,Pe,je,[-Da,-Da/2]),Uc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ye(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ie(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ta,f+.12*l+Ta],[s-.214*l-Ta,f+.234*l-Ta]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ta,f+.166*l+Ta],[s-.115*l-Ta,f+.234*l-Ta]]).stream(c).point,n},n.scale(1070)};var jc,Fc,Hc,Oc,Yc,Ic,Zc={point:y,lineStart:y,lineEnd:y,polygonStart:function(){Fc=0,Zc.lineStart=Ve},polygonEnd:function(){Zc.lineStart=Zc.lineEnd=Zc.point=y,jc+=va(Fc/2)}},Vc={point:Xe,lineStart:y,lineEnd:y,polygonStart:y,polygonEnd:y},Xc={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Xc.lineStart=Ke},polygonEnd:function(){Xc.point=We,Xc.lineStart=Je,Xc.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return jc=0,ta.geo.stream(n,u(Zc)),jc},n.centroid=function(n){return Ec=Ac=Nc=Cc=zc=qc=Lc=Tc=Rc=0,ta.geo.stream(n,u(Xc)),Rc?[Lc/Rc,Tc/Rc]:qc?[Cc/qc,zc/qc]:Nc?[Ec/Nc,Ac/Nc]:[0/0,0/0]},n.bounds=function(n){return Yc=Ic=-(Hc=Oc=1/0),ta.geo.stream(n,u(Vc)),[[Hc,Oc],[Yc,Ic]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):Et,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Fa,t[1]*Fa),t[0]*=Ha,t[1]*=Ha,t}return n=lr(n[0]%360*Fa,n[1]*Fa,n.length>2?n[2]*Fa:0),t.invert=function(t){return t=n.invert(t[0]*Fa,t[1]*Fa),t[0]*=Ha,t[1]*=Ha,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Fa,-n[1]*Fa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ha,n[1]*=Ha}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Fa,u*Fa),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Fa,(u=+r)*Fa),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Fa,u=n[1]*Fa,i=t[1]*Fa,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return va(n%d)>Ta}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return va(n%m)>Ta}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ta],[180,90-Ta]]).minorExtent([[-180,-80-Ta],[180,80+Ta]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Fa,n[1]*Fa,t[0]*Fa,t[1]*Fa)},ta.geo.length=function(n){return $c=0,ta.geo.stream(n,Bc),$c};var $c,Bc={sphere:y,point:y,lineStart:xr,lineEnd:y,polygonStart:y,polygonEnd:y},Wc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Wc)}).raw=Wc;var Jc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},Et);(ta.geo.azimuthalEquidistant=function(){return ur(Jc)}).raw=Jc,(ta.geo.conicConformal=function(){return Ie(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ie(wr)}).raw=wr;var Gc=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur(Gc)}).raw=Gc,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-ja]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Kc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Kc)}).raw=Kc;var Qc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Qc)}).raw=Qc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-ja]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=kt(e),i=kt(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ta)*Ta,y:Math.round(o(n,t)/Ta)*Ta,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=cl;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Ir),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=kt(a),x=kt(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.xm&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=hl.get(e)||fl,r=gl.get(r)||Et,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:pl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var pl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=vl,h=dl,g=-30,p=ml,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,M,x,b=m.length,_=y.length;for(e=0;_>e;++e)a=y[e],f=a.source,h=a.target,M=h.x-f.x,x=h.y-f.y,(p=M*M+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,M*=p,x*=p,h.x-=M*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=M*(d=1-d),f.y+=x*d);if((d=r*v)&&(M=l[0]/2,x=l[1]/2,e=-1,d))for(;++e0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;l>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++at;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(Et).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?(this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e),void 0):e},ta.rebind(a,c,"on")};var vl=20,dl=1,ml=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++lf?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===yl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=yl,r=0,u=Pa,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var yl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=Et,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:Ml.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:xl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var Ml=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),xl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=kt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:kt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.xp.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++oe&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++ie.dx)&&(s=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var bl={floor:Et,ceil:Et};ta.scale.linear=function(){return Yi([0,1],[0,1],mu,!1)};var _l={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var wl=ta.format(".0e"),Sl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(kl)},ta.scale.category20=function(){return ta.scale.ordinal().range(El)},ta.scale.category20b=function(){return ta.scale.ordinal().range(Al)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Nl)};var kl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(yt),El=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(yt),Al=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(yt),Nl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(yt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-ja,f=a.apply(this,arguments)-ja,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ua)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===Cl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=nt(d/l*Math.sin(m))),n&&(E=nt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=Da?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=Da?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),Y=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],Y[1][0],Y[1][1]),",",g," ",Y[1],"A",H,",",H," 0 0,",v," ",Y[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",Y[0])}else N.push("M",y,",",M);if(null!=S){var I=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-I,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-I,g);p===I?N.push("L",V[0],"A",I,",",I," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",I,",",I," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",I,",",I," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=Cl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=kt(t),n):e},n.outerRadius=function(t){return arguments.length?(r=kt(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=kt(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==Cl?Cl:kt(t),n):i},n.startAngle=function(t){return arguments.length?(o=kt(t),n):o},n.endAngle=function(t){return arguments.length?(a=kt(t),n):a},n.padAngle=function(t){return arguments.length?(c=kt(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-ja;return[Math.cos(t)*n,Math.sin(t)*n]},n};var Cl="auto";ta.svg.line=function(){return ho(Et)};var zl=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});zl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var ql=[0,2/3,1/3,0],Ll=[0,1/3,2/3,0],Tl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(Et)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-ja,s=l.call(n,u,r)-ja;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Da)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=kt(t),n):a},n.source=function(t){return arguments.length?(i=kt(t),n):i},n.target=function(t){return arguments.length?(o=kt(t),n):o},n.startAngle=function(t){return arguments.length?(c=kt(t),n):c},n.endAngle=function(t){return arguments.length?(l=kt(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=kt(e),n):t},n.target=function(t){return arguments.length?(e=kt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(Rl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=kt(e),n):t},n.size=function(t){return arguments.length?(e=kt(t),n):e},n};var Rl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Pl)),e=t*Pl;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/Dl),e=t*Dl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Dl),e=t*Dl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=Rl.keys();var Dl=Math.sqrt(3),Pl=Math.tan(30*Fa);ka.transition=function(n){for(var t,e,r=Ul||++Ol,u=Xo(n),i=[],o=jl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++ai;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Io(u,this.namespace,this.id)},Hl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):H(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Hl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Hl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Hl.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=oa.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=mu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Zo(this,"style."+n,t,u)},Hl.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,oa.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Hl.text=function(n){return Zo(this,"text",n,Vo)},Hl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Hl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),H(this,function(r){r[e][t].ease=n}))},Hl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:H(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Hl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:H(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Hl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=jl,i=Ul;try{Ul=e,H(this,function(t,u,i){jl=t[r][e],n.call(t,t.__data__,u,i)})}finally{jl=u,Ul=i}}else H(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Hl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ol,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Io(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):Et:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ta),d=ta.transition(p.exit()).style("opacity",Ta).remove(),m=ta.transition(p.order()).style("opacity",1),y=Math.max(u,0)+o,M=Ui(f),x=l.selectAll(".domain").data([0]),b=(x.enter().append("path").attr("class","domain"),ta.transition(x));v.append("line"),v.append("text");var _,w,S,k,E=v.select("line"),A=m.select("line"),N=p.select("text").text(g),C=v.select("text"),z=m.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,_="x",S="y",w="x2",k="y2",N.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),b.attr("d","M"+M[0]+","+q*i+"V0H"+M[1]+"V"+q*i)):(n=Wo,_="y",S="x",w="y2",k="x2",N.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),b.attr("d","M"+q*i+","+M[0]+"H0V"+M[1]+"H"+q*i)),E.attr(k,q*u),C.attr(S,q*y),A.attr(w,0).attr(k,q*u),z.attr(_,0).attr(S,q*y),f.rangeBand){var L=f,T=L.rangeBand()/2;s=f=function(n){return L(n)+T}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=Yl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Il?t+"":Yl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Yl="bottom",Il={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(i){i.each(function(){var i=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,Et);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Zl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var s,f=ta.transition(i),h=ta.transition(o);c&&(s=Ui(c),h.attr("x",s[0]).attr("width",s[1]-s[0]),e(f)),l&&(s=Ui(l),h.attr("y",s[0]).attr("height",s[1]-s[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==ta.event.keyCode&&(N||(y=null,z[0]-=s[1],z[1]-=f[1],N=2),b())}function p(){32==ta.event.keyCode&&2==N&&(z[0]+=s[1],z[1]+=f[1],N=0,b())}function v(){var n=ta.mouse(x),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),N||(ta.event.altKey?(y||(y=[(s[0]+s[1])/2,(f[0]+f[1])/2]),z[0]=s[+(n[0]p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),C(),w({type:"brushend"})}var y,M,x=this,_=ta.select(ta.event.target),w=a.of(x,arguments),S=ta.select(x),k=_.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&l,N=_.classed("extent"),C=X(),z=ta.mouse(x),q=ta.select(oa).on("keydown.brush",u).on("keyup.brush",p);if(ta.event.changedTouches?q.on("touchmove.brush",v).on("touchend.brush",m):q.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),N)z[0]=s[0]-z[0],z[1]=f[0]-z[1];else if(k){var L=+/w$/.test(k),T=+/^n/.test(k);M=[s[1-L]-z[0],f[1-T]-z[1]],z[0]=s[L],z[1]=f[T]}else ta.event.altKey&&(y=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=w(n,"brushstart","brush","brushend"),c=null,l=null,s=[0,0],f=[0,0],h=!0,g=!0,p=Vl[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:s,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Ul?ta.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,s=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(s,t.x),r=yu(f,t.y);return i=o=null,function(u){s=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Vl[!c<<1|!l],n):c},n.y=function(t){return arguments.length?(l=t,p=Vl[!c<<1|!l],n):l},n.clamp=function(t){return arguments.length?(c&&l?(h=!!t[0],g=!!t[1]):c?h=!!t:l&&(g=!!t),n):c&&l?[h,g]:c?h:l?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],l&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=s[0]||r!=s[1])&&(s=[e,r])),l&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],l.invert&&(u=l(u),a=l(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),l&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],l.invert&&(u=l.invert(u),a=l.invert(a)),u>a&&(h=u,u=a,a=h))),c&&l?[[e,u],[r,a]]:c?[e,r]:l&&[u,a])},n.clear=function(){return n.empty()||(s=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!l&&f[0]==f[1]},ta.rebind(n,a,"on")};var Zl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Vl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Xl=fc.format=mc.timeFormat,$l=Xl.utc,Bl=$l("%Y-%m-%dT%H:%M:%S.%LZ");Xl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Bl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Bl.toString,fc.second=Ft(function(n){return new hc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),fc.seconds=fc.second.range,fc.seconds.utc=fc.second.utc.range,fc.minute=Ft(function(n){return new hc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),fc.minutes=fc.minute.range,fc.minutes.utc=fc.minute.utc.range,fc.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new hc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),fc.hours=fc.hour.range,fc.hours.utc=fc.hour.utc.range,fc.month=Ft(function(n){return n=fc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),fc.months=fc.month.range,fc.months.utc=fc.month.utc.range;var Wl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Jl=[[fc.second,1],[fc.second,5],[fc.second,15],[fc.second,30],[fc.minute,1],[fc.minute,5],[fc.minute,15],[fc.minute,30],[fc.hour,1],[fc.hour,3],[fc.hour,6],[fc.hour,12],[fc.day,1],[fc.day,2],[fc.week,1],[fc.month,1],[fc.month,3],[fc.year,1]],Gl=Xl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Kl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:Et,ceil:Et};Jl.year=fc.year,fc.scale=function(){return Go(ta.scale.linear(),Jl,Gl)};var Ql=Jl.map(function(n){return[n[0].utc,n[1]]}),ns=$l.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Ql.year=fc.year.utc,fc.scale.utc=function(){return Go(ta.scale.linear(),Ql,ns)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}(); \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/dagre-d3.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/dagre-d3.js new file mode 100644 index 0000000000..aed4090dbc --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_commons_gadget/commons/js/dagre-d3.js @@ -0,0 +1,17572 @@ +(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.dagreD3 = f()}})(function(){var define,module,exports;return (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 0; +} + +},{}],14:[function(require,module,exports){ +module.exports = intersectNode; + +function intersectNode(node, point) { + return node.intersect(point); +} + +},{}],15:[function(require,module,exports){ +var intersectLine = require("./intersect-line"); + +module.exports = intersectPolygon; + +/* + * Returns the point ({x, y}) at which the point argument intersects with the + * node argument assuming that it has the shape specified by polygon. + */ +function intersectPolygon(node, polyPoints, point) { + var x1 = node.x; + var y1 = node.y; + + var intersections = []; + + var minX = Number.POSITIVE_INFINITY, + minY = Number.POSITIVE_INFINITY; + polyPoints.forEach(function(entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect = intersectLine(node, point, + {x: left + p1.x, y: top + p1.y}, {x: left + p2.x, y: top + p2.y}); + if (intersect) { + intersections.push(intersect); + } + } + + if (!intersections.length) { + console.log("NO INTERSECTION FOUND, RETURN NODE CENTER", node); + return node; + } + + if (intersections.length > 1) { + // More intersections, find the one nearest to edge end point + intersections.sort(function(p, q) { + var pdx = p.x - point.x, + pdy = p.y - point.y, + distp = Math.sqrt(pdx * pdx + pdy * pdy), + + qdx = q.x - point.x, + qdy = q.y - point.y, + distq = Math.sqrt(qdx * qdx + qdy * qdy); + + return (distp < distq) ? -1 : (distp === distq ? 0 : 1); + }); + } + return intersections[0]; +} + +},{"./intersect-line":13}],16:[function(require,module,exports){ +module.exports = intersectRect; + +function intersectRect(node, point) { + var x = node.x; + var y = node.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = node.width / 2; + var h = node.height / 2; + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : h * dx / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : w * dy / dx; + } + + return {x: x + sx, y: y + sy}; +} + +},{}],17:[function(require,module,exports){ +var util = require("../util"); + +module.exports = addHtmlLabel; + +function addHtmlLabel(root, node) { + var fo = root + .append("foreignObject") + .attr("width", "100000"); + + var div = fo + .append("xhtml:div"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + + var label = node.label; + switch(typeof label) { + case "function": + div.insert(label); + break; + case "object": + // Currently we assume this is a DOM object. + div.insert(function() { return label; }); + break; + default: div.html(label); + } + + util.applyStyle(div, node.labelStyle); + div.style("display", "inline-block"); + // Fix for firefox + div.style("white-space", "nowrap"); + + var client = div[0][0].getBoundingClientRect(); + fo + .attr("width", client.width) + .attr("height", client.height); + + return fo; +} + +},{"../util":27}],18:[function(require,module,exports){ +var addTextLabel = require("./add-text-label"), + addHtmlLabel = require("./add-html-label"), + addSVGLabel = require("./add-svg-label"); + +module.exports = addLabel; + +function addLabel(root, node, location) { + var label = node.label; + var labelSvg = root.append("g"); + + // Allow the label to be a string, a function that returns a DOM element, or + // a DOM element itself. + if (node.labelType === "svg") { + addSVGLabel(labelSvg, node); + } else if (typeof label !== "string" || node.labelType === "html") { + addHtmlLabel(labelSvg, node); + } else { + addTextLabel(labelSvg, node); + } + + var labelBBox = labelSvg.node().getBBox(); + var y; + switch(location) { + case "top": + y = (-node.height / 2); + break; + case "bottom": + y = (node.height / 2) - labelBBox.height; + break; + default: + y = (-labelBBox.height / 2); + } + labelSvg.attr("transform", + "translate(" + (-labelBBox.width / 2) + "," + y + ")"); + + return labelSvg; +} + +},{"./add-html-label":17,"./add-svg-label":19,"./add-text-label":20}],19:[function(require,module,exports){ +var util = require("../util"); + +module.exports = addSVGLabel; + +function addSVGLabel(root, node) { + var domNode = root; + + domNode.node().appendChild(node.label); + + util.applyStyle(domNode, node.labelStyle); + + return domNode; +} + +},{"../util":27}],20:[function(require,module,exports){ +var util = require("../util"); + +module.exports = addTextLabel; + +/* + * Attaches a text label to the specified root. Handles escape sequences. + */ +function addTextLabel(root, node) { + var domNode = root.append("text"); + + var lines = processEscapeSequences(node.label).split("\n"); + for (var i = 0; i < lines.length; i++) { + domNode + .append("tspan") + .attr("xml:space", "preserve") + .attr("dy", "1em") + .attr("x", "1") + .text(lines[i]); + } + + util.applyStyle(domNode, node.labelStyle); + + return domNode; +} + +function processEscapeSequences(text) { + var newText = "", + escaped = false, + ch; + for (var i = 0; i < text.length; ++i) { + ch = text[i]; + if (escaped) { + switch(ch) { + case "n": newText += "\n"; break; + default: newText += ch; + } + escaped = false; + } else if (ch === "\\") { + escaped = true; + } else { + newText += ch; + } + } + return newText; +} + +},{"../util":27}],21:[function(require,module,exports){ +/* global window */ + +var lodash; + +if (require) { + try { + lodash = require("lodash"); + } catch (e) {} +} + +if (!lodash) { + lodash = window._; +} + +module.exports = lodash; + +},{"lodash":79}],22:[function(require,module,exports){ +"use strict"; + +var util = require("./util"), + d3 = require("./d3"); + +module.exports = positionClusters; + +function positionClusters(selection, g) { + var created = selection.filter(function() { return !d3.select(this).classed("update"); }); + + function translate(v) { + var node = g.node(v); + return "translate(" + node.x + "," + node.y + ")"; + } + + created.attr("transform", translate); + + util.applyTransition(selection, g) + .style("opacity", 1) + .attr("transform", translate); + + util.applyTransition(created.selectAll("rect"), g) + .attr("width", function(v) { return g.node(v).width; }) + .attr("height", function(v) { return g.node(v).height; }) + .attr("x", function(v) { + var node = g.node(v); + return -node.width / 2; + }) + .attr("y", function(v) { + var node = g.node(v); + return -node.height / 2; + }); + +} + +},{"./d3":7,"./util":27}],23:[function(require,module,exports){ +"use strict"; + +var util = require("./util"), + d3 = require("./d3"), + _ = require("./lodash"); + +module.exports = positionEdgeLabels; + +function positionEdgeLabels(selection, g) { + var created = selection.filter(function() { return !d3.select(this).classed("update"); }); + + function translate(e) { + var edge = g.edge(e); + return _.has(edge, "x") ? "translate(" + edge.x + "," + edge.y + ")" : ""; + } + + created.attr("transform", translate); + + util.applyTransition(selection, g) + .style("opacity", 1) + .attr("transform", translate); +} + +},{"./d3":7,"./lodash":21,"./util":27}],24:[function(require,module,exports){ +"use strict"; + +var util = require("./util"), + d3 = require("./d3"); + +module.exports = positionNodes; + +function positionNodes(selection, g) { + var created = selection.filter(function() { return !d3.select(this).classed("update"); }); + + function translate(v) { + var node = g.node(v); + return "translate(" + node.x + "," + node.y + ")"; + } + + created.attr("transform", translate); + + util.applyTransition(selection, g) + .style("opacity", 1) + .attr("transform", translate); +} + +},{"./d3":7,"./util":27}],25:[function(require,module,exports){ +var _ = require("./lodash"), + layout = require("./dagre").layout; + +module.exports = render; + +// This design is based on http://bost.ocks.org/mike/chart/. +function render() { + var createNodes = require("./create-nodes"), + createClusters = require("./create-clusters"), + createEdgeLabels = require("./create-edge-labels"), + createEdgePaths = require("./create-edge-paths"), + positionNodes = require("./position-nodes"), + positionEdgeLabels = require("./position-edge-labels"), + positionClusters = require("./position-clusters"), + shapes = require("./shapes"), + arrows = require("./arrows"); + + var fn = function(svg, g) { + preProcessGraph(g); + + var outputGroup = createOrSelectGroup(svg, "output"), + clustersGroup = createOrSelectGroup(outputGroup, "clusters"), + edgePathsGroup = createOrSelectGroup(outputGroup, "edgePaths"), + edgeLabels = createEdgeLabels(createOrSelectGroup(outputGroup, "edgeLabels"), g), + nodes = createNodes(createOrSelectGroup(outputGroup, "nodes"), g, shapes); + + layout(g); + + positionNodes(nodes, g); + positionEdgeLabels(edgeLabels, g); + createEdgePaths(edgePathsGroup, g, arrows); + + var clusters = createClusters(clustersGroup, g); + positionClusters(clusters, g); + + postProcessGraph(g); + }; + + fn.createNodes = function(value) { + if (!arguments.length) return createNodes; + createNodes = value; + return fn; + }; + + fn.createClusters = function(value) { + if (!arguments.length) return createClusters; + createClusters = value; + return fn; + }; + + fn.createEdgeLabels = function(value) { + if (!arguments.length) return createEdgeLabels; + createEdgeLabels = value; + return fn; + }; + + fn.createEdgePaths = function(value) { + if (!arguments.length) return createEdgePaths; + createEdgePaths = value; + return fn; + }; + + fn.shapes = function(value) { + if (!arguments.length) return shapes; + shapes = value; + return fn; + }; + + fn.arrows = function(value) { + if (!arguments.length) return arrows; + arrows = value; + return fn; + }; + + return fn; +} + +var NODE_DEFAULT_ATTRS = { + paddingLeft: 10, + paddingRight: 10, + paddingTop: 10, + paddingBottom: 10, + rx: 0, + ry: 0, + shape: "rect" +}; + +var EDGE_DEFAULT_ATTRS = { + arrowhead: "normal", + lineInterpolate: "linear" +}; + +function preProcessGraph(g) { + g.nodes().forEach(function(v) { + var node = g.node(v); + if (!_.has(node, "label") && !g.children(v).length) { node.label = v; } + + if (_.has(node, "paddingX")) { + _.defaults(node, { + paddingLeft: node.paddingX, + paddingRight: node.paddingX + }); + } + + if (_.has(node, "paddingY")) { + _.defaults(node, { + paddingTop: node.paddingY, + paddingBottom: node.paddingY + }); + } + + if (_.has(node, "padding")) { + _.defaults(node, { + paddingLeft: node.padding, + paddingRight: node.padding, + paddingTop: node.padding, + paddingBottom: node.padding + }); + } + + _.defaults(node, NODE_DEFAULT_ATTRS); + + _.each(["paddingLeft", "paddingRight", "paddingTop", "paddingBottom"], function(k) { + node[k] = Number(node[k]); + }); + + // Save dimensions for restore during post-processing + if (_.has(node, "width")) { node._prevWidth = node.width; } + if (_.has(node, "height")) { node._prevHeight = node.height; } + }); + + g.edges().forEach(function(e) { + var edge = g.edge(e); + if (!_.has(edge, "label")) { edge.label = ""; } + _.defaults(edge, EDGE_DEFAULT_ATTRS); + }); +} + +function postProcessGraph(g) { + _.each(g.nodes(), function(v) { + var node = g.node(v); + + // Restore original dimensions + if (_.has(node, "_prevWidth")) { + node.width = node._prevWidth; + } else { + delete node.width; + } + + if (_.has(node, "_prevHeight")) { + node.height = node._prevHeight; + } else { + delete node.height; + } + + delete node._prevWidth; + delete node._prevHeight; + }); +} + +function createOrSelectGroup(root, name) { + var selection = root.select("g." + name); + if (selection.empty()) { + selection = root.append("g").attr("class", name); + } + return selection; +} + +},{"./arrows":2,"./create-clusters":3,"./create-edge-labels":4,"./create-edge-paths":5,"./create-nodes":6,"./dagre":8,"./lodash":21,"./position-clusters":22,"./position-edge-labels":23,"./position-nodes":24,"./shapes":26}],26:[function(require,module,exports){ +"use strict"; + +var intersectRect = require("./intersect/intersect-rect"), + intersectEllipse = require("./intersect/intersect-ellipse"), + intersectCircle = require("./intersect/intersect-circle"), + intersectPolygon = require("./intersect/intersect-polygon"); + +module.exports = { + rect: rect, + ellipse: ellipse, + circle: circle, + diamond: diamond +}; + +function rect(parent, bbox, node) { + var shapeSvg = parent.insert("rect", ":first-child") + .attr("rx", node.rx) + .attr("ry", node.ry) + .attr("x", -bbox.width / 2) + .attr("y", -bbox.height / 2) + .attr("width", bbox.width) + .attr("height", bbox.height); + + node.intersect = function(point) { + return intersectRect(node, point); + }; + + return shapeSvg; +} + +function ellipse(parent, bbox, node) { + var rx = bbox.width / 2, + ry = bbox.height / 2, + shapeSvg = parent.insert("ellipse", ":first-child") + .attr("x", -bbox.width / 2) + .attr("y", -bbox.height / 2) + .attr("rx", rx) + .attr("ry", ry); + + node.intersect = function(point) { + return intersectEllipse(node, rx, ry, point); + }; + + return shapeSvg; +} + +function circle(parent, bbox, node) { + var r = Math.max(bbox.width, bbox.height) / 2, + shapeSvg = parent.insert("circle", ":first-child") + .attr("x", -bbox.width / 2) + .attr("y", -bbox.height / 2) + .attr("r", r); + + node.intersect = function(point) { + return intersectCircle(node, r, point); + }; + + return shapeSvg; +} + +// Circumscribe an ellipse for the bounding box with a diamond shape. I derived +// the function to calculate the diamond shape from: +// http://mathforum.org/kb/message.jspa?messageID=3750236 +function diamond(parent, bbox, node) { + var w = (bbox.width * Math.SQRT2) / 2, + h = (bbox.height * Math.SQRT2) / 2, + points = [ + { x: 0, y: -h }, + { x: -w, y: 0 }, + { x: 0, y: h }, + { x: w, y: 0 } + ], + shapeSvg = parent.insert("polygon", ":first-child") + .attr("points", points.map(function(p) { return p.x + "," + p.y; }).join(" ")); + + node.intersect = function(p) { + return intersectPolygon(node, points, p); + }; + + return shapeSvg; +} + +},{"./intersect/intersect-circle":11,"./intersect/intersect-ellipse":12,"./intersect/intersect-polygon":15,"./intersect/intersect-rect":16}],27:[function(require,module,exports){ +var _ = require("./lodash"); + +// Public utility functions +module.exports = { + isSubgraph: isSubgraph, + edgeToId: edgeToId, + applyStyle: applyStyle, + applyClass: applyClass, + applyTransition: applyTransition +}; + +/* + * Returns true if the specified node in the graph is a subgraph node. A + * subgraph node is one that contains other nodes. + */ +function isSubgraph(g, v) { + return !!g.children(v).length; +} + +function edgeToId(e) { + return escapeId(e.v) + ":" + escapeId(e.w) + ":" + escapeId(e.name); +} + +var ID_DELIM = /:/g; +function escapeId(str) { + return str ? String(str).replace(ID_DELIM, "\\:") : ""; +} + +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} + +function applyClass(dom, classFn, otherClasses) { + if (classFn) { + dom + .attr("class", classFn) + .attr("class", otherClasses + " " + dom.attr("class")); + } +} + +function applyTransition(selection, g) { + var graph = g.graph(); + + if (_.isPlainObject(graph)) { + var transition = graph.transition; + if (_.isFunction(transition)) { + return transition(selection); + } + } + + return selection; +} + +},{"./lodash":21}],28:[function(require,module,exports){ +module.exports = "0.4.17"; + +},{}],29:[function(require,module,exports){ +/* +Copyright (c) 2012-2014 Chris Pettitt + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +module.exports = { + graphlib: require("./lib/graphlib"), + + layout: require("./lib/layout"), + debug: require("./lib/debug"), + util: { + time: require("./lib/util").time, + notime: require("./lib/util").notime + }, + version: require("./lib/version") +}; + +},{"./lib/debug":34,"./lib/graphlib":35,"./lib/layout":37,"./lib/util":57,"./lib/version":58}],30:[function(require,module,exports){ +"use strict"; + +var _ = require("./lodash"), + greedyFAS = require("./greedy-fas"); + +module.exports = { + run: run, + undo: undo +}; + +function run(g) { + var fas = (g.graph().acyclicer === "greedy" + ? greedyFAS(g, weightFn(g)) + : dfsFAS(g)); + _.each(fas, function(e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, _.uniqueId("rev")); + }); + + function weightFn(g) { + return function(e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = [], + stack = {}, + visited = {}; + + function dfs(v) { + if (_.has(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + _.each(g.outEdges(v), function(e) { + if (_.has(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + _.each(g.nodes(), dfs); + return fas; +} + +function undo(g) { + _.each(g.edges(), function(e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +},{"./greedy-fas":36,"./lodash":38}],31:[function(require,module,exports){ +var _ = require("./lodash"), + util = require("./util"); + +module.exports = addBorderSegments; + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v), + node = g.node(v); + if (children.length) { + _.each(children, dfs); + } + + if (_.has(node, "minRank")) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; + rank < maxRank; + ++rank) { + addBorderNode(g, "borderLeft", "_bl", v, node, rank); + addBorderNode(g, "borderRight", "_br", v, node, rank); + } + } + } + + _.each(g.children(), dfs); +} + +function addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }, + prev = sgNode[prop][rank - 1], + curr = util.addDummyNode(g, "border", label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +},{"./lodash":38,"./util":57}],32:[function(require,module,exports){ +"use strict"; + +var _ = require("./lodash"); + +module.exports = { + adjust: adjust, + undo: undo +}; + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === "lr" || rankDir === "rl") { + swapWidthHeight(g); + } +} + +function undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === "bt" || rankDir === "rl") { + reverseY(g); + } + + if (rankDir === "lr" || rankDir === "rl") { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + _.each(g.nodes(), function(v) { swapWidthHeightOne(g.node(v)); }); + _.each(g.edges(), function(e) { swapWidthHeightOne(g.edge(e)); }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + _.each(g.nodes(), function(v) { reverseYOne(g.node(v)); }); + + _.each(g.edges(), function(e) { + var edge = g.edge(e); + _.each(edge.points, reverseYOne); + if (_.has(edge, "y")) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + _.each(g.nodes(), function(v) { swapXYOne(g.node(v)); }); + + _.each(g.edges(), function(e) { + var edge = g.edge(e); + _.each(edge.points, swapXYOne); + if (_.has(edge, "x")) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +},{"./lodash":38}],33:[function(require,module,exports){ +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + +module.exports = List; + +function List() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; +} + +List.prototype.dequeue = function() { + var sentinel = this._sentinel, + entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } +}; + +List.prototype.enqueue = function(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; +}; + +List.prototype.toString = function() { + var strs = [], + sentinel = this._sentinel, + curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return "[" + strs.join(", ") + "]"; +}; + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== "_next" && k !== "_prev") { + return v; + } +} + +},{}],34:[function(require,module,exports){ +var _ = require("./lodash"), + util = require("./util"), + Graph = require("./graphlib").Graph; + +module.exports = { + debugOrdering: debugOrdering +}; + +/* istanbul ignore next */ +function debugOrdering(g) { + var layerMatrix = util.buildLayerMatrix(g); + + var h = new Graph({ compound: true, multigraph: true }).setGraph({}); + + _.each(g.nodes(), function(v) { + h.setNode(v, { label: v }); + h.setParent(v, "layer" + g.node(v).rank); + }); + + _.each(g.edges(), function(e) { + h.setEdge(e.v, e.w, {}, e.name); + }); + + _.each(layerMatrix, function(layer, i) { + var layerV = "layer" + i; + h.setNode(layerV, { rank: "same" }); + _.reduce(layer, function(u, v) { + h.setEdge(u, v, { style: "invis" }); + return v; + }); + }); + + return h; +} + +},{"./graphlib":35,"./lodash":38,"./util":57}],35:[function(require,module,exports){ +arguments[4][9][0].apply(exports,arguments) +},{"dup":9,"graphlib":59}],36:[function(require,module,exports){ +var _ = require("./lodash"), + Graph = require("./graphlib").Graph, + List = require("./data/list"); + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ +module.exports = greedyFAS; + +var DEFAULT_WEIGHT_FN = _.constant(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return _.flatten(_.map(results, function(e) { + return g.outEdges(e.v, e.w); + }), true); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = [], + sources = buckets[buckets.length - 1], + sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { removeNode(g, buckets, zeroIdx, entry); } + while ((entry = sources.dequeue())) { removeNode(g, buckets, zeroIdx, entry); } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + _.each(g.inEdges(entry.v), function(edge) { + var weight = g.edge(edge), + uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + _.each(g.outEdges(entry.v), function(edge) { + var weight = g.edge(edge), + w = edge.w, + wEntry = g.node(w); + wEntry["in"] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new Graph(), + maxIn = 0, + maxOut = 0; + + _.each(g.nodes(), function(v) { + fasGraph.setNode(v, { v: v, "in": 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + _.each(g.edges(), function(e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0, + weight = weightFn(e), + edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, fasGraph.node(e.v).out += weight); + maxIn = Math.max(maxIn, fasGraph.node(e.w)["in"] += weight); + }); + + var buckets = _.range(maxOut + maxIn + 3).map(function() { return new List(); }); + var zeroIdx = maxIn + 1; + + _.each(fasGraph.nodes(), function(v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry["in"]) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry["in"] + zeroIdx].enqueue(entry); + } +} + +},{"./data/list":33,"./graphlib":35,"./lodash":38}],37:[function(require,module,exports){ +"use strict"; + +var _ = require("./lodash"), + acyclic = require("./acyclic"), + normalize = require("./normalize"), + rank = require("./rank"), + normalizeRanks = require("./util").normalizeRanks, + parentDummyChains = require("./parent-dummy-chains"), + removeEmptyRanks = require("./util").removeEmptyRanks, + nestingGraph = require("./nesting-graph"), + addBorderSegments = require("./add-border-segments"), + coordinateSystem = require("./coordinate-system"), + order = require("./order"), + position = require("./position"), + util = require("./util"), + Graph = require("./graphlib").Graph; + +module.exports = layout; + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util.time : util.notime; + time("layout", function() { + var layoutGraph = time(" buildLayoutGraph", + function() { return buildLayoutGraph(g); }); + time(" runLayout", function() { runLayout(layoutGraph, time); }); + time(" updateInputGraph", function() { updateInputGraph(g, layoutGraph); }); + }); +} + +function runLayout(g, time) { + time(" makeSpaceForEdgeLabels", function() { makeSpaceForEdgeLabels(g); }); + time(" removeSelfEdges", function() { removeSelfEdges(g); }); + time(" acyclic", function() { acyclic.run(g); }); + time(" nestingGraph.run", function() { nestingGraph.run(g); }); + time(" rank", function() { rank(util.asNonCompoundGraph(g)); }); + time(" injectEdgeLabelProxies", function() { injectEdgeLabelProxies(g); }); + time(" removeEmptyRanks", function() { removeEmptyRanks(g); }); + time(" nestingGraph.cleanup", function() { nestingGraph.cleanup(g); }); + time(" normalizeRanks", function() { normalizeRanks(g); }); + time(" assignRankMinMax", function() { assignRankMinMax(g); }); + time(" removeEdgeLabelProxies", function() { removeEdgeLabelProxies(g); }); + time(" normalize.run", function() { normalize.run(g); }); + time(" parentDummyChains", function() { parentDummyChains(g); }); + time(" addBorderSegments", function() { addBorderSegments(g); }); + time(" order", function() { order(g); }); + time(" insertSelfEdges", function() { insertSelfEdges(g); }); + time(" adjustCoordinateSystem", function() { coordinateSystem.adjust(g); }); + time(" position", function() { position(g); }); + time(" positionSelfEdges", function() { positionSelfEdges(g); }); + time(" removeBorderNodes", function() { removeBorderNodes(g); }); + time(" normalize.undo", function() { normalize.undo(g); }); + time(" fixupEdgeLabelCoords", function() { fixupEdgeLabelCoords(g); }); + time(" undoCoordinateSystem", function() { coordinateSystem.undo(g); }); + time(" translateGraph", function() { translateGraph(g); }); + time(" assignNodeIntersects", function() { assignNodeIntersects(g); }); + time(" reversePoints", function() { reversePointsForReversedEdges(g); }); + time(" acyclic.undo", function() { acyclic.undo(g); }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + _.each(inputGraph.nodes(), function(v) { + var inputLabel = inputGraph.node(v), + layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + _.each(inputGraph.edges(), function(e) { + var inputLabel = inputGraph.edge(e), + layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (_.has(layoutLabel, "x")) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ["nodesep", "edgesep", "ranksep", "marginx", "marginy"], + graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: "tb" }, + graphAttrs = ["acyclicer", "ranker", "rankdir", "align"], + nodeNumAttrs = ["width", "height"], + nodeDefaults = { width: 0, height: 0 }, + edgeNumAttrs = ["minlen", "weight", "width", "height", "labeloffset"], + edgeDefaults = { + minlen: 1, weight: 1, width: 0, height: 0, + labeloffset: 10, labelpos: "r" + }, + edgeAttrs = ["labelpos"]; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new Graph({ multigraph: true, compound: true }), + graph = canonicalize(inputGraph.graph()); + + g.setGraph(_.merge({}, + graphDefaults, + selectNumberAttrs(graph, graphNumAttrs), + _.pick(graph, graphAttrs))); + + _.each(inputGraph.nodes(), function(v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, _.defaults(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + _.each(inputGraph.edges(), function(e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge(e, _.merge({}, + edgeDefaults, + selectNumberAttrs(edge, edgeNumAttrs), + _.pick(edge, edgeAttrs))); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + _.each(g.edges(), function(e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== "c") { + if (graph.rankdir === "TB" || graph.rankdir === "BT") { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + _.each(g.edges(), function(e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v), + w = g.node(e.w), + label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + util.addDummyNode(g, "edge-proxy", label, "_ep"); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + _.each(g.nodes(), function(v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + maxRank = _.max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + _.each(g.nodes(), function(v) { + var node = g.node(v); + if (node.dummy === "edge-proxy") { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY, + maxX = 0, + minY = Number.POSITIVE_INFINITY, + maxY = 0, + graphLabel = g.graph(), + marginX = graphLabel.marginx || 0, + marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x, + y = attrs.y, + w = attrs.width, + h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + _.each(g.nodes(), function(v) { getExtremes(g.node(v)); }); + _.each(g.edges(), function(e) { + var edge = g.edge(e); + if (_.has(edge, "x")) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + _.each(g.nodes(), function(v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + _.each(g.edges(), function(e) { + var edge = g.edge(e); + _.each(edge.points, function(p) { + p.x -= minX; + p.y -= minY; + }); + if (_.has(edge, "x")) { edge.x -= minX; } + if (_.has(edge, "y")) { edge.y -= minY; } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + _.each(g.edges(), function(e) { + var edge = g.edge(e), + nodeV = g.node(e.v), + nodeW = g.node(e.w), + p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(util.intersectRect(nodeV, p1)); + edge.points.push(util.intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + _.each(g.edges(), function(e) { + var edge = g.edge(e); + if (_.has(edge, "x")) { + if (edge.labelpos === "l" || edge.labelpos === "r") { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case "l": edge.x -= edge.width / 2 + edge.labeloffset; break; + case "r": edge.x += edge.width / 2 + edge.labeloffset; break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + _.each(g.edges(), function(e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + _.each(g.nodes(), function(v) { + if (g.children(v).length) { + var node = g.node(v), + t = g.node(node.borderTop), + b = g.node(node.borderBottom), + l = g.node(_.last(node.borderLeft)), + r = g.node(_.last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + _.each(g.nodes(), function(v) { + if (g.node(v).dummy === "border") { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + _.each(g.edges(), function(e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = util.buildLayerMatrix(g); + _.each(layers, function(layer) { + var orderShift = 0; + _.each(layer, function(v, i) { + var node = g.node(v); + node.order = i + orderShift; + _.each(node.selfEdges, function(selfEdge) { + util.addDummyNode(g, "selfedge", { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + (++orderShift), + e: selfEdge.e, + label: selfEdge.label + }, "_se"); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + _.each(g.nodes(), function(v) { + var node = g.node(v); + if (node.dummy === "selfedge") { + var selfNode = g.node(node.e.v), + x = selfNode.x + selfNode.width / 2, + y = selfNode.y, + dx = node.x - x, + dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + 2 * dx / 3, y: y - dy }, + { x: x + 5 * dx / 6, y: y - dy }, + { x: x + dx , y: y }, + { x: x + 5 * dx / 6, y: y + dy }, + { x: x + 2 * dx / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return _.mapValues(_.pick(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + _.each(attrs, function(v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +},{"./acyclic":30,"./add-border-segments":31,"./coordinate-system":32,"./graphlib":35,"./lodash":38,"./nesting-graph":39,"./normalize":40,"./order":45,"./parent-dummy-chains":50,"./position":52,"./rank":54,"./util":57}],38:[function(require,module,exports){ +arguments[4][21][0].apply(exports,arguments) +},{"dup":21,"lodash":79}],39:[function(require,module,exports){ +var _ = require("./lodash"), + util = require("./util"); + +module.exports = { + run: run, + cleanup: cleanup +}; + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function run(g) { + var root = util.addDummyNode(g, "root", {}, "_root"), + depths = treeDepths(g), + height = _.max(depths) - 1, + nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + _.each(g.edges(), function(e) { g.edge(e).minlen *= nodeSep; }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + _.each(g.children(), function(child) { + dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = util.addBorderNode(g, "_bt"), + bottom = util.addBorderNode(g, "_bb"), + label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + _.each(children, function(child) { + dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child), + childTop = childNode.borderTop ? childNode.borderTop : child, + childBottom = childNode.borderBottom ? childNode.borderBottom : child, + thisWeight = childNode.borderTop ? weight : 2 * weight, + minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + _.each(children, function(child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + _.each(g.children(), function(v) { dfs(v, 1); }); + return depths; +} + +function sumWeights(g) { + return _.reduce(g.edges(), function(acc, e) { + return acc + g.edge(e).weight; + }, 0); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + _.each(g.edges(), function(e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +},{"./lodash":38,"./util":57}],40:[function(require,module,exports){ +"use strict"; + +var _ = require("./lodash"), + util = require("./util"); + +module.exports = { + run: run, + undo: undo +}; + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function run(g) { + g.graph().dummyChains = []; + _.each(g.edges(), function(edge) { normalizeEdge(g, edge); }); +} + +function normalizeEdge(g, e) { + var v = e.v, + vRank = g.node(v).rank, + w = e.w, + wRank = g.node(w).rank, + name = e.name, + edgeLabel = g.edge(e), + labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, height: 0, + edgeLabel: edgeLabel, edgeObj: e, + rank: vRank + }; + dummy = util.addDummyNode(g, "edge", attrs, "_d"); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + attrs.dummy = "edge-label"; + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function undo(g) { + _.each(g.graph().dummyChains, function(v) { + var node = g.node(v), + origLabel = node.edgeLabel, + w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === "edge-label") { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +},{"./lodash":38,"./util":57}],41:[function(require,module,exports){ +var _ = require("../lodash"); + +module.exports = addSubgraphConstraints; + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + _.each(vs, function(v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +},{"../lodash":38}],42:[function(require,module,exports){ +var _ = require("../lodash"); + +module.exports = barycenter; + +function barycenter(g, movable) { + return _.map(movable, function(v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = _.reduce(inV, function(acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + (edge.weight * nodeU.order), + weight: acc.weight + edge.weight + }; + }, { sum: 0, weight: 0 }); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight + }; + } + }); +} + + +},{"../lodash":38}],43:[function(require,module,exports){ +var _ = require("../lodash"), + Graph = require("../graphlib").Graph; + +module.exports = buildLayerGraph; + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new Graph({ compound: true }).setGraph({ root: root }) + .setDefaultNodeLabel(function(v) { return g.node(v); }); + + _.each(g.nodes(), function(v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || node.minRank <= rank && rank <= node.maxRank) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + _.each(g[relationship](v), function(e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !_.isUndefined(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (_.has(node, "minRank")) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank] + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = _.uniqueId("_root")))); + return v; +} + +},{"../graphlib":35,"../lodash":38}],44:[function(require,module,exports){ +"use strict"; + +var _ = require("../lodash"); + +module.exports = crossCount; + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i-1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = _.zipObject(southLayer, + _.map(southLayer, function (v, i) { return i; })); + var southEntries = _.flatten(_.map(northLayer, function(v) { + return _.chain(g.outEdges(v)) + .map(function(e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }) + .sortBy("pos") + .value(); + }), true); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = _.map(new Array(treeSize), function() { return 0; }); + + // Calculate the weighted crossings + var cc = 0; + _.each(southEntries.forEach(function(entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + while (index > 0) { + if (index % 2) { + weightSum += tree[index + 1]; + } + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + })); + + return cc; +} + +},{"../lodash":38}],45:[function(require,module,exports){ +"use strict"; + +var _ = require("../lodash"), + initOrder = require("./init-order"), + crossCount = require("./cross-count"), + sortSubgraph = require("./sort-subgraph"), + buildLayerGraph = require("./build-layer-graph"), + addSubgraphConstraints = require("./add-subgraph-constraints"), + Graph = require("../graphlib").Graph, + util = require("../util"); + +module.exports = order; + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util.maxRank(g), + downLayerGraphs = buildLayerGraphs(g, _.range(1, maxRank + 1), "inEdges"), + upLayerGraphs = buildLayerGraphs(g, _.range(maxRank - 1, -1, -1), "outEdges"); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = util.buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = _.cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return _.map(ranks, function(rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new Graph(); + _.each(layerGraphs, function(lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + _.each(sorted.vs, function(v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + _.each(layering, function(layer) { + _.each(layer, function(v, i) { + g.node(v).order = i; + }); + }); +} + +},{"../graphlib":35,"../lodash":38,"../util":57,"./add-subgraph-constraints":41,"./build-layer-graph":43,"./cross-count":44,"./init-order":46,"./sort-subgraph":48}],46:[function(require,module,exports){ +"use strict"; + +var _ = require("../lodash"); + +module.exports = initOrder; + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}, + simpleNodes = _.filter(g.nodes(), function(v) { + return !g.children(v).length; + }), + maxRank = _.max(_.map(simpleNodes, function(v) { return g.node(v).rank; })), + layers = _.map(_.range(maxRank + 1), function() { return []; }); + + function dfs(v) { + if (_.has(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + _.each(g.successors(v), dfs); + } + + var orderedVs = _.sortBy(simpleNodes, function(v) { return g.node(v).rank; }); + _.each(orderedVs, dfs); + + return layers; +} + +},{"../lodash":38}],47:[function(require,module,exports){ +"use strict"; + +var _ = require("../lodash"); + +module.exports = resolveConflicts; + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + _.each(entries, function(entry, i) { + var tmp = mappedEntries[entry.v] = { + indegree: 0, + "in": [], + out: [], + vs: [entry.v], + i: i + }; + if (!_.isUndefined(entry.barycenter)) { + tmp.barycenter = entry.barycenter; + tmp.weight = entry.weight; + } + }); + + _.each(cg.edges(), function(e) { + var entryV = mappedEntries[e.v], + entryW = mappedEntries[e.w]; + if (!_.isUndefined(entryV) && !_.isUndefined(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = _.filter(mappedEntries, function(entry) { + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function(uEntry) { + if (uEntry.merged) { + return; + } + if (_.isUndefined(uEntry.barycenter) || + _.isUndefined(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function(wEntry) { + wEntry["in"].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + _.each(entry["in"].reverse(), handleIn(entry)); + _.each(entry.out, handleOut(entry)); + } + + return _.chain(entries) + .filter(function(entry) { return !entry.merged; }) + .map(function(entry) { + return _.pick(entry, ["vs", "i", "barycenter", "weight"]); + }) + .value(); +} + +function mergeEntries(target, source) { + var sum = 0, + weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +},{"../lodash":38}],48:[function(require,module,exports){ +var _ = require("../lodash"), + barycenter = require("./barycenter"), + resolveConflicts = require("./resolve-conflicts"), + sort = require("./sort"); + +module.exports = sortSubgraph; + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v), + node = g.node(v), + bl = node ? node.borderLeft : undefined, + br = node ? node.borderRight: undefined, + subgraphs = {}; + + if (bl) { + movable = _.filter(movable, function(w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + _.each(barycenters, function(entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (_.has(subgraphResult, "barycenter")) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = _.flatten([bl, result.vs, br], true); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!_.has(result, "barycenter")) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = (result.barycenter * result.weight + + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + _.each(entries, function(entry) { + entry.vs = _.flatten(entry.vs.map(function(v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }), true); + }); +} + +function mergeBarycenters(target, other) { + if (!_.isUndefined(target.barycenter)) { + target.barycenter = (target.barycenter * target.weight + + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +},{"../lodash":38,"./barycenter":42,"./resolve-conflicts":47,"./sort":49}],49:[function(require,module,exports){ +var _ = require("../lodash"), + util = require("../util"); + +module.exports = sort; + +function sort(entries, biasRight) { + var parts = util.partition(entries, function(entry) { + return _.has(entry, "barycenter"); + }); + var sortable = parts.lhs, + unsortable = _.sortBy(parts.rhs, function(entry) { return -entry.i; }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + _.each(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: _.flatten(vs, true) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = _.last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function(entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +},{"../lodash":38,"../util":57}],50:[function(require,module,exports){ +var _ = require("./lodash"); + +module.exports = parentDummyChains; + +function parentDummyChains(g) { + var postorderNums = postorder(g); + + _.each(g.graph().dummyChains, function(v) { + var node = g.node(v), + edgeObj = node.edgeObj, + pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w), + path = pathData.path, + lca = pathData.lca, + pathIdx = 0, + pathV = path[pathIdx], + ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && + g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while (pathIdx < path.length - 1 && + g.node(pathV = path[pathIdx + 1]).minRank <= node.rank) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = [], + wPath = [], + low = Math.min(postorderNums[v].low, postorderNums[w].low), + lim = Math.max(postorderNums[v].lim, postorderNums[w].lim), + parent, + lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && + (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function postorder(g) { + var result = {}, + lim = 0; + + function dfs(v) { + var low = lim; + _.each(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + _.each(g.children(), dfs); + + return result; +} + +},{"./lodash":38}],51:[function(require,module,exports){ +"use strict"; + +var _ = require("../lodash"), + Graph = require("../graphlib").Graph, + util = require("../util"); + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + +module.exports = { + positionX: positionX, + findType1Conflicts: findType1Conflicts, + findType2Conflicts: findType2Conflicts, + addConflict: addConflict, + hasConflict: hasConflict, + verticalAlignment: verticalAlignment, + horizontalCompaction: horizontalCompaction, + alignCoordinates: alignCoordinates, + findSmallestWidthAlignment: findSmallestWidthAlignment, + balance: balance +}; + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var + // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = _.last(layer); + + _.each(layer, function(v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + _.each(layer.slice(scanPos, i +1), function(scanNode) { + _.each(g.predecessors(scanNode), function(u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && + !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + _.reduce(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + _.each(_.range(southPos, southEnd), function(i) { + v = south[i]; + if (g.node(v).dummy) { + _.each(g.predecessors(v), function(u) { + var uNode = g.node(u); + if (uNode.dummy && + (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + _.each(south, function(v, southLookahead) { + if (g.node(v).dummy === "border") { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + _.reduce(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return _.find(g.predecessors(v), function(u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return _.has(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + _.each(layering, function(layer) { + _.each(layer, function(v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + _.each(layering, function(layer) { + var prevIdx = -1; + _.each(layer, function(v) { + var ws = neighborFn(v); + if (ws.length) { + ws = _.sortBy(ws, function(w) { return pos[w]; }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && + prevIdx < pos[w] && + !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep); + + // First pass, assign smallest coordinates via DFS + var visited = {}; + function pass1(v) { + if (!_.has(visited, v)) { + visited[v] = true; + xs[v] = _.reduce(blockG.inEdges(v), function(max, e) { + pass1(e.v); + return Math.max(max, xs[e.v] + blockG.edge(e)); + }, 0); + } + } + _.each(blockG.nodes(), pass1); + + var borderType = reverseSep ? "borderLeft" : "borderRight"; + function pass2(v) { + if (visited[v] !== 2) { + visited[v]++; + var node = g.node(v); + var min = _.reduce(blockG.outEdges(v), function(min, e) { + pass2(e.w); + return Math.min(min, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[v] = Math.max(xs[v], min); + } + } + } + _.each(blockG.nodes(), pass2); + + // Assign x coordinates to all nodes + _.each(align, function(v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new Graph(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + _.each(layering, function(layer) { + var u; + _.each(layer, function(v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return _.min(xss, function(xs) { + var min = _.min(xs, function(x, v) { return x - width(g, v) / 2; }), + max = _.max(xs, function(x, v) { return x + width(g, v) / 2; }); + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToMin = _.min(alignTo), + alignToMax = _.max(alignTo); + + _.each(["u", "d"], function(vert) { + _.each(["l", "r"], function(horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + delta = horiz === "l" ? alignToMin - _.min(xs) : alignToMax - _.max(xs); + + if (delta) { + xss[alignment] = _.mapValues(xs, function(x) { return x + delta; }); + } + }); + }); +} + +function balance(xss, align) { + return _.mapValues(xss.ul, function(ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = _.sortBy(_.pluck(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = util.buildLayerMatrix(g), + conflicts = _.merge(findType1Conflicts(g, layering), + findType2Conflicts(g, layering)); + + var xss = {}, + adjustedLayering; + _.each(["u", "d"], function(vert) { + adjustedLayering = vert === "u" ? layering : _.values(layering).reverse(); + _.each(["l", "r"], function(horiz) { + if (horiz === "r") { + adjustedLayering = _.map(adjustedLayering, function(inner) { + return _.values(inner).reverse(); + }); + } + + var neighborFn = _.bind(vert === "u" ? g.predecessors : g.successors, g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, + align.root, align.align, + horiz === "r"); + if (horiz === "r") { + xs = _.mapValues(xs, function(x) { return -x; }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function(g, v, w) { + var vLabel = g.node(v), + wLabel = g.node(w), + sum = 0, + delta; + + sum += vLabel.width / 2; + if (_.has(vLabel, "labelpos")) { + switch (vLabel.labelpos.toLowerCase()) { + case "l": delta = -vLabel.width / 2; break; + case "r": delta = vLabel.width / 2; break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (_.has(wLabel, "labelpos")) { + switch (wLabel.labelpos.toLowerCase()) { + case "l": delta = wLabel.width / 2; break; + case "r": delta = -wLabel.width / 2; break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +},{"../graphlib":35,"../lodash":38,"../util":57}],52:[function(require,module,exports){ +"use strict"; + +var _ = require("../lodash"), + util = require("../util"), + positionX = require("./bk").positionX; + +module.exports = position; + +function position(g) { + g = util.asNonCompoundGraph(g); + + positionY(g); + _.each(positionX(g), function(x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = util.buildLayerMatrix(g), + rankSep = g.graph().ranksep, + prevY = 0; + _.each(layering, function(layer) { + var maxHeight = _.max(_.map(layer, function(v) { return g.node(v).height; })); + _.each(layer, function(v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + + +},{"../lodash":38,"../util":57,"./bk":51}],53:[function(require,module,exports){ +"use strict"; + +var _ = require("../lodash"), + Graph = require("../graphlib").Graph, + slack = require("./util").slack; + +module.exports = feasibleTree; + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new Graph({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0], + size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + _.each(g.nodeEdges(v), function(e) { + var edgeV = e.v, + w = (v === edgeV) ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + _.each(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return _.min(g.edges(), function(e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + _.each(t.nodes(), function(v) { + g.node(v).rank += delta; + }); +} + +},{"../graphlib":35,"../lodash":38,"./util":56}],54:[function(require,module,exports){ +"use strict"; + +var rankUtil = require("./util"), + longestPath = rankUtil.longestPath, + feasibleTree = require("./feasible-tree"), + networkSimplex = require("./network-simplex"); + +module.exports = rank; + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch(g.graph().ranker) { + case "network-simplex": networkSimplexRanker(g); break; + case "tight-tree": tightTreeRanker(g); break; + case "longest-path": longestPathRanker(g); break; + default: networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +},{"./feasible-tree":53,"./network-simplex":55,"./util":56}],55:[function(require,module,exports){ +"use strict"; + +var _ = require("../lodash"), + feasibleTree = require("./feasible-tree"), + slack = require("./util").slack, + initRank = require("./util").longestPath, + preorder = require("../graphlib").alg.preorder, + postorder = require("../graphlib").alg.postorder, + simplify = require("../util").simplify; + +module.exports = networkSimplex; + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + initRank(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + _.each(vs, function(v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child), + parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child), + parent = childLab.parent, + // True if the child is on the tail end of the edge in the directed graph + childIsTail = true, + // The graph's view of the tree edge we're inspecting + graphEdge = g.edge(child, parent), + // The accumulated cut value for the edge between this node and its parent + cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + _.each(g.nodeEdges(child), function(e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim, + label = tree.node(v); + + visited[v] = true; + _.each(tree.neighbors(v), function(w) { + if (!_.has(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return _.find(tree.edges(), function(e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v, + w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v), + wLabel = t.node(w), + tailLabel = vLabel, + flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = _.filter(g.edges(), function(edge) { + return flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel); + }); + + return _.min(candidates, function(edge) { return slack(g, edge); }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v, + w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = _.find(t.nodes(), function(v) { return !g.node(v).parent; }), + vs = preorder(t, root); + vs = vs.slice(1); + _.each(vs, function(v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +},{"../graphlib":35,"../lodash":38,"../util":57,"./feasible-tree":53,"./util":56}],56:[function(require,module,exports){ +"use strict"; + +var _ = require("../lodash"); + +module.exports = { + longestPath: longestPath, + slack: slack +}; + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (_.has(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = _.min(_.map(g.outEdges(v), function(e) { + return dfs(e.w) - g.edge(e).minlen; + })); + + if (rank === Number.POSITIVE_INFINITY) { + rank = 0; + } + + return (label.rank = rank); + } + + _.each(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +},{"../lodash":38}],57:[function(require,module,exports){ +"use strict"; + +var _ = require("./lodash"), + Graph = require("./graphlib").Graph; + +module.exports = { + addDummyNode: addDummyNode, + simplify: simplify, + asNonCompoundGraph: asNonCompoundGraph, + successorWeights: successorWeights, + predecessorWeights: predecessorWeights, + intersectRect: intersectRect, + buildLayerMatrix: buildLayerMatrix, + normalizeRanks: normalizeRanks, + removeEmptyRanks: removeEmptyRanks, + addBorderNode: addBorderNode, + maxRank: maxRank, + partition: partition, + time: time, + notime: notime +}; + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = _.uniqueId(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new Graph().setGraph(g.graph()); + _.each(g.nodes(), function(v) { simplified.setNode(v, g.node(v)); }); + _.each(g.edges(), function(e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }, + label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen) + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new Graph({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + _.each(g.nodes(), function(v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + _.each(g.edges(), function(e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function(v) { + var sucs = {}; + _.each(g.outEdges(v), function(e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function(v) { + var preds = {}; + _.each(g.inEdges(v), function(e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error("Not possible to find intersection inside of the rectangle"); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = h * dx / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = w * dy / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = _.map(_.range(maxRank(g) + 1), function() { return []; }); + _.each(g.nodes(), function(v) { + var node = g.node(v), + rank = node.rank; + if (!_.isUndefined(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = _.min(_.map(g.nodes(), function(v) { return g.node(v).rank; })); + _.each(g.nodes(), function(v) { + var node = g.node(v); + if (_.has(node, "rank")) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = _.min(_.map(g.nodes(), function(v) { return g.node(v).rank; })); + + var layers = []; + _.each(g.nodes(), function(v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0, + nodeRankFactor = g.graph().nodeRankFactor; + _.each(layers, function(vs, i) { + if (_.isUndefined(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + _.each(vs, function(v) { g.node(v).rank += delta; }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0 + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, "border", node, prefix); +} + +function maxRank(g) { + return _.max(_.map(g.nodes(), function(v) { + var rank = g.node(v).rank; + if (!_.isUndefined(rank)) { + return rank; + } + })); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + _.each(collection, function(value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function time(name, fn) { + var start = _.now(); + try { + return fn(); + } finally { + console.log(name + " time: " + (_.now() - start) + "ms"); + } +} + +function notime(name, fn) { + return fn(); +} + +},{"./graphlib":35,"./lodash":38}],58:[function(require,module,exports){ +module.exports = "0.7.3"; + +},{}],59:[function(require,module,exports){ +/** + * Copyright (c) 2014, Chris Pettitt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +var lib = require("./lib"); + +module.exports = { + Graph: lib.Graph, + json: require("./lib/json"), + alg: require("./lib/alg"), + version: lib.version +}; + +},{"./lib":75,"./lib/alg":66,"./lib/json":76}],60:[function(require,module,exports){ +var _ = require("../lodash"); + +module.exports = components; + +function components(g) { + var visited = {}, + cmpts = [], + cmpt; + + function dfs(v) { + if (_.has(visited, v)) return; + visited[v] = true; + cmpt.push(v); + _.each(g.successors(v), dfs); + _.each(g.predecessors(v), dfs); + } + + _.each(g.nodes(), function(v) { + cmpt = []; + dfs(v); + if (cmpt.length) { + cmpts.push(cmpt); + } + }); + + return cmpts; +} + +},{"../lodash":77}],61:[function(require,module,exports){ +var _ = require("../lodash"); + +module.exports = dfs; + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. This algorithm treats + * the input as undirected. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!_.isArray(vs)) { + vs = [vs]; + } + + var acc = [], + visited = {}; + _.each(vs, function(v) { + if (!g.hasNode(v)) { + throw new Error("Graph does not have node: " + v); + } + + doDfs(g, v, order === "post", visited, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, acc) { + if (!_.has(visited, v)) { + visited[v] = true; + + if (!postorder) { acc.push(v); } + _.each(g.neighbors(v), function(w) { + doDfs(g, w, postorder, visited, acc); + }); + if (postorder) { acc.push(v); } + } +} + +},{"../lodash":77}],62:[function(require,module,exports){ +var dijkstra = require("./dijkstra"), + _ = require("../lodash"); + +module.exports = dijkstraAll; + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform(g.nodes(), function(acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, {}); +} + +},{"../lodash":77,"./dijkstra":63}],63:[function(require,module,exports){ +var _ = require("../lodash"), + PriorityQueue = require("../data/priority-queue"); + +module.exports = dijkstra; + +var DEFAULT_WEIGHT_FUNC = _.constant(1); + +function dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra(g, String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || function(v) { return g.outEdges(v); }); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}, + pq = new PriorityQueue(), + v, vEntry; + + var updateNeighbors = function(edge) { + var w = edge.v !== v ? edge.v : edge.w, + wEntry = results[w], + weight = weightFn(edge), + distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error("dijkstra does not allow negative edge weights. " + + "Bad edge: " + edge + " Weight: " + weight); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function(v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +},{"../data/priority-queue":73,"../lodash":77}],64:[function(require,module,exports){ +var _ = require("../lodash"), + tarjan = require("./tarjan"); + +module.exports = findCycles; + +function findCycles(g) { + return _.filter(tarjan(g), function(cmpt) { + return cmpt.length > 1 || (cmpt.length === 1 && g.hasEdge(cmpt[0], cmpt[0])); + }); +} + +},{"../lodash":77,"./tarjan":71}],65:[function(require,module,exports){ +var _ = require("../lodash"); + +module.exports = floydWarshall; + +var DEFAULT_WEIGHT_FUNC = _.constant(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall(g, + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || function(v) { return g.outEdges(v); }); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}, + nodes = g.nodes(); + + nodes.forEach(function(v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function(w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function(edge) { + var w = edge.v === v ? edge.w : edge.v, + d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function(k) { + var rowK = results[k]; + nodes.forEach(function(i) { + var rowI = results[i]; + nodes.forEach(function(j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +},{"../lodash":77}],66:[function(require,module,exports){ +module.exports = { + components: require("./components"), + dijkstra: require("./dijkstra"), + dijkstraAll: require("./dijkstra-all"), + findCycles: require("./find-cycles"), + floydWarshall: require("./floyd-warshall"), + isAcyclic: require("./is-acyclic"), + postorder: require("./postorder"), + preorder: require("./preorder"), + prim: require("./prim"), + tarjan: require("./tarjan"), + topsort: require("./topsort") +}; + +},{"./components":60,"./dijkstra":63,"./dijkstra-all":62,"./find-cycles":64,"./floyd-warshall":65,"./is-acyclic":67,"./postorder":68,"./preorder":69,"./prim":70,"./tarjan":71,"./topsort":72}],67:[function(require,module,exports){ +var topsort = require("./topsort"); + +module.exports = isAcyclic; + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof topsort.CycleException) { + return false; + } + throw e; + } + return true; +} + +},{"./topsort":72}],68:[function(require,module,exports){ +var dfs = require("./dfs"); + +module.exports = postorder; + +function postorder(g, vs) { + return dfs(g, vs, "post"); +} + +},{"./dfs":61}],69:[function(require,module,exports){ +var dfs = require("./dfs"); + +module.exports = preorder; + +function preorder(g, vs) { + return dfs(g, vs, "pre"); +} + +},{"./dfs":61}],70:[function(require,module,exports){ +var _ = require("../lodash"), + Graph = require("../graph"), + PriorityQueue = require("../data/priority-queue"); + +module.exports = prim; + +function prim(g, weightFunc) { + var result = new Graph(), + parents = {}, + pq = new PriorityQueue(), + v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v, + pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function(v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error("Input graph is not connected: " + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +},{"../data/priority-queue":73,"../graph":74,"../lodash":77}],71:[function(require,module,exports){ +var _ = require("../lodash"); + +module.exports = tarjan; + +function tarjan(g) { + var index = 0, + stack = [], + visited = {}, // node id -> { onStack, lowlink, index } + results = []; + + function dfs(v) { + var entry = visited[v] = { + onStack: true, + lowlink: index, + index: index++ + }; + stack.push(v); + + g.successors(v).forEach(function(w) { + if (!_.has(visited, w)) { + dfs(w); + entry.lowlink = Math.min(entry.lowlink, visited[w].lowlink); + } else if (visited[w].onStack) { + entry.lowlink = Math.min(entry.lowlink, visited[w].index); + } + }); + + if (entry.lowlink === entry.index) { + var cmpt = [], + w; + do { + w = stack.pop(); + visited[w].onStack = false; + cmpt.push(w); + } while (v !== w); + results.push(cmpt); + } + } + + g.nodes().forEach(function(v) { + if (!_.has(visited, v)) { + dfs(v); + } + }); + + return results; +} + +},{"../lodash":77}],72:[function(require,module,exports){ +var _ = require("../lodash"); + +module.exports = topsort; +topsort.CycleException = CycleException; + +function topsort(g) { + var visited = {}, + stack = {}, + results = []; + + function visit(node) { + if (_.has(stack, node)) { + throw new CycleException(); + } + + if (!_.has(visited, node)) { + stack[node] = true; + visited[node] = true; + _.each(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + _.each(g.sinks(), visit); + + if (_.size(visited) !== g.nodeCount()) { + throw new CycleException(); + } + + return results; +} + +function CycleException() {} + +},{"../lodash":77}],73:[function(require,module,exports){ +var _ = require("../lodash"); + +module.exports = PriorityQueue; + +/** + * A min-priority queue data structure. This algorithm is derived from Cormen, + * et al., "Introduction to Algorithms". The basic idea of a min-priority + * queue is that you can efficiently (in O(1) time) get the smallest key in + * the queue. Adding and removing elements takes O(log n) time. A key can + * have its priority decreased in O(log n) time. + */ +function PriorityQueue() { + this._arr = []; + this._keyIndices = {}; +} + +/** + * Returns the number of elements in the queue. Takes `O(1)` time. + */ +PriorityQueue.prototype.size = function() { + return this._arr.length; +}; + +/** + * Returns the keys that are in the queue. Takes `O(n)` time. + */ +PriorityQueue.prototype.keys = function() { + return this._arr.map(function(x) { return x.key; }); +}; + +/** + * Returns `true` if **key** is in the queue and `false` if not. + */ +PriorityQueue.prototype.has = function(key) { + return _.has(this._keyIndices, key); +}; + +/** + * Returns the priority for **key**. If **key** is not present in the queue + * then this function returns `undefined`. Takes `O(1)` time. + * + * @param {Object} key + */ +PriorityQueue.prototype.priority = function(key) { + var index = this._keyIndices[key]; + if (index !== undefined) { + return this._arr[index].priority; + } +}; + +/** + * Returns the key for the minimum element in this queue. If the queue is + * empty this function throws an Error. Takes `O(1)` time. + */ +PriorityQueue.prototype.min = function() { + if (this.size() === 0) { + throw new Error("Queue underflow"); + } + return this._arr[0].key; +}; + +/** + * Inserts a new key into the priority queue. If the key already exists in + * the queue this function returns `false`; otherwise it will return `true`. + * Takes `O(n)` time. + * + * @param {Object} key the key to add + * @param {Number} priority the initial priority for the key + */ +PriorityQueue.prototype.add = function(key, priority) { + var keyIndices = this._keyIndices; + key = String(key); + if (!_.has(keyIndices, key)) { + var arr = this._arr; + var index = arr.length; + keyIndices[key] = index; + arr.push({key: key, priority: priority}); + this._decrease(index); + return true; + } + return false; +}; + +/** + * Removes and returns the smallest key in the queue. Takes `O(log n)` time. + */ +PriorityQueue.prototype.removeMin = function() { + this._swap(0, this._arr.length - 1); + var min = this._arr.pop(); + delete this._keyIndices[min.key]; + this._heapify(0); + return min.key; +}; + +/** + * Decreases the priority for **key** to **priority**. If the new priority is + * greater than the previous priority, this function will throw an Error. + * + * @param {Object} key the key for which to raise priority + * @param {Number} priority the new priority for the key + */ +PriorityQueue.prototype.decrease = function(key, priority) { + var index = this._keyIndices[key]; + if (priority > this._arr[index].priority) { + throw new Error("New priority is greater than current priority. " + + "Key: " + key + " Old: " + this._arr[index].priority + " New: " + priority); + } + this._arr[index].priority = priority; + this._decrease(index); +}; + +PriorityQueue.prototype._heapify = function(i) { + var arr = this._arr; + var l = 2 * i, + r = l + 1, + largest = i; + if (l < arr.length) { + largest = arr[l].priority < arr[largest].priority ? l : largest; + if (r < arr.length) { + largest = arr[r].priority < arr[largest].priority ? r : largest; + } + if (largest !== i) { + this._swap(i, largest); + this._heapify(largest); + } + } +}; + +PriorityQueue.prototype._decrease = function(index) { + var arr = this._arr; + var priority = arr[index].priority; + var parent; + while (index !== 0) { + parent = index >> 1; + if (arr[parent].priority < priority) { + break; + } + this._swap(index, parent); + index = parent; + } +}; + +PriorityQueue.prototype._swap = function(i, j) { + var arr = this._arr; + var keyIndices = this._keyIndices; + var origArrI = arr[i]; + var origArrJ = arr[j]; + arr[i] = origArrJ; + arr[j] = origArrI; + keyIndices[origArrJ.key] = i; + keyIndices[origArrI.key] = j; +}; + +},{"../lodash":77}],74:[function(require,module,exports){ +"use strict"; + +var _ = require("./lodash"); + +module.exports = Graph; + +var DEFAULT_EDGE_NAME = "\x00", + GRAPH_NODE = "\x00", + EDGE_KEY_DELIM = "\x01"; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +function Graph(opts) { + this._isDirected = _.has(opts, "directed") ? opts.directed : true; + this._isMultigraph = _.has(opts, "multigraph") ? opts.multigraph : false; + this._isCompound = _.has(opts, "compound") ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = _.constant(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = _.constant(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + + +/* === Graph functions ========= */ + +Graph.prototype.isDirected = function() { + return this._isDirected; +}; + +Graph.prototype.isMultigraph = function() { + return this._isMultigraph; +}; + +Graph.prototype.isCompound = function() { + return this._isCompound; +}; + +Graph.prototype.setGraph = function(label) { + this._label = label; + return this; +}; + +Graph.prototype.graph = function() { + return this._label; +}; + + +/* === Node functions ========== */ + +Graph.prototype.setDefaultNodeLabel = function(newDefault) { + if (!_.isFunction(newDefault)) { + newDefault = _.constant(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; +}; + +Graph.prototype.nodeCount = function() { + return this._nodeCount; +}; + +Graph.prototype.nodes = function() { + return _.keys(this._nodes); +}; + +Graph.prototype.sources = function() { + return _.filter(this.nodes(), function(v) { + return _.isEmpty(this._in[v]); + }, this); +}; + +Graph.prototype.sinks = function() { + return _.filter(this.nodes(), function(v) { + return _.isEmpty(this._out[v]); + }, this); +}; + +Graph.prototype.setNodes = function(vs, value) { + var args = arguments; + _.each(vs, function(v) { + if (args.length > 1) { + this.setNode(v, value); + } else { + this.setNode(v); + } + }, this); + return this; +}; + +Graph.prototype.setNode = function(v, value) { + if (_.has(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; +}; + +Graph.prototype.node = function(v) { + return this._nodes[v]; +}; + +Graph.prototype.hasNode = function(v) { + return _.has(this._nodes, v); +}; + +Graph.prototype.removeNode = function(v) { + var self = this; + if (_.has(this._nodes, v)) { + var removeEdge = function(e) { self.removeEdge(self._edgeObjs[e]); }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + _.each(this.children(v), function(child) { + this.setParent(child); + }, this); + delete this._children[v]; + } + _.each(_.keys(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + _.each(_.keys(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; +}; + +Graph.prototype.setParent = function(v, parent) { + if (!this._isCompound) { + throw new Error("Cannot set parent in a non-compound graph"); + } + + if (_.isUndefined(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ""; + for (var ancestor = parent; + !_.isUndefined(ancestor); + ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error("Setting " + parent+ " as parent of " + v + + " would create create a cycle"); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; +}; + +Graph.prototype._removeFromParentsChildList = function(v) { + delete this._children[this._parent[v]][v]; +}; + +Graph.prototype.parent = function(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } +}; + +Graph.prototype.children = function(v) { + if (_.isUndefined(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return _.keys(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } +}; + +Graph.prototype.predecessors = function(v) { + var predsV = this._preds[v]; + if (predsV) { + return _.keys(predsV); + } +}; + +Graph.prototype.successors = function(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return _.keys(sucsV); + } +}; + +Graph.prototype.neighbors = function(v) { + var preds = this.predecessors(v); + if (preds) { + return _.union(preds, this.successors(v)); + } +}; + +/* === Edge functions ========== */ + +Graph.prototype.setDefaultEdgeLabel = function(newDefault) { + if (!_.isFunction(newDefault)) { + newDefault = _.constant(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; +}; + +Graph.prototype.edgeCount = function() { + return this._edgeCount; +}; + +Graph.prototype.edges = function() { + return _.values(this._edgeObjs); +}; + +Graph.prototype.setPath = function(vs, value) { + var self = this, + args = arguments; + _.reduce(vs, function(v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; +}; + +/* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ +Graph.prototype.setEdge = function() { + var v, w, name, value, + valueSpecified = false; + + if (_.isPlainObject(arguments[0])) { + v = arguments[0].v; + w = arguments[0].w; + name = arguments[0].name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arguments[0]; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = "" + v; + w = "" + w; + if (!_.isUndefined(name)) { + name = "" + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (_.has(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!_.isUndefined(name) && !this._isMultigraph) { + throw new Error("Cannot set a named edge when isMultigraph = false"); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; +}; + +Graph.prototype.edge = function(v, w, name) { + var e = (arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name)); + return this._edgeLabels[e]; +}; + +Graph.prototype.hasEdge = function(v, w, name) { + var e = (arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name)); + return _.has(this._edgeLabels, e); +}; + +Graph.prototype.removeEdge = function(v, w, name) { + var e = (arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name)), + edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; +}; + +Graph.prototype.inEdges = function(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = _.values(inV); + if (!u) { + return edges; + } + return _.filter(edges, function(edge) { return edge.v === u; }); + } +}; + +Graph.prototype.outEdges = function(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = _.values(outV); + if (!w) { + return edges; + } + return _.filter(edges, function(edge) { return edge.w === w; }); + } +}; + +Graph.prototype.nodeEdges = function(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } +}; + +function incrementOrInitEntry(map, k) { + if (_.has(map, k)) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { delete map[k]; } +} + +function edgeArgsToId(isDirected, v, w, name) { + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + + (_.isUndefined(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v, w, name) { + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + +},{"./lodash":77}],75:[function(require,module,exports){ +// Includes only the "core" of graphlib +module.exports = { + Graph: require("./graph"), + version: require("./version") +}; + +},{"./graph":74,"./version":78}],76:[function(require,module,exports){ +var _ = require("./lodash"), + Graph = require("./graph"); + +module.exports = { + write: write, + read: read +}; + +function write(g) { + var json = { + options: { + directed: g.isDirected(), + multigraph: g.isMultigraph(), + compound: g.isCompound() + }, + nodes: writeNodes(g), + edges: writeEdges(g) + }; + if (!_.isUndefined(g.graph())) { + json.value = _.clone(g.graph()); + } + return json; +} + +function writeNodes(g) { + return _.map(g.nodes(), function(v) { + var nodeValue = g.node(v), + parent = g.parent(v), + node = { v: v }; + if (!_.isUndefined(nodeValue)) { + node.value = nodeValue; + } + if (!_.isUndefined(parent)) { + node.parent = parent; + } + return node; + }); +} + +function writeEdges(g) { + return _.map(g.edges(), function(e) { + var edgeValue = g.edge(e), + edge = { v: e.v, w: e.w }; + if (!_.isUndefined(e.name)) { + edge.name = e.name; + } + if (!_.isUndefined(edgeValue)) { + edge.value = edgeValue; + } + return edge; + }); +} + +function read(json) { + var g = new Graph(json.options).setGraph(json.value); + _.each(json.nodes, function(entry) { + g.setNode(entry.v, entry.value); + if (entry.parent) { + g.setParent(entry.v, entry.parent); + } + }); + _.each(json.edges, function(entry) { + g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value); + }); + return g; +} + +},{"./graph":74,"./lodash":77}],77:[function(require,module,exports){ +/* global window */ + +var lodash; + +if (typeof require === "function") { + try { + lodash = require("lodash"); + } catch (e) {} +} + +if (!lodash) { + lodash = window._; +} + +module.exports = lodash; + +},{"lodash":79}],78:[function(require,module,exports){ +module.exports = '1.0.5'; + +},{}],79:[function(require,module,exports){ +(function (global){ +/** + * @license + * lodash 3.10.0 (Custom Build) + * Build: `lodash modern -d -o ./index.js` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '3.10.0'; + + /** Used to compose bitmasks for wrapper metadata. */ + var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64, + ARY_FLAG = 128, + REARG_FLAG = 256; + + /** Used as default options for `_.trunc`. */ + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; + + /** Used to detect when a function becomes hot. */ + var HOT_COUNT = 150, + HOT_SPAN = 16; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2; + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to match empty string literals in compiled template source. */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, + reUnescapedHtml = /[&<>"'`]/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to match template delimiters. */ + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; + + /** + * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns) + * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern). + */ + var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g, + reHasRegExpChars = RegExp(reRegExpChars.source); + + /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ + var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect hexadecimal string values. */ + var reHasHexPrefix = /^0[xX]/; + + /** Used to detect host constructors (Safari > 5). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^\d+$/; + + /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ + var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; + + /** Used to ensure capturing order of template delimiters. */ + var reNoMatch = /($^)/; + + /** Used to match unescaped characters in compiled string literals. */ + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + + /** Used to match words to create compound words. */ + var reWords = (function() { + var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', + lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; + + return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); + }()); + + /** Used to assign default `context` object properties. */ + var contextProps = [ + 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', + 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite', + 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap' + ]; + + /** Used to make template sourceURLs easier to identify. */ + var templateCounter = -1; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dateTag] = typedArrayTags[errorTag] = + typedArrayTags[funcTag] = typedArrayTags[mapTag] = + typedArrayTags[numberTag] = typedArrayTags[objectTag] = + typedArrayTags[regexpTag] = typedArrayTags[setTag] = + typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = + cloneableTags[dateTag] = cloneableTags[float32Tag] = + cloneableTags[float64Tag] = cloneableTags[int8Tag] = + cloneableTags[int16Tag] = cloneableTags[int32Tag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[stringTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[mapTag] = cloneableTags[setTag] = + cloneableTags[weakMapTag] = false; + + /** Used to map latin-1 supplementary letters to basic latin letters. */ + var deburredLetters = { + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss' + }; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", + '`': '`' + }; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used to escape characters for inclusion in compiled regexes. */ + var regexpEscapes = { + '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', + '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', + 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', + 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', + 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' + }; + + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; + + /** Detect free variable `self`. */ + var freeSelf = objectTypes[typeof self] && self && self.Object && self; + + /** Detect free variable `window`. */ + var freeWindow = objectTypes[typeof window] && window && window.Object && window; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** + * Used as a reference to the global object. + * + * The `this` value is used if it's the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ + var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `compareAscending` which compares values and + * sorts them in ascending order without guaranteeing a stable sort. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function baseCompareAscending(value, other) { + if (value !== other) { + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, + othIsReflexive = other === other; + + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { + return 1; + } + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { + return -1; + } + } + return 0; + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to search. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without support for binary searches. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return indexOfNaN(array, fromIndex); + } + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.isFunction` without support for environments + * with incorrect `typeof` results. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + */ + function baseIsFunction(value) { + // Avoid a Chakra JIT bug in compatibility modes of IE 11. + // See https://github.com/jashkenas/underscore/issues/1621 for more details. + return typeof value == 'function' || false; + } + + /** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` or `undefined` values. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + return value == null ? '' : (value + ''); + } + + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the first character not found in `chars`. + */ + function charsLeftIndex(string, chars) { + var index = -1, + length = string.length; + + while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the last character not found in `chars`. + */ + function charsRightIndex(string, chars) { + var index = string.length; + + while (index-- && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } + + /** + * Used by `_.sortBy` to compare transformed elements of a collection and stable + * sort them in ascending order. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareAscending(object, other) { + return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); + } + + /** + * Used by `_.sortByOrder` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise, + * a value is sorted in ascending order if its corresponding order is "asc", and + * descending if "desc". + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = baseCompareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * ((order === 'asc' || order === true) ? 1 : -1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://code.google.com/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } + + /** + * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + function deburrLetter(letter) { + return deburredLetters[letter]; + } + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(chr) { + return htmlEscapes[chr]; + } + + /** + * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes. + * + * @private + * @param {string} chr The matched character to escape. + * @param {string} leadingChar The capture group for a leading character. + * @param {string} whitespaceChar The capture group for a whitespace character. + * @returns {string} Returns the escaped character. + */ + function escapeRegExpChar(chr, leadingChar, whitespaceChar) { + if (leadingChar) { + chr = regexpEscapes[chr]; + } else if (whitespaceChar) { + chr = stringEscapes[chr]; + } + return '\\' + chr; + } + + /** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; + } + + /** + * Gets the index at which the first occurrence of `NaN` is found in `array`. + * + * @private + * @param {Array} array The array to search. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched `NaN`, else `-1`. + */ + function indexOfNaN(array, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 0 : -1); + + while ((fromRight ? index-- : ++index < length)) { + var other = array[index]; + if (other !== other) { + return index; + } + } + return -1; + } + + /** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a + * character code is whitespace. + * + * @private + * @param {number} charCode The character code to inspect. + * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`. + */ + function isSpace(charCode) { + return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 || + (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); + } + + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + if (array[index] === placeholder) { + array[index] = PLACEHOLDER; + result[++resIndex] = index; + } + } + return result; + } + + /** + * An implementation of `_.uniq` optimized for sorted arrays without support + * for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function sortedUniq(array, iteratee) { + var seen, + index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (!index || seen !== computed) { + seen = computed; + result[++resIndex] = value; + } + } + return result; + } + + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the first non-whitespace character. + */ + function trimmedLeftIndex(string) { + var index = -1, + length = string.length; + + while (++index < length && isSpace(string.charCodeAt(index))) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ + function trimmedRightIndex(string) { + var index = string.length; + + while (index-- && isSpace(string.charCodeAt(index))) {} + return index; + } + + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(chr) { + return htmlUnescapes[chr]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new pristine `lodash` function using the given `context` object. + * + * @static + * @memberOf _ + * @category Utility + * @param {Object} [context=root] The context object. + * @returns {Function} Returns a new `lodash` function. + * @example + * + * _.mixin({ 'foo': _.constant('foo') }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'bar': lodash.constant('bar') }); + * + * _.isFunction(_.foo); + * // => true + * _.isFunction(_.bar); + * // => false + * + * lodash.isFunction(lodash.foo); + * // => false + * lodash.isFunction(lodash.bar); + * // => true + * + * // using `context` to mock `Date#getTime` use in `_.now` + * var mock = _.runInContext({ + * 'Date': function() { + * return { 'getTime': getTimeMock }; + * } + * }); + * + * // or creating a suped-up `defer` in Node.js + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See https://es5.github.io/#x11.1.5 for more details. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references. */ + var Array = context.Array, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** Used for native method references. */ + var arrayProto = Array.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; + + /** Used to resolve the decompiled source of functions. */ + var fnToString = Function.prototype.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ + var objToString = objectProto.toString; + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Native method references. */ + var ArrayBuffer = context.ArrayBuffer, + clearTimeout = context.clearTimeout, + parseFloat = context.parseFloat, + pow = Math.pow, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + Set = getNative(context, 'Set'), + setTimeout = context.setTimeout, + splice = arrayProto.splice, + Uint8Array = context.Uint8Array, + WeakMap = getNative(context, 'WeakMap'); + + /* Native method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil, + nativeCreate = getNative(Object, 'create'), + nativeFloor = Math.floor, + nativeIsArray = getNative(Array, 'isArray'), + nativeIsFinite = context.isFinite, + nativeKeys = getNative(Object, 'keys'), + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = getNative(Date, 'now'), + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used as references for `-Infinity` and `Infinity`. */ + var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, + POSITIVE_INFINITY = Number.POSITIVE_INFINITY; + + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + + /** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /** Used to lookup unminified function names. */ + var realNames = {}; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit chaining. + * Methods that operate on and return arrays, collections, and functions can + * be chained together. Methods that retrieve a single value or may return a + * primitive value will automatically end the chain returning the unwrapped + * value. Explicit chaining may be enabled using `_.chain`. The execution of + * chained methods is lazy, that is, execution is deferred until `_#value` + * is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization strategy which merge iteratee calls; this can help + * to avoid the creation of intermediate data structures and greatly reduce the + * number of iteratee executions. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, + * `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, + * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, + * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, + * and `where` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, + * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, + * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, + * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, + * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, + * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, + * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, + * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, + * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, + * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, + * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, + * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, + * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, + * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, + * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, + * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, + * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, + * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, + * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, + * `unescape`, `uniqueId`, `value`, and `words` + * + * The wrapper method `sample` will return a wrapped value when `n` is provided, + * otherwise an unwrapped value is returned. + * + * @name _ + * @constructor + * @category Chain + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(total, n) { + * return total + n; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(n) { + * return n * n; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } + + /** + * The function whose prototype all chaining wrappers inherit from. + * + * @private + */ + function baseLodash() { + // No operation performed. + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable chaining for all wrapper methods. + * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. + */ + function LodashWrapper(value, chainAll, actions) { + this.__wrapped__ = value; + this.__actions__ = actions || []; + this.__chain__ = !!chainAll; + } + + /** + * An object environment feature flags. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB). Change the following template settings to use + * alternative delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': reEscape, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': reEvaluate, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = POSITIVE_INFINITY; + this.__views__ = []; + } + + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = arrayCopy(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = arrayCopy(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = arrayCopy(this.__views__); + return result; + } + + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ + function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; + } + + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ + function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { + return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__); + } + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a cache object to store key/value pairs. + * + * @private + * @static + * @name Cache + * @memberOf _.memoize + */ + function MapCache() { + this.__data__ = {}; + } + + /** + * Removes `key` and its value from the cache. + * + * @private + * @name delete + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`. + */ + function mapDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the cached value for `key`. + * + * @private + * @name get + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to get. + * @returns {*} Returns the cached value. + */ + function mapGet(key) { + return key == '__proto__' ? undefined : this.__data__[key]; + } + + /** + * Checks if a cached value for `key` exists. + * + * @private + * @name has + * @memberOf _.memoize.Cache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapHas(key) { + return key != '__proto__' && hasOwnProperty.call(this.__data__, key); + } + + /** + * Sets `value` to `key` of the cache. + * + * @private + * @name set + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to cache. + * @param {*} value The value to cache. + * @returns {Object} Returns the cache object. + */ + function mapSet(key, value) { + if (key != '__proto__') { + this.__data__[key] = value; + } + return this; + } + + /*------------------------------------------------------------------------*/ + + /** + * + * Creates a cache object to store unique values. + * + * @private + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var length = values ? values.length : 0; + + this.data = { 'hash': nativeCreate(null), 'set': new Set }; + while (length--) { + this.push(values[length]); + } + } + + /** + * Checks if `value` is in `cache` mimicking the return signature of + * `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache to search. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var data = cache.data, + result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; + + return result ? 0 : -1; + } + + /** + * Adds `value` to the cache. + * + * @private + * @name push + * @memberOf SetCache + * @param {*} value The value to cache. + */ + function cachePush(value) { + var data = this.data; + if (typeof value == 'string' || isObject(value)) { + data.set.add(value); + } else { + data.hash[value] = true; + } + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a new array joining `array` with `other`. + * + * @private + * @param {Array} array The array to join. + * @param {Array} other The other array to join. + * @returns {Array} Returns the new concatenated array. + */ + function arrayConcat(array, other) { + var index = -1, + length = array.length, + othIndex = -1, + othLength = other.length, + result = Array(length + othLength); + + while (++index < length) { + result[index] = array[index]; + } + while (++othIndex < othLength) { + result[index++] = other[othIndex]; + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function arrayCopy(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * A specialized version of `_.forEach` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `baseExtremum` for arrays which invokes `iteratee` + * with one argument: (value). + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {*} Returns the extremum value. + */ + function arrayExtremum(array, iteratee, comparator, exValue) { + var index = -1, + length = array.length, + computed = exValue, + result = computed; + + while (++index < length) { + var value = array[index], + current = +iteratee(value); + + if (comparator(current, computed)) { + computed = current; + result = value; + } + } + return result; + } + + /** + * A specialized version of `_.filter` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * A specialized version of `_.map` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the first element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initFromArray) { + var index = -1, + length = array.length; + + if (initFromArray && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the last element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initFromArray) { + var length = array.length; + if (initFromArray && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * A specialized version of `_.sum` for arrays without support for callback + * shorthands and `this` binding.. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function arraySum(array, iteratee) { + var length = array.length, + result = 0; + + while (length--) { + result += +iteratee(array[length]) || 0; + } + return result; + } + + /** + * Used by `_.defaults` to customize its `_.assign` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : objectValue; + } + + /** + * Used by `_.template` to customize its `_.assign` use. + * + * **Note:** This function is like `assignDefaults` except that it ignores + * inherited property values when checking if a property is `undefined`. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @param {string} key The key associated with the object and source values. + * @param {Object} object The destination object. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignOwnDefaults(objectValue, sourceValue, key, object) { + return (objectValue === undefined || !hasOwnProperty.call(object, key)) + ? sourceValue + : objectValue; + } + + /** + * A specialized version of `_.assign` for customizing assigned values without + * support for argument juggling, multiple sources, and `this` binding `customizer` + * functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + */ + function assignWith(object, source, customizer) { + var index = -1, + props = keys(source), + length = props.length; + + while (++index < length) { + var key = props[index], + value = object[key], + result = customizer(value, source[key], key, object, source); + + if ((result === result ? (result !== value) : (value === value)) || + (value === undefined && !(key in object))) { + object[key] = result; + } + } + return object; + } + + /** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return source == null + ? object + : baseCopy(source, keys(source), object); + } + + /** + * The base implementation of `_.at` without support for string collections + * and individual key arguments. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {number[]|string[]} props The property names or indexes of elements to pick. + * @returns {Array} Returns the new array of picked elements. + */ + function baseAt(collection, props) { + var index = -1, + isNil = collection == null, + isArr = !isNil && isArrayLike(collection), + length = isArr ? collection.length : 0, + propsLength = props.length, + result = Array(propsLength); + + while(++index < propsLength) { + var key = props[index]; + if (isArr) { + result[index] = isIndex(key, length) ? collection[key] : undefined; + } else { + result[index] = isNil ? undefined : collection[key]; + } + } + return result; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ + function baseCopy(source, props, object) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; + } + + /** + * The base implementation of `_.callback` which supports specifying the + * number of arguments to provide to `func`. + * + * @private + * @param {*} [func=_.identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function baseCallback(func, thisArg, argCount) { + var type = typeof func; + if (type == 'function') { + return thisArg === undefined + ? func + : bindCallback(func, thisArg, argCount); + } + if (func == null) { + return identity; + } + if (type == 'object') { + return baseMatches(func); + } + return thisArg === undefined + ? property(func) + : baseMatchesProperty(func, thisArg); + } + + /** + * The base implementation of `_.clone` without support for argument juggling + * and `this` binding `customizer` functions. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The object `value` belongs to. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { + var result; + if (customizer) { + result = object ? customizer(value, key, object) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return arrayCopy(value, result); + } + } else { + var tag = objToString.call(value), + isFunc = tag == funcTag; + + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return baseAssign(result, value); + } + } else { + return cloneableTags[tag] + ? initCloneByTag(value, tag, isDeep) + : (object ? value : {}); + } + } + // Check for circular references and return its corresponding clone. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + // Add the source value to the stack of traversed objects and associate it with its clone. + stackA.push(value); + stackB.push(result); + + // Recursively populate clone (susceptible to call stack limits). + (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { + result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(prototype) { + if (isObject(prototype)) { + object.prototype = prototype; + var result = new object; + object.prototype = undefined; + } + return result || {}; + }; + }()); + + /** + * The base implementation of `_.delay` and `_.defer` which accepts an index + * of where to slice the arguments to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The arguments provide to `func`. + * @returns {number} Returns the timer id. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * The base implementation of `_.difference` which accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values) { + var length = array ? array.length : 0, + result = []; + + if (!length) { + return result; + } + var index = -1, + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null, + valuesLength = values.length; + + if (cache) { + indexOf = cacheIndexOf; + isCommon = false; + values = cache; + } + outer: + while (++index < length) { + var value = array[index]; + + if (isCommon && value === value) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === value) { + continue outer; + } + } + result.push(value); + } + else if (indexOf(values, value, 0) < 0) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.forEach` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.forEachRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEachRight = createBaseEach(baseForOwnRight, true); + + /** + * The base implementation of `_.every` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * Gets the extremum value of `collection` invoking `iteratee` for each value + * in `collection` to generate the criterion by which the value is ranked. + * The `iteratee` is invoked with three arguments: (value, index|key, collection). + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(collection, iteratee, comparator, exValue) { + var computed = exValue, + result = computed; + + baseEach(collection, function(value, index, collection) { + var current = +iteratee(value, index, collection); + if (comparator(current, computed) || (current === exValue && current === result)) { + computed = current; + result = value; + } + }); + return result; + } + + /** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ + function baseFill(array, value, start, end) { + var length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : (end >>> 0); + start >>>= 0; + + while (start < length) { + array[start++] = value; + } + return array; + } + + /** + * The base implementation of `_.filter` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, + * without support for callback shorthands and `this` binding, which iterates + * over `collection` using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element + * instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with added support for restricting + * flattening and specifying the start index. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, isDeep, isStrict, result) { + result || (result = []); + + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + if (isObjectLike(value) && isArrayLike(value) && + (isStrict || isArray(value) || isArguments(value))) { + if (isDeep) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, isDeep, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseForRight = createBaseFor(true); + + /** + * The base implementation of `_.forIn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForIn(object, iteratee) { + return baseFor(object, iteratee, keysIn); + } + + /** + * The base implementation of `_.forOwn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.forOwnRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwnRight(object, iteratee) { + return baseForRight(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from those provided. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the new array of filtered property names. + */ + function baseFunctions(object, props) { + var index = -1, + length = props.length, + resIndex = -1, + result = []; + + while (++index < length) { + var key = props[index]; + if (isFunction(object[key])) { + result[++resIndex] = key; + } + } + return result; + } + + /** + * The base implementation of `get` without support for string paths + * and default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path of the property to get. + * @param {string} [pathKey] The key representation of path. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path, pathKey) { + if (object == null) { + return; + } + if (pathKey !== undefined && pathKey in toObject(object)) { + path = [pathKey]; + } + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[path[index++]]; + } + return (index && index == length) ? object : undefined; + } + + /** + * The base implementation of `_.isEqual` without support for `this` binding + * `customizer` functions. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing objects. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `value` objects. + * @param {Array} [stackB=[]] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = objToString.call(object); + if (objTag == argsTag) { + objTag = objectTag; + } else if (objTag != objectTag) { + objIsArr = isTypedArray(object); + } + } + if (!othIsArr) { + othTag = objToString.call(other); + if (othTag == argsTag) { + othTag = objectTag; + } else if (othTag != objectTag) { + othIsArr = isTypedArray(other); + } + } + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && !(objIsArr || objIsObj)) { + return equalByTag(object, other, objTag); + } + if (!isLoose) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); + } + } + if (!isSameTag) { + return false; + } + // Assume cyclic values are equal. + // For more information on detecting circular references see https://es5.github.io/#JO. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == object) { + return stackB[length] == other; + } + } + // Add `object` and `other` to the stack of traversed objects. + stackA.push(object); + stackB.push(other); + + var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); + + stackA.pop(); + stackB.pop(); + + return result; + } + + /** + * The base implementation of `_.isMatch` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} matchData The propery names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparing objects. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = toObject(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var result = customizer ? customizer(objValue, srcValue, key) : undefined; + if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { + return false; + } + } + } + return true; + } + + /** + * The base implementation of `_.map` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which does not clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + var key = matchData[0][0], + value = matchData[0][1]; + + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && (value !== undefined || (key in toObject(object))); + }; + } + return function(object) { + return baseIsMatch(object, matchData); + }; + } + + /** + * The base implementation of `_.matchesProperty` which does not clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to compare. + * @returns {Function} Returns the new function. + */ + function baseMatchesProperty(path, srcValue) { + var isArr = isArray(path), + isCommon = isKey(path) && isStrictComparable(srcValue), + pathKey = (path + ''); + + path = toPath(path); + return function(object) { + if (object == null) { + return false; + } + var key = pathKey; + object = toObject(object); + if ((isArr || !isCommon) && !(key in object)) { + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + key = last(path); + object = toObject(object); + } + return object[key] === srcValue + ? (srcValue !== undefined || (key in object)) + : baseIsEqual(srcValue, object[key], undefined, true); + }; + } + + /** + * The base implementation of `_.merge` without support for argument juggling, + * multiple sources, and `this` binding `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [customizer] The function to customize merged values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {Object} Returns `object`. + */ + function baseMerge(object, source, customizer, stackA, stackB) { + if (!isObject(object)) { + return object; + } + var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), + props = isSrcArr ? undefined : keys(source); + + arrayEach(props || source, function(srcValue, key) { + if (props) { + key = srcValue; + srcValue = source[key]; + } + if (isObjectLike(srcValue)) { + stackA || (stackA = []); + stackB || (stackB = []); + baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); + } + else { + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; + + if (isCommon) { + result = srcValue; + } + if ((result !== undefined || (isSrcArr && !(key in object))) && + (isCommon || (result === result ? (result !== value) : (value === value)))) { + object[key] = result; + } + } + }); + return object; + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize merged values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { + var length = stackA.length, + srcValue = source[key]; + + while (length--) { + if (stackA[length] == srcValue) { + object[key] = stackB[length]; + return; + } + } + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; + + if (isCommon) { + result = srcValue; + if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) { + result = isArray(value) + ? value + : (isArrayLike(value) ? arrayCopy(value) : []); + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + result = isArguments(value) + ? toPlainObject(value) + : (isPlainObject(value) ? value : {}); + } + else { + isCommon = false; + } + } + // Add the source value to the stack of traversed objects and associate + // it with its merged value. + stackA.push(srcValue); + stackB.push(result); + + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); + } else if (result === result ? (result !== value) : (value === value)) { + object[key] = result; + } + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + */ + function basePropertyDeep(path) { + var pathKey = (path + ''); + path = toPath(path); + return function(object) { + return baseGet(object, path, pathKey); + }; + } + + /** + * The base implementation of `_.pullAt` without support for individual + * index arguments and capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ + function basePullAt(array, indexes) { + var length = array ? indexes.length : 0; + while (length--) { + var index = indexes[length]; + if (index != previous && isIndex(index)) { + var previous = index; + splice.call(array, index, 1); + } + } + return array; + } + + /** + * The base implementation of `_.random` without support for argument juggling + * and returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns the random number. + */ + function baseRandom(min, max) { + return min + nativeFloor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight` without support + * for callback shorthands and `this` binding, which iterates over `collection` + * using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initFromCollection Specify using the first or last element + * of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initFromCollection + ? (initFromCollection = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `setData` without support for hot loop detection. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; + }; + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * The base implementation of `_.some` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `_.sortBy` which uses `comparer` to define + * the sort order of `array` and replaces criteria objects with their + * corresponding values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ + function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } + + /** + * The base implementation of `_.sortByOrder` without param guards. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseSortByOrder(collection, iteratees, orders) { + var callback = getCallback(), + index = -1; + + iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); + + var result = baseMap(collection, function(value) { + var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } + + /** + * The base implementation of `_.sum` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function baseSum(collection, iteratee) { + var result = 0; + baseEach(collection, function(value, index, collection) { + result += +iteratee(value, index, collection) || 0; + }); + return result; + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function baseUniq(array, iteratee) { + var index = -1, + indexOf = getIndexOf(), + length = array.length, + isCommon = indexOf == baseIndexOf, + isLarge = isCommon && length >= LARGE_ARRAY_SIZE, + seen = isLarge ? createCache() : null, + result = []; + + if (seen) { + indexOf = cacheIndexOf; + isCommon = false; + } else { + isLarge = false; + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (isCommon && value === value) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (indexOf(seen, computed, 0) < 0) { + if (iteratee || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + var index = -1, + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /** + * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, + * and `_.takeWhile` without support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ + function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to peform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + var index = -1, + length = actions.length; + + while (++index < length) { + var action = actions[index]; + result = action.func.apply(action.thisArg, arrayPush([result], action.args)); + } + return result; + } + + /** + * Performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndex(array, value, retHighest) { + var low = 0, + high = array ? array.length : low; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return binaryIndexBy(array, value, identity, retHighest); + } + + /** + * This function is like `binaryIndex` except that it invokes `iteratee` for + * `value` and each element of `array` to compute their sort ranking. The + * iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The function invoked per iteration. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); + + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsNull = value === null, + valIsUndef = value === undefined; + + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + isDef = computed !== undefined, + isReflexive = computed === computed; + + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsNull) { + setLow = isReflexive && isDef && (retHighest || computed != null); + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || isDef); + } else if (computed == null) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } + + /** + * A specialized version of `baseCallback` which only supports `this` binding + * and specifying the number of arguments to provide to `func`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function bindCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + if (thisArg === undefined) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + case 5: return function(value, other, key, object, source) { + return func.call(thisArg, value, other, key, object, source); + }; + } + return function() { + return func.apply(thisArg, arguments); + }; + } + + /** + * Creates a clone of the given array buffer. + * + * @private + * @param {ArrayBuffer} buffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function bufferClone(buffer) { + var result = new ArrayBuffer(buffer.byteLength), + view = new Uint8Array(result); + + view.set(new Uint8Array(buffer)); + return result; + } + + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders) { + var holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + leftIndex = -1, + leftLength = partials.length, + result = Array(leftLength + argsLength); + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + while (argsLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } + + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders) { + var holdersIndex = -1, + holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + rightIndex = -1, + rightLength = partials.length, + result = Array(argsLength + rightLength); + + while (++argsIndex < argsLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + return result; + } + + /** + * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function. + * + * @private + * @param {Function} setter The function to set keys and values of the accumulator object. + * @param {Function} [initializer] The function to initialize the accumulator object. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function(collection, iteratee, thisArg) { + var result = initializer ? initializer() : {}; + iteratee = getCallback(iteratee, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + setter(result, value, iteratee(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, iteratee(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a `_.assign`, `_.defaults`, or `_.merge` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return restParam(function(object, sources) { + var index = -1, + length = object == null ? 0 : sources.length, + customizer = length > 2 ? sources[length - 2] : undefined, + guard = length > 2 ? sources[2] : undefined, + thisArg = length > 1 ? sources[length - 1] : undefined; + + if (typeof customizer == 'function') { + customizer = bindCallback(customizer, thisArg, 5); + length -= 2; + } else { + customizer = typeof thisArg == 'function' ? thisArg : undefined; + length -= (customizer ? 1 : 0); + } + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + return eachFunc(collection, iteratee); + } + var index = fromRight ? length : -1, + iterable = toObject(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var iterable = toObject(object), + props = keysFunc(object), + length = props.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + var key = props[index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that wraps `func` and invokes it with the `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new bound function. + */ + function createBindWrapper(func, thisArg) { + var Ctor = createCtorWrapper(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(thisArg, arguments); + } + return wrapper; + } + + /** + * Creates a `Set` cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [values] The values to cache. + * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. + */ + function createCache(values) { + return (nativeCreate && Set) ? new SetCache(values) : null; + } + + /** + * Creates a function that produces compound words out of the words in a + * given string. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + var index = -1, + array = words(deburr(string)), + length = array.length, + result = ''; + + while (++index < length) { + result = callback(result, array[index], index); + } + return result; + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtorWrapper(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a `_.curry` or `_.curryRight` function. + * + * @private + * @param {boolean} flag The curry bit flag. + * @returns {Function} Returns the new curry function. + */ + function createCurry(flag) { + function curryFunc(func, arity, guard) { + if (guard && isIterateeCall(func, arity, guard)) { + arity = undefined; + } + var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryFunc.placeholder; + return result; + } + return curryFunc; + } + + /** + * Creates a `_.defaults` or `_.defaultsDeep` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @param {Function} customizer The function to customize assigned values. + * @returns {Function} Returns the new defaults function. + */ + function createDefaults(assigner, customizer) { + return restParam(function(args) { + var object = args[0]; + if (object == null) { + return object; + } + args.push(customizer); + return assigner.apply(undefined, args); + }); + } + + /** + * Creates a `_.max` or `_.min` function. + * + * @private + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {Function} Returns the new extremum function. + */ + function createExtremum(comparator, exValue) { + return function(collection, iteratee, thisArg) { + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; + } + iteratee = getCallback(iteratee, thisArg, 3); + if (iteratee.length == 1) { + collection = isArray(collection) ? collection : toIterable(collection); + var result = arrayExtremum(collection, iteratee, comparator, exValue); + if (!(collection.length && result === exValue)) { + return result; + } + } + return baseExtremum(collection, iteratee, comparator, exValue); + }; + } + + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFind(eachFunc, fromRight) { + return function(collection, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, fromRight); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, eachFunc); + }; + } + + /** + * Creates a `_.findIndex` or `_.findLastIndex` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFindIndex(fromRight) { + return function(array, predicate, thisArg) { + if (!(array && array.length)) { + return -1; + } + predicate = getCallback(predicate, thisArg, 3); + return baseFindIndex(array, predicate, fromRight); + }; + } + + /** + * Creates a `_.findKey` or `_.findLastKey` function. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new find function. + */ + function createFindKey(objectFunc) { + return function(object, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + return baseFind(object, predicate, objectFunc, true); + }; + } + + /** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ + function createFlow(fromRight) { + return function() { + var wrapper, + length = arguments.length, + index = fromRight ? length : -1, + leftIndex = 0, + funcs = Array(length); + + while ((fromRight ? index-- : ++index < length)) { + var func = funcs[leftIndex++] = arguments[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { + wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? -1 : length; + while (++index < length) { + func = funcs[index]; + + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; + + if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }; + } + + /** + * Creates a function for `_.forEach` or `_.forEachRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createForEach(arrayFunc, eachFunc) { + return function(collection, iteratee, thisArg) { + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee) + : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); + }; + } + + /** + * Creates a function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForIn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee, keysIn); + }; + } + + /** + * Creates a function for `_.forOwn` or `_.forOwnRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForOwn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee); + }; + } + + /** + * Creates a function for `_.mapKeys` or `_.mapValues`. + * + * @private + * @param {boolean} [isMapKeys] Specify mapping keys instead of values. + * @returns {Function} Returns the new map function. + */ + function createObjectMapper(isMapKeys) { + return function(object, iteratee, thisArg) { + var result = {}; + iteratee = getCallback(iteratee, thisArg, 3); + + baseForOwn(object, function(value, key, object) { + var mapped = iteratee(value, key, object); + key = isMapKeys ? mapped : key; + value = isMapKeys ? value : mapped; + result[key] = value; + }); + return result; + }; + } + + /** + * Creates a function for `_.padLeft` or `_.padRight`. + * + * @private + * @param {boolean} [fromRight] Specify padding from the right. + * @returns {Function} Returns the new pad function. + */ + function createPadDir(fromRight) { + return function(string, length, chars) { + string = baseToString(string); + return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string); + }; + } + + /** + * Creates a `_.partial` or `_.partialRight` function. + * + * @private + * @param {boolean} flag The partial bit flag. + * @returns {Function} Returns the new partial function. + */ + function createPartial(flag) { + var partialFunc = restParam(function(func, partials) { + var holders = replaceHolders(partials, partialFunc.placeholder); + return createWrapper(func, flag, undefined, partials, holders); + }); + return partialFunc; + } + + /** + * Creates a function for `_.reduce` or `_.reduceRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createReduce(arrayFunc, eachFunc) { + return function(collection, iteratee, accumulator, thisArg) { + var initFromArray = arguments.length < 3; + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee, accumulator, initFromArray) + : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); + }; + } + + /** + * Creates a function that wraps `func` and invokes it with optional `this` + * binding of, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & ARY_FLAG, + isBind = bitmask & BIND_FLAG, + isBindKey = bitmask & BIND_KEY_FLAG, + isCurry = bitmask & CURRY_FLAG, + isCurryBound = bitmask & CURRY_BOUND_FLAG, + isCurryRight = bitmask & CURRY_RIGHT_FLAG, + Ctor = isBindKey ? undefined : createCtorWrapper(func); + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it to other functions. + var length = arguments.length, + index = length, + args = Array(length); + + while (index--) { + args[index] = arguments[index]; + } + if (partials) { + args = composeArgs(args, partials, holders); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight); + } + if (isCurry || isCurryRight) { + var placeholder = wrapper.placeholder, + argsHolders = replaceHolders(args, placeholder); + + length -= argsHolders.length; + if (length < arity) { + var newArgPos = argPos ? arrayCopy(argPos) : undefined, + newArity = nativeMax(arity - length, 0), + newsHolders = isCurry ? argsHolders : undefined, + newHoldersRight = isCurry ? undefined : argsHolders, + newPartials = isCurry ? args : undefined, + newPartialsRight = isCurry ? undefined : args; + + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + + if (!isCurryBound) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], + result = createHybridWrapper.apply(undefined, newData); + + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return result; + } + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + + if (argPos) { + args = reorder(args, argPos); + } + if (isAry && ary < args.length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtorWrapper(func); + } + return fn.apply(thisBinding, args); + } + return wrapper; + } + + /** + * Creates the padding required for `string` based on the given `length`. + * The `chars` string is truncated if the number of characters exceeds `length`. + * + * @private + * @param {string} string The string to create padding for. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the pad for `string`. + */ + function createPadding(string, length, chars) { + var strLength = string.length; + length = +length; + + if (strLength >= length || !nativeIsFinite(length)) { + return ''; + } + var padLength = length - strLength; + chars = chars == null ? ' ' : (chars + ''); + return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength); + } + + /** + * Creates a function that wraps `func` and invokes it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to partially apply arguments to. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to the new function. + * @returns {Function} Returns the new bound function. + */ + function createPartialWrapper(func, bitmask, thisArg, partials) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it `func`. + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength); + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * Creates a `_.ceil`, `_.floor`, or `_.round` function. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ + function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + precision = precision === undefined ? 0 : (+precision || 0); + if (precision) { + precision = pow(10, precision); + return func(number * precision) / precision; + } + return func(number); + }; + } + + /** + * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. + * + * @private + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {Function} Returns the new index function. + */ + function createSortedIndex(retHighest) { + return function(array, value, iteratee, thisArg) { + var callback = getCallback(iteratee); + return (iteratee == null && callback === baseCallback) + ? binaryIndex(array, value, retHighest) + : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest); + }; + } + + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + length -= (holders ? holders.length : 0); + if (bitmask & PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func), + newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; + + if (data) { + mergeData(newData, data); + bitmask = newData[1]; + arity = newData[9]; + } + newData[9] = arity == null + ? (isBindKey ? 0 : func.length) + : (nativeMax(arity - length, 0) || 0); + + if (bitmask == BIND_FLAG) { + var result = createBindWrapper(newData[0], newData[2]); + } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { + result = createPartialWrapper.apply(undefined, newData); + } else { + result = createHybridWrapper.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setter(result, newData); + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing arrays. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { + var index = -1, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isLoose && othLength > arrLength)) { + return false; + } + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index], + result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; + + if (result !== undefined) { + if (result) { + continue; + } + return false; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isLoose) { + if (!arraySome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + })) { + return false; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { + return false; + } + } + return true; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag) { + switch (tag) { + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) + ? other != +other + : object == +other; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isLoose) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + var skipCtor = isLoose; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key], + result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; + + // Recursively compare objects (susceptible to call stack limits). + if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { + return false; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (!skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + return false; + } + } + return true; + } + + /** + * Gets the appropriate "callback" function. If the `_.callback` method is + * customized this function returns the custom method, otherwise it returns + * the `baseCallback` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function} Returns the chosen function or its result. + */ + function getCallback(func, thisArg, argCount) { + var result = lodash.callback || callback; + result = result === callback ? baseCallback : result; + return argCount ? result(func, thisArg, argCount) : result; + } + + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ + var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); + }; + + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + function getFuncName(func) { + var result = func.name, + array = realNames[result], + length = array ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + } + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized this function returns the custom method, otherwise it returns + * the `baseIndexOf` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function|number} Returns the chosen function or its result. + */ + function getIndexOf(collection, target, fromIndex) { + var result = lodash.indexOf || indexOf; + result = result === indexOf ? baseIndexOf : result; + return collection ? result(collection, target, fromIndex) : result; + } + + /** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); + + /** + * Gets the propery names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = pairs(object), + length = result.length; + + while (length--) { + result[length][2] = isStrictComparable(result[length][1]); + } + return result; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = object == null ? undefined : object[key]; + return isNative(value) ? value : undefined; + } + + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ + function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add array properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + var Ctor = object.constructor; + if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { + Ctor = Object; + } + return new Ctor; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return bufferClone(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + var buffer = object.buffer; + return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + var result = new Ctor(object.source, reFlags.exec(object)); + result.lastIndex = object.lastIndex; + } + return result; + } + + /** + * Invokes the method at `path` on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function invokePath(object, path, args) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + path = last(path); + } + var func = object == null ? object : object[path]; + return func == null ? undefined : func.apply(object, args); + } + + /** + * Checks if `value` is array-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + */ + function isArrayLike(value) { + return value != null && isLength(getLength(value)); + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; + } + + /** + * Checks if the provided arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + var other = object[index]; + return value === value ? (value === other) : (other !== other); + } + return false; + } + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + var type = typeof value; + if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { + return true; + } + if (isArray(value)) { + return false; + } + var result = !reIsDeepProp.test(value); + return result || (object != null && value in toObject(object)); + } + + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. + */ + function isLaziable(func) { + var funcName = getFuncName(func); + if (!(funcName in LazyWrapper.prototype)) { + return false; + } + var other = lodash[funcName]; + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ + function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers required to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` + * augment function arguments, making the order in which they are executed important, + * preventing the merging of metadata. However, we make an exception for a safe + * common case where curried functions have `_.ary` and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < ARY_FLAG; + + var isCombo = + (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || + (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || + (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = arrayCopy(value); + } + // Use source `ary` if it's smaller. + if (srcBitmask & ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; + } + + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function mergeDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults); + } + + /** + * A specialized version of `_.pick` which picks `object` properties specified + * by `props`. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ + function pickByArray(object, props) { + object = toObject(object); + + var index = -1, + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + return result; + } + + /** + * A specialized version of `_.pick` which picks `object` properties `predicate` + * returns truthy for. + * + * @private + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per iteration. + * @returns {Object} Returns the new object. + */ + function pickByCallback(object, predicate) { + var result = {}; + baseForIn(object, function(value, key, object) { + if (predicate(value, key, object)) { + result[key] = value; + } + }); + return result; + } + + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = arrayCopy(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; + } + + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity function + * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var setData = (function() { + var count = 0, + lastCalled = 0; + + return function(key, value) { + var stamp = now(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return key; + } + } else { + count = 0; + } + return baseSetData(key, value); + }; + }()); + + /** + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length; + + var allowIndexes = !!length && isLength(length) && + (isArray(object) || isArguments(object)); + + var index = -1, + result = []; + + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } + } + return result; + } + + /** + * Converts `value` to an array-like object if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array|Object} Returns the array-like object. + */ + function toIterable(value) { + if (value == null) { + return []; + } + if (!isArrayLike(value)) { + return values(value); + } + return isObject(value) ? value : Object(value); + } + + /** + * Converts `value` to an object if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Object} Returns the object. + */ + function toObject(value) { + return isObject(value) ? value : Object(value); + } + + /** + * Converts `value` to property path array if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array} Returns the property path array. + */ + function toPath(value) { + if (isArray(value)) { + return value; + } + var result = []; + baseToString(value).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + } + + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + return wrapper instanceof LazyWrapper + ? wrapper.clone() + : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements split into groups the length of `size`. + * If `collection` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ + function chunk(array, size, guard) { + if (guard ? isIterateeCall(array, size, guard) : size == null) { + size = 1; + } else { + size = nativeMax(nativeFloor(size) || 1, 1); + } + var index = 0, + length = array ? array.length : 0, + resIndex = -1, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[++resIndex] = baseSlice(array, index, (index += size)); + } + return result; + } + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * Creates an array of unique `array` values not included in the other + * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([1, 2, 3], [4, 2]); + * // => [1, 3] + */ + var difference = restParam(function(array, values) { + return (isObjectLike(array) && isArrayLike(array)) + ? baseDifference(array, baseFlatten(values, false, true)) + : []; + }); + + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that match the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [1] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); + * // => ['barney'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function dropRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) + : []; + } + + /** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [3] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropWhile(users, 'active', false), 'user'); + * // => ['pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function dropWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true) + : []; + } + + /** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8], '*', 1, 2); + * // => [4, '*', 8] + */ + function fill(array, value, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(chr) { + * return chr.user == 'barney'; + * }); + * // => 0 + * + * // using the `_.matches` callback shorthand + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // using the `_.matchesProperty` callback shorthand + * _.findIndex(users, 'active', false); + * // => 0 + * + * // using the `_.property` callback shorthand + * _.findIndex(users, 'active'); + * // => 2 + */ + var findIndex = createFindIndex(); + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(chr) { + * return chr.user == 'pebbles'; + * }); + * // => 2 + * + * // using the `_.matches` callback shorthand + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastIndex(users, 'active', false); + * // => 2 + * + * // using the `_.property` callback shorthand + * _.findLastIndex(users, 'active'); + * // => 0 + */ + var findLastIndex = createFindIndex(true); + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias head + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([]); + * // => undefined + */ + function first(array) { + return array ? array[0] : undefined; + } + + /** + * Flattens a nested array. If `isDeep` is `true` the array is recursively + * flattened, otherwise it is only flattened a single level. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, 3, [4]]]); + * // => [1, 2, 3, [4]] + * + * // using `isDeep` + * _.flatten([1, [2, 3, [4]]], true); + * // => [1, 2, 3, 4] + */ + function flatten(array, isDeep, guard) { + var length = array ? array.length : 0; + if (guard && isIterateeCall(array, isDeep, guard)) { + isDeep = false; + } + return length ? baseFlatten(array, isDeep) : []; + } + + /** + * Recursively flattens a nested array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to recursively flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, 3, [4]]]); + * // => [1, 2, 3, 4] + */ + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, true) : []; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it is used as the offset + * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` + * performs a faster binary search. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // using `fromIndex` + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + * + * // performing a binary search + * _.indexOf([1, 1, 2, 2], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; + } else if (fromIndex) { + var index = binaryIndex(array, value); + if (index < length && + (value === value ? (value === array[index]) : (array[index] !== array[index]))) { + return index; + } + return -1; + } + return baseIndexOf(array, value, fromIndex || 0); + } + + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ + function initial(array) { + return dropRight(array, 1); + } + + /** + * Creates an array of unique values that are included in all of the provided + * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of shared values. + * @example + * _.intersection([1, 2], [4, 2], [2, 1]); + * // => [2] + */ + var intersection = restParam(function(arrays) { + var othLength = arrays.length, + othIndex = othLength, + caches = Array(length), + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + result = []; + + while (othIndex--) { + var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; + caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; + } + var array = arrays[0], + index = -1, + length = array ? array.length : 0, + seen = caches[0]; + + outer: + while (++index < length) { + value = array[index]; + if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { + var othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { + continue outer; + } + } + if (seen) { + seen.push(value); + } + result.push(value); + } + } + return result; + }); + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; + } + + /** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=array.length-1] The index to search from + * or `true` to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // using `fromIndex` + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + * + * // performing a binary search + * _.lastIndexOf([1, 1, 2, 2], 2, true); + * // => 3 + */ + function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; + } else if (fromIndex) { + index = binaryIndex(array, value, true) - 1; + var other = array[index]; + if (value === value ? (value === other) : (other !== other)) { + return index; + } + return -1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.without`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull() { + var args = arguments, + array = args[0]; + + if (!(array && array.length)) { + return array; + } + var index = 0, + indexOf = getIndexOf(), + length = args.length; + + while (++index < length) { + var fromIndex = 0, + value = args[index]; + + while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { + splice.call(array, fromIndex, 1); + } + } + return array; + } + + /** + * Removes elements from `array` corresponding to the given indexes and returns + * an array of the removed elements. Indexes may be specified as an array of + * indexes or as individual arguments. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove, + * specified as individual indexes or arrays of indexes. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [5, 10, 15, 20]; + * var evens = _.pullAt(array, 1, 3); + * + * console.log(array); + * // => [5, 15] + * + * console.log(evens); + * // => [10, 20] + */ + var pullAt = restParam(function(array, indexes) { + indexes = baseFlatten(indexes); + + var result = baseAt(array, indexes); + basePullAt(array, indexes.sort(baseCompareAscending)); + return result; + }); + + /** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * **Note:** Unlike `_.filter`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ + function remove(array, predicate, thisArg) { + var result = []; + if (!(array && array.length)) { + return result; + } + var index = -1, + indexes = [], + length = array.length; + + predicate = getCallback(predicate, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); + return result; + } + + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @alias tail + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + */ + function rest(array) { + return drop(array, 1); + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of `Array#slice` to support node + * lists in IE < 9 and to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + return baseSlice(array, start, end); + } + + /** + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. If an iteratee + * function is provided it is invoked for `value` and each element of `array` + * to compute their sort ranking. The iteratee is bound to `thisArg` and + * invoked with one argument; (value). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 4, 5, 5], 5); + * // => 2 + * + * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; + * + * // using an iteratee function + * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { + * return this.data[word]; + * }, dict); + * // => 1 + * + * // using the `_.property` callback shorthand + * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 1 + */ + var sortedIndex = createSortedIndex(); + + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 4, 5, 5], 5); + * // => 4 + */ + var sortedLastIndex = createSortedIndex(true); + + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ + function take(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ + function takeRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is bound to `thisArg` + * and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [2, 3] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active'), 'user'); + * // => [] + */ + function takeRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) + : []; + } + + /** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [1, 2] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false}, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeWhile(users, 'active', false), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeWhile(users, 'active'), 'user'); + * // => [] + */ + function takeWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3)) + : []; + } + + /** + * Creates an array of unique values, in order, from all of the provided arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([1, 2], [4, 2], [2, 1]); + * // => [1, 2, 4] + */ + var union = restParam(function(arrays) { + return baseUniq(baseFlatten(arrays, false, true)); + }); + + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurence of each element + * is kept. Providing `true` for `isSorted` performs a faster search algorithm + * for sorted arrays. If an iteratee function is provided it is invoked for + * each element in the array to generate the criterion by which uniqueness + * is computed. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index, array). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Array + * @param {Array} array The array to inspect. + * @param {boolean} [isSorted] Specify the array is sorted. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new duplicate-value-free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + * + * // using `isSorted` + * _.uniq([1, 1, 2], true); + * // => [1, 2] + * + * // using an iteratee function + * _.uniq([1, 2.5, 1.5, 2], function(n) { + * return this.floor(n); + * }, Math); + * // => [1, 2.5] + * + * // using the `_.property` callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (isSorted != null && typeof isSorted != 'boolean') { + thisArg = iteratee; + iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; + isSorted = false; + } + var callback = getCallback(); + if (!(iteratee == null && callback === baseCallback)) { + iteratee = callback(iteratee, thisArg, 3); + } + return (isSorted && getIndexOf() == baseIndexOf) + ? sortedUniq(array, iteratee) + : baseUniq(array, iteratee); + } + + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + * + * _.unzip(zipped); + * // => [['fred', 'barney'], [30, 40], [true, false]] + */ + function unzip(array) { + if (!(array && array.length)) { + return []; + } + var index = -1, + length = 0; + + array = arrayFilter(array, function(group) { + if (isArrayLike(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + var result = Array(length); + while (++index < length) { + result[index] = arrayMap(array, baseProperty(index)); + } + return result; + } + + /** + * This method is like `_.unzip` except that it accepts an iteratee to specify + * how regrouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee] The function to combine regrouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ + function unzipWith(array, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + iteratee = bindCallback(iteratee, thisArg, 4); + return arrayMap(result, function(group) { + return arrayReduce(group, iteratee, undefined, true); + }); + } + + /** + * Creates an array excluding all provided values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to filter. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.without([1, 2, 1, 3], 1, 2); + * // => [3] + */ + var without = restParam(function(array, values) { + return isArrayLike(array) + ? baseDifference(array, values) + : []; + }); + + /** + * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the provided arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xor([1, 2], [4, 2]); + * // => [1, 4] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArrayLike(array)) { + var result = result + ? arrayPush(baseDifference(result, array), baseDifference(array, result)) + : array; + } + } + return result ? baseUniq(result) : []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second elements + * of the given arrays, and so on. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + var zip = restParam(unzip); + + /** + * The inverse of `_.pairs`; this method returns an object composed from arrays + * of property names and values. Provide either a single two dimensional array, + * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names + * and one of corresponding values. + * + * @static + * @memberOf _ + * @alias object + * @category Array + * @param {Array} props The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(props, values) { + var index = -1, + length = props ? props.length : 0, + result = {}; + + if (length && !values && !isArray(props[0])) { + values = []; + } + while (++index < length) { + var key = props[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /** + * This method is like `_.zip` except that it accepts an iteratee to specify + * how grouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee] The function to combine grouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], _.add); + * // => [111, 222] + */ + var zipWith = restParam(function(arrays) { + var length = arrays.length, + iteratee = length > 2 ? arrays[length - 2] : undefined, + thisArg = length > 1 ? arrays[length - 1] : undefined; + + if (length > 2 && typeof iteratee == 'function') { + length -= 2; + } else { + iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; + thisArg = undefined; + } + arrays.length = length; + return unzipWith(arrays, iteratee, thisArg); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object that wraps `value` with explicit method + * chaining enabled. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _.chain(users) + * .sortBy('age') + * .map(function(chr) { + * return chr.user + ' is ' + chr.age; + * }) + * .first() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor is + * bound to `thisArg` and invoked with one argument; (value). The purpose of + * this method is to "tap into" a method chain in order to perform operations + * on intermediate results within the chain. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor, thisArg) { + interceptor.call(thisArg, value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor, thisArg) { + return interceptor.call(thisArg, value); + } + + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // without explicit chaining + * _(users).first(); + * // => { 'user': 'barney', 'age': 36 } + * + * // with explicit chaining + * _(users).chain() + * .first() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); + } + + /** + * Creates a new array joining a wrapped array with any additional arrays + * and/or values. + * + * @name concat + * @memberOf _ + * @category Chain + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var wrapped = _(array).concat(2, [3], [[4]]); + * + * console.log(wrapped.value()); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + var wrapperConcat = restParam(function(values) { + values = baseFlatten(values); + return this.thru(function(array) { + return arrayConcat(isArray(array) ? array : [toObject(array)], values); + }); + }); + + /** + * Creates a clone of the chained sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).map(function(value) { + * return Math.pow(value, 2); + * }); + * + * var other = [3, 4]; + * var otherWrapped = wrapped.plant(other); + * + * otherWrapped.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ + function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; + } + + /** + * Reverses the wrapped array so the first element becomes the last, the + * second element becomes the second to last, and so on. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new reversed `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function wrapperReverse() { + var value = this.__wrapped__; + + var interceptor = function(value) { + return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse(); + }; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + return new LodashWrapper(wrapped, this.__chain__); + } + return this.thru(interceptor); + } + + /** + * Produces the result of coercing the unwrapped value to a string. + * + * @name toString + * @memberOf _ + * @category Chain + * @returns {string} Returns the coerced string value. + * @example + * + * _([1, 2, 3]).toString(); + * // => '1,2,3' + */ + function wrapperToString() { + return (this.value() + ''); + } + + /** + * Executes the chained sequence to extract the unwrapped value. + * + * @name value + * @memberOf _ + * @alias run, toJSON, valueOf + * @category Chain + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements corresponding to the given keys, or indexes, + * of `collection`. Keys may be specified as individual arguments or as arrays + * of keys. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [props] The property names + * or indexes of elements to pick, specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * _.at(['a', 'b', 'c'], [0, 2]); + * // => ['a', 'c'] + * + * _.at(['barney', 'fred', 'pebbles'], 0, 2); + * // => ['barney', 'pebbles'] + */ + var at = restParam(function(collection, props) { + return baseAt(collection, baseFlatten(props)); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the number of times the key was returned by `iteratee`. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); + }); + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * The predicate is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.every(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.filter([4, 5, 6], function(n) { + * return n % 2 == 0; + * }); + * // => [4, 6] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.filter(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.filter(users, 'active'), 'user'); + * // => ['barney'] + */ + function filter(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, predicate); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias detect + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.result(_.find(users, function(chr) { + * return chr.age < 40; + * }), 'user'); + * // => 'barney' + * + * // using the `_.matches` callback shorthand + * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.result(_.find(users, 'active', false), 'user'); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.result(_.find(users, 'active'), 'user'); + * // => 'barney' + */ + var find = createFind(baseEach); + + /** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ + var findLast = createFind(baseEachRight, true); + + /** + * Performs a deep comparison between each element in `collection` and the + * source object, returning the first element that has equivalent property + * values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); + * // => 'barney' + * + * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); + * // => 'fred' + */ + function findWhere(collection, source) { + return find(collection, baseMatches(source)); + } + + /** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). Iteratee functions may exit iteration early + * by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEach(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from left to right and returns the array + * + * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { + * console.log(n, key); + * }); + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) + */ + var forEach = createForEach(arrayEach, baseEach); + + /** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEachRight(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from right to left and returns the array + */ + var forEachRight = createForEach(arrayEachRight, baseEachRight); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using the `_.property` callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } + }); + + /** + * Checks if `value` is in `collection` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it is used as the offset + * from the end of `collection`. + * + * @static + * @memberOf _ + * @alias contains, include + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} target The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {boolean} Returns `true` if a matching element is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); + * // => true + */ + function includes(collection, target, fromIndex, guard) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + collection = values(collection); + length = collection.length; + } + if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { + fromIndex = 0; + } else { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); + } + return (typeof collection == 'string' || !isArray(collection) && isString(collection)) + ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) + : (!!length && getIndexOf(collection, target, fromIndex) > -1); + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keyData = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keyData, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return String.fromCharCode(object.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return this.fromCharCode(object.code); + * }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `methodName` is a function it is + * invoked for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + var invoke = restParam(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); + result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); + }); + return result; + }); + + /** + * Creates an array of values by running each element in `collection` through + * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, + * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, + * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, + * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, + * `sum`, `uniq`, and `words` + * + * @static + * @memberOf _ + * @alias collect + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new mapped array. + * @example + * + * function timesThree(n) { + * return n * 3; + * } + * + * _.map([1, 2], timesThree); + * // => [3, 6] + * + * _.map({ 'a': 1, 'b': 2 }, timesThree); + * // => [3, 6] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // using the `_.property` callback shorthand + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee, thisArg) { + var func = isArray(collection) ? arrayMap : baseMap; + iteratee = getCallback(iteratee, thisArg, 3); + return func(collection, iteratee); + } + + /** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, while the second of which + * contains elements `predicate` returns falsey for. The predicate is bound + * to `thisArg` and invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * _.partition([1, 2, 3], function(n) { + * return n % 2; + * }); + * // => [[1, 3], [2]] + * + * _.partition([1.2, 2.3, 3.4], function(n) { + * return this.floor(n) % 2; + * }, Math); + * // => [[1.2, 3.4], [2.3]] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * var mapper = function(array) { + * return _.pluck(array, 'user'); + * }; + * + * // using the `_.matches` callback shorthand + * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); + * // => [['pebbles'], ['barney', 'fred']] + * + * // using the `_.matchesProperty` callback shorthand + * _.map(_.partition(users, 'active', false), mapper); + * // => [['barney', 'pebbles'], ['fred']] + * + * // using the `_.property` callback shorthand + * _.map(_.partition(users, 'active'), mapper); + * // => [['fred'], ['barney', 'pebbles']] + */ + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); + + /** + * Gets the property value of `path` from all elements in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|string} path The path of the property to pluck. + * @returns {Array} Returns the property values. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.pluck(users, 'user'); + * // => ['barney', 'fred'] + * + * var userIndex = _.indexBy(users, 'user'); + * _.pluck(userIndex, 'age'); + * // => [36, 40] (iteration order is not guaranteed) + */ + function pluck(collection, path) { + return map(collection, property(path)); + } + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not provided the first element of `collection` is used as the initial + * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, + * and `sortByOrder` + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.reduce([1, 2], function(total, n) { + * return total + n; + * }); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) + */ + var reduce = createReduce(arrayReduce, baseEach); + + /** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + var reduceRight = createReduce(arrayReduceRight, baseEachRight); + + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.reject([1, 2, 3, 4], function(n) { + * return n % 2 == 0; + * }); + * // => [1, 3] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.reject(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.reject(users, 'active'), 'user'); + * // => ['barney'] + */ + function reject(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, function(value, index, collection) { + return !predicate(value, index, collection); + }); + } + + /** + * Gets a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {*} Returns the random sample(s). + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (guard ? isIterateeCall(collection, n, guard) : n == null) { + collection = toIterable(collection); + var length = collection.length; + return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; + } + var index = -1, + result = toArray(collection), + length = result.length, + lastIndex = length - 1; + + n = nativeMin(n < 0 ? 0 : (+n || 0), length); + while (++index < n) { + var rand = baseRandom(index, lastIndex), + value = result[rand]; + + result[rand] = result[index]; + result[index] = value; + } + result.length = n; + return result; + } + + /** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ + function shuffle(collection) { + return sample(collection, POSITIVE_INFINITY); + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the size of `collection`. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? getLength(collection) : 0; + return isLength(length) ? length : keys(collection).length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * The function returns as soon as it finds a passing value and does not iterate + * over the entire collection. The predicate is bound to `thisArg` and invoked + * with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.some(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, thisArg) { + var func = isArray(collection) ? arraySome : baseSome; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through `iteratee`. This method performs + * a stable sort, that is, it preserves the original sort order of equal elements. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new sorted array. + * @example + * + * _.sortBy([1, 2, 3], function(n) { + * return Math.sin(n); + * }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(n) { + * return this.sin(n); + * }, Math); + * // => [3, 1, 2] + * + * var users = [ + * { 'user': 'fred' }, + * { 'user': 'pebbles' }, + * { 'user': 'barney' } + * ]; + * + * // using the `_.property` callback shorthand + * _.pluck(_.sortBy(users, 'user'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function sortBy(collection, iteratee, thisArg) { + if (collection == null) { + return []; + } + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; + } + var index = -1; + iteratee = getCallback(iteratee, thisArg, 3); + + var result = baseMap(collection, function(value, key, collection) { + return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; + }); + return baseSortBy(result, compareAscending); + } + + /** + * This method is like `_.sortBy` except that it can sort by multiple iteratees + * or property names. + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees + * The iteratees to sort by, specified as individual values or arrays of values. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.map(_.sortByAll(users, ['user', 'age']), _.values); + * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.map(_.sortByAll(users, 'user', function(chr) { + * return Math.floor(chr.age / 10); + * }), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + var sortByAll = restParam(function(collection, iteratees) { + if (collection == null) { + return []; + } + var guard = iteratees[2]; + if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { + iteratees.length = 1; + } + return baseSortByOrder(collection, baseFlatten(iteratees), []); + }); + + /** + * This method is like `_.sortByAll` except that it allows specifying the + * sort orders of the iteratees to sort by. If `orders` is unspecified, all + * values are sorted in ascending order. Otherwise, a value is sorted in + * ascending order if its corresponding order is "asc", and descending if "desc". + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // sort by `user` in ascending order and by `age` in descending order + * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + function sortByOrder(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (guard && isIterateeCall(iteratees, orders, guard)) { + orders = undefined; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseSortByOrder(collection, iteratees, orders); + } + + /** + * Performs a deep comparison between each element in `collection` and the + * source object, returning an array of all elements that have equivalent + * property values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); + * // => ['barney'] + * + * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); + * // => ['fred'] + */ + function where(collection, source) { + return filter(collection, baseMatches(source)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Date + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => logs the number of milliseconds it took for the deferred function to be invoked + */ + var now = nativeNow || function() { + return new Date().getTime(); + }; + + /*------------------------------------------------------------------------*/ + + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it is called `n` or more times. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'done saving!' after the two async saves have completed + */ + function after(n, func) { + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + n = nativeIsFinite(n = +n) ? n : 0; + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that accepts up to `n` arguments ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ + function ary(func, n, guard) { + if (guard && isIterateeCall(func, n, guard)) { + n = undefined; + } + n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); + } + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it is called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery('#add').on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method does not set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // using placeholders + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = restParam(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bind.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(func, bitmask, thisArg, partials, holders); + }); + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all enumerable function + * properties, own and inherited, of `object` are bound. + * + * **Note:** This method does not set the "length" property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} [methodNames] The object method names to bind, + * specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { + * console.log('clicked ' + this.label); + * } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs' when the element is clicked + */ + var bindAll = restParam(function(object, methodNames) { + methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); + + var index = -1, + length = methodNames.length; + + while (++index < length) { + var key = methodNames[index]; + object[key] = createWrapper(object[key], BIND_FLAG, object); + } + return object; + }); + + /** + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. + * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // using placeholders + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ + var bindKey = restParam(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bindKey.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(key, bitmask, object, partials, holders); + }); + + /** + * Creates a function that accepts one or more arguments of `func` that when + * called either invokes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` may be specified + * if `func.length` is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ + var curry = createCurry(CURRY_FLAG); + + /** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ + var curryRight = createCurry(CURRY_RIGHT_FLAG); + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. + * Subsequent calls to the debounced function return the result of the last + * `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify invoking on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it is invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // invoke `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // ensure `batchLog` is invoked once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * jQuery(source).on('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * })); + * + * // cancel a debounced call + * var todoChanges = _.debounce(batchLog, 1000); + * Object.observe(models.todo, todoChanges); + * + * Object.observe(models, function(changes) { + * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { + * todoChanges.cancel(); + * } + * }, ['delete']); + * + * // ...at some point `models.todo` is changed + * models.todo.completed = true; + * + * // ...before 1 second has passed `models.todo` is deleted + * // which cancels the debounced `todoChanges` call + * delete models.todo; + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = wait < 0 ? 0 : (+wait || 0); + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = !!options.leading; + maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + lastCalled = 0; + maxTimeoutId = timeoutId = trailingCall = undefined; + } + + function complete(isCalled, id) { + if (id) { + clearTimeout(id); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + } + } + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + complete(trailingCall, maxTimeoutId); + } else { + timeoutId = setTimeout(delayed, remaining); + } + } + + function maxDelayed() { + complete(trailing, timeoutId); + } + + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0 || remaining > maxWait; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + return result; + } + debounced.cancel = cancel; + return debounced; + } + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + var defer = restParam(function(func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second + */ + var delay = restParam(function(func, wait, args) { + return baseDelay(func, wait, args); + }); + + /** + * Creates a function that returns the result of invoking the provided + * functions with the `this` binding of the created function, where each + * successive invocation is supplied the return value of the previous. + * + * @static + * @memberOf _ + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow(_.add, square); + * addSquare(1, 2); + * // => 9 + */ + var flow = createFlow(); + + /** + * This method is like `_.flow` except that it creates a function that + * invokes the provided functions from right to left. + * + * @static + * @memberOf _ + * @alias backflow, compose + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flowRight(square, _.add); + * addSquare(1, 2); + * // => 9 + */ + var flowRight = createFlow(true); + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is coerced to a string and used as the + * cache key. The `func` is invoked with the `this` binding of the memoized + * function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) + * method interface of `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var upperCase = _.memoize(function(string) { + * return string.toUpperCase(); + * }); + * + * upperCase('fred'); + * // => 'FRED' + * + * // modifying the result cache + * upperCase.cache.set('fred', 'BARNEY'); + * upperCase('fred'); + * // => 'BARNEY' + * + * // replacing `_.memoize.Cache` + * var object = { 'user': 'fred' }; + * var other = { 'user': 'barney' }; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'fred' } + * + * _.memoize.Cache = WeakMap; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'barney' } + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result); + return result; + }; + memoized.cache = new memoize.Cache; + return memoized; + } + + /** + * Creates a function that runs each argument through a corresponding + * transform function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms] The functions to transform + * arguments, specified as individual functions or arrays of functions. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var modded = _.modArgs(function(x, y) { + * return [x, y]; + * }, square, doubled); + * + * modded(1, 2); + * // => [1, 4] + * + * modded(5, 10); + * // => [25, 20] + */ + var modArgs = restParam(function(func, transforms) { + transforms = baseFlatten(transforms); + if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = transforms.length; + return restParam(function(args) { + var index = nativeMin(args.length, length); + while (index--) { + args[index] = transforms[index](args[index]); + } + return func.apply(this, args); + }); + }); + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first call. The `func` is invoked + * with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once + */ + function once(func) { + return before(2, func); + } + + /** + * Creates a function that invokes `func` with `partial` arguments prepended + * to those provided to the new function. This method is like `_.bind` except + * it does **not** alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // using placeholders + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ + var partial = createPartial(PARTIAL_FLAG); + + /** + * This method is like `_.partial` except that partially applied arguments + * are appended to those provided to the new function. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // using placeholders + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ + var partialRight = createPartial(PARTIAL_RIGHT_FLAG); + + /** + * Creates a function that invokes `func` with arguments arranged according + * to the specified indexes where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes, + * specified as individual indexes or arrays of indexes. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, 2, 0, 1); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + * + * var map = _.rearg(_.map, [1, 0]); + * map(function(n) { + * return n * 3; + * }, [1, 2, 3]); + * // => [3, 6, 9] + */ + var rearg = restParam(function(func, indexes) { + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); + }); + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.restParam(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function restParam(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); + + while (++index < length) { + rest[index] = args[start + index]; + } + switch (start) { + case 0: return func.call(this, rest); + case 1: return func.call(this, args[0], rest); + case 2: return func.call(this, args[0], args[1], rest); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of the created + * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). + * + * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to spread arguments over. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * // with a Promise + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ + function spread(func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function(array) { + return func.apply(this, array); + }; + } + + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed invocations. Provide an options object to indicate + * that `func` should be invoked on the leading and/or trailing edge of the + * `wait` timeout. Subsequent calls to the throttled function return the + * result of the last `func` call. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify invoking on the leading + * edge of the timeout. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + * + * // cancel a trailing throttled call + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Any additional arguments provided to the function are + * appended to those provided to the wrapper function. The wrapper is invoked + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

' + func(text) + '

'; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

fred, barney, & pebbles

' + */ + function wrap(value, wrapper) { + wrapper = wrapper == null ? identity : wrapper; + return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, + * otherwise they are assigned by reference. If `customizer` is provided it is + * invoked to produce the cloned values. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is bound to + * `thisArg` and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the cloned value. + * @example + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var shallow = _.clone(users); + * shallow[0] === users[0]; + * // => true + * + * var deep = _.clone(users, true); + * deep[0] === users[0]; + * // => false + * + * // using a customizer callback + * var el = _.clone(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, customizer, thisArg) { + if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { + isDeep = false; + } + else if (typeof isDeep == 'function') { + thisArg = customizer; + customizer = isDeep; + isDeep = false; + } + return typeof customizer == 'function' + ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 1)) + : baseClone(value, isDeep); + } + + /** + * Creates a deep clone of `value`. If `customizer` is provided it is invoked + * to produce the cloned values. If `customizer` returns `undefined` cloning + * is handled by the method instead. The `customizer` is bound to `thisArg` + * and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var deep = _.cloneDeep(users); + * deep[0] === users[0]; + * // => false + * + * // using a customizer callback + * var el = _.cloneDeep(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 20 + */ + function cloneDeep(value, customizer, thisArg) { + return typeof customizer == 'function' + ? baseClone(value, true, bindCallback(customizer, thisArg, 1)) + : baseClone(value, true); + } + + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ + function gt(value, other) { + return value > other; + } + + /** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ + function gte(value, other) { + return value >= other; + } + + /** + * Checks if `value` is classified as an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return isObjectLike(value) && isArrayLike(value) && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(function() { return arguments; }()); + * // => false + */ + var isArray = nativeIsArray || function(value) { + return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; + }; + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); + } + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + function isDate(value) { + return isObjectLike(value) && objToString.call(value) == dateTag; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ + function isElement(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); + } + + /** + * Checks if `value` is empty. A value is considered empty unless it is an + * `arguments` object, array, string, or jQuery-like collection with a length + * greater than `0` or an object with own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (value == null) { + return true; + } + if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || + (isObjectLike(value) && isFunction(value.splice)))) { + return !value.length; + } + return !keys(value).length; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. If `customizer` is provided it is invoked to compare values. + * If `customizer` returns `undefined` comparisons are handled by the method + * instead. The `customizer` is bound to `thisArg` and invoked with three + * arguments: (value, other [, index|key]). + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. Functions and DOM nodes + * are **not** supported. Provide a customizer function to extend support + * for comparing other values. + * + * @static + * @memberOf _ + * @alias eq + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * object == other; + * // => false + * + * _.isEqual(object, other); + * // => true + * + * // using a customizer callback + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqual(array, other, function(value, other) { + * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { + * return true; + * } + * }); + * // => true + */ + function isEqual(value, other, customizer, thisArg) { + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; + } + + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ + function isError(value) { + return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(10); + * // => true + * + * _.isFinite('10'); + * // => false + * + * _.isFinite(true); + * // => false + * + * _.isFinite(Object(10)); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 equivalents which return 'object' for typed array constructors. + return isObject(value) && objToString.call(value) == funcTag; + } + + /** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Performs a deep comparison between `object` and `source` to determine if + * `object` contains equivalent property values. If `customizer` is provided + * it is invoked to compare values. If `customizer` returns `undefined` + * comparisons are handled by the method instead. The `customizer` is bound + * to `thisArg` and invoked with three arguments: (value, other, index|key). + * + * **Note:** This method supports comparing properties of arrays, booleans, + * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions + * and DOM nodes are **not** supported. Provide a customizer function to extend + * support for comparing other values. + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.isMatch(object, { 'age': 40 }); + * // => true + * + * _.isMatch(object, { 'age': 36 }); + * // => false + * + * // using a customizer callback + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatch(object, source, function(value, other) { + * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; + * }); + * // => true + */ + function isMatch(object, source, customizer, thisArg) { + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + return baseIsMatch(object, getMatchData(source), customizer); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some host objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ + function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(fnToString.call(value)); + } + return isObjectLike(value) && reIsHostCtor.test(value); + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isNumber(8.4); + * // => true + * + * _.isNumber(NaN); + * // => true + * + * _.isNumber('8.4'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * **Note:** This method assumes objects created by the `Object` constructor + * have no inherited enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + var Ctor; + + // Exit early for non `Object` objects. + if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) || + (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { + return false; + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + var result; + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + baseForIn(value, function(subValue, key) { + result = key; + }); + return result === undefined || hasOwnProperty.call(value, result); + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + function isRegExp(value) { + return isObject(value) && objToString.call(value) == regexpTag; + } + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + function isTypedArray(value) { + return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + function lt(value, other) { + return value < other; + } + + /** + * Checks if `value` is less than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`. + * @example + * + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false + */ + function lte(value, other) { + return value <= other; + } + + /** + * Converts `value` to an array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * (function() { + * return _.toArray(arguments).slice(1); + * }(1, 2, 3)); + * // => [2, 3] + */ + function toArray(value) { + var length = value ? getLength(value) : 0; + if (!isLength(length)) { + return values(value); + } + if (!length) { + return []; + } + return arrayCopy(value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable + * properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return baseCopy(value, keysIn(value)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * overwrite property assignments of previous sources. If `customizer` is + * provided it is invoked to produce the merged values of the destination and + * source properties. If `customizer` returns `undefined` merging is handled + * by the method instead. The `customizer` is bound to `thisArg` and invoked + * with five arguments: (objectValue, sourceValue, key, object, source). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; + * + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; + * + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } + * + * // using a customizer callback + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(object, other, function(a, b) { + * if (_.isArray(a)) { + * return a.concat(b); + * } + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + */ + var merge = createAssigner(baseMerge); + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources overwrite property assignments of previous sources. + * If `customizer` is provided it is invoked to produce the assigned values. + * The `customizer` is bound to `thisArg` and invoked with five arguments: + * (objectValue, sourceValue, key, object, source). + * + * **Note:** This method mutates `object` and is based on + * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); + * // => { 'user': 'fred', 'age': 40 } + * + * // using a customizer callback + * var defaults = _.partialRight(_.assign, function(value, other) { + * return _.isUndefined(value) ? other : value; + * }); + * + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var assign = createAssigner(function(object, source, customizer) { + return customizer + ? assignWith(object, source, customizer) + : baseAssign(object, source); + }); + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties, guard) { + var result = baseCreate(prototype); + if (guard && isIterateeCall(prototype, properties, guard)) { + properties = undefined; + } + return properties ? baseAssign(result, properties) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var defaults = createDefaults(assign, assignDefaults); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); + * // => { 'user': { 'name': 'barney', 'age': 36 } } + * + */ + var defaultsDeep = createDefaults(merge, mergeDefaults); + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (iteration order is not guaranteed) + * + * // using the `_.matches` callback shorthand + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.findKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.findKey(users, 'active'); + * // => 'barney' + */ + var findKey = createFindKey(baseForOwn); + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles` assuming `_.findKey` returns `barney` + * + * // using the `_.matches` callback shorthand + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + var findLastKey = createFindKey(baseForOwnRight); + + /** + * Iterates over own and inherited enumerable properties of an object invoking + * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) + */ + var forIn = createForIn(baseFor); + + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' + */ + var forInRight = createForIn(baseForRight); + + /** + * Iterates over own enumerable properties of an object invoking `iteratee` + * for each property. The `iteratee` is bound to `thisArg` and invoked with + * three arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' and 'b' (iteration order is not guaranteed) + */ + var forOwn = createForOwn(baseForOwn); + + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' + */ + var forOwnRight = createForOwn(baseForOwnRight); + + /** + * Creates an array of function property names from all enumerable properties, + * own and inherited, of `object`. + * + * @static + * @memberOf _ + * @alias methods + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * _.functions(_); + * // => ['after', 'ary', 'assign', ...] + */ + function functions(object) { + return baseFunctions(object, keysIn(object)); + } + + /** + * Gets the property value at `path` of `object`. If the resolved value is + * `undefined` the `defaultValue` is used in its place. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, toPath(path), path + ''); + return result === undefined ? defaultValue : result; + } + + /** + * Checks if `path` is a direct property. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` is a direct property, else `false`. + * @example + * + * var object = { 'a': { 'b': { 'c': 3 } } }; + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true + */ + function has(object, path) { + if (object == null) { + return false; + } + var result = hasOwnProperty.call(object, path); + if (!result && !isKey(path)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + path = last(path); + result = hasOwnProperty.call(object, path); + } + return result || (isLength(object.length) && isIndex(path, object.length) && + (isArray(object) || isArguments(object))); + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite property + * assignments of previous values unless `multiValue` is `true`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @param {boolean} [multiValue] Allow multiple values per key. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + * + * // with `multiValue` + * _.invert(object, true); + * // => { '1': ['a', 'c'], '2': ['b'] } + */ + function invert(object, multiValue, guard) { + if (guard && isIterateeCall(object, multiValue, guard)) { + multiValue = undefined; + } + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index], + value = object[key]; + + if (multiValue) { + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + } + else { + result[value] = key; + } + } + return result; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + var keys = !nativeKeys ? shimKeys : function(object) { + var Ctor = object == null ? undefined : object.constructor; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && isArrayLike(object))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; + }; + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || isArguments(object)) && length) || 0; + + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; + + while (++index < length) { + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * property of `object` through `iteratee`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + var mapKeys = createObjectMapper(true); + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through `iteratee`. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, key, object). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { + * return n * 3; + * }); + * // => { 'a': 3, 'b': 6 } + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * // using the `_.property` callback shorthand + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + var mapValues = createObjectMapper(); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable properties of `object` that are not omitted. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to omit, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.omit(object, 'age'); + * // => { 'user': 'fred' } + * + * _.omit(object, _.isNumber); + * // => { 'user': 'fred' } + */ + var omit = restParam(function(object, props) { + if (object == null) { + return {}; + } + if (typeof props[0] != 'function') { + var props = arrayMap(baseFlatten(props), String); + return pickByArray(object, baseDifference(keysIn(object), props)); + } + var predicate = bindCallback(props[0], props[1], 3); + return pickByCallback(object, function(value, key, object) { + return !predicate(value, key, object); + }); + }); + + /** + * Creates a two dimensional array of the key-value pairs for `object`, + * e.g. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) + */ + function pairs(object) { + object = toObject(object); + + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates an object composed of the picked `object` properties. Property + * names may be specified as individual arguments or as arrays of property + * names. If `predicate` is provided it is invoked for each property of `object` + * picking the properties `predicate` returns truthy for. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.pick(object, 'user'); + * // => { 'user': 'fred' } + * + * _.pick(object, _.isString); + * // => { 'user': 'fred' } + */ + var pick = restParam(function(object, props) { + if (object == null) { + return {}; + } + return typeof props[0] == 'function' + ? pickByCallback(object, bindCallback(props[0], props[1], 3)) + : pickByArray(object, baseFlatten(props)); + }); + + /** + * This method is like `_.get` except that if the resolved value is a function + * it is invoked with the `this` binding of its parent object and its result + * is returned. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a.b.c', 'default'); + * // => 'default' + * + * _.result(object, 'a.b.c', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + var result = object == null ? undefined : object[path]; + if (result === undefined) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + result = object == null ? undefined : object[last(path)]; + } + result = result === undefined ? defaultValue : result; + } + return isFunction(result) ? result.call(object) : result; + } + + /** + * Sets the property value of `path` on `object`. If a portion of `path` + * does not exist it is created. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to augment. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, 'x[0].y.z', 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + if (object == null) { + return object; + } + var pathKey = (path + ''); + path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = path[index]; + if (isObject(nested)) { + if (index == lastIndex) { + nested[key] = value; + } else if (nested[key] == null) { + nested[key] = isIndex(path[index + 1]) ? [] : {}; + } + } + nested = nested[key]; + } + return object; + } + + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own enumerable + * properties through `iteratee`, with each invocation potentially mutating + * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked + * with four arguments: (accumulator, value, key, object). Iteratee functions + * may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Array|Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * }); + * // => { 'a': 3, 'b': 6 } + */ + function transform(object, iteratee, accumulator, thisArg) { + var isArr = isArray(object) || isTypedArray(object); + iteratee = getCallback(iteratee, thisArg, 4); + + if (accumulator == null) { + if (isArr || isObject(object)) { + var Ctor = object.constructor; + if (isArr) { + accumulator = isArray(object) ? new Ctor : []; + } else { + accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined); + } + } else { + accumulator = {}; + } + } + (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + + /** + * Creates an array of the own enumerable property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return baseValues(object, keys(object)); + } + + /** + * Creates an array of the own and inherited enumerable property values + * of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ + function valuesIn(object) { + return baseValues(object, keysIn(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Checks if `n` is between `start` and up to but not including, `end`. If + * `end` is not specified it is set to `start` with `start` then set to `0`. + * + * @static + * @memberOf _ + * @category Number + * @param {number} n The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `n` is in the range, else `false`. + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + */ + function inRange(value, start, end) { + start = +start || 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = +end || 0; + } + return value >= nativeMin(start, end) && value < nativeMax(start, end); + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number is returned. + * If `floating` is `true`, or either `min` or `max` are floats, a floating-point + * number is returned instead of an integer. + * + * @static + * @memberOf _ + * @category Number + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + if (floating && isIterateeCall(min, max, floating)) { + max = floating = undefined; + } + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (noMax && typeof min == 'boolean') { + floating = min; + min = 1; + } + else if (typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + noMax = false; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max); + } + return baseRandom(min, max); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar'); + * // => 'fooBar' + * + * _.camelCase('__foo_bar__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); + }); + + /** + * Capitalizes the first character of `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('fred'); + * // => 'Fred' + */ + function capitalize(string) { + string = baseToString(string); + return string && (string.charAt(0).toUpperCase() + string.slice(1)); + } + + /** + * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = baseToString(string); + return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); + } + + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search from. + * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ + function endsWith(string, target, position) { + string = baseToString(string); + target = (target + ''); + + var length = string.length; + position = position === undefined + ? length + : nativeMin(position < 0 ? 0 : (+position || 0), length); + + position -= target.length; + return position >= 0 && string.indexOf(target, position) == position; + } + + /** + * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional characters + * use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in Internet Explorer < 9, they can break out + * of attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and + * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) + * for more details. + * + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + // Reset `lastIndex` because in IE < 9 `String#replace` does not. + string = baseToString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", + * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https:\/\/lodash\.com\/\)' + */ + function escapeRegExp(string) { + string = baseToString(string); + return (string && reHasRegExpChars.test(string)) + ? string.replace(reRegExpChars, escapeRegExpChar) + : (string || '(?:)'); + } + + /** + * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__foo_bar__'); + * // => 'foo-bar' + */ + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + + /** + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + function pad(string, length, chars) { + string = baseToString(string); + length = +length; + + var strLength = string.length; + if (strLength >= length || !nativeIsFinite(length)) { + return string; + } + var mid = (length - strLength) / 2, + leftLength = nativeFloor(mid), + rightLength = nativeCeil(mid); + + chars = createPadding('', rightLength, chars); + return chars.slice(0, leftLength) + string + chars; + } + + /** + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padLeft('abc', 6); + * // => ' abc' + * + * _.padLeft('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padLeft('abc', 3); + * // => 'abc' + */ + var padLeft = createPadDir(); + + /** + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padRight('abc', 6); + * // => 'abc ' + * + * _.padRight('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padRight('abc', 3); + * // => 'abc' + */ + var padRight = createPadDir(true); + + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, + * in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E) + * of `parseInt`. + * + * @static + * @memberOf _ + * @category String + * @param {string} string The string to convert. + * @param {number} [radix] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ + function parseInt(string, radix, guard) { + // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. + // Chrome fails to trim leading whitespace characters. + // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. + if (guard ? isIterateeCall(string, radix, guard) : radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + string = trim(string); + return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); + } + + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=0] The number of times to repeat the string. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ + function repeat(string, n) { + var result = ''; + string = baseToString(string); + n = +n; + if (n < 1 || !string || !nativeIsFinite(n)) { + return result; + } + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = nativeFloor(n / 2); + string += string; + } while (n); + + return result; + } + + /** + * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--foo-bar'); + * // => 'foo_bar' + */ + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + + /** + * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__foo_bar__'); + * // => 'Foo Bar' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); + }); + + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + function startsWith(string, target, position) { + string = baseToString(string); + position = position == null + ? 0 + : nativeMin(position < 0 ? 0 : (+position || 0), string.length); + + return string.lastIndexOf(target, position) == position; + } + + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is provided it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as free variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. + * @param {string} [options.variable] The data object variable name. + * @param- {Object} [otherOptions] Enables the legacy `options` param signature. + * @returns {Function} Returns the compiled template function. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // using the HTML "escape" delimiter to escape data property values + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': ' + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_script/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_script/artifact.xml new file mode 100644 index 0000000000..b0d2792a72 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_script/artifact.xml @@ -0,0 +1,23 @@ + + + + + AndriodDataScript.xml + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_event_sink/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_event_sink/artifact.xml new file mode 100644 index 0000000000..909b0cda2c --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_event_sink/artifact.xml @@ -0,0 +1,23 @@ + + + + + org_wso2_iot_android_data_stats.xml + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_event_sink/org_wso2_iot_android_data_stats.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_event_sink/org_wso2_iot_android_data_stats.xml new file mode 100755 index 0000000000..5ba15e500d --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_event_sink/org_wso2_iot_android_data_stats.xml @@ -0,0 +1,90 @@ + + + + + meta_owner + false + false + false + false + STRING + + + meta_deviceId + false + false + false + false + STRING + + + meta_timestamp + false + false + false + false + LONG + + + type + false + false + false + false + STRING + + + total + false + false + false + false + LONG + + + year + false + false + false + false + INTEGER + + + month + false + false + false + false + INTEGER + + + day + false + false + false + false + INTEGER + + + hour + false + false + false + false + INTEGER + + + minute + false + false + false + false + INTEGER + + + + org.wso2.iot.android.data.stats:1.0.0 + + false + EVENT_STORE + \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_streams/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_streams/artifact.xml new file mode 100644 index 0000000000..0bf9aaca5a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_streams/artifact.xml @@ -0,0 +1,23 @@ + + + + + org.wso2.iot.android.data.stats_1.0.0.json + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_streams/org.wso2.iot.android.data.stats_1.0.0.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_streams/org.wso2.iot.android.data.stats_1.0.0.json new file mode 100755 index 0000000000..50cc1660e6 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_stats_streams/org.wso2.iot.android.data.stats_1.0.0.json @@ -0,0 +1,50 @@ +{ + "name": "org.wso2.iot.android.data.stats", + "version": "1.0.0", + "nickName": "", + "description": "", + "metaData": [ + { + "name": "owner", + "type": "STRING" + }, + { + "name": "deviceId", + "type": "STRING" + }, + { + "name": "timestamp", + "type": "LONG" + } + ], + "payloadData": [ + { + "name": "type", + "type": "STRING" + }, + { + "name": "total", + "type": "LONG" + }, + { + "name": "year", + "type": "INT" + }, + { + "name": "month", + "type": "INT" + }, + { + "name": "day", + "type": "INT" + }, + { + "name": "hour", + "type": "INT" + }, + { + "name": "minute", + "type": "INT" + } + ] +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_streams/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_streams/artifact.xml new file mode 100644 index 0000000000..87fb993ac6 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_streams/artifact.xml @@ -0,0 +1,23 @@ + + + + + org.wso2.iot.android.data_1.0.0.json + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_streams/org.wso2.iot.android.data_1.0.0.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_streams/org.wso2.iot.android.data_1.0.0.json new file mode 100755 index 0000000000..1494f76818 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_streams/org.wso2.iot.android.data_1.0.0.json @@ -0,0 +1,34 @@ +{ + "name": "org.wso2.iot.android.data", + "version": "1.0.0", + "nickName": "", + "description": "", + "metaData": [ + { + "name": "owner", + "type": "STRING" + }, + { + "name": "deviceId", + "type": "STRING" + }, + { + "name": "timestamp", + "type": "LONG" + } + ], + "payloadData": [ + { + "name": "type", + "type": "STRING" + }, + { + "name": "received", + "type": "LONG" + }, + { + "name": "sent", + "type": "LONG" + } + ] +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_ui_event_publisher/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_ui_event_publisher/artifact.xml new file mode 100644 index 0000000000..b261b8a7be --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_ui_event_publisher/artifact.xml @@ -0,0 +1,23 @@ + + + + + org.wso2.iot.android.data.ui.publisher.xml + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_ui_event_publisher/org.wso2.iot.android.data.ui.publisher.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_ui_event_publisher/org.wso2.iot.android.data.ui.publisher.xml new file mode 100755 index 0000000000..72478f79cf --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_ui_event_publisher/org.wso2.iot.android.data.ui.publisher.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/conf.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/conf.json new file mode 100644 index 0000000000..7c74d53f78 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/conf.json @@ -0,0 +1 @@ +{"provider-conf" : {"tableName" : "ANDROID_DATA_STAT_PER_DAY", "query" : "", "limit" : "2", "provider-name" : "batch"}, "chart-conf" : {"x" : "total", "color" : "type", "maxLength" : "2", "gadget-name" : "Android Data Usage Chart", "chart-name" : "donut-chart"}} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/gadget-controller.jag b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/gadget-controller.jag new file mode 100644 index 0000000000..f84538a40a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/gadget-controller.jag @@ -0,0 +1,42 @@ +<% +/** + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +(function () { + + response.contentType = 'application/json'; + var PROVIDER_CONF = 'provider-conf'; + var PROVIDER_NAME = 'provider-name'; + + var action = request.getParameter("action"); + var data = request.getContent(); + var providerConf = data[PROVIDER_CONF]; + var providerAPI = require('js/core/' + providerConf[PROVIDER_NAME] + '-provider-api.js'); + + if (action === 'getSchema') { + print(providerAPI.getSchema(providerConf)); + return; + } else if(action === 'getData'){ + print(providerAPI.getData(providerConf)); + return; + } + +}()); + + +%> diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/gadget.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/gadget.json new file mode 100644 index 0000000000..aef316e3a3 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/gadget.json @@ -0,0 +1,9 @@ +{ + "id": "Android_Data_Usage_Chart", + "title": "Android Data Usage Chart", + "type": "gadget", + "thumbnail": "gadget/Android_Data_Usage_Chart/thumbnail.png", + "data": { + "url": "gadget/Android_Data_Usage_Chart/gadget.xml" + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/gadget.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/gadget.xml new file mode 100644 index 0000000000..93cc23bfeb --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/gadget.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ]]> +
+
diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/batch-provider-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/batch-provider-api.js new file mode 100644 index 0000000000..30c96902a5 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/batch-provider-api.js @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, getMode, getSchema, getData, registerCallBackforPush; + +(function() { + + var PROVIDERS_LOCATION = '/extensions/providers/'; + + var PROVIDER_NAME = 'batch'; + var TYPE = "type"; + var TABLE_NAME = "tableName"; + var HTTPS_TRANSPORT = "https"; + var CONTENT_TYPE_JSON = "application/json"; + var AUTHORIZATION_HEADER = "Authorization"; + var USER_TOKEN = "user"; + var TENANT_DOMAIN = "domain"; + var CONST_AT = "@"; + var USERNAME = "username"; + var HTTP_USER_NOT_AUTHENTICATED = 403; + var JS_MAX_VALUE = "9007199254740992"; + var JS_MIN_VALUE = "-9007199254740992"; + + var typeMap = { + "bool" : "string", + "boolean" : "string", + "string" : "string", + "int" : "number", + "integer" : "number", + "long" : "number", + "double" : "number", + "float" : "number", + "time": "time" + }; + + var log = new Log(); + var carbon = require('carbon'); + var configs = require('/configs/designer.json'); + var utils = require('/modules/utils.js'); + var JSUtils = Packages.org.wso2.carbon.analytics.jsservice.Utils; + var AnalyticsCachedJSServiceConnector = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector; + var AnalyticsCache = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector.AnalyticsCache; + var cacheTimeoutSeconds = 5; + var loggedInUser = null; + + if (configs.cacheTimeoutSeconds) { + cacheTimeoutSeconds = parseInt(configs.cacheTimeoutSeconds); + } + var cacheSizeBytes = 1024 * 1024 * 1024; // 1GB + if (configs.cacheSizeBytes) { + cacheSizeBytes = parseInt(configs.cacheSizeBytes); + } + response.contentType = CONTENT_TYPE_JSON; + + var authParam = request.getHeader(AUTHORIZATION_HEADER); + if (authParam != null) { + credentials = JSUtils.authenticate(authParam); + loggedInUser = credentials[0]; + } else { + var token = session.get(USER_TOKEN); + if (token != null) { + loggedInUser = token[USERNAME] + CONST_AT + token[TENANT_DOMAIN]; + } else { + log.error("user is not authenticated!"); + response.status = HTTP_USER_NOT_AUTHENTICATED; + print('{ "status": "Failed", "message": "User is not authenticated." }'); + return; + } + } + + var cache = application.get("AnalyticsWebServiceCache"); + if (cache == null) { + cache = new AnalyticsCache(cacheTimeoutSeconds, cacheSizeBytes); + application.put("AnalyticsWebServiceCache", cache); + } + var connector = new AnalyticsCachedJSServiceConnector(cache); + + /** + * require the existing config.json and push any dynamic fields that needs to be populated in the UI + */ + getConfig = function() { + var formConfig = require(PROVIDERS_LOCATION + '/' + PROVIDER_NAME + '/config.json'); + var tables; + try { + tables = JSON.parse(connector.getTableList(loggedInUser).getMessage()); + } catch (e) { + log.error(e); + } + var configs = formConfig.config; + configs.forEach(function(config) { + if (config.fieldName === TABLE_NAME) { + config.valueSet = tables; + } + }); + return formConfig; + } + + /** + * validate the user input of provider configuration + * @param providerConfig + */ + validate = function(providerConfig) { + /* + validate the form and return + + */ + return true; + } + + /** + * returns the data mode either push or pull + */ + getMode = function() { + return "PULL"; + } + + /** + * returns an array of column names & types + * @param providerConfig + */ + getSchema = function(providerConfig) { + var schema = []; + var tableName = providerConfig["tableName"]; + var result = connector.getTableSchema(loggedInUser, tableName).getMessage(); + result = JSON.parse(result); + + var columns = result.columns; + Object.getOwnPropertyNames(columns).forEach(function(name, idx, array) { + var type = "ordinal"; + if(columns[name]['type']) { + type = columns[name]['type']; + } + schema.push({ + fieldName: name, + fieldType: typeMap[type.toLowerCase()] + }); + }); + // log.info(schema); + return schema; + }; + + /** + * returns the actual data + * @param providerConfig + * @param limit + */ + getData = function(providerConfig, limit) { + var tableName = providerConfig.tableName; + var query = providerConfig.query; + var limit = 100; + if (providerConfig.limit) { + limit = providerConfig.limit; + } + var result; + //if there's a filter present, we should perform a Lucene search instead of reading the table + if (query) { + var filter = { + "query": query, + "start": 0, + "count": limit + }; + result = connector.search(loggedInUser, tableName, stringify(filter)).getMessage(); + } else { + var from = JS_MIN_VALUE; + var to = JS_MAX_VALUE; + result = connector.getRecordsByRange(loggedInUser, tableName, from, to, 0, limit, null).getMessage(); + + } + result = JSON.parse(result); + var data = []; + for (var i = 0; i < result.length; i++) { + var values = result[i].values; + data.push(values); + } + return data; + }; + +}()); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/donut-chart-api.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/donut-chart-api.js new file mode 100644 index 0000000000..88de63f20b --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/donut-chart-api.js @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getConfig, validate, isProviderRequired, draw, update; + +(function() { + + var CHART_LOCATION = '/extensions/chart-templates/'; + + /** + * return the config to be populated in the chart configuration UI + * @param schema + */ + getConfig = function(schema) { + var chartConf = require(CHART_LOCATION + '/donut-chart/config.json').config; + /* + dynamic logic goes here + */ + return chartConf; + + }; + + /** + * validate the user inout for the chart configuration + * @param chartConfig + */ + validate = function(chartConfig) { + return true; + }; + + /** + * TO be used when provider configuration steps need to be skipped + */ + isProviderRequired = function() { + + } + + + /** + * return the gadget content + * @param chartConfig + * @param schema + * @param data + */ + draw = function(placeholder, chartConfig, _schema, data) { + var schema = toVizGrammarSchema(_schema); + var view = { + id: "chart-0", + schema: schema, + chartConfig: buildChartConfig(chartConfig), + data: function() { + if(data) { + var result = []; + console.log(data); + data.forEach(function(item) { + var row = []; + schema[0].metadata.names.forEach(function(name) { + row.push(item[name]); + }); + result.push(row); + }); + console.log(result); + wso2gadgets.onDataReady(result); + } + } + + }; + + try { + wso2gadgets.init(placeholder, view); + var view = wso2gadgets.load("chart-0"); + } catch (e) { + console.error(e); + } + + }; + + /** + * + * @param data + */ + update = function(data) { + wso2gadgets.onDataReady(data,"append"); + } + + buildChartConfig = function (_chartConfig) { + var conf = {}; + conf.x = _chartConfig.x; + conf.maxLength = _chartConfig.maxLength; + conf.charts = []; + conf.charts[0] = { + type : "arc", + color: _chartConfig.color, + mode: "donut" + }; + conf.legendOffset = -30; + conf.colorScale = ["#50B432", "#6699ff"]; + return conf; + }; + + +}()); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/gadget-core.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/gadget-core.js new file mode 100644 index 0000000000..a4b3c7971a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/gadget-core.js @@ -0,0 +1,95 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +$(function () { + var gadgetLocation; + var conf; + var schema; + var pref = new gadgets.Prefs(); + + var refreshInterval; + var providerData; + + var CHART_CONF = 'chart-conf'; + var PROVIDER_CONF = 'provider-conf'; + + var REFRESH_INTERVAL = 'refreshInterval'; + +var init = function () { + $.ajax({ + url: gadgetLocation + '/conf.json', + method: "GET", + contentType: "application/json", + async: false, + success: function (data) { + conf = JSON.parse(data); + $.ajax({ + url: gadgetLocation + '/gadget-controller.jag?action=getSchema', + method: "POST", + data: JSON.stringify(conf), + contentType: "application/json", + async: false, + success: function (data) { + schema = data; + } + }); + + getProviderData(); + + } + }); +}; + +var getProviderData = function (){ + $.ajax({ + url: gadgetLocation + '/gadget-controller.jag?action=getData', + method: "POST", + data: JSON.stringify(conf), + contentType: "application/json", + async: false, + success: function (data) { + if(data.length == 2) { + if(data[0].timestamp == data[1].timestamp) { + providerData = data; + } else if(data[0].timestamp > data[1].timestamp) { + providerData = [data[0]]; + } else { + providerData = [data[1]]; + } + } else { + providerData = data; + } + } + }); + return providerData; +}; + + +var drawGadget = function (){ + + draw('#canvas', conf[CHART_CONF], schema, providerData); + setInterval(function() { + draw('#canvas', conf[CHART_CONF], schema, getProviderData()); + },pref.getInt(REFRESH_INTERVAL)); + +}; + +getGadgetLocation(function (gadget_Location) { + gadgetLocation = gadget_Location; + init(); + drawGadget(); + +}); +}); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/gadget-util.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/gadget-util.js new file mode 100644 index 0000000000..d9d71c2509 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/js/core/gadget-util.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var getGadgetLocation = function (callback) { + var gadgetLocation = "/portal/store/carbon.super/fs/gadget/Android_Data_Usage_Chart"; + var PATH_SEPERATOR = "/"; + if (gadgetLocation.search("store") != -1) { + wso2.gadgets.identity.getTenantDomain(function (tenantDomain) { + var gadgetPath = gadgetLocation.split(PATH_SEPERATOR); + var modifiedPath = ''; + for (var i = 1; i < gadgetPath.length; i++) { + if (i === 3) { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, tenantDomain); + } else { + modifiedPath = modifiedPath.concat(PATH_SEPERATOR, gadgetPath[i]) + } + } + callback(modifiedPath); + }); + } else { + callback(gadgetLocation); + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/thumbnail.png b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_data_usage_chart_gadget/Android_Data_Usage_Chart/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..663d63900b53c15e83a006388540f0163c457507 GIT binary patch literal 11569 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 + + + + Android_Data_Usage_Chart + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/artifact.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/artifact.xml new file mode 100644 index 0000000000..18a7c53565 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/artifact.xml @@ -0,0 +1,23 @@ + + + + + date-picker + + diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/css/bootstrap-datepicker.min.css b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/css/bootstrap-datepicker.min.css new file mode 100644 index 0000000000..679e25cc45 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/css/bootstrap-datepicker.min.css @@ -0,0 +1,8 @@ +/*! + * Datepicker for Bootstrap v1.4.0 (https://github.com/eternicode/bootstrap-datepicker) + * + * Copyright 2012 Stefan Petre + * Improvements by Andrew Rowls + * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) + */ +.datepicker{padding:4px;border-radius:4px;direction:ltr}.datepicker-inline{width:220px}.datepicker.datepicker-rtl{direction:rtl}.datepicker.datepicker-rtl table tr td span{float:right}.datepicker-dropdown{top:0;left:0}.datepicker-dropdown:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-top:0;border-bottom-color:rgba(0,0,0,.2);position:absolute}.datepicker-dropdown:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;border-top:0;position:absolute}.datepicker-dropdown.datepicker-orient-left:before{left:6px}.datepicker-dropdown.datepicker-orient-left:after{left:7px}.datepicker-dropdown.datepicker-orient-right:before{right:6px}.datepicker-dropdown.datepicker-orient-right:after{right:7px}.datepicker-dropdown.datepicker-orient-top:before{top:-7px}.datepicker-dropdown.datepicker-orient-top:after{top:-6px}.datepicker-dropdown.datepicker-orient-bottom:before{bottom:-7px;border-bottom:0;border-top:7px solid #999}.datepicker-dropdown.datepicker-orient-bottom:after{bottom:-6px;border-bottom:0;border-top:6px solid #fff}.datepicker>div{display:none}.datepicker.days .datepicker-days,.datepicker.months .datepicker-months,.datepicker.years .datepicker-years{display:block}.datepicker table{margin:0;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.datepicker table tr td,.datepicker table tr th{text-align:center;width:30px;height:30px;border-radius:4px;border:none}.table-striped .datepicker table tr td,.table-striped .datepicker table tr th{background-color:transparent}.datepicker table tr td.day:hover,.datepicker table tr td.day.focused{background:#eee;cursor:pointer}.datepicker table tr td.old,.datepicker table tr td.new{color:#999}.datepicker table tr td.disabled,.datepicker table tr td.disabled:hover{background:0 0;color:#999;cursor:default}.datepicker table tr td.today,.datepicker table tr td.today:hover,.datepicker table tr td.today.disabled,.datepicker table tr td.today.disabled:hover{color:#000;background-color:#ffdb99;border-color:#ffb733}.datepicker table tr td.today:hover,.datepicker table tr td.today:hover:hover,.datepicker table tr td.today.disabled:hover,.datepicker table tr td.today.disabled:hover:hover,.datepicker table tr td.today:focus,.datepicker table tr td.today:hover:focus,.datepicker table tr td.today.disabled:focus,.datepicker table tr td.today.disabled:hover:focus,.datepicker table tr td.today:active,.datepicker table tr td.today:hover:active,.datepicker table tr td.today.disabled:active,.datepicker table tr td.today.disabled:hover:active,.datepicker table tr td.today.active,.datepicker table tr td.today:hover.active,.datepicker table tr td.today.disabled.active,.datepicker table tr td.today.disabled:hover.active,.open .dropdown-toggle.datepicker table tr td.today,.open .dropdown-toggle.datepicker table tr td.today:hover,.open .dropdown-toggle.datepicker table tr td.today.disabled,.open .dropdown-toggle.datepicker table tr td.today.disabled:hover{color:#000;background-color:#ffcd70;border-color:#f59e00}.datepicker table tr td.today:active,.datepicker table tr td.today:hover:active,.datepicker table tr td.today.disabled:active,.datepicker table tr td.today.disabled:hover:active,.datepicker table tr td.today.active,.datepicker table tr td.today:hover.active,.datepicker table tr td.today.disabled.active,.datepicker table tr td.today.disabled:hover.active,.open .dropdown-toggle.datepicker table tr td.today,.open .dropdown-toggle.datepicker table tr td.today:hover,.open .dropdown-toggle.datepicker table tr td.today.disabled,.open .dropdown-toggle.datepicker table tr td.today.disabled:hover{background-image:none}.datepicker table tr td.today.disabled,.datepicker table tr td.today:hover.disabled,.datepicker table tr td.today.disabled.disabled,.datepicker table tr td.today.disabled:hover.disabled,.datepicker table tr td.today[disabled],.datepicker table tr td.today:hover[disabled],.datepicker table tr td.today.disabled[disabled],.datepicker table tr td.today.disabled:hover[disabled],fieldset[disabled] .datepicker table tr td.today,fieldset[disabled] .datepicker table tr td.today:hover,fieldset[disabled] .datepicker table tr td.today.disabled,fieldset[disabled] .datepicker table tr td.today.disabled:hover,.datepicker table tr td.today.disabled:hover,.datepicker table tr td.today:hover.disabled:hover,.datepicker table tr td.today.disabled.disabled:hover,.datepicker table tr td.today.disabled:hover.disabled:hover,.datepicker table tr td.today[disabled]:hover,.datepicker table tr td.today:hover[disabled]:hover,.datepicker table tr td.today.disabled[disabled]:hover,.datepicker table tr td.today.disabled:hover[disabled]:hover,fieldset[disabled] .datepicker table tr td.today:hover,fieldset[disabled] .datepicker table tr td.today:hover:hover,fieldset[disabled] .datepicker table tr td.today.disabled:hover,fieldset[disabled] .datepicker table tr td.today.disabled:hover:hover,.datepicker table tr td.today.disabled:focus,.datepicker table tr td.today:hover.disabled:focus,.datepicker table tr td.today.disabled.disabled:focus,.datepicker table tr td.today.disabled:hover.disabled:focus,.datepicker table tr td.today[disabled]:focus,.datepicker table tr td.today:hover[disabled]:focus,.datepicker table tr td.today.disabled[disabled]:focus,.datepicker table tr td.today.disabled:hover[disabled]:focus,fieldset[disabled] .datepicker table tr td.today:focus,fieldset[disabled] .datepicker table tr td.today:hover:focus,fieldset[disabled] .datepicker table tr td.today.disabled:focus,fieldset[disabled] .datepicker table tr td.today.disabled:hover:focus,.datepicker table tr td.today.disabled:active,.datepicker table tr td.today:hover.disabled:active,.datepicker table tr td.today.disabled.disabled:active,.datepicker table tr td.today.disabled:hover.disabled:active,.datepicker table tr td.today[disabled]:active,.datepicker table tr td.today:hover[disabled]:active,.datepicker table tr td.today.disabled[disabled]:active,.datepicker table tr td.today.disabled:hover[disabled]:active,fieldset[disabled] .datepicker table tr td.today:active,fieldset[disabled] .datepicker table tr td.today:hover:active,fieldset[disabled] .datepicker table tr td.today.disabled:active,fieldset[disabled] .datepicker table tr td.today.disabled:hover:active,.datepicker table tr td.today.disabled.active,.datepicker table tr td.today:hover.disabled.active,.datepicker table tr td.today.disabled.disabled.active,.datepicker table tr td.today.disabled:hover.disabled.active,.datepicker table tr td.today[disabled].active,.datepicker table tr td.today:hover[disabled].active,.datepicker table tr td.today.disabled[disabled].active,.datepicker table tr td.today.disabled:hover[disabled].active,fieldset[disabled] .datepicker table tr td.today.active,fieldset[disabled] .datepicker table tr td.today:hover.active,fieldset[disabled] .datepicker table tr td.today.disabled.active,fieldset[disabled] .datepicker table tr td.today.disabled:hover.active{background-color:#ffdb99;border-color:#ffb733}.datepicker table tr td.today:hover:hover{color:#000}.datepicker table tr td.today.active:hover{color:#fff}.datepicker table tr td.range,.datepicker table tr td.range:hover,.datepicker table tr td.range.disabled,.datepicker table tr td.range.disabled:hover{background:#eee;border-radius:0}.datepicker table tr td.range.today,.datepicker table tr td.range.today:hover,.datepicker table tr td.range.today.disabled,.datepicker table tr td.range.today.disabled:hover{color:#000;background-color:#f7ca77;border-color:#f1a417;border-radius:0}.datepicker table tr td.range.today:hover,.datepicker table tr td.range.today:hover:hover,.datepicker table tr td.range.today.disabled:hover,.datepicker table tr td.range.today.disabled:hover:hover,.datepicker table tr td.range.today:focus,.datepicker table tr td.range.today:hover:focus,.datepicker table tr td.range.today.disabled:focus,.datepicker table tr td.range.today.disabled:hover:focus,.datepicker table tr td.range.today:active,.datepicker table tr td.range.today:hover:active,.datepicker table tr td.range.today.disabled:active,.datepicker table tr td.range.today.disabled:hover:active,.datepicker table tr td.range.today.active,.datepicker table tr td.range.today:hover.active,.datepicker table tr td.range.today.disabled.active,.datepicker table tr td.range.today.disabled:hover.active,.open .dropdown-toggle.datepicker table tr td.range.today,.open .dropdown-toggle.datepicker table tr td.range.today:hover,.open .dropdown-toggle.datepicker table tr td.range.today.disabled,.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover{color:#000;background-color:#f4bb51;border-color:#bf800c}.datepicker table tr td.range.today:active,.datepicker table tr td.range.today:hover:active,.datepicker table tr td.range.today.disabled:active,.datepicker table tr td.range.today.disabled:hover:active,.datepicker table tr td.range.today.active,.datepicker table tr td.range.today:hover.active,.datepicker table tr td.range.today.disabled.active,.datepicker table tr td.range.today.disabled:hover.active,.open .dropdown-toggle.datepicker table tr td.range.today,.open .dropdown-toggle.datepicker table tr td.range.today:hover,.open .dropdown-toggle.datepicker table tr td.range.today.disabled,.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover{background-image:none}.datepicker table tr td.range.today.disabled,.datepicker table tr td.range.today:hover.disabled,.datepicker table tr td.range.today.disabled.disabled,.datepicker table tr td.range.today.disabled:hover.disabled,.datepicker table tr td.range.today[disabled],.datepicker table tr td.range.today:hover[disabled],.datepicker table tr td.range.today.disabled[disabled],.datepicker table tr td.range.today.disabled:hover[disabled],fieldset[disabled] .datepicker table tr td.range.today,fieldset[disabled] .datepicker table tr td.range.today:hover,fieldset[disabled] .datepicker table tr td.range.today.disabled,fieldset[disabled] .datepicker table tr td.range.today.disabled:hover,.datepicker table tr td.range.today.disabled:hover,.datepicker table tr td.range.today:hover.disabled:hover,.datepicker table tr td.range.today.disabled.disabled:hover,.datepicker table tr td.range.today.disabled:hover.disabled:hover,.datepicker table tr td.range.today[disabled]:hover,.datepicker table tr td.range.today:hover[disabled]:hover,.datepicker table tr td.range.today.disabled[disabled]:hover,.datepicker table tr td.range.today.disabled:hover[disabled]:hover,fieldset[disabled] .datepicker table tr td.range.today:hover,fieldset[disabled] .datepicker table tr td.range.today:hover:hover,fieldset[disabled] .datepicker table tr td.range.today.disabled:hover,fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover,.datepicker table tr td.range.today.disabled:focus,.datepicker table tr td.range.today:hover.disabled:focus,.datepicker table tr td.range.today.disabled.disabled:focus,.datepicker table tr td.range.today.disabled:hover.disabled:focus,.datepicker table tr td.range.today[disabled]:focus,.datepicker table tr td.range.today:hover[disabled]:focus,.datepicker table tr td.range.today.disabled[disabled]:focus,.datepicker table tr td.range.today.disabled:hover[disabled]:focus,fieldset[disabled] .datepicker table tr td.range.today:focus,fieldset[disabled] .datepicker table tr td.range.today:hover:focus,fieldset[disabled] .datepicker table tr td.range.today.disabled:focus,fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus,.datepicker table tr td.range.today.disabled:active,.datepicker table tr td.range.today:hover.disabled:active,.datepicker table tr td.range.today.disabled.disabled:active,.datepicker table tr td.range.today.disabled:hover.disabled:active,.datepicker table tr td.range.today[disabled]:active,.datepicker table tr td.range.today:hover[disabled]:active,.datepicker table tr td.range.today.disabled[disabled]:active,.datepicker table tr td.range.today.disabled:hover[disabled]:active,fieldset[disabled] .datepicker table tr td.range.today:active,fieldset[disabled] .datepicker table tr td.range.today:hover:active,fieldset[disabled] .datepicker table tr td.range.today.disabled:active,fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:active,.datepicker table tr td.range.today.disabled.active,.datepicker table tr td.range.today:hover.disabled.active,.datepicker table tr td.range.today.disabled.disabled.active,.datepicker table tr td.range.today.disabled:hover.disabled.active,.datepicker table tr td.range.today[disabled].active,.datepicker table tr td.range.today:hover[disabled].active,.datepicker table tr td.range.today.disabled[disabled].active,.datepicker table tr td.range.today.disabled:hover[disabled].active,fieldset[disabled] .datepicker table tr td.range.today.active,fieldset[disabled] .datepicker table tr td.range.today:hover.active,fieldset[disabled] .datepicker table tr td.range.today.disabled.active,fieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active{background-color:#f7ca77;border-color:#f1a417}.datepicker table tr td.selected,.datepicker table tr td.selected:hover,.datepicker table tr td.selected.disabled,.datepicker table tr td.selected.disabled:hover{color:#fff;background-color:#999;border-color:#555;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datepicker table tr td.selected:hover,.datepicker table tr td.selected:hover:hover,.datepicker table tr td.selected.disabled:hover,.datepicker table tr td.selected.disabled:hover:hover,.datepicker table tr td.selected:focus,.datepicker table tr td.selected:hover:focus,.datepicker table tr td.selected.disabled:focus,.datepicker table tr td.selected.disabled:hover:focus,.datepicker table tr td.selected:active,.datepicker table tr td.selected:hover:active,.datepicker table tr td.selected.disabled:active,.datepicker table tr td.selected.disabled:hover:active,.datepicker table tr td.selected.active,.datepicker table tr td.selected:hover.active,.datepicker table tr td.selected.disabled.active,.datepicker table tr td.selected.disabled:hover.active,.open .dropdown-toggle.datepicker table tr td.selected,.open .dropdown-toggle.datepicker table tr td.selected:hover,.open .dropdown-toggle.datepicker table tr td.selected.disabled,.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover{color:#fff;background-color:#858585;border-color:#373737}.datepicker table tr td.selected:active,.datepicker table tr td.selected:hover:active,.datepicker table tr td.selected.disabled:active,.datepicker table tr td.selected.disabled:hover:active,.datepicker table tr td.selected.active,.datepicker table tr td.selected:hover.active,.datepicker table tr td.selected.disabled.active,.datepicker table tr td.selected.disabled:hover.active,.open .dropdown-toggle.datepicker table tr td.selected,.open .dropdown-toggle.datepicker table tr td.selected:hover,.open .dropdown-toggle.datepicker table tr td.selected.disabled,.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover{background-image:none}.datepicker table tr td.selected.disabled,.datepicker table tr td.selected:hover.disabled,.datepicker table tr td.selected.disabled.disabled,.datepicker table tr td.selected.disabled:hover.disabled,.datepicker table tr td.selected[disabled],.datepicker table tr td.selected:hover[disabled],.datepicker table tr td.selected.disabled[disabled],.datepicker table tr td.selected.disabled:hover[disabled],fieldset[disabled] .datepicker table tr td.selected,fieldset[disabled] .datepicker table tr td.selected:hover,fieldset[disabled] .datepicker table tr td.selected.disabled,fieldset[disabled] .datepicker table tr td.selected.disabled:hover,.datepicker table tr td.selected.disabled:hover,.datepicker table tr td.selected:hover.disabled:hover,.datepicker table tr td.selected.disabled.disabled:hover,.datepicker table tr td.selected.disabled:hover.disabled:hover,.datepicker table tr td.selected[disabled]:hover,.datepicker table tr td.selected:hover[disabled]:hover,.datepicker table tr td.selected.disabled[disabled]:hover,.datepicker table tr td.selected.disabled:hover[disabled]:hover,fieldset[disabled] .datepicker table tr td.selected:hover,fieldset[disabled] .datepicker table tr td.selected:hover:hover,fieldset[disabled] .datepicker table tr td.selected.disabled:hover,fieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover,.datepicker table tr td.selected.disabled:focus,.datepicker table tr td.selected:hover.disabled:focus,.datepicker table tr td.selected.disabled.disabled:focus,.datepicker table tr td.selected.disabled:hover.disabled:focus,.datepicker table tr td.selected[disabled]:focus,.datepicker table tr td.selected:hover[disabled]:focus,.datepicker table tr td.selected.disabled[disabled]:focus,.datepicker table tr td.selected.disabled:hover[disabled]:focus,fieldset[disabled] .datepicker table tr td.selected:focus,fieldset[disabled] .datepicker table tr td.selected:hover:focus,fieldset[disabled] .datepicker table tr td.selected.disabled:focus,fieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus,.datepicker table tr td.selected.disabled:active,.datepicker table tr td.selected:hover.disabled:active,.datepicker table tr td.selected.disabled.disabled:active,.datepicker table tr td.selected.disabled:hover.disabled:active,.datepicker table tr td.selected[disabled]:active,.datepicker table tr td.selected:hover[disabled]:active,.datepicker table tr td.selected.disabled[disabled]:active,.datepicker table tr td.selected.disabled:hover[disabled]:active,fieldset[disabled] .datepicker table tr td.selected:active,fieldset[disabled] .datepicker table tr td.selected:hover:active,fieldset[disabled] .datepicker table tr td.selected.disabled:active,fieldset[disabled] .datepicker table tr td.selected.disabled:hover:active,.datepicker table tr td.selected.disabled.active,.datepicker table tr td.selected:hover.disabled.active,.datepicker table tr td.selected.disabled.disabled.active,.datepicker table tr td.selected.disabled:hover.disabled.active,.datepicker table tr td.selected[disabled].active,.datepicker table tr td.selected:hover[disabled].active,.datepicker table tr td.selected.disabled[disabled].active,.datepicker table tr td.selected.disabled:hover[disabled].active,fieldset[disabled] .datepicker table tr td.selected.active,fieldset[disabled] .datepicker table tr td.selected:hover.active,fieldset[disabled] .datepicker table tr td.selected.disabled.active,fieldset[disabled] .datepicker table tr td.selected.disabled:hover.active{background-color:#999;border-color:#555}.datepicker table tr td.active,.datepicker table tr td.active:hover,.datepicker table tr td.active.disabled,.datepicker table tr td.active.disabled:hover{color:#fff;background-color:#428bca;border-color:#357ebd;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datepicker table tr td.active:hover,.datepicker table tr td.active:hover:hover,.datepicker table tr td.active.disabled:hover,.datepicker table tr td.active.disabled:hover:hover,.datepicker table tr td.active:focus,.datepicker table tr td.active:hover:focus,.datepicker table tr td.active.disabled:focus,.datepicker table tr td.active.disabled:hover:focus,.datepicker table tr td.active:active,.datepicker table tr td.active:hover:active,.datepicker table tr td.active.disabled:active,.datepicker table tr td.active.disabled:hover:active,.datepicker table tr td.active.active,.datepicker table tr td.active:hover.active,.datepicker table tr td.active.disabled.active,.datepicker table tr td.active.disabled:hover.active,.open .dropdown-toggle.datepicker table tr td.active,.open .dropdown-toggle.datepicker table tr td.active:hover,.open .dropdown-toggle.datepicker table tr td.active.disabled,.open .dropdown-toggle.datepicker table tr td.active.disabled:hover{color:#fff;background-color:#3276b1;border-color:#285e8e}.datepicker table tr td.active:active,.datepicker table tr td.active:hover:active,.datepicker table tr td.active.disabled:active,.datepicker table tr td.active.disabled:hover:active,.datepicker table tr td.active.active,.datepicker table tr td.active:hover.active,.datepicker table tr td.active.disabled.active,.datepicker table tr td.active.disabled:hover.active,.open .dropdown-toggle.datepicker table tr td.active,.open .dropdown-toggle.datepicker table tr td.active:hover,.open .dropdown-toggle.datepicker table tr td.active.disabled,.open .dropdown-toggle.datepicker table tr td.active.disabled:hover{background-image:none}.datepicker table tr td.active.disabled,.datepicker table tr td.active:hover.disabled,.datepicker table tr td.active.disabled.disabled,.datepicker table tr td.active.disabled:hover.disabled,.datepicker table tr td.active[disabled],.datepicker table tr td.active:hover[disabled],.datepicker table tr td.active.disabled[disabled],.datepicker table tr td.active.disabled:hover[disabled],fieldset[disabled] .datepicker table tr td.active,fieldset[disabled] .datepicker table tr td.active:hover,fieldset[disabled] .datepicker table tr td.active.disabled,fieldset[disabled] .datepicker table tr td.active.disabled:hover,.datepicker table tr td.active.disabled:hover,.datepicker table tr td.active:hover.disabled:hover,.datepicker table tr td.active.disabled.disabled:hover,.datepicker table tr td.active.disabled:hover.disabled:hover,.datepicker table tr td.active[disabled]:hover,.datepicker table tr td.active:hover[disabled]:hover,.datepicker table tr td.active.disabled[disabled]:hover,.datepicker table tr td.active.disabled:hover[disabled]:hover,fieldset[disabled] .datepicker table tr td.active:hover,fieldset[disabled] .datepicker table tr td.active:hover:hover,fieldset[disabled] .datepicker table tr td.active.disabled:hover,fieldset[disabled] .datepicker table tr td.active.disabled:hover:hover,.datepicker table tr td.active.disabled:focus,.datepicker table tr td.active:hover.disabled:focus,.datepicker table tr td.active.disabled.disabled:focus,.datepicker table tr td.active.disabled:hover.disabled:focus,.datepicker table tr td.active[disabled]:focus,.datepicker table tr td.active:hover[disabled]:focus,.datepicker table tr td.active.disabled[disabled]:focus,.datepicker table tr td.active.disabled:hover[disabled]:focus,fieldset[disabled] .datepicker table tr td.active:focus,fieldset[disabled] .datepicker table tr td.active:hover:focus,fieldset[disabled] .datepicker table tr td.active.disabled:focus,fieldset[disabled] .datepicker table tr td.active.disabled:hover:focus,.datepicker table tr td.active.disabled:active,.datepicker table tr td.active:hover.disabled:active,.datepicker table tr td.active.disabled.disabled:active,.datepicker table tr td.active.disabled:hover.disabled:active,.datepicker table tr td.active[disabled]:active,.datepicker table tr td.active:hover[disabled]:active,.datepicker table tr td.active.disabled[disabled]:active,.datepicker table tr td.active.disabled:hover[disabled]:active,fieldset[disabled] .datepicker table tr td.active:active,fieldset[disabled] .datepicker table tr td.active:hover:active,fieldset[disabled] .datepicker table tr td.active.disabled:active,fieldset[disabled] .datepicker table tr td.active.disabled:hover:active,.datepicker table tr td.active.disabled.active,.datepicker table tr td.active:hover.disabled.active,.datepicker table tr td.active.disabled.disabled.active,.datepicker table tr td.active.disabled:hover.disabled.active,.datepicker table tr td.active[disabled].active,.datepicker table tr td.active:hover[disabled].active,.datepicker table tr td.active.disabled[disabled].active,.datepicker table tr td.active.disabled:hover[disabled].active,fieldset[disabled] .datepicker table tr td.active.active,fieldset[disabled] .datepicker table tr td.active:hover.active,fieldset[disabled] .datepicker table tr td.active.disabled.active,fieldset[disabled] .datepicker table tr td.active.disabled:hover.active{background-color:#428bca;border-color:#357ebd}.datepicker table tr td span{display:block;width:23%;height:54px;line-height:54px;float:left;margin:1%;cursor:pointer;border-radius:4px}.datepicker table tr td span:hover{background:#eee}.datepicker table tr td span.disabled,.datepicker table tr td span.disabled:hover{background:0 0;color:#999;cursor:default}.datepicker table tr td span.active,.datepicker table tr td span.active:hover,.datepicker table tr td span.active.disabled,.datepicker table tr td span.active.disabled:hover{color:#fff;background-color:#428bca;border-color:#357ebd;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datepicker table tr td span.active:hover,.datepicker table tr td span.active:hover:hover,.datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active.disabled:hover:hover,.datepicker table tr td span.active:focus,.datepicker table tr td span.active:hover:focus,.datepicker table tr td span.active.disabled:focus,.datepicker table tr td span.active.disabled:hover:focus,.datepicker table tr td span.active:active,.datepicker table tr td span.active:hover:active,.datepicker table tr td span.active.disabled:active,.datepicker table tr td span.active.disabled:hover:active,.datepicker table tr td span.active.active,.datepicker table tr td span.active:hover.active,.datepicker table tr td span.active.disabled.active,.datepicker table tr td span.active.disabled:hover.active,.open .dropdown-toggle.datepicker table tr td span.active,.open .dropdown-toggle.datepicker table tr td span.active:hover,.open .dropdown-toggle.datepicker table tr td span.active.disabled,.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover{color:#fff;background-color:#3276b1;border-color:#285e8e}.datepicker table tr td span.active:active,.datepicker table tr td span.active:hover:active,.datepicker table tr td span.active.disabled:active,.datepicker table tr td span.active.disabled:hover:active,.datepicker table tr td span.active.active,.datepicker table tr td span.active:hover.active,.datepicker table tr td span.active.disabled.active,.datepicker table tr td span.active.disabled:hover.active,.open .dropdown-toggle.datepicker table tr td span.active,.open .dropdown-toggle.datepicker table tr td span.active:hover,.open .dropdown-toggle.datepicker table tr td span.active.disabled,.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover{background-image:none}.datepicker table tr td span.active.disabled,.datepicker table tr td span.active:hover.disabled,.datepicker table tr td span.active.disabled.disabled,.datepicker table tr td span.active.disabled:hover.disabled,.datepicker table tr td span.active[disabled],.datepicker table tr td span.active:hover[disabled],.datepicker table tr td span.active.disabled[disabled],.datepicker table tr td span.active.disabled:hover[disabled],fieldset[disabled] .datepicker table tr td span.active,fieldset[disabled] .datepicker table tr td span.active:hover,fieldset[disabled] .datepicker table tr td span.active.disabled,fieldset[disabled] .datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active:hover.disabled:hover,.datepicker table tr td span.active.disabled.disabled:hover,.datepicker table tr td span.active.disabled:hover.disabled:hover,.datepicker table tr td span.active[disabled]:hover,.datepicker table tr td span.active:hover[disabled]:hover,.datepicker table tr td span.active.disabled[disabled]:hover,.datepicker table tr td span.active.disabled:hover[disabled]:hover,fieldset[disabled] .datepicker table tr td span.active:hover,fieldset[disabled] .datepicker table tr td span.active:hover:hover,fieldset[disabled] .datepicker table tr td span.active.disabled:hover,fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover,.datepicker table tr td span.active.disabled:focus,.datepicker table tr td span.active:hover.disabled:focus,.datepicker table tr td span.active.disabled.disabled:focus,.datepicker table tr td span.active.disabled:hover.disabled:focus,.datepicker table tr td span.active[disabled]:focus,.datepicker table tr td span.active:hover[disabled]:focus,.datepicker table tr td span.active.disabled[disabled]:focus,.datepicker table tr td span.active.disabled:hover[disabled]:focus,fieldset[disabled] .datepicker table tr td span.active:focus,fieldset[disabled] .datepicker table tr td span.active:hover:focus,fieldset[disabled] .datepicker table tr td span.active.disabled:focus,fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus,.datepicker table tr td span.active.disabled:active,.datepicker table tr td span.active:hover.disabled:active,.datepicker table tr td span.active.disabled.disabled:active,.datepicker table tr td span.active.disabled:hover.disabled:active,.datepicker table tr td span.active[disabled]:active,.datepicker table tr td span.active:hover[disabled]:active,.datepicker table tr td span.active.disabled[disabled]:active,.datepicker table tr td span.active.disabled:hover[disabled]:active,fieldset[disabled] .datepicker table tr td span.active:active,fieldset[disabled] .datepicker table tr td span.active:hover:active,fieldset[disabled] .datepicker table tr td span.active.disabled:active,fieldset[disabled] .datepicker table tr td span.active.disabled:hover:active,.datepicker table tr td span.active.disabled.active,.datepicker table tr td span.active:hover.disabled.active,.datepicker table tr td span.active.disabled.disabled.active,.datepicker table tr td span.active.disabled:hover.disabled.active,.datepicker table tr td span.active[disabled].active,.datepicker table tr td span.active:hover[disabled].active,.datepicker table tr td span.active.disabled[disabled].active,.datepicker table tr td span.active.disabled:hover[disabled].active,fieldset[disabled] .datepicker table tr td span.active.active,fieldset[disabled] .datepicker table tr td span.active:hover.active,fieldset[disabled] .datepicker table tr td span.active.disabled.active,fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active{background-color:#428bca;border-color:#357ebd}.datepicker table tr td span.old,.datepicker table tr td span.new{color:#999}.datepicker .datepicker-switch{width:145px}.datepicker thead tr:first-child th,.datepicker tfoot tr th{cursor:pointer}.datepicker thead tr:first-child th:hover,.datepicker tfoot tr th:hover{background:#eee}.datepicker .cw{font-size:10px;width:12px;padding:0 2px 0 5px;vertical-align:middle}.datepicker thead tr:first-child .cw{cursor:default;background-color:transparent}.input-group.date .input-group-addon{cursor:pointer}.input-daterange{width:100%}.input-daterange input{text-align:center}.input-daterange input:first-child{border-radius:3px 0 0 3px}.input-daterange input:last-child{border-radius:0 3px 3px 0}.input-daterange .input-group-addon{width:auto;min-width:16px;padding:4px 5px;font-weight:400;line-height:1.42857143;text-align:center;text-shadow:0 1px 0 #fff;vertical-align:middle;background-color:#eee;border:solid #ccc;border-width:1px 0;margin-left:-5px;margin-right:-5px} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/css/jquery-ui.css b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/css/jquery-ui.css new file mode 100644 index 0000000000..1c22746c81 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/css/jquery-ui.css @@ -0,0 +1,1225 @@ +/*! jQuery UI - v1.11.4 - 2015-03-11 +* http://jqueryui.com +* Includes: core.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, draggable.css, menu.css, progressbar.css, resizable.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px +* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { + display: none; +} +.ui-helper-hidden-accessible { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} +.ui-helper-reset { + margin: 0; + padding: 0; + border: 0; + outline: 0; + line-height: 1.3; + text-decoration: none; + font-size: 100%; + list-style: none; +} +.ui-helper-clearfix:before, +.ui-helper-clearfix:after { + content: ""; + display: table; + border-collapse: collapse; +} +.ui-helper-clearfix:after { + clear: both; +} +.ui-helper-clearfix { + min-height: 0; /* support: IE7 */ +} +.ui-helper-zfix { + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0; + filter:Alpha(Opacity=0); /* support: IE8 */ +} + +.ui-front { + z-index: 100; +} + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { + cursor: default !important; +} + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { + display: block; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; +} + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +.ui-accordion .ui-accordion-header { + display: block; + cursor: pointer; + position: relative; + margin: 2px 0 0 0; + padding: .5em .5em .5em .7em; + min-height: 0; /* support: IE7 */ + font-size: 100%; +} +.ui-accordion .ui-accordion-icons { + padding-left: 2.2em; +} +.ui-accordion .ui-accordion-icons .ui-accordion-icons { + padding-left: 2.2em; +} +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { + position: absolute; + left: .5em; + top: 50%; + margin-top: -8px; +} +.ui-accordion .ui-accordion-content { + padding: 1em 2.2em; + border-top: 0; + overflow: auto; +} +.ui-autocomplete { + position: absolute; + top: 0; + left: 0; + cursor: default; +} +.ui-button { + display: inline-block; + position: relative; + padding: 0; + line-height: normal; + margin-right: .1em; + cursor: pointer; + vertical-align: middle; + text-align: center; + overflow: visible; /* removes extra width in IE */ +} +.ui-button, +.ui-button:link, +.ui-button:visited, +.ui-button:hover, +.ui-button:active { + text-decoration: none; +} +/* to make room for the icon, a width needs to be set here */ +.ui-button-icon-only { + width: 2.2em; +} +/* button elements seem to need a little more width */ +button.ui-button-icon-only { + width: 2.4em; +} +.ui-button-icons-only { + width: 3.4em; +} +button.ui-button-icons-only { + width: 3.7em; +} + +/* button text element */ +.ui-button .ui-button-text { + display: block; + line-height: normal; +} +.ui-button-text-only .ui-button-text { + padding: .4em 1em; +} +.ui-button-icon-only .ui-button-text, +.ui-button-icons-only .ui-button-text { + padding: .4em; + text-indent: -9999999px; +} +.ui-button-text-icon-primary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: .4em 1em .4em 2.1em; +} +.ui-button-text-icon-secondary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: .4em 2.1em .4em 1em; +} +.ui-button-text-icons .ui-button-text { + padding-left: 2.1em; + padding-right: 2.1em; +} +/* no icon support for input elements, provide padding by default */ +input.ui-button { + padding: .4em 1em; +} + +/* button icon element(s) */ +.ui-button-icon-only .ui-icon, +.ui-button-text-icon-primary .ui-icon, +.ui-button-text-icon-secondary .ui-icon, +.ui-button-text-icons .ui-icon, +.ui-button-icons-only .ui-icon { + position: absolute; + top: 50%; + margin-top: -8px; +} +.ui-button-icon-only .ui-icon { + left: 50%; + margin-left: -8px; +} +.ui-button-text-icon-primary .ui-button-icon-primary, +.ui-button-text-icons .ui-button-icon-primary, +.ui-button-icons-only .ui-button-icon-primary { + left: .5em; +} +.ui-button-text-icon-secondary .ui-button-icon-secondary, +.ui-button-text-icons .ui-button-icon-secondary, +.ui-button-icons-only .ui-button-icon-secondary { + right: .5em; +} + +/* button sets */ +.ui-buttonset { + margin-right: 7px; +} +.ui-buttonset .ui-button { + margin-left: 0; + margin-right: -.3em; +} + +/* workarounds */ +/* reset extra padding in Firefox, see h5bp.com/l */ +input.ui-button::-moz-focus-inner, +button.ui-button::-moz-focus-inner { + border: 0; + padding: 0; +} +.ui-datepicker { + width: 17em; + padding: .2em .2em 0; + display: none; +} +.ui-datepicker .ui-datepicker-header { + position: relative; + padding: .2em 0; +} +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-next { + position: absolute; + top: 2px; + width: 1.8em; + height: 1.8em; +} +.ui-datepicker .ui-datepicker-prev-hover, +.ui-datepicker .ui-datepicker-next-hover { + top: 1px; +} +.ui-datepicker .ui-datepicker-prev { + left: 2px; +} +.ui-datepicker .ui-datepicker-next { + right: 2px; +} +.ui-datepicker .ui-datepicker-prev-hover { + left: 1px; +} +.ui-datepicker .ui-datepicker-next-hover { + right: 1px; +} +.ui-datepicker .ui-datepicker-prev span, +.ui-datepicker .ui-datepicker-next span { + display: block; + position: absolute; + left: 50%; + margin-left: -8px; + top: 50%; + margin-top: -8px; +} +.ui-datepicker .ui-datepicker-title { + margin: 0 2.3em; + line-height: 1.8em; + text-align: center; +} +.ui-datepicker .ui-datepicker-title select { + font-size: 1em; + margin: 1px 0; +} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { + width: 45%; +} +.ui-datepicker table { + width: 100%; + font-size: .9em; + border-collapse: collapse; + margin: 0 0 .4em; +} +.ui-datepicker th { + padding: .7em .3em; + text-align: center; + font-weight: bold; + border: 0; +} +.ui-datepicker td { + border: 0; + padding: 1px; +} +.ui-datepicker td span, +.ui-datepicker td a { + display: block; + padding: .2em; + text-align: right; + text-decoration: none; +} +.ui-datepicker .ui-datepicker-buttonpane { + background-image: none; + margin: .7em 0 0 0; + padding: 0 .2em; + border-left: 0; + border-right: 0; + border-bottom: 0; +} +.ui-datepicker .ui-datepicker-buttonpane button { + float: right; + margin: .5em .2em .4em; + cursor: pointer; + padding: .2em .6em .3em .6em; + width: auto; + overflow: visible; +} +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { + float: left; +} + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { + width: auto; +} +.ui-datepicker-multi .ui-datepicker-group { + float: left; +} +.ui-datepicker-multi .ui-datepicker-group table { + width: 95%; + margin: 0 auto .4em; +} +.ui-datepicker-multi-2 .ui-datepicker-group { + width: 50%; +} +.ui-datepicker-multi-3 .ui-datepicker-group { + width: 33.3%; +} +.ui-datepicker-multi-4 .ui-datepicker-group { + width: 25%; +} +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { + border-left-width: 0; +} +.ui-datepicker-multi .ui-datepicker-buttonpane { + clear: left; +} +.ui-datepicker-row-break { + clear: both; + width: 100%; + font-size: 0; +} + +/* RTL support */ +.ui-datepicker-rtl { + direction: rtl; +} +.ui-datepicker-rtl .ui-datepicker-prev { + right: 2px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next { + left: 2px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-prev:hover { + right: 1px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next:hover { + left: 1px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane { + clear: right; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button { + float: left; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, +.ui-datepicker-rtl .ui-datepicker-group { + float: right; +} +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { + border-right-width: 0; + border-left-width: 1px; +} +.ui-dialog { + overflow: hidden; + position: absolute; + top: 0; + left: 0; + padding: .2em; + outline: 0; +} +.ui-dialog .ui-dialog-titlebar { + padding: .4em 1em; + position: relative; +} +.ui-dialog .ui-dialog-title { + float: left; + margin: .1em 0; + white-space: nowrap; + width: 90%; + overflow: hidden; + text-overflow: ellipsis; +} +.ui-dialog .ui-dialog-titlebar-close { + position: absolute; + right: .3em; + top: 50%; + width: 20px; + margin: -10px 0 0 0; + padding: 1px; + height: 20px; +} +.ui-dialog .ui-dialog-content { + position: relative; + border: 0; + padding: .5em 1em; + background: none; + overflow: auto; +} +.ui-dialog .ui-dialog-buttonpane { + text-align: left; + border-width: 1px 0 0 0; + background-image: none; + margin-top: .5em; + padding: .3em 1em .5em .4em; +} +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { + float: right; +} +.ui-dialog .ui-dialog-buttonpane button { + margin: .5em .4em .5em 0; + cursor: pointer; +} +.ui-dialog .ui-resizable-se { + width: 12px; + height: 12px; + right: -5px; + bottom: -5px; + background-position: 16px 16px; +} +.ui-draggable .ui-dialog-titlebar { + cursor: move; +} +.ui-draggable-handle { + -ms-touch-action: none; + touch-action: none; +} +.ui-menu { + list-style: none; + padding: 0; + margin: 0; + display: block; + outline: none; +} +.ui-menu .ui-menu { + position: absolute; +} +.ui-menu .ui-menu-item { + position: relative; + margin: 0; + padding: 3px 1em 3px .4em; + cursor: pointer; + min-height: 0; /* support: IE7 */ + /* support: IE10, see #8844 */ + list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"); +} +.ui-menu .ui-menu-divider { + margin: 5px 0; + height: 0; + font-size: 0; + line-height: 0; + border-width: 1px 0 0 0; +} +.ui-menu .ui-state-focus, +.ui-menu .ui-state-active { + margin: -1px; +} + +/* icon support */ +.ui-menu-icons { + position: relative; +} +.ui-menu-icons .ui-menu-item { + padding-left: 2em; +} + +/* left-aligned */ +.ui-menu .ui-icon { + position: absolute; + top: 0; + bottom: 0; + left: .2em; + margin: auto 0; +} + +/* right-aligned */ +.ui-menu .ui-menu-icon { + left: auto; + right: 0; +} +.ui-progressbar { + height: 2em; + text-align: left; + overflow: hidden; +} +.ui-progressbar .ui-progressbar-value { + margin: -1px; + height: 100%; +} +.ui-progressbar .ui-progressbar-overlay { + background: url("data:image/gif;base64,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"); + height: 100%; + filter: alpha(opacity=25); /* support: IE8 */ + opacity: 0.25; +} +.ui-progressbar-indeterminate .ui-progressbar-value { + background-image: none; +} +.ui-resizable { + position: relative; +} +.ui-resizable-handle { + position: absolute; + font-size: 0.1px; + display: block; + -ms-touch-action: none; + touch-action: none; +} +.ui-resizable-disabled .ui-resizable-handle, +.ui-resizable-autohide .ui-resizable-handle { + display: none; +} +.ui-resizable-n { + cursor: n-resize; + height: 7px; + width: 100%; + top: -5px; + left: 0; +} +.ui-resizable-s { + cursor: s-resize; + height: 7px; + width: 100%; + bottom: -5px; + left: 0; +} +.ui-resizable-e { + cursor: e-resize; + width: 7px; + right: -5px; + top: 0; + height: 100%; +} +.ui-resizable-w { + cursor: w-resize; + width: 7px; + left: -5px; + top: 0; + height: 100%; +} +.ui-resizable-se { + cursor: se-resize; + width: 12px; + height: 12px; + right: 1px; + bottom: 1px; +} +.ui-resizable-sw { + cursor: sw-resize; + width: 9px; + height: 9px; + left: -5px; + bottom: -5px; +} +.ui-resizable-nw { + cursor: nw-resize; + width: 9px; + height: 9px; + left: -5px; + top: -5px; +} +.ui-resizable-ne { + cursor: ne-resize; + width: 9px; + height: 9px; + right: -5px; + top: -5px; +} +.ui-selectable { + -ms-touch-action: none; + touch-action: none; +} +.ui-selectable-helper { + position: absolute; + z-index: 100; + border: 1px dotted black; +} +.ui-selectmenu-menu { + padding: 0; + margin: 0; + position: absolute; + top: 0; + left: 0; + display: none; +} +.ui-selectmenu-menu .ui-menu { + overflow: auto; + /* Support: IE7 */ + overflow-x: hidden; + padding-bottom: 1px; +} +.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup { + font-size: 1em; + font-weight: bold; + line-height: 1.5; + padding: 2px 0.4em; + margin: 0.5em 0 0 0; + height: auto; + border: 0; +} +.ui-selectmenu-open { + display: block; +} +.ui-selectmenu-button { + display: inline-block; + overflow: hidden; + position: relative; + text-decoration: none; + cursor: pointer; +} +.ui-selectmenu-button span.ui-icon { + right: 0.5em; + left: auto; + margin-top: -8px; + position: absolute; + top: 50%; +} +.ui-selectmenu-button span.ui-selectmenu-text { + text-align: left; + padding: 0.4em 2.1em 0.4em 1em; + display: block; + line-height: 1.4; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.ui-slider { + position: relative; + text-align: left; +} +.ui-slider .ui-slider-handle { + position: absolute; + z-index: 2; + width: 1.2em; + height: 1.2em; + cursor: default; + -ms-touch-action: none; + touch-action: none; +} +.ui-slider .ui-slider-range { + position: absolute; + z-index: 1; + font-size: .7em; + display: block; + border: 0; + background-position: 0 0; +} + +/* support: IE8 - See #6727 */ +.ui-slider.ui-state-disabled .ui-slider-handle, +.ui-slider.ui-state-disabled .ui-slider-range { + filter: inherit; +} + +.ui-slider-horizontal { + height: .8em; +} +.ui-slider-horizontal .ui-slider-handle { + top: -.3em; + margin-left: -.6em; +} +.ui-slider-horizontal .ui-slider-range { + top: 0; + height: 100%; +} +.ui-slider-horizontal .ui-slider-range-min { + left: 0; +} +.ui-slider-horizontal .ui-slider-range-max { + right: 0; +} + +.ui-slider-vertical { + width: .8em; + height: 100px; +} +.ui-slider-vertical .ui-slider-handle { + left: -.3em; + margin-left: 0; + margin-bottom: -.6em; +} +.ui-slider-vertical .ui-slider-range { + left: 0; + width: 100%; +} +.ui-slider-vertical .ui-slider-range-min { + bottom: 0; +} +.ui-slider-vertical .ui-slider-range-max { + top: 0; +} +.ui-sortable-handle { + -ms-touch-action: none; + touch-action: none; +} +.ui-spinner { + position: relative; + display: inline-block; + overflow: hidden; + padding: 0; + vertical-align: middle; +} +.ui-spinner-input { + border: none; + background: none; + color: inherit; + padding: 0; + margin: .2em 0; + vertical-align: middle; + margin-left: .4em; + margin-right: 22px; +} +.ui-spinner-button { + width: 16px; + height: 50%; + font-size: .5em; + padding: 0; + margin: 0; + text-align: center; + position: absolute; + cursor: default; + display: block; + overflow: hidden; + right: 0; +} +/* more specificity required here to override default borders */ +.ui-spinner a.ui-spinner-button { + border-top: none; + border-bottom: none; + border-right: none; +} +/* vertically center icon */ +.ui-spinner .ui-icon { + position: absolute; + margin-top: -8px; + top: 50%; + left: 0; +} +.ui-spinner-up { + top: 0; +} +.ui-spinner-down { + bottom: 0; +} + +/* TR overrides */ +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position: -65px -16px; +} +.ui-tabs { + position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ + padding: .2em; +} +.ui-tabs .ui-tabs-nav { + margin: 0; + padding: .2em .2em 0; +} +.ui-tabs .ui-tabs-nav li { + list-style: none; + float: left; + position: relative; + top: 0; + margin: 1px .2em 0 0; + border-bottom-width: 0; + padding: 0; + white-space: nowrap; +} +.ui-tabs .ui-tabs-nav .ui-tabs-anchor { + float: left; + padding: .5em 1em; + text-decoration: none; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active { + margin-bottom: -1px; + padding-bottom: 1px; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor, +.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor, +.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor { + cursor: text; +} +.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor { + cursor: pointer; +} +.ui-tabs .ui-tabs-panel { + display: block; + border-width: 0; + padding: 1em 1.4em; + background: none; +} +.ui-tooltip { + padding: 8px; + position: absolute; + z-index: 9999; + max-width: 300px; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 0 0 5px #aaa; +} +body .ui-tooltip { + border-width: 2px; +} + +/* Component containers +----------------------------------*/ +.ui-widget { + font-family: Verdana,Arial,sans-serif; + font-size: 1.1em; +} +.ui-widget .ui-widget { + font-size: 1em; +} +.ui-widget input, +.ui-widget select, +.ui-widget textarea, +.ui-widget button { + font-family: Verdana,Arial,sans-serif; + font-size: 1em; +} +.ui-widget-content { + border: 1px solid #aaaaaa; + background: #ffffff url("images/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x; + color: #222222; +} +.ui-widget-content a { + color: #222222; +} +.ui-widget-header { + border: 1px solid #aaaaaa; + background: #cccccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x; + color: #222222; + font-weight: bold; +} +.ui-widget-header a { + color: #222222; +} + +/* Interaction states +----------------------------------*/ +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default { + border: 1px solid #d3d3d3; + background: #e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x; + font-weight: normal; + color: #555555; +} +.ui-state-default a, +.ui-state-default a:link, +.ui-state-default a:visited { + color: #555555; + text-decoration: none; +} +.ui-state-hover, +.ui-widget-content .ui-state-hover, +.ui-widget-header .ui-state-hover, +.ui-state-focus, +.ui-widget-content .ui-state-focus, +.ui-widget-header .ui-state-focus { + border: 1px solid #999999; + background: #dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x; + font-weight: normal; + color: #212121; +} +.ui-state-hover a, +.ui-state-hover a:hover, +.ui-state-hover a:link, +.ui-state-hover a:visited, +.ui-state-focus a, +.ui-state-focus a:hover, +.ui-state-focus a:link, +.ui-state-focus a:visited { + color: #212121; + text-decoration: none; +} +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active { + border: 1px solid #aaaaaa; + background: #ffffff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x; + font-weight: normal; + color: #212121; +} +.ui-state-active a, +.ui-state-active a:link, +.ui-state-active a:visited { + color: #212121; + text-decoration: none; +} + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, +.ui-widget-content .ui-state-highlight, +.ui-widget-header .ui-state-highlight { + border: 1px solid #fcefa1; + background: #fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x; + color: #363636; +} +.ui-state-highlight a, +.ui-widget-content .ui-state-highlight a, +.ui-widget-header .ui-state-highlight a { + color: #363636; +} +.ui-state-error, +.ui-widget-content .ui-state-error, +.ui-widget-header .ui-state-error { + border: 1px solid #cd0a0a; + background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x; + color: #cd0a0a; +} +.ui-state-error a, +.ui-widget-content .ui-state-error a, +.ui-widget-header .ui-state-error a { + color: #cd0a0a; +} +.ui-state-error-text, +.ui-widget-content .ui-state-error-text, +.ui-widget-header .ui-state-error-text { + color: #cd0a0a; +} +.ui-priority-primary, +.ui-widget-content .ui-priority-primary, +.ui-widget-header .ui-priority-primary { + font-weight: bold; +} +.ui-priority-secondary, +.ui-widget-content .ui-priority-secondary, +.ui-widget-header .ui-priority-secondary { + opacity: .7; + filter:Alpha(Opacity=70); /* support: IE8 */ + font-weight: normal; +} +.ui-state-disabled, +.ui-widget-content .ui-state-disabled, +.ui-widget-header .ui-state-disabled { + opacity: .35; + filter:Alpha(Opacity=35); /* support: IE8 */ + background-image: none; +} +.ui-state-disabled .ui-icon { + filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */ +} + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { + width: 16px; + height: 16px; +} +.ui-icon, +.ui-widget-content .ui-icon { + background-image: url("images/ui-icons_222222_256x240.png"); +} +.ui-widget-header .ui-icon { + background-image: url("images/ui-icons_222222_256x240.png"); +} +.ui-state-default .ui-icon { + background-image: url("images/ui-icons_888888_256x240.png"); +} +.ui-state-hover .ui-icon, +.ui-state-focus .ui-icon { + background-image: url("images/ui-icons_454545_256x240.png"); +} +.ui-state-active .ui-icon { + background-image: url("images/ui-icons_454545_256x240.png"); +} +.ui-state-highlight .ui-icon { + background-image: url("images/ui-icons_2e83ff_256x240.png"); +} +.ui-state-error .ui-icon, +.ui-state-error-text .ui-icon { + background-image: url("images/ui-icons_cd0a0a_256x240.png"); +} + +/* positioning */ +.ui-icon-blank { background-position: 16px 16px; } +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-on { background-position: -96px -144px; } +.ui-icon-radio-off { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, +.ui-corner-top, +.ui-corner-left, +.ui-corner-tl { + border-top-left-radius: 4px; +} +.ui-corner-all, +.ui-corner-top, +.ui-corner-right, +.ui-corner-tr { + border-top-right-radius: 4px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-left, +.ui-corner-bl { + border-bottom-left-radius: 4px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-right, +.ui-corner-br { + border-bottom-right-radius: 4px; +} + +/* Overlays */ +.ui-widget-overlay { + background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x; + opacity: .3; + filter: Alpha(Opacity=30); /* support: IE8 */ +} +.ui-widget-shadow { + margin: -8px 0 0 -8px; + padding: 8px; + background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x; + opacity: .3; + filter: Alpha(Opacity=30); /* support: IE8 */ + border-radius: 8px; +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/gadget.json b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/gadget.json new file mode 100644 index 0000000000..6bc37a8ce8 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/gadget.json @@ -0,0 +1,24 @@ +{ + "id": "date-picker", + "title": "Date Picker", + "type": "gadget", + "category": "Widgets", + "thumbnail": "gadget/date-picker/index.png", + "data": { + "url": "gadget/date-picker/index.xml" + }, + "styles": { + "borders": false, + "title": false + }, + "notify": { + "select": { + "type": "address", + "description": "This notifies selected state" + }, + "cancel": { + "type": "boolean", + "description": "This notifies cancellation of state selection" + } + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/index.png b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/index.png new file mode 100644 index 0000000000000000000000000000000000000000..8b3f4354050480f82c28608a983cd5861e67e5aa GIT binary patch literal 12971 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 hXH@SWyZC + + + + + + + + + jQuery UI Datepicker - Default functionality + + + + + + + + + +
+
+
+
+
+
+
+ + ]]> +
+
\ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/js/bootstrap-datepicker.min.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/js/bootstrap-datepicker.min.js new file mode 100644 index 0000000000..f26d0d8674 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/js/bootstrap-datepicker.min.js @@ -0,0 +1,8 @@ +/*! + * Datepicker for Bootstrap v1.4.0 (https://github.com/eternicode/bootstrap-datepicker) + * + * Copyright 2012 Stefan Petre + * Improvements by Andrew Rowls + * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) + */ +!function(a,b){function c(){return new Date(Date.UTC.apply(Date,arguments))}function d(){var a=new Date;return c(a.getFullYear(),a.getMonth(),a.getDate())}function e(a,b){return a.getUTCFullYear()===b.getUTCFullYear()&&a.getUTCMonth()===b.getUTCMonth()&&a.getUTCDate()===b.getUTCDate()}function f(a){return function(){return this[a].apply(this,arguments)}}function g(b,c){function d(a,b){return b.toLowerCase()}var e,f=a(b).data(),g={},h=new RegExp("^"+c.toLowerCase()+"([A-Z])");c=new RegExp("^"+c.toLowerCase());for(var i in f)c.test(i)&&(e=i.replace(h,d),g[e]=f[i]);return g}function h(b){var c={};if(p[b]||(b=b.split("-")[0],p[b])){var d=p[b];return a.each(o,function(a,b){b in d&&(c[b]=d[b])}),c}}var i=function(){var b={get:function(a){return this.slice(a)[0]},contains:function(a){for(var b=a&&a.valueOf(),c=0,d=this.length;d>c;c++)if(this[c].valueOf()===b)return c;return-1},remove:function(a){this.splice(a,1)},replace:function(b){b&&(a.isArray(b)||(b=[b]),this.clear(),this.push.apply(this,b))},clear:function(){this.length=0},copy:function(){var a=new i;return a.replace(this),a}};return function(){var c=[];return c.push.apply(c,arguments),a.extend(c,b),c}}(),j=function(b,c){this._process_options(c),this.dates=new i,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=a(b),this.isInline=!1,this.isInput=this.element.is("input"),this.component=this.element.hasClass("date")?this.element.find(".add-on, .input-group-addon, .btn"):!1,this.hasInput=this.component&&this.element.find("input").length,this.component&&0===this.component.length&&(this.component=!1),this.picker=a(q.template),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.viewMode=this.o.startView,this.o.calendarWeeks&&this.picker.find("tfoot .today, tfoot .clear").attr("colspan",function(a,b){return parseInt(b)+1}),this._allow_update=!1,this.setStartDate(this._o.startDate),this.setEndDate(this._o.endDate),this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled),this.setDatesDisabled(this.o.datesDisabled),this.fillDow(),this.fillMonths(),this._allow_update=!0,this.update(),this.showMode(),this.isInline&&this.show()};j.prototype={constructor:j,_process_options:function(e){this._o=a.extend({},this._o,e);var f=this.o=a.extend({},this._o),g=f.language;switch(p[g]||(g=g.split("-")[0],p[g]||(g=n.language)),f.language=g,f.startView){case 2:case"decade":f.startView=2;break;case 1:case"year":f.startView=1;break;default:f.startView=0}switch(f.minViewMode){case 1:case"months":f.minViewMode=1;break;case 2:case"years":f.minViewMode=2;break;default:f.minViewMode=0}f.startView=Math.max(f.startView,f.minViewMode),f.multidate!==!0&&(f.multidate=Number(f.multidate)||!1,f.multidate!==!1&&(f.multidate=Math.max(0,f.multidate))),f.multidateSeparator=String(f.multidateSeparator),f.weekStart%=7,f.weekEnd=(f.weekStart+6)%7;var h=q.parseFormat(f.format);if(f.startDate!==-1/0&&(f.startDate=f.startDate?f.startDate instanceof Date?this._local_to_utc(this._zero_time(f.startDate)):q.parseDate(f.startDate,h,f.language):-1/0),1/0!==f.endDate&&(f.endDate=f.endDate?f.endDate instanceof Date?this._local_to_utc(this._zero_time(f.endDate)):q.parseDate(f.endDate,h,f.language):1/0),f.daysOfWeekDisabled=f.daysOfWeekDisabled||[],a.isArray(f.daysOfWeekDisabled)||(f.daysOfWeekDisabled=f.daysOfWeekDisabled.split(/[,\s]*/)),f.daysOfWeekDisabled=a.map(f.daysOfWeekDisabled,function(a){return parseInt(a,10)}),f.datesDisabled=f.datesDisabled||[],!a.isArray(f.datesDisabled)){var i=[];i.push(q.parseDate(f.datesDisabled,h,f.language)),f.datesDisabled=i}f.datesDisabled=a.map(f.datesDisabled,function(a){return q.parseDate(a,h,f.language)});var j=String(f.orientation).toLowerCase().split(/\s+/g),k=f.orientation.toLowerCase();if(j=a.grep(j,function(a){return/^auto|left|right|top|bottom$/.test(a)}),f.orientation={x:"auto",y:"auto"},k&&"auto"!==k)if(1===j.length)switch(j[0]){case"top":case"bottom":f.orientation.y=j[0];break;case"left":case"right":f.orientation.x=j[0]}else k=a.grep(j,function(a){return/^left|right$/.test(a)}),f.orientation.x=k[0]||"auto",k=a.grep(j,function(a){return/^top|bottom$/.test(a)}),f.orientation.y=k[0]||"auto";else;if(f.defaultViewDate){var l=f.defaultViewDate.year||(new Date).getFullYear(),m=f.defaultViewDate.month||0,o=f.defaultViewDate.day||1;f.defaultViewDate=c(l,m,o)}else f.defaultViewDate=d();f.showOnFocus=f.showOnFocus!==b?f.showOnFocus:!0},_events:[],_secondaryEvents:[],_applyEvents:function(a){for(var c,d,e,f=0;fe?(this.picker.addClass("datepicker-orient-right"),n=k.left+m-b):this.picker.addClass("datepicker-orient-left");var p,q,r=this.o.orientation.y;if("auto"===r&&(p=-g+o-c,q=g+f-(o+l+c),r=Math.max(p,q)===q?"top":"bottom"),this.picker.addClass("datepicker-orient-"+r),"top"===r?o+=l:o-=c+parseInt(this.picker.css("padding-top")),this.o.rtl){var s=e-(n+m);this.picker.css({top:o,right:s,zIndex:j})}else this.picker.css({top:o,left:n,zIndex:j});return this},_allow_update:!0,update:function(){if(!this._allow_update)return this;var b=this.dates.copy(),c=[],d=!1;return arguments.length?(a.each(arguments,a.proxy(function(a,b){b instanceof Date&&(b=this._local_to_utc(b)),c.push(b)},this)),d=!0):(c=this.isInput?this.element.val():this.element.data("date")||this.element.find("input").val(),c=c&&this.o.multidate?c.split(this.o.multidateSeparator):[c],delete this.element.data().date),c=a.map(c,a.proxy(function(a){return q.parseDate(a,this.o.format,this.o.language)},this)),c=a.grep(c,a.proxy(function(a){return athis.o.endDate||!a},this),!0),this.dates.replace(c),this.dates.length?this.viewDate=new Date(this.dates.get(-1)):this.viewDatethis.o.endDate&&(this.viewDate=new Date(this.o.endDate)),d?this.setValue():c.length&&String(b)!==String(this.dates)&&this._trigger("changeDate"),!this.dates.length&&b.length&&this._trigger("clearDate"),this.fill(),this},fillDow:function(){var a=this.o.weekStart,b="";if(this.o.calendarWeeks){this.picker.find(".datepicker-days thead tr:first-child .datepicker-switch").attr("colspan",function(a,b){return parseInt(b)+1});var c=' ';b+=c}for(;a'+p[this.o.language].daysMin[a++%7]+"";b+="",this.picker.find(".datepicker-days thead").append(b)},fillMonths:function(){for(var a="",b=0;12>b;)a+=''+p[this.o.language].monthsShort[b++]+"";this.picker.find(".datepicker-months td").html(a)},setRange:function(b){b&&b.length?this.range=a.map(b,function(a){return a.valueOf()}):delete this.range,this.fill()},getClassNames:function(b){var c=[],d=this.viewDate.getUTCFullYear(),f=this.viewDate.getUTCMonth(),g=new Date;return b.getUTCFullYear()d||b.getUTCFullYear()===d&&b.getUTCMonth()>f)&&c.push("new"),this.focusDate&&b.valueOf()===this.focusDate.valueOf()&&c.push("focused"),this.o.todayHighlight&&b.getUTCFullYear()===g.getFullYear()&&b.getUTCMonth()===g.getMonth()&&b.getUTCDate()===g.getDate()&&c.push("today"),-1!==this.dates.contains(b)&&c.push("active"),(b.valueOf()this.o.endDate||-1!==a.inArray(b.getUTCDay(),this.o.daysOfWeekDisabled))&&c.push("disabled"),this.o.datesDisabled.length>0&&a.grep(this.o.datesDisabled,function(a){return e(b,a)}).length>0&&c.push("disabled","disabled-date"),this.range&&(b>this.range[0]&&b"),this.o.calendarWeeks)){var u=new Date(+n+(this.o.weekStart-n.getUTCDay()-7)%7*864e5),v=new Date(Number(u)+(11-u.getUTCDay())%7*864e5),w=new Date(Number(w=c(v.getUTCFullYear(),0,1))+(11-w.getUTCDay())%7*864e5),x=(v-w)/864e5/7+1;t.push(''+x+"")}if(s=this.getClassNames(n),s.push("day"),this.o.beforeShowDay!==a.noop){var y=this.o.beforeShowDay(this._utc_to_local(n));y===b?y={}:"boolean"==typeof y?y={enabled:y}:"string"==typeof y&&(y={classes:y}),y.enabled===!1&&s.push("disabled"),y.classes&&(s=s.concat(y.classes.split(/\s+/))),y.tooltip&&(d=y.tooltip)}s=a.unique(s),t.push('"+n.getUTCDate()+""),d=null,n.getUTCDay()===this.o.weekEnd&&t.push(""),n.setUTCDate(n.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").empty().append(t.join(""));var z=this.picker.find(".datepicker-months").find("th:eq(1)").text(f).end().find("span").removeClass("active");if(a.each(this.dates,function(a,b){b.getUTCFullYear()===f&&z.eq(b.getUTCMonth()).addClass("active")}),(h>f||f>j)&&z.addClass("disabled"),f===h&&z.slice(0,i).addClass("disabled"),f===j&&z.slice(k+1).addClass("disabled"),this.o.beforeShowMonth!==a.noop){var A=this;a.each(z,function(b,c){if(!a(c).hasClass("disabled")){var d=new Date(f,b,1),e=A.o.beforeShowMonth(d);e===!1&&a(c).addClass("disabled")}})}t="",f=10*parseInt(f/10,10);var B=this.picker.find(".datepicker-years").find("th:eq(1)").text(f+"-"+(f+9)).end().find("td");f-=1;for(var C,D=a.map(this.dates,function(a){return a.getUTCFullYear()}),E=-1;11>E;E++)C=["year"],-1===E?C.push("old"):10===E&&C.push("new"),-1!==a.inArray(f,D)&&C.push("active"),(h>f||f>j)&&C.push("disabled"),t+=''+f+"",f+=1;B.html(t)}},updateNavArrows:function(){if(this._allow_update){var a=new Date(this.viewDate),b=a.getUTCFullYear(),c=a.getUTCMonth();switch(this.viewMode){case 0:this.picker.find(".prev").css(this.o.startDate!==-1/0&&b<=this.o.startDate.getUTCFullYear()&&c<=this.o.startDate.getUTCMonth()?{visibility:"hidden"}:{visibility:"visible"}),this.picker.find(".next").css(1/0!==this.o.endDate&&b>=this.o.endDate.getUTCFullYear()&&c>=this.o.endDate.getUTCMonth()?{visibility:"hidden"}:{visibility:"visible"});break;case 1:case 2:this.picker.find(".prev").css(this.o.startDate!==-1/0&&b<=this.o.startDate.getUTCFullYear()?{visibility:"hidden"}:{visibility:"visible"}),this.picker.find(".next").css(1/0!==this.o.endDate&&b>=this.o.endDate.getUTCFullYear()?{visibility:"hidden"}:{visibility:"visible"})}}},click:function(b){b.preventDefault();var d,e,f,g=a(b.target).closest("span, td, th");if(1===g.length)switch(g[0].nodeName.toLowerCase()){case"th":switch(g[0].className){case"datepicker-switch":this.showMode(1);break;case"prev":case"next":var h=q.modes[this.viewMode].navStep*("prev"===g[0].className?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveMonth(this.viewDate,h),this._trigger("changeMonth",this.viewDate);break;case 1:case 2:this.viewDate=this.moveYear(this.viewDate,h),1===this.viewMode&&this._trigger("changeYear",this.viewDate)}this.fill();break;case"today":var i=new Date;i=c(i.getFullYear(),i.getMonth(),i.getDate(),0,0,0),this.showMode(-2);var j="linked"===this.o.todayBtn?null:"view";this._setDate(i,j);break;case"clear":this.clearDates()}break;case"span":g.hasClass("disabled")||(this.viewDate.setUTCDate(1),g.hasClass("month")?(f=1,e=g.parent().find("span").index(g),d=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(e),this._trigger("changeMonth",this.viewDate),1===this.o.minViewMode&&this._setDate(c(d,e,f))):(f=1,e=0,d=parseInt(g.text(),10)||0,this.viewDate.setUTCFullYear(d),this._trigger("changeYear",this.viewDate),2===this.o.minViewMode&&this._setDate(c(d,e,f))),this.showMode(-1),this.fill());break;case"td":g.hasClass("day")&&!g.hasClass("disabled")&&(f=parseInt(g.text(),10)||1,d=this.viewDate.getUTCFullYear(),e=this.viewDate.getUTCMonth(),g.hasClass("old")?0===e?(e=11,d-=1):e-=1:g.hasClass("new")&&(11===e?(e=0,d+=1):e+=1),this._setDate(c(d,e,f)))}this.picker.is(":visible")&&this._focused_from&&a(this._focused_from).focus(),delete this._focused_from},_toggle_multidate:function(a){var b=this.dates.contains(a);if(a||this.dates.clear(),-1!==b?(this.o.multidate===!0||this.o.multidate>1||this.o.toggleActive)&&this.dates.remove(b):this.o.multidate===!1?(this.dates.clear(),this.dates.push(a)):this.dates.push(a),"number"==typeof this.o.multidate)for(;this.dates.length>this.o.multidate;)this.dates.remove(0)},_setDate:function(a,b){b&&"date"!==b||this._toggle_multidate(a&&new Date(a)),b&&"view"!==b||(this.viewDate=a&&new Date(a)),this.fill(),this.setValue(),b&&"view"===b||this._trigger("changeDate");var c;this.isInput?c=this.element:this.component&&(c=this.element.find("input")),c&&c.change(),!this.o.autoclose||b&&"date"!==b||this.hide()},moveMonth:function(a,c){if(!a)return b;if(!c)return a;var d,e,f=new Date(a.valueOf()),g=f.getUTCDate(),h=f.getUTCMonth(),i=Math.abs(c);if(c=c>0?1:-1,1===i)e=-1===c?function(){return f.getUTCMonth()===h}:function(){return f.getUTCMonth()!==d},d=h+c,f.setUTCMonth(d),(0>d||d>11)&&(d=(d+12)%12);else{for(var j=0;i>j;j++)f=this.moveMonth(f,c);d=f.getUTCMonth(),f.setUTCDate(g),e=function(){return d!==f.getUTCMonth()}}for(;e();)f.setUTCDate(--g),f.setUTCMonth(d);return f},moveYear:function(a,b){return this.moveMonth(a,12*b)},dateWithinRange:function(a){return a>=this.o.startDate&&a<=this.o.endDate},keydown:function(a){if(!this.picker.is(":visible"))return void(27===a.keyCode&&this.show());var b,c,e,f=!1,g=this.focusDate||this.viewDate;switch(a.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),a.preventDefault();break;case 37:case 39:if(!this.o.keyboardNavigation)break;b=37===a.keyCode?-1:1,a.ctrlKey?(c=this.moveYear(this.dates.get(-1)||d(),b),e=this.moveYear(g,b),this._trigger("changeYear",this.viewDate)):a.shiftKey?(c=this.moveMonth(this.dates.get(-1)||d(),b),e=this.moveMonth(g,b),this._trigger("changeMonth",this.viewDate)):(c=new Date(this.dates.get(-1)||d()),c.setUTCDate(c.getUTCDate()+b),e=new Date(g),e.setUTCDate(g.getUTCDate()+b)),this.dateWithinRange(e)&&(this.focusDate=this.viewDate=e,this.setValue(),this.fill(),a.preventDefault());break;case 38:case 40:if(!this.o.keyboardNavigation)break;b=38===a.keyCode?-1:1,a.ctrlKey?(c=this.moveYear(this.dates.get(-1)||d(),b),e=this.moveYear(g,b),this._trigger("changeYear",this.viewDate)):a.shiftKey?(c=this.moveMonth(this.dates.get(-1)||d(),b),e=this.moveMonth(g,b),this._trigger("changeMonth",this.viewDate)):(c=new Date(this.dates.get(-1)||d()),c.setUTCDate(c.getUTCDate()+7*b),e=new Date(g),e.setUTCDate(g.getUTCDate()+7*b)),this.dateWithinRange(e)&&(this.focusDate=this.viewDate=e,this.setValue(),this.fill(),a.preventDefault());break;case 32:break;case 13:g=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(g),f=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(a.preventDefault(),"function"==typeof a.stopPropagation?a.stopPropagation():a.cancelBubble=!0,this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}if(f){this._trigger(this.dates.length?"changeDate":"clearDate");var h;this.isInput?h=this.element:this.component&&(h=this.element.find("input")),h&&h.change()}},showMode:function(a){a&&(this.viewMode=Math.max(this.o.minViewMode,Math.min(2,this.viewMode+a))),this.picker.children("div").hide().filter(".datepicker-"+q.modes[this.viewMode].clsName).css("display","block"),this.updateNavArrows()}};var k=function(b,c){this.element=a(b),this.inputs=a.map(c.inputs,function(a){return a.jquery?a[0]:a}),delete c.inputs,m.call(a(this.inputs),c).bind("changeDate",a.proxy(this.dateUpdated,this)),this.pickers=a.map(this.inputs,function(b){return a(b).data("datepicker")}),this.updateDates()};k.prototype={updateDates:function(){this.dates=a.map(this.pickers,function(a){return a.getUTCDate()}),this.updateRanges()},updateRanges:function(){var b=a.map(this.dates,function(a){return a.valueOf()});a.each(this.pickers,function(a,c){c.setRange(b)})},dateUpdated:function(b){if(!this.updating){this.updating=!0;var c=a(b.target).data("datepicker"),d=c.getUTCDate(),e=a.inArray(b.target,this.inputs),f=e-1,g=e+1,h=this.inputs.length;if(-1!==e){if(a.each(this.pickers,function(a,b){b.getUTCDate()||b.setUTCDate(d)}),d=0&&dthis.dates[g])for(;h>g&&d>this.dates[g];)this.pickers[g++].setUTCDate(d);this.updateDates(),delete this.updating}}},remove:function(){a.map(this.pickers,function(a){a.remove()}),delete this.element.data().datepicker}};var l=a.fn.datepicker,m=function(c){var d=Array.apply(null,arguments);d.shift();var e;return this.each(function(){var f=a(this),i=f.data("datepicker"),l="object"==typeof c&&c;if(!i){var m=g(this,"date"),o=a.extend({},n,m,l),p=h(o.language),q=a.extend({},n,p,m,l);if(f.hasClass("input-daterange")||q.inputs){var r={inputs:q.inputs||f.find("input").toArray()};f.data("datepicker",i=new k(this,a.extend(q,r)))}else f.data("datepicker",i=new j(this,q))}return"string"==typeof c&&"function"==typeof i[c]&&(e=i[c].apply(i,d),e!==b)?!1:void 0}),e!==b?e:this};a.fn.datepicker=m;var n=a.fn.datepicker.defaults={autoclose:!1,beforeShowDay:a.noop,beforeShowMonth:a.noop,calendarWeeks:!1,clearBtn:!1,toggleActive:!1,daysOfWeekDisabled:[],datesDisabled:[],endDate:1/0,forceParse:!0,format:"mm/dd/yyyy",keyboardNavigation:!0,language:"en",minViewMode:0,multidate:!1,multidateSeparator:",",orientation:"auto",rtl:!1,startDate:-1/0,startView:0,todayBtn:!1,todayHighlight:!1,weekStart:0,disableTouchKeyboard:!1,enableOnReadonly:!0,container:"body"},o=a.fn.datepicker.locale_opts=["format","rtl","weekStart"];a.fn.datepicker.Constructor=j;var p=a.fn.datepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today",clear:"Clear"}},q={modes:[{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(a){return a%4===0&&a%100!==0||a%400===0},getDaysInMonth:function(a,b){return[31,q.isLeapYear(a)?29:28,31,30,31,30,31,31,30,31,30,31][b]},validParts:/dd?|DD?|mm?|MM?|yy(?:yy)?/g,nonpunctuation:/[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,parseFormat:function(a){var b=a.replace(this.validParts,"\x00").split("\x00"),c=a.match(this.validParts);if(!b||!b.length||!c||0===c.length)throw new Error("Invalid date format.");return{separators:b,parts:c}},parseDate:function(d,e,f){function g(){var a=this.slice(0,m[k].length),b=m[k].slice(0,a.length);return a.toLowerCase()===b.toLowerCase()}if(!d)return b;if(d instanceof Date)return d;"string"==typeof e&&(e=q.parseFormat(e));var h,i,k,l=/([\-+]\d+)([dmwy])/,m=d.match(/([\-+]\d+)([dmwy])/g);if(/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(d)){for(d=new Date,k=0;kb;)b+=12;for(b%=12,a.setUTCMonth(b);a.getUTCMonth()!==b;)a.setUTCDate(a.getUTCDate()-1);return a},d:function(a,b){return a.setUTCDate(b)}};t.M=t.MM=t.mm=t.m,t.dd=t.d,d=c(d.getFullYear(),d.getMonth(),d.getDate(),0,0,0);var u=e.parts.slice();if(m.length!==u.length&&(u=a(u).filter(function(b,c){return-1!==a.inArray(c,s)}).toArray()),m.length===u.length){var v;for(k=0,v=u.length;v>k;k++){if(n=parseInt(m[k],10),h=u[k],isNaN(n))switch(h){case"MM":o=a(p[f].months).filter(g),n=a.inArray(o[0],p[f].months)+1;break;case"M":o=a(p[f].monthsShort).filter(g),n=a.inArray(o[0],p[f].monthsShort)+1}r[h]=n}var w,x;for(k=0;k=g;g++)f.length&&b.push(f.shift()),b.push(e[c.parts[g]]);return b.join("")},headTemplate:'«»',contTemplate:'',footTemplate:''};q.template='
'+q.headTemplate+""+q.footTemplate+'
'+q.headTemplate+q.contTemplate+q.footTemplate+'
'+q.headTemplate+q.contTemplate+q.footTemplate+"
",a.fn.datepicker.DPGlobal=q,a.fn.datepicker.noConflict=function(){return a.fn.datepicker=l,this},a.fn.datepicker.version="1.4.0",a(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(b){var c=a(this);c.data("datepicker")||(b.preventDefault(),m.call(c,"show"))}),a(function(){m.call(a('[data-provide="datepicker-inline"]'))})}(window.jQuery); \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/js/jquery-ui.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/js/jquery-ui.js new file mode 100644 index 0000000000..31ee9cd811 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics2/src/main/resources/carbonapps/android_analytics/android_date_picker_gadget/date-picker/js/jquery-ui.js @@ -0,0 +1,16617 @@ +/*! jQuery UI - v1.11.4 - 2015-03-11 +* http://jqueryui.com +* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js +* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */ + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ "jquery" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { +/*! + * jQuery UI Core 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/category/ui-core/ + */ + + +// $.ui might exist from components with no dependencies, e.g., $.ui.position +$.ui = $.ui || {}; + +$.extend( $.ui, { + version: "1.11.4", + + keyCode: { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 + } +}); + +// plugins +$.fn.extend({ + scrollParent: function( includeHidden ) { + var position = this.css( "position" ), + excludeStaticParent = position === "absolute", + overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, + scrollParent = this.parents().filter( function() { + var parent = $( this ); + if ( excludeStaticParent && parent.css( "position" ) === "static" ) { + return false; + } + return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); + }).eq( 0 ); + + return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent; + }, + + uniqueId: (function() { + var uuid = 0; + + return function() { + return this.each(function() { + if ( !this.id ) { + this.id = "ui-id-" + ( ++uuid ); + } + }); + }; + })(), + + removeUniqueId: function() { + return this.each(function() { + if ( /^ui-id-\d+$/.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + }); + } +}); + +// selectors +function focusable( element, isTabIndexNotNaN ) { + var map, mapName, img, + nodeName = element.nodeName.toLowerCase(); + if ( "area" === nodeName ) { + map = element.parentNode; + mapName = map.name; + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { + return false; + } + img = $( "img[usemap='#" + mapName + "']" )[ 0 ]; + return !!img && visible( img ); + } + return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ? + !element.disabled : + "a" === nodeName ? + element.href || isTabIndexNotNaN : + isTabIndexNotNaN) && + // the element and all of its ancestors must be visible + visible( element ); +} + +function visible( element ) { + return $.expr.filters.visible( element ) && + !$( element ).parents().addBack().filter(function() { + return $.css( this, "visibility" ) === "hidden"; + }).length; +} + +$.extend( $.expr[ ":" ], { + data: $.expr.createPseudo ? + $.expr.createPseudo(function( dataName ) { + return function( elem ) { + return !!$.data( elem, dataName ); + }; + }) : + // support: jQuery <1.8 + function( elem, i, match ) { + return !!$.data( elem, match[ 3 ] ); + }, + + focusable: function( element ) { + return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); + }, + + tabbable: function( element ) { + var tabIndex = $.attr( element, "tabindex" ), + isTabIndexNaN = isNaN( tabIndex ); + return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); + } +}); + +// support: jQuery <1.8 +if ( !$( "
" ).outerWidth( 1 ).jquery ) { + $.each( [ "Width", "Height" ], function( i, name ) { + var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], + type = name.toLowerCase(), + orig = { + innerWidth: $.fn.innerWidth, + innerHeight: $.fn.innerHeight, + outerWidth: $.fn.outerWidth, + outerHeight: $.fn.outerHeight + }; + + function reduce( elem, size, border, margin ) { + $.each( side, function() { + size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; + if ( border ) { + size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; + } + if ( margin ) { + size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; + } + }); + return size; + } + + $.fn[ "inner" + name ] = function( size ) { + if ( size === undefined ) { + return orig[ "inner" + name ].call( this ); + } + + return this.each(function() { + $( this ).css( type, reduce( this, size ) + "px" ); + }); + }; + + $.fn[ "outer" + name] = function( size, margin ) { + if ( typeof size !== "number" ) { + return orig[ "outer" + name ].call( this, size ); + } + + return this.each(function() { + $( this).css( type, reduce( this, size, true, margin ) + "px" ); + }); + }; + }); +} + +// support: jQuery <1.8 +if ( !$.fn.addBack ) { + $.fn.addBack = function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + }; +} + +// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) +if ( $( "" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { + $.fn.removeData = (function( removeData ) { + return function( key ) { + if ( arguments.length ) { + return removeData.call( this, $.camelCase( key ) ); + } else { + return removeData.call( this ); + } + }; + })( $.fn.removeData ); +} + +// deprecated +$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); + +$.fn.extend({ + focus: (function( orig ) { + return function( delay, fn ) { + return typeof delay === "number" ? + this.each(function() { + var elem = this; + setTimeout(function() { + $( elem ).focus(); + if ( fn ) { + fn.call( elem ); + } + }, delay ); + }) : + orig.apply( this, arguments ); + }; + })( $.fn.focus ), + + disableSelection: (function() { + var eventType = "onselectstart" in document.createElement( "div" ) ? + "selectstart" : + "mousedown"; + + return function() { + return this.bind( eventType + ".ui-disableSelection", function( event ) { + event.preventDefault(); + }); + }; + })(), + + enableSelection: function() { + return this.unbind( ".ui-disableSelection" ); + }, + + zIndex: function( zIndex ) { + if ( zIndex !== undefined ) { + return this.css( "zIndex", zIndex ); + } + + if ( this.length ) { + var elem = $( this[ 0 ] ), position, value; + while ( elem.length && elem[ 0 ] !== document ) { + // Ignore z-index if position is set to a value where z-index is ignored by the browser + // This makes behavior of this function consistent across browsers + // WebKit always returns auto if the element is positioned + position = elem.css( "position" ); + if ( position === "absolute" || position === "relative" || position === "fixed" ) { + // IE returns 0 when zIndex is not specified + // other browsers return a string + // we ignore the case of nested elements with an explicit value of 0 + //
+ value = parseInt( elem.css( "zIndex" ), 10 ); + if ( !isNaN( value ) && value !== 0 ) { + return value; + } + } + elem = elem.parent(); + } + } + + return 0; + } +}); + +// $.ui.plugin is deprecated. Use $.widget() extensions instead. +$.ui.plugin = { + add: function( module, option, set ) { + var i, + proto = $.ui[ module ].prototype; + for ( i in set ) { + proto.plugins[ i ] = proto.plugins[ i ] || []; + proto.plugins[ i ].push( [ option, set[ i ] ] ); + } + }, + call: function( instance, name, args, allowDisconnected ) { + var i, + set = instance.plugins[ name ]; + + if ( !set ) { + return; + } + + if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) { + return; + } + + for ( i = 0; i < set.length; i++ ) { + if ( instance.options[ set[ i ][ 0 ] ] ) { + set[ i ][ 1 ].apply( instance.element, args ); + } + } + } +}; + + +/*! + * jQuery UI Widget 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/jQuery.widget/ + */ + + +var widget_uuid = 0, + widget_slice = Array.prototype.slice; + +$.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { + try { + + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} + } + orig( elems ); + }; +})( $.cleanData ); + +$.widget = function( name, base, prototype ) { + var fullName, existingConstructor, constructor, basePrototype, + // proxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + proxiedPrototype = {}, + namespace = name.split( "." )[ 0 ]; + + name = name.split( "." )[ 1 ]; + fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + // create selector for plugin + $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; + + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { + // allow instantiation without "new" keyword + if ( !this._createWidget ) { + return new constructor( options, element ); + } + + // allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + // extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, + // copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), + // track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + }); + + basePrototype = new base(); + // we need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( !$.isFunction( value ) ) { + proxiedPrototype[ prop ] = value; + return; + } + proxiedPrototype[ prop ] = (function() { + var _super = function() { + return base.prototype[ prop ].apply( this, arguments ); + }, + _superApply = function( args ) { + return base.prototype[ prop ].apply( this, args ); + }; + return function() { + var __super = this._super, + __superApply = this._superApply, + returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + })(); + }); + constructor.prototype = $.widget.extend( basePrototype, { + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name + }, proxiedPrototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + widgetFullName: fullName + }); + + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; + + // redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); + }); + // remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } + + $.widget.bridge( name, constructor ); + + return constructor; +}; + +$.widget.extend = function( target ) { + var input = widget_slice.call( arguments, 1 ), + inputIndex = 0, + inputLength = input.length, + key, + value; + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { + // Clone objects + if ( $.isPlainObject( value ) ) { + target[ key ] = $.isPlainObject( target[ key ] ) ? + $.widget.extend( {}, target[ key ], value ) : + // Don't extend strings, arrays, etc. with objects + $.widget.extend( {}, value ); + // Copy everything else by reference + } else { + target[ key ] = value; + } + } + } + } + return target; +}; + +$.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName || name; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string", + args = widget_slice.call( arguments, 1 ), + returnValue = this; + + if ( isMethodCall ) { + this.each(function() { + var methodValue, + instance = $.data( this, fullName ); + if ( options === "instance" ) { + returnValue = instance; + return false; + } + if ( !instance ) { + return $.error( "cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + " widget instance" ); + } + methodValue = instance[ options ].apply( instance, args ); + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + }); + } else { + + // Allow multiple hashes to be passed on init + if ( args.length ) { + options = $.widget.extend.apply( null, [ options ].concat(args) ); + } + + this.each(function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} ); + if ( instance._init ) { + instance._init(); + } + } else { + $.data( this, fullName, new object( options, this ) ); + } + }); + } + + return returnValue; + }; +}; + +$.Widget = function( /* options, element */ ) {}; +$.Widget._childConstructors = []; + +$.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "
", + options: { + disabled: false, + + // callbacks + create: null + }, + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = widget_uuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + + if ( element !== this ) { + $.data( element, this.widgetFullName, this ); + this._on( true, this.element, { + remove: function( event ) { + if ( event.target === element ) { + this.destroy(); + } + } + }); + this.document = $( element.style ? + // element within the document + element.ownerDocument : + // element is window or document + element.document || element ); + this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); + } + + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this._create(); + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + _getCreateOptions: $.noop, + _getCreateEventData: $.noop, + _create: $.noop, + _init: $.noop, + + destroy: function() { + this._destroy(); + // we can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .unbind( this.eventNamespace ) + .removeData( this.widgetFullName ) + // support: jquery <1.6.3 + // http://bugs.jquery.com/ticket/9413 + .removeData( $.camelCase( this.widgetFullName ) ); + this.widget() + .unbind( this.eventNamespace ) + .removeAttr( "aria-disabled" ) + .removeClass( + this.widgetFullName + "-disabled " + + "ui-state-disabled" ); + + // clean up events and states + this.bindings.unbind( this.eventNamespace ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + }, + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key, + parts, + curOption, + i; + + if ( arguments.length === 0 ) { + // don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( arguments.length === 1 ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( arguments.length === 1 ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + _setOption: function( key, value ) { + this.options[ key ] = value; + + if ( key === "disabled" ) { + this.widget() + .toggleClass( this.widgetFullName + "-disabled", !!value ); + + // If the widget is becoming disabled, then nothing is interactive + if ( value ) { + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + } + } + + return this; + }, + + enable: function() { + return this._setOptions({ disabled: false }); + }, + disable: function() { + return this._setOptions({ disabled: true }); + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement, + instance = this; + + // no suppressDisabledCheck flag, shuffle arguments + if ( typeof suppressDisabledCheck !== "boolean" ) { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // no element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + element = delegateElement = $( element ); + this.bindings = this.bindings.add( element ); + } + + $.each( handlers, function( event, handler ) { + function handlerProxy() { + // allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( !suppressDisabledCheck && + ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^([\w:-]*)\s*(.*)$/ ), + eventName = match[1] + instance.eventNamespace, + selector = match[2]; + if ( selector ) { + delegateElement.delegate( selector, eventName, handlerProxy ); + } else { + element.bind( eventName, handlerProxy ); + } + }); + }, + + _off: function( element, eventName ) { + eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + + this.eventNamespace; + element.unbind( eventName ).undelegate( eventName ); + + // Clear the stack to avoid memory leaks (#10056) + this.bindings = $( this.bindings.not( element ).get() ); + this.focusable = $( this.focusable.not( element ).get() ); + this.hoverable = $( this.hoverable.not( element ).get() ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + $( event.currentTarget ).addClass( "ui-state-hover" ); + }, + mouseleave: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-hover" ); + } + }); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + $( event.currentTarget ).addClass( "ui-state-focus" ); + }, + focusout: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-focus" ); + } + }); + }, + + _trigger: function( type, event, data ) { + var prop, orig, + callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + // the original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( $.isFunction( callback ) && + callback.apply( this.element[0], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } +}; + +$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + var hasOptions, + effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + if ( options.delay ) { + element.delay( options.delay ); + } + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue(function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + }); + } + }; +}); + +var widget = $.widget; + + +/*! + * jQuery UI Mouse 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/mouse/ + */ + + +var mouseHandled = false; +$( document ).mouseup( function() { + mouseHandled = false; +}); + +var mouse = $.widget("ui.mouse", { + version: "1.11.4", + options: { + cancel: "input,textarea,button,select,option", + distance: 1, + delay: 0 + }, + _mouseInit: function() { + var that = this; + + this.element + .bind("mousedown." + this.widgetName, function(event) { + return that._mouseDown(event); + }) + .bind("click." + this.widgetName, function(event) { + if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { + $.removeData(event.target, that.widgetName + ".preventClickEvent"); + event.stopImmediatePropagation(); + return false; + } + }); + + this.started = false; + }, + + // TODO: make sure destroying one instance of mouse doesn't mess with + // other instances of mouse + _mouseDestroy: function() { + this.element.unbind("." + this.widgetName); + if ( this._mouseMoveDelegate ) { + this.document + .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate) + .unbind("mouseup." + this.widgetName, this._mouseUpDelegate); + } + }, + + _mouseDown: function(event) { + // don't let more than one widget handle mouseStart + if ( mouseHandled ) { + return; + } + + this._mouseMoved = false; + + // we may have missed mouseup (out of window) + (this._mouseStarted && this._mouseUp(event)); + + this._mouseDownEvent = event; + + var that = this, + btnIsLeft = (event.which === 1), + // event.target.nodeName works around a bug in IE 8 with + // disabled inputs (#7620) + elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); + if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { + return true; + } + + this.mouseDelayMet = !this.options.delay; + if (!this.mouseDelayMet) { + this._mouseDelayTimer = setTimeout(function() { + that.mouseDelayMet = true; + }, this.options.delay); + } + + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { + this._mouseStarted = (this._mouseStart(event) !== false); + if (!this._mouseStarted) { + event.preventDefault(); + return true; + } + } + + // Click event may never have fired (Gecko & Opera) + if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { + $.removeData(event.target, this.widgetName + ".preventClickEvent"); + } + + // these delegates are required to keep context + this._mouseMoveDelegate = function(event) { + return that._mouseMove(event); + }; + this._mouseUpDelegate = function(event) { + return that._mouseUp(event); + }; + + this.document + .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) + .bind( "mouseup." + this.widgetName, this._mouseUpDelegate ); + + event.preventDefault(); + + mouseHandled = true; + return true; + }, + + _mouseMove: function(event) { + // Only check for mouseups outside the document if you've moved inside the document + // at least once. This prevents the firing of mouseup in the case of IE<9, which will + // fire a mousemove event if content is placed under the cursor. See #7778 + // Support: IE <9 + if ( this._mouseMoved ) { + // IE mouseup check - mouseup happened when mouse was out of window + if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { + return this._mouseUp(event); + + // Iframe mouseup check - mouseup occurred in another document + } else if ( !event.which ) { + return this._mouseUp( event ); + } + } + + if ( event.which || event.button ) { + this._mouseMoved = true; + } + + if (this._mouseStarted) { + this._mouseDrag(event); + return event.preventDefault(); + } + + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { + this._mouseStarted = + (this._mouseStart(this._mouseDownEvent, event) !== false); + (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); + } + + return !this._mouseStarted; + }, + + _mouseUp: function(event) { + this.document + .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) + .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate ); + + if (this._mouseStarted) { + this._mouseStarted = false; + + if (event.target === this._mouseDownEvent.target) { + $.data(event.target, this.widgetName + ".preventClickEvent", true); + } + + this._mouseStop(event); + } + + mouseHandled = false; + return false; + }, + + _mouseDistanceMet: function(event) { + return (Math.max( + Math.abs(this._mouseDownEvent.pageX - event.pageX), + Math.abs(this._mouseDownEvent.pageY - event.pageY) + ) >= this.options.distance + ); + }, + + _mouseDelayMet: function(/* event */) { + return this.mouseDelayMet; + }, + + // These are placeholder methods, to be overriden by extending plugin + _mouseStart: function(/* event */) {}, + _mouseDrag: function(/* event */) {}, + _mouseStop: function(/* event */) {}, + _mouseCapture: function(/* event */) { return true; } +}); + + +/*! + * jQuery UI Position 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/position/ + */ + +(function() { + +$.ui = $.ui || {}; + +var cachedScrollbarWidth, supportsOffsetFractions, + max = Math.max, + abs = Math.abs, + round = Math.round, + rhorizontal = /left|center|right/, + rvertical = /top|center|bottom/, + roffset = /[\+\-]\d+(\.[\d]+)?%?/, + rposition = /^\w+/, + rpercent = /%$/, + _position = $.fn.position; + +function getOffsets( offsets, width, height ) { + return [ + parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), + parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) + ]; +} + +function parseCss( element, property ) { + return parseInt( $.css( element, property ), 10 ) || 0; +} + +function getDimensions( elem ) { + var raw = elem[0]; + if ( raw.nodeType === 9 ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: 0, left: 0 } + }; + } + if ( $.isWindow( raw ) ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: elem.scrollTop(), left: elem.scrollLeft() } + }; + } + if ( raw.preventDefault ) { + return { + width: 0, + height: 0, + offset: { top: raw.pageY, left: raw.pageX } + }; + } + return { + width: elem.outerWidth(), + height: elem.outerHeight(), + offset: elem.offset() + }; +} + +$.position = { + scrollbarWidth: function() { + if ( cachedScrollbarWidth !== undefined ) { + return cachedScrollbarWidth; + } + var w1, w2, + div = $( "
" ), + innerDiv = div.children()[0]; + + $( "body" ).append( div ); + w1 = innerDiv.offsetWidth; + div.css( "overflow", "scroll" ); + + w2 = innerDiv.offsetWidth; + + if ( w1 === w2 ) { + w2 = div[0].clientWidth; + } + + div.remove(); + + return (cachedScrollbarWidth = w1 - w2); + }, + getScrollInfo: function( within ) { + var overflowX = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-x" ), + overflowY = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-y" ), + hasOverflowX = overflowX === "scroll" || + ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), + hasOverflowY = overflowY === "scroll" || + ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); + return { + width: hasOverflowY ? $.position.scrollbarWidth() : 0, + height: hasOverflowX ? $.position.scrollbarWidth() : 0 + }; + }, + getWithinInfo: function( element ) { + var withinElement = $( element || window ), + isWindow = $.isWindow( withinElement[0] ), + isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; + return { + element: withinElement, + isWindow: isWindow, + isDocument: isDocument, + offset: withinElement.offset() || { left: 0, top: 0 }, + scrollLeft: withinElement.scrollLeft(), + scrollTop: withinElement.scrollTop(), + + // support: jQuery 1.6.x + // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows + width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(), + height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight() + }; + } +}; + +$.fn.position = function( options ) { + if ( !options || !options.of ) { + return _position.apply( this, arguments ); + } + + // make a copy, we don't want to modify arguments + options = $.extend( {}, options ); + + var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, + target = $( options.of ), + within = $.position.getWithinInfo( options.within ), + scrollInfo = $.position.getScrollInfo( within ), + collision = ( options.collision || "flip" ).split( " " ), + offsets = {}; + + dimensions = getDimensions( target ); + if ( target[0].preventDefault ) { + // force left top to allow flipping + options.at = "left top"; + } + targetWidth = dimensions.width; + targetHeight = dimensions.height; + targetOffset = dimensions.offset; + // clone to reuse original targetOffset later + basePosition = $.extend( {}, targetOffset ); + + // force my and at to have valid horizontal and vertical positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + var pos = ( options[ this ] || "" ).split( " " ), + horizontalOffset, + verticalOffset; + + if ( pos.length === 1) { + pos = rhorizontal.test( pos[ 0 ] ) ? + pos.concat( [ "center" ] ) : + rvertical.test( pos[ 0 ] ) ? + [ "center" ].concat( pos ) : + [ "center", "center" ]; + } + pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; + pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; + + // calculate offsets + horizontalOffset = roffset.exec( pos[ 0 ] ); + verticalOffset = roffset.exec( pos[ 1 ] ); + offsets[ this ] = [ + horizontalOffset ? horizontalOffset[ 0 ] : 0, + verticalOffset ? verticalOffset[ 0 ] : 0 + ]; + + // reduce to just the positions without the offsets + options[ this ] = [ + rposition.exec( pos[ 0 ] )[ 0 ], + rposition.exec( pos[ 1 ] )[ 0 ] + ]; + }); + + // normalize collision option + if ( collision.length === 1 ) { + collision[ 1 ] = collision[ 0 ]; + } + + if ( options.at[ 0 ] === "right" ) { + basePosition.left += targetWidth; + } else if ( options.at[ 0 ] === "center" ) { + basePosition.left += targetWidth / 2; + } + + if ( options.at[ 1 ] === "bottom" ) { + basePosition.top += targetHeight; + } else if ( options.at[ 1 ] === "center" ) { + basePosition.top += targetHeight / 2; + } + + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); + basePosition.left += atOffset[ 0 ]; + basePosition.top += atOffset[ 1 ]; + + return this.each(function() { + var collisionPosition, using, + elem = $( this ), + elemWidth = elem.outerWidth(), + elemHeight = elem.outerHeight(), + marginLeft = parseCss( this, "marginLeft" ), + marginTop = parseCss( this, "marginTop" ), + collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, + collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, + position = $.extend( {}, basePosition ), + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); + + if ( options.my[ 0 ] === "right" ) { + position.left -= elemWidth; + } else if ( options.my[ 0 ] === "center" ) { + position.left -= elemWidth / 2; + } + + if ( options.my[ 1 ] === "bottom" ) { + position.top -= elemHeight; + } else if ( options.my[ 1 ] === "center" ) { + position.top -= elemHeight / 2; + } + + position.left += myOffset[ 0 ]; + position.top += myOffset[ 1 ]; + + // if the browser doesn't support fractions, then round for consistent results + if ( !supportsOffsetFractions ) { + position.left = round( position.left ); + position.top = round( position.top ); + } + + collisionPosition = { + marginLeft: marginLeft, + marginTop: marginTop + }; + + $.each( [ "left", "top" ], function( i, dir ) { + if ( $.ui.position[ collision[ i ] ] ) { + $.ui.position[ collision[ i ] ][ dir ]( position, { + targetWidth: targetWidth, + targetHeight: targetHeight, + elemWidth: elemWidth, + elemHeight: elemHeight, + collisionPosition: collisionPosition, + collisionWidth: collisionWidth, + collisionHeight: collisionHeight, + offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], + my: options.my, + at: options.at, + within: within, + elem: elem + }); + } + }); + + if ( options.using ) { + // adds feedback as second argument to using callback, if present + using = function( props ) { + var left = targetOffset.left - position.left, + right = left + targetWidth - elemWidth, + top = targetOffset.top - position.top, + bottom = top + targetHeight - elemHeight, + feedback = { + target: { + element: target, + left: targetOffset.left, + top: targetOffset.top, + width: targetWidth, + height: targetHeight + }, + element: { + element: elem, + left: position.left, + top: position.top, + width: elemWidth, + height: elemHeight + }, + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" + }; + if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { + feedback.horizontal = "center"; + } + if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { + feedback.vertical = "middle"; + } + if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { + feedback.important = "horizontal"; + } else { + feedback.important = "vertical"; + } + options.using.call( this, props, feedback ); + }; + } + + elem.offset( $.extend( position, { using: using } ) ); + }); +}; + +$.ui.position = { + fit: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, + outerWidth = within.width, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = withinOffset - collisionPosLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, + newOverRight; + + // element is wider than within + if ( data.collisionWidth > outerWidth ) { + // element is initially over the left side of within + if ( overLeft > 0 && overRight <= 0 ) { + newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; + position.left += overLeft - newOverRight; + // element is initially over right side of within + } else if ( overRight > 0 && overLeft <= 0 ) { + position.left = withinOffset; + // element is initially over both left and right sides of within + } else { + if ( overLeft > overRight ) { + position.left = withinOffset + outerWidth - data.collisionWidth; + } else { + position.left = withinOffset; + } + } + // too far left -> align with left edge + } else if ( overLeft > 0 ) { + position.left += overLeft; + // too far right -> align with right edge + } else if ( overRight > 0 ) { + position.left -= overRight; + // adjust based on position and margin + } else { + position.left = max( position.left - collisionPosLeft, position.left ); + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollTop : within.offset.top, + outerHeight = data.within.height, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = withinOffset - collisionPosTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, + newOverBottom; + + // element is taller than within + if ( data.collisionHeight > outerHeight ) { + // element is initially over the top of within + if ( overTop > 0 && overBottom <= 0 ) { + newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; + position.top += overTop - newOverBottom; + // element is initially over bottom of within + } else if ( overBottom > 0 && overTop <= 0 ) { + position.top = withinOffset; + // element is initially over both top and bottom of within + } else { + if ( overTop > overBottom ) { + position.top = withinOffset + outerHeight - data.collisionHeight; + } else { + position.top = withinOffset; + } + } + // too far up -> align with top + } else if ( overTop > 0 ) { + position.top += overTop; + // too far down -> align with bottom edge + } else if ( overBottom > 0 ) { + position.top -= overBottom; + // adjust based on position and margin + } else { + position.top = max( position.top - collisionPosTop, position.top ); + } + } + }, + flip: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.offset.left + within.scrollLeft, + outerWidth = within.width, + offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = collisionPosLeft - offsetLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, + myOffset = data.my[ 0 ] === "left" ? + -data.elemWidth : + data.my[ 0 ] === "right" ? + data.elemWidth : + 0, + atOffset = data.at[ 0 ] === "left" ? + data.targetWidth : + data.at[ 0 ] === "right" ? + -data.targetWidth : + 0, + offset = -2 * data.offset[ 0 ], + newOverRight, + newOverLeft; + + if ( overLeft < 0 ) { + newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; + if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { + position.left += myOffset + atOffset + offset; + } + } else if ( overRight > 0 ) { + newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { + position.left += myOffset + atOffset + offset; + } + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.offset.top + within.scrollTop, + outerHeight = within.height, + offsetTop = within.isWindow ? within.scrollTop : within.offset.top, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = collisionPosTop - offsetTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, + top = data.my[ 1 ] === "top", + myOffset = top ? + -data.elemHeight : + data.my[ 1 ] === "bottom" ? + data.elemHeight : + 0, + atOffset = data.at[ 1 ] === "top" ? + data.targetHeight : + data.at[ 1 ] === "bottom" ? + -data.targetHeight : + 0, + offset = -2 * data.offset[ 1 ], + newOverTop, + newOverBottom; + if ( overTop < 0 ) { + newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; + if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { + position.top += myOffset + atOffset + offset; + } + } else if ( overBottom > 0 ) { + newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; + if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { + position.top += myOffset + atOffset + offset; + } + } + } + }, + flipfit: { + left: function() { + $.ui.position.flip.left.apply( this, arguments ); + $.ui.position.fit.left.apply( this, arguments ); + }, + top: function() { + $.ui.position.flip.top.apply( this, arguments ); + $.ui.position.fit.top.apply( this, arguments ); + } + } +}; + +// fraction support test +(function() { + var testElement, testElementParent, testElementStyle, offsetLeft, i, + body = document.getElementsByTagName( "body" )[ 0 ], + div = document.createElement( "div" ); + + //Create a "fake body" for testing based on method used in jQuery.support + testElement = document.createElement( body ? "div" : "body" ); + testElementStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0, + background: "none" + }; + if ( body ) { + $.extend( testElementStyle, { + position: "absolute", + left: "-1000px", + top: "-1000px" + }); + } + for ( i in testElementStyle ) { + testElement.style[ i ] = testElementStyle[ i ]; + } + testElement.appendChild( div ); + testElementParent = body || document.documentElement; + testElementParent.insertBefore( testElement, testElementParent.firstChild ); + + div.style.cssText = "position: absolute; left: 10.7432222px;"; + + offsetLeft = $( div ).offset().left; + supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11; + + testElement.innerHTML = ""; + testElementParent.removeChild( testElement ); +})(); + +})(); + +var position = $.ui.position; + + +/*! + * jQuery UI Accordion 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/accordion/ + */ + + +var accordion = $.widget( "ui.accordion", { + version: "1.11.4", + options: { + active: 0, + animate: {}, + collapsible: false, + event: "click", + header: "> li > :first-child,> :not(li):even", + heightStyle: "auto", + icons: { + activeHeader: "ui-icon-triangle-1-s", + header: "ui-icon-triangle-1-e" + }, + + // callbacks + activate: null, + beforeActivate: null + }, + + hideProps: { + borderTopWidth: "hide", + borderBottomWidth: "hide", + paddingTop: "hide", + paddingBottom: "hide", + height: "hide" + }, + + showProps: { + borderTopWidth: "show", + borderBottomWidth: "show", + paddingTop: "show", + paddingBottom: "show", + height: "show" + }, + + _create: function() { + var options = this.options; + this.prevShow = this.prevHide = $(); + this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) + // ARIA + .attr( "role", "tablist" ); + + // don't allow collapsible: false and active: false / null + if ( !options.collapsible && (options.active === false || options.active == null) ) { + options.active = 0; + } + + this._processPanels(); + // handle negative values + if ( options.active < 0 ) { + options.active += this.headers.length; + } + this._refresh(); + }, + + _getCreateEventData: function() { + return { + header: this.active, + panel: !this.active.length ? $() : this.active.next() + }; + }, + + _createIcons: function() { + var icons = this.options.icons; + if ( icons ) { + $( "" ) + .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) + .prependTo( this.headers ); + this.active.children( ".ui-accordion-header-icon" ) + .removeClass( icons.header ) + .addClass( icons.activeHeader ); + this.headers.addClass( "ui-accordion-icons" ); + } + }, + + _destroyIcons: function() { + this.headers + .removeClass( "ui-accordion-icons" ) + .children( ".ui-accordion-header-icon" ) + .remove(); + }, + + _destroy: function() { + var contents; + + // clean up main element + this.element + .removeClass( "ui-accordion ui-widget ui-helper-reset" ) + .removeAttr( "role" ); + + // clean up headers + this.headers + .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " + + "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) + .removeAttr( "role" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "aria-selected" ) + .removeAttr( "aria-controls" ) + .removeAttr( "tabIndex" ) + .removeUniqueId(); + + this._destroyIcons(); + + // clean up content panels + contents = this.headers.next() + .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " + + "ui-accordion-content ui-accordion-content-active ui-state-disabled" ) + .css( "display", "" ) + .removeAttr( "role" ) + .removeAttr( "aria-hidden" ) + .removeAttr( "aria-labelledby" ) + .removeUniqueId(); + + if ( this.options.heightStyle !== "content" ) { + contents.css( "height", "" ); + } + }, + + _setOption: function( key, value ) { + if ( key === "active" ) { + // _activate() will handle invalid values and update this.options + this._activate( value ); + return; + } + + if ( key === "event" ) { + if ( this.options.event ) { + this._off( this.headers, this.options.event ); + } + this._setupEvents( value ); + } + + this._super( key, value ); + + // setting collapsible: false while collapsed; open first panel + if ( key === "collapsible" && !value && this.options.active === false ) { + this._activate( 0 ); + } + + if ( key === "icons" ) { + this._destroyIcons(); + if ( value ) { + this._createIcons(); + } + } + + // #5332 - opacity doesn't cascade to positioned elements in IE + // so we need to add the disabled class to the headers and panels + if ( key === "disabled" ) { + this.element + .toggleClass( "ui-state-disabled", !!value ) + .attr( "aria-disabled", value ); + this.headers.add( this.headers.next() ) + .toggleClass( "ui-state-disabled", !!value ); + } + }, + + _keydown: function( event ) { + if ( event.altKey || event.ctrlKey ) { + return; + } + + var keyCode = $.ui.keyCode, + length = this.headers.length, + currentIndex = this.headers.index( event.target ), + toFocus = false; + + switch ( event.keyCode ) { + case keyCode.RIGHT: + case keyCode.DOWN: + toFocus = this.headers[ ( currentIndex + 1 ) % length ]; + break; + case keyCode.LEFT: + case keyCode.UP: + toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; + break; + case keyCode.SPACE: + case keyCode.ENTER: + this._eventHandler( event ); + break; + case keyCode.HOME: + toFocus = this.headers[ 0 ]; + break; + case keyCode.END: + toFocus = this.headers[ length - 1 ]; + break; + } + + if ( toFocus ) { + $( event.target ).attr( "tabIndex", -1 ); + $( toFocus ).attr( "tabIndex", 0 ); + toFocus.focus(); + event.preventDefault(); + } + }, + + _panelKeyDown: function( event ) { + if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { + $( event.currentTarget ).prev().focus(); + } + }, + + refresh: function() { + var options = this.options; + this._processPanels(); + + // was collapsed or no panel + if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { + options.active = false; + this.active = $(); + // active false only when collapsible is true + } else if ( options.active === false ) { + this._activate( 0 ); + // was active, but active panel is gone + } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { + // all remaining panel are disabled + if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { + options.active = false; + this.active = $(); + // activate previous panel + } else { + this._activate( Math.max( 0, options.active - 1 ) ); + } + // was active, active panel still exists + } else { + // make sure active index is correct + options.active = this.headers.index( this.active ); + } + + this._destroyIcons(); + + this._refresh(); + }, + + _processPanels: function() { + var prevHeaders = this.headers, + prevPanels = this.panels; + + this.headers = this.element.find( this.options.header ) + .addClass( "ui-accordion-header ui-state-default ui-corner-all" ); + + this.panels = this.headers.next() + .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) + .filter( ":not(.ui-accordion-content-active)" ) + .hide(); + + // Avoid memory leaks (#10056) + if ( prevPanels ) { + this._off( prevHeaders.not( this.headers ) ); + this._off( prevPanels.not( this.panels ) ); + } + }, + + _refresh: function() { + var maxHeight, + options = this.options, + heightStyle = options.heightStyle, + parent = this.element.parent(); + + this.active = this._findActive( options.active ) + .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) + .removeClass( "ui-corner-all" ); + this.active.next() + .addClass( "ui-accordion-content-active" ) + .show(); + + this.headers + .attr( "role", "tab" ) + .each(function() { + var header = $( this ), + headerId = header.uniqueId().attr( "id" ), + panel = header.next(), + panelId = panel.uniqueId().attr( "id" ); + header.attr( "aria-controls", panelId ); + panel.attr( "aria-labelledby", headerId ); + }) + .next() + .attr( "role", "tabpanel" ); + + this.headers + .not( this.active ) + .attr({ + "aria-selected": "false", + "aria-expanded": "false", + tabIndex: -1 + }) + .next() + .attr({ + "aria-hidden": "true" + }) + .hide(); + + // make sure at least one header is in the tab order + if ( !this.active.length ) { + this.headers.eq( 0 ).attr( "tabIndex", 0 ); + } else { + this.active.attr({ + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + }) + .next() + .attr({ + "aria-hidden": "false" + }); + } + + this._createIcons(); + + this._setupEvents( options.event ); + + if ( heightStyle === "fill" ) { + maxHeight = parent.height(); + this.element.siblings( ":visible" ).each(function() { + var elem = $( this ), + position = elem.css( "position" ); + + if ( position === "absolute" || position === "fixed" ) { + return; + } + maxHeight -= elem.outerHeight( true ); + }); + + this.headers.each(function() { + maxHeight -= $( this ).outerHeight( true ); + }); + + this.headers.next() + .each(function() { + $( this ).height( Math.max( 0, maxHeight - + $( this ).innerHeight() + $( this ).height() ) ); + }) + .css( "overflow", "auto" ); + } else if ( heightStyle === "auto" ) { + maxHeight = 0; + this.headers.next() + .each(function() { + maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); + }) + .height( maxHeight ); + } + }, + + _activate: function( index ) { + var active = this._findActive( index )[ 0 ]; + + // trying to activate the already active panel + if ( active === this.active[ 0 ] ) { + return; + } + + // trying to collapse, simulate a click on the currently active header + active = active || this.active[ 0 ]; + + this._eventHandler({ + target: active, + currentTarget: active, + preventDefault: $.noop + }); + }, + + _findActive: function( selector ) { + return typeof selector === "number" ? this.headers.eq( selector ) : $(); + }, + + _setupEvents: function( event ) { + var events = { + keydown: "_keydown" + }; + if ( event ) { + $.each( event.split( " " ), function( index, eventName ) { + events[ eventName ] = "_eventHandler"; + }); + } + + this._off( this.headers.add( this.headers.next() ) ); + this._on( this.headers, events ); + this._on( this.headers.next(), { keydown: "_panelKeyDown" }); + this._hoverable( this.headers ); + this._focusable( this.headers ); + }, + + _eventHandler: function( event ) { + var options = this.options, + active = this.active, + clicked = $( event.currentTarget ), + clickedIsActive = clicked[ 0 ] === active[ 0 ], + collapsing = clickedIsActive && options.collapsible, + toShow = collapsing ? $() : clicked.next(), + toHide = active.next(), + eventData = { + oldHeader: active, + oldPanel: toHide, + newHeader: collapsing ? $() : clicked, + newPanel: toShow + }; + + event.preventDefault(); + + if ( + // click on active header, but not collapsible + ( clickedIsActive && !options.collapsible ) || + // allow canceling activation + ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { + return; + } + + options.active = collapsing ? false : this.headers.index( clicked ); + + // when the call to ._toggle() comes after the class changes + // it causes a very odd bug in IE 8 (see #6720) + this.active = clickedIsActive ? $() : clicked; + this._toggle( eventData ); + + // switch classes + // corner classes on the previously active header stay after the animation + active.removeClass( "ui-accordion-header-active ui-state-active" ); + if ( options.icons ) { + active.children( ".ui-accordion-header-icon" ) + .removeClass( options.icons.activeHeader ) + .addClass( options.icons.header ); + } + + if ( !clickedIsActive ) { + clicked + .removeClass( "ui-corner-all" ) + .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); + if ( options.icons ) { + clicked.children( ".ui-accordion-header-icon" ) + .removeClass( options.icons.header ) + .addClass( options.icons.activeHeader ); + } + + clicked + .next() + .addClass( "ui-accordion-content-active" ); + } + }, + + _toggle: function( data ) { + var toShow = data.newPanel, + toHide = this.prevShow.length ? this.prevShow : data.oldPanel; + + // handle activating a panel during the animation for another activation + this.prevShow.add( this.prevHide ).stop( true, true ); + this.prevShow = toShow; + this.prevHide = toHide; + + if ( this.options.animate ) { + this._animate( toShow, toHide, data ); + } else { + toHide.hide(); + toShow.show(); + this._toggleComplete( data ); + } + + toHide.attr({ + "aria-hidden": "true" + }); + toHide.prev().attr({ + "aria-selected": "false", + "aria-expanded": "false" + }); + // if we're switching panels, remove the old header from the tab order + // if we're opening from collapsed state, remove the previous header from the tab order + // if we're collapsing, then keep the collapsing header in the tab order + if ( toShow.length && toHide.length ) { + toHide.prev().attr({ + "tabIndex": -1, + "aria-expanded": "false" + }); + } else if ( toShow.length ) { + this.headers.filter(function() { + return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; + }) + .attr( "tabIndex", -1 ); + } + + toShow + .attr( "aria-hidden", "false" ) + .prev() + .attr({ + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + }); + }, + + _animate: function( toShow, toHide, data ) { + var total, easing, duration, + that = this, + adjust = 0, + boxSizing = toShow.css( "box-sizing" ), + down = toShow.length && + ( !toHide.length || ( toShow.index() < toHide.index() ) ), + animate = this.options.animate || {}, + options = down && animate.down || animate, + complete = function() { + that._toggleComplete( data ); + }; + + if ( typeof options === "number" ) { + duration = options; + } + if ( typeof options === "string" ) { + easing = options; + } + // fall back from options to animation in case of partial down settings + easing = easing || options.easing || animate.easing; + duration = duration || options.duration || animate.duration; + + if ( !toHide.length ) { + return toShow.animate( this.showProps, duration, easing, complete ); + } + if ( !toShow.length ) { + return toHide.animate( this.hideProps, duration, easing, complete ); + } + + total = toShow.show().outerHeight(); + toHide.animate( this.hideProps, { + duration: duration, + easing: easing, + step: function( now, fx ) { + fx.now = Math.round( now ); + } + }); + toShow + .hide() + .animate( this.showProps, { + duration: duration, + easing: easing, + complete: complete, + step: function( now, fx ) { + fx.now = Math.round( now ); + if ( fx.prop !== "height" ) { + if ( boxSizing === "content-box" ) { + adjust += fx.now; + } + } else if ( that.options.heightStyle !== "content" ) { + fx.now = Math.round( total - toHide.outerHeight() - adjust ); + adjust = 0; + } + } + }); + }, + + _toggleComplete: function( data ) { + var toHide = data.oldPanel; + + toHide + .removeClass( "ui-accordion-content-active" ) + .prev() + .removeClass( "ui-corner-top" ) + .addClass( "ui-corner-all" ); + + // Work around for rendering bug in IE (#5421) + if ( toHide.length ) { + toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; + } + this._trigger( "activate", null, data ); + } +}); + + +/*! + * jQuery UI Menu 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/menu/ + */ + + +var menu = $.widget( "ui.menu", { + version: "1.11.4", + defaultElement: "
    ", + delay: 300, + options: { + icons: { + submenu: "ui-icon-carat-1-e" + }, + items: "> *", + menus: "ul", + position: { + my: "left-1 top", + at: "right top" + }, + role: "menu", + + // callbacks + blur: null, + focus: null, + select: null + }, + + _create: function() { + this.activeMenu = this.element; + + // Flag used to prevent firing of the click handler + // as the event bubbles up through nested menus + this.mouseHandled = false; + this.element + .uniqueId() + .addClass( "ui-menu ui-widget ui-widget-content" ) + .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) + .attr({ + role: this.options.role, + tabIndex: 0 + }); + + if ( this.options.disabled ) { + this.element + .addClass( "ui-state-disabled" ) + .attr( "aria-disabled", "true" ); + } + + this._on({ + // Prevent focus from sticking to links inside menu after clicking + // them (focus should always stay on UL during navigation). + "mousedown .ui-menu-item": function( event ) { + event.preventDefault(); + }, + "click .ui-menu-item": function( event ) { + var target = $( event.target ); + if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { + this.select( event ); + + // Only set the mouseHandled flag if the event will bubble, see #9469. + if ( !event.isPropagationStopped() ) { + this.mouseHandled = true; + } + + // Open submenu on click + if ( target.has( ".ui-menu" ).length ) { + this.expand( event ); + } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) { + + // Redirect focus to the menu + this.element.trigger( "focus", [ true ] ); + + // If the active item is on the top level, let it stay active. + // Otherwise, blur the active item since it is no longer visible. + if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { + clearTimeout( this.timer ); + } + } + } + }, + "mouseenter .ui-menu-item": function( event ) { + // Ignore mouse events while typeahead is active, see #10458. + // Prevents focusing the wrong item when typeahead causes a scroll while the mouse + // is over an item in the menu + if ( this.previousFilter ) { + return; + } + var target = $( event.currentTarget ); + // Remove ui-state-active class from siblings of the newly focused menu item + // to avoid a jump caused by adjacent elements both having a class with a border + target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" ); + this.focus( event, target ); + }, + mouseleave: "collapseAll", + "mouseleave .ui-menu": "collapseAll", + focus: function( event, keepActiveItem ) { + // If there's already an active item, keep it active + // If not, activate the first item + var item = this.active || this.element.find( this.options.items ).eq( 0 ); + + if ( !keepActiveItem ) { + this.focus( event, item ); + } + }, + blur: function( event ) { + this._delay(function() { + if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { + this.collapseAll( event ); + } + }); + }, + keydown: "_keydown" + }); + + this.refresh(); + + // Clicks outside of a menu collapse any open menus + this._on( this.document, { + click: function( event ) { + if ( this._closeOnDocumentClick( event ) ) { + this.collapseAll( event ); + } + + // Reset the mouseHandled flag + this.mouseHandled = false; + } + }); + }, + + _destroy: function() { + // Destroy (sub)menus + this.element + .removeAttr( "aria-activedescendant" ) + .find( ".ui-menu" ).addBack() + .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" ) + .removeAttr( "role" ) + .removeAttr( "tabIndex" ) + .removeAttr( "aria-labelledby" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "aria-hidden" ) + .removeAttr( "aria-disabled" ) + .removeUniqueId() + .show(); + + // Destroy menu items + this.element.find( ".ui-menu-item" ) + .removeClass( "ui-menu-item" ) + .removeAttr( "role" ) + .removeAttr( "aria-disabled" ) + .removeUniqueId() + .removeClass( "ui-state-hover" ) + .removeAttr( "tabIndex" ) + .removeAttr( "role" ) + .removeAttr( "aria-haspopup" ) + .children().each( function() { + var elem = $( this ); + if ( elem.data( "ui-menu-submenu-carat" ) ) { + elem.remove(); + } + }); + + // Destroy menu dividers + this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); + }, + + _keydown: function( event ) { + var match, prev, character, skip, + preventDefault = true; + + switch ( event.keyCode ) { + case $.ui.keyCode.PAGE_UP: + this.previousPage( event ); + break; + case $.ui.keyCode.PAGE_DOWN: + this.nextPage( event ); + break; + case $.ui.keyCode.HOME: + this._move( "first", "first", event ); + break; + case $.ui.keyCode.END: + this._move( "last", "last", event ); + break; + case $.ui.keyCode.UP: + this.previous( event ); + break; + case $.ui.keyCode.DOWN: + this.next( event ); + break; + case $.ui.keyCode.LEFT: + this.collapse( event ); + break; + case $.ui.keyCode.RIGHT: + if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { + this.expand( event ); + } + break; + case $.ui.keyCode.ENTER: + case $.ui.keyCode.SPACE: + this._activate( event ); + break; + case $.ui.keyCode.ESCAPE: + this.collapse( event ); + break; + default: + preventDefault = false; + prev = this.previousFilter || ""; + character = String.fromCharCode( event.keyCode ); + skip = false; + + clearTimeout( this.filterTimer ); + + if ( character === prev ) { + skip = true; + } else { + character = prev + character; + } + + match = this._filterMenuItems( character ); + match = skip && match.index( this.active.next() ) !== -1 ? + this.active.nextAll( ".ui-menu-item" ) : + match; + + // If no matches on the current filter, reset to the last character pressed + // to move down the menu to the first item that starts with that character + if ( !match.length ) { + character = String.fromCharCode( event.keyCode ); + match = this._filterMenuItems( character ); + } + + if ( match.length ) { + this.focus( event, match ); + this.previousFilter = character; + this.filterTimer = this._delay(function() { + delete this.previousFilter; + }, 1000 ); + } else { + delete this.previousFilter; + } + } + + if ( preventDefault ) { + event.preventDefault(); + } + }, + + _activate: function( event ) { + if ( !this.active.is( ".ui-state-disabled" ) ) { + if ( this.active.is( "[aria-haspopup='true']" ) ) { + this.expand( event ); + } else { + this.select( event ); + } + } + }, + + refresh: function() { + var menus, items, + that = this, + icon = this.options.icons.submenu, + submenus = this.element.find( this.options.menus ); + + this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ); + + // Initialize nested menus + submenus.filter( ":not(.ui-menu)" ) + .addClass( "ui-menu ui-widget ui-widget-content ui-front" ) + .hide() + .attr({ + role: this.options.role, + "aria-hidden": "true", + "aria-expanded": "false" + }) + .each(function() { + var menu = $( this ), + item = menu.parent(), + submenuCarat = $( "" ) + .addClass( "ui-menu-icon ui-icon " + icon ) + .data( "ui-menu-submenu-carat", true ); + + item + .attr( "aria-haspopup", "true" ) + .prepend( submenuCarat ); + menu.attr( "aria-labelledby", item.attr( "id" ) ); + }); + + menus = submenus.add( this.element ); + items = menus.find( this.options.items ); + + // Initialize menu-items containing spaces and/or dashes only as dividers + items.not( ".ui-menu-item" ).each(function() { + var item = $( this ); + if ( that._isDivider( item ) ) { + item.addClass( "ui-widget-content ui-menu-divider" ); + } + }); + + // Don't refresh list items that are already adapted + items.not( ".ui-menu-item, .ui-menu-divider" ) + .addClass( "ui-menu-item" ) + .uniqueId() + .attr({ + tabIndex: -1, + role: this._itemRole() + }); + + // Add aria-disabled attribute to any disabled menu item + items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); + + // If the active item has been removed, blur the menu + if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { + this.blur(); + } + }, + + _itemRole: function() { + return { + menu: "menuitem", + listbox: "option" + }[ this.options.role ]; + }, + + _setOption: function( key, value ) { + if ( key === "icons" ) { + this.element.find( ".ui-menu-icon" ) + .removeClass( this.options.icons.submenu ) + .addClass( value.submenu ); + } + if ( key === "disabled" ) { + this.element + .toggleClass( "ui-state-disabled", !!value ) + .attr( "aria-disabled", value ); + } + this._super( key, value ); + }, + + focus: function( event, item ) { + var nested, focused; + this.blur( event, event && event.type === "focus" ); + + this._scrollIntoView( item ); + + this.active = item.first(); + focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" ); + // Only update aria-activedescendant if there's a role + // otherwise we assume focus is managed elsewhere + if ( this.options.role ) { + this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); + } + + // Highlight active parent menu item, if any + this.active + .parent() + .closest( ".ui-menu-item" ) + .addClass( "ui-state-active" ); + + if ( event && event.type === "keydown" ) { + this._close(); + } else { + this.timer = this._delay(function() { + this._close(); + }, this.delay ); + } + + nested = item.children( ".ui-menu" ); + if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { + this._startOpening(nested); + } + this.activeMenu = item.parent(); + + this._trigger( "focus", event, { item: item } ); + }, + + _scrollIntoView: function( item ) { + var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; + if ( this._hasScroll() ) { + borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; + paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; + offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; + scroll = this.activeMenu.scrollTop(); + elementHeight = this.activeMenu.height(); + itemHeight = item.outerHeight(); + + if ( offset < 0 ) { + this.activeMenu.scrollTop( scroll + offset ); + } else if ( offset + itemHeight > elementHeight ) { + this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); + } + } + }, + + blur: function( event, fromFocus ) { + if ( !fromFocus ) { + clearTimeout( this.timer ); + } + + if ( !this.active ) { + return; + } + + this.active.removeClass( "ui-state-focus" ); + this.active = null; + + this._trigger( "blur", event, { item: this.active } ); + }, + + _startOpening: function( submenu ) { + clearTimeout( this.timer ); + + // Don't open if already open fixes a Firefox bug that caused a .5 pixel + // shift in the submenu position when mousing over the carat icon + if ( submenu.attr( "aria-hidden" ) !== "true" ) { + return; + } + + this.timer = this._delay(function() { + this._close(); + this._open( submenu ); + }, this.delay ); + }, + + _open: function( submenu ) { + var position = $.extend({ + of: this.active + }, this.options.position ); + + clearTimeout( this.timer ); + this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) + .hide() + .attr( "aria-hidden", "true" ); + + submenu + .show() + .removeAttr( "aria-hidden" ) + .attr( "aria-expanded", "true" ) + .position( position ); + }, + + collapseAll: function( event, all ) { + clearTimeout( this.timer ); + this.timer = this._delay(function() { + // If we were passed an event, look for the submenu that contains the event + var currentMenu = all ? this.element : + $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); + + // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway + if ( !currentMenu.length ) { + currentMenu = this.element; + } + + this._close( currentMenu ); + + this.blur( event ); + this.activeMenu = currentMenu; + }, this.delay ); + }, + + // With no arguments, closes the currently active menu - if nothing is active + // it closes all menus. If passed an argument, it will search for menus BELOW + _close: function( startMenu ) { + if ( !startMenu ) { + startMenu = this.active ? this.active.parent() : this.element; + } + + startMenu + .find( ".ui-menu" ) + .hide() + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ) + .end() + .find( ".ui-state-active" ).not( ".ui-state-focus" ) + .removeClass( "ui-state-active" ); + }, + + _closeOnDocumentClick: function( event ) { + return !$( event.target ).closest( ".ui-menu" ).length; + }, + + _isDivider: function( item ) { + + // Match hyphen, em dash, en dash + return !/[^\-\u2014\u2013\s]/.test( item.text() ); + }, + + collapse: function( event ) { + var newItem = this.active && + this.active.parent().closest( ".ui-menu-item", this.element ); + if ( newItem && newItem.length ) { + this._close(); + this.focus( event, newItem ); + } + }, + + expand: function( event ) { + var newItem = this.active && + this.active + .children( ".ui-menu " ) + .find( this.options.items ) + .first(); + + if ( newItem && newItem.length ) { + this._open( newItem.parent() ); + + // Delay so Firefox will not hide activedescendant change in expanding submenu from AT + this._delay(function() { + this.focus( event, newItem ); + }); + } + }, + + next: function( event ) { + this._move( "next", "first", event ); + }, + + previous: function( event ) { + this._move( "prev", "last", event ); + }, + + isFirstItem: function() { + return this.active && !this.active.prevAll( ".ui-menu-item" ).length; + }, + + isLastItem: function() { + return this.active && !this.active.nextAll( ".ui-menu-item" ).length; + }, + + _move: function( direction, filter, event ) { + var next; + if ( this.active ) { + if ( direction === "first" || direction === "last" ) { + next = this.active + [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) + .eq( -1 ); + } else { + next = this.active + [ direction + "All" ]( ".ui-menu-item" ) + .eq( 0 ); + } + } + if ( !next || !next.length || !this.active ) { + next = this.activeMenu.find( this.options.items )[ filter ](); + } + + this.focus( event, next ); + }, + + nextPage: function( event ) { + var item, base, height; + + if ( !this.active ) { + this.next( event ); + return; + } + if ( this.isLastItem() ) { + return; + } + if ( this._hasScroll() ) { + base = this.active.offset().top; + height = this.element.height(); + this.active.nextAll( ".ui-menu-item" ).each(function() { + item = $( this ); + return item.offset().top - base - height < 0; + }); + + this.focus( event, item ); + } else { + this.focus( event, this.activeMenu.find( this.options.items ) + [ !this.active ? "first" : "last" ]() ); + } + }, + + previousPage: function( event ) { + var item, base, height; + if ( !this.active ) { + this.next( event ); + return; + } + if ( this.isFirstItem() ) { + return; + } + if ( this._hasScroll() ) { + base = this.active.offset().top; + height = this.element.height(); + this.active.prevAll( ".ui-menu-item" ).each(function() { + item = $( this ); + return item.offset().top - base + height > 0; + }); + + this.focus( event, item ); + } else { + this.focus( event, this.activeMenu.find( this.options.items ).first() ); + } + }, + + _hasScroll: function() { + return this.element.outerHeight() < this.element.prop( "scrollHeight" ); + }, + + select: function( event ) { + // TODO: It should never be possible to not have an active item at this + // point, but the tests don't trigger mouseenter before click. + this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); + var ui = { item: this.active }; + if ( !this.active.has( ".ui-menu" ).length ) { + this.collapseAll( event, true ); + } + this._trigger( "select", event, ui ); + }, + + _filterMenuItems: function(character) { + var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), + regex = new RegExp( "^" + escapedCharacter, "i" ); + + return this.activeMenu + .find( this.options.items ) + + // Only match on items, not dividers or other content (#10571) + .filter( ".ui-menu-item" ) + .filter(function() { + return regex.test( $.trim( $( this ).text() ) ); + }); + } +}); + + +/*! + * jQuery UI Autocomplete 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/autocomplete/ + */ + + +$.widget( "ui.autocomplete", { + version: "1.11.4", + defaultElement: "", + options: { + appendTo: null, + autoFocus: false, + delay: 300, + minLength: 1, + position: { + my: "left top", + at: "left bottom", + collision: "none" + }, + source: null, + + // callbacks + change: null, + close: null, + focus: null, + open: null, + response: null, + search: null, + select: null + }, + + requestIndex: 0, + pending: 0, + + _create: function() { + // Some browsers only repeat keydown events, not keypress events, + // so we use the suppressKeyPress flag to determine if we've already + // handled the keydown event. #7269 + // Unfortunately the code for & in keypress is the same as the up arrow, + // so we use the suppressKeyPressRepeat flag to avoid handling keypress + // events when we know the keydown event was used to modify the + // search term. #7799 + var suppressKeyPress, suppressKeyPressRepeat, suppressInput, + nodeName = this.element[ 0 ].nodeName.toLowerCase(), + isTextarea = nodeName === "textarea", + isInput = nodeName === "input"; + + this.isMultiLine = + // Textareas are always multi-line + isTextarea ? true : + // Inputs are always single-line, even if inside a contentEditable element + // IE also treats inputs as contentEditable + isInput ? false : + // All other element types are determined by whether or not they're contentEditable + this.element.prop( "isContentEditable" ); + + this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; + this.isNewMenu = true; + + this.element + .addClass( "ui-autocomplete-input" ) + .attr( "autocomplete", "off" ); + + this._on( this.element, { + keydown: function( event ) { + if ( this.element.prop( "readOnly" ) ) { + suppressKeyPress = true; + suppressInput = true; + suppressKeyPressRepeat = true; + return; + } + + suppressKeyPress = false; + suppressInput = false; + suppressKeyPressRepeat = false; + var keyCode = $.ui.keyCode; + switch ( event.keyCode ) { + case keyCode.PAGE_UP: + suppressKeyPress = true; + this._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + suppressKeyPress = true; + this._move( "nextPage", event ); + break; + case keyCode.UP: + suppressKeyPress = true; + this._keyEvent( "previous", event ); + break; + case keyCode.DOWN: + suppressKeyPress = true; + this._keyEvent( "next", event ); + break; + case keyCode.ENTER: + // when menu is open and has focus + if ( this.menu.active ) { + // #6055 - Opera still allows the keypress to occur + // which causes forms to submit + suppressKeyPress = true; + event.preventDefault(); + this.menu.select( event ); + } + break; + case keyCode.TAB: + if ( this.menu.active ) { + this.menu.select( event ); + } + break; + case keyCode.ESCAPE: + if ( this.menu.element.is( ":visible" ) ) { + if ( !this.isMultiLine ) { + this._value( this.term ); + } + this.close( event ); + // Different browsers have different default behavior for escape + // Single press can mean undo or clear + // Double press in IE means clear the whole form + event.preventDefault(); + } + break; + default: + suppressKeyPressRepeat = true; + // search timeout should be triggered before the input value is changed + this._searchTimeout( event ); + break; + } + }, + keypress: function( event ) { + if ( suppressKeyPress ) { + suppressKeyPress = false; + if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { + event.preventDefault(); + } + return; + } + if ( suppressKeyPressRepeat ) { + return; + } + + // replicate some key handlers to allow them to repeat in Firefox and Opera + var keyCode = $.ui.keyCode; + switch ( event.keyCode ) { + case keyCode.PAGE_UP: + this._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + this._move( "nextPage", event ); + break; + case keyCode.UP: + this._keyEvent( "previous", event ); + break; + case keyCode.DOWN: + this._keyEvent( "next", event ); + break; + } + }, + input: function( event ) { + if ( suppressInput ) { + suppressInput = false; + event.preventDefault(); + return; + } + this._searchTimeout( event ); + }, + focus: function() { + this.selectedItem = null; + this.previous = this._value(); + }, + blur: function( event ) { + if ( this.cancelBlur ) { + delete this.cancelBlur; + return; + } + + clearTimeout( this.searching ); + this.close( event ); + this._change( event ); + } + }); + + this._initSource(); + this.menu = $( "
      " ) + .addClass( "ui-autocomplete ui-front" ) + .appendTo( this._appendTo() ) + .menu({ + // disable ARIA support, the live region takes care of that + role: null + }) + .hide() + .menu( "instance" ); + + this._on( this.menu.element, { + mousedown: function( event ) { + // prevent moving focus out of the text field + event.preventDefault(); + + // IE doesn't prevent moving focus even with event.preventDefault() + // so we set a flag to know when we should ignore the blur event + this.cancelBlur = true; + this._delay(function() { + delete this.cancelBlur; + }); + + // clicking on the scrollbar causes focus to shift to the body + // but we can't detect a mouseup or a click immediately afterward + // so we have to track the next mousedown and close the menu if + // the user clicks somewhere outside of the autocomplete + var menuElement = this.menu.element[ 0 ]; + if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { + this._delay(function() { + var that = this; + this.document.one( "mousedown", function( event ) { + if ( event.target !== that.element[ 0 ] && + event.target !== menuElement && + !$.contains( menuElement, event.target ) ) { + that.close(); + } + }); + }); + } + }, + menufocus: function( event, ui ) { + var label, item; + // support: Firefox + // Prevent accidental activation of menu items in Firefox (#7024 #9118) + if ( this.isNewMenu ) { + this.isNewMenu = false; + if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { + this.menu.blur(); + + this.document.one( "mousemove", function() { + $( event.target ).trigger( event.originalEvent ); + }); + + return; + } + } + + item = ui.item.data( "ui-autocomplete-item" ); + if ( false !== this._trigger( "focus", event, { item: item } ) ) { + // use value to match what will end up in the input, if it was a key event + if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { + this._value( item.value ); + } + } + + // Announce the value in the liveRegion + label = ui.item.attr( "aria-label" ) || item.value; + if ( label && $.trim( label ).length ) { + this.liveRegion.children().hide(); + $( "
      " ).text( label ).appendTo( this.liveRegion ); + } + }, + menuselect: function( event, ui ) { + var item = ui.item.data( "ui-autocomplete-item" ), + previous = this.previous; + + // only trigger when focus was lost (click on menu) + if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) { + this.element.focus(); + this.previous = previous; + // #6109 - IE triggers two focus events and the second + // is asynchronous, so we need to reset the previous + // term synchronously and asynchronously :-( + this._delay(function() { + this.previous = previous; + this.selectedItem = item; + }); + } + + if ( false !== this._trigger( "select", event, { item: item } ) ) { + this._value( item.value ); + } + // reset the term after the select event + // this allows custom select handling to work properly + this.term = this._value(); + + this.close( event ); + this.selectedItem = item; + } + }); + + this.liveRegion = $( "", { + role: "status", + "aria-live": "assertive", + "aria-relevant": "additions" + }) + .addClass( "ui-helper-hidden-accessible" ) + .appendTo( this.document[ 0 ].body ); + + // turning off autocomplete prevents the browser from remembering the + // value when navigating through history, so we re-enable autocomplete + // if the page is unloaded before the widget is destroyed. #7790 + this._on( this.window, { + beforeunload: function() { + this.element.removeAttr( "autocomplete" ); + } + }); + }, + + _destroy: function() { + clearTimeout( this.searching ); + this.element + .removeClass( "ui-autocomplete-input" ) + .removeAttr( "autocomplete" ); + this.menu.element.remove(); + this.liveRegion.remove(); + }, + + _setOption: function( key, value ) { + this._super( key, value ); + if ( key === "source" ) { + this._initSource(); + } + if ( key === "appendTo" ) { + this.menu.element.appendTo( this._appendTo() ); + } + if ( key === "disabled" && value && this.xhr ) { + this.xhr.abort(); + } + }, + + _appendTo: function() { + var element = this.options.appendTo; + + if ( element ) { + element = element.jquery || element.nodeType ? + $( element ) : + this.document.find( element ).eq( 0 ); + } + + if ( !element || !element[ 0 ] ) { + element = this.element.closest( ".ui-front" ); + } + + if ( !element.length ) { + element = this.document[ 0 ].body; + } + + return element; + }, + + _initSource: function() { + var array, url, + that = this; + if ( $.isArray( this.options.source ) ) { + array = this.options.source; + this.source = function( request, response ) { + response( $.ui.autocomplete.filter( array, request.term ) ); + }; + } else if ( typeof this.options.source === "string" ) { + url = this.options.source; + this.source = function( request, response ) { + if ( that.xhr ) { + that.xhr.abort(); + } + that.xhr = $.ajax({ + url: url, + data: request, + dataType: "json", + success: function( data ) { + response( data ); + }, + error: function() { + response([]); + } + }); + }; + } else { + this.source = this.options.source; + } + }, + + _searchTimeout: function( event ) { + clearTimeout( this.searching ); + this.searching = this._delay(function() { + + // Search if the value has changed, or if the user retypes the same value (see #7434) + var equalValues = this.term === this._value(), + menuVisible = this.menu.element.is( ":visible" ), + modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; + + if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { + this.selectedItem = null; + this.search( null, event ); + } + }, this.options.delay ); + }, + + search: function( value, event ) { + value = value != null ? value : this._value(); + + // always save the actual value, not the one passed as an argument + this.term = this._value(); + + if ( value.length < this.options.minLength ) { + return this.close( event ); + } + + if ( this._trigger( "search", event ) === false ) { + return; + } + + return this._search( value ); + }, + + _search: function( value ) { + this.pending++; + this.element.addClass( "ui-autocomplete-loading" ); + this.cancelSearch = false; + + this.source( { term: value }, this._response() ); + }, + + _response: function() { + var index = ++this.requestIndex; + + return $.proxy(function( content ) { + if ( index === this.requestIndex ) { + this.__response( content ); + } + + this.pending--; + if ( !this.pending ) { + this.element.removeClass( "ui-autocomplete-loading" ); + } + }, this ); + }, + + __response: function( content ) { + if ( content ) { + content = this._normalize( content ); + } + this._trigger( "response", null, { content: content } ); + if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { + this._suggest( content ); + this._trigger( "open" ); + } else { + // use ._close() instead of .close() so we don't cancel future searches + this._close(); + } + }, + + close: function( event ) { + this.cancelSearch = true; + this._close( event ); + }, + + _close: function( event ) { + if ( this.menu.element.is( ":visible" ) ) { + this.menu.element.hide(); + this.menu.blur(); + this.isNewMenu = true; + this._trigger( "close", event ); + } + }, + + _change: function( event ) { + if ( this.previous !== this._value() ) { + this._trigger( "change", event, { item: this.selectedItem } ); + } + }, + + _normalize: function( items ) { + // assume all items have the right format when the first item is complete + if ( items.length && items[ 0 ].label && items[ 0 ].value ) { + return items; + } + return $.map( items, function( item ) { + if ( typeof item === "string" ) { + return { + label: item, + value: item + }; + } + return $.extend( {}, item, { + label: item.label || item.value, + value: item.value || item.label + }); + }); + }, + + _suggest: function( items ) { + var ul = this.menu.element.empty(); + this._renderMenu( ul, items ); + this.isNewMenu = true; + this.menu.refresh(); + + // size and position menu + ul.show(); + this._resizeMenu(); + ul.position( $.extend({ + of: this.element + }, this.options.position ) ); + + if ( this.options.autoFocus ) { + this.menu.next(); + } + }, + + _resizeMenu: function() { + var ul = this.menu.element; + ul.outerWidth( Math.max( + // Firefox wraps long text (possibly a rounding bug) + // so we add 1px to avoid the wrapping (#7513) + ul.width( "" ).outerWidth() + 1, + this.element.outerWidth() + ) ); + }, + + _renderMenu: function( ul, items ) { + var that = this; + $.each( items, function( index, item ) { + that._renderItemData( ul, item ); + }); + }, + + _renderItemData: function( ul, item ) { + return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); + }, + + _renderItem: function( ul, item ) { + return $( "
    • " ).text( item.label ).appendTo( ul ); + }, + + _move: function( direction, event ) { + if ( !this.menu.element.is( ":visible" ) ) { + this.search( null, event ); + return; + } + if ( this.menu.isFirstItem() && /^previous/.test( direction ) || + this.menu.isLastItem() && /^next/.test( direction ) ) { + + if ( !this.isMultiLine ) { + this._value( this.term ); + } + + this.menu.blur(); + return; + } + this.menu[ direction ]( event ); + }, + + widget: function() { + return this.menu.element; + }, + + _value: function() { + return this.valueMethod.apply( this.element, arguments ); + }, + + _keyEvent: function( keyEvent, event ) { + if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { + this._move( keyEvent, event ); + + // prevents moving cursor to beginning/end of the text field in some browsers + event.preventDefault(); + } + } +}); + +$.extend( $.ui.autocomplete, { + escapeRegex: function( value ) { + return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); + }, + filter: function( array, term ) { + var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); + return $.grep( array, function( value ) { + return matcher.test( value.label || value.value || value ); + }); + } +}); + +// live region extension, adding a `messages` option +// NOTE: This is an experimental API. We are still investigating +// a full solution for string manipulation and internationalization. +$.widget( "ui.autocomplete", $.ui.autocomplete, { + options: { + messages: { + noResults: "No search results.", + results: function( amount ) { + return amount + ( amount > 1 ? " results are" : " result is" ) + + " available, use up and down arrow keys to navigate."; + } + } + }, + + __response: function( content ) { + var message; + this._superApply( arguments ); + if ( this.options.disabled || this.cancelSearch ) { + return; + } + if ( content && content.length ) { + message = this.options.messages.results( content.length ); + } else { + message = this.options.messages.noResults; + } + this.liveRegion.children().hide(); + $( "
      " ).text( message ).appendTo( this.liveRegion ); + } +}); + +var autocomplete = $.ui.autocomplete; + + +/*! + * jQuery UI Button 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/button/ + */ + + +var lastActive, + baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", + typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", + formResetHandler = function() { + var form = $( this ); + setTimeout(function() { + form.find( ":ui-button" ).button( "refresh" ); + }, 1 ); + }, + radioGroup = function( radio ) { + var name = radio.name, + form = radio.form, + radios = $( [] ); + if ( name ) { + name = name.replace( /'/g, "\\'" ); + if ( form ) { + radios = $( form ).find( "[name='" + name + "'][type=radio]" ); + } else { + radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument ) + .filter(function() { + return !this.form; + }); + } + } + return radios; + }; + +$.widget( "ui.button", { + version: "1.11.4", + defaultElement: "").addClass(this._triggerClass). + html(!buttonImage ? buttonText : $("").attr( + { src:buttonImage, alt:buttonText, title:buttonText }))); + input[isRTL ? "before" : "after"](inst.trigger); + inst.trigger.click(function() { + if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { + $.datepicker._hideDatepicker(); + } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { + $.datepicker._hideDatepicker(); + $.datepicker._showDatepicker(input[0]); + } else { + $.datepicker._showDatepicker(input[0]); + } + return false; + }); + } + }, + + /* Apply the maximum length for the date format. */ + _autoSize: function(inst) { + if (this._get(inst, "autoSize") && !inst.inline) { + var findMax, max, maxI, i, + date = new Date(2009, 12 - 1, 20), // Ensure double digits + dateFormat = this._get(inst, "dateFormat"); + + if (dateFormat.match(/[DM]/)) { + findMax = function(names) { + max = 0; + maxI = 0; + for (i = 0; i < names.length; i++) { + if (names[i].length > max) { + max = names[i].length; + maxI = i; + } + } + return maxI; + }; + date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? + "monthNames" : "monthNamesShort")))); + date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? + "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); + } + inst.input.attr("size", this._formatDate(inst, date).length); + } + }, + + /* Attach an inline date picker to a div. */ + _inlineDatepicker: function(target, inst) { + var divSpan = $(target); + if (divSpan.hasClass(this.markerClassName)) { + return; + } + divSpan.addClass(this.markerClassName).append(inst.dpDiv); + $.data(target, "datepicker", inst); + this._setDate(inst, this._getDefaultDate(inst), true); + this._updateDatepicker(inst); + this._updateAlternate(inst); + //If disabled option is true, disable the datepicker before showing it (see ticket #5665) + if( inst.settings.disabled ) { + this._disableDatepicker( target ); + } + // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements + // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height + inst.dpDiv.css( "display", "block" ); + }, + + /* Pop-up the date picker in a "dialog" box. + * @param input element - ignored + * @param date string or Date - the initial date to display + * @param onSelect function - the function to call when a date is selected + * @param settings object - update the dialog date picker instance's settings (anonymous object) + * @param pos int[2] - coordinates for the dialog's position within the screen or + * event - with x/y coordinates or + * leave empty for default (screen centre) + * @return the manager object + */ + _dialogDatepicker: function(input, date, onSelect, settings, pos) { + var id, browserWidth, browserHeight, scrollX, scrollY, + inst = this._dialogInst; // internal instance + + if (!inst) { + this.uuid += 1; + id = "dp" + this.uuid; + this._dialogInput = $(""); + this._dialogInput.keydown(this._doKeyDown); + $("body").append(this._dialogInput); + inst = this._dialogInst = this._newInst(this._dialogInput, false); + inst.settings = {}; + $.data(this._dialogInput[0], "datepicker", inst); + } + datepicker_extendRemove(inst.settings, settings || {}); + date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); + this._dialogInput.val(date); + + this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); + if (!this._pos) { + browserWidth = document.documentElement.clientWidth; + browserHeight = document.documentElement.clientHeight; + scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; + scrollY = document.documentElement.scrollTop || document.body.scrollTop; + this._pos = // should use actual width/height below + [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; + } + + // move input on screen for focus, but hidden behind dialog + this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); + inst.settings.onSelect = onSelect; + this._inDialog = true; + this.dpDiv.addClass(this._dialogClass); + this._showDatepicker(this._dialogInput[0]); + if ($.blockUI) { + $.blockUI(this.dpDiv); + } + $.data(this._dialogInput[0], "datepicker", inst); + return this; + }, + + /* Detach a datepicker from its control. + * @param target element - the target input field or division or span + */ + _destroyDatepicker: function(target) { + var nodeName, + $target = $(target), + inst = $.data(target, "datepicker"); + + if (!$target.hasClass(this.markerClassName)) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + $.removeData(target, "datepicker"); + if (nodeName === "input") { + inst.append.remove(); + inst.trigger.remove(); + $target.removeClass(this.markerClassName). + unbind("focus", this._showDatepicker). + unbind("keydown", this._doKeyDown). + unbind("keypress", this._doKeyPress). + unbind("keyup", this._doKeyUp); + } else if (nodeName === "div" || nodeName === "span") { + $target.removeClass(this.markerClassName).empty(); + } + + if ( datepicker_instActive === inst ) { + datepicker_instActive = null; + } + }, + + /* Enable the date picker to a jQuery selection. + * @param target element - the target input field or division or span + */ + _enableDatepicker: function(target) { + var nodeName, inline, + $target = $(target), + inst = $.data(target, "datepicker"); + + if (!$target.hasClass(this.markerClassName)) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + if (nodeName === "input") { + target.disabled = false; + inst.trigger.filter("button"). + each(function() { this.disabled = false; }).end(). + filter("img").css({opacity: "1.0", cursor: ""}); + } else if (nodeName === "div" || nodeName === "span") { + inline = $target.children("." + this._inlineClass); + inline.children().removeClass("ui-state-disabled"); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). + prop("disabled", false); + } + this._disabledInputs = $.map(this._disabledInputs, + function(value) { return (value === target ? null : value); }); // delete entry + }, + + /* Disable the date picker to a jQuery selection. + * @param target element - the target input field or division or span + */ + _disableDatepicker: function(target) { + var nodeName, inline, + $target = $(target), + inst = $.data(target, "datepicker"); + + if (!$target.hasClass(this.markerClassName)) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + if (nodeName === "input") { + target.disabled = true; + inst.trigger.filter("button"). + each(function() { this.disabled = true; }).end(). + filter("img").css({opacity: "0.5", cursor: "default"}); + } else if (nodeName === "div" || nodeName === "span") { + inline = $target.children("." + this._inlineClass); + inline.children().addClass("ui-state-disabled"); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). + prop("disabled", true); + } + this._disabledInputs = $.map(this._disabledInputs, + function(value) { return (value === target ? null : value); }); // delete entry + this._disabledInputs[this._disabledInputs.length] = target; + }, + + /* Is the first field in a jQuery collection disabled as a datepicker? + * @param target element - the target input field or division or span + * @return boolean - true if disabled, false if enabled + */ + _isDisabledDatepicker: function(target) { + if (!target) { + return false; + } + for (var i = 0; i < this._disabledInputs.length; i++) { + if (this._disabledInputs[i] === target) { + return true; + } + } + return false; + }, + + /* Retrieve the instance data for the target control. + * @param target element - the target input field or division or span + * @return object - the associated instance data + * @throws error if a jQuery problem getting data + */ + _getInst: function(target) { + try { + return $.data(target, "datepicker"); + } + catch (err) { + throw "Missing instance data for this datepicker"; + } + }, + + /* Update or retrieve the settings for a date picker attached to an input field or division. + * @param target element - the target input field or division or span + * @param name object - the new settings to update or + * string - the name of the setting to change or retrieve, + * when retrieving also "all" for all instance settings or + * "defaults" for all global defaults + * @param value any - the new value for the setting + * (omit if above is an object or to retrieve a value) + */ + _optionDatepicker: function(target, name, value) { + var settings, date, minDate, maxDate, + inst = this._getInst(target); + + if (arguments.length === 2 && typeof name === "string") { + return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : + (inst ? (name === "all" ? $.extend({}, inst.settings) : + this._get(inst, name)) : null)); + } + + settings = name || {}; + if (typeof name === "string") { + settings = {}; + settings[name] = value; + } + + if (inst) { + if (this._curInst === inst) { + this._hideDatepicker(); + } + + date = this._getDateDatepicker(target, true); + minDate = this._getMinMaxDate(inst, "min"); + maxDate = this._getMinMaxDate(inst, "max"); + datepicker_extendRemove(inst.settings, settings); + // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided + if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { + inst.settings.minDate = this._formatDate(inst, minDate); + } + if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { + inst.settings.maxDate = this._formatDate(inst, maxDate); + } + if ( "disabled" in settings ) { + if ( settings.disabled ) { + this._disableDatepicker(target); + } else { + this._enableDatepicker(target); + } + } + this._attachments($(target), inst); + this._autoSize(inst); + this._setDate(inst, date); + this._updateAlternate(inst); + this._updateDatepicker(inst); + } + }, + + // change method deprecated + _changeDatepicker: function(target, name, value) { + this._optionDatepicker(target, name, value); + }, + + /* Redraw the date picker attached to an input field or division. + * @param target element - the target input field or division or span + */ + _refreshDatepicker: function(target) { + var inst = this._getInst(target); + if (inst) { + this._updateDatepicker(inst); + } + }, + + /* Set the dates for a jQuery selection. + * @param target element - the target input field or division or span + * @param date Date - the new date + */ + _setDateDatepicker: function(target, date) { + var inst = this._getInst(target); + if (inst) { + this._setDate(inst, date); + this._updateDatepicker(inst); + this._updateAlternate(inst); + } + }, + + /* Get the date(s) for the first entry in a jQuery selection. + * @param target element - the target input field or division or span + * @param noDefault boolean - true if no default date is to be used + * @return Date - the current date + */ + _getDateDatepicker: function(target, noDefault) { + var inst = this._getInst(target); + if (inst && !inst.inline) { + this._setDateFromField(inst, noDefault); + } + return (inst ? this._getDate(inst) : null); + }, + + /* Handle keystrokes. */ + _doKeyDown: function(event) { + var onSelect, dateStr, sel, + inst = $.datepicker._getInst(event.target), + handled = true, + isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); + + inst._keyEvent = true; + if ($.datepicker._datepickerShowing) { + switch (event.keyCode) { + case 9: $.datepicker._hideDatepicker(); + handled = false; + break; // hide on tab out + case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + + $.datepicker._currentClass + ")", inst.dpDiv); + if (sel[0]) { + $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); + } + + onSelect = $.datepicker._get(inst, "onSelect"); + if (onSelect) { + dateStr = $.datepicker._formatDate(inst); + + // trigger custom callback + onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); + } else { + $.datepicker._hideDatepicker(); + } + + return false; // don't submit the form + case 27: $.datepicker._hideDatepicker(); + break; // hide on escape + case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? + -$.datepicker._get(inst, "stepBigMonths") : + -$.datepicker._get(inst, "stepMonths")), "M"); + break; // previous month/year on page up/+ ctrl + case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? + +$.datepicker._get(inst, "stepBigMonths") : + +$.datepicker._get(inst, "stepMonths")), "M"); + break; // next month/year on page down/+ ctrl + case 35: if (event.ctrlKey || event.metaKey) { + $.datepicker._clearDate(event.target); + } + handled = event.ctrlKey || event.metaKey; + break; // clear on ctrl or command +end + case 36: if (event.ctrlKey || event.metaKey) { + $.datepicker._gotoToday(event.target); + } + handled = event.ctrlKey || event.metaKey; + break; // current on ctrl or command +home + case 37: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); + } + handled = event.ctrlKey || event.metaKey; + // -1 day on ctrl or command +left + if (event.originalEvent.altKey) { + $.datepicker._adjustDate(event.target, (event.ctrlKey ? + -$.datepicker._get(inst, "stepBigMonths") : + -$.datepicker._get(inst, "stepMonths")), "M"); + } + // next month/year on alt +left on Mac + break; + case 38: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, -7, "D"); + } + handled = event.ctrlKey || event.metaKey; + break; // -1 week on ctrl or command +up + case 39: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); + } + handled = event.ctrlKey || event.metaKey; + // +1 day on ctrl or command +right + if (event.originalEvent.altKey) { + $.datepicker._adjustDate(event.target, (event.ctrlKey ? + +$.datepicker._get(inst, "stepBigMonths") : + +$.datepicker._get(inst, "stepMonths")), "M"); + } + // next month/year on alt +right + break; + case 40: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, +7, "D"); + } + handled = event.ctrlKey || event.metaKey; + break; // +1 week on ctrl or command +down + default: handled = false; + } + } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home + $.datepicker._showDatepicker(this); + } else { + handled = false; + } + + if (handled) { + event.preventDefault(); + event.stopPropagation(); + } + }, + + /* Filter entered characters - based on date format. */ + _doKeyPress: function(event) { + var chars, chr, + inst = $.datepicker._getInst(event.target); + + if ($.datepicker._get(inst, "constrainInput")) { + chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); + chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); + return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); + } + }, + + /* Synchronise manual entry and field/alternate field. */ + _doKeyUp: function(event) { + var date, + inst = $.datepicker._getInst(event.target); + + if (inst.input.val() !== inst.lastVal) { + try { + date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), + (inst.input ? inst.input.val() : null), + $.datepicker._getFormatConfig(inst)); + + if (date) { // only if valid + $.datepicker._setDateFromField(inst); + $.datepicker._updateAlternate(inst); + $.datepicker._updateDatepicker(inst); + } + } + catch (err) { + } + } + return true; + }, + + /* Pop-up the date picker for a given input field. + * If false returned from beforeShow event handler do not show. + * @param input element - the input field attached to the date picker or + * event - if triggered by focus + */ + _showDatepicker: function(input) { + input = input.target || input; + if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger + input = $("input", input.parentNode)[0]; + } + + if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here + return; + } + + var inst, beforeShow, beforeShowSettings, isFixed, + offset, showAnim, duration; + + inst = $.datepicker._getInst(input); + if ($.datepicker._curInst && $.datepicker._curInst !== inst) { + $.datepicker._curInst.dpDiv.stop(true, true); + if ( inst && $.datepicker._datepickerShowing ) { + $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); + } + } + + beforeShow = $.datepicker._get(inst, "beforeShow"); + beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; + if(beforeShowSettings === false){ + return; + } + datepicker_extendRemove(inst.settings, beforeShowSettings); + + inst.lastVal = null; + $.datepicker._lastInput = input; + $.datepicker._setDateFromField(inst); + + if ($.datepicker._inDialog) { // hide cursor + input.value = ""; + } + if (!$.datepicker._pos) { // position below input + $.datepicker._pos = $.datepicker._findPos(input); + $.datepicker._pos[1] += input.offsetHeight; // add the height + } + + isFixed = false; + $(input).parents().each(function() { + isFixed |= $(this).css("position") === "fixed"; + return !isFixed; + }); + + offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; + $.datepicker._pos = null; + //to avoid flashes on Firefox + inst.dpDiv.empty(); + // determine sizing offscreen + inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); + $.datepicker._updateDatepicker(inst); + // fix width for dynamic number of date pickers + // and adjust position before showing + offset = $.datepicker._checkOffset(inst, offset, isFixed); + inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? + "static" : (isFixed ? "fixed" : "absolute")), display: "none", + left: offset.left + "px", top: offset.top + "px"}); + + if (!inst.inline) { + showAnim = $.datepicker._get(inst, "showAnim"); + duration = $.datepicker._get(inst, "duration"); + inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); + $.datepicker._datepickerShowing = true; + + if ( $.effects && $.effects.effect[ showAnim ] ) { + inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); + } else { + inst.dpDiv[showAnim || "show"](showAnim ? duration : null); + } + + if ( $.datepicker._shouldFocusInput( inst ) ) { + inst.input.focus(); + } + + $.datepicker._curInst = inst; + } + }, + + /* Generate the date picker content. */ + _updateDatepicker: function(inst) { + this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) + datepicker_instActive = inst; // for delegate hover events + inst.dpDiv.empty().append(this._generateHTML(inst)); + this._attachHandlers(inst); + + var origyearshtml, + numMonths = this._getNumberOfMonths(inst), + cols = numMonths[1], + width = 17, + activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ); + + if ( activeCell.length > 0 ) { + datepicker_handleMouseover.apply( activeCell.get( 0 ) ); + } + + inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); + if (cols > 1) { + inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); + } + inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + + "Class"]("ui-datepicker-multi"); + inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + + "Class"]("ui-datepicker-rtl"); + + if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { + inst.input.focus(); + } + + // deffered render of the years select (to avoid flashes on Firefox) + if( inst.yearshtml ){ + origyearshtml = inst.yearshtml; + setTimeout(function(){ + //assure that inst.yearshtml didn't change. + if( origyearshtml === inst.yearshtml && inst.yearshtml ){ + inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); + } + origyearshtml = inst.yearshtml = null; + }, 0); + } + }, + + // #6694 - don't focus the input if it's already focused + // this breaks the change event in IE + // Support: IE and jQuery <1.9 + _shouldFocusInput: function( inst ) { + return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); + }, + + /* Check positioning to remain on screen. */ + _checkOffset: function(inst, offset, isFixed) { + var dpWidth = inst.dpDiv.outerWidth(), + dpHeight = inst.dpDiv.outerHeight(), + inputWidth = inst.input ? inst.input.outerWidth() : 0, + inputHeight = inst.input ? inst.input.outerHeight() : 0, + viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), + viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); + + offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); + offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; + offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; + + // now check if datepicker is showing outside window viewport - move to a better place if so. + offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? + Math.abs(offset.left + dpWidth - viewWidth) : 0); + offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? + Math.abs(dpHeight + inputHeight) : 0); + + return offset; + }, + + /* Find an object's position on the screen. */ + _findPos: function(obj) { + var position, + inst = this._getInst(obj), + isRTL = this._get(inst, "isRTL"); + + while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { + obj = obj[isRTL ? "previousSibling" : "nextSibling"]; + } + + position = $(obj).offset(); + return [position.left, position.top]; + }, + + /* Hide the date picker from view. + * @param input element - the input field attached to the date picker + */ + _hideDatepicker: function(input) { + var showAnim, duration, postProcess, onClose, + inst = this._curInst; + + if (!inst || (input && inst !== $.data(input, "datepicker"))) { + return; + } + + if (this._datepickerShowing) { + showAnim = this._get(inst, "showAnim"); + duration = this._get(inst, "duration"); + postProcess = function() { + $.datepicker._tidyDialog(inst); + }; + + // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed + if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { + inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); + } else { + inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : + (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); + } + + if (!showAnim) { + postProcess(); + } + this._datepickerShowing = false; + + onClose = this._get(inst, "onClose"); + if (onClose) { + onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); + } + + this._lastInput = null; + if (this._inDialog) { + this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); + if ($.blockUI) { + $.unblockUI(); + $("body").append(this.dpDiv); + } + } + this._inDialog = false; + } + }, + + /* Tidy up after a dialog display. */ + _tidyDialog: function(inst) { + inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); + }, + + /* Close date picker if clicked elsewhere. */ + _checkExternalClick: function(event) { + if (!$.datepicker._curInst) { + return; + } + + var $target = $(event.target), + inst = $.datepicker._getInst($target[0]); + + if ( ( ( $target[0].id !== $.datepicker._mainDivId && + $target.parents("#" + $.datepicker._mainDivId).length === 0 && + !$target.hasClass($.datepicker.markerClassName) && + !$target.closest("." + $.datepicker._triggerClass).length && + $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || + ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { + $.datepicker._hideDatepicker(); + } + }, + + /* Adjust one of the date sub-fields. */ + _adjustDate: function(id, offset, period) { + var target = $(id), + inst = this._getInst(target[0]); + + if (this._isDisabledDatepicker(target[0])) { + return; + } + this._adjustInstDate(inst, offset + + (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning + period); + this._updateDatepicker(inst); + }, + + /* Action for current link. */ + _gotoToday: function(id) { + var date, + target = $(id), + inst = this._getInst(target[0]); + + if (this._get(inst, "gotoCurrent") && inst.currentDay) { + inst.selectedDay = inst.currentDay; + inst.drawMonth = inst.selectedMonth = inst.currentMonth; + inst.drawYear = inst.selectedYear = inst.currentYear; + } else { + date = new Date(); + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + } + this._notifyChange(inst); + this._adjustDate(target); + }, + + /* Action for selecting a new month/year. */ + _selectMonthYear: function(id, select, period) { + var target = $(id), + inst = this._getInst(target[0]); + + inst["selected" + (period === "M" ? "Month" : "Year")] = + inst["draw" + (period === "M" ? "Month" : "Year")] = + parseInt(select.options[select.selectedIndex].value,10); + + this._notifyChange(inst); + this._adjustDate(target); + }, + + /* Action for selecting a day. */ + _selectDay: function(id, month, year, td) { + var inst, + target = $(id); + + if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { + return; + } + + inst = this._getInst(target[0]); + inst.selectedDay = inst.currentDay = $("a", td).html(); + inst.selectedMonth = inst.currentMonth = month; + inst.selectedYear = inst.currentYear = year; + this._selectDate(id, this._formatDate(inst, + inst.currentDay, inst.currentMonth, inst.currentYear)); + }, + + /* Erase the input field and hide the date picker. */ + _clearDate: function(id) { + var target = $(id); + this._selectDate(target, ""); + }, + + /* Update the input field with the selected date. */ + _selectDate: function(id, dateStr) { + var onSelect, + target = $(id), + inst = this._getInst(target[0]); + + dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); + if (inst.input) { + inst.input.val(dateStr); + } + this._updateAlternate(inst); + + onSelect = this._get(inst, "onSelect"); + if (onSelect) { + onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback + } else if (inst.input) { + inst.input.trigger("change"); // fire the change event + } + + if (inst.inline){ + this._updateDatepicker(inst); + } else { + this._hideDatepicker(); + this._lastInput = inst.input[0]; + if (typeof(inst.input[0]) !== "object") { + inst.input.focus(); // restore focus + } + this._lastInput = null; + } + }, + + /* Update any alternate field to synchronise with the main field. */ + _updateAlternate: function(inst) { + var altFormat, date, dateStr, + altField = this._get(inst, "altField"); + + if (altField) { // update alternate field too + altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); + date = this._getDate(inst); + dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); + $(altField).each(function() { $(this).val(dateStr); }); + } + }, + + /* Set as beforeShowDay function to prevent selection of weekends. + * @param date Date - the date to customise + * @return [boolean, string] - is this date selectable?, what is its CSS class? + */ + noWeekends: function(date) { + var day = date.getDay(); + return [(day > 0 && day < 6), ""]; + }, + + /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. + * @param date Date - the date to get the week for + * @return number - the number of the week within the year that contains this date + */ + iso8601Week: function(date) { + var time, + checkDate = new Date(date.getTime()); + + // Find Thursday of this week starting on Monday + checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); + + time = checkDate.getTime(); + checkDate.setMonth(0); // Compare with Jan 1 + checkDate.setDate(1); + return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; + }, + + /* Parse a string value into a date object. + * See formatDate below for the possible formats. + * + * @param format string - the expected format of the date + * @param value string - the date in the above format + * @param settings Object - attributes include: + * shortYearCutoff number - the cutoff year for determining the century (optional) + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + * dayNames string[7] - names of the days from Sunday (optional) + * monthNamesShort string[12] - abbreviated names of the months (optional) + * monthNames string[12] - names of the months (optional) + * @return Date - the extracted date value or null if value is blank + */ + parseDate: function (format, value, settings) { + if (format == null || value == null) { + throw "Invalid arguments"; + } + + value = (typeof value === "object" ? value.toString() : value + ""); + if (value === "") { + return null; + } + + var iFormat, dim, extra, + iValue = 0, + shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, + shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : + new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), + dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, + dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, + monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, + monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, + year = -1, + month = -1, + day = -1, + doy = -1, + literal = false, + date, + // Check whether a format character is doubled + lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); + if (matches) { + iFormat++; + } + return matches; + }, + // Extract a number from the string value + getNumber = function(match) { + var isDoubled = lookAhead(match), + size = (match === "@" ? 14 : (match === "!" ? 20 : + (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), + minSize = (match === "y" ? size : 1), + digits = new RegExp("^\\d{" + minSize + "," + size + "}"), + num = value.substring(iValue).match(digits); + if (!num) { + throw "Missing number at position " + iValue; + } + iValue += num[0].length; + return parseInt(num[0], 10); + }, + // Extract a name from the string value and convert to an index + getName = function(match, shortNames, longNames) { + var index = -1, + names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { + return [ [k, v] ]; + }).sort(function (a, b) { + return -(a[1].length - b[1].length); + }); + + $.each(names, function (i, pair) { + var name = pair[1]; + if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { + index = pair[0]; + iValue += name.length; + return false; + } + }); + if (index !== -1) { + return index + 1; + } else { + throw "Unknown name at position " + iValue; + } + }, + // Confirm that a literal character matches the string value + checkLiteral = function() { + if (value.charAt(iValue) !== format.charAt(iFormat)) { + throw "Unexpected literal at position " + iValue; + } + iValue++; + }; + + for (iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + literal = false; + } else { + checkLiteral(); + } + } else { + switch (format.charAt(iFormat)) { + case "d": + day = getNumber("d"); + break; + case "D": + getName("D", dayNamesShort, dayNames); + break; + case "o": + doy = getNumber("o"); + break; + case "m": + month = getNumber("m"); + break; + case "M": + month = getName("M", monthNamesShort, monthNames); + break; + case "y": + year = getNumber("y"); + break; + case "@": + date = new Date(getNumber("@")); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case "!": + date = new Date((getNumber("!") - this._ticksTo1970) / 10000); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case "'": + if (lookAhead("'")){ + checkLiteral(); + } else { + literal = true; + } + break; + default: + checkLiteral(); + } + } + } + + if (iValue < value.length){ + extra = value.substr(iValue); + if (!/^\s+/.test(extra)) { + throw "Extra/unparsed characters found in date: " + extra; + } + } + + if (year === -1) { + year = new Date().getFullYear(); + } else if (year < 100) { + year += new Date().getFullYear() - new Date().getFullYear() % 100 + + (year <= shortYearCutoff ? 0 : -100); + } + + if (doy > -1) { + month = 1; + day = doy; + do { + dim = this._getDaysInMonth(year, month - 1); + if (day <= dim) { + break; + } + month++; + day -= dim; + } while (true); + } + + date = this._daylightSavingAdjust(new Date(year, month - 1, day)); + if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { + throw "Invalid date"; // E.g. 31/02/00 + } + return date; + }, + + /* Standard date formats. */ + ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) + COOKIE: "D, dd M yy", + ISO_8601: "yy-mm-dd", + RFC_822: "D, d M y", + RFC_850: "DD, dd-M-y", + RFC_1036: "D, d M y", + RFC_1123: "D, d M yy", + RFC_2822: "D, d M yy", + RSS: "D, d M y", // RFC 822 + TICKS: "!", + TIMESTAMP: "@", + W3C: "yy-mm-dd", // ISO 8601 + + _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + + Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), + + /* Format a date object into a string value. + * The format can be combinations of the following: + * d - day of month (no leading zero) + * dd - day of month (two digit) + * o - day of year (no leading zeros) + * oo - day of year (three digit) + * D - day name short + * DD - day name long + * m - month of year (no leading zero) + * mm - month of year (two digit) + * M - month name short + * MM - month name long + * y - year (two digit) + * yy - year (four digit) + * @ - Unix timestamp (ms since 01/01/1970) + * ! - Windows ticks (100ns since 01/01/0001) + * "..." - literal text + * '' - single quote + * + * @param format string - the desired format of the date + * @param date Date - the date value to format + * @param settings Object - attributes include: + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + * dayNames string[7] - names of the days from Sunday (optional) + * monthNamesShort string[12] - abbreviated names of the months (optional) + * monthNames string[12] - names of the months (optional) + * @return string - the date in the above format + */ + formatDate: function (format, date, settings) { + if (!date) { + return ""; + } + + var iFormat, + dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, + dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, + monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, + monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, + // Check whether a format character is doubled + lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); + if (matches) { + iFormat++; + } + return matches; + }, + // Format a number, with leading zero if necessary + formatNumber = function(match, value, len) { + var num = "" + value; + if (lookAhead(match)) { + while (num.length < len) { + num = "0" + num; + } + } + return num; + }, + // Format a name, short or long as requested + formatName = function(match, value, shortNames, longNames) { + return (lookAhead(match) ? longNames[value] : shortNames[value]); + }, + output = "", + literal = false; + + if (date) { + for (iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + literal = false; + } else { + output += format.charAt(iFormat); + } + } else { + switch (format.charAt(iFormat)) { + case "d": + output += formatNumber("d", date.getDate(), 2); + break; + case "D": + output += formatName("D", date.getDay(), dayNamesShort, dayNames); + break; + case "o": + output += formatNumber("o", + Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); + break; + case "m": + output += formatNumber("m", date.getMonth() + 1, 2); + break; + case "M": + output += formatName("M", date.getMonth(), monthNamesShort, monthNames); + break; + case "y": + output += (lookAhead("y") ? date.getFullYear() : + (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); + break; + case "@": + output += date.getTime(); + break; + case "!": + output += date.getTime() * 10000 + this._ticksTo1970; + break; + case "'": + if (lookAhead("'")) { + output += "'"; + } else { + literal = true; + } + break; + default: + output += format.charAt(iFormat); + } + } + } + } + return output; + }, + + /* Extract all possible characters from the date format. */ + _possibleChars: function (format) { + var iFormat, + chars = "", + literal = false, + // Check whether a format character is doubled + lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); + if (matches) { + iFormat++; + } + return matches; + }; + + for (iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + literal = false; + } else { + chars += format.charAt(iFormat); + } + } else { + switch (format.charAt(iFormat)) { + case "d": case "m": case "y": case "@": + chars += "0123456789"; + break; + case "D": case "M": + return null; // Accept anything + case "'": + if (lookAhead("'")) { + chars += "'"; + } else { + literal = true; + } + break; + default: + chars += format.charAt(iFormat); + } + } + } + return chars; + }, + + /* Get a setting value, defaulting if necessary. */ + _get: function(inst, name) { + return inst.settings[name] !== undefined ? + inst.settings[name] : this._defaults[name]; + }, + + /* Parse existing date and initialise date picker. */ + _setDateFromField: function(inst, noDefault) { + if (inst.input.val() === inst.lastVal) { + return; + } + + var dateFormat = this._get(inst, "dateFormat"), + dates = inst.lastVal = inst.input ? inst.input.val() : null, + defaultDate = this._getDefaultDate(inst), + date = defaultDate, + settings = this._getFormatConfig(inst); + + try { + date = this.parseDate(dateFormat, dates, settings) || defaultDate; + } catch (event) { + dates = (noDefault ? "" : dates); + } + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + inst.currentDay = (dates ? date.getDate() : 0); + inst.currentMonth = (dates ? date.getMonth() : 0); + inst.currentYear = (dates ? date.getFullYear() : 0); + this._adjustInstDate(inst); + }, + + /* Retrieve the default date shown on opening. */ + _getDefaultDate: function(inst) { + return this._restrictMinMax(inst, + this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); + }, + + /* A date may be specified as an exact value or a relative one. */ + _determineDate: function(inst, date, defaultDate) { + var offsetNumeric = function(offset) { + var date = new Date(); + date.setDate(date.getDate() + offset); + return date; + }, + offsetString = function(offset) { + try { + return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), + offset, $.datepicker._getFormatConfig(inst)); + } + catch (e) { + // Ignore + } + + var date = (offset.toLowerCase().match(/^c/) ? + $.datepicker._getDate(inst) : null) || new Date(), + year = date.getFullYear(), + month = date.getMonth(), + day = date.getDate(), + pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, + matches = pattern.exec(offset); + + while (matches) { + switch (matches[2] || "d") { + case "d" : case "D" : + day += parseInt(matches[1],10); break; + case "w" : case "W" : + day += parseInt(matches[1],10) * 7; break; + case "m" : case "M" : + month += parseInt(matches[1],10); + day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); + break; + case "y": case "Y" : + year += parseInt(matches[1],10); + day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); + break; + } + matches = pattern.exec(offset); + } + return new Date(year, month, day); + }, + newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : + (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); + + newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); + if (newDate) { + newDate.setHours(0); + newDate.setMinutes(0); + newDate.setSeconds(0); + newDate.setMilliseconds(0); + } + return this._daylightSavingAdjust(newDate); + }, + + /* Handle switch to/from daylight saving. + * Hours may be non-zero on daylight saving cut-over: + * > 12 when midnight changeover, but then cannot generate + * midnight datetime, so jump to 1AM, otherwise reset. + * @param date (Date) the date to check + * @return (Date) the corrected date + */ + _daylightSavingAdjust: function(date) { + if (!date) { + return null; + } + date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); + return date; + }, + + /* Set the date(s) directly. */ + _setDate: function(inst, date, noChange) { + var clear = !date, + origMonth = inst.selectedMonth, + origYear = inst.selectedYear, + newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); + + inst.selectedDay = inst.currentDay = newDate.getDate(); + inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); + inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); + if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { + this._notifyChange(inst); + } + this._adjustInstDate(inst); + if (inst.input) { + inst.input.val(clear ? "" : this._formatDate(inst)); + } + }, + + /* Retrieve the date(s) directly. */ + _getDate: function(inst) { + var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : + this._daylightSavingAdjust(new Date( + inst.currentYear, inst.currentMonth, inst.currentDay))); + return startDate; + }, + + /* Attach the onxxx handlers. These are declared statically so + * they work with static code transformers like Caja. + */ + _attachHandlers: function(inst) { + var stepMonths = this._get(inst, "stepMonths"), + id = "#" + inst.id.replace( /\\\\/g, "\\" ); + inst.dpDiv.find("[data-handler]").map(function () { + var handler = { + prev: function () { + $.datepicker._adjustDate(id, -stepMonths, "M"); + }, + next: function () { + $.datepicker._adjustDate(id, +stepMonths, "M"); + }, + hide: function () { + $.datepicker._hideDatepicker(); + }, + today: function () { + $.datepicker._gotoToday(id); + }, + selectDay: function () { + $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); + return false; + }, + selectMonth: function () { + $.datepicker._selectMonthYear(id, this, "M"); + return false; + }, + selectYear: function () { + $.datepicker._selectMonthYear(id, this, "Y"); + return false; + } + }; + $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); + }); + }, + + /* Generate the HTML for the current state of the date picker. */ + _generateHTML: function(inst) { + var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, + controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, + monthNames, monthNamesShort, beforeShowDay, showOtherMonths, + selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, + cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, + printDate, dRow, tbody, daySettings, otherMonth, unselectable, + tempDate = new Date(), + today = this._daylightSavingAdjust( + new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time + isRTL = this._get(inst, "isRTL"), + showButtonPanel = this._get(inst, "showButtonPanel"), + hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), + navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), + numMonths = this._getNumberOfMonths(inst), + showCurrentAtPos = this._get(inst, "showCurrentAtPos"), + stepMonths = this._get(inst, "stepMonths"), + isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), + currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : + new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), + minDate = this._getMinMaxDate(inst, "min"), + maxDate = this._getMinMaxDate(inst, "max"), + drawMonth = inst.drawMonth - showCurrentAtPos, + drawYear = inst.drawYear; + + if (drawMonth < 0) { + drawMonth += 12; + drawYear--; + } + if (maxDate) { + maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), + maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); + maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); + while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { + drawMonth--; + if (drawMonth < 0) { + drawMonth = 11; + drawYear--; + } + } + } + inst.drawMonth = drawMonth; + inst.drawYear = drawYear; + + prevText = this._get(inst, "prevText"); + prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, + this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), + this._getFormatConfig(inst))); + + prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? + "" + prevText + "" : + (hideIfNoPrevNext ? "" : "" + prevText + "")); + + nextText = this._get(inst, "nextText"); + nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, + this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), + this._getFormatConfig(inst))); + + next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? + "" + nextText + "" : + (hideIfNoPrevNext ? "" : "" + nextText + "")); + + currentText = this._get(inst, "currentText"); + gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); + currentText = (!navigationAsDateFormat ? currentText : + this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); + + controls = (!inst.inline ? "" : ""); + + buttonPanel = (showButtonPanel) ? "
      " + (isRTL ? controls : "") + + (this._isInRange(inst, gotoDate) ? "" : "") + (isRTL ? "" : controls) + "
      " : ""; + + firstDay = parseInt(this._get(inst, "firstDay"),10); + firstDay = (isNaN(firstDay) ? 0 : firstDay); + + showWeek = this._get(inst, "showWeek"); + dayNames = this._get(inst, "dayNames"); + dayNamesMin = this._get(inst, "dayNamesMin"); + monthNames = this._get(inst, "monthNames"); + monthNamesShort = this._get(inst, "monthNamesShort"); + beforeShowDay = this._get(inst, "beforeShowDay"); + showOtherMonths = this._get(inst, "showOtherMonths"); + selectOtherMonths = this._get(inst, "selectOtherMonths"); + defaultDate = this._getDefaultDate(inst); + html = ""; + dow; + for (row = 0; row < numMonths[0]; row++) { + group = ""; + this.maxRows = 4; + for (col = 0; col < numMonths[1]; col++) { + selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); + cornerClass = " ui-corner-all"; + calender = ""; + if (isMultiMonth) { + calender += "
      "; + } + calender += "
      " + + (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + + (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + + this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, + row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers + "
      " + + ""; + thead = (showWeek ? "" : ""); + for (dow = 0; dow < 7; dow++) { // days of the week + day = (dow + firstDay) % 7; + thead += ""; + } + calender += thead + ""; + daysInMonth = this._getDaysInMonth(drawYear, drawMonth); + if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { + inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); + } + leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; + curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate + numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) + this.maxRows = numRows; + printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); + for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows + calender += ""; + tbody = (!showWeek ? "" : ""); + for (dow = 0; dow < 7; dow++) { // create date picker days + daySettings = (beforeShowDay ? + beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); + otherMonth = (printDate.getMonth() !== drawMonth); + unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || + (minDate && printDate < minDate) || (maxDate && printDate > maxDate); + tbody += ""; // display selectable date + printDate.setDate(printDate.getDate() + 1); + printDate = this._daylightSavingAdjust(printDate); + } + calender += tbody + ""; + } + drawMonth++; + if (drawMonth > 11) { + drawMonth = 0; + drawYear++; + } + calender += "
      " + this._get(inst, "weekHeader") + "= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + + "" + dayNamesMin[day] + "
      " + + this._get(inst, "calculateWeek")(printDate) + "" + // actions + (otherMonth && !showOtherMonths ? " " : // display for other months + (unselectable ? "" + printDate.getDate() + "" : "" + printDate.getDate() + "")) + "
      " + (isMultiMonth ? "
      " + + ((numMonths[0] > 0 && col === numMonths[1]-1) ? "
      " : "") : ""); + group += calender; + } + html += group; + } + html += buttonPanel; + inst._keyEvent = false; + return html; + }, + + /* Generate the month and year header. */ + _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, + secondary, monthNames, monthNamesShort) { + + var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, + changeMonth = this._get(inst, "changeMonth"), + changeYear = this._get(inst, "changeYear"), + showMonthAfterYear = this._get(inst, "showMonthAfterYear"), + html = "
      ", + monthHtml = ""; + + // month selection + if (secondary || !changeMonth) { + monthHtml += "" + monthNames[drawMonth] + ""; + } else { + inMinYear = (minDate && minDate.getFullYear() === drawYear); + inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); + monthHtml += ""; + } + + if (!showMonthAfterYear) { + html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); + } + + // year selection + if ( !inst.yearshtml ) { + inst.yearshtml = ""; + if (secondary || !changeYear) { + html += "" + drawYear + ""; + } else { + // determine range of years to display + years = this._get(inst, "yearRange").split(":"); + thisYear = new Date().getFullYear(); + determineYear = function(value) { + var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : + (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : + parseInt(value, 10))); + return (isNaN(year) ? thisYear : year); + }; + year = determineYear(years[0]); + endYear = Math.max(year, determineYear(years[1] || "")); + year = (minDate ? Math.max(year, minDate.getFullYear()) : year); + endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); + inst.yearshtml += ""; + + html += inst.yearshtml; + inst.yearshtml = null; + } + } + + html += this._get(inst, "yearSuffix"); + if (showMonthAfterYear) { + html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; + } + html += "
      "; // Close datepicker_header + return html; + }, + + /* Adjust one of the date sub-fields. */ + _adjustInstDate: function(inst, offset, period) { + var year = inst.drawYear + (period === "Y" ? offset : 0), + month = inst.drawMonth + (period === "M" ? offset : 0), + day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), + date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); + + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + if (period === "M" || period === "Y") { + this._notifyChange(inst); + } + }, + + /* Ensure a date is within any min/max bounds. */ + _restrictMinMax: function(inst, date) { + var minDate = this._getMinMaxDate(inst, "min"), + maxDate = this._getMinMaxDate(inst, "max"), + newDate = (minDate && date < minDate ? minDate : date); + return (maxDate && newDate > maxDate ? maxDate : newDate); + }, + + /* Notify change of month/year. */ + _notifyChange: function(inst) { + var onChange = this._get(inst, "onChangeMonthYear"); + if (onChange) { + onChange.apply((inst.input ? inst.input[0] : null), + [inst.selectedYear, inst.selectedMonth + 1, inst]); + } + }, + + /* Determine the number of months to show. */ + _getNumberOfMonths: function(inst) { + var numMonths = this._get(inst, "numberOfMonths"); + return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); + }, + + /* Determine the current maximum date - ensure no time components are set. */ + _getMinMaxDate: function(inst, minMax) { + return this._determineDate(inst, this._get(inst, minMax + "Date"), null); + }, + + /* Find the number of days in a given month. */ + _getDaysInMonth: function(year, month) { + return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); + }, + + /* Find the day of the week of the first of a month. */ + _getFirstDayOfMonth: function(year, month) { + return new Date(year, month, 1).getDay(); + }, + + /* Determines if we should allow a "next/prev" month display change. */ + _canAdjustMonth: function(inst, offset, curYear, curMonth) { + var numMonths = this._getNumberOfMonths(inst), + date = this._daylightSavingAdjust(new Date(curYear, + curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); + + if (offset < 0) { + date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); + } + return this._isInRange(inst, date); + }, + + /* Is the given date in the accepted range? */ + _isInRange: function(inst, date) { + var yearSplit, currentYear, + minDate = this._getMinMaxDate(inst, "min"), + maxDate = this._getMinMaxDate(inst, "max"), + minYear = null, + maxYear = null, + years = this._get(inst, "yearRange"); + if (years){ + yearSplit = years.split(":"); + currentYear = new Date().getFullYear(); + minYear = parseInt(yearSplit[0], 10); + maxYear = parseInt(yearSplit[1], 10); + if ( yearSplit[0].match(/[+\-].*/) ) { + minYear += currentYear; + } + if ( yearSplit[1].match(/[+\-].*/) ) { + maxYear += currentYear; + } + } + + return ((!minDate || date.getTime() >= minDate.getTime()) && + (!maxDate || date.getTime() <= maxDate.getTime()) && + (!minYear || date.getFullYear() >= minYear) && + (!maxYear || date.getFullYear() <= maxYear)); + }, + + /* Provide the configuration settings for formatting/parsing. */ + _getFormatConfig: function(inst) { + var shortYearCutoff = this._get(inst, "shortYearCutoff"); + shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : + new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); + return {shortYearCutoff: shortYearCutoff, + dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), + monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; + }, + + /* Format the given date for display. */ + _formatDate: function(inst, day, month, year) { + if (!day) { + inst.currentDay = inst.selectedDay; + inst.currentMonth = inst.selectedMonth; + inst.currentYear = inst.selectedYear; + } + var date = (day ? (typeof day === "object" ? day : + this._daylightSavingAdjust(new Date(year, month, day))) : + this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); + return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); + } +}); + +/* + * Bind hover events for datepicker elements. + * Done via delegate so the binding only occurs once in the lifetime of the parent div. + * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. + */ +function datepicker_bindHover(dpDiv) { + var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; + return dpDiv.delegate(selector, "mouseout", function() { + $(this).removeClass("ui-state-hover"); + if (this.className.indexOf("ui-datepicker-prev") !== -1) { + $(this).removeClass("ui-datepicker-prev-hover"); + } + if (this.className.indexOf("ui-datepicker-next") !== -1) { + $(this).removeClass("ui-datepicker-next-hover"); + } + }) + .delegate( selector, "mouseover", datepicker_handleMouseover ); +} + +function datepicker_handleMouseover() { + if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) { + $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); + $(this).addClass("ui-state-hover"); + if (this.className.indexOf("ui-datepicker-prev") !== -1) { + $(this).addClass("ui-datepicker-prev-hover"); + } + if (this.className.indexOf("ui-datepicker-next") !== -1) { + $(this).addClass("ui-datepicker-next-hover"); + } + } +} + +/* jQuery extend now ignores nulls! */ +function datepicker_extendRemove(target, props) { + $.extend(target, props); + for (var name in props) { + if (props[name] == null) { + target[name] = props[name]; + } + } + return target; +} + +/* Invoke the datepicker functionality. + @param options string - a command, optionally followed by additional parameters or + Object - settings for attaching new datepicker functionality + @return jQuery object */ +$.fn.datepicker = function(options){ + + /* Verify an empty collection wasn't passed - Fixes #6976 */ + if ( !this.length ) { + return this; + } + + /* Initialise the date picker. */ + if (!$.datepicker.initialized) { + $(document).mousedown($.datepicker._checkExternalClick); + $.datepicker.initialized = true; + } + + /* Append datepicker main container to body if not exist. */ + if ($("#"+$.datepicker._mainDivId).length === 0) { + $("body").append($.datepicker.dpDiv); + } + + var otherArgs = Array.prototype.slice.call(arguments, 1); + if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { + return $.datepicker["_" + options + "Datepicker"]. + apply($.datepicker, [this[0]].concat(otherArgs)); + } + if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { + return $.datepicker["_" + options + "Datepicker"]. + apply($.datepicker, [this[0]].concat(otherArgs)); + } + return this.each(function() { + typeof options === "string" ? + $.datepicker["_" + options + "Datepicker"]. + apply($.datepicker, [this].concat(otherArgs)) : + $.datepicker._attachDatepicker(this, options); + }); +}; + +$.datepicker = new Datepicker(); // singleton instance +$.datepicker.initialized = false; +$.datepicker.uuid = new Date().getTime(); +$.datepicker.version = "1.11.4"; + +var datepicker = $.datepicker; + + +/*! + * jQuery UI Draggable 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/draggable/ + */ + + +$.widget("ui.draggable", $.ui.mouse, { + version: "1.11.4", + widgetEventPrefix: "drag", + options: { + addClasses: true, + appendTo: "parent", + axis: false, + connectToSortable: false, + containment: false, + cursor: "auto", + cursorAt: false, + grid: false, + handle: false, + helper: "original", + iframeFix: false, + opacity: false, + refreshPositions: false, + revert: false, + revertDuration: 500, + scope: "default", + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + snap: false, + snapMode: "both", + snapTolerance: 20, + stack: false, + zIndex: false, + + // callbacks + drag: null, + start: null, + stop: null + }, + _create: function() { + + if ( this.options.helper === "original" ) { + this._setPositionRelative(); + } + if (this.options.addClasses){ + this.element.addClass("ui-draggable"); + } + if (this.options.disabled){ + this.element.addClass("ui-draggable-disabled"); + } + this._setHandleClassName(); + + this._mouseInit(); + }, + + _setOption: function( key, value ) { + this._super( key, value ); + if ( key === "handle" ) { + this._removeHandleClassName(); + this._setHandleClassName(); + } + }, + + _destroy: function() { + if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { + this.destroyOnClear = true; + return; + } + this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); + this._removeHandleClassName(); + this._mouseDestroy(); + }, + + _mouseCapture: function(event) { + var o = this.options; + + this._blurActiveElement( event ); + + // among others, prevent a drag on a resizable-handle + if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { + return false; + } + + //Quit if we're not on a valid handle + this.handle = this._getHandle(event); + if (!this.handle) { + return false; + } + + this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); + + return true; + + }, + + _blockFrames: function( selector ) { + this.iframeBlocks = this.document.find( selector ).map(function() { + var iframe = $( this ); + + return $( "
      " ) + .css( "position", "absolute" ) + .appendTo( iframe.parent() ) + .outerWidth( iframe.outerWidth() ) + .outerHeight( iframe.outerHeight() ) + .offset( iframe.offset() )[ 0 ]; + }); + }, + + _unblockFrames: function() { + if ( this.iframeBlocks ) { + this.iframeBlocks.remove(); + delete this.iframeBlocks; + } + }, + + _blurActiveElement: function( event ) { + var document = this.document[ 0 ]; + + // Only need to blur if the event occurred on the draggable itself, see #10527 + if ( !this.handleElement.is( event.target ) ) { + return; + } + + // support: IE9 + // IE9 throws an "Unspecified error" accessing document.activeElement from an