diff --git a/crm_dashboard/README.rst b/crm_dashboard/README.rst new file mode 100755 index 000000000..671ae14c1 --- /dev/null +++ b/crm_dashboard/README.rst @@ -0,0 +1,40 @@ +CRM Dashboard +============= +* CRM Dashboard module for Odoo 14. + +Installation +============ + - www.odoo.com/documentation/14.0/setup/install.html + - Install our custom addon + +License +------- +General Public License, Version 3 (LGPL v3). +(https://www.odoo.com/documentation/user/14.0/legal/licenses/licenses.html) + +Company +------- +* 'Cybrosys Techno Solutions '__ + +Credits +------- +* 'Cybrosys Techno Solutions '__ + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com + +Bug Tracker +----------- +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Maintainer +========== +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit https://www.cybrosys.com + +Further information +=================== +HTML Description: ``__ + diff --git a/crm_dashboard/__init__.py b/crm_dashboard/__init__.py new file mode 100644 index 000000000..26bd4be6e --- /dev/null +++ b/crm_dashboard/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2021-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# +from . import models diff --git a/crm_dashboard/__manifest__.py b/crm_dashboard/__manifest__.py new file mode 100644 index 000000000..c08ad7e8b --- /dev/null +++ b/crm_dashboard/__manifest__.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2021-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# +{ + 'name': "CRM Dashboard", + 'description': """CRM Dashboard, Detailed Dashboard View for CRM, CRM, Dashboard, odoo14""", + 'summary': """Detailed Dashboard View for CRM""", + 'category': 'Sales', + 'version': '14.0.1.0.0', + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'depends': ['base', 'sale_management', 'crm'], + 'data': [ + 'views/dashboard_view.xml', + 'views/assets.xml', + ], + 'qweb': [ + 'static/src/xml/dashboard_view.xml', + 'static/src/xml/sub_dashboard.xml', + ], + 'images': [ + 'static/description/banner.png', + ], + 'license': 'LGPL-3', + 'installable': True, + 'application': False, + 'auto_install': False, +} diff --git a/crm_dashboard/doc/RELEASE_NOTES.md b/crm_dashboard/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..813f9ec73 --- /dev/null +++ b/crm_dashboard/doc/RELEASE_NOTES.md @@ -0,0 +1,6 @@ +## Module + +#### 17.09.2021 +#### Version 14.0.1.0.0 +#### ADD +- Initial commit for CRM Dashboard Module \ No newline at end of file diff --git a/crm_dashboard/models/__init__.py b/crm_dashboard/models/__init__.py new file mode 100644 index 000000000..2c161d97a --- /dev/null +++ b/crm_dashboard/models/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2021-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# +from . import crm_dashboard diff --git a/crm_dashboard/models/crm_dashboard.py b/crm_dashboard/models/crm_dashboard.py new file mode 100644 index 000000000..09b299766 --- /dev/null +++ b/crm_dashboard/models/crm_dashboard.py @@ -0,0 +1,1415 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2021-TODAY Cybrosys Technologies() +# Author: Cybrosys Techno Solutions() +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################# +import datetime +import calendar + +from odoo import models, fields, api +from odoo.tools import date_utils +from odoo.http import request + +from dateutil.relativedelta import relativedelta +from datetime import datetime + + +class CRMSalesTeam(models.Model): + _inherit = 'crm.team' + + crm_lead_state_id = fields.Many2one("crm.stage", string="CRM Lead", + store=True) + + +class ResUser(models.Model): + _inherit = 'res.users' + + sales = fields.Float(string="Target") + + +class SalesOrder(models.Model): + _inherit = 'sale.order' + + def action_confirm(self): + """Supering the Confirm Button for Changing CRM Stage""" + res = super(SalesOrder, self).action_confirm() + self.opportunity_id.stage_id = self.team_id.crm_lead_state_id + return res + + +class CRMLead(models.Model): + _inherit = 'crm.lead' + + crm_manager_id = fields.Many2one("res.users", string="CRM Manager", + store=True) + monthly_goal = fields.Float(string="Monthly Goal") + achievement_amount = fields.Float(string="Monthly Achievement") + + @api.model + def _get_currency(self): + currency_array = [self.env.user.company_id.currency_id.symbol, + self.env.user.company_id.currency_id.position] + return currency_array + + @api.model + def check_user_group(self): + """Checking user group""" + user = self.env.user + if user.has_group('sales_team.group_sale_manager'): + return True + else: + return False + + @api.model + def get_lead_stage_data(self): + """funnel chart""" + stage_ids = self.env["crm.stage"].search([]) + crm_list = [] + for stage in stage_ids: + leads = self.search_count([("stage_id", "=", stage.id)]) + crm_list.append((stage.name, int(leads))) + return crm_list + + @api.model + def get_lead_month_pie(self): + """pie chart""" + month_count = [] + month_value = [] + leads = self.env['crm.lead'].search([]) + for rec in leads: + month = rec.create_date.month + if month not in month_value: + month_value.append(month) + month_count.append(month) + + month_val = [] + for index in range(len(month_value)): + value = month_count.count(month_value[index]) + month_name = calendar.month_name[month_value[index]] + month_val.append({'label': month_name, 'value': value}) + + name = [] + for record in month_val: + name.append(record.get('label')) + + count = [] + for record in month_val: + count.append(record.get('value')) + + month = [count, name] + return month + + @api.model + def get_the_sales_activity(self): + """Sales Activity Pie""" + self._cr.execute('''select mail_activity_type.name,COUNT(*) from mail_activity + inner join mail_activity_type on mail_activity.activity_type_id = mail_activity_type.id + where res_model = 'crm.lead' GROUP BY mail_activity_type.name''') + data = self._cr.dictfetchall() + + name = [] + for record in data: + name.append(record.get('name')) + + count = [] + for record in data: + count.append(record.get('count')) + + final = [count, name] + return final + + @api.model + def get_the_annual_target(self): + """Annual Target: Year To Date Graph""" + session_user_id = self.env.uid + + self._cr.execute('''SELECT res_users.id,res_users.sales,res_users.sale_team_id, + (SELECT crm_team.invoiced_target FROM crm_team WHERE crm_team.id = res_users.sale_team_id) + FROM res_users WHERE res_users.sales is not null and res_users.id=%s + AND res_users.sale_team_id is not null;''' % session_user_id) + data2 = self._cr.dictfetchall() + + sales = [] + inv_target = [] + team_id = 0 + for rec in data2: + sales.append(rec['sales']) + inv_target.append(rec['invoiced_target']) + team_id = rec['sale_team_id'] + target_annual = (sum(sales) + sum(inv_target)) + + if self.env.user.has_group('sales_team.group_sale_manager'): + self._cr.execute('''SELECT res_users.id,res_users.sales,res_users.sale_team_id, + (SELECT crm_team.invoiced_target FROM crm_team WHERE + crm_team.id = res_users.sale_team_id) FROM res_users WHERE res_users.id = %s + AND res_users.sales is not null;''' % session_user_id) + data3 = self._cr.dictfetchall() + + sales = [] + inv_target = [] + for rec in data3: + sales.append(rec['sales']) + inv_target.append(rec['invoiced_target']) + ytd_target = (sum(sales) + sum(inv_target)) + + self._cr.execute('''select sum(expected_revenue) from crm_lead where stage_id=4 + and team_id=%s AND Extract(Year FROM date_closed)=Extract(Year FROM DATE(NOW( + )))''' % team_id) + achieved_won_data = self._cr.dictfetchall() + achieved_won = [item['sum'] for item in achieved_won_data] + + else: + self._cr.execute('''SELECT res_users.id,res_users.sales FROM res_users + WHERE res_users.id = %s AND res_users.sales is not null;''' % session_user_id) + data4 = self._cr.dictfetchall() + + sales = [] + for rec in data4: + sales.append(rec['sales']) + ytd_target = (sum(sales)) + + self._cr.execute('''select sum(expected_revenue) from crm_lead where stage_id=4 + and user_id=%s AND Extract(Year FROM date_closed)=Extract(Year FROM DATE(NOW( + )))''' % session_user_id) + achieved_won_data = self._cr.dictfetchall() + achieved_won = [item['sum'] for item in achieved_won_data] + + won = achieved_won[0] + if won is None: + won = 0 + value = [target_annual, ytd_target, won] + name = ["Annual Target", "YtD target", "Won"] + final = [value, name] + + return final + + @api.model + def get_the_campaign_pie(self): + """Leads Group By Campaign Pie""" + self._cr.execute('''select campaign_id, COUNT(*), + (SELECT name FROM utm_campaign WHERE utm_campaign.id = crm_lead.campaign_id) + FROM crm_lead WHERE campaign_id is not null GROUP BY campaign_id''') + data = self._cr.dictfetchall() + + name = [] + for record in data: + name.append(record.get('name')) + + count = [] + for record in data: + count.append(record.get('count')) + + final = [count, name] + return final + + @api.model + def get_the_source_pie(self): + """Leads Group By Source Pie""" + self._cr.execute('''select source_id,COUNT(*),(SELECT name FROM utm_source + WHERE utm_source.id = crm_lead.source_id) from crm_lead + WHERE source_id is not null GROUP BY source_id''') + data = self._cr.dictfetchall() + + name = [] + for record in data: + name.append(record.get('name')) + + count = [] + for record in data: + count.append(record.get('count')) + + final = [count, name] + return final + + @api.model + def get_the_medium_pie(self): + """Leads Group By Medium Pie""" + self._cr.execute('''select medium_id,COUNT(*),(SELECT name FROM utm_medium + WHERE utm_medium.id = crm_lead.medium_id) from crm_lead + WHERE medium_id is not null GROUP BY medium_id ''') + data = self._cr.dictfetchall() + + name = [] + for record in data: + name.append(record.get('name')) + + count = [] + for record in data: + count.append(record.get('count')) + + final = [count, name] + return final + + @api.model + def revenue_count_pie(self): + """Total expected revenue and count Pie""" + session_user_id = self.env.uid + self._cr.execute('''select sum(expected_revenue) as revenue from crm_lead + where user_id=%s and type='opportunity' and active=true''' % session_user_id) + total_expected_revenue_data = self._cr.dictfetchall() + total_expected_revenue = [item['revenue'] for item in total_expected_revenue_data] + total_expected_revenue = total_expected_revenue[0] + if total_expected_revenue is None: + total_expected_revenue = 0 + + self._cr.execute('''select sum(expected_revenue) as revenue from crm_lead + where user_id=%s and type='opportunity' and stage_id=4''' % session_user_id) + total_won_rev_data = self._cr.dictfetchall() + total_won_rev = [item['revenue'] for item in total_won_rev_data] + total_won_rev = total_won_rev[0] + if total_won_rev is None: + total_won_rev = 0 + + self._cr.execute('''select sum(expected_revenue) as revenue from crm_lead + where user_id=%s and type='opportunity' and probability=0 and active='false' + ''' % session_user_id) + total_lost_rev_data = self._cr.dictfetchall() + total_lost_rev = [item['revenue'] for item in total_lost_rev_data] + total_lost_rev = total_lost_rev[0] + if total_lost_rev is None: + total_lost_rev = 0 + + exp_revenue_without_won = total_expected_revenue - total_won_rev + revenue_pie_count = [exp_revenue_without_won, total_won_rev, total_lost_rev] + revenue_pie_title = ['Expected without Won', 'Won', 'Lost'] + revenue_data = [revenue_pie_count, revenue_pie_title] + + return revenue_data + + @api.model + def get_upcoming_events(self): + """Upcoming Activities Table""" + today = fields.date.today() + session_user_id = self.env.uid + self._cr.execute('''select mail_activity.activity_type_id,mail_activity.date_deadline, + mail_activity.summary,mail_activity.res_name,(SELECT mail_activity_type.name + FROM mail_activity_type WHERE mail_activity_type.id = mail_activity.activity_type_id), + mail_activity.user_id FROM mail_activity WHERE res_model = 'crm.lead' AND + mail_activity.date_deadline >= '%s' and user_id = %s GROUP BY mail_activity.activity_type_id, + mail_activity.date_deadline,mail_activity.summary,mail_activity.res_name,mail_activity.user_id + order by mail_activity.date_deadline asc''' % (today, session_user_id)) + data = self._cr.fetchall() + + events = [] + for record in data: + user_id = record[5] + user_id_obj = self.env['res.users'].browse(user_id) + record_list = list(record) + record_list[5] = user_id_obj.name + events.append(record_list) + + return {'event': events} + + @api.model + def get_top_deals(self): + """Top 10 Deals Table""" + self._cr.execute('''SELECT crm_lead.user_id,crm_lead.id,crm_lead.expected_revenue, + crm_lead.name,crm_lead.company_id, (SELECT crm_team.name FROM crm_team + WHERE crm_lead.team_id = crm_team.id) from crm_lead + where crm_lead.expected_revenue is not null GROUP BY crm_lead.user_id, + crm_lead.id,crm_lead.expected_revenue,crm_lead.name,crm_lead.company_id + order by crm_lead.expected_revenue DESC limit 10''') + data1 = self._cr.fetchall() + + deals = [] + num = 0 + for rec in data1: + company_id = rec[4] + user_id = rec[0] + company_id_obj = self.env['res.company'].browse(company_id) + user_id_obj = self.env['res.users'].browse(user_id) + currency = company_id_obj.currency_id.symbol + rec_list = list(rec) + rec_list[0] = user_id_obj.name + num += 1 + rec_list.append(currency) + rec_list.append(num) + deals.append(rec_list) + + return {'deals': deals} + + @api.model + def get_monthly_goal(self): + """Monthly Goal Gauge""" + uid = request.session.uid + leads = self.env['crm.lead'].search([('date_deadline', '!=', False), + ('user_id', '=', uid)]) + leads_won = self.env['crm.lead'].search([('date_closed', '!=', False), + ('stage_id', '=', 4), + ('user_id', '=', uid)]) + currency_symbol = self.env.company.currency_id.symbol + + goals = [] + achievement = 0 + for won in leads_won.filtered( + lambda a: a.date_closed.month == fields.date.today().month): + if won.date_closed.year == fields.date.today().year: + achievement += won.expected_revenue + + total = 0 + for rec in leads.filtered(lambda t: t.date_deadline.month == fields.date.today().month): + if rec.date_deadline.year == fields.date.today().year: + total += rec.expected_revenue + + self.monthly_goal = total + self.achievement_amount = achievement + + percent = 0 + if achievement != 0: + percent = (achievement * 100 / total) / 100 + + goals.append(achievement) + goals.append(total) + goals.append(currency_symbol) + goals.append(percent) + + return {'goals': goals} + + @api.model + def get_top_sp_revenue(self): + """Top 10 Salesperson revenue Table""" + user = self.env.user + + self._cr.execute('''SELECT user_id,id,expected_revenue,name,company_id + from crm_lead where expected_revenue is not null AND user_id = %s + GROUP BY user_id,id order by expected_revenue DESC limit 10''' % user.id) + data1 = self._cr.fetchall() + + top_revenue = [] + for rec in data1: + company_id = rec[4] + user_id = rec[0] + company_id_obj = self.env['res.company'].browse(company_id) + user_id_obj = self.env['res.users'].browse(user_id) + currency = company_id_obj.currency_id.symbol + rec_list = list(rec) + rec_list[0] = user_id_obj.name + rec_list.append(currency) + top_revenue.append(rec_list) + + return {'top_revenue': top_revenue} + + @api.model + def get_country_revenue(self): + """Top 10 Country Wise Revenue - Heat Map""" + company_id = self.env.company.id + self._cr.execute('''select country_id, sum(expected_revenue) from crm_lead + where expected_revenue is not null AND country_id is not null + group by country_id order by sum(expected_revenue) desc limit 10''') + data1 = self._cr.fetchall() + + country_revenue = [] + for rec in data1: + country_id = rec[0] + company_id_obj = self.env['res.company'].browse(company_id) + country_id_obj = self.env['res.country'].browse(country_id) + currency = company_id_obj.currency_id.symbol + rec_list = list(rec) + rec_list[0] = country_id_obj.name + rec_list.append(currency) + country_revenue.append(rec_list) + + return {'country_revenue': country_revenue} + + @api.model + def get_country_count(self): + """Top 10 Country Wise Count - Heat Map""" + self._cr.execute('''select country_id,count(*) from crm_lead where country_id is not null + group by country_id order by count(*) desc limit 10''') + data1 = self._cr.fetchall() + + country_count = [] + for rec in data1: + country_id = rec[0] + country_id_obj = self.env['res.country'].browse(country_id) + rec_list = list(rec) + rec_list[0] = country_id_obj.name + country_count.append(rec_list) + + return {'country_count': country_count} + + @api.model + def get_total_lost_crm(self, option): + """Lost Opportunity or Lead Graph""" + month_dict = {} + for i in range(int(option) - 1, -1, -1): + last_month = datetime.now() - relativedelta(months=i) + text = format(last_month, '%B') + month_dict[text] = 0 + + if option == '1': + day_dict = {} + last_day = date_utils.end_of(fields.Date.today(), "month").strftime("%d") + + for i in range(1, int(last_day), 1): + day_dict[i] = 0 + + self._cr.execute('''select create_date::date,count(id) from crm_lead + where probability=0 and active=false and create_date between (now() - interval '1 month') and now() + group by create_date order by create_date;''') + data = self._cr.dictfetchall() + + for rec in data: + day_dict[int(rec['create_date'].strftime("%d"))] = rec['count'] + + test = {'month': list(day_dict.keys()), + 'count': list(day_dict.values())} + else: + month_string = str(int(option)) + ' Months' + self._cr.execute('''select extract(month from create_date),count(id) + from crm_lead where probability=0 and active=false and + create_date between (now() - interval '%s') and now() + group by extract(month from create_date) order by extract( + month from create_date);''' % month_string) + data = self._cr.dictfetchall() + + for rec in data: + datetime_object = datetime.strptime(str(int(rec['date_part'])), "%m") + month_name = datetime_object.strftime("%B") + month_dict[month_name] = rec['count'] + + test = {'month': list(month_dict.keys()), + 'count': list(month_dict.values())} + + return test + + @api.model + def get_lost_reason_count(self): + """Top 5 Lost Reason and Count""" + self._cr.execute('''select lost_reason,count(lost_reason) as counts + from crm_lead where probability=0 and active=false and lost_reason is not null + group by lost_reason order by counts desc limit 5''') + data1 = self._cr.fetchall() + + reason_count = [] + for rec in data1: + reason_id = rec[0] + reason_id_obj = self.env['crm.lost.reason'].browse(reason_id) + rec_list = list(rec) + rec_list[0] = reason_id_obj.name + reason_count.append(rec_list) + + return {'reason_count': reason_count} + + @api.model + def get_ratio_based_country(self): + """Top 5 Won vs Lost Ratio based on Country""" + self._cr.execute('''select (select name from res_country where id=country_id), + count(country_id) from crm_lead where probability=100 and active=true + group by country_id order by count(country_id) desc''') + data_won = self._cr.fetchall() + + self._cr.execute('''select (select name from res_country where id=country_id), + count(country_id) from crm_lead where probability=0 and active=false + group by country_id order by count(country_id) desc''') + data_lost = self._cr.fetchall() + + won = [] + for rec in data_won: + won_list = list(rec) + won.append(won_list) + + for lose in data_lost: + lose_list = list(lose) + + if lose_list[0] == won_list[0]: + won_list.append(lose_list[1]) + + country_wise_ratio = [] + for data in won: + if len(data) != 3: + del data + else: + ratio = round(data[1] / data[2], 2) + data.append(str(ratio)) + country_wise_ratio.append(data) + + country_wise_ratio = sorted(country_wise_ratio, key=lambda x: x[3], reverse=True) + country_wise_ratio = country_wise_ratio[:5] + + return {'country_wise_ratio': country_wise_ratio} + + @api.model + def get_ratio_based_sp(self): + """Top 5 Won vs Lost Ratio based on Sales Person""" + self._cr.execute('''select user_id,count(user_id) from crm_lead where + probability=100 and active=true group by user_id order by count(user_id) desc''') + data_won = self._cr.fetchall() + + self._cr.execute('''select user_id,count(user_id) from crm_lead where probability=0 + and active=false group by user_id order by count(user_id) desc''') + data_lost = self._cr.fetchall() + + won = [] + for rec in data_won: + won_list = list(rec) + user_id = rec[0] + user_id_obj = self.env['res.users'].browse(user_id) + won_list[0] = user_id_obj.name + won.append(won_list) + + for lose in data_lost: + lose_list = list(lose) + user_id = lose[0] + user_id_obj = self.env['res.users'].browse(user_id) + lose_list[0] = user_id_obj.name + + if lose_list[0] == won_list[0]: + won_list.append(lose_list[1]) + + salesperson_wise_ratio = [] + for data in won: + if len(data) != 3: + del data + else: + ratio = round(data[1] / data[2], 2) + data.append(str(ratio)) + salesperson_wise_ratio.append(data) + + salesperson_wise_ratio = sorted(salesperson_wise_ratio, key=lambda x: x[3], reverse=True) + salesperson_wise_ratio = salesperson_wise_ratio[:5] + + return {'salesperson_wise_ratio': salesperson_wise_ratio} + + @api.model + def get_ratio_based_sales_team(self): + """Top 5 Won vs Lost Ratio based on Sales Team""" + self._cr.execute('''select (SELECT name FROM crm_team WHERE crm_team.id = team_id), + count(user_id) from crm_lead where probability=100 and active=true + group by team_id order by count(team_id) desc''') + data_won = self._cr.fetchall() + + self._cr.execute('''select (SELECT name FROM crm_team WHERE crm_team.id = team_id), + count(user_id) from crm_lead where probability=0 and active=false + group by team_id order by count(team_id) desc''') + data_lost = self._cr.fetchall() + + won = [] + for rec in data_won: + won_list = list(rec) + won.append(won_list) + + for lose in data_lost: + lose_list = list(lose) + + if lose_list[0] == won_list[0]: + won_list.append(lose_list[1]) + + sales_team_wise_ratio = [] + for data in won: + if len(data) != 3: + del data + else: + ratio = round(data[1] / data[2], 2) + data.append(str(ratio)) + sales_team_wise_ratio.append(data) + + sales_team_wise_ratio = sorted(sales_team_wise_ratio, key=lambda x: x[3], reverse=True) + sales_team_wise_ratio = sales_team_wise_ratio[:5] + + return {'sales_team_wise_ratio': sales_team_wise_ratio} + + @api.model + def get_lost_lead_by_reason_pie(self): + """Lost Leads by Lost Reason Pie""" + self._cr.execute('''select lost_reason, count(*), (SELECT name FROM crm_lost_reason + WHERE id = lost_reason) from crm_lead where probability=0 and active=false and + type='lead' group by lost_reason''') + data1 = self._cr.dictfetchall() + + name = [] + for rec in data1: + if rec["name"] is None: + rec["name"] = "Undefined" + name.append(rec.get('name')) + + count = [] + for rec in data1: + count.append(rec.get('count')) + + lost_leads = [count, name] + return lost_leads + + @api.model + def get_lost_lead_by_stage_pie(self): + """Lost Leads by Stage Pie""" + self._cr.execute('''select stage_id, count(*),(SELECT name FROM crm_stage + WHERE id = stage_id) from crm_lead where probability=0 and active=false + and type='lead' group by stage_id''') + data1 = self._cr.dictfetchall() + + name = [] + for rec in data1: + name.append(rec.get('name')) + + count = [] + for rec in data1: + count.append(rec.get('count')) + + lost_leads_stage = [count, name] + return lost_leads_stage + + @api.model + def get_recent_activities(self): + """Recent Activities Table""" + today = fields.date.today() + recent_week = today - relativedelta(days=7) + self._cr.execute('''select mail_activity.activity_type_id,mail_activity.date_deadline, + mail_activity.summary,mail_activity.res_name,(SELECT mail_activity_type.name + FROM mail_activity_type WHERE mail_activity_type.id = mail_activity.activity_type_id), + mail_activity.user_id FROM mail_activity WHERE res_model = 'crm.lead' AND + mail_activity.date_deadline between '%s' and '%s' GROUP BY mail_activity.activity_type_id, + mail_activity.date_deadline,mail_activity.summary,mail_activity.res_name,mail_activity.user_id + order by mail_activity.date_deadline desc''' % (recent_week, today)) + data = self._cr.fetchall() + activities = [] + for record in data: + user_id = record[5] + user_id_obj = self.env['res.users'].browse(user_id) + record_list = list(record) + record_list[5] = user_id_obj.name + activities.append(record_list) + + return {'activities': activities} + + @api.model + def get_count_unassigned(self): + """Unassigned Leads Count Card""" + count_unassigned = self.env['crm.lead'].search_count( + [('user_id', '=', False), ('type', '=', 'lead')]) + + return {'count_unassigned': count_unassigned} + + @api.model + def get_top_sp_by_invoice(self): + """Top 10 Sales Person by Invoice Table""" + self._cr.execute('''select user_id,sum(amount_total) as total + from sale_order where invoice_status='invoiced' + group by user_id order by total desc limit 10''') + data1 = self._cr.fetchall() + + sales_person_invoice = [] + num = 0 + for rec in data1: + user_id = rec[0] + user_id_obj = self.env['res.users'].browse(user_id) + currency = user_id_obj.company_id.currency_id.symbol + rec_list = list(rec) + rec_list[0] = user_id_obj.name + num += 1 + rec_list.append(currency) + rec_list.append(num) + sales_person_invoice.append(rec_list) + + return {'sales_person_invoice': sales_person_invoice} + + @api.model + def lead_details_user(self): + """Cards Count and Details based on User""" + session_user_id = self.env.uid + month_count = [] + month_value = [] + leads = self.env['crm.lead'].search([]) + for rec in leads: + month = rec.create_date.month + if month not in month_value: + month_value.append(month) + month_count.append(month) + + value = [] + for index in range(len(month_value)): + value = month_count.count(month_value[index]) + + self._cr.execute('''SELECT res_users.id,res_users.sales,res_users.sale_team_id, + (SELECT crm_team.invoiced_target FROM crm_team WHERE crm_team.id = res_users.sale_team_id) + FROM res_users WHERE res_users.sales is not null and res_users.id=%s + AND res_users.sale_team_id is not null;''' % session_user_id) + data2 = self._cr.dictfetchall() + + sales = [] + inv_target = [] + team_id = 0 + for rec in data2: + sales.append(rec['sales']) + inv_target.append(rec['invoiced_target']) + team_id = rec['sale_team_id'] + target_annual = (sum(sales) + sum(inv_target)) + + if self.env.user.has_group('sales_team.group_sale_manager'): + self._cr.execute('''SELECT res_users.id,res_users.sales,res_users.sale_team_id, + (SELECT crm_team.invoiced_target FROM crm_team WHERE + crm_team.id = res_users.sale_team_id) FROM res_users WHERE res_users.id = %s + AND res_users.sales is not null;''' % session_user_id) + data3 = self._cr.dictfetchall() + + sales = [] + inv_target = [] + for rec in data3: + sales.append(rec['sales']) + inv_target.append(rec['invoiced_target']) + ytd_target = (sum(sales) + sum(inv_target)) + + self._cr.execute('''select sum(expected_revenue) from crm_lead where stage_id=4 + and team_id=%s AND Extract(Year FROM date_closed)=Extract(Year FROM DATE(NOW( + )))''' % team_id) + achieved_won_data = self._cr.dictfetchall() + achieved_won = [item['sum'] for item in achieved_won_data] + + else: + self._cr.execute('''SELECT res_users.id,res_users.sales FROM res_users + WHERE res_users.id = %s AND res_users.sales is not null;''' % session_user_id) + data4 = self._cr.dictfetchall() + + sales = [] + for rec in data4: + sales.append(rec['sales']) + ytd_target = (sum(sales)) + + self._cr.execute('''select sum(expected_revenue) from crm_lead where stage_id=4 + and user_id=%s AND Extract(Year FROM date_closed)=Extract(Year FROM DATE(NOW( + )))''' % session_user_id) + achieved_won_data = self._cr.dictfetchall() + achieved_won = [item['sum'] for item in achieved_won_data] + + won = achieved_won[0] + if won is None: + won = 0 + difference = target_annual - won + + self._cr.execute('''select COUNT(id) from crm_lead WHERE crm_lead.user_id = '%s' + AND Extract(MONTH FROM crm_lead.date_deadline) = Extract( MONTH FROM DATE(NOW())) + AND Extract(Year FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())) + ''' % session_user_id) + record = self._cr.dictfetchall() + rec_ids = [item['count'] for item in record] + crm_lead_value = rec_ids[0] + + self._cr.execute('''select COUNT(id) from crm_lead WHERE crm_lead.user_id = %s + AND crm_lead.type = 'opportunity' AND Extract(MONTH FROM crm_lead.date_deadline + ) = Extract(MONTH FROM DATE(NOW())) AND Extract(Year FROM crm_lead.date_deadline + ) = Extract(Year FROM DATE(NOW( )))''' % session_user_id) + opportunity_data = self._cr.dictfetchall() + opportunity_data_value = [item['count'] for item in opportunity_data] + opportunity_value = opportunity_data_value[0] + + self._cr.execute('''select SUM(crm_lead.expected_revenue) from crm_lead WHERE + crm_lead.user_id = %s and type='opportunity' and active='true' AND Extract(MONTH + FROM crm_lead.date_deadline) = Extract(MONTH FROM DATE(NOW())) AND Extract(Year + FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW()))''' % session_user_id) + exp_revenue_data = self._cr.dictfetchall() + exp_revenue_data_value = [item['sum'] for item in exp_revenue_data] + exp_revenue_value = exp_revenue_data_value[0] + if exp_revenue_value is None: + exp_revenue_value = 0 + + self._cr.execute('''select SUM(crm_lead.expected_revenue) from crm_lead WHERE + crm_lead.user_id = %s and type='opportunity' and active='true' and stage_id=4 + AND Extract(MONTH FROM crm_lead.date_closed) = Extract(MONTH FROM DATE(NOW())) + AND Extract(Year FROM crm_lead.date_closed) = Extract(Year FROM DATE(NOW())) + ''' % session_user_id) + revenue_data = self._cr.dictfetchall() + revenue_data_value = [item['sum'] for item in revenue_data] + revenue_value = revenue_data_value[0] + if revenue_value is None: + revenue_value = 0 + + ratio_value = [] + if revenue_value == 0: + ratio_value = 0 + if revenue_value > 0: + self._cr.execute('''select case when a.count_one+b.count_two = 0 then 0 else ( + CAST(a.count_one as float) / CAST(b.count_two as float))end as final_count + from (select COUNT(id) as count_one from crm_lead WHERE + crm_lead.user_id = '%s' AND crm_lead.active = True AND crm_lead.probability = 100 + AND Extract(MONTH FROM crm_lead.date_deadline) = Extract(MONTH FROM DATE(NOW())) + AND Extract(Year FROM crm_lead.date_open) = Extract(Year FROM DATE(NOW())))a, + (select COUNT(id) as count_two from crm_lead WHERE crm_lead.user_id = '%s' AND + crm_lead.active = False AND crm_lead.probability = 0 AND Extract(MONTH FROM + crm_lead.date_deadline) = Extract(MONTH FROM DATE(NOW())) AND Extract(Year + FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())))b + ''' % (session_user_id, session_user_id)) + ratio_data_value = [row[0] for row in self._cr.fetchall()] + ratio_value = str(ratio_data_value)[1:-1] + + self._cr.execute('''SELECT active,count(active) FROM crm_lead where type='opportunity' + and active = true and probability = 100 and user_id=%s AND Extract(MONTH FROM date_closed + ) = Extract(MONTH FROM DATE(NOW())) AND Extract(Year FROM date_closed) = Extract( + Year FROM DATE(NOW())) or type='opportunity' and active = false and probability = 0 + and user_id=%s AND Extract(MONTH FROM date_deadline) = Extract(MONTH FROM DATE(NOW())) + AND Extract(Year FROM date_deadline) = Extract(Year FROM DATE(NOW())) GROUP BY active + ''' % (session_user_id, session_user_id)) + record_opportunity = dict(self._cr.fetchall()) + opportunity_ratio_value = 0.0 + if record_opportunity == {}: + opportunity_ratio_value = 0.0 + else: + total_opportunity_won = record_opportunity.get(False) + total_opportunity_lost = record_opportunity.get(True) + if total_opportunity_won is None: + total_opportunity_won = 0 + if total_opportunity_lost is None: + total_opportunity_lost = 0 + opportunity_ratio_value = 0.0 + if total_opportunity_lost > 0: + opportunity_ratio_value = round(total_opportunity_won / total_opportunity_lost, 2) + + avg = 0 + if crm_lead_value == 1: + self._cr.execute('''SELECT id, date_conversion, create_date + FROM crm_lead WHERE date_conversion IS NOT NULL;''') + data = self._cr.dictfetchall() + for rec in data: + date_close = rec['date_conversion'] + date_create = rec['create_date'] + avg = (date_close - date_create).seconds + if crm_lead_value > 1: + self._cr.execute('''SELECT id, date_conversion, create_date + FROM crm_lead WHERE date_conversion IS NOT NULL;''') + data1 = self._cr.dictfetchall() + for rec in data1: + date_close = rec['date_conversion'] + date_create = rec['create_date'] + avg = (date_close - date_create).seconds + + avg_time = 0 if crm_lead_value == 0 else round(avg / crm_lead_value) + + data = { + 'record': crm_lead_value, + 'record_op': opportunity_value, + 'record_rev_exp': exp_revenue_value, + 'record_rev': revenue_value, + 'record_ratio': ratio_value, + 'opportunity_ratio_value': str(opportunity_ratio_value), + 'avg_time': avg_time, + 'count': value, + 'target': target_annual, + 'ytd_target': ytd_target, + 'difference': difference, + 'won': won, + } + return data + + @api.model + def crm_year(self): + """Year CRM Dropdown Filter""" + session_user_id = self.env.uid + + self._cr.execute('''select COUNT(id) from crm_lead WHERE crm_lead.user_id = '%s' + AND Extract(Year FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())) + ''' % session_user_id) + record = self._cr.dictfetchall() + rec_ids = [item['count'] for item in record] + crm_lead_value = rec_ids[0] + + self._cr.execute('''select COUNT(id) from crm_lead WHERE crm_lead.user_id = %s + AND crm_lead.type = 'opportunity' AND Extract(Year FROM crm_lead.date_deadline + ) = Extract(Year FROM DATE(NOW()))''' % session_user_id) + opportunity_data = self._cr.dictfetchall() + opportunity_data_value = [item['count'] for item in opportunity_data] + opportunity_value = opportunity_data_value[0] + + self._cr.execute('''select SUM(crm_lead.expected_revenue) from crm_lead + WHERE crm_lead.user_id = %s and type='opportunity' and active='true' AND + Extract(Year FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())) + ''' % session_user_id) + exp_revenue_data = self._cr.dictfetchall() + exp_revenue_data_value = [item['sum'] for item in exp_revenue_data] + exp_revenue_value = exp_revenue_data_value[0] + if exp_revenue_value is None: + exp_revenue_value = 0 + + self._cr.execute('''select SUM(crm_lead.expected_revenue) from crm_lead + WHERE crm_lead.user_id = %s and type='opportunity' and active='true' and + stage_id=4 AND Extract(Year FROM crm_lead.date_closed) = Extract(Year + FROM DATE(NOW()))''' % session_user_id) + revenue_data = self._cr.dictfetchall() + revenue_data_value = [item['sum'] for item in revenue_data] + revenue_value = revenue_data_value[0] + if revenue_value is None: + revenue_value = 0 + + ratio_value = [] + if revenue_value == 0: + ratio_value = 0 + if revenue_value > 0: + self._cr.execute('''select case when a.count_one + b.count_two = 0 then 0 else ( + CAST(a.count_one as float) / CAST(b.count_two as float))end as final_count from ( + select COUNT(id) as count_one from crm_lead WHERE crm_lead.user_id = '%s' AND + crm_lead.active = True AND crm_lead.probability = 100 AND Extract(Year FROM + crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())))a, + (select COUNT(id) as count_two from crm_lead WHERE crm_lead.user_id = '%s' AND + crm_lead.active = False AND crm_lead.probability = 0 AND Extract(Year FROM + crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())))b + ''' % (session_user_id, session_user_id)) + ratio_value = [row[0] for row in self._cr.fetchall()] + ratio_value = str(ratio_value)[1:-1] + + self._cr.execute('''SELECT active,count(active) FROM crm_lead + where type='opportunity' and active = true and probability = 100 and user_id=%s + AND Extract(Year FROM date_closed) = Extract(Year FROM DATE(NOW())) + or type='opportunity' and active = false and probability = 0 and user_id=%s + AND Extract(Year FROM date_deadline) = Extract(Year FROM DATE(NOW())) + GROUP BY active''' % (session_user_id, session_user_id)) + record_opportunity = dict(self._cr.fetchall()) + opportunity_ratio_value = 0.0 + if record_opportunity == {}: + opportunity_ratio_value = 0.0 + else: + total_opportunity_won = record_opportunity.get(False) + total_opportunity_lost = record_opportunity.get(True) + if total_opportunity_won is None: + total_opportunity_won = 0 + if total_opportunity_lost is None: + total_opportunity_lost = 0 + opportunity_ratio_value = 0.0 + if total_opportunity_lost > 0: + opportunity_ratio_value = round(total_opportunity_won / total_opportunity_lost, 2) + + avg = 0 + if crm_lead_value == 1: + self._cr.execute('''SELECT id, date_conversion, create_date + FROM crm_lead WHERE date_conversion IS NOT NULL;''') + data = self._cr.dictfetchall() + for rec in data: + date_close = rec['date_conversion'] + date_create = rec['create_date'] + avg = (date_close - date_create).seconds + if crm_lead_value > 1: + self._cr.execute('''SELECT id, date_conversion, create_date + FROM crm_lead WHERE date_conversion IS NOT NULL;''') + data1 = self._cr.dictfetchall() + for rec in data1: + date_close = rec['date_conversion'] + date_create = rec['create_date'] + avg = (date_close - date_create).seconds + + if crm_lead_value == 0: + record_avg_time = 0 + else: + record_avg_time = round(avg / crm_lead_value) + + data_year = { + 'record': crm_lead_value, + 'record_op': opportunity_value, + 'record_rev_exp': exp_revenue_value, + 'record_rev': revenue_value, + 'record_ratio': ratio_value, + 'opportunity_ratio_value': str(opportunity_ratio_value), + 'avg_time': record_avg_time, + } + return data_year + + @api.model + def crm_quarter(self): + """Quarter CRM Dropdown Filter""" + session_user_id = self.env.uid + + self._cr.execute('''select COUNT(id) from crm_lead WHERE crm_lead.user_id = '%s' + AND Extract(QUARTER FROM crm_lead.date_deadline) = Extract(QUARTER FROM DATE(NOW())) + AND Extract(Year FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())) + ''' % session_user_id) + record = self._cr.dictfetchall() + rec_ids = [item['count'] for item in record] + crm_lead_value = rec_ids[0] + + self._cr.execute('''select COUNT(id) from crm_lead WHERE crm_lead.user_id = %s + AND crm_lead.type = 'opportunity' AND Extract(QUARTER FROM crm_lead.date_deadline + ) = Extract(QUARTER FROM DATE(NOW())) AND Extract(Year FROM crm_lead.date_deadline + ) = Extract(Year FROM DATE(NOW( )))''' % session_user_id) + opportunity_data = self._cr.dictfetchall() + opportunity_data_value = [item['count'] for item in opportunity_data] + opportunity_value = opportunity_data_value[0] + + self._cr.execute('''select SUM(crm_lead.expected_revenue) from crm_lead WHERE + crm_lead.user_id = %s and type='opportunity' and active='true' AND Extract( + QUARTER FROM crm_lead.date_deadline) = Extract(QUARTER FROM DATE(NOW())) AND + Extract(Year FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())) + ''' % session_user_id) + exp_revenue_data = self._cr.dictfetchall() + exp_revenue_data_value = [item['sum'] for item in exp_revenue_data] + exp_revenue_value = exp_revenue_data_value[0] + if exp_revenue_value is None: + exp_revenue_value = 0 + + self._cr.execute('''select SUM(crm_lead.expected_revenue) from crm_lead WHERE + crm_lead.user_id = %s and type='opportunity' and active='true' and stage_id=4 + AND Extract(QUARTER FROM crm_lead.date_closed) = Extract(QUARTER FROM + DATE(NOW())) AND Extract(Year FROM crm_lead.date_closed) = Extract(Year + FROM DATE(NOW()))''' % session_user_id) + revenue_data = self._cr.dictfetchall() + revenue_data_value = [item['sum'] for item in revenue_data] + revenue_value = revenue_data_value[0] + if revenue_value is None: + revenue_value = 0 + + ratio_value = [] + if revenue_value == 0: + ratio_value = 0 + if revenue_value > 0: + self._cr.execute('''select case when a.count_one+b.count_two = 0 then 0 else ( + CAST(a.count_one as float) / CAST(b.count_two as float))end as final_count + from (select COUNT(id) as count_one from crm_lead + WHERE crm_lead.user_id = '%s' AND crm_lead.active = True AND + crm_lead.probability = 100 AND Extract(QUARTER FROM crm_lead.date_deadline + ) = Extract(QUARTER FROM DATE(NOW())) AND Extract(Year FROM crm_lead.date_open + ) = Extract(Year FROM DATE(NOW())))a, + (select COUNT(id) as count_two from crm_lead WHERE crm_lead.user_id = '%s' + AND crm_lead.active = False AND crm_lead.probability = 0 AND Extract( + QUARTER FROM crm_lead.date_deadline) = Extract(QUARTER FROM DATE(NOW())) + AND Extract(Year FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW( + ))))b''' % (session_user_id, session_user_id)) + ratio_value = [row[0] for row in self._cr.fetchall()] + ratio_value = str(ratio_value)[1:-1] + + self._cr.execute('''SELECT active,count(active) FROM crm_lead + where type='opportunity' and active = true and probability = 100 and user_id=%s + AND Extract(QUARTER FROM date_closed) = Extract(QUARTER FROM DATE(NOW())) + AND Extract(Year FROM date_closed) = Extract(Year FROM DATE(NOW())) + or type='opportunity' and active = false and probability = 0 and user_id=%s + AND Extract(QUARTER FROM date_deadline) = Extract(QUARTER FROM DATE(NOW())) + AND Extract(Year FROM date_deadline) = Extract(Year FROM DATE(NOW())) + GROUP BY active''' % (session_user_id, session_user_id)) + record_opportunity = dict(self._cr.fetchall()) + opportunity_ratio_value = 0.0 + if record_opportunity == {}: + opportunity_ratio_value = 0.0 + else: + total_opportunity_won = record_opportunity.get(False) + total_opportunity_lost = record_opportunity.get(True) + if total_opportunity_won is None: + total_opportunity_won = 0 + if total_opportunity_lost is None: + total_opportunity_lost = 0 + opportunity_ratio_value = 0.0 + if total_opportunity_lost > 0: + opportunity_ratio_value = round(total_opportunity_won / total_opportunity_lost, 2) + + avg = 0 + if crm_lead_value == 1: + self._cr.execute('''SELECT id, date_conversion, create_date + FROM crm_lead WHERE date_conversion IS NOT NULL;''') + data = self._cr.dictfetchall() + for rec in data: + date_close = rec['date_conversion'] + date_create = rec['create_date'] + avg = (date_close - date_create).seconds + if crm_lead_value > 1: + self._cr.execute('''SELECT id, date_conversion, create_date + FROM crm_lead WHERE date_conversion IS NOT NULL;''') + data1 = self._cr.dictfetchall() + for rec in data1: + date_close = rec['date_conversion'] + date_create = rec['create_date'] + avg = (date_close - date_create).seconds + + if crm_lead_value == 0: + record_avg_time = 0 + else: + record_avg_time = round(avg / crm_lead_value) + + data_quarter = { + 'record': crm_lead_value, + 'record_op': opportunity_value, + 'record_rev_exp': exp_revenue_value, + 'record_rev': revenue_value, + 'record_ratio': ratio_value, + 'opportunity_ratio_value': str(opportunity_ratio_value), + 'avg_time': record_avg_time, + } + return data_quarter + + @api.model + def crm_month(self): + """Month CRM Dropdown Filter""" + session_user_id = self.env.uid + + self._cr.execute('''select COUNT(id) from crm_lead WHERE crm_lead.user_id = '%s' + AND Extract(MONTH FROM crm_lead.date_deadline) = Extract(MONTH FROM DATE(NOW())) + AND Extract(Year FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())) + ''' % session_user_id) + record = self._cr.dictfetchall() + rec_ids = [item['count'] for item in record] + crm_lead_value = rec_ids[0] + + self._cr.execute('''select COUNT(id) from crm_lead WHERE crm_lead.user_id = %s + AND crm_lead.type = 'opportunity' AND Extract(MONTH FROM crm_lead.date_deadline + ) = Extract(MONTH FROM DATE(NOW())) AND Extract(Year FROM crm_lead.date_deadline + ) = Extract(Year FROM DATE(NOW( )))''' % session_user_id) + opportunity_data = self._cr.dictfetchall() + opportunity_data_value = [item['count'] for item in opportunity_data] + opportunity_value = opportunity_data_value[0] + + self._cr.execute('''select SUM(crm_lead.expected_revenue) from crm_lead WHERE + crm_lead.user_id = %s and type='opportunity' and active='true' AND Extract( + MONTH FROM crm_lead.date_deadline) = Extract(MONTH FROM DATE(NOW())) AND + Extract(Year FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())) + ''' % session_user_id) + exp_revenue_data = self._cr.dictfetchall() + exp_revenue_data_value = [item['sum'] for item in exp_revenue_data] + exp_revenue_value = exp_revenue_data_value[0] + if exp_revenue_value is None: + exp_revenue_value = 0 + + self._cr.execute('''select SUM(crm_lead.expected_revenue) from crm_lead WHERE + crm_lead.user_id = %s and type='opportunity' and active='true' and stage_id=4 + AND Extract(MONTH FROM crm_lead.date_closed) = Extract(MONTH FROM DATE(NOW())) + AND Extract(Year FROM crm_lead.date_closed) = Extract(Year FROM DATE(NOW())) + ''' % session_user_id) + revenue_data = self._cr.dictfetchall() + revenue_data_value = [item['sum'] for item in revenue_data] + revenue_value = revenue_data_value[0] + if revenue_value is None: + revenue_value = 0 + + ratio_value = [] + if revenue_value == 0: + ratio_value = 0 + if revenue_value > 0: + self._cr.execute('''select case when a.count_one+b.count_two = 0 then 0 else ( + CAST(a.count_one as float) / CAST(b.count_two as float))end as final_count + from (select COUNT(id) as count_one from crm_lead + WHERE crm_lead.user_id = '%s' AND crm_lead.active = True AND + crm_lead.probability = 100 AND Extract(MONTH FROM crm_lead.date_deadline + ) = Extract(MONTH FROM DATE(NOW())) AND Extract(Year FROM crm_lead.date_open + ) = Extract(Year FROM DATE(NOW())))a, + (select COUNT(id) as count_two from crm_lead WHERE crm_lead.user_id = '%s' + AND crm_lead.active = False AND crm_lead.probability = 0 AND Extract( + MONTH FROM crm_lead.date_deadline) = Extract(MONTH FROM DATE(NOW())) AND + Extract(Year FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())))b + ''' % (session_user_id, session_user_id)) + ratio_value = [row[0] for row in self._cr.fetchall()] + ratio_value = str(ratio_value)[1:-1] + + self._cr.execute('''SELECT active,count(active) FROM crm_lead + where type='opportunity' and active = true and probability = 100 and user_id=%s + AND Extract(MONTH FROM date_closed) = Extract(MONTH FROM DATE(NOW())) + AND Extract(Year FROM date_closed) = Extract(Year FROM DATE(NOW())) + or type='opportunity' and active = false and probability = 0 and user_id=%s + AND Extract(MONTH FROM date_deadline) = Extract(MONTH FROM DATE(NOW())) + AND Extract(Year FROM date_deadline) = Extract(Year FROM DATE(NOW())) + GROUP BY active''' % (session_user_id, session_user_id)) + record_opportunity = dict(self._cr.fetchall()) + opportunity_ratio_value = 0.0 + if record_opportunity == {}: + opportunity_ratio_value = 0.0 + else: + total_opportunity_won = record_opportunity.get(False) + total_opportunity_lost = record_opportunity.get(True) + if total_opportunity_won is None: + total_opportunity_won = 0 + if total_opportunity_lost is None: + total_opportunity_lost = 0 + opportunity_ratio_value = 0.0 + if total_opportunity_lost > 0: + opportunity_ratio_value = round(total_opportunity_won / total_opportunity_lost, 2) + + avg = 0 + if crm_lead_value == 1: + self._cr.execute('''SELECT id, date_conversion, create_date + FROM crm_lead WHERE date_conversion IS NOT NULL;''') + data = self._cr.dictfetchall() + for rec in data: + date_close = rec['date_conversion'] + date_create = rec['create_date'] + avg = (date_close - date_create).seconds + if crm_lead_value > 1: + self._cr.execute('''SELECT id, date_conversion, create_date + FROM crm_lead WHERE date_conversion IS NOT NULL;''') + data1 = self._cr.dictfetchall() + for rec in data1: + date_close = rec['date_conversion'] + date_create = rec['create_date'] + avg = (date_close - date_create).seconds + + record_avg_time = 0 if crm_lead_value == 0 else round(avg / crm_lead_value) + + data_month = { + 'record': crm_lead_value, + 'record_op': opportunity_value, + 'record_rev_exp': exp_revenue_value, + 'record_rev': revenue_value, + 'record_ratio': ratio_value, + 'opportunity_ratio_value': str(opportunity_ratio_value), + 'avg_time': record_avg_time, + } + return data_month + + @api.model + def crm_week(self): + """Week CRM Dropdown Filter""" + session_user_id = self.env.uid + + self._cr.execute('''select COUNT(id) from crm_lead WHERE crm_lead.user_id = '%s' + AND Extract(MONTH FROM crm_lead.date_deadline) = Extract(MONTH FROM DATE(NOW())) + AND Extract(Week FROM crm_lead.date_deadline) = Extract(Week FROM DATE(NOW())) AND + Extract(Year FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())) + ''' % session_user_id) + record = self._cr.dictfetchall() + rec_ids = [item['count'] for item in record] + crm_lead_value = rec_ids[0] + + self._cr.execute('''select COUNT(id) from crm_lead WHERE crm_lead.user_id = %s + AND crm_lead.type = 'opportunity' AND Extract(MONTH FROM crm_lead.date_deadline + ) = Extract(MONTH FROM DATE(NOW())) AND Extract(Week FROM crm_lead.date_deadline + ) = Extract(Week FROM DATE(NOW())) AND Extract(Year FROM crm_lead.date_deadline + ) = Extract(Year FROM DATE(NOW()))''' % session_user_id) + opportunity_data = self._cr.dictfetchall() + opportunity_data_value = [item['count'] for item in opportunity_data] + opportunity_value = opportunity_data_value[0] + + self._cr.execute('''select SUM(crm_lead.expected_revenue) from crm_lead WHERE + crm_lead.user_id = %s and type='opportunity' and active='true' AND Extract( + MONTH FROM crm_lead.date_deadline) = Extract(MONTH FROM DATE(NOW())) AND + Extract(Week FROM crm_lead.date_deadline) = Extract(Week FROM DATE(NOW())) + AND Extract(Year FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())) + ''' % session_user_id) + exp_revenue_data = self._cr.dictfetchall() + exp_revenue_data_value = [item['sum'] for item in exp_revenue_data] + exp_revenue_value = exp_revenue_data_value[0] + if exp_revenue_value is None: + exp_revenue_value = 0 + + self._cr.execute('''select SUM(crm_lead.expected_revenue) from crm_lead WHERE + crm_lead.user_id = %s and type='opportunity' and active='true' and stage_id=4 + AND Extract(MONTH FROM crm_lead.date_closed) = Extract(MONTH FROM DATE(NOW())) + AND Extract(Week FROM crm_lead.date_closed) = Extract(Week FROM DATE(NOW())) + AND Extract(Year FROM crm_lead.date_closed) = Extract(Year FROM DATE(NOW())) + ''' % session_user_id) + revenue_data = self._cr.dictfetchall() + revenue_data_value = [item['sum'] for item in revenue_data] + revenue_value = revenue_data_value[0] + if revenue_value is None: + revenue_value = 0 + + ratio_value = [] + if revenue_value == 0: + ratio_value = 0 + if revenue_value > 0: + self._cr.execute('''select case when a.count_one+b.count_two = 0 then 0 else ( + CAST(a.count_one as float) / CAST(b.count_two as float))end as final_count + from (select COUNT(id) as count_one from crm_lead + WHERE crm_lead.user_id = '%s' AND crm_lead.active = True AND + crm_lead.probability = 100 AND Extract(MONTH FROM crm_lead.date_deadline + ) = Extract(MONTH FROM DATE(NOW())) AND Extract(Week FROM crm_lead.date_deadline + ) = Extract(Week FROM DATE(NOW())) AND Extract(Year FROM crm_lead.date_open + ) = Extract(Year FROM DATE(NOW())))a, + (select COUNT(id) as count_two from crm_lead WHERE crm_lead.user_id = '%s' + AND crm_lead.active = False AND crm_lead.probability = 0 AND Extract(MONTH + FROM crm_lead.date_deadline) = Extract(MONTH FROM DATE(NOW())) AND Extract(Week + FROM crm_lead.date_deadline) = Extract(Week FROM DATE(NOW())) AND Extract(Year FROM + crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())))b + ''' % (session_user_id, session_user_id)) + ratio_value = [row[0] for row in self._cr.fetchall()] + ratio_value = str(ratio_value)[1:-1] + + self._cr.execute('''SELECT active,count(active) FROM crm_lead + where type='opportunity' and active = true and probability = 100 and user_id=%s + AND Extract(MONTH FROM crm_lead.date_closed) = Extract(MONTH FROM DATE(NOW())) + AND Extract(Week FROM crm_lead.date_closed) = Extract(Week FROM DATE(NOW())) + AND Extract(Year FROM crm_lead.date_closed) = Extract(Year FROM DATE(NOW())) + or type='opportunity' and active = false and probability = 0 and user_id=%s + AND Extract(MONTH FROM crm_lead.date_deadline) = Extract(MONTH FROM DATE(NOW())) + AND Extract(Week FROM crm_lead.date_deadline) = Extract(Week FROM DATE(NOW())) + AND Extract(Year FROM crm_lead.date_deadline) = Extract(Year FROM DATE(NOW())) + GROUP BY active''' % (session_user_id, session_user_id)) + record_opportunity = dict(self._cr.fetchall()) + opportunity_ratio_value = 0.0 + if record_opportunity == {}: + opportunity_ratio_value = 0.0 + else: + total_opportunity_won = record_opportunity.get(False) + total_opportunity_lost = record_opportunity.get(True) + if total_opportunity_won is None: + total_opportunity_won = 0 + if total_opportunity_lost is None: + total_opportunity_lost = 0 + opportunity_ratio_value = 0.0 + if total_opportunity_lost > 0: + opportunity_ratio_value = round(total_opportunity_won / total_opportunity_lost, 2) + + avg = 0 + if crm_lead_value == 1: + self._cr.execute('''SELECT id, date_conversion, create_date + FROM crm_lead WHERE date_conversion IS NOT NULL;''') + data = self._cr.dictfetchall() + for rec in data: + date_close = rec['date_conversion'] + date_create = rec['create_date'] + avg = (date_close - date_create).seconds + if crm_lead_value > 1: + self._cr.execute('''SELECT id, date_conversion, create_date + FROM crm_lead WHERE date_conversion IS NOT NULL;''') + data1 = self._cr.dictfetchall() + for rec in data1: + date_close = rec['date_conversion'] + date_create = rec['create_date'] + avg = (date_close - date_create).seconds + + if crm_lead_value == 0: + record_avg_time = 0 + else: + record_avg_time = round(avg / crm_lead_value) + + data_week = { + 'record': crm_lead_value, + 'record_op': opportunity_value, + 'record_rev_exp': exp_revenue_value, + 'record_rev': revenue_value, + 'record_ratio': ratio_value, + 'opportunity_ratio_value': str(opportunity_ratio_value), + 'avg_time': record_avg_time, + } + return data_week + + +class CampaignSmartButton(models.Model): + _inherit = 'utm.campaign' + + total_ratio = fields.Float(compute='_compute_ratio') + + def get_ratio(self): + """Onclick of Smart Button""" + self.ensure_one() + + return { + 'type': 'ir.actions.act_window', + 'name': 'Win Loss Ratio', + 'view_mode': 'kanban', + 'res_model': 'crm.lead', + 'domain': [['user_id', '=', self.env.uid], "|", + "&", ["active", "=", True], ["probability", '=', 100], + "&", ["active", "=", False], ["probability", '=', 0] + ], + 'context': "{'create': False,'records_draggable': False}" + } + + def _compute_ratio(self): + """Compute the Win Loss Ratio""" + total_won = self.env['crm.lead'].search_count( + [('active', '=', True), ('probability', '=', 100), + ('user_id', '=', self.env.uid)]) + total_lose = self.env['crm.lead'].search_count( + [('active', '=', False), ('probability', '=', 0), + ('user_id', '=', self.env.uid)]) + + if total_lose == 0: + ratio = 0 + else: + ratio = round(total_won / total_lose, 2) + self.total_ratio = ratio diff --git a/crm_dashboard/static/description/assets/icons/check.png b/crm_dashboard/static/description/assets/icons/check.png new file mode 100644 index 000000000..ea0da5029 Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/check.png differ diff --git a/crm_dashboard/static/description/assets/icons/chevron.png b/crm_dashboard/static/description/assets/icons/chevron.png new file mode 100644 index 000000000..f49dd8541 Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/chevron.png differ diff --git a/crm_dashboard/static/description/assets/icons/cogs.png b/crm_dashboard/static/description/assets/icons/cogs.png new file mode 100644 index 000000000..95d0bad62 Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/cogs.png differ diff --git a/crm_dashboard/static/description/assets/icons/consultation.png b/crm_dashboard/static/description/assets/icons/consultation.png new file mode 100644 index 000000000..8319d4baa Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/consultation.png differ diff --git a/crm_dashboard/static/description/assets/icons/ecom-black.png b/crm_dashboard/static/description/assets/icons/ecom-black.png new file mode 100644 index 000000000..a9385ff13 Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/ecom-black.png differ diff --git a/crm_dashboard/static/description/assets/icons/education-black.png b/crm_dashboard/static/description/assets/icons/education-black.png new file mode 100644 index 000000000..3eb09b27b Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/education-black.png differ diff --git a/crm_dashboard/static/description/assets/icons/hotel-black.png b/crm_dashboard/static/description/assets/icons/hotel-black.png new file mode 100644 index 000000000..130f613be Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/hotel-black.png differ diff --git a/crm_dashboard/static/description/assets/icons/icon.png b/crm_dashboard/static/description/assets/icons/icon.png new file mode 100644 index 000000000..61b0eb171 Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/icon.png differ diff --git a/crm_dashboard/static/description/assets/icons/license.png b/crm_dashboard/static/description/assets/icons/license.png new file mode 100644 index 000000000..a5869797e Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/license.png differ diff --git a/crm_dashboard/static/description/assets/icons/lifebuoy.png b/crm_dashboard/static/description/assets/icons/lifebuoy.png new file mode 100644 index 000000000..658d56ccc Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/lifebuoy.png differ diff --git a/crm_dashboard/static/description/assets/icons/logo.png b/crm_dashboard/static/description/assets/icons/logo.png new file mode 100644 index 000000000..478462d3e Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/logo.png differ diff --git a/crm_dashboard/static/description/assets/icons/manufacturing-black.png b/crm_dashboard/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 000000000..697eb0e9f Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/manufacturing-black.png differ diff --git a/crm_dashboard/static/description/assets/icons/pos-black.png b/crm_dashboard/static/description/assets/icons/pos-black.png new file mode 100644 index 000000000..97c0f90c1 Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/pos-black.png differ diff --git a/crm_dashboard/static/description/assets/icons/puzzle.png b/crm_dashboard/static/description/assets/icons/puzzle.png new file mode 100644 index 000000000..65cf854e7 Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/puzzle.png differ diff --git a/crm_dashboard/static/description/assets/icons/restaurant-black.png b/crm_dashboard/static/description/assets/icons/restaurant-black.png new file mode 100644 index 000000000..4a35eb939 Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/restaurant-black.png differ diff --git a/crm_dashboard/static/description/assets/icons/service-black.png b/crm_dashboard/static/description/assets/icons/service-black.png new file mode 100644 index 000000000..301ab51cb Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/service-black.png differ diff --git a/crm_dashboard/static/description/assets/icons/trading-black.png b/crm_dashboard/static/description/assets/icons/trading-black.png new file mode 100644 index 000000000..9398ba2f1 Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/trading-black.png differ diff --git a/crm_dashboard/static/description/assets/icons/training.png b/crm_dashboard/static/description/assets/icons/training.png new file mode 100644 index 000000000..884ca024d Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/training.png differ diff --git a/crm_dashboard/static/description/assets/icons/update.png b/crm_dashboard/static/description/assets/icons/update.png new file mode 100644 index 000000000..ecbc5a01a Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/update.png differ diff --git a/crm_dashboard/static/description/assets/icons/user.png b/crm_dashboard/static/description/assets/icons/user.png new file mode 100644 index 000000000..6ffb23d9f Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/user.png differ diff --git a/crm_dashboard/static/description/assets/icons/wrench.png b/crm_dashboard/static/description/assets/icons/wrench.png new file mode 100644 index 000000000..6c04dea0f Binary files /dev/null and b/crm_dashboard/static/description/assets/icons/wrench.png differ diff --git a/crm_dashboard/static/description/assets/modules/accounting_image.gif b/crm_dashboard/static/description/assets/modules/accounting_image.gif new file mode 100644 index 000000000..69bf230e7 Binary files /dev/null and b/crm_dashboard/static/description/assets/modules/accounting_image.gif differ diff --git a/crm_dashboard/static/description/assets/modules/approval_image.png b/crm_dashboard/static/description/assets/modules/approval_image.png new file mode 100644 index 000000000..84fe94e80 Binary files /dev/null and b/crm_dashboard/static/description/assets/modules/approval_image.png differ diff --git a/crm_dashboard/static/description/assets/modules/budget_image.png b/crm_dashboard/static/description/assets/modules/budget_image.png new file mode 100644 index 000000000..fe6aa6fe4 Binary files /dev/null and b/crm_dashboard/static/description/assets/modules/budget_image.png differ diff --git a/crm_dashboard/static/description/assets/modules/deadline_image.png b/crm_dashboard/static/description/assets/modules/deadline_image.png new file mode 100644 index 000000000..6bd27b8b5 Binary files /dev/null and b/crm_dashboard/static/description/assets/modules/deadline_image.png differ diff --git a/crm_dashboard/static/description/assets/modules/export_image.png b/crm_dashboard/static/description/assets/modules/export_image.png new file mode 100644 index 000000000..4e4ea0e51 Binary files /dev/null and b/crm_dashboard/static/description/assets/modules/export_image.png differ diff --git a/crm_dashboard/static/description/assets/modules/pos_image.png b/crm_dashboard/static/description/assets/modules/pos_image.png new file mode 100644 index 000000000..c5932894b Binary files /dev/null and b/crm_dashboard/static/description/assets/modules/pos_image.png differ diff --git a/crm_dashboard/static/description/assets/screenshots/CRM-Dashboard-user.png b/crm_dashboard/static/description/assets/screenshots/CRM-Dashboard-user.png new file mode 100644 index 000000000..794115f30 Binary files /dev/null and b/crm_dashboard/static/description/assets/screenshots/CRM-Dashboard-user.png differ diff --git a/crm_dashboard/static/description/assets/screenshots/CRM-Dashboard.png b/crm_dashboard/static/description/assets/screenshots/CRM-Dashboard.png new file mode 100644 index 000000000..17d189a5b Binary files /dev/null and b/crm_dashboard/static/description/assets/screenshots/CRM-Dashboard.png differ diff --git a/crm_dashboard/static/description/assets/screenshots/hero.gif b/crm_dashboard/static/description/assets/screenshots/hero.gif new file mode 100644 index 000000000..2c5ff9a29 Binary files /dev/null and b/crm_dashboard/static/description/assets/screenshots/hero.gif differ diff --git a/crm_dashboard/static/description/assets/screenshots/screenshot-1.png b/crm_dashboard/static/description/assets/screenshots/screenshot-1.png new file mode 100644 index 000000000..1d13a5425 Binary files /dev/null and b/crm_dashboard/static/description/assets/screenshots/screenshot-1.png differ diff --git a/crm_dashboard/static/description/assets/screenshots/screenshot-2.png b/crm_dashboard/static/description/assets/screenshots/screenshot-2.png new file mode 100644 index 000000000..5cf05a3c5 Binary files /dev/null and b/crm_dashboard/static/description/assets/screenshots/screenshot-2.png differ diff --git a/crm_dashboard/static/description/assets/screenshots/screenshot-22.png b/crm_dashboard/static/description/assets/screenshots/screenshot-22.png new file mode 100644 index 000000000..ad247eb9d Binary files /dev/null and b/crm_dashboard/static/description/assets/screenshots/screenshot-22.png differ diff --git a/crm_dashboard/static/description/assets/screenshots/screenshot-3.png b/crm_dashboard/static/description/assets/screenshots/screenshot-3.png new file mode 100644 index 000000000..11799ce0a Binary files /dev/null and b/crm_dashboard/static/description/assets/screenshots/screenshot-3.png differ diff --git a/crm_dashboard/static/description/assets/screenshots/screenshot-4.png b/crm_dashboard/static/description/assets/screenshots/screenshot-4.png new file mode 100644 index 000000000..944bdfaf5 Binary files /dev/null and b/crm_dashboard/static/description/assets/screenshots/screenshot-4.png differ diff --git a/crm_dashboard/static/description/assets/screenshots/screenshot-5.png b/crm_dashboard/static/description/assets/screenshots/screenshot-5.png new file mode 100644 index 000000000..d157c91e0 Binary files /dev/null and b/crm_dashboard/static/description/assets/screenshots/screenshot-5.png differ diff --git a/crm_dashboard/static/description/assets/screenshots/screenshot-6.png b/crm_dashboard/static/description/assets/screenshots/screenshot-6.png new file mode 100644 index 000000000..65e5c42cf Binary files /dev/null and b/crm_dashboard/static/description/assets/screenshots/screenshot-6.png differ diff --git a/crm_dashboard/static/description/banner.png b/crm_dashboard/static/description/banner.png new file mode 100644 index 000000000..a5435d94b Binary files /dev/null and b/crm_dashboard/static/description/banner.png differ diff --git a/crm_dashboard/static/description/icon.png b/crm_dashboard/static/description/icon.png new file mode 100644 index 000000000..8e5abc8e0 Binary files /dev/null and b/crm_dashboard/static/description/icon.png differ diff --git a/crm_dashboard/static/description/index.html b/crm_dashboard/static/description/index.html new file mode 100644 index 000000000..0d7871569 --- /dev/null +++ b/crm_dashboard/static/description/index.html @@ -0,0 +1,605 @@ +
+
+
+
+ +
+
+
+ Community +
+
+ Enterprise +
+ +
+
+
+
+ +
+
+
+
+ +

+ CRM Dashboard

+
+ +

+ Detailed Dashboard View for CRM. +

+ +
+
+ +
+
+

+ Explore this module

+ + +
+
+
+ +
+
+

+ Overview

+
+

+ The CRM Dashboard module helps you to see the Overview of the CRM module and its functioning, moreover, the CRM Dashboard helps you to know the overview of the CRM beautifully. Here you can see all details related to CRM module operations such as Leads, Opportunities, Expected, and Total Revenue. Furthermore, we can view the different types of reports in the form of graphs according to the values and operations of CRM. +

+
+
+ +
+
+

+ Features

+
+
+
+
+ +

Different views for user and admin.

+
+ +
+ +

Upcoming and recent activities.

+
+ +
+ +

Year to date bar graph and target field in user + settings.

+
+
+
+
+ +

Lost reason analysis.

+
+ +
+ +

View Top deals and monthly goal.

+
+ +
+ +

Clickable Dashboard Cards.

+
+
+
+
+
+ + +
+
+

+ Screenshots

+
+ +
+
+ +

The Clickable Dashboard Card Helps with the Analysis of Records. +

+
+ +
+ +
+
+ +

Funnel chart and Year to Date chart helps to understand + the target. + Also have the pie chart for lead Analysis by month and activity.

+
+ +
+ +
+
+ +

User Target for Year to Date.
Target: Settings>User + Settings>Below the access right tab.

+
+ +
+ +
+
+ +

Top Deals is listed and the Monthly goal gauge is helping + to achieve the goals. +

+
+ +
+ +
+
+ +

Upcoming activities and Total revenue by salesperson.

+
+ +
+ +
+
+ +

Sales person and country wise revenue and the country wise + count of opportunities in Heatmap.

+
+ +
+ +
+
+ +

Lost analysis graph, Recent activities and Top sales + person by invoice

+
+ +
+ +
+
+ +

Dashboard View for User.

+
+ +
+ +
+
+ + +
+
+

+ Suggested Products

+
+ + +
+
+ + + +
+
+
+

+ Our Services

+
+
+ +
+
+ +
+
+ Odoo + Customization
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Support
+
+ + +
+
+ +
+
+ Hire + Odoo + Developer
+
+ +
+
+ +
+
+ Odoo + Integration
+
+ +
+
+ +
+
+ Odoo + Migration
+
+ + +
+
+ +
+
+ Odoo + Consultancy
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Licensing Consultancy
+
+
+
+ + + +
+
+
+

+ Our Industries

+
+
+ +
+
+ +
+ Trading +
+

+ Easily procure + and + sell your products

+
+
+ +
+
+ +
+ POS +
+

+ Easy + configuration + and convivial experience

+
+
+ +
+
+ +
+ Education +
+

+ A platform for + educational management

+
+
+ +
+
+ +
+ Manufacturing +
+

+ Plan, track and + schedule your operations

+
+
+ +
+
+ +
+ E-commerce & Website +
+

+ Mobile + friendly, + awe-inspiring product pages

+
+
+ +
+
+ +
+ Service Management +
+

+ Keep track of + services and invoice

+
+
+ +
+
+ +
+ Restaurant +
+

+ Run your bar or + restaurant methodically

+
+
+ +
+
+ +
+ Hotel Management +
+

+ An + all-inclusive + hotel management application

+
+
+ +
+
+ + + + + +
+
+
+

+ Need Help?

+
+
+
+ + +
+ +
+ + +
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+
+ + +
\ No newline at end of file diff --git a/crm_dashboard/static/src/css/dashboard.css b/crm_dashboard/static/src/css/dashboard.css new file mode 100644 index 000000000..335e5831e --- /dev/null +++ b/crm_dashboard/static/src/css/dashboard.css @@ -0,0 +1,34 @@ +p, span, a, ul, li, button { + font-size: inherit; + font-weight: inherit; + line-height: inherit; +} + +strong { + font-weight: 600; +} + +h1, h2, h3, h4, h5, h6 { + line-height: 1.5em; + font-weight: 300; +} + +strong { + font-weight: 400; +} + +.sub_title { + font-size: 14px; +} + +.sub_title div span { + font-weight: 600; +} + +.chart #canvas_graph { + height: 400px !important; +} + +.highcharts-background { + fill: none; +} \ No newline at end of file diff --git a/crm_dashboard/static/src/css/material-gauge.css b/crm_dashboard/static/src/css/material-gauge.css new file mode 100644 index 000000000..7f553df9a --- /dev/null +++ b/crm_dashboard/static/src/css/material-gauge.css @@ -0,0 +1,194 @@ +/* + * #### Gauge Component + * + * The standard markup for the component is: + * + *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * No + * + * Yes + *
+ *
+ */ + +/* + * First define all of the relevant rules that aren't dependent + * on the size of the gauge. We want to collect the size-depenent + * rules in one place to make it easier to adjust the size. + */ + +.gauge { + position: relative; +} + +.gauge__container { + margin: 0; + padding: 0; + position: absolute; + left: 50%; + overflow: hidden; + text-align: center; + -webkit-transform: translateX(-50%); + -moz-transform: translateX(-50%); + -ms-transform: translateX(-50%); + -o-transform: translateX(-50%); + transform: translateX(-50%); +} + +.gauge__background { + z-index: 0; + position: absolute; + background-color: #d8f0de; + top: 0; + border-radius: 300px 300px 0 0; +} + +.gauge__data { + z-index: 1; + position: absolute; + background-color: #00c29d; + margin-left: auto; + margin-right: auto; + border-radius: 300px 300px 0 0; + -webkit-transform-origin: center bottom; + -moz-transform-origin: center bottom; + -ms-transform-origin: center bottom; + -o-transform-origin: center bottom; + transform-origin: center bottom; +} + +.gauge__center { + z-index: 2; + position: absolute; + background-color: #f9f9f9; + margin-right: auto; + border-radius: 300px 300px 0 0; +} + +.gauge__marker { + z-index: 3; + background-color: #fff; + position: absolute; + width: 1px; +} + +.gauge__needle { + z-index: 4; + background-color: #21242c; + height: 3px; + position: absolute; + -webkit-transform-origin: left center; + -moz-transform-origin: left center; + -ms-transform-origin: left center; + -o-transform-origin: left center; + transform-origin: left center; +} + +.gauge__labels { + display: table; + margin: 0 auto; + position: relative; +} + +.gauge__label--low { + display: table-cell; + text-align: center; + color: #00c29d; +} + +.gauge__label--spacer { + display: table-cell; +} + +.gauge__label--high { + display: table-cell; + text-align: center; + color: #979f99; +} + +/* + * Now define the rules that depend on the size of + * the gauge. We start with sizing for a small mobile + * device. + */ + +.gauge { height: calc(120px + 3em); } +.gauge__container { width: 240px; height: 120px; } +.gauge__marker { height: 120px; left: 119.5px; } +.gauge__background { width: 240px; height: 120px; } +.gauge__center { width: 144px; height: 72px; top: 48px; margin-left: 48px; } +.gauge__data { width: 240px; height: 120px; } +.gauge__needle { left: 120px; top: 117px; width: 120px; } +.gauge__labels { top: 120px; width: 240px; } +.gauge__label--low { width: 48px; } +.gauge__label--spacer { width: 144px; } +.gauge__label--high { width: 48px; } + +/* + * Increase the gauge size slightly on larger viewports. + */ + + @media only screen and (min-width: 400px) { + .gauge { height: calc(150px + 3em); } + .gauge__container { width: 300px; height: 150px; } + .gauge__marker { height: 150px; left: 149.5px; } + .gauge__background { width: 300px; height: 150px; } + .gauge__center { width: 180px; height: 90px; top: 60px; margin-left: 60px; } + .gauge__data { width: 300px; height: 150px; } + .gauge__needle { left: 150px; top: 147px; width: 150px; } + .gauge__labels { top: 160px; width: 300px; font-size: 20px;} + .gauge__label--low { width: 60px; } + .gauge__label--spacer { width: 180px; } + .gauge__label--high { width: 60px; } +} + +/* + * As an option, the `gauge--liveupdate` class can be added + * to the main gauge element. When this class is present, + * we add a transition that animates any changes to the gauge + * value. Currently, the app does not use this option because + * all the inputs that can change gauge values are present + * on tab panels that are different from the gauge itself. + * Therefore, users won't be able to see any gauge changes + * when they make input changes. The code is available, though, + * should this change. + */ + +.gauge--liveupdate .gauge__data, +.gauge--liveupdate .gauge__needle { + -webkit-transition: all 1s ease-in-out; + -moz-transition: all 1s ease-in-out; + -ms-transition: all 1s ease-in-out; + -o-transition: all 1s ease-in-out; + transition: all 1s ease-in-out; +} + +/* + * For a given gauge value, x, ranging from 0.0 to 1.0, set + * the `transform: rotate()` property according to the + * following equation: `-0.5 + 0.5x turns` The default + * properties below represent an x value of 0. + */ + +.gauge__data { + -webkit-transform: rotate(-.50turn); + -moz-transform: rotate(-.50turn); + -ms-transform: rotate(-.50turn); + -o-transform: rotate(-.50turn); + transform: rotate(-.50turn); +} +.gauge__needle { + -webkit-transform: rotate(-.50turn); + -moz-transform: rotate(-.50turn); + -ms-transform: rotate(-.50turn); + -o-transform: rotate(-.50turn); + transform: rotate(-.50turn); +} diff --git a/crm_dashboard/static/src/css/style.scss b/crm_dashboard/static/src/css/style.scss new file mode 100644 index 000000000..b189646c4 --- /dev/null +++ b/crm_dashboard/static/src/css/style.scss @@ -0,0 +1,237 @@ +:root { + /* Primary */ + --mauve: #7D7EAF; + --pink-dark: #BD85BA; + --pink: #F78EAD; + --peach: #FFA48E; + --orange: #FFCA71; + --gold: #CEA716; + --green: #1EC198; + --grey: #a0a0a0; + /* Light */ + --mauve-light: #e5e5ef; + --pink-dark-light: #f2e7f1; + --pink-light: #fde8ef; + --peach-light: #ffede8; + --orange-light: #fff4e3; + --gold-light: #faf6e8; + --green-light: #e9f9f5; + --grey-light: #e0e0e0; + + /*Lighter*/ + --grey-lighter: #fafafa; + --grey-dark-lighter: #f3f3f3; +} + +/* Background */ +.bg-mauve-light { + background-color: var(--mauve-light); +} + +.bg-pink-dark-light { + background-color: var(--pink-dark-light); +} + +.bg-pink-light { + background-color: var(--pink-light); +} + +.bg-peach-light { + background-color: var(--peach-light); +} + +.bg-orange-light { + background-color: var(--orange-light); +} + +.bg-gold-light { + background-color: var(--gold-light); +} + +.bg-green-light { + background-color: var(--green-light); +} + +/* Text */ +.text-mauve { + color: var(--mauve); +} + +.text-pink-dark { + color: var(--pink-dark); +} + +.text-pink { + color: var(--pink); +} + +.text-peach { + color: var(--peach); +} + +.text-orange { + color: var(--orange); +} + +.text-gold { + color: var(--gold); +} + +.text-green { + color: var(--green); +} + +/* Cards */ + +.dashboard-card { + border-radius: 0.3rem; + display: flex; + justify-content: center; + padding: 1.7rem 1.5rem 1.5rem 1.5rem; + margin: 1rem auto; + height: 90px; +} + +.dashboard-card__icon-container { + height: 50px; + width: 50px; + border-radius: 50%; +} + +.dashboard-card__icon-container i { + font-size: 20px; +} + +.dashboard-card__details { + margin-left: 1rem; + max-width: 120px; +} + +.dashboard-card__details h3 { + font-weight: 700; + font-size: 1.5rem; +} + +.dashboard-card__details h4 { + font-weight: 700; + font-size: 0.7rem; + color: var(--grey); + margin-top: -5px; +} + +h2.section-header { + font-weight: 700; + font-size: 1.5rem; +} + +.chart-container { + border-radius: 0.3rem; + padding: 1rem; + margin: 1rem auto; +} + +.chart-container.card-shadow { + height: 100%; +} + +.half_chart.chart-container.card-shadow { + height: 49%; +} + +.chart-container h2 { + font-weight: 700; + font-size: 1.125rem; +} + +.item-container { + background-color: var(--grey-lighter); + border-radius: 0.3rem; + padding: 1.2rem 1rem; + margin: 1rem auto; +} + +.item-container:hover { + background-color: var(--grey-dark-lighter); + transition: all 0.3s ease-in-out; + cursor: pointer; +} + +.count-container { + font-weight: 700; + font-size: 1.7rem; + background-color: var(--mauve-light); + color: var(--mauve); + height: 50px; + width: 50px; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; +} + +.item-header { + display: flex; + align-items: flex-start; +} + +.item-title h3 { + font-size: 1.3rem; + font-weight: 700; +} + +.item-content ul { + list-style: none; + padding-left: 0px; +} + +.item-content ul>li { + font-size: 0.9rem; + color: var(--grey); + font-weight: 700; +} + +/* Misc */ +.card-shadow { + -webkit-box-shadow: 1px 3px 5px 0px rgba(222, 222, 222, 1); + -moz-box-shadow: 1px 3px 5px 0px rgba(222, 222, 222, 1); + box-shadow: 1px 3px 5px 0px rgba(222, 222, 222, 1); +} + +/* Table */ +thead { + background-color: #e9ecf0; + border-bottom: none; +} + +.table thead th { + border-bottom: none; +} + +.table td, +.table th { + border-top: 1px solid #eceff2; +} + +.crm_scroll_table { + max-height: 395px; + overflow-y: auto; +} +.recent_activity_div .crm_scroll_table { + max-height: 435px; +} + +.crm_scroll_table thead { + position: sticky; + top: 0; +} + +.crm_scroll_table .count-container { + height: 45px; + width: 130px; + border-radius: 50px; + margin-right: 10px; +} + +.crm_scroll_table .item-content ul > li { + font-size: 1.1rem; +} \ No newline at end of file diff --git a/crm_dashboard/static/src/js/custom.js b/crm_dashboard/static/src/js/custom.js new file mode 100644 index 000000000..f0a6955a5 --- /dev/null +++ b/crm_dashboard/static/src/js/custom.js @@ -0,0 +1,8 @@ +$(document).on("click", "#view_lost_dashboard", function(event){ + $(".dashboard_main_section").css({'display':'none'}); + $("#dashboard_sub_section").css({'display':'block'}); +}); +function BreadcrumbSubDash(){ + $(".dashboard_main_section").css({'display':'block'}); + $("#dashboard_sub_section").css({'display':'none'}); +}; \ No newline at end of file diff --git a/crm_dashboard/static/src/js/dashboard_view.js b/crm_dashboard/static/src/js/dashboard_view.js new file mode 100644 index 000000000..6e5090750 --- /dev/null +++ b/crm_dashboard/static/src/js/dashboard_view.js @@ -0,0 +1,1649 @@ +odoo.define('crm_dashboard.CRMDashboard', function (require) { + 'use strict'; + var AbstractAction = require('web.AbstractAction'); + var ajax = require('web.ajax'); + var core = require('web.core'); + var rpc = require('web.rpc'); + var web_client = require('web.web_client'); + var session = require('web.session'); + var _t = core._t; + var QWeb = core.qweb; + var self = this; + var currency; + var DashBoard = AbstractAction.extend({ + contentTemplate: 'CRMdashboard', + events: { + 'click .my_lead': 'my_lead', + 'click .opportunity': 'opportunity', + 'click .unassigned_leads': 'unassigned_leads', + 'click .exp_revenue': 'exp_revenue', + 'click .revenue_card': 'revenue_card', + 'change #income_expense_values': function(e) { + e.stopPropagation(); + var $target = $(e.target); + var value = $target.val(); + if (value=="this_year"){ + this.onclick_this_year($target.val()); + }else if (value=="this_quarter"){ + this.onclick_this_quarter($target.val()); + }else if (value=="this_month"){ + this.onclick_this_month($target.val()); + }else if (value=="this_week"){ + this.onclick_this_week($target.val()); + } + }, + 'change #total_loosed_crm': function(e) { + e.stopPropagation(); + var $target = $(e.target); + var value = $target.val(); + if (value=="lost_last_12months"){ + this.onclick_lost_last_12months($target.val()); + }else if (value=="lost_last_6months"){ + this.onclick_lost_last_6months($target.val()); + }else if (value=="lost_last_month"){ + this.onclick_lost_last_month($target.val()); + } + }, + 'change #total_loosed_crm_sub': function(e) { + e.stopPropagation(); + var $target = $(e.target); + var value = $target.val(); + if (value=="sub_lost_last_12months"){ + this.onclick_sub_lost_last_12months($target.val()); + }else if (value=="sub_lost_last_6months"){ + this.onclick_sub_lost_last_6months($target.val()); + }else if (value=="sub_lost_last_month"){ + this.onclick_sub_lost_last_month($target.val()); + } + }, + }, + + init: function(parent, context) { + this._super(parent, context); + this.upcoming_events = []; + this.dashboards_templates = ['LoginUser','Managercrm','Admincrm', 'SubDashboard']; + this.login_employee = []; + }, + + willStart: function(){ + var self = this; + this.login_employee = {}; + return this._super() + .then(function() { + + var def0 = self._rpc({ + model: 'crm.lead', + method: 'check_user_group' + }).then(function(result) { + if (result == true){ + self.is_manager = true; + } + else{ + self.is_manager = false; + } + }); + + var def1 = self._rpc({ + model: "crm.lead", + method: "get_upcoming_events", + }) + .then(function (res) { + self.upcoming_events = res['event']; + }); + + var def2 = self._rpc({ + model: "crm.lead", + method: "get_top_deals", + }) + .then(function (res) { + self.top_deals = res['deals']; + }); + + var def3 = self._rpc({ + model: "crm.lead", + method: "get_monthly_goal", + }) + .then(function (res) { + self.monthly_goals = res['goals']; + }); + + var def4 = self._rpc({ + model: "crm.lead", + method: "get_top_sp_revenue", + }) + .then(function (res) { + self.top_sp_revenue = res['top_revenue']; + }); + + var def5 = self._rpc({ + model: "crm.lead", + method: "get_country_revenue", + }) + .then(function (res) { + self.top_country_revenue = res['country_revenue']; + }); + + var def6 = self._rpc({ + model: "crm.lead", + method: "get_country_count", + }) + .then(function (res) { + self.top_country_count = res['country_count']; + }); + + var def7 = self._rpc({ + model: "crm.lead", + method: "get_lost_reason_count", + }) + .then(function (res) { + self.top_reason_count = res['reason_count']; + }); + + var def8 = self._rpc({ + model: "crm.lead", + method: "get_ratio_based_country", + }) + .then(function (res) { + self.top_country_wise_ratio = res['country_wise_ratio']; + }); + + var def9 = self._rpc({ + model: "crm.lead", + method: "get_ratio_based_sp", + }) + .then(function (res) { + self.top_salesperson_wise_ratio = res['salesperson_wise_ratio']; + }); + + var def10 = self._rpc({ + model: "crm.lead", + method: "get_ratio_based_sales_team", + }) + .then(function (res) { + self.top_sales_team_wise_ratio = res['sales_team_wise_ratio']; + }); + + var def11 = self._rpc({ + model: "crm.lead", + method: "get_recent_activities", + }) + .then(function (res) { + self.recent_activities = res['activities']; + }); + + var def12 = self._rpc({ + model: "crm.lead", + method: "get_count_unassigned", + }) + .then(function (res) { + self.get_count_unassigned = res['count_unassigned']; + }); + + var def13 = self._rpc({ + model: "crm.lead", + method: "get_top_sp_by_invoice", + }) + .then(function (res) { + self.top_sp_by_invoice = res['sales_person_invoice']; + }); + + return $.when(def0, def1, def2, def3, def4, def5, def6, def7, def8, def9, def10, def11, def12, def13); + }); + }, + + onclick_this_year: function (ev) { + var self = this; + rpc.query({ + model: 'crm.lead', + method: 'crm_year', + args: [], + }) + .then(function (result) { + $('#leads_this_quarter').hide(); + $('#opp_this_quarter').hide(); + $('#exp_rev_this_quarter').hide(); + $('#rev_this_quarter').hide(); + $('#ratio_this_quarter').hide(); + $('#avg_time_this_quarter').hide(); + $('#total_revenue_this_quarter').hide(); + $('#leads_this_month').hide(); + $('#opp_this_month').hide(); + $('#exp_rev_this_month').hide(); + $('#rev_this_month').hide(); + $('#ratio_this_month').hide(); + $('#avg_time_this_month').hide(); + $('#total_revenue_this_month').hide(); + $('#leads_this_week').hide(); + $('#opp_this_week').hide(); + $('#exp_rev_this_week').hide(); + $('#rev_this_week').hide(); + $('#ratio_this_week').hide(); + $('#avg_time_this_week').hide(); + $('#total_revenue_this_week').hide(); + + $('#leads_this_year').show(); + $('#opp_this_year').show(); + $('#exp_rev_this_year').show(); + $('#rev_this_year').show(); + $('#ratio_this_year').show(); + $('#avg_time_this_year').show(); + $('#total_revenue_this_year').show(); + + $('#leads_this_year').empty(); + $('#opp_this_year').empty(); + $('#exp_rev_this_year').empty(); + $('#rev_this_year').empty(); + $('#ratio_this_year').empty(); + $('#avg_time_this_year').empty(); + $('#total_revenue_this_year').empty(); + + $('#leads_this_year').append('' + result.record + ''); + $('#opp_this_year').append('' + result.record_op + ''); + $('#exp_rev_this_year').append('' + self.monthly_goals[2] + ' ' + result.record_rev_exp + ''); + $('#rev_this_year').append('' + self.monthly_goals[2] + ' ' + result.record_rev + ''); + $('#ratio_this_year').append('' + result.record_ratio + ''); + $('#avg_time_this_year').append('' + result.avg_time + ' sec' + ''); + $('#total_revenue_this_year').append('' + result.opportunity_ratio_value + ''); + }) + }, + + onclick_this_quarter: function (ev) { + var self = this; + rpc.query({ + model: 'crm.lead', + method: 'crm_quarter', + args: [], + }) + .then(function (result) { + $('#leads_this_year').hide(); + $('#opp_this_year').hide(); + $('#exp_rev_this_year').hide(); + $('#rev_this_year').hide(); + $('#ratio_this_year').hide(); + $('#avg_time_this_year').hide(); + $('#total_revenue_this_year').hide(); + $('#leads_this_month').hide(); + $('#opp_this_month').hide(); + $('#exp_rev_this_month').hide(); + $('#rev_this_month').hide(); + $('#ratio_this_month').hide(); + $('#avg_time_this_month').hide(); + $('#total_revenue_this_month').hide(); + $('#leads_this_week').hide(); + $('#opp_this_week').hide(); + $('#exp_rev_this_week').hide(); + $('#rev_this_week').hide(); + $('#ratio_this_week').hide(); + $('#avg_time_this_week').hide(); + $('#total_revenue_this_week').hide(); + + $('#leads_this_quarter').show(); + $('#opp_this_quarter').show(); + $('#exp_rev_this_quarter').show(); + $('#rev_this_quarter').show(); + $('#ratio_this_quarter').show(); + $('#avg_time_this_quarter').show(); + $('#total_revenue_this_quarter').show(); + + $('#leads_this_quarter').empty(); + $('#opp_this_quarter').empty(); + $('#exp_rev_this_quarter').empty(); + $('#rev_this_quarter').empty(); + $('#ratio_this_quarter').empty(); + $('#avg_time_this_quarter').empty(); + $('#total_revenue_this_quarter').empty(); + + $('#leads_this_quarter').append('' + result.record + ''); + $('#opp_this_quarter').append('' + result.record_op + ''); + $('#exp_rev_this_quarter').append('' + self.monthly_goals[2] + ' ' + result.record_rev_exp + ''); + $('#rev_this_quarter').append('' + self.monthly_goals[2] + ' ' + result.record_rev + ''); + $('#ratio_this_quarter').append('' + result.record_ratio + ''); + $('#avg_time_this_quarter').append('' + result.avg_time + ' sec' + ''); + $('#total_revenue_this_quarter').append('' + result.opportunity_ratio_value + ''); + }) + }, + + onclick_this_month: function (ev) { + var self = this; + rpc.query({ + model: 'crm.lead', + method: 'crm_month', + args: [], + }) + .then(function (result) { + $('#leads_this_year').hide(); + $('#opp_this_year').hide(); + $('#exp_rev_this_year').hide(); + $('#rev_this_year').hide(); + $('#ratio_this_year').hide(); + $('#avg_time_this_year').hide(); + $('#total_revenue_this_year').hide(); + $('#leads_this_quarter').hide(); + $('#opp_this_quarter').hide(); + $('#exp_rev_this_quarter').hide(); + $('#rev_this_quarter').hide(); + $('#ratio_this_quarter').hide(); + $('#avg_time_this_quarter').hide(); + $('#total_revenue_this_quarter').hide(); + $('#leads_this_week').hide(); + $('#opp_this_week').hide(); + $('#exp_rev_this_week').hide(); + $('#rev_this_week').hide(); + $('#ratio_this_week').hide(); + $('#avg_time_this_week').hide(); + $('#total_revenue_this_week').hide(); + + $('#leads_this_month').show(); + $('#opp_this_month').show(); + $('#exp_rev_this_month').show(); + $('#rev_this_month').show(); + $('#ratio_this_month').show(); + $('#avg_time_this_month').show(); + $('#total_revenue_this_month').show(); + + $('#leads_this_month').empty(); + $('#opp_this_month').empty(); + $('#exp_rev_this_month').empty(); + $('#rev_this_month').empty(); + $('#ratio_this_month').empty(); + $('#avg_time_this_month').empty(); + $('#total_revenue_this_month').empty(); + + $('#leads_this_month').append('' + result.record + ''); + $('#opp_this_month').append('' + result.record_op + ''); + $('#exp_rev_this_month').append('' + self.monthly_goals[2] + ' ' + result.record_rev_exp + ''); + $('#rev_this_month').append('' + self.monthly_goals[2] + ' ' + result.record_rev + ''); + $('#ratio_this_month').append('' + result.record_ratio + ''); + $('#avg_time_this_month').append('' + result.avg_time + ' sec' + ''); + $('#total_revenue_this_month').append('' + result.opportunity_ratio_value + ''); + }) + }, + + onclick_this_week: function (ev) { + var self = this; + rpc.query({ + model: 'crm.lead', + method: 'crm_week', + args: [], + }) + .then(function (result) { + $('#leads_this_year').hide(); + $('#opp_this_year').hide(); + $('#exp_rev_this_year').hide(); + $('#rev_this_year').hide(); + $('#ratio_this_year').hide(); + $('#avg_time_this_year').hide(); + $('#total_revenue_this_year').hide(); + $('#leads_this_quarter').hide(); + $('#opp_this_quarter').hide(); + $('#exp_rev_this_quarter').hide(); + $('#rev_this_quarter').hide(); + $('#ratio_this_quarter').hide(); + $('#avg_time_this_quarter').hide(); + $('#total_revenue_this_quarter').hide(); + $('#leads_this_month').hide(); + $('#opp_this_month').hide(); + $('#exp_rev_this_month').hide(); + $('#rev_this_month').hide(); + $('#ratio_this_month').hide(); + $('#avg_time_this_month').hide(); + $('#total_revenue_this_month').hide(); + + $('#leads_this_week').show(); + $('#opp_this_week').show(); + $('#exp_rev_this_week').show(); + $('#rev_this_week').show(); + $('#ratio_this_week').show(); + $('#avg_time_this_week').show(); + $('#total_revenue_this_week').show(); + + $('#leads_this_week').empty(); + $('#opp_this_week').empty(); + $('#exp_rev_this_week').empty(); + $('#rev_this_week').empty(); + $('#ratio_this_week').empty(); + $('#avg_time_this_week').empty(); + $('#total_revenue_this_week').empty(); + + $('#leads_this_week').append('' + result.record + ''); + $('#opp_this_week').append('' + result.record_op + ''); + $('#exp_rev_this_week').append('' + self.monthly_goals[2] + ' ' + result.record_rev_exp + ''); + $('#rev_this_week').append('' + self.monthly_goals[2] + ' ' + result.record_rev + ''); + $('#ratio_this_week').append('' + result.record_ratio + ''); + $('#avg_time_this_week').append('' + result.avg_time + ' sec' + ''); + $('#total_revenue_this_week').append('' + result.opportunity_ratio_value + ''); + }) + }, + + renderElement: function (ev) { + var self = this; + $.when(this._super()) + .then(function (ev) { + rpc.query({ + model: "crm.lead", + method: "lead_details_user", + args: [], + }) + .then(function (result) { + $('#leads_this_month').append('' + result.record + ''); + $('#opp_this_month').append('' + result.record_op + ''); + $('#exp_rev_this_month').append('' + self.monthly_goals[2] + ' ' + result.record_rev_exp + ''); + $('#rev_this_month').append('' + self.monthly_goals[2] + ' ' + result.record_rev + ''); + $('#ratio_this_month').append('' + result.record_ratio + ''); + $('#avg_time_this_month').append('' + result.avg_time + ' sec' + ''); + $('#total_revenue_this_month').append('' + result.opportunity_ratio_value + ''); + $('#target').append('' + result.target +''); + $('#ytd_target').append('' + result.ytd_target +''); + $('#difference').append('' + result.difference +''); + $('#won').append('' + result.won +''); + }) + }); + }, + + //lead + my_lead: function(e) { + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options = { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }; + this.do_action({ + name: _t("My Leads"), + type: 'ir.actions.act_window', + res_model: 'crm.lead', + view_mode: 'tree,form,calendar', + views: [[false, 'list'],[false, 'form']], + domain: [['user_id', '=', session.uid]], + target: 'current', + }, options) + }, + + //opportunity + opportunity: function(e) { + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options = { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }; + this.do_action({ + name: _t("Opportunity"), + type: 'ir.actions.act_window', + res_model: 'crm.lead', + view_mode: 'tree,form,calendar', + views: [[false, 'list'],[false, 'form']], + domain: [['user_id', '=', session.uid], ['type','=', 'opportunity']], + target: 'current', + }, options) + }, + + //expected_revenue + exp_revenue: function(e) { + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options = { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }; + this.do_action({ + name: _t("Expected Revenue"), + type: 'ir.actions.act_window', + res_model: 'crm.lead', + view_mode: 'tree,form,calendar', + views: [[false, 'list'],[false, 'form']], + domain: [['user_id','=', session.uid], ['type','=', 'opportunity'], ['active','=', true]], + target: 'current', + }, options) + }, + + //revenue + revenue_card: function(e) { + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options = { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }; + this.do_action({ + name: _t("Revenue"), + type: 'ir.actions.act_window', + res_model: 'crm.lead', + view_mode: 'tree,form,calendar', + views: [[false, 'list'],[false, 'form']], + domain: [['user_id','=', session.uid], ['type','=', 'opportunity'], ['stage_id','=', 4]], + target: 'current', + }, options) + }, + + //unassigned_leads + unassigned_leads: function(e) { + var self = this; + e.stopPropagation(); + e.preventDefault(); + var options = { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }; + this.do_action({ + name: _t("Unassigned Leads"), + type: 'ir.actions.act_window', + res_model: 'crm.lead', + view_mode: 'tree,form,calendar', + views: [[false, 'list'],[false, 'form']], + domain: [['user_id','=', false],['type', '=', 'lead']], + context: {'group_by': 'team_id'}, + target: 'current', + }, options) + }, + + start: function() { + var self = this; + this.set("title", 'Dashboard'); + return this._super().then(function() { + self.update_cp(); + self.render_dashboards(); + self.render_graphs(); + self.$el.parent().addClass('oe_background_grey'); + }); + }, + + render_graphs: function(){ + var self = this; + self.render_sales_activity_graph(); + self.render_leads_month_graph(); + self.funnel_chart(); + self.render_annual_chart_graph(); + self.render_campaign_leads_graph(); + self.render_medium_leads_graph(); + self.render_source_leads_graph(); + self.onclick_lost_last_12months(); + self.onclick_sub_lost_last_12months(); + self.render_lost_leads_graph(); + self.render_lost_leads_by_stage_graph(); + self.render_revenue_count_pie(); + }, + + funnel_chart: function () { + rpc.query({ + model: "crm.lead", + method: "get_lead_stage_data", + }).then(function (callbacks) { + Highcharts.chart("container", { + chart: { + type: "funnel", + }, + title: false, + credits: { + enabled: false + }, + plotOptions: { + series: { + dataLabels: { + enabled: true, + softConnector: true + }, + center: ['45%', '50%'], + neckWidth: '40%', + neckHeight: '35%', + width: '90%', + height: '80%' + } + }, + series: [ { + name: "Number Of Leads", + data: callbacks, + }], + }); + }); + }, + + render_lost_leads_graph:function(){ + var self = this; + var ctx = self.$(".lost_leads_graph"); + rpc.query({ + model: "crm.lead", + method: "get_lost_lead_by_reason_pie", + }).then(function (arrays) { + var data = { + labels : arrays[1], + datasets: [{ + label: "", + data: arrays[0], + backgroundColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderWidth: 1 + },] + }; + + //options + var options = { + responsive: true, + title: false, + legend: { + display: true, + position: "bottom", + labels: { + fontColor: "#333", + fontSize: 16 + } + }, + scales: { + yAxes: [{ + gridLines: { + color: "rgba(0, 0, 0, 0)", + display: false, + }, + ticks: { + min: 0, + display: false, + } + }] + } + }; + + //create Chart class object + var chart = new Chart(ctx, { + type: "doughnut", + data: data, + options: options + }); + }); + }, + + render_lost_leads_by_stage_graph:function(){ + var self = this + var ctx = self.$(".lost_leads_by_stage_graph"); + rpc.query({ + model: "crm.lead", + method: "get_lost_lead_by_stage_pie", + }).then(function (arrays) { + var data = { + labels : arrays[1], + datasets: [{ + label: "", + data: arrays[0], + backgroundColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderWidth: 1 + },] + }; + + //options + var options = { + responsive: true, + title: false, + legend: { + display: true, + position: "bottom", + labels: { + fontColor: "#333", + fontSize: 16 + } + }, + scales: { + yAxes: [{ + gridLines: { + color: "rgba(0, 0, 0, 0)", + display: false, + }, + ticks: { + min: 0, + display: false, + } + }] + } + }; + + //create Chart class object + var chart = new Chart(ctx, { + type: "doughnut", + data: data, + options: options + }); + }); + }, + + render_sales_activity_graph:function(){ + var self = this + var ctx = self.$(".sales_activity"); + rpc.query({ + model: "crm.lead", + method: "get_the_sales_activity", + }).then(function (arrays) { + var data = { + labels : arrays[1], + datasets: [{ + label: "", + data: arrays[0], + backgroundColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderWidth: 1 + },] + }; + + //options + var options = { + responsive: true, + title: false, + legend: { + display: true, + position: "right", + labels: { + fontColor: "#333", + fontSize: 16 + } + }, + scales: { + yAxes: [{ + gridLines: { + color: "rgba(0, 0, 0, 0)", + display: false, + }, + ticks: { + min: 0, + display: false, + } + }] + } + }; + + //create Chart class object + var chart = new Chart(ctx, { + type: "doughnut", + data: data, + options: options + }); + }); + }, + + render_leads_month_graph:function(){ + var self = this + var ctx = self.$(".lead_month"); + rpc.query({ + model: "crm.lead", + method: "get_lead_month_pie", + }).then(function (arrays) { + var data = { + labels : arrays[1], + datasets: [{ + label: "", + data: arrays[0], + backgroundColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderWidth: 1 + },] + }; + + //options + var options = { + responsive: true, + title: false, + legend: { + display: true, + position: "right", + labels: { + fontColor: "#333", + fontSize: 16 + } + }, + scales: { + yAxes: [{ + gridLines: { + color: "rgba(0, 0, 0, 0)", + display: false, + }, + ticks: { + min: 0, + display: false, + } + }] + } + }; + + //create Chart class object + var chart = new Chart(ctx, { + type: "doughnut", + data: data, + options: options + }); + }); + }, + + render_revenue_count_pie:function(){ + var self = this; + var ctx = self.$(".revenue_count_pie_canvas"); + rpc.query({ + model: "crm.lead", + method: "revenue_count_pie", + }).then(function (arrays) { + var data = { + labels : arrays[1], + datasets: [{ + label: "", + data: arrays[0], + backgroundColor: [ + "#003f5c", + "#ff7c43", + "#f95d6a" + ], + borderColor: [ + "#003f5c", + "#ff7c43", + "#f95d6a" + ], + borderWidth: 1 + },] + }; + + //options + var options = { + responsive: true, + title: false, + legend: { + display: true, + position: "bottom", + labels: { + fontColor: "#333", + fontSize: 16 + } + }, + scales: { + yAxes: [{ + gridLines: { + color: "rgba(0, 0, 0, 0)", + display: false, + }, + ticks: { + min: 0, + display: false, + } + }] + } + }; + + //create Chart class object + var chart = new Chart(ctx, { + type: "doughnut", + data: data, + options: options + }); + }); + }, + + render_annual_chart_graph:function(){ + var self = this + var ctx = self.$(".annual_target"); + rpc.query({ + model: "crm.lead", + method: "get_the_annual_target", + }).then(function (arrays) { + var data = { + labels : arrays[1], + datasets: [{ + label: "", + data: arrays[0], + backgroundColor: [ + "#003f5c", + "#f95d6a", + "#ff7c43", + "#6d5c16" + ], + borderColor: [ + "#003f5c", + "#f95d6a", + "#ff7c43", + "#6d5c16" + ], + borderWidth: 1 + },] + }; + + //options + var options = { + responsive: true, + title: false, + scales: { + yAxes: [{ + ticks: { + min: 0 + } + }] + } + }; + + //create Chart class object + var chart = new Chart(ctx, { + type: "bar", + data: data, + options: { + responsive:true, + maintainAspectRatio: false, + legend: { + display: false //This will do the task + }, + } + }); + }); + }, + + + render_campaign_leads_graph:function(){ + var self = this + var ctx = self.$(".campaign_source"); + rpc.query({ + model: "crm.lead", + method: "get_the_campaign_pie", + }).then(function (arrays) { + var data = { + labels : arrays[1], + datasets: [{ + label: "", + data: arrays[0], + backgroundColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderWidth: 1 + },] + }; + + //options + var options = { + responsive: true, + title: false, + legend: { + display: true, + position: "bottom", + labels: { + fontColor: "#333", + fontSize: 14 + } + }, + scales: { + yAxes: [{ + gridLines: { + color: "rgba(0, 0, 0, 0)", + display: false, + }, + ticks: { + min: 0, + display: false, + } + }] + } + }; + + //create Chart class object + var chart = new Chart(ctx, { + type: "doughnut", + data: data, + options: options + }); + }); + }, + + render_source_leads_graph:function(){ + var self = this + var ctx = self.$(".source_lead"); + rpc.query({ + model: "crm.lead", + method: "get_the_source_pie", + }).then(function (arrays) { + var data = { + labels : arrays[1], + datasets: [{ + label: "", + data: arrays[0], + backgroundColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderWidth: 1 + },] + }; + + //options + var options = { + responsive: true, + title: false, + legend: { + display: true, + position: "right", + labels: { + fontColor: "#333", + fontSize: 14 + } + }, + scales: { + yAxes: [{ + gridLines: { + color: "rgba(0, 0, 0, 0)", + display: false, + }, + ticks: { + min: 0, + display: false, + } + }] + } + }; + + //create Chart class object + var chart = new Chart(ctx, { + type: "doughnut", + data: data, + options: options + }); + }); + }, + + render_medium_leads_graph:function(){ + var self = this + var ctx = self.$(".medium_leads"); + rpc.query({ + model: "crm.lead", + method: "get_the_medium_pie", + }).then(function (arrays) { + var data = { + labels : arrays[1], + datasets: [{ + label: "", + data: arrays[0], + backgroundColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderColor: [ + "#003f5c", + "#2f4b7c", + "#f95d6a", + "#665191", + "#d45087", + "#ff7c43", + "#ffa600", + "#a05195", + "#6d5c16" + ], + borderWidth: 1 + },] + }; + + //options + var options = { + responsive: true, + title: false, + legend: { + display: true, + position: "right", + labels: { + fontColor: "#333", + fontSize: 14 + } + }, + scales: { + yAxes: [{ + gridLines: { + color: "rgba(0, 0, 0, 0)", + display: false, + }, + ticks: { + min: 0, + display: false, + } + }] + } + }; + + //create Chart class object + var chart = new Chart(ctx, { + type: "doughnut", + data: data, + options: options + }); + }); + }, + + onclick_lost_last_12months: function(ev) { + var self = this; + if( self.is_manager == true){ + self.initial_render = true; + rpc.query({ + model: "crm.lead", + method: "get_total_lost_crm", + args: ['12'] + }).then(function(result){ + var ctx = document.getElementById("canvas").getContext('2d'); + // Define the data + var lost_reason = result.month // Add data values to array + var count = result.count; + var myChart = new Chart(ctx, { + type: 'bar', + data: { + labels: lost_reason,//x axis + datasets: [{ + label: 'Count', // Name the series + data: count, // Specify the data values array + backgroundColor: '#66aecf', + borderColor: '#66aecf', + barPercentage: 0.5, + barThickness: 6, + maxBarThickness: 8, + minBarLength: 0, + borderWidth: 1, // Specify bar border width + type: 'bar', // Set this data to a line chart + fill: false + }] + }, + options: { + scales: { + y: { + beginAtZero: true + }, + }, + responsive: true, // Instruct chart js to respond nicely. + maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height + } + }); + }); + }; + }, + + onclick_lost_last_6months: function(ev) { + var self = this; + self.initial_render = true; + rpc.query({ + model: "crm.lead", + method: "get_total_lost_crm", + args: ['6'] + }).then(function(result){ + var ctx = document.getElementById("canvas").getContext('2d'); + // Define the data + var lost_reason = result.month // Add data values to array + var count = result.count; + var myChart = new Chart(ctx, { + type: 'bar', + data: { + labels: lost_reason,//x axis + datasets: [{ + label: 'Count', // Name the series + data: count, // Specify the data values array + backgroundColor: '#66aecf', + borderColor: '#66aecf', + barPercentage: 0.5, + barThickness: 6, + maxBarThickness: 8, + minBarLength: 0, + borderWidth: 1, // Specify bar border width + type: 'bar', // Set this data to a line chart + fill: false + }] + }, + options: { + scales: { + y: { + beginAtZero: true + } + }, + responsive: true, // Instruct chart js to respond nicely. + maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height + } + }); + }); + }, + + onclick_lost_last_month: function(ev) { + var self = this; + self.initial_render = true; + rpc.query({ + model: "crm.lead", + method: "get_total_lost_crm", + args: ['1'] + }).then(function(result){ + var ctx = document.getElementById("canvas").getContext('2d'); + // Define the data + var lost_reason = result.month // Add data values to array + var count = result.count; + var myChart = new Chart(ctx, { + type: 'bar', + data: { + labels: lost_reason,//x axis + datasets: [{ + label: 'Count', // Name the series + data: count, // Specify the data values array + backgroundColor: '#66aecf', + borderColor: '#66aecf', + barPercentage: 0.5, + barThickness: 6, + maxBarThickness: 8, + minBarLength: 0, + borderWidth: 1, // Specify bar border width + type: 'bar', // Set this data to a line chart + fill: false + }] + }, + options: { + scales: { + y: { + beginAtZero: true + } + }, + responsive: true, // Instruct chart js to respond nicely. + maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height + } + }); + }); + }, + + onclick_sub_lost_last_12months: function(ev) { + var self = this; + if( self.is_manager == true){ + self.initial_render = true; + rpc.query({ + model: "crm.lead", + method: "get_total_lost_crm", + args: ['12'] + }).then(function(result){ + var ctx = document.getElementById('canvas_graph').getContext('2d'); + // Define the data + var lost_reason = result.month; // Add data values to array + var count = result.count; + var myChart = new Chart(ctx, { + type: 'bar', + data: { + labels: lost_reason,//x axis + datasets: [{ + label: 'Count', // Name the series + data: count, // Specify the data values array + backgroundColor: '#66aecf', + borderColor: '#66aecf', + barPercentage: 0.5, + barThickness: 6, + maxBarThickness: 8, + minBarLength: 0, + borderWidth: 1, // Specify bar border width + type: 'bar', // Set this data to a line chart + fill: false + }] + }, + options: { + scales: { + y: { + beginAtZero: true + } + }, + responsive: true, // Instruct chart js to respond nicely. + maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height + } + }); + }); + }; + }, + + onclick_sub_lost_last_6months: function(ev) { + var self = this; + self.initial_render = true; + rpc.query({ + model: "crm.lead", + method: "get_total_lost_crm", + args: ['6'] + }).then(function(result){ + var ctx = document.getElementById("canvas_graph").getContext('2d'); + // Define the data + var lost_reason = result.month // Add data values to array + var count = result.count; + var myChart = new Chart(ctx, { + type: 'bar', + data: { + labels: lost_reason,//x axis + datasets: [{ + label: 'Count', // Name the series + data: count, // Specify the data values array + backgroundColor: '#66aecf', + borderColor: '#66aecf', + barPercentage: 0.5, + barThickness: 6, + maxBarThickness: 8, + minBarLength: 0, + borderWidth: 1, // Specify bar border width + type: 'bar', // Set this data to a line chart + fill: false + }] + }, + options: { + scales: { + y: { + beginAtZero: true + } + }, + responsive: true, // Instruct chart js to respond nicely. + maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height + } + }); + }); + }, + + onclick_sub_lost_last_month: function(ev) { + var self = this; + self.initial_render = true; + rpc.query({ + model: "crm.lead", + method: "get_total_lost_crm", + args: ['1'] + }).then(function(result){ + var ctx = document.getElementById("canvas_graph").getContext('2d'); + // Define the data + var lost_reason = result.month // Add data values to array + var count = result.count; + var myChart = new Chart(ctx, { + type: 'bar', + data: { + labels: lost_reason,//x axis + datasets: [{ + label: 'Count', // Name the series + data: count, // Specify the data values array + backgroundColor: '#66aecf', + borderColor: '#66aecf', + barPercentage: 0.5, + barThickness: 6, + maxBarThickness: 8, + minBarLength: 0, + borderWidth: 1, // Specify bar border width + type: 'bar', // Set this data to a line chart + fill: false + }] + }, + options: { + scales: { + y: { + beginAtZero: true + } + }, + responsive: true, // Instruct chart js to respond nicely. + maintainAspectRatio: false, // Add to prevent default behaviour of full-width/height + } + }); + }); + }, + + fetch_data: function() { + var self = this; + + var def0 = self._rpc({ + model: 'crm.lead', + method: 'check_user_group' + }).then(function(result) { + if (result == true){ + self.is_manager = true; + } + else{ + self.is_manager = false; + } + }); + + var def1 = self._rpc({ + model: "crm.lead", + method: "get_upcoming_events", + }) + .then(function (res) { + self.upcoming_events = res['event']; + }); + + var def2 = self._rpc({ + model: "crm.lead", + method: "get_top_deals", + }) + .then(function (res) { + self.top_deals = res['deals']; + }); + + var def3 = self._rpc({ + model: "crm.lead", + method: "get_monthly_goal", + }) + .then(function (res) { + self.monthly_goals = res['goals']; + }); + + var def4 = self._rpc({ + model: "crm.lead", + method: "get_top_sp_revenue", + }) + .then(function (res) { + self.top_sp_revenue = res['top_revenue']; + }); + + var def5 = self._rpc({ + model: "crm.lead", + method: "get_country_revenue", + }) + .then(function (res) { + self.top_country_revenue = res['country_revenue']; + }); + + var def6 = self._rpc({ + model: "crm.lead", + method: "get_country_count", + }) + .then(function (res) { + self.top_country_count = res['country_count']; + }); + + var def7 = self._rpc({ + model: "crm.lead", + method: "get_lost_reason_count", + }) + .then(function (res) { + self.top_reason_count = res['reason_count']; + }); + + var def8 = self._rpc({ + model: "crm.lead", + method: "get_ratio_based_country", + }) + .then(function (res) { + self.top_country_wise_ratio = res['country_wise_ratio']; + }); + + var def9 = self._rpc({ + model: "crm.lead", + method: "get_ratio_based_sp", + }) + .then(function (res) { + self.top_salesperson_wise_ratio = res['salesperson_wise_ratio']; + }); + + var def10 = self._rpc({ + model: "crm.lead", + method: "get_ratio_based_sales_team", + }) + .then(function (res) { + self.top_sales_team_wise_ratio = res['sales_team_wise_ratio']; + }); + + var def11 = self._rpc({ + model: "crm.lead", + method: "get_recent_activities", + }) + .then(function (res) { + self.recent_activities = res['activities']; + }); + + var def12 = self._rpc({ + model: "crm.lead", + method: "get_count_unassigned", + }) + .then(function (res) { + self.get_count_unassigned = res['count_unassigned']; + }); + + var def13 = self._rpc({ + model: "crm.lead", + method: "get_top_sp_by_invoice", + }) + .then(function (res) { + self.top_sp_by_invoice = res['sales_person_invoice']; + }); + + return $.when(def0, def1, def2, def3, def4, def5, def6, def7, def8, def9, def10, def11, def12, def13); + }, + + render_dashboards: function() { + var self = this; + if (this.login_employee){ + var templates = [] + if( self.is_manager == true){ + templates = ['LoginUser', 'Managercrm', 'Admincrm', 'SubDashboard']; + } + else{ + templates = ['LoginUser','Managercrm']; + } + _.each(templates, function(template) { + self.$('.o_hr_dashboard').append(QWeb.render(template, {widget: self})); + }); + } + else{ + self.$('.o_hr_dashboard').append(QWeb.render('EmployeeWarning', {widget: self})); + } + }, + + on_reverse_breadcrumb: function() { + var self = this; + web_client.do_push_state({}); + this.update_cp(); + this.fetch_data().then(function() { + self.$('.o_hr_dashboard').reload(); + self.render_dashboards(); + }); + }, + + update_cp: function() { + var self = this; + }, + }); + + core.action_registry.add('crm_dashboard', DashBoard); + return DashBoard; +}); \ No newline at end of file diff --git a/crm_dashboard/static/src/js/lib/columnHeatmap.js b/crm_dashboard/static/src/js/lib/columnHeatmap.js new file mode 100644 index 000000000..9faf9a4f2 --- /dev/null +++ b/crm_dashboard/static/src/js/lib/columnHeatmap.js @@ -0,0 +1,114 @@ +(function($) { + $.columnHeatmap = { + name: 'columnHeatmap', + version: '1.0', + release: '2020-06-15', + author: 'Paulo Kramer', + site: 'https://www.paulokramer.com', + documentation: 'https://github.com/PauloAK/jQuery-columnHeatMap' + }; + + $.fn.columnHeatmap = function(options) { + var settings = $.extend({ + columns: [], // 0 is the first column + contrast: true, // Change text color to white on stronger background colors + inverse: false, // By default, higher are red and lower are green, if this options is enabled, the logic are inversed + animated: true, // Animated background-color and text color transition + animationSpeed: .1, // Speed of transition animation in seconds + fn_parseValue: null, // Custom function to parse cell value + colorStartPoint: 0 // HSL color start point + }, options); + + try { + if (!this.is('table')) + throw 'Selected element isn\'t a table'; + + if (settings.columns.length == 0) + throw 'You need to specify the columns'; + + if (settings.colorStartPoint < 0 || settings.colorStartPoint > 360) + throw `colorStartPoint need to be beetween 0 and 360, current: ${settings.colorStartPoint}`; + + let $table = this; + let rows = $table.find('tbody tr'); + let data = []; + + $.each(settings.columns, (loop, col) => { + rows.each((key, row) => { + if (key == 0) { + data[col.toString()] = new Array; + data[col.toString()]['values'] = new Array; + data[col.toString()]['tds'] = new Array; + } + + let td = $(row).find('td')[col]; + data[col.toString()]['tds'].push(td); + + + + if (typeof settings.fn_parseValue == "function") { + let value = fn_parseValue($(td).text()); + if (typeof value == "undefined") { + throw 'None value returned in fn_parseValue'; + } else { + data[col.toString()]['values'].push(value); + } + } else { + // Get only numbers from the cell, (with float points) + let numbers = $(td).text().match(/[\d|\-|.|,]+/)[0]; + + data[col.toString()]['values'].push(parseFloat(numbers)); + } + }); + }); + + data = data.filter((value) => { return value; }); + + $.each(data, (key, col) => { + if (!col || !col['values']) + return; + + data[key]['min'] = null; + data[key]['max'] = null; + + data[key]['min'] = col['values'].reduce(function(a, b) { + return Math.min(a, b); + }); + + data[key]['max'] = col['values'].reduce(function(a, b) { + return Math.max(a, b); + }); + }); + + $.each(data, (key, col) => { + $.each(col['values'], (key, value) => { + let colorGenerated = colorGenerator(value, col['min'], col['max']); + + if (settings.animated) { + $(col['tds'][key]).css('transition', `background-color ${settings.animationSpeed}s linear, color ${settings.animationSpeed}s linear`); + } + + $(col['tds'][key]).css('background-color', colorGenerated.color); + + if (colorGenerated.perc > 70 && settings.contrast) { + $(col['tds'][key]).css('color', '#fff'); + } + }); + }); + + function colorGenerator(value, min, max) { + var perc = (100 * (value - min)) / (max - min); + + if (settings.inverse) + perc = 100 - perc; + + var hsl = Math.abs((perc - 100) * -1) + settings.colorStartPoint; + + return { color: 'hsl(' + hsl + ', 70%, 65%)', perc: perc }; + } + } catch (error) { + console.error(`[${$.columnHeatmap.name}::Error] ${error}`); + return; + } + }; +}(jQuery)); \ No newline at end of file diff --git a/crm_dashboard/static/src/js/lib/columnHeatmap.min.js b/crm_dashboard/static/src/js/lib/columnHeatmap.min.js new file mode 100644 index 000000000..129ddbdbf --- /dev/null +++ b/crm_dashboard/static/src/js/lib/columnHeatmap.min.js @@ -0,0 +1 @@ +!function(t){t.columnHeatmap={name:"columnHeatmap",version:"1.0",release:"2020-06-15",author:"Paulo Kramer",site:"https://www.paulokramer.com",documentation:"https://github.com/PauloAK/jQuery-columnHeatMap"},t.fn.columnHeatmap=function(e){var n=t.extend({columns:[],contrast:!0,inverse:!1,animated:!0,animationSpeed:.1,fn_parseValue:null,colorStartPoint:0},e);try{if(!this.is("table"))throw"Selected element isn't a table";if(0==n.columns.length)throw"You need to specify the columns";if(n.colorStartPoint<0||n.colorStartPoint>360)throw`colorStartPoint need to be beetween 0 and 360, current: ${n.colorStartPoint}`;let e=this.find("tbody tr"),a=[];t.each(n.columns,(o,r)=>{e.each((e,o)=>{0==e&&(a[r.toString()]=new Array,a[r.toString()].values=new Array,a[r.toString()].tds=new Array);let l=t(o).find("td")[r];if(a[r.toString()].tds.push(l),"function"==typeof n.fn_parseValue){let e=fn_parseValue(t(l).text());if(void 0===e)throw"None value returned in fn_parseValue";a[r.toString()].values.push(e)}else{let e=t(l).text().match(/[\d|\-|.|,]+/)[0];a[r.toString()].values.push(parseFloat(e))}})}),a=a.filter(t=>t),t.each(a,(t,e)=>{e&&e.values&&(a[t].min=null,a[t].max=null,a[t].min=e.values.reduce(function(t,e){return Math.min(t,e)}),a[t].max=e.values.reduce(function(t,e){return Math.max(t,e)}))}),t.each(a,(e,a)=>{t.each(a.values,(e,o)=>{let r=function(t,e,a){var o=100*(t-e)/(a-e);n.inverse&&(o=100-o);return{color:"hsl("+(Math.abs(-1*(o-100))+n.colorStartPoint)+", 70%, 65%)",perc:o}}(o,a.min,a.max);n.animated&&t(a.tds[e]).css("transition",`background-color ${n.animationSpeed}s linear, color ${n.animationSpeed}s linear`),t(a.tds[e]).css("background-color",r.color),r.perc>70&&n.contrast&&t(a.tds[e]).css("color","#fff")})})}catch(e){return void console.error(`[${t.columnHeatmap.name}::Error] ${e}`)}}}(jQuery); diff --git a/crm_dashboard/static/src/js/lib/d3.min.js b/crm_dashboard/static/src/js/lib/d3.min.js new file mode 100644 index 000000000..213a10816 --- /dev/null +++ b/crm_dashboard/static/src/js/lib/d3.min.js @@ -0,0 +1,7828 @@ +! function() { + function n(n) { + return n && (n.ownerDocument || n.document).documentElement + } + + function t(n) { + return n && n.ownerDocument ? n.ownerDocument.defaultView : n + } + + function e(n, t) { + return t > n ? -1 : n > t ? 1 : n >= t ? 0 : 0 / 0 + } + + function r(n) { + return null === n ? 0 / 0 : +n + } + + function u(n) { + return !isNaN(n) + } + + function i(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 o(n) { + return n.length + } + + function a(n) { + for (var t = 1; n * t % 1;) t *= 10; + return t + } + + function c(n, t) { + for (var e in t) Object.defineProperty(n.prototype, e, { + value: t[e], + enumerable: !1 + }) + } + + function l() { + this._ = Object.create(null) + } + + function s(n) { + return (n += "") === pa || n[0] === va ? va + n : n + } + + function f(n) { + return (n += "")[0] === va ? n.slice(1) : n + } + + function h(n) { + return s(n) in this._ + } + + function g(n) { + return (n = s(n)) in this._ && delete this._[n] + } + + function p() { + var n = []; + for (var t in this._) n.push(f(t)); + return n + } + + function v() { + var n = 0; + for (var t in this._) ++n; + return n + } + + function d() { + for (var n in this._) return !1; + return !0 + } + + function m() { + this._ = Object.create(null) + } + + function y(n) { + return n + } + + function M(n, t, e) { + return function() { + var r = e.apply(t, arguments); + return r === t ? n : r + } + } + + function x(n, t) { + if (t in n) return t; + t = t.charAt(0).toUpperCase() + t.slice(1); + for (var e = 0, r = da.length; r > e; ++e) { + var u = da[e] + t; + if (u in n) return u + } + } + + function b() {} + + function _() {} + + function w(n) { + function t() { + for (var t, r = e, u = -1, i = r.length; ++u < i;)(t = r[u].on) && t.apply(this, arguments); + return n + } + var e = [], + r = new l; + return t.on = function(t, u) { + var i, o = r.get(t); + return arguments.length < 2 ? o && o.on : (o && (o.on = null, e = e.slice(0, i = e.indexOf(o)).concat(e.slice(i + 1)), r.remove(t)), u && e.push(r.set(t, { + on: u + })), n) + }, t + } + + function S() { + ta.event.preventDefault() + } + + function k() { + for (var n, t = ta.event; n = t.sourceEvent;) t = n; + return t + } + + function E(n) { + for (var t = new _, e = 0, r = arguments.length; ++e < r;) t[arguments[e]] = w(t); + return t.of = function(e, r) { + return function(u) { + try { + var i = u.sourceEvent = ta.event; + u.target = n, ta.event = u, t[u.type].apply(e, r) + } finally { + ta.event = i + } + } + }, t + } + + function A(n) { + return ya(n, _a), n + } + + function N(n) { + return "function" == typeof n ? n : function() { + return Ma(n, this) + } + } + + function C(n) { + return "function" == typeof n ? n : function() { + return xa(n, this) + } + } + + function z(n, t) { + function e() { + this.removeAttribute(n) + } + + function r() { + this.removeAttributeNS(n.space, n.local) + } + + function u() { + this.setAttribute(n, t) + } + + function i() { + this.setAttributeNS(n.space, n.local, t) + } + + function o() { + var e = t.apply(this, arguments); + null == e ? this.removeAttribute(n) : this.setAttribute(n, e) + } + + function a() { + var e = t.apply(this, arguments); + null == e ? this.removeAttributeNS(n.space, n.local) : this.setAttributeNS(n.space, n.local, e) + } + return n = ta.ns.qualify(n), null == t ? n.local ? r : e : "function" == typeof t ? n.local ? a : o : n.local ? i : u + } + + function q(n) { + return n.trim().replace(/\s+/g, " ") + } + + function L(n) { + return new RegExp("(?:^|\\s+)" + ta.requote(n) + "(?:\\s+|$)", "g") + } + + function T(n) { + return (n + "").trim().split(/^|\s+/) + } + + function R(n, t) { + function e() { + for (var e = -1; ++e < u;) n[e](this, t) + } + + function r() { + for (var e = -1, r = t.apply(this, arguments); ++e < u;) n[e](this, r) + } + n = T(n).map(D); + var u = n.length; + return "function" == typeof t ? r : e + } + + function D(n) { + var t = L(n); + return function(e, r) { + if (u = e.classList) return r ? u.add(n) : u.remove(n); + var u = e.getAttribute("class") || ""; + r ? (t.lastIndex = 0, t.test(u) || e.setAttribute("class", q(u + " " + n))) : e.setAttribute("class", q(u.replace(t, " "))) + } + } + + function P(n, t, e) { + function r() { + this.style.removeProperty(n) + } + + function u() { + this.style.setProperty(n, t, e) + } + + function i() { + var r = t.apply(this, arguments); + null == r ? this.style.removeProperty(n) : this.style.setProperty(n, r, e) + } + return null == t ? r : "function" == typeof t ? i : u + } + + function U(n, t) { + function e() { + delete this[n] + } + + function r() { + this[n] = t + } + + function u() { + var e = t.apply(this, arguments); + null == e ? delete this[n] : this[n] = e + } + return null == t ? e : "function" == typeof t ? u : r + } + + function j(n) { + function t() { + var t = this.ownerDocument, + e = this.namespaceURI; + return e ? t.createElementNS(e, n) : t.createElement(n) + } + + function e() { + return this.ownerDocument.createElementNS(n.space, n.local) + } + return "function" == typeof n ? n : (n = ta.ns.qualify(n)).local ? e : t + } + + function F() { + var n = this.parentNode; + n && n.removeChild(this) + } + + function H(n) { + return { + __data__: n + } + } + + function O(n) { + return function() { + return ba(this, n) + } + } + + function I(n) { + return arguments.length || (n = e), + function(t, e) { + return t && e ? n(t.__data__, e.__data__) : !t - !e + } + } + + function Y(n, t) { + for (var e = 0, r = n.length; r > e; 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 Z(n) { + return ya(n, Sa), n + } + + function V(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]) && ++t < c;); + return o + } + } + + function X(n, t, e) { + function r() { + var t = this[o]; + t && (this.removeEventListener(n, t, t.$), delete this[o]) + } + + function u() { + var u = c(t, ra(arguments)); + r.call(this), this.addEventListener(n, this[o] = u, u.$ = e), u._ = t + } + + function i() { + var t, e = new RegExp("^__on([^.]+)" + ta.requote(n) + "$"); + for (var r in this) + if (t = r.match(e)) { + var u = this[r]; + this.removeEventListener(t[1], u, u.$), delete this[r] + } + } + var o = "__on" + n, + a = n.indexOf("."), + c = $; + a > 0 && (n = n.slice(0, a)); + var l = ka.get(n); + return l && (n = l, c = B), a ? t ? u : r : t ? b : i + } + + function $(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 B(n, t) { + var e = $(n, t); + return function(n) { + var t = this, + r = n.relatedTarget; + r && (r === t || 8 & r.compareDocumentPosition(t)) || e.call(t, n) + } + } + + function W(e) { + var r = ".dragsuppress-" + ++Aa, + u = "click" + r, + i = ta.select(t(e)).on("touchmove" + r, S).on("dragstart" + r, S).on("selectstart" + r, S); + if (null == Ea && (Ea = "onselectstart" in e ? !1 : x(e.style, "userSelect")), Ea) { + var o = n(e).style, + a = o[Ea]; + o[Ea] = "none" + } + return function(n) { + if (i.on(r, null), Ea && (o[Ea] = a), n) { + var t = function() { + i.on(u, null) + }; + i.on(u, function() { + S(), t() + }, !0), setTimeout(t, 0) + } + } + } + + function J(n, e) { + e.changedTouches && (e = e.changedTouches[0]); + var r = n.ownerSVGElement || n; + if (r.createSVGPoint) { + var u = r.createSVGPoint(); + if (0 > Na) { + var i = t(n); + if (i.scrollX || i.scrollY) { + r = ta.select("body").append("svg").style({ + position: "absolute", + top: 0, + left: 0, + margin: 0, + padding: 0, + border: "none" + }, "important"); + var o = r[0][0].getScreenCTM(); + Na = !(o.f || o.e), r.remove() + } + } + return Na ? (u.x = e.pageX, u.y = e.pageY) : (u.x = e.clientX, u.y = e.clientY), u = u.matrixTransform(n.getScreenCTM().inverse()), [u.x, u.y] + } + var a = n.getBoundingClientRect(); + return [e.clientX - a.left - n.clientLeft, e.clientY - a.top - n.clientTop] + } + + function G() { + return ta.event.changedTouches[0].identifier + } + + function K(n) { + return n > 0 ? 1 : 0 > n ? -1 : 0 + } + + function Q(n, t, e) { + return (t[0] - n[0]) * (e[1] - n[1]) - (t[1] - n[1]) * (e[0] - n[0]) + } + + function nt(n) { + return n > 1 ? 0 : -1 > n ? qa : Math.acos(n) + } + + function tt(n) { + return n > 1 ? Ra : -1 > n ? -Ra : Math.asin(n) + } + + function et(n) { + return ((n = Math.exp(n)) - 1 / n) / 2 + } + + function rt(n) { + return ((n = Math.exp(n)) + 1 / n) / 2 + } + + function ut(n) { + return ((n = Math.exp(2 * n)) - 1) / (n + 1) + } + + function it(n) { + return (n = Math.sin(n / 2)) * n + } + + function ot() {} + + function at(n, t, e) { + return this instanceof at ? (this.h = +n, this.s = +t, void(this.l = +e)) : arguments.length < 2 ? n instanceof at ? new at(n.h, n.s, n.l) : bt("" + n, _t, at) : new at(n, t, e) + } + + function ct(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 mt(u(n + 120), u(n), u(n - 120)) + } + + function lt(n, t, e) { + return this instanceof lt ? (this.h = +n, this.c = +t, void(this.l = +e)) : arguments.length < 2 ? n instanceof lt ? new lt(n.h, n.c, n.l) : n instanceof ft ? gt(n.l, n.a, n.b) : gt((n = wt((n = ta.rgb(n)).r, n.g, n.b)).l, n.a, n.b) : new lt(n, t, e) + } + + function st(n, t, e) { + return isNaN(n) && (n = 0), isNaN(t) && (t = 0), new ft(e, Math.cos(n *= Da) * t, Math.sin(n) * t) + } + + function ft(n, t, e) { + return this instanceof ft ? (this.l = +n, this.a = +t, void(this.b = +e)) : arguments.length < 2 ? n instanceof ft ? new ft(n.l, n.a, n.b) : n instanceof lt ? st(n.h, n.c, n.l) : wt((n = mt(n)).r, n.g, n.b) : new ft(n, t, e) + } + + function ht(n, t, e) { + var r = (n + 16) / 116, + u = r + t / 500, + i = r - e / 200; + return u = pt(u) * Xa, r = pt(r) * $a, i = pt(i) * Ba, new mt(dt(3.2404542 * u - 1.5371385 * r - .4985314 * i), dt(-.969266 * u + 1.8760108 * r + .041556 * i), dt(.0556434 * u - .2040259 * r + 1.0572252 * i)) + } + + function gt(n, t, e) { + return n > 0 ? new lt(Math.atan2(e, t) * Pa, Math.sqrt(t * t + e * e), n) : new lt(0 / 0, 0 / 0, n) + } + + function pt(n) { + return n > .206893034 ? n * n * n : (n - 4 / 29) / 7.787037 + } + + function vt(n) { + return n > .008856 ? Math.pow(n, 1 / 3) : 7.787037 * n + 4 / 29 + } + + function dt(n) { + return Math.round(255 * (.00304 >= n ? 12.92 * n : 1.055 * Math.pow(n, 1 / 2.4) - .055)) + } + + function mt(n, t, e) { + return this instanceof mt ? (this.r = ~~n, this.g = ~~t, void(this.b = ~~e)) : arguments.length < 2 ? n instanceof mt ? new mt(n.r, n.g, n.b) : bt("" + n, mt, ct) : new mt(n, t, e) + } + + function yt(n) { + return new mt(n >> 16, n >> 8 & 255, 255 & n) + } + + function Mt(n) { + return yt(n) + "" + } + + function xt(n) { + return 16 > n ? "0" + Math.max(0, n).toString(16) : Math.min(255, n).toString(16) + } + + function bt(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(kt(u[0]), kt(u[1]), kt(u[2])) + } + return (i = Ga.get(n.toLowerCase())) ? 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 _t(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 at(r, u, c) + } + + function wt(n, t, e) { + n = St(n), t = St(t), e = St(e); + var r = vt((.4124564 * n + .3575761 * t + .1804375 * e) / Xa), + u = vt((.2126729 * n + .7151522 * t + .072175 * e) / $a), + i = vt((.0193339 * n + .119192 * t + .9503041 * e) / Ba); + return ft(116 * u - 16, 500 * (r - u), 200 * (u - i)) + } + + function St(n) { + return (n /= 255) <= .04045 ? n / 12.92 : Math.pow((n + .055) / 1.055, 2.4) + } + + function kt(n) { + var t = parseFloat(n); + return "%" === n.charAt(n.length - 1) ? Math.round(2.55 * t) : t + } + + function Et(n) { + return "function" == typeof n ? n : function() { + 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 void o.error.call(i, r) + } + 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 !this.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(tc), tc = setTimeout(qt, t)), nc = 0) : (nc = 1, rc(qt)) + } + + function Lt() { + var n = Date.now(); + for (ec = Ka; ec;) n >= ec.t && (ec.f = ec.c(n - ec.t)), ec = ec.n; + return n + } + + function Tt() { + for (var n, t = Ka, e = 1 / 0; t;) t.f ? t = n ? n.n = t.n : Ka = t.n : (t.t < e && (e = t.t), t = (n = t).n); + return Qa = n, e + } + + function Rt(n, t) { + return t - (n ? Math.ceil(Math.log(n) / Math.LN10) : 1) + } + + function Dt(n, t) { + var e = Math.pow(10, 3 * ga(8 - t)); + return { + scale: t > 8 ? 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) + } : y; + return function(n) { + var e = ic.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 = oc.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 cc(e - 1)), 1), e + } + + function i(n, e) { + return t(n = new cc(+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 { + cc = jt; + var r = new jt; + return r._ = n, o(r, t, e) + } finally { + cc = 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 { + cc = jt; + var r = new jt; + return r._ = t, n(r, e)._ + } finally { + cc = Date + } + } + } + + function Ot(n) { + function t(n) { + function t(t) { + for (var e, u, i, o = [], a = -1, c = 0; ++a < r;) 37 === n.charCodeAt(a) && (o.push(n.slice(c, a)), null != (u = sc[e = n.charAt(++a)]) && (e = n.charAt(++a)), (i = N[e]) && (e = i(t, null == u ? "e" === e ? " " : "0" : u)), o.push(e), c = a + 1); + return o.push(n.slice(c, a)), o.join("") + } + var r = n.length; + return t.parse = function(t) { + var r = { + y: 1900, + m: 0, + d: 1, + H: 0, + M: 0, + S: 0, + L: 0, + Z: null + }, + u = e(r, n, t, 0); + if (u != t.length) return null; + "p" in r && (r.H = r.H % 12 + 12 * r.p); + var i = null != r.Z && cc !== jt, + o = new(i ? jt : cc); + return "j" in r ? o.setFullYear(r.y, 0, r.j) : "w" in r && ("W" in r || "U" in r) ? (o.setFullYear(r.y, 0, 1), o.setFullYear(r.y, 0, "W" in r ? (r.w + 6) % 7 + 7 * r.W - (o.getDay() + 5) % 7 : r.w + 7 * r.U - (o.getDay() + 6) % 7)) : o.setFullYear(r.y, r.m, r.d), o.setHours(r.H + (r.Z / 100 | 0), r.M + r.Z % 100, r.S, r.L), i ? o._ : o + }, t.toString = function() { + return n + }, t + } + + function e(n, t, e, r) { + for (var u, i, o, a = 0, c = t.length, l = e.length; c > a;) { + if (r >= l) return -1; + if (u = t.charCodeAt(a++), 37 === u) { + if (o = t.charAt(a++), i = C[o in sc ? 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 { + cc = jt; + var t = new cc; + return t._ = n, r(t) + } finally { + cc = Date + } + } + var r = t(n); + return e.parse = function(n) { + try { + cc = jt; + var t = r.parse(n); + return t && t._ + } finally { + cc = Date + } + }, e.toString = r.toString, e + }, t.multi = t.utc.multi = ae; + var M = ta.map(), + x = Yt(v), + b = Zt(v), + _ = Yt(d), + w = Zt(d), + S = Yt(m), + k = Zt(m), + E = Yt(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 It(n.getDate(), t, 2) + }, + e: function(n, t) { + return It(n.getDate(), t, 2) + }, + H: function(n, t) { + return It(n.getHours(), t, 2) + }, + I: function(n, t) { + return It(n.getHours() % 12 || 12, t, 2) + }, + j: function(n, t) { + return It(1 + ac.dayOfYear(n), t, 3) + }, + L: function(n, t) { + return It(n.getMilliseconds(), t, 3) + }, + m: function(n, t) { + return It(n.getMonth() + 1, t, 2) + }, + M: function(n, t) { + return It(n.getMinutes(), t, 2) + }, + p: function(n) { + return p[+(n.getHours() >= 12)] + }, + S: function(n, t) { + return It(n.getSeconds(), t, 2) + }, + U: function(n, t) { + return It(ac.sundayOfYear(n), t, 2) + }, + w: function(n) { + return n.getDay() + }, + W: function(n, t) { + return It(ac.mondayOfYear(n), t, 2) + }, + x: t(h), + X: t(g), + y: function(n, t) { + return It(n.getFullYear() % 100, t, 2) + }, + Y: function(n, t) { + return It(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 It(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 Yt(n) { + return new RegExp("^(?:" + n.map(ta.requote).join("|") + ")", "i") + } + + function Zt(n) { + for (var t = new l, e = -1, r = n.length; ++e < r;) t.set(n[e].toLowerCase(), e); + return t + } + + function Vt(n, t, e) { + fc.lastIndex = 0; + var r = fc.exec(t.slice(e, e + 1)); + return r ? (n.w = +r[0], e + r[0].length) : -1 + } + + function Xt(n, t, e) { + fc.lastIndex = 0; + var r = fc.exec(t.slice(e)); + return r ? (n.U = +r[0], e + r[0].length) : -1 + } + + function $t(n, t, e) { + fc.lastIndex = 0; + var r = fc.exec(t.slice(e)); + return r ? (n.W = +r[0], e + r[0].length) : -1 + } + + function Bt(n, t, e) { + fc.lastIndex = 0; + var r = fc.exec(t.slice(e, e + 4)); + return r ? (n.y = +r[0], e + r[0].length) : -1 + } + + function Wt(n, t, e) { + fc.lastIndex = 0; + var r = fc.exec(t.slice(e, e + 2)); + return r ? (n.y = Gt(+r[0]), e + r[0].length) : -1 + } + + function Jt(n, t, e) { + return /^[+-]\d{4}$/.test(t = t.slice(e, e + 5)) ? (n.Z = -t, e + 5) : -1 + } + + function Gt(n) { + return n + (n > 68 ? 1900 : 2e3) + } + + function Kt(n, t, e) { + fc.lastIndex = 0; + var r = fc.exec(t.slice(e, e + 2)); + return r ? (n.m = r[0] - 1, e + r[0].length) : -1 + } + + function Qt(n, t, e) { + fc.lastIndex = 0; + var r = fc.exec(t.slice(e, e + 2)); + return r ? (n.d = +r[0], e + r[0].length) : -1 + } + + function ne(n, t, e) { + fc.lastIndex = 0; + var r = fc.exec(t.slice(e, e + 3)); + return r ? (n.j = +r[0], e + r[0].length) : -1 + } + + function te(n, t, e) { + fc.lastIndex = 0; + var r = fc.exec(t.slice(e, e + 2)); + return r ? (n.H = +r[0], e + r[0].length) : -1 + } + + function ee(n, t, e) { + fc.lastIndex = 0; + var r = fc.exec(t.slice(e, e + 2)); + return r ? (n.M = +r[0], e + r[0].length) : -1 + } + + function re(n, t, e) { + fc.lastIndex = 0; + var r = fc.exec(t.slice(e, e + 2)); + return r ? (n.S = +r[0], e + r[0].length) : -1 + } + + function ue(n, t, e) { + fc.lastIndex = 0; + var r = fc.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 = ga(t) / 60 | 0, + u = ga(t) % 60; + return e + It(r, "0", 2) + It(u, "0", 2) + } + + function oe(n, t, e) { + hc.lastIndex = 0; + var r = hc.exec(t.slice(e, e + 1)); + return r ? e + r[0].length : -1 + } + + function ae(n) { + for (var t = n.length, e = -1; ++e < t;) n[e][0] = this(n[e][0]); + return function(t) { + for (var e = 0, r = n[e]; !r[1](t);) r = n[++e]; + return r[0](t) + } + } + + function ce() {} + + function le(n, t, e) { + var r = e.s = n + t, + u = r - n, + i = r - u; + e.t = n - i + (t - u) + } + + function se(n, t) { + n && dc.hasOwnProperty(n.type) && dc[n.type](n, t) + } + + function fe(n, t, e) { + var r, u = -1, + i = n.length - e; + for (t.lineStart(); ++u < i;) r = n[u], t.point(r[0], r[1], r[2]); + t.lineEnd() + } + + function he(n, t) { + var e = -1, + r = n.length; + for (t.polygonStart(); ++e < r;) fe(n[e], t, 1); + t.polygonEnd() + } + + function ge() { + function n(n, t) { + n *= Da, t = t * Da / 2 + qa / 4; + var e = n - r, + o = 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); + yc.add(Math.atan2(h, f)), r = n, u = c, i = l + } + var t, e, r, u, i; + Mc.point = function(o, a) { + Mc.point = n, r = (t = o) * Da, u = Math.cos(a = (e = a) * Da / 2 + qa / 4), i = Math.sin(a) + }, Mc.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]), tt(n[2])] + } + + function be(n, t) { + return ga(n[0] - t[0]) < Ca && ga(n[1] - t[1]) < Ca + } + + function _e(n, t) { + n *= Da; + var e = Math.cos(t *= Da); + we(e * Math.cos(n), e * Math.sin(n), Math.sin(t)) + } + + function we(n, t, e) { + ++xc, _c += (n - _c) / xc, wc += (t - wc) / xc, Sc += (e - Sc) / xc + } + + function Se() { + function n(n, u) { + n *= Da; + var i = Math.cos(u *= Da), + o = i * Math.cos(n), + a = i * Math.sin(n), + c = Math.sin(u), + l = Math.atan2(Math.sqrt((l = e * c - r * a) * l + (l = r * o - t * c) * l + (l = t * a - e * o) * l), t * o + e * a + r * c); + bc += l, kc += l * (t + (t = o)), Ec += l * (e + (e = a)), Ac += l * (r + (r = c)), we(t, e, r) + } + var t, e, r; + qc.point = function(u, i) { + u *= Da; + var o = Math.cos(i *= Da); + t = o * Math.cos(u), e = o * Math.sin(u), r = Math.sin(i), qc.point = n, we(t, e, r) + } + } + + function ke() { + qc.point = _e + } + + function Ee() { + function n(n, t) { + n *= Da; + var e = Math.cos(t *= Da), + o = e * Math.cos(n), + a = e * Math.sin(n), + c = Math.sin(t), + l = u * c - i * a, + s = i * o - r * c, + f = r * a - u * o, + h = Math.sqrt(l * l + s * s + f * f), + g = r * o + u * a + i * c, + p = h && -nt(g) / h, + v = Math.atan2(h, g); + Nc += p * l, Cc += p * s, zc += p * f, bc += v, kc += v * (r + (r = o)), Ec += v * (u + (u = a)), Ac += v * (i + (i = c)), we(r, u, i) + } + var t, e, r, u, i; + qc.point = function(o, a) { + t = o, e = a, qc.point = n, o *= Da; + var c = Math.cos(a *= Da); + r = c * Math.cos(o), u = c * Math.sin(o), i = Math.sin(a), we(r, u, i) + }, qc.lineEnd = function() { + n(t, e), qc.lineEnd = ke, qc.point = _e + } + } + + function Ae(n, t) { + function e(e, r) { + return e = n(e, r), t(e[0], e[1]) + } + return n.invert && t.invert && (e.invert = function(e, r) { + return e = t.invert(e, r), e && n.invert(e[0], e[1]) + }), e + } + + function Ne() { + return !0 + } + + function Ce(n, t, e, r, u) { + var i = [], + o = []; + if (n.forEach(function(n) { + if (!((t = n.length - 1) <= 0)) { + var t, e = n[0], + r = n[t]; + if (be(e, r)) { + u.lineStart(); + for (var a = 0; t > a; ++a) u.point((e = n[a])[0], e[1]); + return void u.lineEnd() + } + 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]; ++r < t;) u.n = e = n[r], e.p = u, u = e; + u.n = e = n[0], e.p = u + } + } + + function qe(n, t, e, r) { + this.x = n, this.z = t, this.o = e, this.e = r, this.v = !1, this.n = this.p = null + } + + function Le(n, t, e, r) { + return function(u, i) { + function o(t, e) { + var r = u(t, e); + n(t = r[0], e = r[1]) && i.point(t, e) + } + + function a(n, t) { + var e = u(n, t); + d.point(e[0], e[1]) + } + + function c() { + y.point = a, d.lineStart() + } + + function l() { + y.point = o, d.lineEnd() + } + + function s(n, t) { + v.push([n, t]); + var e = u(n, t); + x.point(e[0], e[1]) + } + + function f() { + x.lineStart(), v = [] + } + + function h() { + s(v[0][0], v[0][1]), x.lineEnd(); + var n, t = x.clean(), + e = M.buffer(), + r = e.length; + if (v.pop(), p.push(v), v = null, r) + if (1 & t) { + n = e[0]; + var u, r = n.length - 1, + o = -1; + if (r > 0) { + for (b || (i.polygonStart(), b = !0), i.lineStart(); ++o < r;) i.point((u = n[o])[0], u[1]); + i.lineEnd() + } + } else r > 1 && 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: b, + 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] - Ra - Ca : Ra - n[1]) - ((t = t.x)[0] < 0 ? t[1] - Ra - Ca : Ra - 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 ? qa : -qa, + c = ga(i - e); + ga(c - qa) < Ca ? (n.point(e, r = (r + o) / 2 > 0 ? Ra : -Ra), n.point(u, r), n.lineEnd(), n.lineStart(), n.point(a, r), n.point(i, r), t = 0) : u !== a && c >= qa && (ga(e - u) < Ca && (e -= u * Ca), ga(i - a) < Ca && (i -= a * Ca), r = Ue(e, r, i, o), n.point(u, r), n.lineEnd(), n.lineStart(), n.point(a, r), t = 0), n.point(e = i, r = o), u = a + }, + lineEnd: function() { + n.lineEnd(), e = r = 0 / 0 + }, + clean: function() { + return 2 - t + } + } + } + + function Ue(n, t, e, r) { + var u, i, o = Math.sin(n - e); + return ga(o) > Ca ? 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 * Ra, r.point(-qa, u), r.point(0, u), r.point(qa, u), r.point(qa, 0), r.point(qa, -u), r.point(0, -u), r.point(-qa, -u), r.point(-qa, 0), r.point(-qa, u); + else if (ga(n[0] - t[0]) > Ca) { + var i = n[0] < t[0] ? qa : -qa; + u = e * i / 2, r.point(-i, u), r.point(0, u), r.point(i, u) + } else r.point(t[0], t[1]) + } + + function Fe(n, t) { + var e = n[0], + r = n[1], + u = [Math.sin(e), -Math.cos(e), 0], + i = 0, + o = 0; + yc.reset(); + for (var a = 0, c = t.length; c > a; ++a) { + var l = t[a], + s = l.length; + if (s) + for (var f = l[0], h = f[0], g = f[1] / 2 + qa / 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 + qa / 4, + M = Math.sin(y), + x = Math.cos(y), + b = m - h, + _ = b >= 0 ? 1 : -1, + w = _ * b, + S = w > qa, + k = p * M; + if (yc.add(Math.atan2(k * _ * Math.sin(w), v * x + k * Math.cos(w))), i += S ? b + _ * La : 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) * tt(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 (-Ca > i || Ca > i && 0 > yc) ^ 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 ? qa : -qa), h) : 0; + if (!e && (l = c = v) && n.lineStart(), v !== c && (g = r(e, p), (be(e, g) || be(p, g)) && (p[0] += Ca, p[1] += Ca, 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 = ga(A - qa) < Ca, + C = N || Ca > A; + if (!N && k > E && (_ = k, k = E, E = _), C ? N ? k + E > 0 ^ b[1] < (ga(b[0] - w) < Ca ? k : E) : k <= b[1] && b[1] <= E : A > qa ^ (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 : qa - 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 = ga(i) > Ca, + c = gr(n, 6 * Da); + return Le(t, e, c, o ? [0, -n] : [-qa, n - qa]) + } + + 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 Ie(n, t, e, r) { + function u(r, u) { + return ga(r[0] - n) < Ca ? u > 0 ? 0 : 3 : ga(r[0] - e) < Ca ? u > 0 ? 2 : 1 : ga(r[1] - t) < Ca ? u > 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 && Q(l, i, n) > 0 && ++t : i[1] <= r && Q(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(-Tc, Math.min(Tc, n)), t = Math.max(-Tc, Math.min(Tc, 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 Ye(n) { + var t = 0, + e = qa / 3, + r = ir(n), + u = r(t, e); + return u.parallels = function(n) { + return arguments.length ? r(t = n[0] * qa / 180, e = n[1] * qa / 180) : [t / qa * 180, e / qa * 180] + }, 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, tt((i - (n * n + e * e) * u * u) / (2 * u))] + }, e + } + + function Ve() { + function n(n, t) { + Dc += u * n - r * t, r = n, u = t + } + var t, e, r, u; + Hc.point = function(i, o) { + Hc.point = n, t = r = i, e = u = o + }, Hc.lineEnd = function() { + n(t, e) + } + } + + function Xe(n, t) { + Pc > n && (Pc = n), n > jc && (jc = n), Uc > t && (Uc = t), t > Fc && (Fc = 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) { + _c += n, wc += t, ++Sc + } + + function Je() { + function n(n, r) { + var u = n - t, + i = r - e, + o = Math.sqrt(u * u + i * i); + kc += o * (t + n) / 2, Ec += o * (e + r) / 2, Ac += o, We(t = n, e = r) + } + var t, e; + Ic.point = function(r, u) { + Ic.point = n, We(t = r, e = u) + } + } + + function Ge() { + Ic.point = We + } + + function Ke() { + function n(n, t) { + var e = n - r, + i = t - u, + o = Math.sqrt(e * e + i * i); + kc += o * (r + n) / 2, Ec += o * (u + t) / 2, Ac += o, o = u * n - r * t, Nc += o * (r + n), Cc += o * (u + t), zc += 3 * o, We(r = n, u = t) + } + var t, e, r, u; + Ic.point = function(i, o) { + Ic.point = n, We(t = r = i, e = u = o) + }, Ic.lineEnd = function() { + n(t, e) + } + } + + function Qe(n) { + function t(t, e) { + n.moveTo(t + o, e), n.arc(t, e, o, 0, La) + } + + 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: b + }; + 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 = ga(ga(w) - 1) < Ca || ga(r - h) < Ca ? (r + h) / 2 : Math.atan2(_, b), + A = n(E, k), + N = A[0], + C = A[1], + z = N - t, + q = C - e, + L = M * z - y * q; + (L * L / x > i || ga((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 * Da), + 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 * Pa, e * Pa]) + }); + 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] * Da, n[1] * Da), [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] * Pa, n[1] * Pa] + } + + function r() { + a = Ae(o = lr(m, M, x), 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, + M = 0, + x = 0, + b = Lc, + _ = y, + w = null, + S = null; + return t.stream = function(n) { + return s && (s.valid = !1), s = or(b(o, f(_(n)))), s.valid = !0, s + }, t.clipAngle = function(n) { + return arguments.length ? (b = null == n ? (w = n, Lc) : He((w = +n) * Da), u()) : w + }, t.clipExtent = function(n) { + return arguments.length ? (S = n, _ = n ? Ie(n[0][0], n[0][1], n[1][0], n[1][1]) : y, u()) : S + }, 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 * Da, d = n[1] % 360 * Da, r()) : [v * Pa, d * Pa] + }, t.rotate = function(n) { + return arguments.length ? (m = n[0] % 360 * Da, M = n[1] % 360 * Da, x = n.length > 2 ? n[2] % 360 * Da : 0, r()) : [m * Pa, M * Pa, x * Pa] + }, 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 * Da, e * Da) + }) + } + + function ar(n, t) { + return [n, t] + } + + function cr(n, t) { + return [n > qa ? n - La : -qa > n ? n + La : 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 > qa ? t - La : -qa > t ? t + La : 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), tt(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), tt(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 * La)) : (u = n + o * La, 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 = nt(-e[1]); + return ((-e[2] < 0 ? -r : r) + 2 * Math.PI - Ca) % (2 * Math.PI) + } + + function vr(n, t, e) { + var r = ta.range(n, t - Ca, 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 - Ca, 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(it(r - t) + u * o * it(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) * Pa, Math.atan2(o, Math.sqrt(r * r + u * u)) * Pa] + } : function() { + return [n * Pa, t * Pa] + }; + return p.distance = h, p + } + + function xr() { + function n(n, u) { + var i = Math.sin(u *= Da), + o = Math.cos(u), + a = ga((n *= Da) - t), + c = Math.cos(a); + Yc += 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; + Zc.point = function(u, i) { + t = u * Da, e = Math.sin(i *= Da), r = Math.cos(i), Zc.point = n + }, Zc.lineEnd = function() { + Zc.point = Zc.lineEnd = b + } + } + + 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 ? -Ra + Ca > t && (t = -Ra + Ca) : t > Ra - Ca && (t = Ra - Ca); + 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(qa / 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 = K(i) * Math.sqrt(n * n + e * e); + return [Math.atan2(n, e) / i, 2 * Math.atan(Math.pow(o / r, 1 / i)) - Ra] + }, 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 ga(u) < Ca ? ar : (e.invert = function(n, t) { + var e = i - t; + return [Math.atan2(n, e) / u, i - K(u) * Math.sqrt(n * n + e * e)] + }, e) + } + + function Sr(n, t) { + return [n, Math.log(Math.tan(qa / 4 + t / 2))] + } + + function kr(n) { + var t, e = ur(n), + r = e.scale, + u = e.translate, + i = e.clipExtent; + return e.scale = function() { + var n = r.apply(e, arguments); + return n === e ? t ? e.clipExtent(null) : e : n + }, e.translate = function() { + var n = u.apply(e, arguments); + return n === e ? t ? e.clipExtent(null) : e : n + }, e.clipExtent = function(n) { + var o = i.apply(e, arguments); + if (o === e) { + if (t = null == n) { + var a = qa * r(), + c = u(); + i([ + [c[0] - a, c[1] - a], + [c[0] + a, c[1] + a] + ]) + } + } else t && (o = null); + return o + }, e.clipExtent(null) + } + + function Er(n, t) { + return [Math.log(Math.tan(qa / 4 + t / 2)), -n] + } + + function Ar(n) { + return n[0] + } + + function Nr(n) { + return n[1] + } + + function Cr(n) { + for (var t = n.length, e = [0, 1], r = 2, u = 2; t > u; u++) { + for (; r > 1 && Q(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 = el.pop() || new Rr; + return t.site = n, t + } + + function Pr(n) { + Xr(n), Qc.remove(n), el.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 && ga(e - c.circle.x) < Ca && ga(r - c.circle.cy) < Ca;) i = c.P, a.unshift(c), Pr(c), c = i; + a.unshift(c), Xr(c); + for (var l = o; l.circle && ga(e - l.circle.x) < Ca && ga(r - l.circle.cy) < Ca;) o = l.N, a.push(l), Pr(l), l = o; + a.push(l), Xr(l); + var s, f = a.length; + for (s = 1; f > 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 = Qc._; a;) + if (r = Fr(a, o) - i, r > Ca) a = a.L; + else { + if (u = i - Hr(a, o), !(u > Ca)) { + r > -Ca ? (t = a.P, e = a) : u > -Ca ? (t = a, e = a.N) : t = e = a; + break + } + if (!a.R) { + t = a; + break + } + a = a.R + } var c = Dr(n); + if (Qc.insert(t, c), t || e) { + if (t === e) return Xr(t), e = Dr(t.site), Qc.insert(c, e), c.edge = e.edge = Jr(t.site, c.site), Vr(t), void Vr(e); + if (!e) return void(c.edge = Jr(t.site, c.site)); + 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 Ir(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 = Kc, 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, (ga(r - t) > Ca || ga(u - e) > Ca) && (a.splice(o, 0, new Qr(Gr(i.site, s, ga(r - f) < Ca && p - u > Ca ? { + x: f, + y: ga(t - f) < Ca ? e : p + } : ga(u - p) < Ca && h - r > Ca ? { + x: ga(e - p) < Ca ? t : h, + y: p + } : ga(r - h) < Ca && u - g > Ca ? { + x: h, + y: ga(t - h) < Ca ? e : g + } : ga(u - g) < Ca && r - f > Ca ? { + x: ga(e - g) < Ca ? t : f, + y: g + } : null), i.site, null)), ++c) + } + + function Yr(n, t) { + return t.angle - n.angle + } + + function Zr() { + tu(this), this.x = this.y = this.arc = this.site = this.cy = null + } + + function Vr(n) { + var t = n.P, + e = n.N; + if (t && e) { + var r = t.site, + u = n.site, + i = e.site; + if (r !== i) { + var o = u.x, + a = u.y, + c = r.x - o, + l = r.y - a, + s = i.x - o, + f = i.y - a, + h = 2 * (c * f - l * s); + if (!(h >= -za)) { + 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 = rl.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 = tl._; M;) + if (m.y < M.y || m.y === M.y && m.x <= M.x) { + if (!M.L) { + y = M.P; + break + } + M = M.L + } else { + if (!M.R) { + y = M; + break + } + M = M.R + } tl.insert(y, m), y || (nl = m) + } + } + } + } + + function Xr(n) { + var t = n.circle; + t && (t.P || (nl = t.N), tl.remove(t), rl.push(t), tu(t), n.circle = null) + } + + function $r(n) { + for (var t, e = Gc, r = Oe(n[0][0], n[0][1], n[1][0], n[1][1]), u = e.length; u--;) t = e[u], (!Br(t, n) || !r(t) || ga(t.a.x - t.b.x) < Ca && ga(t.a.y - t.b.y) < Ca) && (t.a = t.b = null, e.splice(u, 1)) + } + + function Br(n, t) { + var e = n.b; + if (e) return !0; + var r, u, i = n.a, + o = t[0][0], + a = t[1][0], + c = t[0][1], + l = t[1][1], + s = n.l, + f = n.r, + h = s.x, + g = s.y, + p = f.x, + v = f.y, + d = (h + p) / 2, + m = (g + v) / 2; + if (v === g) { + if (o > d || 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.y < c) return + } else i = { + x: d, + y: l + }; + e = { + x: d, + y: c + } + } + } else if (r = (h - p) / (v - g), u = m - r * d, -1 > r || 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.y < c) return + } else i = { + x: (l - u) / r, + y: l + }; + e = { + x: (c - u) / r, + y: c + } + } + else if (v > g) { + 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.x < o) return + } else i = { + x: a, + y: r * a + u + }; + e = { + x: o, + y: r * o + u + } + } + return n.a = i, n.b = e, !0 + } + + function Wr(n, t) { + this.l = n, this.r = t, this.a = this.b = null + } + + function Jr(n, t, e, r) { + var u = new Wr(n, t); + return Gc.push(u), e && Kr(u, n, t, e), r && Kr(u, t, n, r), Kc[n.i].edges.push(new Qr(u, n, t)), Kc[t.i].edges.push(new Qr(u, t, n)), u + } + + function Gr(n, t, e) { + var r = new Wr(n, null); + return r.a = t, r.b = e, Gc.push(r), r + } + + function Kr(n, t, e, r) { + n.a || n.b ? n.l === e ? n.b = r : n.a = r : (n.a = r, n.l = t, n.r = e) + } + + function Qr(n, t, e) { + var r = n.a, + u = n.b; + this.edge = n, this.site = t, this.angle = e ? Math.atan2(e.y - t.y, e.x - t.x) : n.l === t ? Math.atan2(u.x - r.x, r.y - u.y) : Math.atan2(r.x - u.x, u.y - r.y) + } + + function nu() { + this._ = null + } + + function tu(n) { + n.U = n.C = n.L = n.R = n.P = n.N = null + } + + function eu(n, t) { + var e = t, + r = t.R, + u = e.U; + u ? u.L === e ? u.L = r : u.R = r : n._ = r, r.U = u, e.U = r, e.R = r.L, e.R && (e.R.U = e), r.L = e + } + + function ru(n, t) { + var e = t, + r = t.L, + u = e.U; + u ? u.L === e ? u.L = r : u.R = r : n._ = r, r.U = u, e.U = r, e.L = r.R, e.L && (e.L.U = e), r.R = e + } + + function uu(n) { + for (; n.L;) n = n.L; + return n + } + + function iu(n, t) { + var e, r, u, i = n.sort(ou).pop(); + for (Gc = [], Kc = new Array(n.length), Qc = new nu, tl = new nu;;) + if (u = nl, i && (!u || i.y < u.y || i.y === u.y && i.x < u.x))(i.x !== e || i.y !== r) && (Kc[i.i] = new Or(i), jr(i), e = i.x, r = i.y), i = n.pop(); + else { + if (!u) break; + Ur(u.arc) + } t && ($r(t), Ir(t)); + var o = { + cells: Kc, + edges: Gc + }; + return Qc = tl = Gc = Kc = null, o + } + + function ou(n, t) { + return t.y - n.y || t.x - n.x + } + + function au(n, t, e) { + return (n.x - e.x) * (t.y - n.y) - (n.x - t.x) * (e.y - n.y) + } + + function cu(n) { + return n.x + } + + function lu(n) { + return n.y + } + + function su() { + return { + leaf: !0, + nodes: [], + point: null, + x: null, + y: null + } + } + + function fu(n, t, e, r, u, i) { + if (!n(t, e, r, u, i)) { + var o = .5 * (e + u), + a = .5 * (r + i), + c = t.nodes; + c[0] && fu(n, c[0], e, r, o, a), c[1] && fu(n, c[1], o, r, u, a), c[2] && fu(n, c[2], e, a, o, i), c[3] && fu(n, c[3], o, a, u, i) + } + } + + function hu(n, t, e, r, u, i, o) { + var a, c = 1 / 0; + return function l(n, s, f, h, g) { + if (!(s > i || f > o || r > h || u > g)) { + if (p = n.point) { + var p, v = t - n.x, + d = e - n.y, + 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 "#" + xt(Math.round(e + i * n)) + xt(Math.round(r + o * n)) + xt(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 = il.lastIndex = ol.lastIndex = 0, + o = -1, + a = [], + c = []; + for (n += "", t += ""; + (e = il.exec(n)) && (r = ol.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 = ol.lastIndex; + return i < t.length && (u = t.slice(i), a[o] ? a[o] += u : a[++o] = u), a.length < 2 ? c[0] ? (t = c[0].x, function(n) { + return t(n) + "" + }) : function() { + return t + } : (t = c.length, function(n) { + for (var e, r = 0; t > r; ++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 * Ra) + } + + 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 / La * Math.asin(1 / n) : (n = 1, e = t / 4), + function(r) { + return 1 + n * Math.pow(2, -10 * r) * Math.sin((r - e) * La / 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 st(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 ct(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 ht(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] < e[0] * t[1] && (t[0] *= -1, t[1] *= -1, r *= -1, u *= -1), this.rotate = (r ? Math.atan2(t[1], t[0]) : Math.atan2(-e[0], e[1])) * Pa, this.translate = [n.e, n.f], this.scale = [r, i], this.skew = i ? Math.atan2(u, i) * Pa : 0 + } + + function Uu(n, t) { + return n[0] * t[0] + n[1] * t[1] + } + + function ju(n) { + var t = Math.sqrt(Uu(n, n)); + return t && (n[0] /= t, n[1] /= t), t + } + + function Fu(n, t, e) { + return n[0] += e * t[0], n[1] += e * t[1], n + } + + function Hu(n, t) { + var e, r = [], + u = [], + i = ta.transform(n), + o = ta.transform(t), + a = i.translate, + c = o.translate, + l = i.rotate, + s = o.rotate, + f = i.skew, + h = o.skew, + g = i.scale, + p = o.scale; + return a[0] != c[0] || a[1] != c[1] ? (r.push("translate(", null, ",", null, ")"), u.push({ + i: 1, + x: vu(a[0], c[0]) + }, { + i: 3, + x: vu(a[1], c[1]) + })) : r.push(c[0] || c[1] ? "translate(" + c + ")" : ""), l != s ? (l - s > 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 < e;) r[(t = u[i]).i] = t.x(n); + return r.join("") + } + } + + function Ou(n, t) { + return t = (t -= n = +n) || 1 / t, + function(e) { + return (e - n) / t + } + } + + function Iu(n, t) { + return t = (t -= n = +n) || 1 / t, + function(e) { + return Math.max(0, Math.min(1, (e - n) / t)) + } + } + + function Yu(n) { + for (var t = n.source, e = n.target, r = Vu(t, e), u = [t]; t !== r;) t = t.parent, u.push(t); + for (var i = u.length; e !== r;) u.splice(i, 0, e), e = e.parent; + return u + } + + function Zu(n) { + for (var t = [], e = n.parent; null != e;) t.push(n), n = e, e = e.parent; + return t.push(n), t + } + + function Vu(n, t) { + if (n === t) return n; + for (var e = Zu(n), r = Zu(t), u = e.pop(), i = r.pop(), o = null; u === i;) o = u, u = e.pop(), i = r.pop(); + return o + } + + function Xu(n) { + n.fixed |= 2 + } + + function $u(n) { + n.fixed &= -7 + } + + function Bu(n) { + n.fixed |= 4, n.px = n.x, n.py = n.y + } + + function Wu(n) { + n.fixed &= -5 + } + + function Ju(n, t, e) { + var r = 0, + u = 0; + if (n.charge = 0, !n.leaf) + for (var i, o = n.nodes, a = o.length, c = -1; ++c < a;) i = o[c], null != i && (Ju(i, t, e), n.charge += i.charge, r += i.charge * i.cx, u += i.charge * i.cy); + if (n.point) { + n.leaf || (n.point.x += Math.random() - .5, n.point.y += Math.random() - .5); + var l = t * e[n.point.index]; + n.charge += n.pointCharge = l, r += l * n.point.x, u += l * n.point.y + } + n.cx = r / n.charge, n.cy = u / n.charge + } + + function Gu(n, t) { + return ta.rebind(n, t, "sort", "children", "value"), n.nodes = n, n.links = ri, n + } + + function Ku(n, t) { + for (var e = [n]; null != (n = e.pop());) + if (t(n), (u = n.children) && (r = u.length)) + for (var r, u; --r >= 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; ++o < u;) e.push(i[o]); + for (; null != (n = r.pop());) t(n) + } + + function ni(n) { + return n.children + } + + function ti(n) { + return n.value + } + + function ei(n, t) { + return t.value - n.value + } + + function ri(n) { + return ta.merge(n.map(function(n) { + return (n.children || []).map(function(t) { + return { + source: n, + target: t + } + }) + })) + } + + function ui(n) { + return n.x + } + + function ii(n) { + return n.y + } + + function oi(n, t, e) { + n.y0 = t, n.y = e + } + + function ai(n) { + return ta.range(n.length) + } + + function ci(n) { + for (var t = -1, e = n[0].length, r = []; ++t < e;) r[t] = 0; + return r + } + + function li(n) { + for (var t, e = 1, r = 0, u = n[0][1], i = n.length; i > e; ++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.r < r.r ? mi(r, u = a) : mi(r = c, u), o--) : (di(r, i), u = i, t(i)) + } + var m = (s + f) / 2, + y = (h + g) / 2, + M = 0; + for (o = 0; l > o; 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 < o;) _i(u[i], t, e, r) + } + + function wi(n, t, e) { + var r = n.r + e.r, + u = t.x - n.x, + i = t.y - n.y; + if (r && (u || i)) { + var o = t.r + e.r, + a = u * u + i * i; + o *= o, r *= r; + var c = .5 + (r - o) / (2 * a), + l = Math.sqrt(Math.max(0, 2 * o * (r + a) - (r -= a) * r - o * o)) / (2 * a); + e.x = n.x + c * u + l * i, e.y = n.y + c * i - l * u + } else e.x = n.x + r, e.y = n.y + } + + function Si(n, t) { + return n.parent == t.parent ? 1 : 2 + } + + function ki(n) { + var t = n.children; + return t.length ? t[0] : n.t + } + + function Ei(n) { + var t, e = n.children; + return (t = e.length) ? e[t - 1] : n.t + } + + function Ai(n, t, e) { + var r = e / (t.i - n.i); + t.c -= r, t.s += e, n.c += r, t.z += e, t.m += e + } + + function Ni(n) { + for (var t, e = 0, r = 0, u = n.children, i = 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 + } + } : ml + } + + function Oi(n, t, e, r) { + var u = [], + i = [], + o = 0, + a = Math.min(n.length, t.length) - 1; + for (n[a] < n[0] && (n = n.slice().reverse(), t = t.slice().reverse()); ++o <= a;) u.push(e(n[o - 1], n[o])), i.push(r(t[o - 1], t[o])); + return function(t) { + var e = ta.bisect(n, t, 1, a) - 1; + return i[e](u[e](t)) + } + } + + function Ii(n, t, e, r) { + function u() { + var u = Math.min(n.length, t.length) > 2 ? Oi : ji, + c = r ? Iu : 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 Ii(n, t, e, r) + }, u() + } + + function Yi(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 = ic.exec(e); + if (u.shift(), "s" === u[8]) { + var i = ta.formatPrefix(Math.max(ga(r[0]), ga(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 yl ? Math.abs(e - Bi(Math.max(ga(t[0]), ga(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 : xl); + 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++ < s;) + for (var h = f - 1; h > 0; h--) o.push(i(l) * h); + for (l = 0; o[l] < a; l++); + for (s = o.length; o[s - 1] > c; s--); + o = o.slice(l, s) + } + return o + }, o.tickFormat = function(n, t) { + if (!arguments.length) return Ml; + arguments.length < 2 ? t = Ml : "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) + }, Yi(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) + }, Yi(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 l; + for (var i, o = -1, a = r.length; ++o < a;) u.has(i = r[o]) || u.set(i, n.push(i)); + return e[t.t].apply(e, t.a) + }, e.range = function(n) { + return arguments.length ? (i = n, o = 0, t = { + t: "range", + a: arguments + }, e) : i + }, e.rangePoints = function(u, a) { + arguments.length < 2 && (a = 0); + var c = u[0], + l = u[1], + s = n.length < 2 ? (c = (c + l) / 2, 0) : (l - c) / (n.length - 1 + a); + return i = r(c + s * a / 2, s), o = 0, t = { + t: "rangePoints", + a: arguments + }, e + }, e.rangeRoundPoints = function(u, a) { + arguments.length < 2 && (a = 0); + var c = u[0], + l = u[1], + s = n.length < 2 ? (c = l = Math.round((c + l) / 2), 0) : (l - c) / (n.length - 1 + a) | 0; + return i = r(c + Math.round(s * a / 2 + (l - c - (n.length - 1 + a) * s) / 2), s), o = 0, t = { + t: "rangeRoundPoints", + a: arguments + }, e + }, e.rangeBands = function(u, a, c) { + arguments.length < 2 && (a = 0), arguments.length < 3 && (c = a); + var l = u[1] < u[0], + s = u[l - 0], + f = u[1 - l], + h = (f - s) / (n.length - a + 2 * c); + return i = r(s + h * c, h), l && i.reverse(), o = h * (1 - a), t = { + t: "rangeBands", + a: arguments + }, e + }, e.rangeRoundBands = function(u, a, c) { + arguments.length < 2 && (a = 0), arguments.length < 3 && (c = a); + var l = u[1] < u[0], + s = u[l - 0], + f = u[1 - l], + h = Math.floor((f - s) / (n.length - a + 2 * c)); + return i = r(s + Math.round((f - s - (n.length - a) * h) / 2), h), l && i.reverse(), o = Math.round(h * (1 - a)), t = { + t: "rangeRoundBands", + a: arguments + }, e + }, e.rangeBand = function() { + return o + }, e.rangeExtent = function() { + return Pi(t.a[0]) + }, e.copy = function() { + return Qi(n, t) + }, e.domain(n) + } + + function no(n, t) { + function i() { + var e = 0, + r = t.length; + for (a = []; ++e < r;) a[e - 1] = ta.quantile(n, e / r); + return o + } + + function o(n) { + return isNaN(n = +n) ? void 0 : t[ta.bisect(a, n)] + } + var a; + return o.domain = function(t) { + return arguments.length ? (n = t.map(r).filter(u).sort(e), i()) : n + }, o.range = function(n) { + return arguments.length ? (t = n, i()) : t + }, o.quantiles = function() { + return a + }, o.invertExtent = function(e) { + return e = t.indexOf(e), 0 > e ? [0 / 0, 0 / 0] : [e > 0 ? a[e - 1] : n[0], e < a.length ? a[e] : n[n.length - 1]] + }, o.copy = function() { + return no(n, t) + }, i() + } + + function to(n, t, e) { + function r(t) { + return e[Math.max(0, Math.min(o, Math.floor(i * (t - n))))] + } + + function u() { + return i = e.length / (t - n), o = e.length - 1, r + } + var i, o; + return r.domain = function(e) { + return arguments.length ? (n = +e[0], t = +e[e.length - 1], u()) : [n, t] + }, r.range = function(n) { + return arguments.length ? (e = n, u()) : e + }, r.invertExtent = function(t) { + return t = e.indexOf(t), t = 0 > t ? 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 = Et(e), p = Et(r); ++f < h;) u.call(this, c = t[f], f) ? s.push([+g.call(this, c, f), +p.call(this, c, f)]) : s.length && (o(), s = []); + return s.length && o(), l.length ? l.join("") : null + } + var e = Ar, + r = Nr, + u = Ne, + i = go, + o = i.key, + a = .7; + return t.x = function(n) { + return arguments.length ? (e = n, t) : e + }, t.y = function(n) { + return arguments.length ? (r = n, t) : r + }, t.defined = function(n) { + return arguments.length ? (u = n, t) : u + }, t.interpolate = function(n) { + return arguments.length ? (o = "function" == typeof n ? i = n : (i = El.get(n) || go).key, t) : o + }, t.tension = function(n) { + return arguments.length ? (a = n, t) : a + }, t + } + + function go(n) { + return n.join("L") + } + + function po(n) { + return go(n) + "Z" + } + + function vo(n) { + for (var t = 0, e = n.length, r = n[0], u = [r[0], ",", r[1]]; ++t < e;) u.push("H", (r[0] + (r = n[t])[0]) / 2, "V", r[1]); + return e > 1 && 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]]; ++t < e;) u.push("V", (r = n[t])[1], "H", r[0]); + return u.join("") + } + + function yo(n) { + for (var t = 0, e = n.length, r = n[0], u = [r[0], ",", r[1]]; ++t < e;) u.push("H", (r = n[t])[0], "V", r[1]); + return u.join("") + } + + function Mo(n, t) { + return n.length < 4 ? go(n) : n[1] + _o(n.slice(1, -1), wo(n, t)) + } + + function xo(n, t) { + return n.length < 3 ? go(n) : n[0] + _o((n.push(n[0]), n), wo([n[n.length - 2]].concat(n, [n[1]]), t)) + } + + function bo(n, t) { + return n.length < 3 ? go(n) : n[0] + _o(n, wo(n, t)) + } + + function _o(n, t) { + if (t.length < 1 || n.length != t.length && n.length != t.length + 2) return go(n); + var e = n.length != t.length, + r = "", + u = n[0], + i = n[1], + o = t[0], + a = o, + c = 1; + if (e && (r += "Q" + (i[0] - 2 * o[0] / 3) + "," + (i[1] - 2 * o[1] / 3) + "," + i[0] + "," + i[1], u = n[1], c = 2), t.length > 1) { + 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; l < t.length; l++, c++) i = n[c], a = t[l], r += "S" + (i[0] - a[0]) + "," + (i[1] - a[1]) + "," + i[0] + "," + i[1] + } + if (e) { + var s = n[c]; + r += "Q" + (i[0] + 2 * a[0] / 3) + "," + (i[1] + 2 * a[1] / 3) + "," + s[0] + "," + s[1] + } + return r + } + + function wo(n, t) { + for (var e, r = [], u = (1 - t) / 2, i = n[0], o = n[1], a = 1, c = n.length; ++a < c;) e = i, i = o, o = n[a], r.push([u * (o[0] - e[0]), u * (o[1] - e[1])]); + return r + } + + function So(n) { + if (n.length < 3) return go(n); + var t = 1, + e = n.length, + r = n[0], + u = r[0], + i = r[1], + o = [u, u, u, (r = n[1])[0]], + a = [i, i, i, r[1]], + c = [u, ",", i, "L", No(Cl, o), ",", No(Cl, a)]; + for (n.push(n[e - 1]); ++t <= e;) r = n[t], o.shift(), o.push(r[0]), a.shift(), a.push(r[1]), Co(c, o, a); + return n.pop(), c.push("L", r), c.join("") + } + + function ko(n) { + if (n.length < 4) return go(n); + for (var t, e = [], r = -1, u = n.length, i = [0], o = [0]; ++r < 3;) t = n[r], i.push(t[0]), o.push(t[1]); + for (e.push(No(Cl, i) + "," + No(Cl, o)), --r; ++r < u;) t = n[r], i.shift(), i.push(t[0]), o.shift(), o.push(t[1]), Co(e, i, o); + return e.join("") + } + + function Eo(n) { + for (var t, e, r = -1, u = n.length, i = u + 4, o = [], a = []; ++r < 4;) e = n[r % u], o.push(e[0]), a.push(e[1]); + for (t = [No(Cl, o), ",", No(Cl, a)], --r; ++r < i;) e = n[r % u], o.shift(), o.push(e[0]), a.shift(), a.push(e[1]), Co(t, o, a); + return t.join("") + } + + function Ao(n, t) { + var e = n.length - 1; + if (e) + for (var r, u, i = n[0][0], o = n[0][1], a = n[e][0] - i, c = n[e][1] - o, l = -1; ++l <= e;) r = n[l], u = l / e, r[0] = t * r[0] + (1 - t) * (i + u * a), r[1] = t * r[1] + (1 - t) * (o + u * c); + return So(n) + } + + function No(n, t) { + return n[0] * t[0] + n[1] * t[1] + n[2] * t[2] + n[3] * t[3] + } + + function Co(n, t, e) { + n.push("C", No(Al, t), ",", No(Al, e), ",", No(Nl, t), ",", No(Nl, e), ",", No(Cl, t), ",", No(Cl, e)) + } + + function zo(n, t) { + return (t[1] - n[1]) / (t[0] - n[0]) + } + + function qo(n) { + for (var t = 0, e = n.length - 1, r = [], u = n[0], i = n[1], o = r[0] = zo(u, i); ++t < e;) r[t] = (o + (o = zo(u = i, i = n[t + 1]))) / 2; + return r[t] = o, r + } + + function Lo(n) { + for (var t, e, r, u, i = [], o = qo(n), a = -1, c = n.length - 1; ++a < c;) t = zo(n[a], n[a + 1]), ga(t) < Ca ? o[a] = o[a + 1] = 0 : (e = o[a] / t, r = o[a + 1] / t, u = e * e + r * r, u > 9 && (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; ++u < i;) t = n[u], e = t[0], r = t[1] - Ra, t[0] = e * Math.cos(r), t[1] = e * Math.sin(r); + return n + } + + function Do(n) { + function t(t) { + function c() { + v.push("M", a(n(m), f), s, l(n(d.reverse()), f), "Z") + } + for (var h, g, p, v = [], d = [], m = [], y = -1, M = t.length, x = Et(e), b = Et(u), _ = e === r ? function() { + return g + } : Et(r), w = u === i ? function() { + return p + } : Et(i); ++y < M;) o.call(this, h = t[y], y) ? (d.push([g = +x.call(this, h, y), p = +b.call(this, h, y)]), m.push([+_.call(this, h, y), +w.call(this, h, y)])) : d.length && (c(), d = [], m = []); + return d.length && c(), v.length ? v.join("") : null + } + var e = Ar, + r = Ar, + u = 0, + i = Nr, + o = Ne, + a = go, + c = a.key, + l = a, + s = "L", + f = .7; + return t.x = function(n) { + return arguments.length ? (e = r = n, t) : r + }, t.x0 = function(n) { + return arguments.length ? (e = n, t) : e + }, t.x1 = function(n) { + return arguments.length ? (r = n, t) : r + }, t.y = function(n) { + return arguments.length ? (u = i = n, t) : i + }, t.y0 = function(n) { + return arguments.length ? (u = n, t) : u + }, t.y1 = function(n) { + return arguments.length ? (i = n, t) : i + }, t.defined = function(n) { + return arguments.length ? (o = n, t) : o + }, t.interpolate = function(n) { + return arguments.length ? (c = "function" == typeof n ? a = n : (a = El.get(n) || go).key, l = a.reverse || a, s = a.closed ? "M" : "L", t) : c + }, t.tension = function(n) { + return arguments.length ? (f = n, t) : f + }, t + } + + function Po(n) { + return n.radius + } + + function Uo(n) { + return [n.x, n.y] + } + + function jo(n) { + return function() { + var t = n.apply(this, arguments), + e = t[0], + r = t[1] - Ra; + return [e * Math.cos(r), e * Math.sin(r)] + } + } + + function Fo() { + return 64 + } + + function Ho() { + return "circle" + } + + function Oo(n) { + var t = Math.sqrt(n / qa); + return "M0," + t + "A" + t + "," + t + " 0 1,1 0," + -t + "A" + t + "," + t + " 0 1,1 0," + t + "Z" + } + + function Io(n) { + return function() { + var t, e; + (t = this[n]) && (e = t[t.active]) && (--t.count ? delete t[t.active] : delete this[n], t.active += .5, e.event && e.event.interrupt.call(this, this.__data__, e.index)) + } + } + + function Yo(n, t, e) { + return ya(n, Pl), n.namespace = t, n.id = e, n + } + + function Zo(n, t, e, r) { + var u = n.id, + i = n.namespace; + return Y(n, "function" == typeof e ? function(n, o, a) { + n[i][u].tween.set(t, r(e.call(n, n.__data__, o, a))) + } : (e = r(e), function(n) { + n[i][u].tween.set(t, e) + })) + } + + function Vo(n) { + return null == n && (n = ""), + function() { + this.textContent = n + } + } + + function Xo(n) { + return null == n ? "__transition__" : "__transition_" + n + "__" + } + + function $o(n, t, e, r, u) { + var i = n[e] || (n[e] = { + active: 0, + count: 0 + }), + o = i[r]; + if (!o) { + var a = u.time; + o = i[r] = { + tween: new l, + time: a, + delay: u.delay, + duration: u.duration, + ease: u.ease, + index: t + }, u = null, ++i.count, ta.timer(function(u) { + function c(e) { + if (i.active > r) 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, a) + } + + 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 = ec, + v = []; + return p.t = g + a, u >= g ? c(u - g) : void(p.c = c) + }, 0, a) + } + } + + 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(Vl, u); + return i == Vl.length ? [t.year, Vi(n.map(function(n) { + return n / 31536e6 + }), e)[2]] : i ? t[u / Vl[i - 1] < Vl[i] / u ? i - 1 : i] : [Bl, Vi(n, e)[2]] + } + return r.invert = function(t) { + return Ko(n.invert(t)) + }, r.domain = function(t) { + return arguments.length ? (n.domain(t), r) : n.domain().map(Ko) + }, r.nice = function(n, t) { + function e(e) { + return !isNaN(e) && !n.range(e, Ko(+e + 1), t).length + } + var i = r.domain(), + o = Pi(i), + a = null == n ? u(o, 10) : "number" == typeof n && u(o, n); + return a && (n = a[0], t = a[1]), r.domain(Fi(i, t > 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) + }, Yi(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.4" + }, + ea = [].slice, + ra = function(n) { + return ea.call(n) + }, + ua = this.document; + if (ua) try { + ra(ua.documentElement.childNodes)[0].nodeType + } catch (ia) { + ra = function(n) { + for (var t = n.length, e = new Array(t); t--;) e[t] = n[t]; + return e + } + } + if (Date.now || (Date.now = function() { + return +new Date + }), ua) try { + ua.createElement("DIV").style.setProperty("opacity", 0, "") + } catch (oa) { + var aa = this.Element.prototype, + ca = aa.setAttribute, + la = aa.setAttributeNS, + sa = this.CSSStyleDeclaration.prototype, + fa = sa.setProperty; + aa.setAttribute = function(n, t) { + ca.call(this, n, t + "") + }, aa.setAttributeNS = function(n, t, e) { + la.call(this, n, t, e + "") + }, sa.setProperty = function(n, t, e) { + fa.call(this, n, t + "", e) + } + } + ta.ascending = e, 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 < i;) + if (null != (r = n[u]) && r >= r) { + e = r; + break + } for (; ++u < i;) null != (r = n[u]) && e > r && (e = r) + } else { + for (; ++u < i;) + if (null != (r = t.call(n, n[u], u)) && r >= r) { + e = r; + break + } for (; ++u < i;) null != (r = t.call(n, n[u], u)) && e > r && (e = r) + } + return e + }, ta.max = function(n, t) { + var e, r, u = -1, + i = n.length; + if (1 === arguments.length) { + for (; ++u < i;) + if (null != (r = n[u]) && r >= r) { + e = r; + break + } for (; ++u < i;) null != (r = n[u]) && r > e && (e = r) + } else { + for (; ++u < i;) + if (null != (r = t.call(n, n[u], u)) && r >= r) { + e = r; + break + } for (; ++u < i;) null != (r = t.call(n, n[u], u)) && r > e && (e = r) + } + return e + }, ta.extent = function(n, t) { + var e, r, u, i = -1, + o = n.length; + if (1 === arguments.length) { + for (; ++i < o;) + if (null != (r = n[i]) && r >= r) { + e = u = r; + break + } for (; ++i < o;) null != (r = n[i]) && (e > r && (e = r), r > u && (u = r)) + } else { + for (; ++i < o;) + if (null != (r = t.call(n, n[i], i)) && r >= r) { + e = u = r; + break + } for (; ++i < o;) null != (r = t.call(n, n[i], i)) && (e > r && (e = r), r > u && (u = r)) + } + return [e, u] + }, ta.sum = function(n, t) { + var e, r = 0, + i = n.length, + o = -1; + if (1 === arguments.length) + for (; ++o < i;) u(e = +n[o]) && (r += e); + else + for (; ++o < i;) u(e = +t.call(n, n[o], o)) && (r += e); + return r + }, ta.mean = function(n, t) { + var e, i = 0, + o = n.length, + a = -1, + c = o; + if (1 === arguments.length) + for (; ++a < o;) u(e = r(n[a])) ? i += e : --c; + else + for (; ++a < o;) u(e = r(t.call(n, n[a], a))) ? i += e : --c; + return c ? i / c : void 0 + }, ta.quantile = function(n, t) { + var e = (n.length - 1) * t + 1, + r = Math.floor(e), + u = +n[r - 1], + i = e - r; + return i ? u + i * (n[r] - u) : u + }, ta.median = function(n, t) { + var i, o = [], + a = n.length, + c = -1; + if (1 === arguments.length) + for (; ++c < a;) u(i = r(n[c])) && o.push(i); + else + for (; ++c < a;) u(i = r(t.call(n, n[c], c))) && o.push(i); + return o.length ? ta.quantile(o.sort(e), .5) : void 0 + }, ta.variance = function(n, t) { + var e, i, o = n.length, + a = 0, + c = 0, + l = -1, + s = 0; + if (1 === arguments.length) + for (; ++l < o;) u(e = r(n[l])) && (i = e - a, a += i / ++s, c += i * (e - a)); + else + for (; ++l < o;) u(e = r(t.call(n, n[l], l))) && (i = e - a, a += i / ++s, c += i * (e - a)); + return s > 1 ? c / (s - 1) : void 0 + }, ta.deviation = function() { + var n = ta.variance.apply(this, arguments); + return n ? Math.sqrt(n) : n + }; + var ha = i(e); + ta.bisectLeft = ha.left, ta.bisect = ta.bisectRight = ha.right, ta.bisector = function(n) { + return i(1 === n.length ? function(t, r) { + return e(n(t), r) + } : n) + }, 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 = Math.random() * i-- | 0, 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, o), e = new Array(t); ++n < t;) + for (var r, u = -1, i = e[n] = new Array(r); ++u < r;) i[u] = arguments[u][n]; + return e + }, ta.transpose = function(n) { + return ta.zip.apply(ta, n) + }, ta.keys = function(n) { + var t = []; + for (var e in n) t.push(e); + return t + }, ta.values = function(n) { + var t = []; + for (var e in n) t.push(n[e]); + return t + }, ta.entries = function(n) { + var t = []; + for (var e in n) t.push({ + key: e, + value: n[e] + }); + return t + }, ta.merge = function(n) { + for (var t, e, r, u = n.length, i = -1, o = 0; ++i < u;) o += n[i].length; + for (e = new Array(o); --u >= 0;) + for (r = n[u], t = r.length; --t >= 0;) e[--o] = r[t]; + return e + }; + var ga = Math.abs; + ta.range = function(n, t, e) { + if (arguments.length < 3 && (e = 1, arguments.length < 2 && (t = n, n = 0)), (t - n) / e === 1 / 0) throw new Error("infinite range"); + var r, u = [], + i = a(ga(e)), + o = -1; + if (n *= i, t *= i, e *= i, 0 > e) + for (; + (r = n + e * ++o) > t;) u.push(r / i); + else + for (; + (r = n + e * ++o) < t;) u.push(r / i); + return u + }, ta.map = function(n, t) { + var e = new l; + if (n instanceof l) n.forEach(function(n, t) { + e.set(n, t) + }); + else if (Array.isArray(n)) { + var r, u = -1, + i = n.length; + if (1 === arguments.length) + for (; ++u < i;) e.set(u, n[u]); + else + for (; ++u < i;) e.set(t.call(n, r = n[u], u), r) + } else + for (var o in n) e.set(o, n[o]); + return e + }; + var pa = "__proto__", + va = "\x00"; + c(l, { + has: h, + get: function(n) { + return this._[s(n)] + }, + set: function(n, t) { + return this._[s(n)] = t + }, + remove: g, + keys: p, + values: function() { + var n = []; + for (var t in this._) n.push(this._[t]); + return n + }, + entries: function() { + var n = []; + for (var t in this._) n.push({ + key: f(t), + value: this._[t] + }); + return n + }, + size: v, + empty: d, + forEach: function(n) { + for (var t in this._) n.call(this, f(t), this._[t]) + } + }), ta.nest = function() { + function n(t, o, a) { + if (a >= i.length) return r ? r.call(u, o) : e ? o.sort(e) : o; + for (var c, s, f, h, g = -1, p = o.length, v = i[a++], d = new l; ++g < p;)(h = d.get(c = v(s = o[g]))) ? h.push(s) : d.set(c, [s]); + return t ? (s = t(), f = function(e, r) { + s.set(e, n(t, r, a)) + }) : (s = {}, f = function(e, r) { + s[e] = n(t, r, a) + }), d.forEach(f), s + } + + function t(n, e) { + if (e >= 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 m; + if (n) + for (var e = 0, r = n.length; r > e; ++e) t.add(n[e]); + return t + }, c(m, { + has: h, + add: function(n) { + return this._[s(n += "")] = !0, n + }, + remove: g, + values: p, + size: v, + empty: d, + forEach: function(n) { + for (var t in this._) n.call(this, f(t)) + } + }), ta.behavior = {}, ta.rebind = function(n, t) { + for (var e, r = 1, u = arguments.length; ++r < u;) n[e = arguments[r]] = M(n, t, t[e]); + return n + }; + var da = ["webkit", "ms", "moz", "Moz", "o", "O"]; + ta.dispatch = function() { + for (var n = new _, t = -1, e = arguments.length; ++t < e;) n[arguments[t]] = w(n); + return n + }, _.prototype.on = function(n, t) { + var e = n.indexOf("."), + r = ""; + if (e >= 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, + ya = {}.__proto__ ? function(n, t) { + n.__proto__ = t + } : function(n, t) { + for (var e in t) n[e] = t[e] + }, + Ma = function(n, t) { + return t.querySelector(n) + }, + xa = function(n, t) { + return t.querySelectorAll(n) + }, + ba = function(n, t) { + var e = n.matches || n[x(n, "matchesSelector")]; + return (ba = function(n, t) { + return e.call(n, t) + })(n, t) + }; + "function" == typeof Sizzle && (Ma = function(n, t) { + return Sizzle(n, t)[0] || null + }, xa = Sizzle, ba = Sizzle.matchesSelector), ta.selection = function() { + return ta.select(ua.documentElement) + }; + var _a = ta.selection.prototype = []; + _a.select = function(n) { + var t, e, r, u, i = []; + n = N(n); + for (var o = -1, a = this.length; ++o < a;) { + i.push(t = []), t.parentNode = (r = this[o]).parentNode; + for (var c = -1, l = r.length; ++c < l;)(u = r[c]) ? (t.push(e = n.call(u, u.__data__, c, o)), e && "__data__" in u && (e.__data__ = u.__data__)) : t.push(null) + } + return A(i) + }, _a.selectAll = function(n) { + var t, e, r = []; + n = C(n); + for (var u = -1, i = this.length; ++u < i;) + for (var o = this[u], a = -1, c = o.length; ++a < c;)(e = o[a]) && (r.push(t = ra(n.call(e, e.__data__, a, u))), t.parentNode = e); + return A(r) + }; + var wa = { + svg: "http://www.w3.org/2000/svg", + xhtml: "http://www.w3.org/1999/xhtml", + xlink: "http://www.w3.org/1999/xlink", + xml: "http://www.w3.org/XML/1998/namespace", + xmlns: "http://www.w3.org/2000/xmlns/" + }; + ta.ns = { + prefix: wa, + qualify: function(n) { + var t = n.indexOf(":"), + e = n; + return t >= 0 && (e = n.slice(0, t), n = n.slice(t + 1)), wa.hasOwnProperty(e) ? { + space: wa[e], + local: n + } : n + } + }, _a.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(z(t, n[t])); + return this + } + return this.each(z(n, t)) + }, _a.classed = function(n, t) { + if (arguments.length < 2) { + if ("string" == typeof n) { + var e = this.node(), + r = (n = T(n)).length, + u = -1; + if (t = e.classList) { + for (; ++u < r;) + if (!t.contains(n[u])) return !1 + } else + for (t = e.getAttribute("class"); ++u < r;) + if (!L(n[u]).test(t)) return !1; + return !0 + } + for (t in n) this.each(R(t, n[t])); + return this + } + return this.each(R(n, t)) + }, _a.style = function(n, e, r) { + var u = arguments.length; + if (3 > u) { + if ("string" != typeof n) { + 2 > u && (e = ""); + for (r in n) this.each(P(r, n[r], e)); + return this + } + if (2 > u) { + var i = this.node(); + return t(i).getComputedStyle(i, null).getPropertyValue(n) + } + r = "" + } + return this.each(P(n, e, r)) + }, _a.property = function(n, t) { + if (arguments.length < 2) { + if ("string" == typeof n) return this.node()[n]; + for (t in n) this.each(U(t, n[t])); + return this + } + return this.each(U(n, t)) + }, _a.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 + }, _a.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 + }, _a.append = function(n) { + return n = j(n), this.select(function() { + return this.appendChild(n.apply(this, arguments)) + }) + }, _a.insert = function(n, t) { + return n = j(n), t = N(t), this.select(function() { + return this.insertBefore(n.apply(this, arguments), t.apply(this, arguments) || null) + }) + }, _a.remove = function() { + return this.each(F) + }, _a.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 l, + y = new Array(o); + for (r = -1; ++r < o;) m.has(d = t.call(u = n[r], u.__data__, r)) ? v[r] = u : m.set(d, u), y[r] = d; + for (r = -1; ++r < f;)(u = m.get(d = t.call(e, i = e[r], r))) ? u !== !0 && (g[r] = u, u.__data__ = i) : p[r] = H(i), m.set(d, !0); + for (r = -1; ++r < o;) m.get(y[r]) !== !0 && (v[r] = n[r]) + } else { + for (r = -1; ++r < h;) u = n[r], i = e[r], u ? (u.__data__ = i, g[r] = u) : p[r] = H(i); + for (; f > r; ++r) p[r] = H(e[r]); + for (; o > r; ++r) v[r] = n[r] + } + p.update = g, p.parentNode = g.parentNode = v.parentNode = n.parentNode, a.push(p), c.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); ++i < o;)(u = r[i]) && (n[i] = u.__data__); + return n + } + var a = Z([]), + c = A([]), + s = A([]); + if ("function" == typeof n) + for (; ++i < o;) e(r = this[i], n.call(r, r.parentNode.__data__, i)); + else + for (; ++i < o;) e(r = this[i], n); + return c.enter = function() { + return a + }, c.exit = function() { + return s + }, c + }, _a.datum = function(n) { + return arguments.length ? this.property("__data__", n) : this.property("__data__") + }, _a.filter = function(n) { + var t, e, r, u = []; + "function" != typeof n && (n = O(n)); + for (var i = 0, o = this.length; o > i; 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 A(u) + }, _a.order = function() { + for (var n = -1, t = this.length; ++n < t;) + for (var e, r = this[n], u = r.length - 1, i = r[u]; --u >= 0;)(e = r[u]) && (i && i !== e.nextSibling && i.parentNode.insertBefore(e, i), i = e); + return this + }, _a.sort = function(n) { + n = I.apply(this, arguments); + for (var t = -1, e = this.length; ++t < e;) this[t].sort(n); + return this.order() + }, _a.each = function(n) { + return Y(this, function(t, e, r) { + n.call(t, t.__data__, e, r) + }) + }, _a.call = function(n) { + var t = ra(arguments); + return n.apply(t[0] = this, t), this + }, _a.empty = function() { + return !this.node() + }, _a.node = function() { + for (var n = 0, t = this.length; t > n; n++) + for (var e = this[n], r = 0, u = e.length; u > r; r++) { + var i = e[r]; + if (i) return i + } + return null + }, _a.size = function() { + var n = 0; + return Y(this, function() { + ++n + }), n + }; + var Sa = []; + ta.selection.enter = Z, ta.selection.enter.prototype = Sa, Sa.append = _a.append, Sa.empty = _a.empty, Sa.node = _a.node, Sa.call = _a.call, Sa.size = _a.size, Sa.select = function(n) { + for (var t, e, r, u, i, o = [], a = -1, c = this.length; ++a < c;) { + r = (u = this[a]).update, o.push(t = []), t.parentNode = u.parentNode; + for (var l = -1, s = u.length; ++l < s;)(i = u[l]) ? (t.push(r[l] = e = n.call(u.parentNode, i.__data__, l, a)), e.__data__ = i.__data__) : t.push(null) + } + return A(o) + }, Sa.insert = function(n, t) { + return arguments.length < 2 && (t = V(this)), _a.insert.call(this, n, t) + }, ta.select = function(t) { + var e; + return "string" == typeof t ? (e = [Ma(t, ua)], e.parentNode = ua.documentElement) : (e = [t], e.parentNode = n(t)), A([e]) + }, ta.selectAll = function(n) { + var t; + return "string" == typeof n ? (t = ra(xa(n, ua)), t.parentNode = ua.documentElement) : (t = n, t.parentNode = null), A([t]) + }, _a.on = function(n, t, e) { + var r = arguments.length; + if (3 > r) { + if ("string" != typeof n) { + 2 > r && (t = !1); + for (e in n) this.each(X(e, n[e], t)); + return this + } + if (2 > r) return (r = this.node()["__on" + n]) && r._; + e = !1 + } + return this.each(X(n, t, e)) + }; + var ka = ta.map({ + mouseenter: "mouseover", + mouseleave: "mouseout" + }); + ua && ka.forEach(function(n) { + "on" + n in ua && ka.remove(n) + }); + var Ea, Aa = 0; + ta.mouse = function(n) { + return J(n, k()) + }; + var Na = this.navigator && /WebKit/.test(this.navigator.userAgent) ? -1 : 0; + ta.touch = function(n, t, e) { + if (arguments.length < 3 && (e = t, t = k().changedTouches), t) + for (var r, u = 0, i = t.length; i > u; ++u) + if ((r = t[u]).identifier === e) return J(n, r) + }, ta.behavior.drag = function() { + function n() { + this.on("mousedown.drag", i).on("touchstart.drag", o) + } + + function e(n, t, e, 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 = r.of(s, arguments), + p = 0, + v = n(), + d = ".drag" + (null == v ? "" : "-" + v), + m = ta.select(e(f)).on(i + d, a).on(o + d, c), + y = W(f), + M = t(h, v); + u ? (l = u.apply(s, arguments), l = [l.x - M[0], l.y - M[1]]) : l = [0, 0], g({ + type: "dragstart" + }) + } + } + var r = E(n, "drag", "dragstart", "dragend"), + u = null, + i = e(b, ta.mouse, t, "mousemove", "mouseup"), + o = e(G, ta.touch, y, "touchmove", "touchend"); + return n.origin = function(t) { + return arguments.length ? (u = t, n) : u + }, ta.rebind(n, r, "on") + }, ta.touches = function(n, t) { + return arguments.length < 2 && (t = k().touches), t ? ra(t).map(function(t) { + var e = J(n, t); + return e.identifier = t.identifier, e + }) : [] + }; + var Ca = 1e-6, + za = Ca * Ca, + qa = Math.PI, + La = 2 * qa, + Ta = La - Ca, + Ra = qa / 2, + Da = qa / 180, + Pa = 180 / qa, + Ua = Math.SQRT2, + ja = 2, + Fa = 4; + ta.interpolateZoom = function(n, t) { + function e(n) { + var t = n * y; + if (m) { + var e = rt(v), + o = i / (ja * h) * (e * ut(Ua * t + v) - et(v)); + return [r + o * l, u + o * s, i * e / rt(Ua * t + v)] + } + return [r + n * l, u + n * s, i * Math.exp(Ua * 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 + Fa * f) / (2 * i * ja * h), + p = (c * c - i * i - Fa * f) / (2 * c * ja * 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)) / Ua; + return e.duration = 1e3 * y, e + }, ta.behavior.zoom = function() { + function n(n) { + n.on(q, f).on(Oa + ".zoom", g).on("dblclick.zoom", p).on(R, h) + } + + function e(n) { + return [(n[0] - k.x) / k.k, (n[1] - k.y) / k.k] + } + + function r(n) { + return [n[0] * k.k + k.x, n[1] * k.k + k.y] + } + + function u(n) { + k.k = Math.max(N[0], Math.min(N[1], n)) + } + + function i(n, t) { + t = r(t), k.x += n[0] - t[0], k.y += n[1] - t[1] + } + + function o(t, e, r, o) { + t.__chart__ = { + x: k.x, + y: k.y, + k: k.k + }, u(Math.pow(2, o)), i(d = e, r), t = ta.select(t), C > 0 && (t = t.transition().duration(C)), t.call(n.event) + } + + function a() { + b && b.domain(x.range().map(function(n) { + return (n - k.x) / k.k + }).map(x.invert)), w && w.domain(_.range().map(function(n) { + return (n - k.y) / k.k + }).map(_.invert)) + } + + function c(n) { + z++ || n({ + type: "zoomstart" + }) + } + + function l(n) { + a(), n({ + type: "zoom", + scale: k.k, + translate: [k.x, k.y] + }) + } + + function s(n) { + --z || n({ + type: "zoomend" + }), d = null + } + + function f() { + function n() { + f = 1, i(ta.mouse(u), g), l(a) + } + + function r() { + h.on(L, null).on(T, null), p(f && ta.event.target === o), s(a) + } + var u = this, + o = ta.event.target, + a = D.of(u, arguments), + f = 0, + h = ta.select(t(u)).on(L, n).on(T, r), + g = e(ta.mouse(u)), + p = W(u); + Dl.call(u), c(a) + } + + function h() { + function n() { + var n = ta.touches(p); + return g = k.k, n.forEach(function(n) { + n.identifier in d && (d[n.identifier] = e(n)) + }), n + } + + function t() { + var t = ta.event.target; + ta.select(t).on(x, r).on(b, a), _.push(t); + for (var e = ta.event.changedTouches, u = 0, i = e.length; i > u; ++u) d[e[u].identifier] = null; + var c = n(), + l = Date.now(); + if (1 === c.length) { + if (500 > l - M) { + var s = c[0]; + o(p, s, d[s.identifier], Math.floor(Math.log(k.k) / Math.LN2) + 1), S() + } + M = l + } else if (c.length > 1) { + var s = c[0], + f = c[1], + h = s[0] - f[0], + g = s[1] - f[1]; + m = h * h + g * g + } + } + + function r() { + var n, t, e, r, o = ta.touches(p); + Dl.call(p); + for (var a = 0, c = o.length; c > a; ++a, r = null) + if (e = o[a], r = d[e.identifier]) { + if (t) break; + n = e, t = r + } if (r) { + 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] + r[0]) / 2, (t[1] + r[1]) / 2], u(f * g) + } + M = null, i(n, t), l(v) + } + + function a() { + 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(_).on(y, null), w.on(q, f).on(R, h), E(), s(v) + } + var g, p = this, + v = D.of(p, arguments), + d = {}, + m = 0, + y = ".zoom-" + ta.event.changedTouches[0].identifier, + x = "touchmove" + y, + b = "touchend" + y, + _ = [], + w = ta.select(p), + E = W(p); + t(), c(v), w.on(q, null).on(R, t) + } + + function g() { + var n = D.of(this, arguments); + y ? clearTimeout(y) : (v = e(d = m || ta.mouse(this)), Dl.call(this), c(n)), y = setTimeout(function() { + y = null, s(n) + }, 50), S(), u(Math.pow(2, .002 * Ha()) * k.k), i(d, v), l(n) + } + + function p() { + var n = ta.mouse(this), + t = Math.log(k.k) / Math.LN2; + o(this, n, e(n), ta.event.shiftKey ? Math.ceil(t) - 1 : Math.floor(t) + 1) + } + var v, d, m, y, M, x, b, _, w, k = { + x: 0, + y: 0, + k: 1 + }, + A = [960, 500], + N = Ia, + C = 250, + z = 0, + q = "mousedown.zoom", + L = "mousemove.zoom", + T = "mouseup.zoom", + R = "touchstart.zoom", + D = E(n, "zoomstart", "zoom", "zoomend"); + return Oa || (Oa = "onwheel" in ua ? (Ha = function() { + return -ta.event.deltaY * (ta.event.deltaMode ? 120 : 1) + }, "wheel") : "onmousewheel" in ua ? (Ha = function() { + return ta.event.wheelDelta + }, "mousewheel") : (Ha = function() { + return -ta.event.detail + }, "MozMousePixelScroll")), n.event = function(n) { + n.each(function() { + var n = D.of(this, arguments), + t = k; + Tl ? ta.select(this).transition().each("start.zoom", function() { + k = this.__chart__ || { + x: 0, + y: 0, + k: 1 + }, c(n) + }).tween("zoom:zoom", function() { + var e = A[0], + r = A[1], + u = d ? d[0] : e / 2, + i = d ? d[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 + }, l(n) + } + }).each("interrupt.zoom", function() { + s(n) + }).each("end.zoom", function() { + s(n) + }) : (this.__chart__ = k, c(n), l(n), s(n)) + }) + }, n.translate = function(t) { + return arguments.length ? (k = { + x: +t[0], + y: +t[1], + k: k.k + }, a(), n) : [k.x, k.y] + }, n.scale = function(t) { + return arguments.length ? (k = { + x: k.x, + y: k.y, + k: +t + }, a(), n) : k.k + }, n.scaleExtent = function(t) { + return arguments.length ? (N = null == t ? Ia : [+t[0], +t[1]], n) : N + }, n.center = function(t) { + return arguments.length ? (m = t && [+t[0], +t[1]], n) : m + }, n.size = function(t) { + return arguments.length ? (A = t && [+t[0], +t[1]], n) : A + }, n.duration = function(t) { + return arguments.length ? (C = +t, n) : C + }, n.x = function(t) { + return arguments.length ? (b = t, x = t.copy(), k = { + x: 0, + y: 0, + k: 1 + }, n) : b + }, n.y = function(t) { + return arguments.length ? (w = t, _ = t.copy(), k = { + x: 0, + y: 0, + k: 1 + }, n) : w + }, ta.rebind(n, D, "on") + }; + var Ha, Oa, Ia = [0, 1 / 0]; + ta.color = ot, ot.prototype.toString = function() { + return this.rgb() + "" + }, ta.hsl = at; + var Ya = at.prototype = new ot; + Ya.brighter = function(n) { + return n = Math.pow(.7, arguments.length ? n : 1), new at(this.h, this.s, this.l / n) + }, Ya.darker = function(n) { + return n = Math.pow(.7, arguments.length ? n : 1), new at(this.h, this.s, n * this.l) + }, Ya.rgb = function() { + return ct(this.h, this.s, this.l) + }, ta.hcl = lt; + var Za = lt.prototype = new ot; + Za.brighter = function(n) { + return new lt(this.h, this.c, Math.min(100, this.l + Va * (arguments.length ? n : 1))) + }, Za.darker = function(n) { + return new lt(this.h, this.c, Math.max(0, this.l - Va * (arguments.length ? n : 1))) + }, Za.rgb = function() { + return st(this.h, this.c, this.l).rgb() + }, ta.lab = ft; + var Va = 18, + Xa = .95047, + $a = 1, + Ba = 1.08883, + Wa = ft.prototype = new ot; + Wa.brighter = function(n) { + return new ft(Math.min(100, this.l + Va * (arguments.length ? n : 1)), this.a, this.b) + }, Wa.darker = function(n) { + return new ft(Math.max(0, this.l - Va * (arguments.length ? n : 1)), this.a, this.b) + }, Wa.rgb = function() { + return ht(this.l, this.a, this.b) + }, ta.rgb = mt; + var Ja = mt.prototype = new ot; + Ja.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 mt(Math.min(255, t / n), Math.min(255, e / n), Math.min(255, r / n))) : new mt(u, u, u) + }, Ja.darker = function(n) { + return n = Math.pow(.7, arguments.length ? n : 1), new mt(n * this.r, n * this.g, n * this.b) + }, Ja.hsl = function() { + return _t(this.r, this.g, this.b) + }, Ja.toString = function() { + return "#" + xt(this.r) + xt(this.g) + xt(this.b) + }; + var Ga = 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, + rebeccapurple: 6697881, + 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 + }); + Ga.forEach(function(n, t) { + Ga.set(n, yt(t)) + }), ta.functor = Et, ta.xhr = At(y), 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++ < l;) + if (34 === n.charCodeAt(e)) { + if (34 !== n.charCodeAt(e + 1)) break; + ++e + } s = e + 2; + var r = n.charCodeAt(e + 1); + return 13 === r ? (u = !0, 10 === n.charCodeAt(e + 2) && ++s) : 10 === r && (u = !0), n.slice(t + 1, e).replace(/""/g, '"') + } + for (; l > 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 m, + 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 Ka, Qa, nc, tc, ec, rc = this[x(this, "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 + }; + Qa ? Qa.n = i : Ka = i, Qa = i, nc || (tc = clearTimeout(tc), nc = 1, rc(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 uc = ["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)))), uc[8 + e / 3] + }; + var ic = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i, + oc = 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)))) + } + }), + ac = ta.time = {}, + cc = 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() { + lc.setUTCDate.apply(this._, arguments) + }, + setDay: function() { + lc.setUTCDay.apply(this._, arguments) + }, + setFullYear: function() { + lc.setUTCFullYear.apply(this._, arguments) + }, + setHours: function() { + lc.setUTCHours.apply(this._, arguments) + }, + setMilliseconds: function() { + lc.setUTCMilliseconds.apply(this._, arguments) + }, + setMinutes: function() { + lc.setUTCMinutes.apply(this._, arguments) + }, + setMonth: function() { + lc.setUTCMonth.apply(this._, arguments) + }, + setSeconds: function() { + lc.setUTCSeconds.apply(this._, arguments) + }, + setTime: function() { + lc.setTime.apply(this._, arguments) + } + }; + var lc = Date.prototype; + ac.year = Ft(function(n) { + return n = ac.day(n), n.setMonth(0, 1), n + }, function(n, t) { + n.setFullYear(n.getFullYear() + t) + }, function(n) { + return n.getFullYear() + }), ac.years = ac.year.range, ac.years.utc = ac.year.utc.range, ac.day = Ft(function(n) { + var t = new cc(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 + }), ac.days = ac.day.range, ac.days.utc = ac.day.utc.range, ac.dayOfYear = function(n) { + var t = ac.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 = ac[n] = Ft(function(n) { + return (n = ac.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 = ac.year(n).getDay(); + return Math.floor((ac.dayOfYear(n) + (e + t) % 7) / 7) - (e !== t) + }); + ac[n + "s"] = e.range, ac[n + "s"].utc = e.utc.range, ac[n + "OfYear"] = function(n) { + var e = ac.year(n).getDay(); + return Math.floor((ac.dayOfYear(n) + (e + t) % 7) / 7) + } + }), ac.week = ac.sunday, ac.weeks = ac.sunday.range, ac.weeks.utc = ac.sunday.utc.range, ac.weekOfYear = ac.sundayOfYear; + var sc = { + "-": "", + _: " ", + 0: "0" + }, + fc = /^\s*\d+/, + hc = /^%/; + ta.locale = function(n) { + return { + numberFormat: Pt(n), + timeFormat: Ot(n) + } + }; + var gc = 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 = gc.numberFormat, ta.geo = {}, ce.prototype = { + s: 0, + t: 0, + add: function(n) { + le(n, this.t, pc), le(pc.s, this.s, this), this.s ? this.t += pc.t : this.s = pc.t + }, + reset: function() { + this.s = this.t = 0 + }, + valueOf: function() { + return this.s + } + }; + var pc = new ce; + ta.geo.stream = function(n, t) { + n && vc.hasOwnProperty(n.type) ? vc[n.type](n, t) : se(n, t) + }; + var vc = { + Feature: function(n, t) { + se(n.geometry, t) + }, + FeatureCollection: function(n, t) { + for (var e = n.features, r = -1, u = e.length; ++r < u;) se(e[r].geometry, t) + } + }, + dc = { + Sphere: function(n, t) { + t.sphere() + }, + Point: function(n, t) { + n = n.coordinates, t.point(n[0], n[1], n[2]) + }, + MultiPoint: function(n, t) { + for (var e = n.coordinates, r = -1, u = e.length; ++r < u;) n = e[r], t.point(n[0], n[1], n[2]) + }, + LineString: function(n, t) { + fe(n.coordinates, t, 0) + }, + MultiLineString: function(n, t) { + for (var e = n.coordinates, r = -1, u = e.length; ++r < u;) fe(e[r], t, 0) + }, + Polygon: function(n, t) { + he(n.coordinates, t) + }, + MultiPolygon: function(n, t) { + for (var e = n.coordinates, r = -1, u = e.length; ++r < u;) he(e[r], t) + }, + GeometryCollection: function(n, t) { + for (var e = n.geometries, r = -1, u = e.length; ++r < u;) se(e[r], t) + } + }; + ta.geo.area = function(n) { + return mc = 0, ta.geo.stream(n, Mc), mc + }; + var mc, yc = new ce, + Mc = { + sphere: function() { + mc += 4 * qa + }, + point: b, + lineStart: b, + lineEnd: b, + polygonStart: function() { + yc.reset(), Mc.lineStart = ge + }, + polygonEnd: function() { + var n = 2 * yc; + mc += 0 > n ? 4 * qa + n : n, Mc.lineStart = Mc.lineEnd = Mc.point = b + } + }; + 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 * Da, e * Da]); + 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] * Pa * l, + d = ga(c) > 180; + if (d ^ (v > l * p && l * t > v)) { + var y = o[1] * Pa; + y > g && (g = y) + } else if (v = (v + 360) % 360 - 180, d ^ (v > l * p && l * t > v)) { + var y = -o[1] * Pa; + 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 += ga(r) > 180 ? r + (r > 0 ? 360 : -360) : r + } else v = n, d = e; + Mc.point(n, e), t(n, e) + } + + function i() { + Mc.lineStart() + } + + function o() { + u(v, d), Mc.lineEnd(), ga(y) > Ca && (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 < t[0] || t[1] < n + } + var s, f, h, g, p, v, d, m, y, M, x, b = { + point: n, + lineStart: e, + lineEnd: r, + polygonStart: function() { + b.point = u, b.lineStart = i, b.lineEnd = o, y = 0, Mc.polygonStart() + }, + polygonEnd: function() { + Mc.polygonEnd(), b.point = n, b.lineStart = e, b.lineEnd = r, 0 > yc ? (s = -(h = 180), f = -(g = 90)) : y > Ca ? g = 90 : -Ca > 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) { + xc = bc = _c = wc = Sc = kc = Ec = Ac = Nc = Cc = zc = 0, ta.geo.stream(n, qc); + var t = Nc, + e = Cc, + r = zc, + u = t * t + e * e + r * r; + return za > u && (t = kc, e = Ec, r = Ac, Ca > bc && (t = _c, e = wc, r = Sc), u = t * t + e * e + r * r, za > u) ? [0 / 0, 0 / 0] : [Math.atan2(e, t) * Pa, tt(r / Math.sqrt(u)) * Pa] + }; + var xc, bc, _c, wc, Sc, kc, Ec, Ac, Nc, Cc, zc, qc = { + sphere: b, + point: _e, + lineStart: Se, + lineEnd: ke, + polygonStart: function() { + qc.lineStart = Ee + }, + polygonEnd: function() { + qc.lineStart = Se + } + }, + Lc = Le(Ne, Pe, je, [-qa, -qa / 2]), + Tc = 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 = Ie(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 Ye(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 + Ca, f + .12 * l + Ca], + [s - .214 * l - Ca, f + .234 * l - Ca] + ]).stream(c).point, u = a.translate([s - .205 * l, f + .212 * l]).clipExtent([ + [s - .214 * l + Ca, f + .166 * l + Ca], + [s - .115 * l - Ca, f + .234 * l - Ca] + ]).stream(c).point, n + }, n.scale(1070) + }; + var Rc, Dc, Pc, Uc, jc, Fc, Hc = { + point: b, + lineStart: b, + lineEnd: b, + polygonStart: function() { + Dc = 0, Hc.lineStart = Ve + }, + polygonEnd: function() { + Hc.lineStart = Hc.lineEnd = Hc.point = b, Rc += ga(Dc / 2) + } + }, + Oc = { + point: Xe, + lineStart: b, + lineEnd: b, + polygonStart: b, + polygonEnd: b + }, + Ic = { + point: We, + lineStart: Je, + lineEnd: Ge, + polygonStart: function() { + Ic.lineStart = Ke + }, + polygonEnd: function() { + Ic.point = We, Ic.lineStart = Je, Ic.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 Rc = 0, ta.geo.stream(n, u(Hc)), Rc + }, n.centroid = function(n) { + return _c = wc = Sc = kc = Ec = Ac = Nc = Cc = zc = 0, ta.geo.stream(n, u(Ic)), zc ? [Nc / zc, Cc / zc] : Ac ? [kc / Ac, Ec / Ac] : Sc ? [_c / Sc, wc / Sc] : [0 / 0, 0 / 0] + }, n.bounds = function(n) { + return jc = Fc = -(Pc = Uc = 1 / 0), ta.geo.stream(n, u(Oc)), [ + [Pc, Uc], + [jc, Fc] + ] + }, n.projection = function(n) { + return arguments.length ? (u = (e = n) ? n.stream || tr(n) : y, 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] * Da, t[1] * Da), t[0] *= Pa, t[1] *= Pa, t + } + return n = lr(n[0] % 360 * Da, n[1] * Da, n.length > 2 ? n[2] * Da : 0), t.invert = function(t) { + return t = n.invert(t[0] * Da, t[1] * Da), t[0] *= Pa, t[1] *= Pa, 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] * Da, -n[1] * Da, 0).invert, + u = []; + return e(null, null, 1, { + point: function(n, e) { + u.push(n = t(n, e)), n[0] *= Pa, n[1] *= Pa + } + }), { + 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) * Da, u * Da), n) : t + }, n.precision = function(r) { + return arguments.length ? (e = gr(t * Da, (u = +r) * Da), n) : u + }, n.angle(90) + }, ta.geo.distance = function(n, t) { + var e, r = (t[0] - n[0]) * Da, + u = n[1] * Da, + i = t[1] * Da, + 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 ga(n % d) > Ca + }).map(s)).concat(ta.range(Math.ceil(a / v) * v, o, v).filter(function(n) { + return ga(n % m) > Ca + }).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 + Ca], + [180, 90 - Ca] + ]).minorExtent([ + [-180, -80 - Ca], + [180, 80 + Ca] + ]) + }, 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] * Da, n[1] * Da, t[0] * Da, t[1] * Da) + }, ta.geo.length = function(n) { + return Yc = 0, ta.geo.stream(n, Zc), Yc + }; + var Yc, Zc = { + sphere: b, + point: b, + lineStart: xr, + lineEnd: b, + polygonStart: b, + polygonEnd: b + }, + Vc = br(function(n) { + return Math.sqrt(2 / (1 + n)) + }, function(n) { + return 2 * Math.asin(n / 2) + }); + (ta.geo.azimuthalEqualArea = function() { + return ur(Vc) + }).raw = Vc; + var Xc = br(function(n) { + var t = Math.acos(n); + return t && t / Math.sin(t) + }, y); + (ta.geo.azimuthalEquidistant = function() { + return ur(Xc) + }).raw = Xc, (ta.geo.conicConformal = function() { + return Ye(_r) + }).raw = _r, (ta.geo.conicEquidistant = function() { + return Ye(wr) + }).raw = wr; + var $c = br(function(n) { + return 1 / n + }, Math.atan); + (ta.geo.gnomonic = function() { + return ur($c) + }).raw = $c, Sr.invert = function(n, t) { + return [n, 2 * Math.atan(Math.exp(t)) - Ra] + }, (ta.geo.mercator = function() { + return kr(Sr) + }).raw = Sr; + var Bc = br(function() { + return 1 + }, Math.asin); + (ta.geo.orthographic = function() { + return ur(Bc) + }).raw = Bc; + var Wc = br(function(n) { + return 1 / (1 + n) + }, function(n) { + return 2 * Math.atan(n) + }); + (ta.geo.stereographic = function() { + return ur(Wc) + }).raw = Wc, Er.invert = function(n, t) { + return [-t, 2 * Math.atan(Math.exp(n)) - Ra] + }, (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 = Et(e), + i = Et(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 < s.length - h; ++t) g.push(n[a[s[t]][2]]); + return g + } + var e = Ar, + r = Nr; + return arguments.length ? t(n) : (t.x = function(n) { + return arguments.length ? (e = n, t) : e + }, t.y = function(n) { + return arguments.length ? (r = n, t) : r + }, t) + }, ta.geom.polygon = function(n) { + return ya(n, Jc), n + }; + var Jc = ta.geom.polygon.prototype = []; + Jc.area = function() { + for (var n, t = -1, e = this.length, r = this[e - 1], u = 0; ++t < e;) n = r, r = this[t], u += n[1] * r[0] - n[0] * r[1]; + return .5 * u + }, Jc.centroid = function(n) { + var t, e, r = -1, + u = this.length, + i = 0, + o = 0, + a = this[u - 1]; + for (arguments.length || (n = -1 / (6 * this.area())); ++r < u;) t = a, a = this[r], e = t[0] * a[1] - a[0] * t[1], i += (t[0] + a[0]) * e, o += (t[1] + a[1]) * e; + return [i * n, o * n] + }, Jc.clip = function(n) { + for (var t, e, r, u, i, o, a = Tr(n), c = -1, l = this.length - Tr(this), s = this[l - 1]; ++c < l;) { + for (t = n.slice(), n.length = 0, u = this[c], i = t[(r = t.length - a) - 1], e = -1; ++e < r;) o = t[e], qr(o, s, u) ? (qr(i, s, u) || n.push(Lr(i, o, s, u)), n.push(o)) : qr(i, s, u) && n.push(Lr(i, o, s, u)), i = o; + a && n.push(n[0]), s = u + } + return n + }; + var Gc, Kc, Qc, nl, tl, el = [], + rl = []; + Or.prototype.prepare = function() { + for (var n, t = this.edges, e = t.length; e--;) n = t[e].edge, n.b && n.a || t.splice(e, 1); + return t.sort(Yr), t.length + }, Qr.prototype = { + start: function() { + return this.edge.l === this.site ? this.edge.a : this.edge.b + }, + end: function() { + return this.edge.l === this.site ? this.edge.b : this.edge.a + } + }, nu.prototype = { + insert: function(n, t) { + var e, r, u; + if (n) { + if (t.P = n, t.N = n.N, n.N && (n.N.P = t), n.N = t, n.R) { + for (n = n.R; n.L;) n = n.L; + n.L = t + } else n.R = t; + e = n + } else this._ ? (n = uu(this._), t.P = null, t.N = n, n.P = n.L = t, e = n) : (t.P = t.N = null, this._ = t, e = null); + for (t.L = t.R = null, t.U = e, t.C = !0, n = t; e && e.C;) r = e.U, e === r.L ? (u = r.R, u && u.C ? (e.C = u.C = !1, r.C = !0, n = r) : (n === e.R && (eu(this, e), n = e, e = n.U), e.C = !1, r.C = !0, ru(this, r))) : (u = r.L, u && u.C ? (e.C = u.C = !1, r.C = !0, n = r) : (n === e.L && (ru(this, e), n = e, e = n.U), e.C = !1, r.C = !0, eu(this, r))), e = n.U; + this._.C = !1 + }, + remove: function(n) { + n.N && (n.N.P = n.P), n.P && (n.P.N = n.N), n.N = n.P = null; + var t, e, r, u = n.U, + i = n.L, + o = n.R; + if (e = i ? o ? uu(o) : i : o, u ? u.L === n ? u.L = e : u.R = e : this._ = e, i && o ? (r = e.C, e.C = n.C, e.L = i, i.U = e, e !== o ? (u = e.U, e.U = n.U, n = e.R, u.L = n, e.R = o, o.U = e) : (e.U = u, u = e, n = e.R)) : (r = n.C, n = e), n && (n.U = u), !r) { + if (n && n.C) return void(n.C = !1); + do { + if (n === this._) break; + if (n === u.L) { + if (t = u.R, t.C && (t.C = !1, u.C = !0, eu(this, u), t = u.R), t.L && t.L.C || t.R && t.R.C) { + t.R && t.R.C || (t.L.C = !1, t.C = !0, ru(this, t), t = u.R), t.C = u.C, u.C = t.R.C = !1, eu(this, u), n = this._; + break + } + } else if (t = u.L, t.C && (t.C = !1, u.C = !0, ru(this, u), t = u.L), t.L && t.L.C || t.R && t.R.C) { + t.L && t.L.C || (t.R.C = !1, t.C = !0, eu(this, t), t = u.L), t.C = u.C, u.C = t.L.C = !1, ru(this, u), n = this._; + break + } + t.C = !0, n = u, u = u.U + } while (!n.C); + n && (n.C = !1) + } + } + }, ta.geom.voronoi = function(n) { + function t(n) { + var t = new Array(n.length), + r = a[0][0], + u = a[0][1], + i = a[1][0], + o = a[1][1]; + return iu(e(n), a).cells.forEach(function(e, a) { + var c = e.edges, + l = e.site, + s = t[a] = c.length ? c.map(function(n) { + var t = n.start(); + return [t.x, t.y] + }) : l.x >= 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) / Ca) * Ca, + y: Math.round(o(n, t) / Ca) * Ca, + i: t + } + }) + } + var r = Ar, + u = Nr, + i = r, + o = u, + a = ul; + 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(Yr), c = -1, l = a.length, s = a[l - 1].edge, f = s.l === o ? s.r : s.l; ++c < l;) u = s, i = f, s = a[c].edge, f = s.l === o ? s.r : s.l, r < i.i && r < f.i && au(o, i, f) < 0 && t.push([n[r], n[i.i], n[f.i]]) + }), t + }, t.x = function(n) { + return arguments.length ? (i = Et(r = n), t) : r + }, t.y = function(n) { + return arguments.length ? (o = Et(u = n), t) : u + }, t.clipExtent = function(n) { + return arguments.length ? (a = null == n ? ul : n, t) : a === ul ? null : a + }, t.size = function(n) { + return arguments.length ? t.clipExtent(n && [ + [0, 0], n + ]) : a === ul ? null : a && a[1] + }, t) + }; + var ul = [ + [-1e6, -1e6], + [1e6, 1e6] + ]; + ta.geom.delaunay = function(n) { + return ta.geom.voronoi().triangles(n) + }, ta.geom.quadtree = function(n, t, e, r, u) { + function i(n) { + function i(n, t, e, r, u, i, o, a) { + if (!isNaN(e) && !isNaN(r)) + if (n.leaf) { + var c = n.x, + s = n.y; + if (null != c) + if (ga(c - e) + ga(s - r) < .01) l(n, t, e, r, u, i, o, a); + else { + var f = n.point; + n.x = n.y = n.point = null, l(n, f, c, s, u, i, o, a), l(n, t, e, r, u, i, o, a) + } + else n.x = e, n.y = r, n.point = t + } else l(n, t, e, r, u, i, o, a) + } + + function l(n, t, e, r, u, o, a, c) { + var l = .5 * (u + a), + s = .5 * (o + c), + f = e >= 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 = Et(a), + x = Et(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.x < v && (v = s.x), s.y < d && (d = s.y), s.x > m && (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 < p;) i(k, n[g], f[g], h[g], v, d, m, y); + --g + } else n.forEach(k.add); + return f = h = n = s = null, k + } + var o, a = Ar, + c = Nr; + return (o = arguments.length) ? (a = cu, c = lu, 3 === o && (u = e, r = t, e = t = 0), i(n)) : (i.x = function(n) { + return arguments.length ? (a = n, i) : a + }, i.y = function(n) { + return arguments.length ? (c = n, i) : c + }, i.extent = function(n) { + return arguments.length ? (null == n ? t = e = r = u = null : (t = +n[0][0], e = +n[0][1], r = +n[1][0], u = +n[1][1]), i) : null == t ? null : [ + [t, e], + [r, u] + ] + }, i.size = function(n) { + return arguments.length ? (null == n ? t = e = r = u = null : (t = e = 0, r = +n[0], u = +n[1]), i) : null == t ? null : [r - t, u - e] + }, i) + }, ta.interpolateRgb = gu, ta.interpolateObject = pu, ta.interpolateNumber = vu, ta.interpolateString = du; + var il = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, + ol = new RegExp(il.source, "g"); + ta.interpolate = mu, ta.interpolators = [function(n, t) { + var e = typeof t; + return ("string" === e ? Ga.has(t) || /^(#|rgb\(|hsl\()/.test(t) ? gu : du : t instanceof ot ? gu : Array.isArray(t) ? yu : "object" === e && isNaN(t) ? pu : vu)(n, t) + }], ta.interpolateArray = yu; + var al = function() { + return y + }, + cl = ta.map({ + linear: al, + poly: ku, + quad: function() { + return _u + }, + cubic: function() { + return wu + }, + sin: function() { + return Eu + }, + exp: function() { + return Au + }, + circle: function() { + return Nu + }, + elastic: Cu, + back: zu, + bounce: function() { + return qu + } + }), + ll = ta.map({ + "in": y, + out: xu, + "in-out": bu, + "out-in": function(n) { + return bu(xu(n)) + } + }); + ta.ease = function(n) { + var t = n.indexOf("-"), + e = t >= 0 ? n.slice(0, t) : n, + r = t >= 0 ? n.slice(t + 1) : "in"; + return e = cl.get(e) || al, r = ll.get(r) || y, 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 : sl) + })(n) + }, Pu.prototype.toString = function() { + return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")" + }; + var sl = { + 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; ++e < r;) t.push(Yu(n[e])); + return t + } + }, ta.layout.chord = function() { + function n() { + var n, l, f, h, g, p = {}, + v = [], + d = ta.range(i), + m = []; + for (e = [], r = [], n = 0, h = -1; ++h < i;) { + for (l = 0, g = -1; ++g < i;) l += u[h][g]; + v.push(l), m.push(ta.range(i)), n += l + } + for (o && d.sort(function(n, t) { + return o(v[n], v[t]) + }), a && m.forEach(function(n, t) { + n.sort(function(n, e) { + return a(u[t][n], u[t][e]) + }) + }), n = (La - s * i) / n, l = 0, h = -1; ++h < i;) { + for (f = l, g = -1; ++g < i;) { + var y = d[h], + M = m[y][g], + x = u[y][M], + b = l, + _ = l += x * n; + p[y + "-" + M] = { + index: y, + subindex: M, + startAngle: b, + endAngle: _, + value: x + } + } + r[y] = { + index: y, + startAngle: f, + endAngle: l, + value: (l - f) / n + }, l += s + } + for (h = -1; ++h < i;) + for (g = h - 1; ++g < i;) { + var w = p[h + "-" + g], + S = p[g + "-" + h]; + (w.value || S.value) && e.push(w.value < S.value ? { + source: S, + target: w + } : { + source: w, + target: S + }) + } + c && t() + } + + function t() { + e.sort(function(n, t) { + return c((n.source.value + n.target.value) / 2, (t.source.value + t.target.value) / 2) + }) + } + var e, r, u, i, o, a, c, l = {}, + s = 0; + return l.matrix = function(n) { + return arguments.length ? (i = (u = n) && u.length, e = r = null, l) : u + }, l.padding = function(n) { + return arguments.length ? (s = n, e = r = null, l) : s + }, l.sortGroups = function(n) { + return arguments.length ? (o = n, e = r = null, l) : o + }, l.sortSubgroups = function(n) { + return arguments.length ? (a = n, e = null, l) : a + }, l.sortChords = function(n) { + return arguments.length ? (c = n, e && t(), l) : c + }, l.chords = function() { + return e || n(), e + }, l.groups = function() { + return r || n(), r + }, l + }, ta.layout.force = function() { + function n(n) { + return function(t, e, r, u) { + if (t.point !== n) { + var i = t.cx - n.x, + o = t.cy - n.y, + a = u - e, + c = i * i + o * o; + if (c > a * 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 = fl, + h = hl, + g = -30, + p = gl, + v = .1, + d = .64, + m = [], + M = []; + 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, y, x, b = m.length, + _ = M.length; + for (e = 0; _ > e; ++e) a = M[e], f = a.source, h = a.target, y = h.x - f.x, x = h.y - f.y, (p = y * y + x * x) && (p = r * i[e] * ((p = Math.sqrt(p)) - u[e]) / p, y *= p, x *= p, h.x -= y * (d = f.weight / (h.weight + f.weight)), h.y -= x * d, f.x += y * (d = 1 - d), f.y += x * d); + if ((d = r * v) && (y = l[0] / 2, x = l[1] / 2, e = -1, d)) + for (; ++e < b;) a = m[e], a.x += (y - a.x) * d, a.y += (x - a.y) * d; + if (g) + for (Ju(t = ta.geom.quadtree(m), r, o), e = -1; ++e < b;)(a = m[e]).fixed || t.visit(n(a)); + for (e = -1; ++e < b;) a = m[e], a.fixed ? (a.x = a.px, a.y = a.py) : (a.x -= (a.px - (a.px = a.x)) * s, a.y -= (a.py - (a.py = a.y)) * s); + c.tick({ + type: "tick", + alpha: r + }) + }, a.nodes = function(n) { + return arguments.length ? (m = n, a) : m + }, a.links = function(n) { + return arguments.length ? (M = n, a) : M + }, a.size = function(n) { + return arguments.length ? (l = n, a) : l + }, a.linkDistance = function(n) { + return arguments.length ? (f = "function" == typeof n ? n : +n, a) : f + }, a.distance = a.linkDistance, a.linkStrength = function(n) { + return arguments.length ? (h = "function" == typeof n ? n : +n, a) : h + }, a.friction = function(n) { + return arguments.length ? (s = +n, a) : s + }, a.charge = function(n) { + return arguments.length ? (g = "function" == typeof n ? n : +n, a) : g + }, a.chargeDistance = function(n) { + return arguments.length ? (p = n * n, a) : Math.sqrt(p) + }, a.gravity = function(n) { + return arguments.length ? (v = +n, a) : v + }, a.theta = function(n) { + return arguments.length ? (d = n * n, a) : Math.sqrt(d) + }, a.alpha = function(n) { + return arguments.length ? (n = +n, r ? r = n > 0 ? 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; s > a; ++a) { + var u = M[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; ++a < l;) + if (!isNaN(i = o[a][n])) return i; + return Math.random() * r + } + var t, e, r, c = m.length, + s = M.length, + p = l[0], + v = l[1]; + for (t = 0; c > t; ++t)(r = m[t]).index = t, r.weight = 0; + for (t = 0; s > t; ++t) r = M[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, M[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, M[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(y).on("dragstart.force", Xu).on("drag.force", t).on("dragend.force", $u)), arguments.length ? void this.on("mouseover.force", Bu).on("mouseout.force", Wu).call(e) : e + }, ta.rebind(a, c, "on") + }; + var fl = 20, + hl = 1, + gl = 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; ++l < o;) n(a = i[l], e, c = a.value * r, u), e += c + } + } + + function t(n) { + var e = n.children, + r = 0; + if (e && (u = e.length)) + for (var u, i = -1; ++i < u;) r = Math.max(r, t(e[i])); + return 1 + r + } + + function e(e, i) { + var o = r.call(this, e, i); + return n(o[0], 0, u[0], u[1] / t(o[0])), o + } + var r = ta.layout.hierarchy(), + u = [1, 1]; + return e.size = function(n) { + return arguments.length ? (u = n, e) : u + }, Gu(e, r) + }, ta.layout.pie = function() { + function n(o) { + var a, c = o.length, + l = o.map(function(e, r) { + return +t.call(n, e, r) + }), + s = +("function" == typeof r ? r.apply(this, arguments) : r), + f = ("function" == typeof u ? u.apply(this, arguments) : u) - s, + h = Math.min(Math.abs(f) / c, +("function" == typeof i ? i.apply(this, arguments) : i)), + g = h * (0 > f ? -1 : 1), + p = (f - c * g) / ta.sum(l), + v = ta.range(c), + d = []; + return null != e && v.sort(e === pl ? 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 = pl, + r = 0, + u = La, + 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 pl = {}; + 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 = y, + 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 : vl.get(t) || ai, n) : e + }, n.offset = function(t) { + return arguments.length ? (r = "function" == typeof t ? t : dl.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 vl = 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 + }), + dl = 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; ++i < g;) o = c[i] = [], o.dx = f[i + 1] - (o.x = f[i]), o.y = 0; + if (g > 0) + for (i = -1; ++i < h;) a = l[i], a >= 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 = Et(t), n) : r + }, n.bins = function(t) { + return arguments.length ? (u = "number" == typeof t ? function(n) { + return gi(n, t) + } : Et(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.x < g.x && (g = n), n.x > p.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; ++u < i;) r = (e = n[u]).value * (0 > t ? 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; ++o < a;)(e = n[o].area) && (i > e && (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); ++i < o;) u = n[i], u.x = a, u.y = l, u.dy = s, a += u.dx = Math.min(e.x + e.dx - a, s ? c(u.area / s) : 0); + u.z = !0, u.dx += e.x + e.dx - a, e.y += s, e.dy -= s + } else { + for ((r || s > e.dx) && (s = e.dx); ++i < o;) u = n[i], u.x = a, u.y = l, u.dx = s, l += u.dy = Math.min(e.y + e.dy - l, s ? c(u.area / s) : 0); + u.z = !1, u.dy += e.y + e.dy - l, e.x += s, e.dx -= s + } + } + + function i(r) { + var u = o || a(r), + i = u[0]; + return i.x = 0, i.y = 0, i.dx = l[0], i.dy = l[1], o && a.revalue(i), n([i], i.dx * i.dy / i.value), (o ? e : t)(i), h && (o = u), u + } + var o, a = ta.layout.hierarchy(), + c = Math.round, + l = [1, 1], + s = null, + f = Ri, + h = !1, + g = "squarify", + p = .5 * (1 + Math.sqrt(5)); + return i.size = function(n) { + return arguments.length ? (l = n, i) : l + }, i.padding = function(n) { + function t(t) { + var e = n.call(i, t, t.depth); + return null == e ? Ri(t) : Di(t, "number" == typeof e ? [e, e, e, e] : e) + } + + function e(t) { + return Di(t, n) + } + if (!arguments.length) return s; + var r; + return f = null == (s = n) ? Ri : "function" == (r = typeof n) ? t : "number" === r ? (n = [n, n, n, n], e) : e, i + }, i.round = function(n) { + return arguments.length ? (c = n ? Math.round : Number, i) : c != Number + }, i.sticky = function(n) { + return arguments.length ? (h = n, o = null, i) : h + }, i.ratio = function(n) { + return arguments.length ? (p = n, i) : p + }, i.mode = function(n) { + return arguments.length ? (g = n + "", i) : g + }, Gu(i, a) + }, ta.random = { + normal: function(n, t) { + var e = arguments.length; + return 2 > e && (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 ml = { + floor: y, + ceil: y + }; + ta.scale.linear = function() { + return Ii([0, 1], [0, 1], mu, !1) + }; + var yl = { + 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 Ml = ta.format(".0e"), + xl = { + 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(bl) + }, ta.scale.category20 = function() { + return ta.scale.ordinal().range(_l) + }, ta.scale.category20b = function() { + return ta.scale.ordinal().range(wl) + }, ta.scale.category20c = function() { + return ta.scale.ordinal().range(Sl) + }; + var bl = [2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175].map(Mt), + _l = [2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725].map(Mt), + wl = [3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654].map(Mt), + Sl = [3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081].map(Mt); + 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) - Ra, + f = a.apply(this, arguments) - Ra, + h = Math.abs(f - s), + g = s > f ? 0 : 1; + if (n > l && (p = l, l = n, n = p), h >= Ta) 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 === kl ? Math.sqrt(n * n + l * l) : +i.apply(this, arguments), g || (A *= -1), l && (A = tt(d / l * Math.sin(m))), n && (E = tt(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) <= qa ? 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) <= qa ? 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), + I = 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], I[1][0], I[1][1]), ",", g, " ", I[1], "A", H, ",", H, " 0 0,", v, " ", I[0]) : N.push("M", O[0], "A", H, ",", H, " 0 1,", v, " ", I[0]) + } else N.push("M", y, ",", M); + if (null != S) { + var Y = Math.min(p, (n - F) / (j - 1)), + Z = fo([y, M], [S, k], n, -Y, g), + V = fo([_, w], null == x ? [y, M] : [x, b], n, -Y, g); + p === Y ? N.push("L", V[0], "A", Y, ",", Y, " 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", Y, ",", Y, " 0 0,", v, " ", Z[0]) : N.push("L", V[0], "A", Y, ",", Y, " 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 = kl, + o = ao, + a = co, + c = lo; + return n.innerRadius = function(t) { + return arguments.length ? (e = Et(t), n) : e + }, n.outerRadius = function(t) { + return arguments.length ? (r = Et(t), n) : r + }, n.cornerRadius = function(t) { + return arguments.length ? (u = Et(t), n) : u + }, n.padRadius = function(t) { + return arguments.length ? (i = t == kl ? kl : Et(t), n) : i + }, n.startAngle = function(t) { + return arguments.length ? (o = Et(t), n) : o + }, n.endAngle = function(t) { + return arguments.length ? (a = Et(t), n) : a + }, n.padAngle = function(t) { + return arguments.length ? (c = Et(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 - Ra; + return [Math.cos(t) * n, Math.sin(t) * n] + }, n + }; + var kl = "auto"; + ta.svg.line = function() { + return ho(y) + }; + var El = 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 + }); + El.forEach(function(n, t) { + t.key = n, t.closed = /-closed$/.test(n) + }); + var Al = [0, 2 / 3, 1 / 3, 0], + Nl = [0, 1 / 3, 2 / 3, 0], + Cl = [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(y) + }, 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) - Ra, + s = l.call(n, u, r) - Ra; + 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 > qa) + ",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 = Et(t), n) : a + }, n.source = function(t) { + return arguments.length ? (i = Et(t), n) : i + }, n.target = function(t) { + return arguments.length ? (o = Et(t), n) : o + }, n.startAngle = function(t) { + return arguments.length ? (c = Et(t), n) : c + }, n.endAngle = function(t) { + return arguments.length ? (l = Et(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 = Et(e), n) : t + }, n.target = function(t) { + return arguments.length ? (e = Et(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 (zl.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 = Et(e), n) : t + }, n.size = function(t) { + return arguments.length ? (e = Et(t), n) : e + }, n + }; + var zl = 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 * Ll)), + e = t * Ll; + return "M0," + -t + "L" + e + ",0 0," + t + " " + -e + ",0Z" + }, + 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 / ql), + e = t * ql / 2; + return "M0," + e + "L" + t + "," + -e + " " + -t + "," + -e + "Z" + }, + "triangle-up": function(n) { + var t = Math.sqrt(n / ql), + e = t * ql / 2; + return "M0," + -e + "L" + t + "," + e + " " + -t + "," + e + "Z" + } + }); + ta.svg.symbolTypes = zl.keys(); + var ql = Math.sqrt(3), + Ll = Math.tan(30 * Da); + _a.transition = function(n) { + for (var t, e, r = Tl || ++Ul, u = Xo(n), i = [], o = Rl || { + time: Date.now(), + ease: Su, + delay: 0, + duration: 250 + }, a = -1, c = this.length; ++a < c;) { + i.push(t = []); + for (var l = this[a], s = -1, f = l.length; ++s < f;)(e = l[s]) && $o(e, s, u, r, o), t.push(e) + } + return Yo(i, u, r) + }, _a.interrupt = function(n) { + return this.each(null == n ? Dl : Io(Xo(n))) + }; + var Tl, Rl, Dl = Io(Xo()), + Pl = [], + Ul = 0; + Pl.call = _a.call, Pl.empty = _a.empty, Pl.node = _a.node, Pl.size = _a.size, ta.transition = function(n, t) { + return n && n.transition ? Tl ? n.transition(t) : n : ta.selection().transition(n) + }, ta.transition.prototype = Pl, Pl.select = function(n) { + var t, e, r, u = this.id, + i = this.namespace, + o = []; + n = N(n); + for (var a = -1, c = this.length; ++a < c;) { + o.push(t = []); + for (var l = this[a], s = -1, f = l.length; ++s < f;)(r = l[s]) && (e = n.call(r, r.__data__, s, a)) ? ("__data__" in r && (e.__data__ = r.__data__), $o(e, s, i, u, r[i][u]), t.push(e)) : t.push(null) + } + return Yo(o, i, u) + }, Pl.selectAll = function(n) { + var t, e, r, u, i, o = this.id, + a = this.namespace, + c = []; + n = C(n); + for (var l = -1, s = this.length; ++l < s;) + for (var f = this[l], h = -1, g = f.length; ++h < g;) + if (r = f[h]) { + i = r[a][o], e = n.call(r, r.__data__, h, l), c.push(t = []); + for (var p = -1, v = e.length; ++p < v;)(u = e[p]) && $o(u, p, a, o, i), t.push(u) + } return Yo(c, a, o) + }, Pl.filter = function(n) { + var t, e, r, u = []; + "function" != typeof n && (n = O(n)); + for (var i = 0, o = this.length; o > i; 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 Yo(u, this.namespace, this.id) + }, Pl.tween = function(n, t) { + var e = this.id, + r = this.namespace; + return arguments.length < 2 ? this.node()[r][e].tween.get(n) : Y(this, null == t ? function(t) { + t[r][e].tween.remove(n) + } : function(u) { + u[r][e].tween.set(n, t) + }) + }, Pl.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) + }, Pl.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) + }, Pl.style = function(n, e, r) { + function u() { + this.style.removeProperty(n) + } + + function i(e) { + return null == e ? u : (e += "", function() { + var u, i = t(this).getComputedStyle(this, null).getPropertyValue(n); + return i !== e && (u = mu(i, e), function(t) { + this.style.setProperty(n, u(t), r) + }) + }) + } + var o = arguments.length; + if (3 > o) { + if ("string" != typeof n) { + 2 > o && (e = ""); + for (r in n) this.style(r, n[r], e); + return this + } + r = "" + } + return Zo(this, "style." + n, e, i) + }, Pl.styleTween = function(n, e, r) { + function u(u, i) { + var o = e.call(this, u, i, t(this).getComputedStyle(this, null).getPropertyValue(n)); + return o && function(t) { + this.style.setProperty(n, o(t), r) + } + } + return arguments.length < 3 && (r = ""), this.tween("style." + n, u) + }, Pl.text = function(n) { + return Zo(this, "text", n, Vo) + }, Pl.remove = function() { + var n = this.namespace; + return this.each("end.transition", function() { + var t; + this[n].count < 2 && (t = this.parentNode) && t.removeChild(this) + }) + }, Pl.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)), Y(this, function(r) { + r[e][t].ease = n + })) + }, Pl.delay = function(n) { + var t = this.id, + e = this.namespace; + return arguments.length < 1 ? this.node()[e][t].delay : Y(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 + })) + }, Pl.duration = function(n) { + var t = this.id, + e = this.namespace; + return arguments.length < 1 ? this.node()[e][t].duration : Y(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 + })) + }, Pl.each = function(n, t) { + var e = this.id, + r = this.namespace; + if (arguments.length < 2) { + var u = Rl, + i = Tl; + try { + Tl = e, Y(this, function(t, u, i) { + Rl = t[r][e], n.call(t, t.__data__, u, i) + }) + } finally { + Rl = u, Tl = i + } + } else Y(this, function(u) { + var i = u[r][e]; + (i.event || (i.event = ta.dispatch("start", "end", "interrupt"))).on(n, t) + }); + return this + }, Pl.transition = function() { + for (var n, t, e, r, u = this.id, i = ++Ul, 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 Yo(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) : y : t, + p = l.selectAll(".tick").data(h, f), + v = p.enter().insert("g", ".domain").attr("class", "tick").style("opacity", Ca), + d = ta.transition(p.exit()).style("opacity", Ca).remove(), + m = ta.transition(p.order()).style("opacity", 1), + M = Math.max(u, 0) + o, + x = Ui(f), + b = l.selectAll(".domain").data([0]), + _ = (b.enter().append("path").attr("class", "domain"), ta.transition(b)); + v.append("line"), v.append("text"); + var w, S, k, E, A = v.select("line"), + N = m.select("line"), + C = p.select("text").text(g), + z = v.select("text"), + q = m.select("text"), + L = "top" === r || "left" === r ? -1 : 1; + if ("bottom" === r || "top" === r ? (n = Bo, w = "x", k = "y", S = "x2", E = "y2", C.attr("dy", 0 > L ? "0em" : ".71em").style("text-anchor", "middle"), _.attr("d", "M" + x[0] + "," + L * i + "V0H" + x[1] + "V" + L * i)) : (n = Wo, w = "y", k = "x", S = "y2", E = "x2", C.attr("dy", ".32em").style("text-anchor", 0 > L ? "end" : "start"), _.attr("d", "M" + L * i + "," + x[0] + "H0V" + x[1] + "H" + L * i)), A.attr(E, L * u), z.attr(k, L * M), N.attr(S, 0).attr(E, L * u), q.attr(w, 0).attr(k, L * M), f.rangeBand) { + var T = f, + R = T.rangeBand() / 2; + s = f = function(n) { + return T(n) + R + } + } 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 = jl, + 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 Fl ? t + "" : jl, 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 jl = "bottom", + Fl = { + top: 1, + right: 1, + bottom: 1, + left: 1 + }; + ta.svg.brush = function() { + function n(t) { + t.each(function() { + var t = ta.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", i).on("touchstart.brush", i), + o = t.selectAll(".background").data([0]); + o.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"), t.selectAll(".extent").data([0]).enter().append("rect").attr("class", "extent").style("cursor", "move"); + var a = t.selectAll(".resize").data(v, y); + a.exit().remove(), a.enter().append("g").attr("class", function(n) { + return "resize " + n + }).style("cursor", function(n) { + return Hl[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 c, f = ta.transition(t), + h = ta.transition(o); + l && (c = Ui(l), h.attr("x", c[0]).attr("width", c[1] - c[0]), r(f)), s && (c = Ui(s), h.attr("y", c[0]).attr("height", c[1] - c[0]), u(f)), e(f) + }) + } + + function e(n) { + n.selectAll(".resize").attr("transform", function(n) { + return "translate(" + f[+/e$/.test(n)] + "," + h[+/^s/.test(n)] + ")" + }) + } + + function r(n) { + n.select(".extent").attr("x", f[0]), n.selectAll(".extent,.n>rect,.s>rect").attr("width", f[1] - f[0]) + } + + function u(n) { + n.select(".extent").attr("y", h[0]), n.selectAll(".extent,.e>rect,.w>rect").attr("height", h[1] - h[0]) + } + + function i() { + function i() { + 32 == ta.event.keyCode && (C || (M = null, q[0] -= f[1], q[1] -= h[1], C = 2), S()) + } + + function v() { + 32 == ta.event.keyCode && 2 == C && (q[0] += f[1], q[1] += h[1], C = 0, S()) + } + + function d() { + var n = ta.mouse(b), + t = !1; + x && (n[0] += x[0], n[1] += x[1]), C || (ta.event.altKey ? (M || (M = [(f[0] + f[1]) / 2, (h[0] + h[1]) / 2]), q[0] = f[+(n[0] < M[0])], q[1] = h[+(n[1] < M[1])]) : M = null), A && m(n, l, 0) && (r(k), t = !0), N && m(n, s, 1) && (u(k), t = !0), t && (e(k), w({ + type: "brush", + mode: C ? "move" : "resize" + })) + } + + function m(n, t, e) { + var r, u, i = Ui(t), + c = i[0], + l = i[1], + s = q[e], + v = e ? h : f, + d = v[1] - v[0]; + return C && (c -= s, l -= d + s), r = (e ? p : g) ? Math.max(c, Math.min(l, n[e])) : n[e], C ? u = (r += s) + d : (M && (s = Math.max(c, Math.min(l, 2 * M[e] - r))), r > s ? (u = r, r = s) : u = s), v[0] != r || v[1] != u ? (e ? a = null : o = null, v[0] = r, v[1] = u, !0) : void 0 + } + + function y() { + d(), k.style("pointer-events", "all").selectAll(".resize").style("display", n.empty() ? "none" : null), ta.select("body").style("cursor", null), L.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null), z(), w({ + type: "brushend" + }) + } + var M, x, b = this, + _ = ta.select(ta.event.target), + w = c.of(b, arguments), + k = ta.select(b), + E = _.datum(), + A = !/^(n|s)$/.test(E) && l, + N = !/^(e|w)$/.test(E) && s, + C = _.classed("extent"), + z = W(b), + q = ta.mouse(b), + L = ta.select(t(b)).on("keydown.brush", i).on("keyup.brush", v); + if (ta.event.changedTouches ? L.on("touchmove.brush", d).on("touchend.brush", y) : L.on("mousemove.brush", d).on("mouseup.brush", y), k.interrupt().selectAll("*").interrupt(), C) q[0] = f[0] - q[0], q[1] = h[0] - q[1]; + else if (E) { + var T = +/w$/.test(E), + R = +/^n/.test(E); + x = [f[1 - T] - q[0], h[1 - R] - q[1]], q[0] = f[T], q[1] = h[R] + } else ta.event.altKey && (M = q.slice()); + k.style("pointer-events", "none").selectAll(".resize").style("display", null), ta.select("body").style("cursor", _.style("cursor")), w({ + type: "brushstart" + }), d() + } + var o, a, c = E(n, "brushstart", "brush", "brushend"), + l = null, + s = null, + f = [0, 0], + h = [0, 0], + g = !0, + p = !0, + v = Ol[0]; + return n.event = function(n) { + n.each(function() { + var n = c.of(this, arguments), + t = { + x: f, + y: h, + i: o, + j: a + }, + e = this.__chart__ || t; + this.__chart__ = t, Tl ? ta.select(this).transition().each("start.brush", function() { + o = e.i, a = e.j, f = e.x, h = e.y, n({ + type: "brushstart" + }) + }).tween("brush:brush", function() { + var e = yu(f, t.x), + r = yu(h, t.y); + return o = a = null, + function(u) { + f = t.x = e(u), h = t.y = r(u), n({ + type: "brush", + mode: "resize" + }) + } + }).each("end.brush", function() { + o = t.i, a = 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 ? (l = t, v = Ol[!l << 1 | !s], n) : l + }, n.y = function(t) { + return arguments.length ? (s = t, v = Ol[!l << 1 | !s], n) : s + }, n.clamp = function(t) { + return arguments.length ? (l && s ? (g = !!t[0], p = !!t[1]) : l ? g = !!t : s && (p = !!t), n) : l && s ? [g, p] : l ? g : s ? p : null + }, n.extent = function(t) { + var e, r, u, i, c; + return arguments.length ? (l && (e = t[0], r = t[1], s && (e = e[0], r = r[0]), o = [e, r], l.invert && (e = l(e), r = l(r)), e > r && (c = e, e = r, r = c), (e != f[0] || r != f[1]) && (f = [e, r])), s && (u = t[0], i = t[1], l && (u = u[1], i = i[1]), a = [u, i], s.invert && (u = s(u), i = s(i)), u > i && (c = u, u = i, i = c), (u != h[0] || i != h[1]) && (h = [u, i])), n) : (l && (o ? (e = o[0], r = o[1]) : (e = f[0], r = f[1], l.invert && (e = l.invert(e), r = l.invert(r)), e > r && (c = e, e = r, r = c))), s && (a ? (u = a[0], i = a[1]) : (u = h[0], i = h[1], s.invert && (u = s.invert(u), i = s.invert(i)), u > i && (c = u, u = i, i = c))), l && s ? [ + [e, u], + [r, i] + ] : l ? [e, r] : s && [u, i]) + }, n.clear = function() { + return n.empty() || (f = [0, 0], h = [0, 0], o = a = null), n + }, n.empty = function() { + return !!l && f[0] == f[1] || !!s && h[0] == h[1] + }, ta.rebind(n, c, "on") + }; + var Hl = { + n: "ns-resize", + e: "ew-resize", + s: "ns-resize", + w: "ew-resize", + nw: "nwse-resize", + ne: "nesw-resize", + se: "nwse-resize", + sw: "nesw-resize" + }, + Ol = [ + ["n", "e", "s", "w", "nw", "ne", "se", "sw"], + ["e", "w"], + ["n", "s"], + [] + ], + Il = ac.format = gc.timeFormat, + Yl = Il.utc, + Zl = Yl("%Y-%m-%dT%H:%M:%S.%LZ"); + Il.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? Jo : Zl, Jo.parse = function(n) { + var t = new Date(n); + return isNaN(t) ? null : t + }, Jo.toString = Zl.toString, ac.second = Ft(function(n) { + return new cc(1e3 * Math.floor(n / 1e3)) + }, function(n, t) { + n.setTime(n.getTime() + 1e3 * Math.floor(t)) + }, function(n) { + return n.getSeconds() + }), ac.seconds = ac.second.range, ac.seconds.utc = ac.second.utc.range, ac.minute = Ft(function(n) { + return new cc(6e4 * Math.floor(n / 6e4)) + }, function(n, t) { + n.setTime(n.getTime() + 6e4 * Math.floor(t)) + }, function(n) { + return n.getMinutes() + }), ac.minutes = ac.minute.range, ac.minutes.utc = ac.minute.utc.range, ac.hour = Ft(function(n) { + var t = n.getTimezoneOffset() / 60; + return new cc(36e5 * (Math.floor(n / 36e5 - t) + t)) + }, function(n, t) { + n.setTime(n.getTime() + 36e5 * Math.floor(t)) + }, function(n) { + return n.getHours() + }), ac.hours = ac.hour.range, ac.hours.utc = ac.hour.utc.range, ac.month = Ft(function(n) { + return n = ac.day(n), n.setDate(1), n + }, function(n, t) { + n.setMonth(n.getMonth() + t) + }, function(n) { + return n.getMonth() + }), ac.months = ac.month.range, ac.months.utc = ac.month.utc.range; + var Vl = [1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6], + Xl = [ + [ac.second, 1], + [ac.second, 5], + [ac.second, 15], + [ac.second, 30], + [ac.minute, 1], + [ac.minute, 5], + [ac.minute, 15], + [ac.minute, 30], + [ac.hour, 1], + [ac.hour, 3], + [ac.hour, 6], + [ac.hour, 12], + [ac.day, 1], + [ac.day, 2], + [ac.week, 1], + [ac.month, 1], + [ac.month, 3], + [ac.year, 1] + ], + $l = Il.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] + ]), + Bl = { + range: function(n, t, e) { + return ta.range(Math.ceil(n / e) * e, +t, e).map(Ko) + }, + floor: y, + ceil: y + }; + Xl.year = ac.year, ac.scale = function() { + return Go(ta.scale.linear(), Xl, $l) + }; + var Wl = Xl.map(function(n) { + return [n[0].utc, n[1]] + }), + Jl = Yl.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] + ]); + Wl.year = ac.year.utc, ac.scale.utc = function() { + return Go(ta.scale.linear(), Wl, Jl) + }, 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/crm_dashboard/static/src/js/lib/funnel.js b/crm_dashboard/static/src/js/lib/funnel.js new file mode 100644 index 000000000..ccfa100d2 --- /dev/null +++ b/crm_dashboard/static/src/js/lib/funnel.js @@ -0,0 +1,5 @@ +(function(b){typeof module==="object"&&module.exports?module.exports=b:b(Highcharts)})(function(b){var q=b.getOptions(),w=q.plotOptions,r=b.seriesTypes,G=b.merge,E=function(){},B=b.each,F=b.pick;w.funnel=G(w.pie,{animation:!1,center:["50%","50%"],width:"90%",neckWidth:"30%",height:"100%",neckHeight:"25%",reversed:!1,dataLabels:{connectorWidth:1,connectorColor:"#606060"},size:!0,states:{select:{color:"#C0C0C0",borderColor:"#000000",shadow:!1}}});r.funnel=b.extendClass(r.pie,{type:"funnel",animate:E, +translate:function(){var a=function(k,a){return/%$/.test(k)?a*parseInt(k,10)/100:parseInt(k,10)},b=0,f=this.chart,c=this.options,g=c.reversed,l=c.ignoreHiddenPoint,h=f.plotWidth,d=f.plotHeight,q=0,f=c.center,i=a(f[0],h),x=a(f[1],d),r=a(c.width,h),m,s,e=a(c.height,d),t=a(c.neckWidth,h),C=a(c.neckHeight,d),u=x-e/2+e-C,a=this.data,y,z,w=c.dataLabels.position==="left"?1:0,A,n,D,p,j,v,o;this.getWidthAt=s=function(k){var a=x-e/2;return k>u||e===C?t:t+(r-t)*(1-(k-a)/(e-C))};this.getX=function(k,a){return i+ +(a?-1:1)*(s(g?d-k:k)/2+c.dataLabels.distance)};this.center=[i,x,e];this.centerX=i;B(a,function(a){if(!l||a.visible!==!1)b+=a.y});B(a,function(a){o=null;z=b?a.y/b:0;n=x-e/2+q*e;j=n+z*e;m=s(n);A=i-m/2;D=A+m;m=s(j);p=i-m/2;v=p+m;n>u?(A=p=i-t/2,D=v=i+t/2):j>u&&(o=j,m=s(u),p=i-m/2,v=p+m,j=u);g&&(n=e-n,j=e-j,o=o?e-o:null);y=["M",A,n,"L",D,n,v,j];o&&y.push(v,o,p,o);y.push(p,j,"Z");a.shapeType="path";a.shapeArgs={d:y};a.percentage=z*100;a.plotX=i;a.plotY=(n+(o||j))/2;a.tooltipPos=[i,a.plotY];a.slice=E;a.half= +w;if(!l||a.visible!==!1)q+=z})},drawPoints:function(){var a=this,b=a.options,f=a.chart.renderer,c,g,l,h;B(a.data,function(d){c=d.options;h=d.graphic;l=d.shapeArgs;g={fill:d.color,stroke:F(c.borderColor,b.borderColor),"stroke-width":F(c.borderWidth,b.borderWidth)};h?h.attr(g).animate(l):d.graphic=f.path(l).attr(g).add(a.group)})},sortByAngle:function(a){a.sort(function(a,b){return a.plotY-b.plotY})},drawDataLabels:function(){var a=this.data,b=this.options.dataLabels.distance,f,c,g,l=a.length,h,d;for(this.center[2]-= +2*b;l--;)g=a[l],c=(f=g.half)?1:-1,d=g.plotY,h=this.getX(d,f),g.labelPos=[0,d,h+(b-5)*c,d,h+b*c,d,f?"right":"left",0];r.pie.prototype.drawDataLabels.call(this)}});q.plotOptions.pyramid=b.merge(q.plotOptions.funnel,{neckWidth:"0%",neckHeight:"0%",reversed:!0});b.seriesTypes.pyramid=b.extendClass(b.seriesTypes.funnel,{type:"pyramid"})}); diff --git a/crm_dashboard/static/src/js/lib/highcharts.js b/crm_dashboard/static/src/js/lib/highcharts.js new file mode 100644 index 000000000..fc26d2d83 --- /dev/null +++ b/crm_dashboard/static/src/js/lib/highcharts.js @@ -0,0 +1,333 @@ +(function(E,X){typeof module==="object"&&module.exports?module.exports=E.document?X(E):X:E.Highcharts=X(E)})(typeof window!=="undefined"?window:this,function(E){function X(a,b){var c="Highcharts error #"+a+": www.highcharts.com/errors/"+a;if(b)throw Error(c);E.console&&console.log(c)}function pb(a,b,c){this.options=b;this.elem=a;this.prop=c}function D(){var a,b=arguments,c,d={},e=function(a,b){var c,d;typeof a!=="object"&&(a={});for(d in b)b.hasOwnProperty(d)&&(c=b[d],a[d]=c&&typeof c==="object"&& +Object.prototype.toString.call(c)!=="[object Array]"&&d!=="renderTo"&&typeof c.nodeType!=="number"?e(a[d]||{},c):b[d]);return a};b[0]===!0&&(d=b[1],b=Array.prototype.slice.call(b,2));c=b.length;for(a=0;a-1?h.thousandsSep:""))):e=Qa(f,e)}k.push(e);a=a.slice(c+1);c=(d=!d)?"}":"{"}k.push(a);return k.join("")}function rb(a){return W.pow(10,T(W.log(a)/W.LN10))}function sb(a,b,c,d,e){var f,g=a,c=p(c,1);f=a/c;b||(b=[1,2,2.5,5,10],d===!1&&(c===1?b=[1,2,5,10]:c<=0.1&&(b=[1/c])));for(d=0;d=a||!e&&f<=(b[d]+(b[d+1]||b[d]))/ +2)break;g*=c;return g}function ib(a,b){var c=a.length,d,e;for(e=0;ec&&(c=a[b]);return c}function Sa(a,b){for(var c in a)a[c]&&a[c]!==b&&a[c].destroy&&a[c].destroy(),delete a[c]}function Ta(a){jb||(jb=Z(La));a&&jb.appendChild(a);jb.innerHTML=""}function fa(a,b){return parseFloat(a.toPrecision(b|| +14))}function Ua(a,b){b.renderer.globalAnimation=p(a,b.animation)}function Fb(){var a=N.global,b=a.useUTC,c=b?"getUTC":"get",d=b?"setUTC":"set";qa=a.Date||E.Date;qb=b&&a.timezoneOffset;Za=b&&a.getTimezoneOffset;kb=function(a,c,d,h,i,k){var j;b?(j=qa.UTC.apply(0,arguments),j+=Ya(j)):j=(new qa(a,c,p(d,1),p(h,0),p(i,0),p(k,0))).getTime();return j};tb=c+"Minutes";ub=c+"Hours";vb=c+"Day";$a=c+"Date";ab=c+"Month";bb=c+"FullYear";Gb=d+"Milliseconds";Hb=d+"Seconds";Ib=d+"Minutes";Jb=d+"Hours";wb=d+"Date"; +xb=d+"Month";yb=d+"FullYear"}function ia(a){if(!(this instanceof ia))return new ia(a);this.init(a)}function O(){}function Va(a,b,c,d){this.axis=a;this.pos=b;this.type=c||"";this.isNew=!0;!c&&!d&&this.addLabel()}function Kb(a,b,c,d,e){var f=a.chart.inverted;this.axis=a;this.isNegative=c;this.options=b;this.x=d;this.total=null;this.points={};this.stack=e;this.rightCliff=this.leftCliff=0;this.alignOptions={align:b.align||(f?c?"left":"right":"center"),verticalAlign:b.verticalAlign||(f?"middle":c?"bottom": +"top"),y:p(b.y,f?4:c?14:-6),x:p(b.x,f?c?-6:6:0)};this.textAlign=b.textAlign||(f?c?"right":"left":"center")}var z,y=E.document,W=Math,A=W.round,T=W.floor,ua=W.ceil,t=W.max,F=W.min,P=W.abs,U=W.cos,$=W.sin,ra=W.PI,ga=ra*2/360,za=E.navigator&&E.navigator.userAgent||"",Lb=E.opera,ya=/(msie|trident|edge)/i.test(za)&&!Lb,lb=y&&y.documentMode===8,mb=!ya&&/AppleWebKit/.test(za),Ma=/Firefox/.test(za),Mb=/(Mobile|Android|Windows Phone)/.test(za),Fa="http://www.w3.org/2000/svg",ca=y&&y.createElementNS&&!!y.createElementNS(Fa, +"svg").createSVGRect,Qb=Ma&&parseInt(za.split("Firefox/")[1],10)<4,ha=y&&!ca&&!ya&&!!y.createElement("canvas").getContext,cb,db,Nb={},zb=0,jb,N,Qa,G,Aa=function(){},S=[],eb=0,La="div",Rb=/^[0-9]+$/,nb=["plotTop","marginRight","marginBottom","plotLeft"],qa,kb,qb,Za,tb,ub,vb,$a,ab,bb,Gb,Hb,Ib,Jb,wb,xb,yb,I={},B;B=E.Highcharts?X(16,!0):{win:E};B.seriesTypes=I;var Ga=[],ja,sa,o,Na,Ab,Ba,M,V,H,Wa,Oa;pb.prototype={dSetter:function(){var a=this.paths[0],b=this.paths[1],c=[],d=this.now,e=a.length,f;if(d=== +1)c=this.toD;else if(e===b.length&&d<1)for(;e--;)f=parseFloat(a[e]),c[e]=isNaN(f)?a[e]:d*parseFloat(b[e]-f)+f;else c=b;this.elem.attr("d",c)},update:function(){var a=this.elem,b=this.prop,c=this.now,d=this.options.step;if(this[b+"Setter"])this[b+"Setter"]();else a.attr?a.element&&a.attr(b,c):a.style[b]=c+this.unit;d&&d.call(a,c,this)},run:function(a,b,c){var d=this,e=function(a){return e.stopped?!1:d.step(a)},f;this.startTime=+new qa;this.start=a;this.end=b;this.unit=c;this.now=this.start;this.pos= +0;e.elem=this.elem;if(e()&&Ga.push(e)===1)e.timerId=setInterval(function(){for(f=0;f=f+this.startTime){this.now=this.end;this.pos=1;this.update();a=g[this.prop]=!0;for(h in g)g[h]!==!0&&(a=!1);a&&e&&e.call(c);c=!1}else this.pos=d.easing((b-this.startTime)/f),this.now=this.start+ +(this.end-this.start)*this.pos,this.update(),c=!0;return c},initPath:function(a,b,c){var b=b||"",d=a.shift,e=b.indexOf("C")>-1,f=e?7:3,g,b=b.split(" "),c=[].concat(c),h=a.isArea,i=h?2:1,k=function(a){for(g=a.length;g--;)(a[g]==="M"||a[g]==="L")&&a.splice(g+1,0,a[g+1],a[g+2],a[g+1],a[g+2])};e&&(k(b),k(c));if(d<=c.length/f&&b.length===c.length)for(;d--;)c=c.slice(0,f).concat(c),h&&(c=c.concat(c.slice(c.length-f)));a.shift=0;if(b.length)for(a=c.length;b.length3?g.length%3:0;c=p(c,e.decimalPoint);d=p(d,e.thousandsSep);a=a<0?"-":"";a+=h?g.substr(0,h)+d:"";a+=g.substr(h).replace(/(\d{3})(?=\d)/g,"$1"+d);+b&&(d=Math.abs(i-g+Math.pow(10,-Math.max(b,f)-1)),a+=c+d.toFixed(b).slice(2)); +return a};Math.easeInOutSine=function(a){return-0.5*(Math.cos(Math.PI*a)-1)};ja=function(a,b){var c;if(b==="width")return Math.min(a.offsetWidth,a.scrollWidth)-ja(a,"padding-left")-ja(a,"padding-right");else if(b==="height")return Math.min(a.offsetHeight,a.scrollHeight)-ja(a,"padding-top")-ja(a,"padding-bottom");return(c=E.getComputedStyle(a,void 0))&&C(c.getPropertyValue(b))};sa=function(a,b){return b.indexOf?b.indexOf(a):[].indexOf.call(b,a)};Na=function(a,b){return[].filter.call(a,b)};Ba=function(a, +b){for(var c=[],d=0,e=a.length;d-1&&(f.splice(h,1),g[b]=f),d(b,c)):(e(),g[b]=[])):(e(),a.hcEvents={})};H=function(a,b,c,d){var e;e=a.hcEvents;var f,g,h,i,c=c||{};if(y.createEvent&&(a.dispatchEvent||a.fireEvent))e=y.createEvent("Events"),e.initEvent(b,!0,!0),e.target=a,u(e,c),a.dispatchEvent?a.dispatchEvent(e):a.fireEvent(b,e);else if(e){e=e[b]||[];f=e.length;h=function(){c.defaultPrevented=!0};for(g=0;g{point.key}
',pointFormat:'\u25cf {series.name}: {point.y}
',shadow:!0,snap:Mb?25:10,style:{color:"#333333",cursor:"default",fontSize:"12px",padding:"8px",pointerEvents:"none",whiteSpace:"nowrap"}},credits:{enabled:!0,text:"Highcharts.com", +href:"http://www.highcharts.com",position:{align:"right",x:-10,verticalAlign:"bottom",y:-5},style:{cursor:"pointer",color:"#909090",fontSize:"9px"}}};var aa=N.plotOptions,da=aa.line;Fb();ia.prototype={parsers:[{regex:/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/,parse:function(a){return[C(a[1]),C(a[2]),C(a[3]),parseFloat(a[4],10)]}},{regex:/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,parse:function(a){return[C(a[1],16),C(a[2],16),C(a[3],16), +1]}},{regex:/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/,parse:function(a){return[C(a[1]),C(a[2]),C(a[3]),1]}}],init:function(a){var b,c,d,e;if((this.input=a)&&a.stops)this.stops=Ba(a.stops,function(a){return new ia(a[1])});else for(d=this.parsers.length;d--&&!c;)e=this.parsers[d],(b=e.regex.exec(a))&&(c=e.parse(b));this.rgba=c||[]},get:function(a){var b=this.input,c=this.rgba,d;this.stops?(d=D(b),d.stops=[].concat(d.stops),o(this.stops,function(b,c){d.stops[c]=[d.stops[c][0], +b.get(a)]})):d=c&&!isNaN(c[0])?a==="rgb"||!a&&c[3]===1?"rgb("+c[0]+","+c[1]+","+c[2]+")":a==="a"?c[3]:"rgba("+c.join(",")+")":b;return d},brighten:function(a){var b,c=this.rgba;if(this.stops)o(this.stops,function(b){b.brighten(a)});else if(ma(a)&&a!==0)for(b=0;b<3;b++)c[b]+=C(a*255),c[b]<0&&(c[b]=0),c[b]>255&&(c[b]=255);return this},setOpacity:function(a){this.rgba[3]=a;return this}};O.prototype={opacity:1,textProps:"direction,fontSize,fontWeight,fontFamily,fontStyle,color,lineHeight,width,textDecoration,textOverflow,textShadow".split(","), +init:function(a,b){this.element=b==="span"?Z(b):y.createElementNS(Fa,b);this.renderer=a},animate:function(a,b,c){b=p(b,this.renderer.globalAnimation,!0);Oa(this);if(b){b=D(b,{});if(c)b.complete=c;Wa(this,a,b)}else this.attr(a,null,c);return this},colorGradient:function(a,b,c){var d=this.renderer,e,f,g,h,i,k,j,l,m,n,r,s=[],p;a.linearGradient?f="linearGradient":a.radialGradient&&(f="radialGradient");if(f){g=a[f];i=d.gradients;j=a.stops;n=c.radialReference;Ia(g)&&(a[f]=g={x1:g[0],y1:g[1],x2:g[2],y2:g[3], +gradientUnits:"userSpaceOnUse"});f==="radialGradient"&&n&&!q(g.gradientUnits)&&(h=g,g=D(g,d.getRadialAttr(n,h),{gradientUnits:"userSpaceOnUse"}));for(r in g)r!=="id"&&s.push(r,g[r]);for(r in j)s.push(j[r]);s=s.join(",");i[s]?n=i[s].attr("id"):(g.id=n="highcharts-"+zb++,i[s]=k=d.createElement(f).attr(g).add(d.defs),k.radAttr=h,k.stops=[],o(j,function(a){a[1].indexOf("rgba")===0?(e=ia(a[1]),l=e.get("rgb"),m=e.get("a")):(l=a[1],m=1);a=d.createElement("stop").attr({offset:a[0],"stop-color":l,"stop-opacity":m}).add(k); +k.stops.push(a)}));p="url("+d.url+"#"+n+")";c.setAttribute(b,p);c.gradient=s;a.toString=function(){return p}}},applyTextShadow:function(a){var b=this.element,c,d=a.indexOf("contrast")!==-1,e={},f=this.renderer.forExport,g=f||b.style.textShadow!==z&&!ya;if(d)e.textShadow=a=a.replace(/contrast/g,this.renderer.getContrast(b.style.fill));if(mb||f)e.textRendering="geometricPrecision";g?this.css(e):(this.fakeTS=!0,this.ySetter=this.xSetter,c=[].slice.call(b.getElementsByTagName("tspan")),o(a.split(/\s?,\s?/g), +function(a){var d=b.firstChild,e,f,a=a.split(" ");e=a[a.length-1];(f=a[a.length-2])&&o(c,function(a,c){var g;c===0&&(a.setAttribute("x",b.getAttribute("x")),c=b.getAttribute("y"),a.setAttribute("y",c||0),c===null&&b.setAttribute("y",0));g=a.cloneNode(1);K(g,{"class":"highcharts-text-shadow",fill:e,stroke:e,"stroke-opacity":1/t(C(f),3),"stroke-width":f,"stroke-linejoin":"round"});b.insertBefore(g,d)})}))},attr:function(a,b,c){var d,e=this.element,f,g=this,h;typeof a==="string"&&b!==z&&(d=a,a={},a[d]= +b);if(typeof a==="string")g=(this[a+"Getter"]||this._defaultGetter).call(this,a,e);else{for(d in a){b=a[d];h=!1;this.symbolName&&/^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(d)&&(f||(this.symbolAttr(a),f=!0),h=!0);if(this.rotation&&(d==="x"||d==="y"))this.doTransform=!0;h||(h=this[d+"Setter"]||this._defaultSetter,h.call(this,b,d,e),this.shadows&&/^(width|height|visibility|x|y|d|transform|cx|cy|r)$/.test(d)&&this.updateShadows(d,b,h))}if(this.doTransform)this.updateTransform(),this.doTransform= +!1}c&&c();return g},updateShadows:function(a,b,c){for(var d=this.shadows,e=d.length;e--;)c.call(null,a==="height"?Math.max(b-(d[e].cutHeight||0),0):a==="d"?this.d:b,a,d[e])},addClass:function(a){var b=this.element,c=K(b,"class")||"";c.indexOf(a)===-1&&K(b,"class",c+" "+a);return this},symbolAttr:function(a){var b=this;o("x,y,r,start,end,width,height,innerR,anchorX,anchorY".split(","),function(c){b[c]=p(a[c],b[c])});b.attr({d:b.renderer.symbols[b.symbolName](b.x,b.y,b.width,b.height,b)})},clip:function(a){return this.attr("clip-path", +a?"url("+this.renderer.url+"#"+a.id+")":"none")},crisp:function(a){var b,c={},d,e=this.strokeWidth||0;d=A(e)%2/2;a.x=T(a.x||this.x||0)+d;a.y=T(a.y||this.y||0)+d;a.width=T((a.width||this.width||0)-2*d);a.height=T((a.height||this.height||0)-2*d);a.strokeWidth=e;for(b in a)this[b]!==a[b]&&(this[b]=c[b]=a[b]);return c},css:function(a){var b=this.styles,c={},d=this.element,e,f,g="";e=!b;if(a&&a.color)a.fill=a.color;if(b)for(f in a)a[f]!==b[f]&&(c[f]=a[f],e=!0);if(e){e=this.textWidth=a&&a.width&&d.nodeName.toLowerCase()=== +"text"&&C(a.width)||this.textWidth;b&&(a=u(b,c));this.styles=a;e&&(ha||!ca&&this.renderer.forExport)&&delete a.width;if(ya&&!ca)L(this.element,a);else{b=function(a,b){return"-"+b.toLowerCase()};for(f in a)g+=f.replace(/([A-Z])/g,b)+":"+a[f]+";";K(d,"style",g)}e&&this.added&&this.renderer.buildText(this)}return this},on:function(a,b){var c=this,d=c.element;db&&a==="click"?(d.ontouchstart=function(a){c.touchEventFired=qa.now();a.preventDefault();b.call(d,a)},d.onclick=function(a){(za.indexOf("Android")=== +-1||qa.now()-(c.touchEventFired||0)>1100)&&b.call(d,a)}):d["on"+a]=b;return this},setRadialReference:function(a){var b=this.renderer.gradients[this.element.gradient];this.element.radialReference=a;b&&b.radAttr&&b.animate(this.renderer.getRadialAttr(a,b.radAttr));return this},translate:function(a,b){return this.attr({translateX:a,translateY:b})},invert:function(){this.inverted=!0;this.updateTransform();return this},updateTransform:function(){var a=this.translateX||0,b=this.translateY||0,c=this.scaleX, +d=this.scaleY,e=this.inverted,f=this.rotation,g=this.element;e&&(a+=this.attr("width"),b+=this.attr("height"));a=["translate("+a+","+b+")"];e?a.push("rotate(90) scale(-1,1)"):f&&a.push("rotate("+f+" "+(g.getAttribute("x")||0)+" "+(g.getAttribute("y")||0)+")");(q(c)||q(d))&&a.push("scale("+p(c,1)+" "+p(d,1)+")");a.length&&g.setAttribute("transform",a.join(" "))},toFront:function(){var a=this.element;a.parentNode.appendChild(a);return this},align:function(a,b,c){var d,e,f,g,h={};e=this.renderer;f=e.alignedObjects; +if(a){if(this.alignOptions=a,this.alignByTranslate=b,!c||xa(c))this.alignTo=d=c||"renderer",oa(f,this),f.push(this),c=null}else a=this.alignOptions,b=this.alignByTranslate,d=this.alignTo;c=p(c,e[d],e);d=a.align;e=a.verticalAlign;f=(c.x||0)+(a.x||0);g=(c.y||0)+(a.y||0);if(d==="right"||d==="center")f+=(c.width-(a.width||0))/{right:1,center:2}[d];h[b?"translateX":"x"]=A(f);if(e==="bottom"||e==="middle")g+=(c.height-(a.height||0))/({bottom:1,middle:2}[e]||1);h[b?"translateY":"y"]=A(g);this[this.placed? +"animate":"attr"](h);this.placed=!0;this.alignAttr=h;return this},getBBox:function(a,b){var c,d=this.renderer,e,f,g,h=this.element,i=this.styles;e=this.textStr;var k,j=h.style,l,m=d.cache,n=d.cacheKeys,r;f=p(b,this.rotation);g=f*ga;e!==z&&(r=["",f||0,i&&i.fontSize,h.style.width].join(","),r=e===""||Rb.test(e)?"num:"+e.toString().length+r:e+r);r&&!a&&(c=m[r]);if(!c){if(h.namespaceURI===Fa||d.forExport){try{l=this.fakeTS&&function(a){o(h.querySelectorAll(".highcharts-text-shadow"),function(b){b.style.display= +a})},Ma&&j.textShadow?(k=j.textShadow,j.textShadow=""):l&&l("none"),c=h.getBBox?u({},h.getBBox()):{width:h.offsetWidth,height:h.offsetHeight},k?j.textShadow=k:l&&l("")}catch(s){}if(!c||c.width<0)c={width:0,height:0}}else c=this.htmlGetBBox();if(d.isSVG){d=c.width;e=c.height;if(ya&&i&&i.fontSize==="11px"&&e.toPrecision(3)==="16.9")c.height=e=14;if(f)c.width=P(e*$(g))+P(d*U(g)),c.height=P(e*U(g))+P(d*$(g))}if(r){for(;n.length>250;)delete m[n.shift()];m[r]||n.push(r);m[r]=c}}return c},show:function(a){return this.attr({visibility:a? +"inherit":"visible"})},hide:function(){return this.attr({visibility:"hidden"})},fadeOut:function(a){var b=this;b.animate({opacity:0},{duration:a||150,complete:function(){b.attr({y:-9999})}})},add:function(a){var b=this.renderer,c=this.element,d;if(a)this.parentGroup=a;this.parentInverted=a&&a.inverted;this.textStr!==void 0&&b.buildText(this);this.added=!0;if(!a||a.handleZ||this.zIndex)d=this.zIndexSetter();d||(a?a.element:b.box).appendChild(c);if(this.onAdd)this.onAdd();return this},safeRemoveChild:function(a){var b= +a.parentNode;b&&b.removeChild(a)},destroy:function(){var a=this,b=a.element||{},c=a.shadows,d=a.renderer.isSVG&&b.nodeName==="SPAN"&&a.parentGroup,e,f;b.onclick=b.onmouseout=b.onmouseover=b.onmousemove=b.point=null;Oa(a);if(a.clipPath)a.clipPath=a.clipPath.destroy();if(a.stops){for(f=0;f]*>/g,"")))},textSetter:function(a){if(a!==this.textStr)delete this.bBox,this.textStr=a,this.added&&this.renderer.buildText(this)},fillSetter:function(a,b,c){typeof a==="string"?c.setAttribute(b,a):a&&this.colorGradient(a,b,c)},visibilitySetter:function(a,b,c){a=== +"inherit"?c.removeAttribute(b):c.setAttribute(b,a)},zIndexSetter:function(a,b){var c=this.renderer,d=this.parentGroup,c=(d||c).element||c.box,e,f,g=this.element,h;e=this.added;var i;q(a)&&(g.setAttribute(b,a),a=+a,this[b]===a&&(e=!1),this[b]=a);if(e){if((a=this.zIndex)&&d)d.handleZ=!0;d=c.childNodes;for(i=0;ia||!q(a)&&q(f)))c.insertBefore(g,e),h=!0;h||c.appendChild(g)}return h},_defaultSetter:function(a,b,c){c.setAttribute(b,a)}};O.prototype.yGetter= +O.prototype.xGetter;O.prototype.translateXSetter=O.prototype.translateYSetter=O.prototype.rotationSetter=O.prototype.verticalAlignSetter=O.prototype.scaleXSetter=O.prototype.scaleYSetter=function(a,b){this[b]=a;this.doTransform=!0};O.prototype["stroke-widthSetter"]=O.prototype.strokeSetter=function(a,b,c){this[b]=a;if(this.stroke&&this["stroke-width"])this.strokeWidth=this["stroke-width"],O.prototype.fillSetter.call(this,this.stroke,"stroke",c),c.setAttribute("stroke-width",this["stroke-width"]), +this.hasStroke=!0;else if(b==="stroke-width"&&a===0&&this.hasStroke)c.removeAttribute("stroke"),this.hasStroke=!1};var Ca=function(){this.init.apply(this,arguments)};Ca.prototype={Element:O,init:function(a,b,c,d,e,f){var g,d=this.createElement("svg").attr({version:"1.1"}).css(this.getStyle(d));g=d.element;a.appendChild(g);a.innerHTML.indexOf("xmlns")===-1&&K(g,"xmlns",Fa);this.isSVG=!0;this.box=g;this.boxWrapper=d;this.alignedObjects=[];this.url=(Ma||mb)&&y.getElementsByTagName("base").length?E.location.href.replace(/#.*?$/, +"").replace(/([\('\)])/g,"\\$1").replace(/ /g,"%20"):"";this.createElement("desc").add().element.appendChild(y.createTextNode("Created with Highcharts 4.2.3"));this.defs=this.createElement("defs").add();this.allowHTML=f;this.forExport=e;this.gradients={};this.cache={};this.cacheKeys=[];this.imgCount=0;this.setSize(b,c,!1);var h;if(Ma&&a.getBoundingClientRect)this.subPixelFix=b=function(){L(a,{left:0,top:0});h=a.getBoundingClientRect();L(a,{left:ua(h.left)-h.left+"px",top:ua(h.top)-h.top+"px"})},b(), +M(E,"resize",b)},getStyle:function(a){return this.style=u({fontFamily:'"Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif',fontSize:"12px"},a)},isHidden:function(){return!this.boxWrapper.getBBox().width},destroy:function(){var a=this.defs;this.box=null;this.boxWrapper=this.boxWrapper.destroy();Sa(this.gradients||{});this.gradients=null;if(a)this.defs=a.destroy();this.subPixelFix&&V(E,"resize",this.subPixelFix);return this.alignedObjects=null},createElement:function(a){var b=new this.Element; +b.init(this,a);return b},draw:function(){},getRadialAttr:function(a,b){return{cx:a[0]-a[2]/2+b.cx*a[2],cy:a[1]-a[2]/2+b.cy*a[2],r:b.r*a[2]}},buildText:function(a){for(var b=a.element,c=this,d=c.forExport,e=p(a.textStr,"").toString(),f=e.indexOf("<")!==-1,g=b.childNodes,h,i,k=K(b,"x"),j=a.styles,l=a.textWidth,m=j&&j.lineHeight,n=j&&j.textShadow,r=j&&j.textOverflow==="ellipsis",s=g.length,R=l&&!a.added&&this.box,v=function(a){return m?C(m):c.fontMetrics(/(px|em)$/.test(a&&a.style.fontSize)?a.style.fontSize: +j&&j.fontSize||c.style.fontSize||12,a).h},x=function(a){return a.replace(/</g,"<").replace(/>/g,">")};s--;)b.removeChild(g[s]);!f&&!n&&!r&&e.indexOf(" ")===-1?b.appendChild(y.createTextNode(x(e))):(h=/<.*style="([^"]+)".*>/,i=/<.*href="(http[^"]+)".*>/,R&&R.appendChild(b),e=f?e.replace(/<(b|strong)>/g,'').replace(/<(i|em)>/g,'').replace(//g,"").split(//g):[e],e[e.length-1]=== +""&&e.pop(),o(e,function(e,f){var g,m=0,e=e.replace(//g,"|||");g=e.split("|||");o(g,function(e){if(e!==""||g.length===1){var n={},s=y.createElementNS(Fa,"tspan"),p;h.test(e)&&(p=e.match(h)[1].replace(/(;| |^)color([ :])/,"$1fill$2"),K(s,"style",p));i.test(e)&&!d&&(K(s,"onclick",'location.href="'+e.match(i)[1]+'"'),L(s,{cursor:"pointer"}));e=x(e.replace(/<(.|\n)*?>/g,"")||" ");if(e!==" "){s.appendChild(y.createTextNode(e));if(m)n.dx=0;else if(f&&k!==null)n.x= +k;K(s,n);b.appendChild(s);!m&&f&&(!ca&&d&&L(s,{display:"block"}),K(s,"dy",v(s)));if(l){for(var n=e.replace(/([^\^])-/g,"$1- ").split(" "),R=g.length>1||f||n.length>1&&j.whiteSpace!=="nowrap",o,w,q,t=[],u=v(s),A=1,z=a.rotation,B=e,D=B.length;(R||r)&&(n.length||t.length);)a.rotation=0,o=a.getBBox(!0),q=o.width,!ca&&c.forExport&&(q=c.measureSpanWidth(s.firstChild.data,a.styles)),o=q>l,w===void 0&&(w=o),r&&w?(D/=2,B===""||!o&&D<0.5?n=[]:(o&&(w=!0),B=e.substring(0,B.length+(o?-1:1)*ua(D)),n=[B+(l>3?"\u2026": +"")],s.removeChild(s.firstChild))):!o||n.length===1?(n=t,t=[],n.length&&(A++,s=y.createElementNS(Fa,"tspan"),K(s,{dy:u,x:k}),p&&K(s,"style",p),b.appendChild(s)),q>l&&(l=q)):(s.removeChild(s.firstChild),t.unshift(n.pop())),n.length&&s.appendChild(y.createTextNode(n.join(" ").replace(/- /g,"-")));w&&a.attr("title",a.textStr);a.rotation=z}m++}}})}),R&&R.removeChild(b),n&&a.applyTextShadow&&a.applyTextShadow(n))},getContrast:function(a){a=ia(a).rgba;return a[0]+a[1]+a[2]>384?"#000000":"#FFFFFF"},button:function(a, +b,c,d,e,f,g,h,i){var k=this.label(a,b,c,i,null,null,null,null,"button"),j=0,l,m,n,r,s,p,a={x1:0,y1:0,x2:0,y2:1},e=D({"stroke-width":1,stroke:"#CCCCCC",fill:{linearGradient:a,stops:[[0,"#FEFEFE"],[1,"#F6F6F6"]]},r:2,padding:5,style:{color:"black"}},e);n=e.style;delete e.style;f=D(e,{stroke:"#68A",fill:{linearGradient:a,stops:[[0,"#FFF"],[1,"#ACF"]]}},f);r=f.style;delete f.style;g=D(e,{stroke:"#68A",fill:{linearGradient:a,stops:[[0,"#9BD"],[1,"#CDF"]]}},g);s=g.style;delete g.style;h=D(e,{style:{color:"#CCC"}}, +h);p=h.style;delete h.style;M(k.element,ya?"mouseover":"mouseenter",function(){j!==3&&k.attr(f).css(r)});M(k.element,ya?"mouseout":"mouseleave",function(){j!==3&&(l=[e,f,g][j],m=[n,r,s][j],k.attr(l).css(m))});k.setState=function(a){(k.state=j=a)?a===2?k.attr(g).css(s):a===3&&k.attr(h).css(p):k.attr(e).css(n)};return k.on("click",function(a){j!==3&&d.call(k,a)}).attr(e).css(u({cursor:"default"},n))},crispLine:function(a,b){a[1]===a[4]&&(a[1]=a[4]=A(a[1])-b%2/2);a[2]===a[5]&&(a[2]=a[5]=A(a[2])+b%2/ +2);return a},path:function(a){var b={fill:"none"};Ia(a)?b.d=a:Y(a)&&u(b,a);return this.createElement("path").attr(b)},circle:function(a,b,c){a=Y(a)?a:{x:a,y:b,r:c};b=this.createElement("circle");b.xSetter=b.ySetter=function(a,b,c){c.setAttribute("c"+b,a)};return b.attr(a)},arc:function(a,b,c,d,e,f){if(Y(a))b=a.y,c=a.r,d=a.innerR,e=a.start,f=a.end,a=a.x;a=this.symbol("arc",a||0,b||0,c||0,c||0,{innerR:d||0,start:e||0,end:f||0});a.r=c;return a},rect:function(a,b,c,d,e,f){var e=Y(a)?a.r:e,g=this.createElement("rect"), +a=Y(a)?a:a===z?{}:{x:a,y:b,width:t(c,0),height:t(d,0)};if(f!==z)g.strokeWidth=f,a=g.crisp(a);if(e)a.r=e;g.rSetter=function(a,b,c){K(c,{rx:a,ry:a})};return g.attr(a)},setSize:function(a,b,c){var d=this.alignedObjects,e=d.length;this.width=a;this.height=b;for(this.boxWrapper[p(c,!0)?"animate":"attr"]({width:a,height:b});e--;)d[e].align()},g:function(a){var b=this.createElement("g");return q(a)?b.attr({"class":"highcharts-"+a}):b},image:function(a,b,c,d,e){var f={preserveAspectRatio:"none"};arguments.length> +1&&u(f,{x:b,y:c,width:d,height:e});f=this.createElement("image").attr(f);f.element.setAttributeNS?f.element.setAttributeNS("http://www.w3.org/1999/xlink","href",a):f.element.setAttribute("hc-svg-href",a);return f},symbol:function(a,b,c,d,e,f){var g=this,h,i=this.symbols[a],i=i&&i(A(b),A(c),d,e,f),k=/^url\((.*?)\)$/,j,l;if(i)h=this.path(i),u(h,{symbolName:a,x:b,y:c,width:d,height:e}),f&&u(h,f);else if(k.test(a))l=function(a,b){a.element&&(a.attr({width:b[0],height:b[1]}),a.alignByTranslate||a.translate(A((d- +b[0])/2),A((e-b[1])/2)))},j=a.match(k)[1],a=Nb[j]||f&&f.width&&f.height&&[f.width,f.height],h=this.image(j).attr({x:b,y:c}),h.isImg=!0,a?l(h,a):(h.attr({width:0,height:0}),Z("img",{onload:function(){this.width===0&&(L(this,{position:"absolute",top:"-999em"}),y.body.appendChild(this));l(h,Nb[j]=[this.width,this.height]);this.parentNode&&this.parentNode.removeChild(this);g.imgCount--;if(!g.imgCount)S[g.chartIndex].onload()},src:j})),this.imgCount++;return h},symbols:{circle:function(a,b,c,d){var e= +0.166*c;return["M",a+c/2,b,"C",a+c+e,b,a+c+e,b+d,a+c/2,b+d,"C",a-e,b+d,a-e,b,a+c/2,b,"Z"]},square:function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c,b+d,a,b+d,"Z"]},triangle:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d,a,b+d,"Z"]},"triangle-down":function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c/2,b+d,"Z"]},diamond:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d/2,a+c/2,b+d,a,b+d/2,"Z"]},arc:function(a,b,c,d,e){var f=e.start,c=e.r||c||d,g=e.end-0.001,d=e.innerR,h=e.open,i=U(f),k=$(f),j=U(g),g=$(g), +e=e.end-fc&&e>b+g&&eb+g&&ed&&h>a+g&&ha+g&&hj&&/[ \-]/.test(b.textContent||b.innerText))L(b,{width:j+"px",display:"block",whiteSpace:l||"normal"}),this.hasTextWidth=!0;else if(this.hasTextWidth)L(b,{width:"",display:"",whiteSpace:l||"nowrap"}),this.hasTextWidth=!1;this.getSpanCorrection(this.hasTextWidth? +j:b.offsetWidth,k,h,i,g)}L(b,{left:e+(this.xCorr||0)+"px",top:f+(this.yCorr||0)+"px"});if(mb)k=b.offsetHeight;this.cTT=m}}else this.alignOnAdd=!0},setSpanRotation:function(a,b,c){var d={},e=ya?"-ms-transform":mb?"-webkit-transform":Ma?"MozTransform":Lb?"-o-transform":"";d[e]=d.transform="rotate("+a+"deg)";d[e+(Ma?"Origin":"-origin")]=d.transformOrigin=b*100+"% "+c+"px";L(this.element,d)},getSpanCorrection:function(a,b,c){this.xCorr=-a*c;this.yCorr=-b}});u(Ca.prototype,{html:function(a,b,c){var d= +this.createElement("span"),e=d.element,f=d.renderer,g=function(a,b){o(["opacity","visibility"],function(c){fb(a,c+"Setter",function(a,c,d,e){a.call(this,c,d,e);b[d]=c})})};d.textSetter=function(a){a!==e.innerHTML&&delete this.bBox;e.innerHTML=this.textStr=a;d.htmlUpdateTransform()};g(d,d.element.style);d.xSetter=d.ySetter=d.alignSetter=d.rotationSetter=function(a,b){b==="align"&&(b="textAlign");d[b]=a;d.htmlUpdateTransform()};d.attr({text:a,x:A(b),y:A(c)}).css({position:"absolute",fontFamily:this.style.fontFamily, +fontSize:this.style.fontSize});e.style.whiteSpace="nowrap";d.css=d.htmlCss;if(f.isSVG)d.add=function(a){var b,c=f.box.parentNode,j=[];if(this.parentGroup=a){if(b=a.div,!b){for(;a;)j.push(a),a=a.parentGroup;o(j.reverse(),function(a){var d,e=K(a.element,"class");e&&(e={className:e});b=a.div=a.div||Z(La,e,{position:"absolute",left:(a.translateX||0)+"px",top:(a.translateY||0)+"px"},b||c);d=b.style;u(a,{translateXSetter:function(b,c){d.left=b+"px";a[c]=b;a.doTransform=!0},translateYSetter:function(b,c){d.top= +b+"px";a[c]=b;a.doTransform=!0}});g(a,d)})}}else b=c;b.appendChild(e);d.added=!0;d.alignOnAdd&&d.htmlUpdateTransform();return d};return d}});var J;if(!ca&&!ha){J={init:function(a,b){var c=["<",b,' filled="f" stroked="f"'],d=["position: ","absolute",";"],e=b===La;(b==="shape"||e)&&d.push("left:0;top:0;width:1px;height:1px;");d.push("visibility: ",e?"hidden":"visible");c.push(' style="',d.join(""),'"/>');if(b)c=e||b==="span"||b==="img"?c.join(""):a.prepVML(c),this.element=Z(c);this.renderer=a},add:function(a){var b= +this.renderer,c=this.element,d=b.box,e=a&&a.inverted,d=a?a.element||a:d;if(a)this.parentGroup=a;e&&b.invertChild(c,d);d.appendChild(c);this.added=!0;this.alignOnAdd&&!this.deferUpdateTransform&&this.updateTransform();if(this.onAdd)this.onAdd();return this},updateTransform:O.prototype.htmlUpdateTransform,setSpanRotation:function(){var a=this.rotation,b=U(a*ga),c=$(a*ga);L(this.element,{filter:a?["progid:DXImageTransform.Microsoft.Matrix(M11=",b,", M12=",-c,", M21=",c,", M22=",b,", sizingMethod='auto expand')"].join(""): +"none"})},getSpanCorrection:function(a,b,c,d,e){var f=d?U(d*ga):1,g=d?$(d*ga):0,h=p(this.elemHeight,this.element.offsetHeight),i;this.xCorr=f<0&&-a;this.yCorr=g<0&&-h;i=f*g<0;this.xCorr+=g*b*(i?1-c:c);this.yCorr-=f*b*(d?i?c:1-c:1);e&&e!=="left"&&(this.xCorr-=a*c*(f<0?-1:1),d&&(this.yCorr-=h*c*(g<0?-1:1)),L(this.element,{textAlign:e}))},pathToVML:function(a){for(var b=a.length,c=[];b--;)if(ma(a[b]))c[b]=A(a[b]*10)-5;else if(a[b]==="Z")c[b]="x";else if(c[b]=a[b],a.isArc&&(a[b]==="wa"||a[b]==="at"))c[b+ +5]===c[b+7]&&(c[b+7]+=a[b+7]>a[b+5]?1:-1),c[b+6]===c[b+8]&&(c[b+8]+=a[b+8]>a[b+6]?1:-1);return c.join(" ")||"x"},clip:function(a){var b=this,c;a?(c=a.members,oa(c,b),c.push(b),b.destroyClip=function(){oa(c,b)},a=a.getCSS(b)):(b.destroyClip&&b.destroyClip(),a={clip:lb?"inherit":"rect(auto)"});return b.css(a)},css:O.prototype.htmlCss,safeRemoveChild:function(a){a.parentNode&&Ta(a)},destroy:function(){this.destroyClip&&this.destroyClip();return O.prototype.destroy.apply(this)},on:function(a,b){this.element["on"+ +a]=function(){var a=E.event;a.target=a.srcElement;b(a)};return this},cutOffPath:function(a,b){var c,a=a.split(/[ ,]/);c=a.length;if(c===9||c===11)a[c-4]=a[c-2]=C(a[c-2])-10*b;return a.join(" ")},shadow:function(a,b,c){var d=[],e,f=this.element,g=this.renderer,h,i=f.style,k,j=f.path,l,m,n,r;j&&typeof j.value!=="string"&&(j="x");m=j;if(a){n=p(a.width,3);r=(a.opacity||0.15)/n;for(e=1;e<=3;e++){l=n*2+1-2*e;c&&(m=this.cutOffPath(j.value,l+0.5));k=[''];h=Z(g.prepVML(k),null,{left:C(i.left)+p(a.offsetX,1),top:C(i.top)+p(a.offsetY,1)});if(c)h.cutOff=l+1;k=[''];Z(g.prepVML(k),null,null,h);b?b.element.appendChild(h):f.parentNode.insertBefore(h,f);d.push(h)}this.shadows=d}return this},updateShadows:Aa,setAttr:function(a,b){lb?this.element[a]=b:this.element.setAttribute(a,b)},classSetter:function(a){this.element.className=a},dashstyleSetter:function(a, +b,c){(c.getElementsByTagName("stroke")[0]||Z(this.renderer.prepVML([""]),null,null,c))[b]=a||"solid";this[b]=a},dSetter:function(a,b,c){var d=this.shadows,a=a||[];this.d=a.join&&a.join(" ");c.path=a=this.pathToVML(a);if(d)for(c=d.length;c--;)d[c].path=d[c].cutOff?this.cutOffPath(a,d[c].cutOff):a;this.setAttr(b,a)},fillSetter:function(a,b,c){var d=c.nodeName;if(d==="SPAN")c.style.color=a;else if(d!=="IMG")c.filled=a!=="none",this.setAttr("fillcolor",this.renderer.color(a,c,b,this))},"fill-opacitySetter":function(a, +b,c){Z(this.renderer.prepVML(["<",b.split("-")[0],' opacity="',a,'"/>']),null,null,c)},opacitySetter:Aa,rotationSetter:function(a,b,c){c=c.style;this[b]=c[b]=a;c.left=-A($(a*ga)+1)+"px";c.top=A(U(a*ga))+"px"},strokeSetter:function(a,b,c){this.setAttr("strokecolor",this.renderer.color(a,c,b,this))},"stroke-widthSetter":function(a,b,c){c.stroked=!!a;this[b]=a;ma(a)&&(a+="px");this.setAttr("strokeweight",a)},titleSetter:function(a,b){this.setAttr(b,a)},visibilitySetter:function(a,b,c){a==="inherit"&& +(a="visible");this.shadows&&o(this.shadows,function(c){c.style[b]=a});c.nodeName==="DIV"&&(a=a==="hidden"?"-999em":0,lb||(c.style[b]=a?"visible":"hidden"),b="top");c.style[b]=a},xSetter:function(a,b,c){this[b]=a;b==="x"?b="left":b==="y"&&(b="top");this.updateClipping?(this[b]=a,this.updateClipping()):c.style[b]=a},zIndexSetter:function(a,b,c){c.style[b]=a}};J["stroke-opacitySetter"]=J["fill-opacitySetter"];B.VMLElement=J=pa(O,J);J.prototype.ySetter=J.prototype.widthSetter=J.prototype.heightSetter= +J.prototype.xSetter;var Cb={Element:J,isIE8:za.indexOf("MSIE 8.0")>-1,init:function(a,b,c,d){var e;this.alignedObjects=[];d=this.createElement(La).css(u(this.getStyle(d),{position:"relative"}));e=d.element;a.appendChild(d.element);this.isVML=!0;this.box=e;this.boxWrapper=d;this.gradients={};this.cache={};this.cacheKeys=[];this.imgCount=0;this.setSize(b,c,!1);if(!y.namespaces.hcv){y.namespaces.add("hcv","urn:schemas-microsoft-com:vml");try{y.createStyleSheet().cssText="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } "}catch(f){y.styleSheets[0].cssText+= +"hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } "}}},isHidden:function(){return!this.box.offsetWidth},clipRect:function(a,b,c,d){var e=this.createElement(),f=Y(a);return u(e,{members:[],count:0,left:(f?a.x:a)+1,top:(f?a.y:b)+1,width:(f?a.width:c)-1,height:(f?a.height:d)-1,getCSS:function(a){var b=a.element,c=b.nodeName,a=a.inverted,d=this.top-(c==="shape"?b.offsetTop:0),e=this.left,b=e+this.width,f=d+this.height,d={clip:"rect("+A(a?e:d)+"px,"+ +A(a?f:b)+"px,"+A(a?b:f)+"px,"+A(a?d:e)+"px)"};!a&&lb&&c==="DIV"&&u(d,{width:b+"px",height:f+"px"});return d},updateClipping:function(){o(e.members,function(a){a.element&&a.css(e.getCSS(a))})}})},color:function(a,b,c,d){var e=this,f,g=/^rgba/,h,i,k="none";a&&a.linearGradient?i="gradient":a&&a.radialGradient&&(i="pattern");if(i){var j,l,m=a.linearGradient||a.radialGradient,n,r,s,p,v,x="",a=a.stops,w,q=[],ba=function(){h=[''];Z(e.prepVML(h),null,null,b)};n=a[0];w=a[a.length-1];n[0]>0&&a.unshift([0,n[1]]);w[0]<1&&a.push([1,w[1]]);o(a,function(a,b){g.test(a[1])?(f=ia(a[1]),j=f.get("rgb"),l=f.get("a")):(j=a[1],l=1);q.push(a[0]*100+"% "+j);b?(s=l,p=j):(r=l,v=j)});if(c==="fill")if(i==="gradient")c=m.x1||m[0]||0,a=m.y1||m[1]||0,n=m.x2||m[2]||0,m=m.y2||m[3]||0,x='angle="'+(90-W.atan((m-a)/(n-c))*180/ra)+'"',ba();else{var k=m.r,t=k*2,u=k*2,A=m.cx,B=m.cy,z=b.radialReference,y,k=function(){z&&(y= +d.getBBox(),A+=(z[0]-y.x)/y.width-0.5,B+=(z[1]-y.y)/y.height-0.5,t*=z[2]/y.width,u*=z[2]/y.height);x='src="'+N.global.VMLRadialGradientURL+'" size="'+t+","+u+'" origin="0.5,0.5" position="'+A+","+B+'" color2="'+v+'" ';ba()};d.added?k():d.onAdd=k;k=p}else k=j}else if(g.test(a)&&b.tagName!=="IMG")f=ia(a),d[c+"-opacitySetter"](f.get("a"),c,b),k=f.get("rgb");else{k=b.getElementsByTagName(c);if(k.length)k[0].opacity=1,k[0].type="solid";k=a}return k},prepVML:function(a){var b=this.isIE8,a=a.join("");b? +(a=a.replace("/>",' xmlns="urn:schemas-microsoft-com:vml" />'),a=a.indexOf('style="')===-1?a.replace("/>",' style="display:inline-block;behavior:url(#default#VML);" />'):a.replace('style="','style="display:inline-block;behavior:url(#default#VML);')):a=a.replace("<","1&&f.attr({x:b,y:c,width:d,height:e});return f},createElement:function(a){return a==="rect"?this.symbol(a):Ca.prototype.createElement.call(this,a)},invertChild:function(a,b){var c=this,d=b.style,e=a.tagName==="IMG"&&a.style;L(a,{flip:"x",left:C(d.width)-(e?C(e.top): +1),top:C(d.height)-(e?C(e.left):1),rotation:-90});o(a.childNodes,function(b){c.invertChild(b,a)})},symbols:{arc:function(a,b,c,d,e){var f=e.start,g=e.end,h=e.r||c||d,c=e.innerR,d=U(f),i=$(f),k=U(g),j=$(g);if(g-f===0)return["x"];f=["wa",a-h,b-h,a+h,b+h,a+h*d,b+h*i,a+h*k,b+h*j];e.open&&!c&&f.push("e","M",a,b);f.push("at",a-c,b-c,a+c,b+c,a+c*k,b+c*j,a+c*d,b+c*i,"x","e");f.isArc=!0;return f},circle:function(a,b,c,d,e){e&&(c=d=2*e.r);e&&e.isCircle&&(a-=c/2,b-=d/2);return["wa",a,b,a+c,b+d,a+c,b+d/2,a+c, +b+d/2,"e"]},rect:function(a,b,c,d,e){return Ca.prototype.symbols[!q(e)||!e.r?"square":"callout"].call(0,a,b,c,d,e)}}};B.VMLRenderer=J=function(){this.init.apply(this,arguments)};J.prototype=D(Ca.prototype,Cb);cb=J}Ca.prototype.measureSpanWidth=function(a,b){var c=y.createElement("span"),d;d=y.createTextNode(a);c.appendChild(d);L(c,b);this.box.appendChild(c);d=c.offsetWidth;Ta(c);return d};var Ob;if(ha)B.CanVGRenderer=J=function(){Fa="http://www.w3.org/1999/xhtml"},J.prototype.symbols={},Ob=function(){function a(){var a= +b.length,d;for(d=0;d0&&c+i*k>e&&(m=A((d-c)/U(h*ga)));else if(d=c+(1-i)*k,c-i*ke&&(j=e-a.x+j*i,l=-1),j=F(b.slotWidth,j),jj||b.autoRotation&&g.styles.width)m=j;if(m){n.width= +m;if(!b.options.labels.style.textOverflow)n.textOverflow="ellipsis";g.css(n)}},getPosition:function(a,b,c,d){var e=this.axis,f=e.chart,g=d&&f.oldChartHeight||f.chartHeight;return{x:a?e.translate(b+c,null,null,d)+e.transB:e.left+e.offset+(e.opposite?(d&&f.oldChartWidth||f.chartWidth)-e.right-e.left:0),y:a?g-e.bottom+e.offset-(e.opposite?e.height:0):g-e.translate(b+c,null,null,d)-e.transB}},getLabelPosition:function(a,b,c,d,e,f,g,h){var i=this.axis,k=i.transA,j=i.reversed,l=i.staggerLines,m=i.tickRotCorr|| +{x:0,y:0},n=e.y;q(n)||(n=i.side===2?m.y+8:n=U(c.rotation*ga)*(m.y-c.getBBox(!1,0).height/2));a=a+e.x+m.x-(f&&d?f*k*(j?-1:1):0);b=b+n-(f&&!d?f*k*(j?1:-1):0);l&&(c=g/(h||1)%l,i.opposite&&(c=l-c-1),b+=c*(i.labelOffset/l));return{x:a,y:A(b)}},getMarkPath:function(a,b,c,d,e,f){return f.crispLine(["M",a,b,"L",a+(e?0:-c),b+(e?c:0)],d)},render:function(a,b,c){var d=this.axis,e=d.options,f=d.chart.renderer,g=d.horiz,h=this.type,i=this.label,k=this.pos,j=e.labels,l=this.gridLine,m=h?h+"Grid":"grid",n=h?h+"Tick": +"tick",r=e[m+"LineWidth"],s=e[m+"LineColor"],o=e[m+"LineDashStyle"],v=e[n+"Length"],m=p(e[n+"Width"],!h&&d.isXAxis?1:0),x=e[n+"Color"],w=e[n+"Position"],n=this.mark,q=j.step,ba=!0,t=d.tickmarkOffset,u=this.getPosition(g,k,t,b),A=u.x,u=u.y,B=g&&A===d.pos+d.len||!g&&u===d.pos?-1:1,c=p(c,1);this.isActive=!0;if(r){k=d.getPlotLinePath(k+t,r*B,b,!0);if(l===z){l={stroke:s,"stroke-width":r};if(o)l.dashstyle=o;if(!h)l.zIndex=1;if(b)l.opacity=0;this.gridLine=l=r?f.path(k).attr(l).add(d.gridGroup):null}if(!b&& +l&&k)l[this.isNew?"attr":"animate"]({d:k,opacity:c})}if(m&&v)w==="inside"&&(v=-v),d.opposite&&(v=-v),h=this.getMarkPath(A,u,v,m*B,g,f),n?n.animate({d:h,opacity:c}):this.mark=f.path(h).attr({stroke:x,"stroke-width":m,opacity:c}).add(d.axisGroup);if(i&&!isNaN(A))i.xy=u=this.getLabelPosition(A,u,i,g,j,t,a,q),this.isFirst&&!this.isLast&&!p(e.showFirstLabel,1)||this.isLast&&!this.isFirst&&!p(e.showLastLabel,1)?ba=!1:g&&!d.isRadial&&!j.step&&!j.rotation&&!b&&c!==0&&this.handleOverflow(u),q&&a%q&&(ba=!1), +ba&&!isNaN(u.y)?(u.opacity=c,i[this.isNew?"attr":"animate"](u),this.isNew=!1):i.attr("y",-9999)},destroy:function(){Sa(this,this.axis)}};B.PlotLineOrBand=function(a,b){this.axis=a;if(b)this.options=b,this.id=b.id};B.PlotLineOrBand.prototype={render:function(){var a=this,b=a.axis,c=b.horiz,d=a.options,e=d.label,f=a.label,g=d.width,h=d.to,i=d.from,k=q(i)&&q(h),j=d.value,l=d.dashStyle,m=a.svgElem,n=[],r,s=d.color,o=p(d.zIndex,0),v=d.events,x={},w=b.chart.renderer;b.isLog&&(i=Da(i),h=Da(h),j=Da(j));if(g){if(n= +b.getPlotLinePath(j,g),x={stroke:s,"stroke-width":g},l)x.dashstyle=l}else if(k){n=b.getPlotBandPath(i,h,d);if(s)x.fill=s;if(d.borderWidth)x.stroke=d.borderColor,x["stroke-width"]=d.borderWidth}else return;x.zIndex=o;if(m)if(n)m.show(),m.animate({d:n});else{if(m.hide(),f)a.label=f=f.destroy()}else if(n&&n.length&&(a.svgElem=m=w.path(n).attr(x).add(),v))for(r in d=function(b){m.on(b,function(c){v[b].apply(a,[c])})},v)d(r);e&&q(e.text)&&n&&n.length&&b.width>0&&b.height>0&&!n.flat?(e=D({align:c&&k&&"center", +x:c?!k&&4:10,verticalAlign:!c&&k&&"middle",y:c?k?16:10:k?6:-4,rotation:c&&!k&&90},e),this.renderLabel(e,n,k,o)):f&&f.hide();return a},renderLabel:function(a,b,c,d){var e=this.label,f=this.axis.chart.renderer;if(!e)e={align:a.textAlign||a.align,rotation:a.rotation},e.zIndex=d,this.label=e=f.text(a.text,0,0,a.useHTML).attr(e).css(a.style).add();d=[b[1],b[4],c?b[6]:b[1]];b=[b[2],b[5],c?b[7]:b[2]];c=Ra(d);f=Ra(b);e.align(a,!1,{x:c,y:f,width:Ea(d)-c,height:Ea(b)-f});e.show()},destroy:function(){oa(this.axis.plotLinesAndBands, +this);delete this.axis;Sa(this)}};var ka=B.Axis=function(){this.init.apply(this,arguments)};ka.prototype={defaultOptions:{dateTimeLabelFormats:{millisecond:"%H:%M:%S.%L",second:"%H:%M:%S",minute:"%H:%M",hour:"%H:%M",day:"%e. %b",week:"%e. %b",month:"%b '%y",year:"%Y"},endOnTick:!1,gridLineColor:"#D8D8D8",labels:{enabled:!0,style:{color:"#606060",cursor:"default",fontSize:"11px"},x:0,y:15},lineColor:"#C0D0E0",lineWidth:1,minPadding:0.01,maxPadding:0.01,minorGridLineColor:"#E0E0E0",minorGridLineWidth:1, +minorTickColor:"#A0A0A0",minorTickLength:2,minorTickPosition:"outside",startOfWeek:1,startOnTick:!1,tickColor:"#C0D0E0",tickLength:10,tickmarkPlacement:"between",tickPixelInterval:100,tickPosition:"outside",title:{align:"middle",style:{color:"#707070"}},type:"linear"},defaultYAxisOptions:{endOnTick:!0,gridLineWidth:1,tickPixelInterval:72,showLastLabel:!0,labels:{x:-8,y:3},lineWidth:0,maxPadding:0.05,minPadding:0.05,startOnTick:!0,title:{rotation:270,text:"Values"},stackLabels:{enabled:!1,formatter:function(){return B.numberFormat(this.total, +-1)},style:D(aa.line.dataLabels.style,{color:"#000000"})}},defaultLeftAxisOptions:{labels:{x:-15,y:null},title:{rotation:270}},defaultRightAxisOptions:{labels:{x:15,y:null},title:{rotation:90}},defaultBottomAxisOptions:{labels:{autoRotation:[-45],x:0,y:null},title:{rotation:0}},defaultTopAxisOptions:{labels:{autoRotation:[-45],x:0,y:-15},title:{rotation:0}},init:function(a,b){var c=b.isX;this.chart=a;this.horiz=a.inverted?!c:c;this.coll=(this.isXAxis=c)?"xAxis":"yAxis";this.opposite=b.opposite;this.side= +b.side||(this.horiz?this.opposite?0:2:this.opposite?1:3);this.setOptions(b);var d=this.options,e=d.type;this.labelFormatter=d.labels.formatter||this.defaultLabelFormatter;this.userOptions=b;this.minPixelPadding=0;this.reversed=d.reversed;this.visible=d.visible!==!1;this.zoomEnabled=d.zoomEnabled!==!1;this.categories=d.categories||e==="category";this.names=this.names||[];this.isLog=e==="logarithmic";this.isDatetimeAxis=e==="datetime";this.isLinked=q(d.linkedTo);this.ticks={};this.labelEdge=[];this.minorTicks= +{};this.plotLinesAndBands=[];this.alternateBands={};this.len=0;this.minRange=this.userMinRange=d.minRange||d.maxZoom;this.range=d.range;this.offset=d.offset||0;this.stacks={};this.oldStacks={};this.stacksTouched=0;this.min=this.max=null;this.crosshair=p(d.crosshair,ta(a.options.tooltip.crosshairs)[c?0:1],!1);var f,d=this.options.events;sa(this,a.axes)===-1&&(c&&!this.isColorAxis?a.axes.splice(a.xAxis.length,0,this):a.axes.push(this),a[this.coll].push(this));this.series=this.series||[];if(a.inverted&& +c&&this.reversed===z)this.reversed=!0;this.removePlotLine=this.removePlotBand=this.removePlotBandOrLine;for(f in d)M(this,f,d[f]);if(this.isLog)this.val2lin=Da,this.lin2val=na},setOptions:function(a){this.options=D(this.defaultOptions,this.isXAxis?{}:this.defaultYAxisOptions,[this.defaultTopAxisOptions,this.defaultRightAxisOptions,this.defaultBottomAxisOptions,this.defaultLeftAxisOptions][this.side],D(N[this.coll],a))},defaultLabelFormatter:function(){var a=this.axis,b=this.value,c=a.categories,d= +this.dateTimeLabelFormat,e=N.lang.numericSymbols,f=e&&e.length,g,h=a.options.labels.format,a=a.isLog?b:a.tickInterval;if(h)g=Ka(h,this);else if(c)g=b;else if(d)g=Qa(d,b);else if(f&&a>=1E3)for(;f--&&g===z;)c=Math.pow(1E3,f+1),a>=c&&b*10%c===0&&e[f]!==null&&(g=B.numberFormat(b/c,-1)+e[f]);g===z&&(g=P(b)>=1E4?B.numberFormat(b,-1):B.numberFormat(b,-1,z,""));return g},getSeriesExtremes:function(){var a=this,b=a.chart;a.hasVisibleSeries=!1;a.dataMin=a.dataMax=a.threshold=null;a.softThreshold=!a.isXAxis; +a.buildStacks&&a.buildStacks();o(a.series,function(c){if(c.visible||!b.options.chart.ignoreHiddenSeries){var d=c.options,e=d.threshold,f;a.hasVisibleSeries=!0;a.isLog&&e<=0&&(e=null);if(a.isXAxis){if(d=c.xData,d.length)a.dataMin=F(p(a.dataMin,d[0]),Ra(d)),a.dataMax=t(p(a.dataMax,d[0]),Ea(d))}else{c.getExtremes();f=c.dataMax;c=c.dataMin;if(q(c)&&q(f))a.dataMin=F(p(a.dataMin,c),c),a.dataMax=t(p(a.dataMax,f),f);if(q(e))a.threshold=e;if(!d.softThreshold||a.isLog)a.softThreshold=!1}}})},translate:function(a, +b,c,d,e,f){var g=this.linkedParent||this,h=1,i=0,k=d?g.oldTransA:g.transA,d=d?g.oldMin:g.min,j=g.minPixelPadding,e=(g.isOrdinal||g.isBroken||g.isLog&&e)&&g.lin2val;if(!k)k=g.transA;if(c)h*=-1,i=g.len;g.reversed&&(h*=-1,i-=h*(g.sector||g.len));b?(a=a*h+i,a-=j,a=a/k+d,e&&(a=g.lin2val(a))):(e&&(a=g.val2lin(a)),f==="between"&&(f=0.5),a=h*(a-d)*k+i+h*j+(ma(f)?k*f*g.pointRange:0));return a},toPixels:function(a,b){return this.translate(a,!1,!this.horiz,null,!0)+(b?0:this.pos)},toValue:function(a,b){return this.translate(a- +(b?0:this.pos),!0,!this.horiz,null,!0)},getPlotLinePath:function(a,b,c,d,e){var f=this.chart,g=this.left,h=this.top,i,k,j=c&&f.oldChartHeight||f.chartHeight,l=c&&f.oldChartWidth||f.chartWidth,m;i=this.transB;var n=function(a,b,c){if(ac)d?a=F(t(b,a),c):m=!0;return a},e=p(e,this.translate(a,null,null,c)),a=c=A(e+i);i=k=A(j-e-i);isNaN(e)?m=!0:this.horiz?(i=h,k=j-this.bottom,a=c=n(a,g,g+this.width)):(a=g,c=l-this.right,i=k=n(i,h,h+this.height));return m&&!d?null:f.renderer.crispLine(["M",a,i,"L", +c,k],b||1)},getLinearTickPositions:function(a,b,c){var d,e=fa(T(b/a)*a),f=fa(ua(c/a)*a),g=[];if(b===c&&ma(b))return[b];for(b=e;b<=f;){g.push(b);b=fa(b+a);if(b===d)break;d=b}return g},getMinorTickPositions:function(){var a=this.options,b=this.tickPositions,c=this.minorTickInterval,d=[],e,f=this.pointRangePadding||0;e=this.min-f;var f=this.max+f,g=f-e;if(g&&g/c=this.minRange,f,g,h,i,k,j;if(this.isXAxis&&this.minRange===z&&!this.isLog)q(a.min)||q(a.max)?this.minRange=null:(o(this.series,function(a){i=a.xData;for(g=k=a.xIncrement?1:i.length-1;g>0;g--)if(h=i[g]- +i[g-1],f===z||h=n?(s=n,k=0):b.dataMax<=n&&(R=n,i=0)),b.min=p(v,s,b.dataMin),b.max=p(x,R,b.dataMax));if(e)!a&&F(b.min,p(b.dataMin,b.min))<=0&&X(10,1),b.min=fa(Da(b.min),15),b.max=fa(Da(b.max),15);if(b.range&&q(b.max))b.userMin=b.min=v=t(b.min,b.minFromRange()),b.userMax=x=b.max,b.range=null;b.beforePadding&&b.beforePadding();b.adjustForMinRange();if(!m&&!b.axisPointRange&&!b.usePercentage&&!h&&q(b.min)&&q(b.max)&&(c=b.max-b.min))!q(v)&&k&&(b.min-=c*k),!q(x)&& +i&&(b.max+=c*i);if(ma(d.floor))b.min=t(b.min,d.floor);if(ma(d.ceiling))b.max=F(b.max,d.ceiling);if(r&&q(b.dataMin))if(n=n||0,!q(v)&&b.min=n)b.min=n;else if(!q(x)&&b.max>n&&b.dataMax<=n)b.max=n;b.tickInterval=b.min===b.max||b.min===void 0||b.max===void 0?1:h&&!j&&l===b.linkedParent.options.tickPixelInterval?j=b.linkedParent.tickInterval:p(j,this.tickAmount?(b.max-b.min)/t(this.tickAmount-1,1):void 0,m?1:(b.max-b.min)*l/t(b.len,l));g&&!a&&o(b.series,function(a){a.processData(b.min!==b.oldMin|| +b.max!==b.oldMax)});b.setAxisTranslation(!0);b.beforeSetTickPositions&&b.beforeSetTickPositions();if(b.postProcessTickInterval)b.tickInterval=b.postProcessTickInterval(b.tickInterval);if(b.pointRange&&!j)b.tickInterval=t(b.pointRange,b.tickInterval);a=p(d.minTickInterval,b.isDatetimeAxis&&b.closestPointRange);if(!j&&b.tickInterval0.5&&b.tickInterval<5&&b.max>1E3&&b.max<9999)), +!!this.tickAmount);if(!this.tickAmount&&this.len)b.tickInterval=b.unsquish();this.setTickPositions()},setTickPositions:function(){var a=this.options,b,c=a.tickPositions,d=a.tickPositioner,e=a.startOnTick,f=a.endOnTick,g;this.tickmarkOffset=this.categories&&a.tickmarkPlacement==="between"&&this.tickInterval===1?0.5:0;this.minorTickInterval=a.minorTickInterval==="auto"&&this.tickInterval?this.tickInterval/5:a.minorTickInterval;this.tickPositions=b=c&&c.slice();if(!b&&(b=this.isDatetimeAxis?this.getTimeTicks(this.normalizeTimeTickInterval(this.tickInterval, +a.units),this.min,this.max,a.startOfWeek,this.ordinalPositions,this.closestPointRange,!0):this.isLog?this.getLogTickPositions(this.tickInterval,this.min,this.max):this.getLinearTickPositions(this.tickInterval,this.min,this.max),b.length>this.len&&(b=[b[0],b.pop()]),this.tickPositions=b,d&&(d=d.apply(this,[this.min,this.max]))))this.tickPositions=b=d;if(!this.isLinked)this.trimTicks(b,e,f),this.min===this.max&&q(this.min)&&!this.tickAmount&&(g=!0,this.min-=0.5,this.max+=0.5),this.single=g,!c&&!d&& +this.adjustTickAmount()},trimTicks:function(a,b,c){var d=a[0],e=a[a.length-1],f=this.minPointOffset||0;if(b)this.min=d;else for(;this.min-f>a[0];)a.shift();if(c)this.max=e;else for(;this.max+fc&&(this.tickInterval*=2,this.setTickPositions());if(q(d)){for(a=c=b.length;a--;)(d===3&&a%2===1||d<=2&&a>0&&a=e&&(b=e));this.displayBtn=a!==z||b!==z;this.setExtremes(a,b,!1,z,{trigger:"zoom"});return!0},setAxisSize:function(){var a=this.chart,b=this.options,c=b.offsetLeft||0,d=this.horiz,e=p(b.width,a.plotWidth-c+(b.offsetRight||0)),f=p(b.height,a.plotHeight),g=p(b.top,a.plotTop),b=p(b.left,a.plotLeft+c),c=/%$/;c.test(f)&&(f=Math.round(parseFloat(f)/ +100*a.plotHeight));c.test(g)&&(g=Math.round(parseFloat(g)/100*a.plotHeight+a.plotTop));this.left=b;this.top=g;this.width=e;this.height=f;this.bottom=a.chartHeight-f-g;this.right=a.chartWidth-e-b;this.len=t(d?e:f,0);this.pos=d?b:g},getExtremes:function(){var a=this.isLog;return{min:a?fa(na(this.min)):this.min,max:a?fa(na(this.max)):this.max,dataMin:this.dataMin,dataMax:this.dataMax,userMin:this.userMin,userMax:this.userMax}},getThreshold:function(a){var b=this.isLog,c=b?na(this.min):this.min,b=b?na(this.max): +this.max;a===null?a=b<0?b:c:c>a?a=c:b15&&a<165?"right":a>195&&a<345?"left":"center"},unsquish:function(){var a=this.ticks,b=this.options.labels,c=this.horiz,d=this.tickInterval,e=d,f=this.len/(((this.categories?1:0)+this.max-this.min)/d),g,h=b.rotation,i=this.chart.renderer.fontMetrics(b.style.fontSize,a[0]&&a[0].label),k,j=Number.MAX_VALUE,l,m=function(a){a/=f||1;a=a>1?ua(a):1;return a* +d};c?(l=!b.staggerLines&&!b.step&&(q(h)?[h]:f=-90&&a<=90)k=m(P(i.h/$(ga*a))),b=k+P(a/360),bm)m=a.labelLength}),m>i&&m>h.h?k.rotation=this.labelRotation:this.labelRotation=0;else if(g&&(l={width:i+"px"},!j)){l.textOverflow="clip";for(n=c.length;!f&&n--;)if(r=c[n],i=d[r].label)if(i.styles.textOverflow=== +"ellipsis"&&i.css({textOverflow:"clip"}),i.getBBox().height>this.len/c.length-(h.h-h.f)||d[r].labelLength>g)i.specCss={textOverflow:"ellipsis"}}if(k.rotation&&(l={width:(m>a.chartHeight*0.5?a.chartHeight*0.33:a.chartHeight)+"px"},!j))l.textOverflow="ellipsis";if(this.labelAlign=e.align||this.autoLabelAlign(this.labelRotation))k.align=this.labelAlign;o(c,function(a){var b=(a=d[a])&&a.label;if(b)b.attr(k),l&&b.css(D(l,b.specCss)),delete b.specCss,a.rotation=k.rotation});this.tickRotCorr=b.rotCorr(h.b, +this.labelRotation||0,this.side!==0)},hasData:function(){return this.hasVisibleSeries||q(this.min)&&q(this.max)&&!!this.tickPositions},getOffset:function(){var a=this,b=a.chart,c=b.renderer,d=a.options,e=a.tickPositions,f=a.ticks,g=a.horiz,h=a.side,i=b.inverted?[1,0,3,2][h]:h,k,j,l=0,m,n=0,r=d.title,s=d.labels,R=0,v=a.opposite,x=b.axisOffset,b=b.clipOffset,w=[-1,1,1,-1][h],u,ba=a.axisParent;k=a.hasData();a.showAxis=j=k||p(d.showEmpty,!0);a.staggerLines=a.horiz&&s.staggerLines;if(!a.axisGroup)a.gridGroup= +c.g("grid").attr({zIndex:d.gridZIndex||1}).add(ba),a.axisGroup=c.g("axis").attr({zIndex:d.zIndex||2}).add(ba),a.labelGroup=c.g("axis-labels").attr({zIndex:s.zIndex||7}).addClass("highcharts-"+a.coll.toLowerCase()+"-labels").add(ba);if(k||a.isLinked){if(o(e,function(b){f[b]?f[b].addLabel():f[b]=new Va(a,b)}),a.renderUnsquish(),s.reserveSpace!==!1&&(h===0||h===2||{1:"left",3:"right"}[h]===a.labelAlign||a.labelAlign==="center")&&o(e,function(a){R=t(f[a].getLabelSize(),R)}),a.staggerLines)R*=a.staggerLines, +a.labelOffset=R*(a.opposite?-1:1)}else for(u in f)f[u].destroy(),delete f[u];if(r&&r.text&&r.enabled!==!1){if(!a.axisTitle)a.axisTitle=c.text(r.text,0,0,r.useHTML).attr({zIndex:7,rotation:r.rotation||0,align:r.textAlign||{low:v?"right":"left",middle:"center",high:v?"left":"right"}[r.align]}).addClass("highcharts-"+this.coll.toLowerCase()+"-title").css(r.style).add(a.axisGroup),a.axisTitle.isNew=!0;if(j)l=a.axisTitle.getBBox()[g?"height":"width"],m=r.offset,n=q(m)?0:p(r.margin,g?5:10);a.axisTitle[j? +"show":"hide"](!0)}a.offset=w*p(d.offset,x[h]);a.tickRotCorr=a.tickRotCorr||{x:0,y:0};c=h===2?a.tickRotCorr.y:0;g=Math.abs(R)+n+(R&&w*(g?p(s.y,a.tickRotCorr.y+8):s.x)-c);a.axisTitleMargin=p(m,g);x[h]=t(x[h],a.axisTitleMargin+l+w*a.offset,g);d=d.offset?0:T(d.lineWidth/2)*2;b[i]=t(b[i],d)},getLinePath:function(a){var b=this.chart,c=this.opposite,d=this.offset,e=this.horiz,f=this.left+(c?this.width:0)+d,d=b.chartHeight-this.bottom-(c?this.height:0)+d;c&&(a*=-1);return b.renderer.crispLine(["M",e?this.left: +f,e?d:this.top,"L",e?b.chartWidth-this.right:f,e?d:b.chartHeight-this.bottom],a)},getTitlePosition:function(){var a=this.horiz,b=this.left,c=this.top,d=this.len,e=this.options.title,f=a?b:c,g=this.opposite,h=this.offset,i=e.x||0,k=e.y||0,j=C(e.style.fontSize||12),d={low:f+(a?0:d),middle:f+d/2,high:f+(a?d:0)}[e.align],b=(a?c+this.height:b)+(a?1:-1)*(g?-1:1)*this.axisTitleMargin+(this.side===2?j:0);return{x:a?d+i:b+(g?this.width:0)+h+i,y:a?b+k-(g?this.height:0)+h:d+k}},render:function(){var a=this, +b=a.chart,c=b.renderer,d=a.options,e=a.isLog,f=a.isLinked,g=a.tickPositions,h=a.axisTitle,i=a.ticks,k=a.minorTicks,j=a.alternateBands,l=d.stackLabels,m=d.alternateGridColor,n=a.tickmarkOffset,r=d.lineWidth,s,p=b.hasRendered&&q(a.oldMin)&&!isNaN(a.oldMin),v=a.showAxis,x=c.globalAnimation,w,t;a.labelEdge.length=0;a.overlap=!1;o([i,k,j],function(a){for(var b in a)a[b].isActive=!1});if(a.hasData()||f){a.minorTickInterval&&!a.categories&&o(a.getMinorTickPositions(),function(b){k[b]||(k[b]=new Va(a,b,"minor")); +p&&k[b].isNew&&k[b].render(null,!0);k[b].render(null,!1,1)});if(g.length&&(o(g,function(b,c){if(!f||b>=a.min&&b<=a.max)i[b]||(i[b]=new Va(a,b)),p&&i[b].isNew&&i[b].render(c,!0,0.1),i[b].render(c)}),n&&(a.min===0||a.single)))i[-1]||(i[-1]=new Va(a,-1,null,!0)),i[-1].render(-1);m&&o(g,function(c,d){t=g[d+1]!==z?g[d+1]+n:a.max-n;if(d%2===0&&c=G.second?0:j*T(i.getMilliseconds()/j));if(k>=G.second)i[Hb](k>=G.minute?0:j*T(i.getSeconds()/j));if(k>=G.minute)i[Ib](k>=G.hour?0:j*T(i[tb]()/j));if(k>=G.hour)i[Jb](k>=G.day?0:j*T(i[ub]()/j));if(k>=G.day)i[wb](k>=G.month? +1:j*T(i[$a]()/j));k>=G.month&&(i[xb](k>=G.year?0:j*T(i[ab]()/j)),h=i[bb]());k>=G.year&&(h-=h%j,i[yb](h));if(k===G.week)i[wb](i[$a]()-i[vb]()+p(d,1));b=1;if(qb||Za)i=i.getTime(),i=new qa(i+Ya(i));h=i[bb]();for(var d=i.getTime(),l=i[ab](),m=i[$a](),n=!g||!!Za,r=(G.day+(g?Ya(i):i.getTimezoneOffset()*6E4))%G.day;d=0.5)a=A(a),g=this.getLinearTickPositions(a,b,c);else if(a>=0.08)for(var f=T(b),h,i,k,j,l,e=a>0.3?[1,2,4]:a>0.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9];fb&&(!d||j<=c)&&j!==z&&g.push(j),j>c&&(l=!0),j=k}else if(b=na(b),c=na(c),a=e[d? +"minorTickInterval":"tickInterval"],a=p(a==="auto"?null:a,this._minorAutoInterval,(c-b)*(e.tickPixelInterval/(d?5:1))/((d?f/this.tickPositions.length:f)||1)),a=sb(a,null,rb(a)),g=Ba(this.getLinearTickPositions(a,b,c),Da),!d)this._minorAutoInterval=a/5;if(!d)this.tickInterval=a;return g};var Pb=B.Tooltip=function(){this.init.apply(this,arguments)};Pb.prototype={init:function(a,b){var c=b.borderWidth,d=b.style,e=C(d.padding);this.chart=a;this.options=b;this.crosshairs=[];this.now={x:0,y:0};this.isHidden= +!0;this.label=a.renderer.label("",0,0,b.shape||"callout",null,null,b.useHTML,null,"tooltip").attr({padding:e,fill:b.backgroundColor,"stroke-width":c,r:b.borderRadius,zIndex:8}).css(d).css({padding:0}).add().attr({y:-9999});ha||this.label.shadow(b.shadow);this.shared=b.shared},destroy:function(){if(this.label)this.label=this.label.destroy();clearTimeout(this.hideTimer);clearTimeout(this.tooltipTimeout)},move:function(a,b,c,d){var e=this,f=e.now,g=e.options.animation!==!1&&!e.isHidden&&(P(a-f.x)>1|| +P(b-f.y)>1),h=e.followPointer||e.len>1;u(f,{x:g?(2*f.x+a)/3:a,y:g?(f.y+b)/2:b,anchorX:h?z:g?(2*f.anchorX+c)/3:c,anchorY:h?z:g?(f.anchorY+d)/2:d});e.label.attr(f);if(g)clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(function(){e&&e.move(a,b,c,d)},32)},hide:function(a){var b=this;clearTimeout(this.hideTimer);a=p(a,this.options.hideDelay,500);if(!this.isHidden)this.hideTimer=Pa(function(){b.label[a?"fadeOut":"hide"]();b.isHidden=!0},a)},getAnchor:function(a,b){var c,d=this.chart,e=d.inverted, +f=d.plotTop,g=d.plotLeft,h=0,i=0,k,j,a=ta(a);c=a[0].tooltipPos;this.followPointer&&b&&(b.chartX===z&&(b=d.pointer.normalize(b)),c=[b.chartX-d.plotLeft,b.chartY-f]);c||(o(a,function(a){k=a.series.yAxis;j=a.series.xAxis;h+=a.plotX+(!e&&j?j.left-g:0);i+=(a.plotLow?(a.plotLow+a.plotHigh)/2:a.plotY)+(!e&&k?k.top-f:0)}),h/=a.length,i/=a.length,c=[e?d.plotWidth-i:h,this.shared&&!e&&a.length>1&&b?b.chartY-f:e?d.plotHeight-h:i]);return Ba(c,A)},getPosition:function(a,b,c){var d=this.chart,e=this.distance, +f={},g=c.h||0,h,i=["y",d.chartHeight,b,c.plotY+d.plotTop,d.plotTop,d.plotTop+d.plotHeight],k=["x",d.chartWidth,a,c.plotX+d.plotLeft,d.plotLeft,d.plotLeft+d.plotWidth],j=p(c.ttBelow,d.inverted&&!c.negative||!d.inverted&&c.negative),l=function(a,b,c,d,h,i){var k=cb?d:d+g);else return!1},m=function(a,b,c,d){var g;db-e?g=!1:f[a]=db-c/2?b-c-2:d-c/2;return g},n=function(a){var b= +i;i=k;k=b;h=a},r=function(){l.apply(0,i)!==!1?m.apply(0,k)===!1&&!h&&(n(!0),r()):h?f.x=f.y=0:(n(!0),r())};(d.inverted||this.len>1)&&n();r();return f},defaultFormatter:function(a){var b=this.points||ta(this),c;c=[a.tooltipFooterHeaderFormatter(b[0])];c=c.concat(a.bodyFormatter(b));c.push(a.tooltipFooterHeaderFormatter(b[0],!0));return c.join("")},refresh:function(a,b){var c=this.chart,d=this.label,e=this.options,f,g,h,i={},k,j=[];k=e.formatter||this.defaultFormatter;var i=c.hoverPoints,l,m=this.shared; +clearTimeout(this.hideTimer);this.followPointer=ta(a)[0].series.tooltipOptions.followPointer;h=this.getAnchor(a,b);f=h[0];g=h[1];m&&(!a.series||!a.series.noSharedTooltip)?(c.hoverPoints=a,i&&o(i,function(a){a.setState()}),o(a,function(a){a.setState("hover");j.push(a.getLabelConfig())}),i={x:a[0].category,y:a[0].y},i.points=j,this.len=j.length,a=a[0]):i=a.getLabelConfig();k=k.call(i,this);i=a.series;this.distance=p(i.tooltipOptions.distance,16);k===!1?this.hide():(this.isHidden&&(Oa(d),d.attr("opacity", +1).show()),d.attr({text:k}),l=e.borderColor||a.color||i.color||"#606060",d.attr({stroke:l}),this.updatePosition({plotX:f,plotY:g,negative:a.negative,ttBelow:a.ttBelow,h:h[2]||0}),this.isHidden=!1);H(c,"tooltipRefresh",{text:k,x:f+c.plotLeft,y:g+c.plotTop,borderColor:l})},updatePosition:function(a){var b=this.chart,c=this.label,c=(this.options.positioner||this.getPosition).call(this,c.width,c.height,a);this.move(A(c.x),A(c.y||0),a.plotX+b.plotLeft,a.plotY+b.plotTop)},getXDateFormat:function(a,b,c){var d, +b=b.dateTimeLabelFormats,e=c&&c.closestPointRange,f,g={millisecond:15,second:12,minute:9,hour:6,day:3},h,i="millisecond";if(e){h=Qa("%m-%d %H:%M:%S.%L",a.x);for(f in G){if(e===G.week&&+Qa("%w",a.x)===c.options.startOfWeek&&h.substr(6)==="00:00:00.000"){f="week";break}if(G[f]>e){f=i;break}if(g[f]&&h.substr(g[f])!=="01-01 00:00:00.000".substr(g[f]))break;f!=="week"&&(i=f)}f&&(d=b[f])}else d=b.day;return d||b.year},tooltipFooterHeaderFormatter:function(a,b){var c=b?"footer":"header",d=a.series,e=d.tooltipOptions, +f=e.xDateFormat,g=d.xAxis,h=g&&g.options.type==="datetime"&&ma(a.key),c=e[c+"Format"];h&&!f&&(f=this.getXDateFormat(a,e,g));h&&f&&(c=c.replace("{point.key}","{point.key:"+f+"}"));return Ka(c,{point:a,series:d})},bodyFormatter:function(a){return Ba(a,function(a){var c=a.series.tooltipOptions;return(c.pointFormatter||a.point.tooltipFormatter).call(a.point,c.pointFormat)})}};var ea;db=y&&y.documentElement.ontouchstart!==z;var Xa=B.Pointer=function(a,b){this.init(a,b)};Xa.prototype={init:function(a,b){var c= +b.chart,d=c.events,e=ha?"":c.zoomType,c=a.inverted,f;this.options=b;this.chart=a;this.zoomX=f=/x/.test(e);this.zoomY=e=/y/.test(e);this.zoomHor=f&&!c||e&&c;this.zoomVert=e&&!c||f&&c;this.hasZoom=f||e;this.runChartClick=d&&!!d.click;this.pinchDown=[];this.lastValidTouch={};if(B.Tooltip&&b.tooltip.enabled)a.tooltip=new Pb(a,b.tooltip),this.followTouchMove=p(b.tooltip.followTouchMove,!0);this.setDOMEvents()},normalize:function(a,b){var c,d,a=a||E.event;if(!a.target)a.target=a.srcElement;d=a.touches? +a.touches.length?a.touches.item(0):a.changedTouches[0]:a;if(!b)this.chartPosition=b=Ab(this.chart.container);d.pageX===z?(c=t(a.x,a.clientX-b.left),d=a.y):(c=d.pageX-b.left,d=d.pageY-b.top);return u(a,{chartX:A(c),chartY:A(d)})},getCoordinates:function(a){var b={xAxis:[],yAxis:[]};o(this.chart.axes,function(c){b[c.isXAxis?"xAxis":"yAxis"].push({axis:c,value:c.toValue(a[c.horiz?"chartX":"chartY"])})});return b},runPointActions:function(a){var b=this.chart,c=b.series,d=b.tooltip,e=d?d.shared:!1,f=b.hoverPoint, +g=b.hoverSeries,h=[Number.MAX_VALUE,Number.MAX_VALUE],i,k,j=[],l=[],m;if(!e&&!g)for(b=0;bh+k&&(d=h+k),ei+j&&(e=i+j),this.hasDragged=Math.sqrt(Math.pow(n-d,2)+Math.pow(r-e,2)),this.hasDragged>10){l=b.isInsidePlot(n-h,r-i);if(b.hasCartesianSeries&&(this.zoomX||this.zoomY)&&l&&!s&&!m)this.selectionMarker=m=b.renderer.rect(h,i,f?1:k,g?1:j,0).attr({fill:c.selectionMarkerFill||"rgba(69,114,167,0.25)",zIndex:7}).add();m&&f&&(d-=n,m.attr({width:P(d),x:(d>0?0:d)+n})); +m&&g&&(d=e-r,m.attr({height:P(d),y:(d>0?0:d)+r}));l&&!m&&c.panning&&b.pan(a,c.panning)}},drop:function(a){var b=this,c=this.chart,d=this.hasPinched;if(this.selectionMarker){var e={originalEvent:a,xAxis:[],yAxis:[]},f=this.selectionMarker,g=f.attr?f.attr("x"):f.x,h=f.attr?f.attr("y"):f.y,i=f.attr?f.attr("width"):f.width,k=f.attr?f.attr("height"):f.height,j;if(this.hasDragged||d)o(c.axes,function(c){if(c.zoomEnabled&&q(c.min)&&(d||b[{xAxis:"zoomX",yAxis:"zoomY"}[c.coll]])){var f=c.horiz,n=a.type=== +"touchend"?c.minPixelPadding:0,r=c.toValue((f?g:h)+n),f=c.toValue((f?g+i:h+k)-n);e[c.coll].push({axis:c,min:F(r,f),max:t(r,f)});j=!0}}),j&&H(c,"selection",e,function(a){c.zoom(u(a,d?{animation:!1}:null))});this.selectionMarker=this.selectionMarker.destroy();d&&this.scaleGroups()}if(c)L(c.container,{cursor:c._cursor}),c.cancelClick=this.hasDragged>10,c.mouseIsDown=this.hasDragged=this.hasPinched=!1,this.pinchDown=[]},onContainerMouseDown:function(a){a=this.normalize(a);a.preventDefault&&a.preventDefault(); +this.dragStart(a)},onDocumentMouseUp:function(a){S[ea]&&S[ea].pointer.drop(a)},onDocumentMouseMove:function(a){var b=this.chart,c=this.chartPosition,a=this.normalize(a,c);c&&!this.inClass(a.target,"highcharts-tracker")&&!b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)&&this.reset()},onContainerMouseLeave:function(a){var b=S[ea];if(b&&(a.relatedTarget||a.toElement))b.pointer.reset(),b.pointer.chartPosition=null},onContainerMouseMove:function(a){var b=this.chart;if(!q(ea)||!S[ea]||!S[ea].mouseIsDown)ea= +b.index;a=this.normalize(a);a.returnValue=!1;b.mouseIsDown==="mousedown"&&this.drag(a);(this.inClass(a.target,"highcharts-tracker")||b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop))&&!b.openMenu&&this.runPointActions(a)},inClass:function(a,b){for(var c;a;){if(c=K(a,"class")){if(c.indexOf(b)!==-1)return!0;if(c.indexOf("highcharts-container")!==-1)return!1}a=a.parentNode}},onTrackerMouseOut:function(a){var b=this.chart.hoverSeries,a=a.relatedTarget||a.toElement;if(b&&a&&!b.options.stickyTracking&& +!this.inClass(a,"highcharts-tooltip")&&!this.inClass(a,"highcharts-series-"+b.index))b.onMouseOut()},onContainerClick:function(a){var b=this.chart,c=b.hoverPoint,d=b.plotLeft,e=b.plotTop,a=this.normalize(a);b.cancelClick||(c&&this.inClass(a.target,"highcharts-tracker")?(H(c.series,"click",u(a,{point:c})),b.hoverPoint&&c.firePointEvent("click",a)):(u(a,this.getCoordinates(a)),b.isInsidePlot(a.chartX-d,a.chartY-e)&&H(b,"click",a)))},setDOMEvents:function(){var a=this,b=a.chart.container;b.onmousedown= +function(b){a.onContainerMouseDown(b)};b.onmousemove=function(b){a.onContainerMouseMove(b)};b.onclick=function(b){a.onContainerClick(b)};M(b,"mouseleave",a.onContainerMouseLeave);eb===1&&M(y,"mouseup",a.onDocumentMouseUp);if(db)b.ontouchstart=function(b){a.onContainerTouchStart(b)},b.ontouchmove=function(b){a.onContainerTouchMove(b)},eb===1&&M(y,"touchend",a.onDocumentTouchEnd)},destroy:function(){var a;V(this.chart.container,"mouseleave",this.onContainerMouseLeave);eb||(V(y,"mouseup",this.onDocumentMouseUp), +V(y,"touchend",this.onDocumentTouchEnd));clearInterval(this.tooltipTimeout);for(a in this)this[a]=null}};u(B.Pointer.prototype,{pinchTranslate:function(a,b,c,d,e,f){(this.zoomHor||this.pinchHor)&&this.pinchTranslateDirection(!0,a,b,c,d,e,f);(this.zoomVert||this.pinchVert)&&this.pinchTranslateDirection(!1,a,b,c,d,e,f)},pinchTranslateDirection:function(a,b,c,d,e,f,g,h){var i=this.chart,k=a?"x":"y",j=a?"X":"Y",l="chart"+j,m=a?"width":"height",n=i["plot"+(a?"Left":"Top")],r,s,p=h||1,o=i.inverted,x=i.bounds[a? +"h":"v"],w=b.length===1,q=b[0][l],t=c[0][l],u=!w&&b[1][l],A=!w&&c[1][l],B,c=function(){!w&&P(q-u)>20&&(p=h||P(t-A)/P(q-u));s=(n-t)/p+q;r=i["plot"+(a?"Width":"Height")]/p};c();b=s;bx.max&&(b=x.max-r,B=!0);B?(t-=0.8*(t-g[k][0]),w||(A-=0.8*(A-g[k][1])),c()):g[k]=[t,A];o||(f[k]=s-n,f[m]=r);f=o?1/p:p;e[m]=r;e[k]=b;d[o?a?"scaleY":"scaleX":"scale"+j]=p;d["translate"+j]=f*n+(t-f*q)},pinch:function(a){var b=this,c=b.chart,d=b.pinchDown,e=a.touches,f=e.length,g=b.lastValidTouch,h= +b.hasZoom,i=b.selectionMarker,k={},j=f===1&&(b.inClass(a.target,"highcharts-tracker")&&c.runTrackerClick||b.runChartClick),l={};if(f>1)b.initiated=!0;h&&b.initiated&&!j&&a.preventDefault();Ba(e,function(a){return b.normalize(a)});if(a.type==="touchstart")o(e,function(a,b){d[b]={chartX:a.chartX,chartY:a.chartY}}),g.x=[d[0].chartX,d[1]&&d[1].chartX],g.y=[d[0].chartY,d[1]&&d[1].chartY],o(c.axes,function(a){if(a.zoomEnabled){var b=c.bounds[a.horiz?"h":"v"],d=a.minPixelPadding,e=a.toPixels(p(a.options.min, +a.dataMin)),f=a.toPixels(p(a.options.max,a.dataMax)),g=F(e,f),e=t(e,f);b.min=F(a.pos,g-d);b.max=t(a.pos+a.len,e+d)}}),b.res=!0;else if(d.length){if(!i)b.selectionMarker=i=u({destroy:Aa,touch:!0},c.plotBox);b.pinchTranslate(d,e,k,i,l,g);b.hasPinched=h;b.scaleGroups(k,l);if(!h&&b.followTouchMove&&f===1)this.runPointActions(b.normalize(a));else if(b.res)b.res=!1,this.reset(!1,0)}},touch:function(a,b){var c=this.chart;ea=c.index;a.touches.length===1?(a=this.normalize(a),c.isInsidePlot(a.chartX-c.plotLeft, +a.chartY-c.plotTop)&&!c.openMenu?(b&&this.runPointActions(a),this.pinch(a)):b&&this.reset()):a.touches.length===2&&this.pinch(a)},onContainerTouchStart:function(a){this.touch(a,!0)},onContainerTouchMove:function(a){this.touch(a)},onDocumentTouchEnd:function(a){S[ea]&&S[ea].pointer.drop(a)}});if(E.PointerEvent||E.MSPointerEvent){var va={},Db=!!E.PointerEvent,Sb=function(){var a,b=[];b.item=function(a){return this[a]};for(a in va)va.hasOwnProperty(a)&&b.push({pageX:va[a].pageX,pageY:va[a].pageY,target:va[a].target}); +return b},Eb=function(a,b,c,d){if((a.pointerType==="touch"||a.pointerType===a.MSPOINTER_TYPE_TOUCH)&&S[ea])d(a),d=S[ea].pointer,d[b]({type:c,target:a.currentTarget,preventDefault:Aa,touches:Sb()})};u(Xa.prototype,{onContainerPointerDown:function(a){Eb(a,"onContainerTouchStart","touchstart",function(a){va[a.pointerId]={pageX:a.pageX,pageY:a.pageY,target:a.currentTarget}})},onContainerPointerMove:function(a){Eb(a,"onContainerTouchMove","touchmove",function(a){va[a.pointerId]={pageX:a.pageX,pageY:a.pageY}; +if(!va[a.pointerId].target)va[a.pointerId].target=a.currentTarget})},onDocumentPointerUp:function(a){Eb(a,"onDocumentTouchEnd","touchend",function(a){delete va[a.pointerId]})},batchMSEvents:function(a){a(this.chart.container,Db?"pointerdown":"MSPointerDown",this.onContainerPointerDown);a(this.chart.container,Db?"pointermove":"MSPointerMove",this.onContainerPointerMove);a(y,Db?"pointerup":"MSPointerUp",this.onDocumentPointerUp)}});fb(Xa.prototype,"init",function(a,b,c){a.call(this,b,c);this.hasZoom&& +L(b.container,{"-ms-touch-action":"none","touch-action":"none"})});fb(Xa.prototype,"setDOMEvents",function(a){a.apply(this);(this.hasZoom||this.followTouchMove)&&this.batchMSEvents(M)});fb(Xa.prototype,"destroy",function(a){this.batchMSEvents(V);a.call(this)})}var ob=B.Legend=function(a,b){this.init(a,b)};ob.prototype={init:function(a,b){var c=this,d=b.itemStyle,e=b.itemMarginTop||0;this.options=b;if(b.enabled)c.itemStyle=d,c.itemHiddenStyle=D(d,b.itemHiddenStyle),c.itemMarginTop=e,c.padding=d=p(b.padding, +8),c.initialItemX=d,c.initialItemY=d-5,c.maxItemWidth=0,c.chart=a,c.itemHeight=0,c.symbolWidth=p(b.symbolWidth,16),c.pages=[],c.render(),M(c.chart,"endResize",function(){c.positionCheckboxes()})},colorizeItem:function(a,b){var c=this.options,d=a.legendItem,e=a.legendLine,f=a.legendSymbol,g=this.itemHiddenStyle.color,c=b?c.itemStyle.color:g,h=b?a.legendColor||a.color||"#CCC":g,g=a.options&&a.options.marker,i={fill:h},k;d&&d.css({fill:c,color:c});e&&e.attr({stroke:h});if(f){if(g&&f.isMarker)for(k in i.stroke= +h,g=a.convertAttribs(g),g)d=g[k],d!==z&&(i[k]=d);f.attr(i)}},positionItem:function(a){var b=this.options,c=b.symbolPadding,b=!b.rtl,d=a._legendItemPos,e=d[0],d=d[1],f=a.checkbox;(a=a.legendGroup)&&a.element&&a.translate(b?e:this.legendWidth-e-2*c-4,d);if(f)f.x=e,f.y=d},destroyItem:function(a){var b=a.checkbox;o(["legendItem","legendLine","legendSymbol","legendGroup"],function(b){a[b]&&(a[b]=a[b].destroy())});b&&Ta(a.checkbox)},destroy:function(){var a=this.group,b=this.box;if(b)this.box=b.destroy(); +if(a)this.group=a.destroy()},positionCheckboxes:function(a){var b=this.group.alignAttr,c,d=this.clipHeight||this.legendHeight,e=this.titleHeight;if(b)c=b.translateY,o(this.allItems,function(f){var g=f.checkbox,h;g&&(h=c+e+g.y+(a||0)+3,L(g,{left:b.translateX+f.checkboxOffset+g.x-20+"px",top:h+"px",display:h>c-6&&h(m||b.chartWidth-2*k-s-d.x))this.itemX=s,this.itemY+=r+this.lastLineHeight+n,this.lastLineHeight=0;this.maxItemWidth=t(this.maxItemWidth, +f);this.lastItemY=r+this.itemY+n;this.lastLineHeight=t(g,this.lastLineHeight);a._legendItemPos=[this.itemX,this.itemY];e?this.itemX+=f:(this.itemY+=r+g+n,this.lastLineHeight=g);this.offsetWidth=m||t((e?this.itemX-s-j:f)+k,this.offsetWidth)},getAllItems:function(){var a=[];o(this.chart.series,function(b){var c=b.options;if(p(c.showInLegend,!q(c.linkedTo)?z:!1,!0))a=a.concat(b.legendItems||(c.legendType==="point"?b.data:b))});return a},adjustMargins:function(a,b){var c=this.chart,d=this.options,e=d.align.charAt(0)+ +d.verticalAlign.charAt(0)+d.layout.charAt(0);this.display&&!d.floating&&o([/(lth|ct|rth)/,/(rtv|rm|rbv)/,/(rbh|cb|lbh)/,/(lbv|lm|ltv)/],function(f,g){f.test(e)&&!q(a[g])&&(c[nb[g]]=t(c[nb[g]],c.legend[(g+1)%2?"legendHeight":"legendWidth"]+[1,-1,-1,1][g]*d[g%2?"x":"y"]+p(d.margin,12)+b[g]))})},render:function(){var a=this,b=a.chart,c=b.renderer,d=a.group,e,f,g,h,i=a.box,k=a.options,j=a.padding,l=k.borderWidth,m=k.backgroundColor;a.itemX=a.initialItemX;a.itemY=a.initialItemY;a.offsetWidth=0;a.lastItemY= +0;if(!d)a.group=d=c.g("legend").attr({zIndex:7}).add(),a.contentGroup=c.g().attr({zIndex:1}).add(d),a.scrollGroup=c.g().add(a.contentGroup);a.renderTitle();e=a.getAllItems();ib(e,function(a,b){return(a.options&&a.options.legendIndex||0)-(b.options&&b.options.legendIndex||0)});k.reversed&&e.reverse();a.allItems=e;a.display=f=!!e.length;a.lastLineHeight=0;o(e,function(b){a.renderItem(b)});g=(k.width||a.offsetWidth)+j;h=a.lastItemY+a.lastLineHeight+a.titleHeight;h=a.handleOverflow(h);h+=j;if(l||m){if(i){if(g> +0&&h>0)i[i.isNew?"attr":"animate"](i.crisp({width:g,height:h})),i.isNew=!1}else a.box=i=c.rect(0,0,g,h,k.borderRadius,l||0).attr({stroke:k.borderColor,"stroke-width":l||0,fill:m||"none"}).add(d).shadow(k.shadow),i.isNew=!0;i[f?"show":"hide"]()}a.legendWidth=g;a.legendHeight=h;o(e,function(b){a.positionItem(b)});f&&d.align(u({width:g,height:h},k),!0,"spacingBox");b.isResizing||this.positionCheckboxes()},handleOverflow:function(a){var b=this,c=this.chart,d=c.renderer,e=this.options,f=e.y,f=c.spacingBox.height+ +(e.verticalAlign==="top"?-f:f)-this.padding,g=e.maxHeight,h,i=this.clipRect,k=e.navigation,j=p(k.animation,!0),l=k.arrowSize||12,m=this.nav,n=this.pages,r=this.padding,s,R=this.allItems,v=function(a){i.attr({height:a});if(b.contentGroup.div)b.contentGroup.div.style.clip="rect("+r+"px,9999px,"+(r+a)+"px,0)"};e.layout==="horizontal"&&(f/=2);g&&(f=F(f,g));n.length=0;if(a>f){this.clipHeight=h=t(f-20-this.titleHeight-r,0);this.currentPage=p(this.currentPage,1);this.fullHeight=a;o(R,function(a,b){var c= +a._legendItemPos[1],d=A(a.legendItem.getBBox().height),e=n.length;if(!e||c-n[e-1]>h&&(s||c)!==n[e-1])n.push(s||c),e++;b===R.length-1&&c+d-n[e-1]>h&&n.push(c);c!==s&&(s=c)});if(!i)i=b.clipRect=d.clipRect(0,r,9999,0),b.contentGroup.clip(i);v(h);if(!m)this.nav=m=d.g().attr({zIndex:1}).add(this.group),this.up=d.symbol("triangle",0,0,l,l).on("click",function(){b.scroll(-1,j)}).add(m),this.pager=d.text("",15,10).css(k.style).add(m),this.down=d.symbol("triangle-down",0,0,l,l).on("click",function(){b.scroll(1, +j)}).add(m);b.scroll(0);a=f}else if(m)v(c.chartHeight),m.hide(),this.scrollGroup.attr({translateY:1}),this.clipHeight=0;return a},scroll:function(a,b){var c=this.pages,d=c.length,e=this.currentPage+a,f=this.clipHeight,g=this.options.navigation,h=g.activeColor,g=g.inactiveColor,i=this.pager,k=this.padding;e>d&&(e=d);if(e>0)b!==z&&Ua(b,this.chart),this.nav.attr({translateX:k,translateY:f+this.padding+7+this.titleHeight,visibility:"visible"}),this.up.attr({fill:e===1?g:h}).css({cursor:e===1?"default": +"pointer"}),i.attr({text:e+"/"+d}),this.down.attr({x:18+this.pager.getBBox().width,fill:e===d?g:h}).css({cursor:e===d?"default":"pointer"}),c=-c[e-1]+this.initialItemY,this.scrollGroup.animate({translateY:c}),this.currentPage=e,this.positionCheckboxes(c)}};J=B.LegendSymbolMixin={drawRectangle:function(a,b){var c=a.options.symbolHeight||a.fontMetrics.f;b.legendSymbol=this.chart.renderer.rect(0,a.baseline-c+1,a.symbolWidth,c,a.options.symbolRadius||0).attr({zIndex:3}).add(b.legendGroup)},drawLineMarker:function(a){var b= +this.options,c=b.marker,d=a.symbolWidth,e=this.chart.renderer,f=this.legendGroup,a=a.baseline-A(a.fontMetrics.b*0.3),g;if(b.lineWidth){g={"stroke-width":b.lineWidth};if(b.dashStyle)g.dashstyle=b.dashStyle;this.legendLine=e.path(["M",0,a,"L",d,a]).attr(g).add(f)}if(c&&c.enabled!==!1)b=c.radius,this.legendSymbol=c=e.symbol(this.symbol,d/2-b,a-b,2*b,2*b,c).add(f),c.isMarker=!0}};(/Trident\/7\.0/.test(za)||Ma)&&fb(ob.prototype,"positionItem",function(a,b){var c=this,d=function(){b._legendItemPos&&a.call(c, +b)};d();setTimeout(d)});var hb=B.Chart=function(){this.getArgs.apply(this,arguments)};B.chart=function(a,b,c){return new hb(a,b,c)};hb.prototype={callbacks:[],getArgs:function(){var a=[].slice.call(arguments);if(xa(a[0])||a[0].nodeName)this.renderTo=a.shift();this.init(a[0],a[1])},init:function(a,b){var c,d=a.series;a.series=null;c=D(N,a);c.series=a.series=d;this.userOptions=a;d=c.chart;this.margin=this.splashArray("margin",d);this.spacing=this.splashArray("spacing",d);var e=d.events;this.bounds= +{h:{},v:{}};this.callback=b;this.isResizing=0;this.options=c;this.axes=[];this.series=[];this.hasCartesianSeries=d.showAxes;var f=this,g;f.index=S.length;S.push(f);eb++;d.reflow!==!1&&M(f,"load",function(){f.initReflow()});if(e)for(g in e)M(f,g,e[g]);f.xAxis=[];f.yAxis=[];f.animation=ha?!1:p(d.animation,!0);f.pointCount=f.colorCounter=f.symbolCounter=0;f.firstRender()},initSeries:function(a){var b=this.options.chart;(b=I[a.type||b.type||b.defaultSeriesType])||X(17,!0);b=new b;b.init(this,a);return b}, +isInsidePlot:function(a,b,c){var d=c?b:a,a=c?a:b;return d>=0&&d<=this.plotWidth&&a>=0&&a<=this.plotHeight},redraw:function(a){var b=this.axes,c=this.series,d=this.pointer,e=this.legend,f=this.isDirtyLegend,g,h,i=this.hasCartesianSeries,k=this.isDirtyBox,j=c.length,l=j,m=this.renderer,n=m.isHidden(),r=[];Ua(a,this);n&&this.cloneRenderTo();for(this.layOutTitles();l--;)if(a=c[l],a.options.stacking&&(g=!0,a.isDirty)){h=!0;break}if(h)for(l=j;l--;)if(a=c[l],a.options.stacking)a.isDirty=!0;o(c,function(a){a.isDirty&& +a.options.legendType==="point"&&(a.updateTotals&&a.updateTotals(),f=!0)});if(f&&e.options.enabled)e.render(),this.isDirtyLegend=!1;g&&this.getStacks();if(i&&!this.isResizing)this.maxTicks=null,o(b,function(a){a.setScale()});this.getMargins();i&&(o(b,function(a){a.isDirty&&(k=!0)}),o(b,function(a){var b=a.min+","+a.max;if(a.extKey!==b)a.extKey=b,r.push(function(){H(a,"afterSetExtremes",u(a.eventArgs,a.getExtremes()));delete a.eventArgs});(k||g)&&a.redraw()}));k&&this.drawChartBox();o(c,function(a){a.isDirty&& +a.visible&&(!a.isCartesian||a.xAxis)&&a.redraw()});d&&d.reset(!0);m.draw();H(this,"redraw");n&&this.cloneRenderTo(!0);o(r,function(a){a.call()})},get:function(a){var b=this.axes,c=this.series,d,e;for(d=0;d19?this.containerHeight:600))},cloneRenderTo:function(a){var b=this.renderToClone,c=this.container;a?b&&(this.renderTo.appendChild(c),Ta(b),delete this.renderToClone):(c&&c.parentNode===this.renderTo&&this.renderTo.removeChild(c),this.renderToClone=b=this.renderTo.cloneNode(0),L(b,{position:"absolute",top:"-9999px",display:"block"}),b.style.setProperty&&b.style.setProperty("display","block", +"important"),y.body.appendChild(b),c&&b.appendChild(c))},getContainer:function(){var a,b=this.options,c=b.chart,d,e;a=this.renderTo;var f="highcharts-"+zb++;if(!a)this.renderTo=a=c.renderTo;if(xa(a))this.renderTo=a=y.getElementById(a);a||X(13,!0);d=C(K(a,"data-highcharts-chart"));!isNaN(d)&&S[d]&&S[d].hasRendered&&S[d].destroy();K(a,"data-highcharts-chart",this.index);a.innerHTML="";!c.skipClone&&!a.offsetWidth&&this.cloneRenderTo();this.getChartSize();d=this.chartWidth;e=this.chartHeight;this.container= +a=Z(La,{className:"highcharts-container"+(c.className?" "+c.className:""),id:f},u({position:"relative",overflow:"hidden",width:d+"px",height:e+"px",textAlign:"left",lineHeight:"normal",zIndex:0,"-webkit-tap-highlight-color":"rgba(0,0,0,0)"},c.style),this.renderToClone||a);this._cursor=a.style.cursor;this.renderer=new (B[c.renderer]||cb)(a,d,e,c.style,c.forExport,b.exporting&&b.exporting.allowHTML);ha&&this.renderer.create(this,a,d,e);this.renderer.chartIndex=this.index},getMargins:function(a){var b= +this.spacing,c=this.margin,d=this.titleOffset;this.resetMargins();if(d&&!q(c[0]))this.plotTop=t(this.plotTop,d+this.options.title.margin+b[0]);this.legend.adjustMargins(c,b);this.extraBottomMargin&&(this.marginBottom+=this.extraBottomMargin);this.extraTopMargin&&(this.plotTop+=this.extraTopMargin);a||this.getAxisMargins()},getAxisMargins:function(){var a=this,b=a.axisOffset=[0,0,0,0],c=a.margin;a.hasCartesianSeries&&o(a.axes,function(a){a.visible&&a.getOffset()});o(nb,function(d,e){q(c[e])||(a[d]+= +b[e])});a.setChartSize()},reflow:function(a){var b=this,c=b.options.chart,d=b.renderTo,e=c.width||ja(d,"width"),f=c.height||ja(d,"height"),c=a?a.target:E;if(!b.hasUserSize&&!b.isPrinting&&e&&f&&(c===E||c===y)){if(e!==b.containerWidth||f!==b.containerHeight)clearTimeout(b.reflowTimeout),b.reflowTimeout=Pa(function(){if(b.container)b.setSize(e,f,!1),b.hasUserSize=null},a?100:0);b.containerWidth=e;b.containerHeight=f}},initReflow:function(){var a=this,b=function(b){a.reflow(b)};M(E,"resize",b);M(a,"destroy", +function(){V(E,"resize",b)})},setSize:function(a,b,c){var d=this,e,f,g=d.renderer;d.isResizing+=1;Ua(c,d);d.oldChartHeight=d.chartHeight;d.oldChartWidth=d.chartWidth;if(q(a))d.chartWidth=e=t(0,A(a)),d.hasUserSize=!!e;if(q(b))d.chartHeight=f=t(0,A(b));a=g.globalAnimation;(a?Wa:L)(d.container,{width:e+"px",height:f+"px"},a);d.setChartSize(!0);g.setSize(e,f,c);d.maxTicks=null;o(d.axes,function(a){a.isDirty=!0;a.setScale()});o(d.series,function(a){a.isDirty=!0});d.isDirtyLegend=!0;d.isDirtyBox=!0;d.layOutTitles(); +d.getMargins();d.redraw(c);d.oldChartHeight=null;H(d,"resize");a=g.globalAnimation;Pa(function(){d&&H(d,"endResize",null,function(){d.isResizing-=1})},a===!1?0:a&&a.duration||500)},setChartSize:function(a){var b=this.inverted,c=this.renderer,d=this.chartWidth,e=this.chartHeight,f=this.options.chart,g=this.spacing,h=this.clipOffset,i,k,j,l;this.plotLeft=i=A(this.plotLeft);this.plotTop=k=A(this.plotTop);this.plotWidth=j=t(0,A(d-i-this.marginRight));this.plotHeight=l=t(0,A(e-k-this.marginBottom));this.plotSizeX= +b?l:j;this.plotSizeY=b?j:l;this.plotBorderWidth=f.plotBorderWidth||0;this.spacingBox=c.spacingBox={x:g[3],y:g[0],width:d-g[3]-g[1],height:e-g[0]-g[2]};this.plotBox=c.plotBox={x:i,y:k,width:j,height:l};d=2*T(this.plotBorderWidth/2);b=ua(t(d,h[3])/2);c=ua(t(d,h[0])/2);this.clipBox={x:b,y:c,width:T(this.plotSizeX-t(d,h[1])/2-b),height:t(0,T(this.plotSizeY-t(d,h[2])/2-c))};a||o(this.axes,function(a){a.setAxisSize();a.setAxisTranslation()})},resetMargins:function(){var a=this;o(nb,function(b,c){a[b]=p(a.margin[c], +a.spacing[c])});a.axisOffset=[0,0,0,0];a.clipOffset=[0,0,0,0]},drawChartBox:function(){var a=this.options.chart,b=this.renderer,c=this.chartWidth,d=this.chartHeight,e=this.chartBackground,f=this.plotBackground,g=this.plotBorder,h=this.plotBGImage,i=a.borderWidth||0,k=a.backgroundColor,j=a.plotBackgroundColor,l=a.plotBackgroundImage,m=a.plotBorderWidth||0,n,r=this.plotLeft,p=this.plotTop,o=this.plotWidth,v=this.plotHeight,x=this.plotBox,w=this.clipRect,t=this.clipBox;n=i+(a.shadow?8:0);if(i||k)if(e)e.animate(e.crisp({width:c- +n,height:d-n}));else{e={fill:k||"none"};if(i)e.stroke=a.borderColor,e["stroke-width"]=i;this.chartBackground=b.rect(n/2,n/2,c-n,d-n,a.borderRadius,i).attr(e).addClass("highcharts-background").add().shadow(a.shadow)}if(j)f?f.animate(x):this.plotBackground=b.rect(r,p,o,v,0).attr({fill:j}).add().shadow(a.plotShadow);if(l)h?h.animate(x):this.plotBGImage=b.image(l,r,p,o,v).add();w?w.animate({width:t.width,height:t.height}):this.clipRect=b.clipRect(t);if(m)g?(g.strokeWidth=-m,g.animate(g.crisp({x:r,y:p, +width:o,height:v}))):this.plotBorder=b.rect(r,p,o,v,0,-m).attr({stroke:a.plotBorderColor,"stroke-width":m,fill:"none",zIndex:1}).add();this.isDirtyBox=!1},propFromSeries:function(){var a=this,b=a.options.chart,c,d=a.options.series,e,f;o(["inverted","angular","polar"],function(g){c=I[b.type||b.defaultSeriesType];f=a[g]||b[g]||c&&c.prototype[g];for(e=d&&d.length;!f&&e--;)(c=I[d[e].type])&&c.prototype[g]&&(f=!0);a[g]=f})},linkSeries:function(){var a=this,b=a.series;o(b,function(a){a.linkedSeries.length= +0});o(b,function(b){var d=b.options.linkedTo;if(xa(d)&&(d=d===":previous"?a.series[b.index-1]:a.get(d)))d.linkedSeries.push(b),b.linkedParent=d,b.visible=p(b.options.visible,d.options.visible,b.visible)})},renderSeries:function(){o(this.series,function(a){a.translate();a.render()})},renderLabels:function(){var a=this,b=a.options.labels;b.items&&o(b.items,function(c){var d=u(b.style,c.style),e=C(d.left)+a.plotLeft,f=C(d.top)+a.plotTop+12;delete d.left;delete d.top;a.renderer.text(c.html,e,f).attr({zIndex:2}).css(d).add()})}, +render:function(){var a=this.axes,b=this.renderer,c=this.options,d,e,f,g;this.setTitle();this.legend=new ob(this,c.legend);this.getStacks&&this.getStacks();this.getMargins(!0);this.setChartSize();d=this.plotWidth;e=this.plotHeight-=21;o(a,function(a){a.setScale()});this.getAxisMargins();f=d/this.plotWidth>1.1;g=e/this.plotHeight>1.05;if(f||g)this.maxTicks=null,o(a,function(a){(a.horiz&&f||!a.horiz&&g)&&a.setTickInterval(!0)}),this.getMargins();this.drawChartBox();this.hasCartesianSeries&&o(a,function(a){a.visible&& +a.render()});if(!this.seriesGroup)this.seriesGroup=b.g("series-group").attr({zIndex:3}).add();this.renderSeries();this.renderLabels();this.showCredits(c.credits);this.hasRendered=!0},showCredits:function(a){if(a.enabled&&!this.credits)this.credits=this.renderer.text(a.text,0,0).on("click",function(){if(a.href)E.location.href=a.href}).attr({align:a.position.align,zIndex:8}).css(a.style).add().align(a.position)},destroy:function(){var a=this,b=a.axes,c=a.series,d=a.container,e,f=d&&d.parentNode;H(a, +"destroy");S[a.index]=z;eb--;a.renderTo.removeAttribute("data-highcharts-chart");V(a);for(e=b.length;e--;)b[e]=b[e].destroy();for(e=c.length;e--;)c[e]=c[e].destroy();o("title,subtitle,chartBackground,plotBackground,plotBGImage,plotBorder,seriesGroup,clipRect,credits,pointer,scroller,rangeSelector,legend,resetZoomButton,tooltip,renderer".split(","),function(b){var c=a[b];c&&c.destroy&&(a[b]=c.destroy())});if(d)d.innerHTML="",V(d),f&&Ta(d);for(e in a)delete a[e]},isReadyToRender:function(){var a=this; +return!ca&&E==E.top&&y.readyState!=="complete"||ha&&!E.canvg?(ha?Ob.push(function(){a.firstRender()},a.options.global.canvasToolsURL):y.attachEvent("onreadystatechange",function(){y.detachEvent("onreadystatechange",a.firstRender);y.readyState==="complete"&&a.firstRender()}),!1):!0},firstRender:function(){var a=this,b=a.options;if(a.isReadyToRender()){a.getContainer();H(a,"init");a.resetMargins();a.setChartSize();a.propFromSeries();a.getAxes();o(b.series||[],function(b){a.initSeries(b)});a.linkSeries(); +H(a,"beforeRender");if(B.Pointer)a.pointer=new Xa(a,b);a.render();a.renderer.draw();if(!a.renderer.imgCount)a.onload();a.cloneRenderTo(!0)}},onload:function(){var a=this;o([this.callback].concat(this.callbacks),function(b){b&&a.index!==void 0&&b.apply(a,[a])});a.renderer.imgCount||H(a,"load")},splashArray:function(a,b){var c=b[a],c=Y(c)?c:[c,c,c,c];return[p(b[a+"Top"],c[0]),p(b[a+"Right"],c[1]),p(b[a+"Bottom"],c[2]),p(b[a+"Left"],c[3])]}};var Cb=B.CenteredSeriesMixin={getCenter:function(){var a=this.options, +b=this.chart,c=2*(a.slicedOffset||0),d=b.plotWidth-2*c,b=b.plotHeight-2*c,e=a.center,e=[p(e[0],"50%"),p(e[1],"50%"),a.size||"100%",a.innerSize||0],f=F(d,b),g,h;for(g=0;g<4;++g)h=e[g],a=g<2||g===2&&/%$/.test(h),e[g]=(/%$/.test(h)?[d,b,f,e[2]][g]*parseFloat(h)/100:parseFloat(h))+(a?c:0);e[3]>e[2]&&(e[3]=e[2]);return e}},Ha=function(){};Ha.prototype={init:function(a,b,c){this.series=a;this.color=a.color;this.applyOptions(b,c);this.pointAttr={};if(a.options.colorByPoint&&(b=a.options.colors||a.chart.options.colors, +this.color=this.color||b[a.colorCounter++],a.colorCounter===b.length))a.colorCounter=0;a.chart.pointCount++;return this},applyOptions:function(a,b){var c=this.series,d=c.options.pointValKey||c.pointValKey,a=Ha.prototype.optionsToObject.call(this,a);u(this,a);this.options=this.options?u(this.options,a):a;if(d)this.y=this[d];this.isNull=this.y===null;if(typeof this.x!=="number"&&c)this.x=b===void 0?c.autoIncrement():b;return this},optionsToObject:function(a){var b={},c=this.series,d=c.options.keys, +e=d||c.pointArrayMap||["y"],f=e.length,g=0,h=0;if(typeof a==="number"||a===null)b[e[0]]=a;else if(Ia(a)){if(!d&&a.length>f){c=typeof a[0];if(c==="string")b.name=a[0];else if(c==="number")b.x=a[0];g++}for(;hn){for(c=0;j===null&&ci||this.forceCrop))if(b[d-1]p)b=[],c=[];else if(b[0]p)e=this.cropData(this.xData,this.yData,n,p),b=e.xData,c=e.yData,e=e.start,f=!0;for(i=b.length||1;--i;)d=m?k(b[i])-k(b[i-1]):b[i]-b[i-1],d>0&&(g===z||d=c){f=t(0,i-h);break}for(c=i;cd){g=c+h;break}return{xData:a.slice(f,g),yData:b.slice(f,g),start:f,end:g}},generatePoints:function(){var a=this.options.data,b=this.data,c,d=this.processedXData,e=this.processedYData,f=this.pointClass,g=d.length,h=this.cropStart||0,i,k=this.hasGroupedData,j,l=[],m;if(!b&&!k)b=[],b.length=a.length,b=this.data=b;for(m=0;m0),k=this.getExtremesFromAll||this.options.getExtremesFromAll||this.cropped|| +(c[l+1]||k)>=g&&(c[l-1]||k)<=h,i&&k)if(i=j.length)for(;i--;)j[i]!==null&&(e[f++]=j[i]);else e[f++]=j;this.dataMin=Ra(e);this.dataMax=Ea(e)},translate:function(){this.processedXData||this.processData();this.generatePoints();for(var a=this.options,b=a.stacking,c=this.xAxis,d=c.categories,e=this.yAxis,f=this.points,g=f.length,h=!!this.modifyValue,i=a.pointPlacement,k=i==="between"||ma(i),j=a.threshold,l=a.startFromThreshold?j:0,m,n,r,o,R=Number.MAX_VALUE,a=0;a=0&&n<=e.len&&m>=0&&m<=c.len;v.clientX=k?c.translate(x,0,0,0,1):m;v.negative=v.y<(j||0);v.category=d&&d[v.x]!==z?d[v.x]:v.x;a&&(R=F(R,P(m-r)));r=m}this.closestPointRangePx=R},getValidPoints:function(a){return Na(a||this.points,function(a){return!a.isNull})},setClip:function(a){var b=this.chart,c=this.options,d=b.renderer,e=b.inverted,f=this.clipBox,g=f||b.clipBox, +h=this.sharedClipKey||["_sharedClip",a&&a.duration,a&&a.easing,g.height,c.xAxis,c.yAxis].join(","),i=b[h],k=b[h+"m"];if(!i){if(a)g.width=0,b[h+"m"]=k=d.clipRect(-99,e?-b.plotLeft:-b.plotTop,99,e?b.chartWidth:b.chartHeight);b[h]=i=d.clipRect(g)}a&&(i.count+=1);if(c.clip!==!1)this.group.clip(a||f?i:b.clipRect),this.markerGroup.clip(k),this.sharedClipKey=h;a||(i.count-=1,i.count<=0&&h&&b[h]&&(f||(b[h]=b[h].destroy()),b[h+"m"]&&(b[h+"m"]=b[h+"m"].destroy())))},animate:function(a){var b=this.chart,c=this.options.animation, +d;if(c&&!Y(c))c=aa[this.type].animation;a?this.setClip(c):(d=this.sharedClipKey,(a=b[d])&&a.animate({width:b.plotSizeX},c),b[d+"m"]&&b[d+"m"].animate({width:b.plotSizeX+99},c),this.animate=null)},afterAnimate:function(){this.setClip();H(this,"afterAnimate")},drawPoints:function(){var a,b=this.points,c=this.chart,d,e,f,g,h,i,k,j,l=this.options.marker,m=this.pointAttr[""],n,r,o,t=this.markerGroup,v=p(l.enabled,this.xAxis.isRadial,this.closestPointRangePx>2*l.radius);if(l.enabled!==!1||this._hasPointMarkers)for(f= +b.length;f--;)if(g=b[f],d=T(g.plotX),e=g.plotY,j=g.graphic,n=g.marker||{},r=!!g.marker,a=v&&n.enabled===z||n.enabled,o=g.isInside,a&&e!==z&&!isNaN(e)&&g.y!==null)if(a=g.pointAttr[g.selected?"select":""]||m,h=a.r,i=p(n.symbol,this.symbol),k=i.indexOf("url")===0,j)j[o?"show":"hide"](!0).attr(a).animate(u({x:d-h,y:e-h},j.symbolName?{width:2*h,height:2*h}:{}));else{if(o&&(h>0||k))g.graphic=c.renderer.symbol(i,d-h,e-h,2*h,2*h,r?n:l).attr(a).add(t)}else if(j)g.graphic=j.destroy()},convertAttribs:function(a, +b,c,d){var e=this.pointAttrToOptions,f,g,h={},a=a||{},b=b||{},c=c||{},d=d||{};for(f in e)g=e[f],h[f]=p(a[g],b[f],c[f],d[f]);return h},getAttribs:function(){var a=this,b=a.options,c=aa[a.type].marker?b.marker:b,d=c.states,e=d.hover,f,g=a.color,h=a.options.negativeColor;f={stroke:g,fill:g};var i=a.points||[],k,j,l=[],m=a.pointAttrToOptions;k=a.hasPointSpecificOptions;var n=c.lineColor,r=c.fillColor;j=b.turboThreshold;var s=a.zones,t=a.zoneAxis||"y",v;b.marker?(e.radius=e.radius||c.radius+e.radiusPlus, +e.lineWidth=e.lineWidth||c.lineWidth+e.lineWidthPlus):(e.color=e.color||ia(e.color||g).brighten(e.brightness).get(),e.negativeColor=e.negativeColor||ia(e.negativeColor||h).brighten(e.brightness).get());l[""]=a.convertAttribs(c,f);o(["hover","select"],function(b){l[b]=a.convertAttribs(d[b],l[""])});a.pointAttr=l;g=i.length;if(!j||g=f.value;)f=s[++k];j.color=j.fillColor= +p(f.color,a.color)}k=b.colorByPoint||j.color;if(j.options)for(v in m)q(c[m[v]])&&(k=!0);if(k){c=c||{};k=[];d=c.states||{};f=d.hover=d.hover||{};if(!b.marker||j.negative&&!f.fillColor&&!e.fillColor)f[a.pointAttrToOptions.fill]=f.color||!j.options.color&&e[j.negative&&h?"negativeColor":"color"]||ia(j.color).brighten(f.brightness||e.brightness).get();f={color:j.color};if(!r)f.fillColor=j.color;if(!n)f.lineColor=j.color;c.hasOwnProperty("color")&&!c.color&&delete c.color;k[""]=a.convertAttribs(u(f,c), +l[""]);k.hover=a.convertAttribs(d.hover,l.hover,k[""]);k.select=a.convertAttribs(d.select,l.select,k[""])}else k=l;j.pointAttr=k}},destroy:function(){var a=this,b=a.chart,c=/AppleWebKit\/533/.test(za),d,e=a.data||[],f,g,h;H(a,"destroy");V(a);o(a.axisTypes||[],function(b){if(h=a[b])oa(h.series,a),h.isDirty=h.forceRedraw=!0});a.legendItem&&a.chart.legend.destroyItem(a);for(d=e.length;d--;)(f=e[d])&&f.destroy&&f.destroy();a.points=null;clearTimeout(a.animationTimeout);for(g in a)a[g]instanceof O&&!a[g].survive&& +(d=c&&g==="group"?"hide":"destroy",a[g][d]());if(b.hoverSeries===a)b.hoverSeries=null;oa(b.series,a);for(g in a)delete a[g]},getGraphPath:function(a,b,c){var d=this,e=d.options,f=e.step,g,h=[],i,a=a||d.points;(g=a.reversed)&&a.reverse();(f={right:1,center:2}[f]||f&&3)&&g&&(f=4-f);e.connectNulls&&!b&&!c&&(a=this.getValidPoints(a));o(a,function(g,j){var l=g.plotX,m=g.plotY,n=a[j-1];if((g.leftCliff||n&&n.rightCliff)&&!c)i=!0;g.isNull&&!q(b)&&j>0?i=!e.connectNulls:g.isNull&&!b?i=!0:(j===0||i?n=["M",g.plotX, +g.plotY]:d.getPointSpline?n=d.getPointSpline(a,g,j):f?(n=f===1?["L",n.plotX,m]:f===2?["L",(n.plotX+l)/2,n.plotY,"L",(n.plotX+l)/2,m]:["L",l,n.plotY],n.push("L",l,m)):n=["L",l,m],h.push.apply(h,n),i=!1)});return d.graphPath=h},drawGraph:function(){var a=this,b=this.options,c=[["graph",b.lineColor||this.color,b.dashStyle]],d=b.lineWidth,e=b.linecap!=="square",f=(this.gappedPath||this.getGraphPath).call(this),g=this.fillGraph&&this.color||"none";o(this.zones,function(d,e){c.push(["zoneGraph"+e,d.color|| +a.color,d.dashStyle||b.dashStyle])});o(c,function(c,i){var k=c[0],j=a[k];if(j)j.animate({d:f});else if((d||g)&&f.length)j={stroke:c[1],"stroke-width":d,fill:g,zIndex:1},c[2]?j.dashstyle=c[2]:e&&(j["stroke-linecap"]=j["stroke-linejoin"]="round"),a[k]=a.chart.renderer.path(f).attr(j).add(a.group).shadow(i<2&&b.shadow)})},applyZones:function(){var a=this,b=this.chart,c=b.renderer,d=this.zones,e,f,g=this.clips||[],h,i=this.graph,k=this.area,j=t(b.chartWidth,b.chartHeight),l=this[(this.zoneAxis||"y")+ +"Axis"],m,n=l.reversed,r=b.inverted,s=l.horiz,q,v,x,w=!1;if(d.length&&(i||k)&&l.min!==z)i&&i.hide(),k&&k.hide(),m=l.getExtremes(),o(d,function(d,o){e=n?s?b.plotWidth:0:s?0:l.toPixels(m.min);e=F(t(p(f,e),0),j);f=F(t(A(l.toPixels(p(d.value,m.max),!0)),0),j);w&&(e=f=l.toPixels(m.max));q=Math.abs(e-f);v=F(e,f);x=t(e,f);if(l.isXAxis){if(h={x:r?x:v,y:0,width:q,height:j},!s)h.x=b.plotHeight-h.x}else if(h={x:0,y:r?x:v,width:j,height:q},s)h.y=b.plotWidth-h.y;b.inverted&&c.isVML&&(h=l.isXAxis?{x:0,y:n?v:x, +height:h.width,width:b.chartWidth}:{x:h.y-b.plotLeft-b.spacingBox.x,y:0,width:h.height,height:b.chartHeight});g[o]?g[o].animate(h):(g[o]=c.clipRect(h),i&&a["zoneGraph"+o].clip(g[o]),k&&a["zoneArea"+o].clip(g[o]));w=d.value>m.max}),this.clips=g},invertGroups:function(){function a(){var a={width:b.yAxis.len,height:b.xAxis.len};o(["group","markerGroup"],function(c){b[c]&&b[c].attr(a).invert()})}var b=this,c=b.chart;if(b.xAxis)M(c,"resize",a),M(b,"destroy",function(){V(c,"resize",a)}),a(),b.invertGroups= +a},plotGroup:function(a,b,c,d,e){var f=this[a],g=!f;g&&(this[a]=f=this.chart.renderer.g(b).attr({zIndex:d||0.1}).add(e),f.addClass("highcharts-series-"+this.index));f.attr({visibility:c})[g?"attr":"animate"](this.getPlotBox());return f},getPlotBox:function(){var a=this.chart,b=this.xAxis,c=this.yAxis;if(a.inverted)b=c,c=this.xAxis;return{translateX:b?b.left:a.plotLeft,translateY:c?c.top:a.plotTop,scaleX:1,scaleY:1}},render:function(){var a=this,b=a.chart,c,d=a.options,e=(c=d.animation)&&!!a.animate&& +b.renderer.isSVG&&p(c.duration,500)||0,f=a.visible?"inherit":"hidden",g=d.zIndex,h=a.hasRendered,i=b.seriesGroup;c=a.plotGroup("group","series",f,g,i);a.markerGroup=a.plotGroup("markerGroup","markers",f,g,i);e&&a.animate(!0);a.getAttribs();c.inverted=a.isCartesian?b.inverted:!1;a.drawGraph&&(a.drawGraph(),a.applyZones());o(a.points,function(a){a.redraw&&a.redraw()});a.drawDataLabels&&a.drawDataLabels();a.visible&&a.drawPoints();a.drawTracker&&a.options.enableMouseTracking!==!1&&a.drawTracker();b.inverted&& +a.invertGroups();d.clip!==!1&&!a.sharedClipKey&&!h&&c.clip(b.clipRect);e&&a.animate();if(!h)a.animationTimeout=Pa(function(){a.afterAnimate()},e);a.isDirty=a.isDirtyData=!1;a.hasRendered=!0},redraw:function(){var a=this.chart,b=this.isDirtyData,c=this.isDirty,d=this.group,e=this.xAxis,f=this.yAxis;d&&(a.inverted&&d.attr({width:a.plotWidth,height:a.plotHeight}),d.animate({translateX:p(e&&e.left,a.plotLeft),translateY:p(f&&f.top,a.plotTop)}));this.translate();this.render();b&&H(this,"updatedData"); +(c||b)&&delete this.kdTree},kdDimensions:1,kdAxisArray:["clientX","plotY"],searchPoint:function(a,b){var c=this.xAxis,d=this.yAxis,e=this.chart.inverted;return this.searchKDTree({clientX:e?c.len-a.chartY+c.pos:a.chartX-c.pos,plotY:e?d.len-a.chartX+d.pos:a.chartY-d.pos},b)},buildKDTree:function(){function a(c,e,f){var g,h;if(h=c&&c.length)return g=b.kdAxisArray[e%f],c.sort(function(a,b){return a[g]-b[g]}),h=Math.floor(h/2),{point:c[h],left:a(c.slice(0,h),e+1,f),right:a(c.slice(h+1),e+1,f)}}var b=this, +c=b.kdDimensions;delete b.kdTree;Pa(function(){b.kdTree=a(b.getValidPoints(),c,c)},b.options.kdNow?0:1)},searchKDTree:function(a,b){function c(a,b,k,j){var l=b.point,m=d.kdAxisArray[k%j],n,p,o=l;p=q(a[e])&&q(l[e])?Math.pow(a[e]-l[e],2):null;n=q(a[f])&&q(l[f])?Math.pow(a[f]-l[f],2):null;n=(p||0)+(n||0);l.dist=q(n)?Math.sqrt(n):Number.MAX_VALUE;l.distX=q(p)?Math.sqrt(p):Number.MAX_VALUE;m=a[m]-l[m];n=m<0?"left":"right";p=m<0?"right":"left";b[n]&&(n=c(a,b[n],k+1,j),o=n[g]0&&this.singleStacks===!1&&(q.points[v][0]=q.points[this.index+","+w+",0"][0]); +e==="percent"?(s=s?i:k,j&&m[s]&&m[s][w]?(s=m[s][w],q.total=s.total=t(s.total,q.total)+P(u)||0):q.total=fa(q.total+(P(u)||0))):q.total=fa(q.total+(u||0));q.cum=p(q.cum,g)+(u||0);u!==null&&q.points[v].push(q.cum);c[x]=q.cum}if(e==="percent")l.usePercentage=!0;this.stackedYData=c;l.oldStacks={}}};Q.prototype.setPercentStacks=function(){var a=this,b=a.stackKey,c=a.yAxis.stacks,d=a.processedXData,e;o([b,"-"+b],function(b){var f;for(var g=d.length,h,i;g--;)if(h=d[g],e=a.getStackIndicator(e,h,a.index),f= +(i=c[b]&&c[b][h])&&i.points[e.key],h=f)i=i.total?100/i.total:0,h[0]=fa(h[0]*i),h[1]=fa(h[1]*i),a.stackedYData[g]=h[1]})};Q.prototype.getStackIndicator=function(a,b,c){!q(a)||a.x!==b?a={x:b,index:0}:a.index++;a.key=[c,b,a.index].join(",");return a};u(hb.prototype,{addSeries:function(a,b,c){var d,e=this;a&&(b=p(b,!0),H(e,"addSeries",{options:a},function(){d=e.initSeries(a);e.isDirtyLegend=!0;e.linkSeries();b&&e.redraw(c)}));return d},addAxis:function(a,b,c,d){var e=b?"xAxis":"yAxis",f=this.options; +new ka(this,D(a,{index:this[e].length,isX:b}));f[e]=ta(f[e]||{});f[e].push(a);p(c,!0)&&this.redraw(d)},showLoading:function(a){var b=this,c=b.options,d=b.loadingDiv,e=c.loading,f=function(){d&&L(d,{left:b.plotLeft+"px",top:b.plotTop+"px",width:b.plotWidth+"px",height:b.plotHeight+"px"})};if(!d)b.loadingDiv=d=Z(La,{className:"highcharts-loading"},u(e.style,{zIndex:10,display:"none"}),b.container),b.loadingSpan=Z("span",null,e.labelStyle,d),M(b,"redraw",f);b.loadingSpan.innerHTML=a||c.lang.loading; +if(!b.loadingShown)L(d,{opacity:0,display:""}),Wa(d,{opacity:e.style.opacity},{duration:e.showDuration||0}),b.loadingShown=!0;f()},hideLoading:function(){var a=this.options,b=this.loadingDiv;b&&Wa(b,{opacity:0},{duration:a.loading.hideDuration||100,complete:function(){L(b,{display:"none"})}});this.loadingShown=!1}});u(Ha.prototype,{update:function(a,b,c,d){function e(){f.applyOptions(a);if(f.y===null&&h)f.graphic=h.destroy();if(Y(a)&&!Ia(a))f.redraw=function(){if(h&&h.element&&a&&a.marker&&a.marker.symbol)f.graphic= +h.destroy();if(a&&a.dataLabels&&f.dataLabel)f.dataLabel=f.dataLabel.destroy();f.redraw=null};i=f.index;g.updateParallelArrays(f,i);if(l&&f.name)l[f.x]=f.name;j.data[i]=Y(j.data[i])?f.options:a;g.isDirty=g.isDirtyData=!0;if(!g.fixedBox&&g.hasCartesianSeries)k.isDirtyBox=!0;if(j.legendType==="point")k.isDirtyLegend=!0;b&&k.redraw(c)}var f=this,g=f.series,h=f.graphic,i,k=g.chart,j=g.options,l=g.xAxis&&g.xAxis.names,b=p(b,!0);d===!1?e():f.firePointEvent("update",{options:a},e)},remove:function(a,b){this.series.removePoint(sa(this, +this.series.data),a,b)}});u(Q.prototype,{addPoint:function(a,b,c,d){var e=this,f=e.options,g=e.data,h=e.graph,i=e.area,k=e.chart,j=e.xAxis&&e.xAxis.names,l=h&&h.shift||0,m=["graph","area"],h=f.data,n,r=e.xData;Ua(d,k);if(c){for(d=e.zones.length;d--;)m.push("zoneGraph"+d,"zoneArea"+d);o(m,function(a){if(e[a])e[a].shift=l+(f.step?2:1)})}if(i)i.isArea=!0;b=p(b,!0);i={series:e};e.pointClass.prototype.applyOptions.apply(i,[a]);m=i.x;d=r.length;if(e.requireSorting&&mm;)d--;e.updateParallelArrays(i, +"splice",d,0,0);e.updateParallelArrays(i,d);if(j&&i.name)j[m]=i.name;h.splice(d,0,a);n&&(e.data.splice(d,0,null),e.processData());f.legendType==="point"&&e.generatePoints();c&&(g[0]&&g[0].remove?g[0].remove(!1):(g.shift(),e.updateParallelArrays(i,"shift"),h.shift()));e.isDirty=!0;e.isDirtyData=!0;b&&(e.getAttribs(),k.redraw())},removePoint:function(a,b,c){var d=this,e=d.data,f=e[a],g=d.points,h=d.chart,i=function(){g&&g.length===e.length&&g.splice(a,1);e.splice(a,1);d.options.data.splice(a,1);d.updateParallelArrays(f|| +{series:d},"splice",a,1);f&&f.destroy();d.isDirty=!0;d.isDirtyData=!0;b&&h.redraw()};Ua(c,h);b=p(b,!0);f?f.firePointEvent("remove",null,i):i()},remove:function(a,b){var c=this,d=c.chart;H(c,"remove",null,function(){c.destroy();d.isDirtyLegend=d.isDirtyBox=!0;d.linkSeries();p(a,!0)&&d.redraw(b)})},update:function(a,b){var c=this,d=this.chart,e=this.userOptions,f=this.type,g=I[f].prototype,h=["group","markerGroup","dataLabelsGroup"],i;if(a.type&&a.type!==f||a.zIndex!==void 0)h.length=0;o(h,function(a){h[a]= +c[a];delete c[a]});a=D(e,{animation:!1,index:this.index,pointStart:this.xData[0]},{data:this.options.data},a);this.remove(!1);for(i in g)this[i]=z;u(this,I[a.type||f].prototype);o(h,function(a){c[a]=h[a]});this.init(d,a);d.linkSeries();p(b,!0)&&d.redraw(!1)}});u(ka.prototype,{update:function(a,b){var c=this.chart,a=c.options[this.coll][this.options.index]=D(this.userOptions,a);this.destroy(!0);this._addedPlotLB=this.chart._labelPanes=z;this.init(c,u(a,{events:z}));c.isDirtyBox=!0;p(b,!0)&&c.redraw()}, +remove:function(a){for(var b=this.chart,c=this.coll,d=this.series,e=d.length;e--;)d[e]&&d[e].remove(!1);oa(b.axes,this);oa(b[c],this);b.options[c].splice(this.options.index,1);o(b[c],function(a,b){a.options.index=b});this.destroy();b.isDirtyBox=!0;p(a,!0)&&b.redraw()},setTitle:function(a,b){this.update({title:a},b)},setCategories:function(a,b){this.update({categories:a},b)}});var wa=pa(Q);I.line=wa;aa.area=D(da,{softThreshold:!1,threshold:0});var la=pa(Q,{type:"area",singleStacks:!1,getStackPoints:function(){var a= +[],b=[],c=this.xAxis,d=this.yAxis,e=d.stacks[this.stackKey],f={},g=this.points,h=this.index,i=d.series,k=i.length,j,l=p(d.options.reversedStacks,!0)?1:-1,m,n;if(this.options.stacking){for(m=0;m=0&&m=0&&ma&&h>e?(h=t(a,e),k=2*e-h):hc&&k>e?(k=t(c,e), +h=2*e-k):k0.5;b=Math.round(b)+f;d-= +b;g&&(b-=1,d+=1);return{x:a,y:b,width:c,height:d}},translate:function(){var a=this,b=a.chart,c=a.options,d=a.borderWidth=p(c.borderWidth,a.closestPointRange*a.xAxis.transA<2?0:1),e=a.yAxis,f=a.translatedThreshold=e.getThreshold(c.threshold),g=p(c.minPointLength,5),h=a.getColumnMetrics(),i=h.width,k=a.barW=t(i,1+2*d),j=a.pointXOffset=h.offset;b.inverted&&(f-=0.5);c.pointPadding&&(k=ua(k));Q.prototype.translate.apply(a);o(a.points,function(c){var d=F(p(c.yBottom,f),9E4),h=999+P(d),h=F(t(-h,c.plotY), +e.len+h),o=c.plotX+j,s=k,q=F(h,d),v,u=t(h,d)-q;P(u)g?d-g:f-(v?g:0));c.barX=o;c.pointWidth=i;c.tooltipPos=b.inverted?[e.len+e.pos-b.plotLeft-h,a.xAxis.len-o-s/2,u]:[o+s/2,h+e.pos-b.plotTop,u];c.shapeType="rect";c.shapeArgs=a.crispCol(o,q,s,u)})},getSymbol:Aa,drawLegendSymbol:J.drawRectangle,drawGraph:Aa,drawPoints:function(){var a=this,b=this.chart,c=a.options,d=b.renderer,e=c.animationLimit||250,f,g;o(a.points,function(h){var i= +h.plotY,k=h.graphic;if(i!==z&&!isNaN(i)&&h.y!==null)f=h.shapeArgs,i=q(a.borderWidth)?{"stroke-width":a.borderWidth}:{},g=h.pointAttr[h.selected?"select":""]||a.pointAttr[""],k?(Oa(k),k.attr(i).attr(g)[b.pointCount\u25cf {series.name}
', +pointFormat:"x: {point.x}
y: {point.y}
"}});la=pa(Q,{type:"scatter",sorted:!1,requireSorting:!1,noSharedTooltip:!0,trackerGroups:["group","markerGroup","dataLabelsGroup"],takeOrdinalPosition:!1,kdDimensions:2,drawGraph:function(){this.options.lineWidth&&Q.prototype.drawGraph.call(this)}});I.scatter=la;aa.pie=D(da,{borderColor:"#FFFFFF",borderWidth:1,center:[null,null],clip:!1,colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return this.y===null?void 0: +this.point.name},x:0},ignoreHiddenPoint:!0,legendType:"point",marker:null,size:null,showInLegend:!1,slicedOffset:10,states:{hover:{brightness:0.1,shadow:!1}},stickyTracking:!1,tooltip:{followPointer:!0}});da={type:"pie",isCartesian:!1,pointClass:pa(Ha,{init:function(){Ha.prototype.init.apply(this,arguments);var a=this,b;a.name=p(a.name,"Slice");b=function(b){a.slice(b.type==="select")};M(a,"select",b);M(a,"unselect",b);return a},setVisible:function(a,b){var c=this,d=c.series,e=d.chart,f=d.options.ignoreHiddenPoint, +b=p(b,f);if(a!==c.visible){c.visible=c.options.visible=a=a===z?!c.visible:a;d.options.data[sa(c,d.data)]=c.options;o(["graphic","dataLabel","connector","shadowGroup"],function(b){if(c[b])c[b][a?"show":"hide"](!0)});c.legendItem&&e.legend.colorizeItem(c,a);!a&&c.state==="hover"&&c.setState("");if(f)d.isDirty=!0;b&&e.redraw()}},slice:function(a,b,c){var d=this.series;Ua(c,d.chart);p(b,!0);this.sliced=this.options.sliced=a=q(a)?a:!this.sliced;d.options.data[sa(this,d.data)]=this.options;a=a?this.slicedTranslation: +{translateX:0,translateY:0};this.graphic.animate(a);this.shadowGroup&&this.shadowGroup.animate(a)},haloPath:function(a){var b=this.shapeArgs,c=this.series.chart;return this.sliced||!this.visible?[]:this.series.chart.renderer.symbols.arc(c.plotLeft+b.x,c.plotTop+b.y,b.r+a,b.r+a,{innerR:this.shapeArgs.r,start:b.start,end:b.end})}}),requireSorting:!1,directTouch:!0,noSharedTooltip:!0,trackerGroups:["group","dataLabelsGroup"],axisTypes:[],pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth", +fill:"color"},animate:function(a){var b=this,c=b.points,d=b.startAngleRad;if(!a)o(c,function(a){var c=a.graphic,g=a.shapeArgs;c&&(c.attr({r:a.startR||b.center[3]/2,start:d,end:d}),c.animate({r:g.r,start:g.start,end:g.end},b.options.animation))}),b.animate=null},updateTotals:function(){var a,b=0,c=this.points,d=c.length,e,f=this.options.ignoreHiddenPoint;for(a=0;a0&&(e.visible||!f)?e.y/b*100:0,e.total=b},generatePoints:function(){Q.prototype.generatePoints.call(this); +this.updateTotals()},translate:function(a){this.generatePoints();var b=0,c=this.options,d=c.slicedOffset,e=d+c.borderWidth,f,g,h,i=c.startAngle||0,k=this.startAngleRad=ra/180*(i-90),i=(this.endAngleRad=ra/180*(p(c.endAngle,i+360)-90))-k,j=this.points,l=c.dataLabels.distance,c=c.ignoreHiddenPoint,m,n=j.length,o;if(!a)this.center=a=this.getCenter();this.getX=function(b,c){h=W.asin(F((b-a[1])/(a[2]/2+l),1));return a[0]+(c?-1:1)*U(h)*(a[2]/2+l)};for(m=0;m1.5*ra?h-=2*ra:h<-ra/2&&(h+=2*ra);o.slicedTranslation={translateX:A(U(h)*d),translateY:A($(h)*d)};f=U(h)*a[2]/2;g=$(h)*a[2]/2;o.tooltipPos=[a[0]+f*0.7,a[1]+g*0.7];o.half=h<-ra/2||h>ra/2?1:0;o.angle=h;e=F(e,l/2);o.labelPos=[a[0]+f+U(h)*l,a[1]+g+$(h)*l,a[0]+f+U(h)*e,a[1]+g+$(h)*e,a[0]+f,a[1]+g,l<0?"center":o.half?"right":"left",h]}},drawGraph:null,drawPoints:function(){var a= +this,b=a.chart.renderer,c,d,e=a.options.shadow,f,g,h,i;if(e&&!a.shadowGroup)a.shadowGroup=b.g("shadow").add(a.group);o(a.points,function(k){if(k.y!==null){d=k.graphic;h=k.shapeArgs;f=k.shadowGroup;g=k.pointAttr[k.selected?"select":""];if(!g.stroke)g.stroke=g.fill;if(e&&!f)f=k.shadowGroup=b.g("shadow").add(a.shadowGroup);c=k.sliced?k.slicedTranslation:{translateX:0,translateY:0};f&&f.attr(c);if(d)d.setRadialReference(a.center).attr(g).animate(u(h,c));else{i={"stroke-linejoin":"round"};if(!k.visible)i.visibility= +"hidden";k.graphic=d=b[k.shapeType](h).setRadialReference(a.center).attr(g).attr(i).attr(c).add(a.group).shadow(e,f)}}})},searchPoint:Aa,sortByAngle:function(a,b){a.sort(function(a,d){return a.angle!==void 0&&(d.angle-a.angle)*b})},drawLegendSymbol:J.drawRectangle,getCenter:Cb.getCenter,getSymbol:Aa};da=pa(Q,da);I.pie=da;Q.prototype.drawDataLabels=function(){var a=this,b=a.options,c=b.cursor,d=b.dataLabels,e=a.points,f,g,h=a.hasRendered||0,i,k,j=a.chart.renderer;if(d.enabled||a._hasPointLabels)a.dlProcessOptions&& +a.dlProcessOptions(d),k=a.plotGroup("dataLabelsGroup","data-labels",d.defer?"hidden":"visible",d.zIndex||6),p(d.defer,!0)&&(k.attr({opacity:+h}),h||M(a,"afterAnimate",function(){a.visible&&k.show();k[b.animation?"animate":"attr"]({opacity:1},{duration:200})})),g=d,o(e,function(e){var h,n=e.dataLabel,o,s,t=e.connector,v=!0,x,w={};f=e.dlOptions||e.options&&e.options.dataLabels;h=p(f&&f.enabled,g.enabled)&&e.y!==null;if(n&&!h)e.dataLabel=n.destroy();else if(h){d=D(g,f);x=d.style;h=d.rotation;o=e.getLabelConfig(); +i=d.format?Ka(d.format,o):d.formatter.call(o,d);x.color=p(d.color,x.color,a.color,"black");if(n)if(q(i))n.attr({text:i}),v=!1;else{if(e.dataLabel=n=n.destroy(),t)e.connector=t.destroy()}else if(q(i)){n={fill:d.backgroundColor,stroke:d.borderColor,"stroke-width":d.borderWidth,r:d.borderRadius||0,rotation:h,padding:d.padding,zIndex:1};if(x.color==="contrast")w.color=d.inside||d.distance<0||b.stacking?j.getContrast(e.color||a.color):"#000000";if(c)w.cursor=c;for(s in n)n[s]===z&&delete n[s];n=e.dataLabel= +j[h?"text":"label"](i,0,-9999,d.shape,null,null,d.useHTML).attr(n).css(u(x,w)).add(k).shadow(d.shadow)}n&&a.alignDataLabel(e,n,d,null,v)}})};Q.prototype.alignDataLabel=function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=p(a.plotX,-9999),i=p(a.plotY,-9999),k=b.getBBox(),j=f.renderer.fontMetrics(c.style.fontSize).b,l=c.rotation,m=c.align,n=this.visible&&(a.series.forceDL||f.isInsidePlot(h,A(i),g)||d&&f.isInsidePlot(h,g?d.x+1:d.y+d.height-1,g)),o=p(c.overflow,"justify")==="justify";if(n)d=u({x:g?f.plotWidth- +i:h,y:A(g?f.plotHeight-h:i),width:0,height:0},d),u(c,{width:k.width,height:k.height}),l?(o=!1,g=f.renderer.rotCorr(j,l),g={x:d.x+c.x+d.width/2+g.x,y:d.y+c.y+d.height/2},b[e?"attr":"animate"](g).attr({align:c.align}),h=(l+720)%360,h=h>180&&h<360,m==="left"?g.y-=h?k.height:0:m==="center"?(g.x-=k.width/2,g.y-=k.height/2):m==="right"&&(g.x-=k.width,g.y-=h?0:k.height)):(b.align(c,null,d),g=b.alignAttr),o?this.justifyDataLabel(b,c,g,k,d,e):p(c.crop,!0)&&(n=f.isInsidePlot(g.x,g.y)&&f.isInsidePlot(g.x+k.width, +g.y+k.height)),c.shape&&!l&&b.attr({anchorX:a.plotX,anchorY:a.plotY});if(!n)Oa(b),b.attr({y:-9999}),b.placed=!1};Q.prototype.justifyDataLabel=function(a,b,c,d,e,f){var g=this.chart,h=b.align,i=b.verticalAlign,k,j,l=a.box?0:a.padding||0;k=c.x+l;if(k<0)h==="right"?b.align="left":b.x=-k,j=!0;k=c.x+d.width-l;if(k>g.plotWidth)h==="left"?b.align="right":b.x=g.plotWidth-k,j=!0;k=c.y+l;if(k<0)i==="bottom"?b.verticalAlign="top":b.y=-k,j=!0;k=c.y+d.height-l;if(k>g.plotHeight)i==="top"?b.verticalAlign="bottom": +b.y=g.plotHeight-k,j=!0;if(j)a.placed=!f,a.align(b,null,e)};if(I.pie)I.pie.prototype.drawDataLabels=function(){var a=this,b=a.data,c,d=a.chart,e=a.options.dataLabels,f=p(e.connectorPadding,10),g=p(e.connectorWidth,1),h=d.plotWidth,i=d.plotHeight,k,j,l=p(e.softConnector,!0),m=e.distance,n=a.center,r=n[2]/2,q=n[1],u=m>0,v,x,w,B=[[],[]],z,y,E,D,C,G=[0,0,0,0],L=function(a,b){return b.y-a.y};if(a.visible&&(e.enabled||a._hasPointLabels)){Q.prototype.drawDataLabels.apply(a);o(b,function(a){if(a.dataLabel&& +a.visible)B[a.half].push(a),a.dataLabel._pos=null});for(D=2;D--;){var H=[],M=[],I=B[D],K=I.length,J;if(K){a.sortByAngle(I,D-0.5);for(C=b=0;!b&&I[C];)b=I[C]&&I[C].dataLabel&&(I[C].dataLabel.getBBox().height||21),C++;if(m>0){x=F(q+r+m,d.plotHeight);for(C=t(0,q-r-m);C<=x;C+=b)H.push(C);x=H.length;if(K>x){c=[].concat(I);c.sort(L);for(C=K;C--;)c[C].rank=C;for(C=K;C--;)I[C].rank>=x&&I.splice(C,1);K=I.length}for(C=0;C0){if(x=M.pop(),J=x.i,y=x.y,c>y&&H[J+1]!==null||ch-f&&(G[1]=t(A(z+x-h+f),G[1])),y-b/2<0?G[0]=t(A(-y+b/2),G[0]):y+b/2>i&&(G[2]=t(A(y+b/2-i),G[2]))}}}if(Ea(G)===0||this.verifyDataLabelOverflow(G))this.placeDataLabels(),u&&g&&o(this.points,function(b){k=b.connector;w=b.labelPos;if((v=b.dataLabel)&&v._pos&&b.visible)E=v._attr.visibility,z=v.connX,y=v.connY,j=l?["M",z+(w[6]==="left"?5:-5),y,"C",z,y,2*w[2]-w[4],2*w[3]-w[5],w[2],w[3],"L",w[4],w[5]]:["M",z+(w[6]==="left"?5:-5),y,"L", +w[2],w[3],"L",w[4],w[5]],k?(k.animate({d:j}),k.attr("visibility",E)):b.connector=k=a.chart.renderer.path(j).attr({"stroke-width":g,stroke:e.connectorColor||b.color||"#606060",visibility:E}).add(a.dataLabelsGroup);else if(k)b.connector=k.destroy()})}},I.pie.prototype.placeDataLabels=function(){o(this.points,function(a){var b=a.dataLabel;if(b&&a.visible)(a=b._pos)?(b.attr(b._attr),b[b.moved?"animate":"attr"](a),b.moved=!0):b&&b.attr({y:-9999})})},I.pie.prototype.alignDataLabel=Aa,I.pie.prototype.verifyDataLabelOverflow= +function(a){var b=this.center,c=this.options,d=c.center,e=c.minSize||80,f=e,g;d[0]!==null?f=t(b[2]-t(a[1],a[3]),e):(f=t(b[2]-a[1]-a[3],e),b[0]+=(a[3]-a[1])/2);d[1]!==null?f=t(F(f,b[2]-t(a[0],a[2])),e):(f=t(F(f,b[2]-a[0]-a[2]),e),b[1]+=(a[0]-a[2])/2);fp(this.translatedThreshold,g.yAxis.len)),k=p(c.inside,!!this.options.stacking);if(h){d=D(h);if(d.y<0)d.height+=d.y,d.y=0;h=d.y+d.height-g.yAxis.len;h>0&&(d.height-=h);f&&(d={x:g.yAxis.len-d.y-d.height,y:g.xAxis.len-d.x-d.width,width:d.height,height:d.width});if(!k)f?(d.x+=i?0:d.width,d.width=0):(d.y+=i?d.height:0,d.height=0)}c.align=p(c.align,!f||k?"center":i?"right":"left");c.verticalAlign=p(c.verticalAlign, +f||k?"middle":i?"top":"bottom");Q.prototype.alignDataLabel.call(this,a,b,c,d,e)};(function(a){var b=a.Chart,c=a.each,d=a.pick,e=a.addEvent;b.prototype.callbacks.push(function(a){function b(){var e=[];c(a.series,function(a){var b=a.options.dataLabels,f=a.dataLabelCollections||["dataLabel"];(b.enabled||a._hasPointLabels)&&!b.allowOverlap&&a.visible&&c(f,function(b){c(a.points,function(a){if(a[b])a[b].labelrank=d(a.labelrank,a.shapeArgs&&a.shapeArgs.height),e.push(a[b])})})});a.hideOverlappingLabels(e)} +b();e(a,"redraw",b)});b.prototype.hideOverlappingLabels=function(a){var b=a.length,d,e,k,j,l,m,n,o,p;for(e=0;el.x+n.translateX+(k.width-p)||m.x+o.translateX+(j.width- +p)l.y+n.translateY+(k.height-p)||m.y+o.translateY+(j.height-p)h;if(b.series.length&&(i||l>F(j.dataMin,j.min))&&(!i||k + + +
+
+
+ + +
+
+
+
+
+

CRM Dashboard

+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+

+ +
+
+
+
+ +

+

My Leads

+
+
+
+ +
+
+
+ +
+
+

+ +
+
+
+
+ +

+

My Opportunities

+
+
+
+ +
+
+
+ +
+
+

+ +
+
+
+
+ +

+

Expected Revenue

+
+
+
+ +
+
+
+ +
+
+

+ +
+
+
+
+ +

+

Revenue

+
+
+
+ +
+
+
+ +
+
+

+ +
+
+
+
+ +

+

Win Ratio

+
+
+
+ +
+
+
+ +
+
+

+ +
+
+
+
+ +

+

Average Closing Time

+
+
+
+ +
+
+
+ +
+
+

+ +
+
+
+
+ +

+

Opportunity Win Loss Ratio

+
+
+
+ +
+
+
+ +
+
+

+ + + +

+

Unassigned Leads Count

+
+
+
+
+ +
+
+
+

Funnel Chart

+
+
+
+
+
+
+
+
+

Year to Date

+
+
+ +
+
+
Annual Target :&nbsp
+
YtD Target :&nbsp
+
Achieved Won :&nbsp
+
Difference :&nbsp
+
+
+
+ +
+
+

Leads by Month

+
+
+ +
+
+
+

CRM Activity

+
+
+ +
+
+
+
+ +
+
+
+

Upcoming Activities

+
+
+
+
+ +
+
+ +
+
+
+
    +
  • + Activity: + + + +
  • +
  • + Name: + + + +
  • +
  • Summary: + + + +
  • +
+
+
+
+
+
+
+
+
+
+ +
+
+

Total Revenue by Salesperson

+
+
+ +
+
+
+
+
+
+ + +
+
+
+
+

Top Deals

+
+
+
+ +
+
+ +
+
+

.

+
+
    +
  • + Sales Person: ,&nbsp + Team: +
  • +
+
+
+
+
+
+
+
+
+ +
+
+

Monthly Goal

+
+ +
+
+
+
+
+
+
+
+ + + + + + + +
+
+ +
+
+

Leads group by Campaign

+
+
+ +
+
+
+ +
+
+

Leads group by Medium

+
+
+ +
+
+
+

Leads group by Source

+
+
+ +
+
+
+
+ +
+
+
+

Top Salesperson Revenue

+
+ + + + + + + + + + + + + + + +
OpportunityRevenue
+
+ +
+ +
+
+

Top Country Wise Revenue

+
+ + + + + + + + + + + + + + + +
CountryRevenue
+
+ +
+ +
+
+

Top Country Wise Count

+
+ + + + + + + + + + + + + + + +
CountryCount
+
+ +
+
+ +
+
+
+

Recent Activities

+
+
+
+
+ +
+
+ +
+
+
+
    +
  • + Activity: + + + +
  • +
  • Name: + + + +
  • +
  • Summary: + + + +
  • +
  • + Sales Rep.: +
  • +
+
+
+
+
+
+
+
+
+
+ +
+
+

Lost Opportunity/Lead Graph

+
+
+
+ + + + +
+
+ +
+
+
+ +
+
+
+ +
+
+

Top Sales Person by Invoice

+
+
+
+ +
+
+ +
+
+

&nbsp

+
+
    +
  • + +

  • +
+
+
+
+
+
+
+
+
+
+
+
+ diff --git a/crm_dashboard/static/src/xml/sub_dashboard.xml b/crm_dashboard/static/src/xml/sub_dashboard.xml new file mode 100644 index 000000000..bd0a92b43 --- /dev/null +++ b/crm_dashboard/static/src/xml/sub_dashboard.xml @@ -0,0 +1,150 @@ + + + +
+ + \ No newline at end of file diff --git a/crm_dashboard/views/assets.xml b/crm_dashboard/views/assets.xml new file mode 100644 index 000000000..eb95cf70f --- /dev/null +++ b/crm_dashboard/views/assets.xml @@ -0,0 +1,18 @@ + +