diff --git a/genmon.py b/genmon.py index 84d2d3ac..2289c064 100644 --- a/genmon.py +++ b/genmon.py @@ -25,15 +25,20 @@ from genmonlib import mymail, mylog, mythread, mypipe, mysupport, generac_evolution, generac_HPanel, myplatform -GENMON_VERSION = "V1.8.8" +GENMON_VERSION = "V1.8.9" #------------ Monitor class -------------------------------------------- class Monitor(mysupport.MySupport): - def __init__(self): + def __init__(self, ConfigFilePath = None): super(Monitor, self).__init__() self.ProgramName = "Generator Monitor" self.Version = "Unknown" + if ConfigFilePath == None: + self.ConfigFilePath = "/etc/" + else: + self.ConfigFilePath = ConfigFilePath + self.ConnectionList = [] # list of incoming connections for heartbeat # defautl values self.SiteName = "Home" @@ -141,7 +146,7 @@ def GetConfig(self, reload = False): config = RawConfigParser() # config parser reads from current directory, when running form a cron tab this is # not defined so we specify the full path - config.read('/etc/genmon.conf') + config.read(self.ConfigFilePath + 'genmon.conf') # getfloat() raises an exception if the value is not a float # getint() and getboolean() also do this for their respective types @@ -798,13 +803,13 @@ def signal_handler(signal, frame): #------------------- Command-line interface for monitor -----------------# if __name__=='__main__': # - + ConfigFilePath = None if len(sys.argv)<2 else sys.argv[1] # Set the signal handler signal.signal(signal.SIGINT, signal_handler) #Start things up - MyMonitor = Monitor() + MyMonitor = Monitor(ConfigFilePath = ConfigFilePath) while True: time.sleep(1) diff --git a/genmonlib/controller.py b/genmonlib/controller.py index f1922fae..63c0f1ba 100644 --- a/genmonlib/controller.py +++ b/genmonlib/controller.py @@ -25,7 +25,7 @@ class GeneratorController(mysupport.MySupport): #---------------------GeneratorController::__init__------------------------- - def __init__(self, log, newinstall = False, simulation = False, simulationfile = None, message = None, feedback = None): + def __init__(self, log, newinstall = False, simulation = False, simulationfile = None, message = None, feedback = None, ConfigFilePath = None): super(GeneratorController, self).__init__() self.log = log self.NewInstall = newinstall @@ -33,6 +33,10 @@ def __init__(self, log, newinstall = False, simulation = False, simulationfile = self.SimulationFile = simulationfile self.FeedbackPipe = feedback self.MessagePipe = message + if ConfigFilePath == None: + self.ConfigFilePath = "/etc/" + else: + self.ConfigFilePath = ConfigFilePath self.Address = None self.SerialPort = "/dev/serial0" self.BaudRate = 9600 @@ -75,7 +79,7 @@ def __init__(self, log, newinstall = False, simulation = False, simulationfile = config = RawConfigParser() # config parser reads from current directory, when running form a cron tab this is # not defined so we specify the full path - config.read('/etc/genmon.conf') + config.read(self.ConfigFilePath + 'genmon.conf') # getfloat() raises an exception if the value is not a float # getint() and getboolean() also do this for their respective types diff --git a/genmonlib/generac_HPanel.py b/genmonlib/generac_HPanel.py index a0fd819a..d21fb5c3 100644 --- a/genmonlib/generac_HPanel.py +++ b/genmonlib/generac_HPanel.py @@ -315,10 +315,10 @@ class Output8(object): class HPanel(controller.GeneratorController): #---------------------HPanel::__init__-------------------------------------- - def __init__(self, log, newinstall = False, simulation = False, simulationfile = None, message = None, feedback = None): + def __init__(self, log, newinstall = False, simulation = False, simulationfile = None, message = None, feedback = None, ConfigFilePath = None): # call parent constructor - super(HPanel, self).__init__(log, newinstall = newinstall, simulation = simulation, simulationfile = simulationfile, message = message, feedback = feedback) + super(HPanel, self).__init__(log, newinstall = newinstall, simulation = simulation, simulationfile = simulationfile, message = message, feedback = feedback, ConfigFilePath = ConfigFilePath) self.LastEngineState = "" self.CurrentAlarmState = False @@ -484,7 +484,7 @@ def GetConfig(self): config = RawConfigParser() # config parser reads from current directory, when running form a cron tab this is # not defined so we specify the full path - config.read('/etc/genmon.conf') + config.read(self.ConfigFilePath + 'genmon.conf') if config.has_option(ConfigSection, 'address'): self.Address = int(config.get(ConfigSection, 'address'),16) # modbus address diff --git a/genmonlib/generac_evolution.py b/genmonlib/generac_evolution.py index da17ba7b..b8741c3e 100644 --- a/genmonlib/generac_evolution.py +++ b/genmonlib/generac_evolution.py @@ -46,11 +46,11 @@ class Evolution(controller.GeneratorController): #---------------------Evolution::__init__------------------------ - def __init__(self, log, newinstall = False, simulation = False, simulationfile = None, message = None, feedback = None): + def __init__(self, log, newinstall = False, simulation = False, simulationfile = None, message = None, feedback = None, ConfigFilePath = None): #self.log = log # call parent constructor - super(Evolution, self).__init__(log, newinstall = newinstall, simulation = simulation, simulationfile = simulationfile, message = message, feedback = feedback) + super(Evolution, self).__init__(log, newinstall = newinstall, simulation = simulation, simulationfile = simulationfile, message = message, feedback = feedback, ConfigFilePath = ConfigFilePath) # Controller Type self.EvolutionController = None @@ -1172,237 +1172,217 @@ def RegisterIsKnown(self, Register): #------------ Evolution:DisplayRegisters -------------------------------------------- def DisplayRegisters(self, AllRegs = False, DictOut = False): - Registers = collections.OrderedDict() - Regs = collections.OrderedDict() - Registers["Registers"] = Regs + try: + Registers = collections.OrderedDict() + Regs = collections.OrderedDict() + Registers["Registers"] = Regs - RegList = [] + RegList = [] - Regs["Num Regs"] = "%d" % len(self.Registers) - if self.NotChanged == 0: - self.TotalChanged = 0.0 - else: - self.TotalChanged = float(self.Changed)/float(self.NotChanged) - Regs["Not Changed"] = "%d" % self.NotChanged - Regs["Changed"] = "%d" % self.Changed - Regs["Total Changed"] = "%.2f" % self.TotalChanged + Regs["Num Regs"] = "%d" % len(self.Registers) + if self.NotChanged == 0: + self.TotalChanged = 0.0 + else: + self.TotalChanged = float(self.Changed)/float(self.NotChanged) + Regs["Not Changed"] = "%d" % self.NotChanged + Regs["Changed"] = "%d" % self.Changed + Regs["Total Changed"] = "%.2f" % self.TotalChanged - Regs["Base Registers"] = RegList - # print all the registers - for Register, Value in self.Registers.items(): + Regs["Base Registers"] = RegList + # print all the registers + for Register, Value in self.Registers.items(): - # do not display log registers or model register - if self.RegisterIsLog(Register): - continue - ## - RegList.append({Register:Value}) + # do not display log registers or model register + if self.RegisterIsLog(Register): + continue + ## + RegList.append({Register:Value}) - Register = "%04x" % MODEL_REG - Value = self.GetRegisterValueFromList(Register) - if len(Value) != 0: - RegList.append({Register:Value}) + Register = "%04x" % MODEL_REG + Value = self.GetRegisterValueFromList(Register) + if len(Value) != 0: + RegList.append({Register:Value}) - if AllRegs: - Regs["Log Registers"]= self.DisplayLogs(AllLogs = True, RawOutput = True, DictOut = True) + if AllRegs: + Regs["Log Registers"]= self.DisplayLogs(AllLogs = True, RawOutput = True, DictOut = True) - if not DictOut: - return self.printToString(self.ProcessDispatch(Registers,"")) + if not DictOut: + return self.printToString(self.ProcessDispatch(Registers,"")) + except Exception as e1: + self.LogErrorLine("Error in DisplayOutage: " + str(e1)) return Registers #------------ Evolution:CheckForOutage ---------------------------------------- # also update min and max utility voltage def CheckForOutage(self): - if self.DisableOutageCheck: - # do not check for outage - return "" - - Value = self.GetRegisterValueFromList("0009") - if len(Value) != 4: - return "" # we don't have a value for this register yet - UtilityVolts = int(Value, 16) + try: + if self.DisableOutageCheck: + # do not check for outage + return "" - # Get threshold voltage - Value = self.GetRegisterValueFromList("0011") - if len(Value) != 4: - return "" # we don't have a value for this register yet - ThresholdVoltage = int(Value, 16) + if not self.InitComplete: + return "" - # get pickup voltage - if self.EvolutionController and self.LiquidCooled: - Value = self.GetRegisterValueFromList("023b") - if len(Value) != 4: - return "" # we don't have a value for this register yet - PickupVoltage = int(Value, 16) - else: - PickupVoltage = DEFAULT_PICKUP_VOLTAGE + UtilityVolts = self.GetUtilityVoltage(ReturnInt = True) - # if something is wrong then we use some sensible values here - if PickupVoltage == 0: - PickupVoltage = DEFAULT_PICKUP_VOLTAGE - if ThresholdVoltage == 0: - ThresholdVoltage = DEFAULT_THRESHOLD_VOLTAGE + # Get threshold voltage + ThresholdVoltage = self.GetThresholdVoltage(ReturnInt = True) + # get pickup voltage + PickupVoltage = self.GetPickUpVoltage(ReturnInt = True) - # first time thru set the values to the same voltage level - if self.UtilityVoltsMin == 0 and self.UtilityVoltsMax == 0: - self.UtilityVoltsMin = UtilityVolts - self.UtilityVoltsMax = UtilityVolts + # if something is wrong then we use some sensible values here + if PickupVoltage == 0: + PickupVoltage = DEFAULT_PICKUP_VOLTAGE + if ThresholdVoltage == 0: + ThresholdVoltage = DEFAULT_THRESHOLD_VOLTAGE - if UtilityVolts > self.UtilityVoltsMax: - if UtilityVolts > PickupVoltage: + # first time thru set the values to the same voltage level + if self.UtilityVoltsMin == 0 and self.UtilityVoltsMax == 0: + self.UtilityVoltsMin = UtilityVolts self.UtilityVoltsMax = UtilityVolts - if UtilityVolts < self.UtilityVoltsMin: - if UtilityVolts > ThresholdVoltage: - self.UtilityVoltsMin = UtilityVolts + if UtilityVolts > self.UtilityVoltsMax: + if UtilityVolts > PickupVoltage: + self.UtilityVoltsMax = UtilityVolts - TransferStatus = self.GetTransferStatus() + if UtilityVolts < self.UtilityVoltsMin: + if UtilityVolts > ThresholdVoltage: + self.UtilityVoltsMin = UtilityVolts - if len(TransferStatus): - if self.TransferActive: - if TransferStatus == "Utility": - self.TransferActive = False - msgbody = "\nPower is being supplied by the utility line. " - self.MessagePipe.SendMessage("Transfer Switch Changed State Notice at " + self.SiteName, msgbody, msgtype = "outage") - else: - if TransferStatus == "Generator": - self.TransferActive = True - msgbody = "\nPower is being supplied by the generator. " - self.MessagePipe.SendMessage("Transfer Switch Changed State Notice at " + self.SiteName, msgbody, msgtype = "outage") - - # Check for outage - # are we in an outage now - # NOTE: for now we are just comparing these numbers, the generator has a programmable delay - # that must be met once the voltage passes the threshold. This may cause some "switch bounce" - # testing needed - if self.SystemInOutage: - if UtilityVolts > PickupVoltage: - self.SystemInOutage = False - self.LastOutageDuration = datetime.datetime.now() - self.OutageStartTime - OutageStr = str(self.LastOutageDuration).split(".")[0] # remove microseconds from string - msgbody = "\nUtility Power Restored. Duration of outage " + OutageStr - self.MessagePipe.SendMessage("Outage Recovery Notice at " + self.SiteName, msgbody, msgtype = "outage") - # log outage to file - self.LogToFile(self.OutageLog, self.OutageStartTime.strftime("%Y-%m-%d %H:%M:%S"), OutageStr) - else: - if UtilityVolts < ThresholdVoltage: - self.SystemInOutage = True - self.OutageStartTime = datetime.datetime.now() - msgbody = "\nUtility Power Out at " + self.OutageStartTime.strftime("%Y-%m-%d %H:%M:%S") - self.MessagePipe.SendMessage("Outage Notice at " + self.SiteName, msgbody, msgtype = "outage") + TransferStatus = self.GetTransferStatus() + if len(TransferStatus): + if self.TransferActive: + if TransferStatus == "Utility": + self.TransferActive = False + msgbody = "\nPower is being supplied by the utility line. " + self.MessagePipe.SendMessage("Transfer Switch Changed State Notice at " + self.SiteName, msgbody, msgtype = "outage") + else: + if TransferStatus == "Generator": + self.TransferActive = True + msgbody = "\nPower is being supplied by the generator. " + self.MessagePipe.SendMessage("Transfer Switch Changed State Notice at " + self.SiteName, msgbody, msgtype = "outage") + + # Check for outage + # are we in an outage now + # NOTE: for now we are just comparing these numbers, the generator has a programmable delay + # that must be met once the voltage passes the threshold. This may cause some "switch bounce" + # testing needed + if self.SystemInOutage: + if UtilityVolts > PickupVoltage: + self.SystemInOutage = False + self.LastOutageDuration = datetime.datetime.now() - self.OutageStartTime + OutageStr = str(self.LastOutageDuration).split(".")[0] # remove microseconds from string + msgbody = "\nUtility Power Restored. Duration of outage " + OutageStr + self.MessagePipe.SendMessage("Outage Recovery Notice at " + self.SiteName, msgbody, msgtype = "outage") + # log outage to file + self.LogToFile(self.OutageLog, self.OutageStartTime.strftime("%Y-%m-%d %H:%M:%S"), OutageStr) + else: + if UtilityVolts < ThresholdVoltage: + self.SystemInOutage = True + self.OutageStartTime = datetime.datetime.now() + msgbody = "\nUtility Power Out at " + self.OutageStartTime.strftime("%Y-%m-%d %H:%M:%S") + self.MessagePipe.SendMessage("Outage Notice at " + self.SiteName, msgbody, msgtype = "outage") + except Exception as e1: + self.LogErrorLine("Error in CheckForOutage: " + str(e1)) #------------ Evolution:CheckForAlarms ---------------------------------------- # Note this must be called from the Process thread since it queries the log registers # when in master emulation mode def CheckForAlarms(self): - # update outage time, update utility low voltage and high voltage - self.CheckForOutage() - - # now check to see if there is an alarm - Value = self.GetRegisterValueFromList("0001") - if len(Value) != 8: - return "" # we don't have a value for this register yet - RegVal = int(Value, 16) + try: + # update outage time, update utility low voltage and high voltage + self.CheckForOutage() - if RegVal == self.LastAlarmValue: - return # nothing new to report, return + # now check to see if there is an alarm + Value = self.GetRegisterValueFromList("0001") + if len(Value) != 8: + return "" # we don't have a value for this register yet + RegVal = int(Value, 16) - # if we get past this point there is something to report, either first time through - # or there is an alarm that has been set or reset - self.LastAlarmValue = RegVal # update the stored alarm + if RegVal == self.LastAlarmValue: + return # nothing new to report, return - self.UpdateLogRegistersAsMaster() # Update all log registers + # if we get past this point there is something to report, either first time through + # or there is an alarm that has been set or reset + self.LastAlarmValue = RegVal # update the stored alarm - # Create notice email strings - msgsubject = "" - msgbody = "\n\n" - msgbody += self.printToString("Notice from Generator: \n") + self.UpdateLogRegistersAsMaster() # Update all log registers - # get switch state - Value = self.GetSwitchState() - if len(Value): - msgbody += self.printToString("Switch State: " + Value) - #get Engine state - # This reports on the state read at the beginning of the routine which fixes a - # race condition when switching from starting to running - Value = self.GetEngineState(RegVal) - if len(Value): # - msgbody += self.printToString("Engine State: " + Value) + msgsubject = "" + msgbody = "\n" - if self.EvolutionController and self.LiquidCooled: - msgbody += self.printToString("Active Relays: " + self.GetDigitalOutputs()) - msgbody += self.printToString("Active Sensors: " + self.GetSensorInputs()) + if self.SystemInAlarm(): # Update Alarm Status global flag, returns True if system in alarm - if self.SystemInAlarm(): # Update Alarm Status global flag, returns True if system in alarm + msgsubject += "Generator Alert at " + self.SiteName + ": " + AlarmState = self.GetAlarmState() - msgsubject += "Generator Alert at " + self.SiteName + ": " - AlarmState = self.GetAlarmState() + msgsubject += "CRITICAL " + if len(AlarmState): + msgbody += self.printToString("\nCurrent Alarm: " + AlarmState) + else: + msgbody += self.printToString("\nSystem In Alarm! Please check alarm log") - msgsubject += "CRITICAL " - if len(AlarmState): - msgbody += self.printToString("\nCurrent Alarm: " + AlarmState) + msgbody += self.printToString("System In Alarm: 0001:%08x" % RegVal) else: - msgbody += self.printToString("\nSystem In Alarm! Please check alarm log") - - msgbody += self.printToString("System In Alarm: 0001:%08x" % RegVal) - else: - - msgsubject = "Generator Notice: " + self.SiteName - msgbody += self.printToString("\nNo Alarms: 0001:%08x" % RegVal) + msgsubject = "Generator Notice: " + self.SiteName + msgbody += self.DisplayStatus() - # send email notice - msgbody += self.printToString("\nLast Log Entries:") - - # display last log entries - msgbody += self.DisplayLogs(AllLogs = False) # if false don't display full logs + if self.SystemInAlarm(): + msgbody += self.printToString("\nTo clear the Alarm/Warning message, press OFF on the control panel keypad followed by the ENTER key.") + else: + msgbody += self.printToString("\nNo Alarms: 0001:%08x" % RegVal) - if self.SystemInAlarm(): - msgbody += self.printToString("\nTo clear the Alarm/Warning message, press OFF on the control panel keypad followed by the ENTER key.") + self.MessagePipe.SendMessage(msgsubject , msgbody, msgtype = "warn") + except Exception as e1: + self.LogErrorLine("Error in CheckForAlarms: " + str(e1)) - self.MessagePipe.SendMessage(msgsubject , msgbody, msgtype = "warn") #------------ Evolution:DisplayMaintenance ---------------------------------------- def DisplayMaintenance (self, DictOut = False): - # use ordered dict to maintain order of output - # ordered dict to handle evo vs nexus functions - Maintenance = collections.OrderedDict() - Maint = collections.OrderedDict() - Maintenance["Maintenance"] = Maint - Maint["Model"] = self.Model - Maint["Generator Serial Number"] = self.GetSerialNumber() - Maint["Controller"] = self.GetController() - Maint["Nominal RPM"] = self.NominalRPM - Maint["Rated kW"] = self.NominalKW - Maint["Nominal Frequency"] = self.NominalFreq - Maint["Fuel Type"] = self.FuelType - Exercise = collections.OrderedDict() - Exercise["Exercise Time"] = self.GetExerciseTime() - if self.EvolutionController and self.LiquidCooled: - Exercise["Exercise Duration"] = self.GetExerciseDuration() - Maint["Exercise"] = Exercise - Service = collections.OrderedDict() - if not self.EvolutionController and self.LiquidCooled: - Service["Air Filter Service Due"] = self.GetServiceDue("AIR") + " or " + self.GetServiceDueDate("AIR") - Service["Oil Change and Filter Due"] = self.GetServiceDue("OIL") + " or " + self.GetServiceDueDate("OIL") - Service["Spark Plug Change Due"] = self.GetServiceDue("SPARK") + " or " + self.GetServiceDueDate("SPARK") - elif not self.EvolutionController and not self.LiquidCooled: - # Note: On Nexus AC These represent Air Filter, Oil Filter, and Spark Plugs, possibly 5 all together - # The labels are generic for now until I get clarification from someone with a Nexus AC - Service["Air Filter Service Due"] = self.GetServiceDue("AIR") + " or " + self.GetServiceDueDate("AIR") - Service["Oil and Oil Filter Service Due"] = self.GetServiceDue("OIL") + " or " + self.GetServiceDueDate("OIL") - Service["Spark Plug Service Due"] = self.GetServiceDue("SPARK") + " or " + self.GetServiceDueDate("SPARK") - Service["Battery Service Due"] = self.GetServiceDue("BATTERY") + " or " + self.GetServiceDueDate("BATTERY") - else: - Service["Service A Due"] = self.GetServiceDue("A") + " or " + self.GetServiceDueDate("A") - Service["Service B Due"] = self.GetServiceDue("B") + " or " + self.GetServiceDueDate("B") + try: + # use ordered dict to maintain order of output + # ordered dict to handle evo vs nexus functions + Maintenance = collections.OrderedDict() + Maint = collections.OrderedDict() + Maintenance["Maintenance"] = Maint + Maint["Model"] = self.Model + Maint["Generator Serial Number"] = self.GetSerialNumber() + Maint["Controller"] = self.GetController() + Maint["Nominal RPM"] = self.NominalRPM + Maint["Rated kW"] = self.NominalKW + Maint["Nominal Frequency"] = self.NominalFreq + Maint["Fuel Type"] = self.FuelType + Exercise = collections.OrderedDict() + Exercise["Exercise Time"] = self.GetExerciseTime() + if self.EvolutionController and self.LiquidCooled: + Exercise["Exercise Duration"] = self.GetExerciseDuration() + Maint["Exercise"] = Exercise + Service = collections.OrderedDict() + if not self.EvolutionController and self.LiquidCooled: + Service["Air Filter Service Due"] = self.GetServiceDue("AIR") + " or " + self.GetServiceDueDate("AIR") + Service["Oil Change and Filter Due"] = self.GetServiceDue("OIL") + " or " + self.GetServiceDueDate("OIL") + Service["Spark Plug Change Due"] = self.GetServiceDue("SPARK") + " or " + self.GetServiceDueDate("SPARK") + elif not self.EvolutionController and not self.LiquidCooled: + # Note: On Nexus AC These represent Air Filter, Oil Filter, and Spark Plugs, possibly 5 all together + # The labels are generic for now until I get clarification from someone with a Nexus AC + Service["Air Filter Service Due"] = self.GetServiceDue("AIR") + " or " + self.GetServiceDueDate("AIR") + Service["Oil and Oil Filter Service Due"] = self.GetServiceDue("OIL") + " or " + self.GetServiceDueDate("OIL") + Service["Spark Plug Service Due"] = self.GetServiceDue("SPARK") + " or " + self.GetServiceDueDate("SPARK") + Service["Battery Service Due"] = self.GetServiceDue("BATTERY") + " or " + self.GetServiceDueDate("BATTERY") + else: + Service["Service A Due"] = self.GetServiceDue("A") + " or " + self.GetServiceDueDate("A") + Service["Service B Due"] = self.GetServiceDue("B") + " or " + self.GetServiceDueDate("B") - Service["Total Run Hours"] = self.GetRunTimes() - Service["Hardware Version"] = self.GetHardwareVersion() - Service["Firmware Version"] = self.GetFirmwareVersion() - Maint["Service"] = Service + Service["Total Run Hours"] = self.GetRunTimes() + Service["Hardware Version"] = self.GetHardwareVersion() + Service["Firmware Version"] = self.GetFirmwareVersion() + Maint["Service"] = Service + except Exception as e1: + self.LogErrorLine("Error in DisplayMaintenance: " + str(e1)) if not DictOut: return self.printToString(self.ProcessDispatch(Maintenance,"")) @@ -1559,50 +1539,53 @@ def GetLogs(self, Title, StartReg, Stride, AllLogs = False, RawOutput = False): #------------ Evolution:DisplayLogs -------------------------------------------- def DisplayLogs(self, AllLogs = False, DictOut = False, RawOutput = False): - # if DictOut is True, return a dictionary containing a Dictionaries (dict entry for each log) - # Each dict item a log (alarm, start/stop). For Example: - # - # Dict[Logs] = {"Alarm Log" : [Log Entry1, LogEntry2, ...]}, - # {"Start Stop Log" : [Log Entry3, Log Entry 4, ...]}... + try: + # if DictOut is True, return a dictionary containing a Dictionaries (dict entry for each log) + # Each dict item a log (alarm, start/stop). For Example: + # + # Dict[Logs] = {"Alarm Log" : [Log Entry1, LogEntry2, ...]}, + # {"Start Stop Log" : [Log Entry3, Log Entry 4, ...]}... - ALARMLOG = "Alarm Log: " - SERVICELOG = "Service Log: " - STARTSTOPLOG = "Start Stop Log:" + ALARMLOG = "Alarm Log: " + SERVICELOG = "Service Log: " + STARTSTOPLOG = "Start Stop Log:" - EvolutionLog = [[ALARMLOG, ALARM_LOG_STARTING_REG, ALARM_LOG_STRIDE], - [SERVICELOG, SERVICE_LOG_STARTING_REG, SERVICE_LOG_STRIDE], - [STARTSTOPLOG, START_LOG_STARTING_REG, START_LOG_STRIDE]] - NexusLog = [[ALARMLOG, NEXUS_ALARM_LOG_STARTING_REG, NEXUS_ALARM_LOG_STRIDE], - [STARTSTOPLOG, START_LOG_STARTING_REG, START_LOG_STRIDE]] + EvolutionLog = [[ALARMLOG, ALARM_LOG_STARTING_REG, ALARM_LOG_STRIDE], + [SERVICELOG, SERVICE_LOG_STARTING_REG, SERVICE_LOG_STRIDE], + [STARTSTOPLOG, START_LOG_STARTING_REG, START_LOG_STRIDE]] + NexusLog = [[ALARMLOG, NEXUS_ALARM_LOG_STARTING_REG, NEXUS_ALARM_LOG_STRIDE], + [STARTSTOPLOG, START_LOG_STARTING_REG, START_LOG_STRIDE]] - LogParams = EvolutionLog if self.EvolutionController else NexusLog + LogParams = EvolutionLog if self.EvolutionController else NexusLog - RetValue = collections.OrderedDict() - LogDict = collections.OrderedDict() + RetValue = collections.OrderedDict() + LogDict = collections.OrderedDict() - for Params in LogParams: - LogOutput = self.GetLogs(Params[0], Params[1], Params[2], AllLogs, RawOutput) - LogDict = self.MergeDicts(LogDict,LogOutput) + for Params in LogParams: + LogOutput = self.GetLogs(Params[0], Params[1], Params[2], AllLogs, RawOutput) + LogDict = self.MergeDicts(LogDict,LogOutput) - RetValue["Logs"] = LogDict + RetValue["Logs"] = LogDict - UnknownFound = False - for Key, Entries in RetValue["Logs"].items(): - if not AllLogs: - if "unknown" in Entries.lower(): - UnknownFound = True - break - else: - for LogItems in Entries: - if "unknown" in LogItems.lower(): + UnknownFound = False + for Key, Entries in RetValue["Logs"].items(): + if not AllLogs: + if "unknown" in Entries.lower(): UnknownFound = True break - if UnknownFound: - msgbody = "\nThe output appears to have unknown values. Please see the following threads to resolve these issues:" - msgbody += "\n https://github.com/jgyates/genmon/issues/12" - msgbody += "\n https://github.com/jgyates/genmon/issues/13" - RetValue["Note"] = msgbody - self.FeedbackPipe.SendFeedback("Logs", FullLogs = True, Always = True, Message="Unknown Entries in Log") + else: + for LogItems in Entries: + if "unknown" in LogItems.lower(): + UnknownFound = True + break + if UnknownFound: + msgbody = "\nThe output appears to have unknown values. Please see the following threads to resolve these issues:" + msgbody += "\n https://github.com/jgyates/genmon/issues/12" + msgbody += "\n https://github.com/jgyates/genmon/issues/13" + RetValue["Note"] = msgbody + self.FeedbackPipe.SendFeedback("Logs", FullLogs = True, Always = True, Message="Unknown Entries in Log") + except Exception as e1: + self.LogErrorLine("Error in DisplayLogs: " + str(e1)) if not DictOut: return self.printToString(self.ProcessDispatch(RetValue,"")) @@ -2387,31 +2370,39 @@ def GetUnknownSensor(self, Register, RequiresRunning = False, Hex = False): return SensorValue #------------ Evolution:GetRPM --------------------------------------------- - def GetRPM(self): + def GetRPM(self, ReturnInt = True): # get RPM Value = self.GetRegisterValueFromList("0007") if len(Value) != 4: return "" + if ReturnInt: + return int(Value,16) + RPMValue = "%5d" % int(Value,16) return RPMValue #------------ Evolution:GetCurrentOutput ----------------------------------- - def GetCurrentOutput(self): + def GetCurrentOutput(self, ReturnFloat = False): CurrentOutput = 0.0 Divisor = 1.0 CurrentOffset = 0.0 CurrentFloat = 0.0 + + if ReturnFloat: + DefaultReturn = 0.0 + else: + DefaultReturn = "0.00A" try: if not self.PowerMeterIsSupported(): - return "0.00A" + return DefaultReturn EngineState = self.GetEngineState() # report null if engine is not running if "Stopped" in EngineState or "Off" in EngineState or not len(EngineState): - return "0.00A" + return DefaultReturn if self.EvolutionController and self.LiquidCooled: Value = self.GetRegisterValueFromList("0058") @@ -2475,41 +2466,54 @@ def GetCurrentOutput(self): CurrentOutput = (CurrentFloat + CurrentOffset) / Divisor # is the current out of bounds? - VoltageStr = self.removeAlpha(self.GetVoltageOutput()) - if float(VoltageStr) > 100: # only bounds check if the voltage is over 100V to give things a chance to stabalize + Voltage = self.GetVoltageOutput(ReturnInt = True) + if Voltage > 100: # only bounds check if the voltage is over 100V to give things a chance to stabalize if CurrentOutput > ((int(self.NominalKW) * 1000) / 240) + 2 or CurrentOutput < 0: msg = "Current Calculation: %f, CurrentFloat: %f, Divisor: %f, Offset %f" % (CurrentOutput, CurrentFloat, Divisor, CurrentOffset) self.FeedbackPipe.SendFeedback("Current Calculation", Message=msg, FullLogs = True ) + if ReturnFloat: + return CurrentOutput + return "%.2fA" % CurrentOutput except Exception as e1: self.LogErrorLine("Error in GetCurrentOutput: " + str(e1)) - return "0.0A" + return DefaultReturn ##------------ Evolution:GetActiveRotorPoles ------------------------------ - def GetActiveRotorPoles(self): + def GetActiveRotorPoles(self, ReturnInt = True): # (2 * 60 * Freq) / RPM = Num Rotor Poles if not self.EvolutionController: return "" - FreqStr = self.removeAlpha(self.GetFrequency()) - RPMStr = self.removeAlpha(self.GetRPM().strip()) + if ReturnInt: + DefaultReturn = 0 + else: + DefaultReturn = "0" + + try: + FreqFloat = self.GetFrequency(ReturnFloat = True) + RPMInt = self.GetRPM(ReturnInt = True) + + RotorPoles = DefaultReturn - RotorPoles = "0" - if len(FreqStr) and len(RPMStr): - RPMInt = int(RPMStr) if RPMInt: - FreqFloat = float(FreqStr) NumRotorPoles = int(round((2 * 60 * FreqFloat) / RPMInt)) if NumRotorPoles > 4: NumRotorPoles = 0 - RotorPoles = str(NumRotorPoles) + if ReturnInt: + RotorPoles = NumRotorPoles + else: + RotorPoles = str(NumRotorPoles) - return RotorPoles + return RotorPoles + except Exception as e1: + self.LogErrorLine("Error in GetActiveRotorPoles: " + str(e1)) + return DefaultReturn #------------ Evolution:GetPowerOutput --------------------------------------- - def GetPowerOutput(self): + def GetPowerOutput(self, ReturnFloat = False): if not self.PowerMeterIsSupported(): return "" @@ -2519,72 +2523,86 @@ def GetPowerOutput(self): if "Stopped" in EngineState or "Off" in EngineState or not len(EngineState): return "0kW" - CurrentStr = self.removeAlpha(self.GetCurrentOutput()) - VoltageStr = self.removeAlpha(self.GetVoltageOutput()) + Current = self.GetCurrentOutput(ReturnFloat = True) + Voltage = self.GetVoltageOutput(ReturnInt = True) PowerOut = 0.0 - if len(CurrentStr) and len(VoltageStr): - PowerOut = float(VoltageStr) * float(CurrentStr) + if not Current == 0: + PowerOut = Voltage * Current + if ReturnFloat: + return PowerOut / 1000.0 return "%.2fkW" % (PowerOut / 1000.0) #------------ Evolution:GetFrequency --------------------------------------- - def GetFrequency(self, Calculate = False): + def GetFrequency(self, Calculate = False, ReturnFloat = False): # get Frequency FloatTemp = 0.0 + try: - if not Calculate: - Value = self.GetRegisterValueFromList("0008") - if len(Value) != 4: - return "" + if not Calculate: + Value = self.GetRegisterValueFromList("0008") + if len(Value) != 4: + return "" + + IntTemp = int(Value,16) + if self.EvolutionController and self.LiquidCooled: + FloatTemp = IntTemp / 10.0 # Evolution + elif not self.EvolutionController and self.LiquidCooled: + FloatTemp = IntTemp / 1.0 # Nexus Liquid Cooled + FloatTemp = FloatTemp * 2.0 + else: + FloatTemp = IntTemp / 1.0 # Nexus and Evolution Air Cooled - IntTemp = int(Value,16) - if self.EvolutionController and self.LiquidCooled: - FloatTemp = IntTemp / 10.0 # Evolution - elif not self.EvolutionController and self.LiquidCooled: - FloatTemp = IntTemp / 1.0 # Nexus Liquid Cooled - FloatTemp = FloatTemp * 2.0 else: - FloatTemp = IntTemp / 1.0 # Nexus and Evolution Air Cooled - - else: - # (RPM * Poles) / 2 * 60 - RPM = self.GetRPM() - Poles = self.GetActiveRotorPoles() - if len(RPM) and len(Poles): - FloatTemp = (float(RPM) * float(Poles)) / (2*60) + # (RPM * Poles) / 2 * 60 + RPM = self.GetRPM(ReturnInt = True) + Poles = self.GetActiveRotorPoles(ReturnInt = True) + FloatTemp = (RPM * Poles) / (2*60) + except Exception as e1: + self.LogErrorLine("Error in GetFrequency: " + str(e1)) + if ReturnFloat: + return FloatTemp FreqValue = "%2.1f Hz" % FloatTemp return FreqValue #------------ Evolution:GetVoltageOutput -------------------------- - def GetVoltageOutput(self): + def GetVoltageOutput(self, ReturnInt = False): # get Output Voltage Value = self.GetRegisterValueFromList("0012") if len(Value) != 4: return "" + if ReturnInt: + return int(Value,16) + VolatageValue = "%dV" % int(Value,16) return VolatageValue #------------ Evolution:GetPickUpVoltage -------------------------- - def GetPickUpVoltage(self): + def GetPickUpVoltage(self, ReturnInt = False): # get Utility Voltage Pickup Voltage - Value = self.GetRegisterValueFromList("023b") - if len(Value) != 4: - return "" - PickupVoltage = int(Value,16) + if self.EvolutionController and self.LiquidCooled: + Value = self.GetRegisterValueFromList("023b") + if len(Value) != 4: + return "" # we don't have a value for this register yet + PickupVoltage = int(Value, 16) + else: + PickupVoltage = DEFAULT_PICKUP_VOLTAGE + if ReturnInt: + return PickupVoltage return "%dV" % PickupVoltage #------------ Evolution:GetThresholdVoltage -------------------------- - def GetThresholdVoltage(self): + def GetThresholdVoltage(self, ReturnInt = False): # get Utility Voltage Threshold Value = self.GetRegisterValueFromList("0011") @@ -2592,6 +2610,8 @@ def GetThresholdVoltage(self): return "" ThresholdVoltage = int(Value,16) + if ReturnInt: + return ThresholdVoltage return "%dV" % ThresholdVoltage #------------ Evolution:GetSetOutputVoltage -------------------------- @@ -2626,13 +2646,20 @@ def GetStartupDelay(self): return "%d s" % StartupDelay #------------ Evolution:GetUtilityVoltage -------------------------- - def GetUtilityVoltage(self): + def GetUtilityVoltage(self, ReturnInt = False): + + if ReturnInt: + DefaultReturn = 0 + else: + DefaultReturn = "0" # get Utility Voltage Value = self.GetRegisterValueFromList("0009") if len(Value) != 4: - return "" + return DefaultReturn + if ReturnInt: + return int(Value,16) VolatageValue = "%dV" % int(Value,16) return VolatageValue @@ -3032,63 +3059,66 @@ def DisplayOutage(self, DictOut = False): #------------ Evolution:DisplayStatus ---------------------------------------- def DisplayStatus(self, DictOut = False): - Status = collections.OrderedDict() - Stat = collections.OrderedDict() - Status["Status"] = Stat - Engine = collections.OrderedDict() - Stat["Engine"] = Engine - Line = collections.OrderedDict() - Stat["Line State"] = Line - LastLog = collections.OrderedDict() - Stat["Last Log Entries"] = self.DisplayLogs(AllLogs = False, DictOut = True) - Time = collections.OrderedDict() - Stat["Time"] = Time - - - Engine["Switch State"] = self.GetSwitchState() - Engine["Engine State"] = self.GetEngineState() - if self.EvolutionController and self.LiquidCooled: - Engine["Active Relays"] = self.GetDigitalOutputs() - Engine["Active Sensors"] = self.GetSensorInputs() + try: + Status = collections.OrderedDict() + Stat = collections.OrderedDict() + Status["Status"] = Stat + Engine = collections.OrderedDict() + Stat["Engine"] = Engine + Line = collections.OrderedDict() + Stat["Line State"] = Line + LastLog = collections.OrderedDict() + Stat["Last Log Entries"] = self.DisplayLogs(AllLogs = False, DictOut = True) + Time = collections.OrderedDict() + Stat["Time"] = Time + + + Engine["Switch State"] = self.GetSwitchState() + Engine["Engine State"] = self.GetEngineState() + if self.EvolutionController and self.LiquidCooled: + Engine["Active Relays"] = self.GetDigitalOutputs() + Engine["Active Sensors"] = self.GetSensorInputs() - if self.SystemInAlarm(): - Engine["System In Alarm"] = self.GetAlarmState() + if self.SystemInAlarm(): + Engine["System In Alarm"] = self.GetAlarmState() - Engine["Battery Voltage"] = self.GetBatteryVoltage() - if self.EvolutionController and self.LiquidCooled: - Engine["Battery Status"] = self.GetBatteryStatus() + Engine["Battery Voltage"] = self.GetBatteryVoltage() + if self.EvolutionController and self.LiquidCooled: + Engine["Battery Status"] = self.GetBatteryStatus() - Engine["RPM"] = self.GetRPM() + Engine["RPM"] = self.GetRPM() - Engine["Frequency"] = self.GetFrequency() - Engine["Output Voltage"] = self.GetVoltageOutput() + Engine["Frequency"] = self.GetFrequency() + Engine["Output Voltage"] = self.GetVoltageOutput() - if self.PowerMeterIsSupported(): - Engine["Output Current"] = self.GetCurrentOutput() - Engine["Output Power (Single Phase)"] = self.GetPowerOutput() + if self.PowerMeterIsSupported(): + Engine["Output Current"] = self.GetCurrentOutput() + Engine["Output Power (Single Phase)"] = self.GetPowerOutput() - Engine["Active Rotor Poles (Calculated)"] = self.GetActiveRotorPoles() + Engine["Active Rotor Poles (Calculated)"] = self.GetActiveRotorPoles() - if self.bDisplayUnknownSensors: - Engine["Unsupported Sensors"] = self.DisplayUnknownSensors() + if self.bDisplayUnknownSensors: + Engine["Unsupported Sensors"] = self.DisplayUnknownSensors() - if self.EvolutionController: - Line["Transfer Switch State"] = self.GetTransferStatus() - Line["Utility Voltage"] = self.GetUtilityVoltage() - # - Line["Utility Voltage Max"] = "%dV " % (self.UtilityVoltsMax) - Line["Utility Voltage Min"] = "%dV " % (self.UtilityVoltsMin) - Line["Utility Threshold Voltage"] = self.GetThresholdVoltage() + if self.EvolutionController: + Line["Transfer Switch State"] = self.GetTransferStatus() + Line["Utility Voltage"] = self.GetUtilityVoltage() + # + Line["Utility Voltage Max"] = "%dV " % (self.UtilityVoltsMax) + Line["Utility Voltage Min"] = "%dV " % (self.UtilityVoltsMin) + Line["Utility Threshold Voltage"] = self.GetThresholdVoltage() - if self.EvolutionController and self.LiquidCooled: - Line["Utility Pickup Voltage"] = self.GetPickUpVoltage() - Line["Set Output Voltage"] = self.GetSetOutputVoltage() + if self.EvolutionController and self.LiquidCooled: + Line["Utility Pickup Voltage"] = self.GetPickUpVoltage() + Line["Set Output Voltage"] = self.GetSetOutputVoltage() - # Generator time - Time["Monitor Time"] = datetime.datetime.now().strftime("%A %B %-d, %Y %H:%M:%S") - Time["Generator Time"] = self.GetDateTime() + # Generator time + Time["Monitor Time"] = datetime.datetime.now().strftime("%A %B %-d, %Y %H:%M:%S") + Time["Generator Time"] = self.GetDateTime() + except Exception as e1: + self.LogErrorLine("Error in DisplayStatus: " + str(e1)) if not DictOut: return self.printToString(self.ProcessDispatch(Status,"")) @@ -3135,7 +3165,7 @@ def GetConfig(self, reload = False): config = RawConfigParser() # config parser reads from current directory, when running form a cron tab this is # not defined so we specify the full path - config.read('/etc/genmon.conf') + config.read(self.ConfigFilePath + 'genmon.conf') if config.has_option(ConfigSection, 'address'): self.Address = int(config.get(ConfigSection, 'address'),16) # modbus address diff --git a/genmonlib/mymail.py b/genmonlib/mymail.py index 8ece6f7d..d51c62ca 100644 --- a/genmonlib/mymail.py +++ b/genmonlib/mymail.py @@ -26,12 +26,16 @@ #------------ MyMail class -------------------------------------------- class MyMail(mycommon.MyCommon): - def __init__(self, monitor = False, incoming_folder = None, processed_folder = None, incoming_callback = None, localinit = False, loglocation = "/var/log/"): + def __init__(self, monitor = False, incoming_folder = None, processed_folder = None, incoming_callback = None, localinit = False, loglocation = "/var/log/", ConfigFilePath = None): self.Monitor = monitor # true if we receive IMAP email self.IncomingFolder = incoming_folder # folder to look for incoming email self.ProcessedFolder = processed_folder # folder to move mail to once processed self.IncomingCallback = incoming_callback # called back with mail subject as a parameter + if ConfigFilePath == None: + self.ConfigFilePath = "/etc/" + else: + self.ConfigFilePath = ConfigFilePath self.Mailbox = 0 self.EmailSendQueue = [] # queue for email to send self.DisableEmail = False @@ -44,7 +48,7 @@ def __init__(self, monitor = False, incoming_folder = None, processed_folder = N self.configfile = "mymail.conf" else: self.logfile = loglocation + "mymail.log" - self.configfile = "/etc/mymail.conf" + self.configfile = self.ConfigFilePath + "mymail.conf" self.log = mylog.SetupLogger("mymail", self.logfile) diff --git a/genserv.py b/genserv.py index a3f17b34..a117cf40 100644 --- a/genserv.py +++ b/genserv.py @@ -34,7 +34,7 @@ log = None AppPath = "" favicon = "favicon.ico" - +ConfigFilePath = "/etc/" MAIL_CONFIG = "/etc/mymail.conf" GENMON_CONFIG = "/etc/genmon.conf" @@ -621,7 +621,12 @@ def ValidateFilePresent(FileName): #------------------------------------------------------------ if __name__ == "__main__": - address='localhost' if len(sys.argv)<2 else sys.argv[1] + address='localhost' if len(sys.argv) <=2 else sys.argv[1] + + ConfigFilePath='/etc/' if len(sys.argv) <=3 else sys.argv[2] + + MAIL_CONFIG = ConfigFilePath + "mymail.conf" + GENMON_CONFIG = ConfigFilePath + "genmon.conf" AppPath = sys.argv[0] LoadConfig() diff --git a/static/css/dd.css b/static/css/dd.css deleted file mode 100644 index bff213fb..00000000 --- a/static/css/dd.css +++ /dev/null @@ -1,64 +0,0 @@ -.borderRadius{-moz-border-radius:5px; border-radius:5px; } -.borderRadiusTp{-moz-border-radius:5px 5px 0 0; border-radius:5px 5px 0 0;} -.borderRadiusBtm{-moz-border-radius:0 0 5px 5px ; border-radius:0 0 5px 5px;} - -.ddcommon {position:relative;display:-moz-inline-stack; zoom:1; display:inline-block; *display:inline; cursor:default;} -.ddcommon ul{padding:0;margin:0;} -.ddcommon ul li{list-style-type:none;} -.borderRadiusTp ul li:last-child{-moz-border-radius:0 0 5px 5px ; border-radius:0 0 5px 5px;border-bottom:0 none #c3c3c3; } -.borderRadiusBtm ul li:first-child{-moz-border-radius:5px 5px 0 0; border-radius:5px 5px 0 0 ;border-bottom:1 solid #c3c3c3; } - -.ddcommon .disabled img, .ddcommon .disabled span, .ddcommon.disabledAll{ -opacity: .5; /* standard: ff gt 1.5, opera, safari */ --ms-filter:"alpha(opacity=50)"; /* ie 8 */ -filter:alpha(opacity=50); /* ie lt 7 */ --khtml-opacity:.5; /* safari 1.x */ --moz-opacity:.5; /* ff lt 1.5, netscape */ -color:#999999; -} -.ddcommon .clear{clear:both} -.ddcommon .shadow{-moz-box-shadow:5px 5px 5px -5px #888888;-webkit-box-shadow:5px 5px 5px -5px #888888;box-shadow: 5px 5px 5px -5px #888888;} -.ddcommon input.text{color:#7e7e7e;padding:0 0 0 0; position:absolute; background:#fff; display:block; width:98%; height:98%; left:2px; top:0; border:none;} -.ddOutOfVision{position:relative; display:-moz-inline-stack; display:inline-block; zoom:1; *display:inline;} -.borderRadius .shadow{-moz-box-shadow:5px 5px 5px -5px #888888;-webkit-box-shadow:5px 5px 5px -5px #888888;box-shadow: 5px 5px 5px -5px #888888;} -.borderRadiusBtm .shadow{-moz-box-shadow:-5px -5px 5px -5px #888888;-webkit-box-shadow:-5px -5px 5px -5px #888888;box-shadow: -5px -5px 5px -5px #888888} -.borderRadiusTp .border, .borderRadius .border{-moz-border-radius:0 0 5px 5px ; border-radius:0 0 5px 5px;} -.borderRadiusBtm .border{-moz-border-radius:5px 5px 0 0; border-radius:5px 5px 0 0;} -img.fnone{float:none !important} -.ddcommon .divider{width:0; height:100%; position:absolute;} -.ddcommon .ddArrow{display:inline-block; position:absolute; top:50%; right:4px;} -.ddcommon .ddArrow:hover{background-position:0 100%;} -.ddcommon .ddTitle{padding:0; position:relative; display:inline-block; width:100%} -.ddcommon .ddTitle .ddTitleText{display:block;} -.ddcommon .ddTitle .ddTitleText .ddTitleText{padding:0;} -.ddcommon .ddTitle .description{display:block;} -.ddcommon .ddTitle .ddTitleText img{position:relative; vertical-align:middle; float:left} -.ddcommon .ddChild{position:absolute;display:none;width:100%;overflow-y:auto; overflow-x:hidden; zoom:1; z-index:9999} -.ddcommon .ddChild li{clear:both;} -.ddcommon .ddChild li .description{display:block;} -.ddcommon .ddChild li img{border:0 none; position:relative;vertical-align:middle;float:left} -.ddcommon .ddChild li.optgroup{padding:0;} -.ddcommon .ddChild li.optgroup .optgroupTitle{padding:0 5px; font-weight:bold; font-style:italic} -.ddcommon .ddChild li.optgroup ul li{padding:5px 5px 5px 15px} -.ddcommon .noBorderTop{border-top:none 0 !important; padding:0; margin:0;} - -/*************** default theme **********************/ -.dd{border:1px solid #c3c3c3;} -.dd .divider{border-left:1px solid #c3c3c3; border-right:1px solid #fff;; right:24px;} -.dd .ddArrow{width:16px;height:16px; margin-top:-8px; background:url(../images/dd_arrow.gif) no-repeat;} -.dd .ddArrow:hover{background-position:0 100%;} -.dd .ddTitle{color:#000;background:#e2e2e4 url(../images/title-bg.gif) repeat-x left top;} -.dd .ddTitle .ddTitleText{padding:5px 20px 5px 5px;} -.dd .ddTitle .ddTitleText .ddTitleText{padding:0;} -.dd .ddTitle .description{font-size:12px; color:#666} -.dd .ddTitle .ddTitleText img{padding-right:5px;} -.dd .ddChild{border:1px solid #c3c3c3; background-color:#fff; left:-1px;} -.dd .ddChild li{padding:5px; background-color:#fff; border-bottom:1px solid #c3c3c3;} -.dd .ddChild li .description{color:#666;} -.dd .ddChild li .ddlabel{color:#333;} -.dd .ddChild li.hover{background-color:#f2f2f2} -.dd .ddChild li img{padding:0 6px 0 0;} -.dd .ddChild li.optgroup{padding:0;} -.dd .ddChild li.optgroup .optgroupTitle{padding:0 5px; font-weight:bold; font-style:italic} -.dd .ddChild li.optgroup ul li{padding:5px 5px 5px 15px} -.dd .ddChild li.selected{background-color:#d5d5d5; color:#000;} diff --git a/static/css/jquery.CalendarHeatmap.css b/static/css/jquery.CalendarHeatmap.css old mode 100644 new mode 100755 diff --git a/static/css/jquery.idealforms.css b/static/css/jquery.idealforms.css old mode 100644 new mode 100755 index b80b204a..e63e7c91 --- a/static/css/jquery.idealforms.css +++ b/static/css/jquery.idealforms.css @@ -33,12 +33,10 @@ form.idealforms .field.valid input,form.idealforms .field.valid select,form.idea form.idealforms .field.invalid input,form.idealforms .field.invalid select,form.idealforms .field.invalid textarea,form.idealforms .field.invalid .group{color:#430e08;background:#ffeded;border-color:#cc2a18} form.idealforms .field.valid .group,form.idealforms .field.invalid .group,form.idealforms .field.valid textarea,form.idealforms .field.invalid textarea,form.idealforms .field.valid select,form.idealforms .field.invalid select{color:inherit;background:none} form.idealforms .field.valid select,form.idealforms .field.invalid select{background:-webkit-linear-gradient(#fff, #ddd);background:-moz-linear-gradient(#fff, #ddd);background:-o-linear-gradient(#fff, #ddd);background:-ms-linear-gradient(#fff, #ddd);background:linear-gradient(#fff, #ddd)} -form.idealforms .field .icon{position:absolute;width:16px;height:16px;top:50%;left:100%;margin-top:-8px;margin-left:8px;background:url("../images/validation.png") -16px 0 no-repeat;cursor:pointer} -form.idealforms .field.invalid .icon{background-position:-16px 0} -form.idealforms .field.valid .icon{background-position:0 0;cursor:default} +form.idealforms .field .icon{position:absolute;width:16px;height:16px;top:50%;left:100%;margin-top:-8px;margin-left:8px;background:url("../images/sprites.png") no-repeat;cursor:pointer} +form.idealforms .field.invalid .icon{background-position: -20px -317px ;width: 16px;height: 16px;} +form.idealforms .field.valid .icon{background-position: -66px -318px;width: 16px;height: 16px;cursor:default} form.idealforms .field.invalid .group input,form.idealforms .field.valid .group input{border:0;outline:0;-webkit-box-shadow:none;box-shadow:none} -form.idealforms .field.ajax input{color:#463a09;background:#faf9e8;border-color:#cfaa19} -form.idealforms .field.ajax .icon{background:url("../images/loading.gif")} form.idealforms .error{display:none;position:absolute;z-index:1;left:100%;top:50%;padding:1em 0.5em;width:193.33333333333334px;margin-left:40px;background:#ffaaaa;background:-webkit-linear-gradient(#ffaaaa, #ffcccc);background:-moz-linear-gradient(#ffaaaa, #ffcccc);background:-o-linear-gradient(#ffaaaa, #ffcccc);background:-ms-linear-gradient(#ffaaaa, #ffcccc);background:linear-gradient(#ffaaaa, #ffcccc);color:#333333;font-size:70%;font-weight:bold;line-height:1;border:1px solid #ffaaaa;-webkit-border-radius:0 3.01px 3.01px 3.01px;border-radius:0 3.01px 3.01px 3.01px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.15);box-shadow:0 1px 1px rgba(0,0,0,0.15);} form.idealforms .error:after{content:"";position:absolute;z-index:-1;top:-1px;left:-.7em;border-width:.7em;border-style:solid;border-color:transparent;border-top-color:#ffaaaa} form.idealforms .tooltip{display:none;position:absolute;z-index:1;left:100%;top:50%;padding:1em 0.5em;width:193.33333333333334px;margin-left:40px;background:#aaaaaa;background:-webkit-linear-gradient(#aaaaaa, #cccccc);background:-moz-linear-gradient(#aaaaaa, #cccccc);background:-o-linear-gradient(#aaaaaa, #cccccc);background:-ms-linear-gradient(#aaaaaa, #cccccc);background:linear-gradient(#aaaaaa, #cccccc);color:#333333;font-size:70%;font-weight:bold;line-height:1;border:1px solid #aaaaaa;-webkit-border-radius:0 3.01px 3.01px 3.01px;border-radius:0 3.01px 3.01px 3.01px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.15);box-shadow:0 1px 1px rgba(0,0,0,0.15);} diff --git a/static/css/jquery.jqplot.min.css b/static/css/jquery.jqplot.min.css old mode 100644 new mode 100755 diff --git a/static/css/lc_switch.css b/static/css/lc_switch.css old mode 100644 new mode 100755 diff --git a/static/css/print.css b/static/css/print.css old mode 100644 new mode 100755 index 7874e26a..7df7c7e6 --- a/static/css/print.css +++ b/static/css/print.css @@ -23,7 +23,7 @@ h2 { font-family: Arial; } -.registerTD { +.printRegisterTD { border:5px solid white; background-color: #AAAAAA; vertical-align:top; @@ -34,12 +34,12 @@ h2 { font-family: Arial; } -.registerTD table { +.printRegisterTD table { border:2px solid #AAAAAA; height:100%; } -.registerTDtitle { +.printRegisterTDtitle { font-weight: bold; font-family: Arial; border-bottom: 1px solid #444444; @@ -47,20 +47,20 @@ h2 { height:50px; } -.registerTDsubtitle { +.printRegisterTDsubtitle { border-bottom: 1px solid #444444; font-weight: bold; font-family: Arial; font-size:16px; } -.registerTDvalMedium { +.printRegisterTDvalMedium { font-weight: bold; font-family: Arial; font-size:18px; } -.registerTDvalSmall { +.printRegisterTDvalSmall { font-weight: bold; font-family: Arial; font-size:16px; diff --git a/static/css/selectize.default.css b/static/css/selectize.default.css old mode 100644 new mode 100755 diff --git a/static/css/tooltipster.bundle.min.css b/static/css/tooltipster.bundle.min.css old mode 100644 new mode 100755 diff --git a/static/css/vex-theme-os.css b/static/css/vex-theme-os.css old mode 100644 new mode 100755 diff --git a/static/css/vex.css b/static/css/vex.css old mode 100644 new mode 100755 diff --git a/static/favicon.ico b/static/favicon.ico old mode 100644 new mode 100755 diff --git a/static/genmon.css b/static/genmon.css old mode 100644 new mode 100755 index 5aa4c616..e84449ab --- a/static/genmon.css +++ b/static/genmon.css @@ -144,7 +144,159 @@ li a:hover:not(.active) { color: white; } +/* Pictures */ +.registers, .alert_small, .validation_ok, .validation_text, .print10, .print24, .print60, .temp1, .temp2, .temp3, .temp4, .wifi1, .wifi2, .wifi3, .wifi4, .status, .settings, .outage, .notifications, .monitor, .log, .maintenance, .remove_bin, .alert{ + background: url(images/sprites.png) no-repeat; +} + +.registers{ + background-position: -115px -315px ; + width: 20px; + height: 20px; +} + +.alert_small{ + background-position: -161px -61px ; + width: 28px; + height: 28px; +} + +.validation_ok{ + background-position: -66px -318px ; + width: 16px; + height: 16px; +} + +.validation_text{ + background-position: -20px -317px ; + width: 16px; + height: 16px; +} + +.print10{ + background-position: -154px -106px ; + width: 36px; + height: 36px; +} + +.print24{ + background-position: -105px -105px ; + width: 36px; + height: 36px; +} + +.print60{ + background-position: -56px -105px ; + width: 36px; + height: 36px; +} + +.temp1{ + background-position: -14px -158px ; + width: 28px; + height: 28px; +} + +.temp2{ + background-position: -61px -158px ; + width: 28px; + height: 28px; +} + +.temp3{ + background-position: -111px -162px ; + width: 28px; + height: 28px; +} + +.temp4{ + background-position: -160px -161px ; + width: 28px; + height: 28px; +} + +.wifi1{ + background-position: -106px -206px ; + width: 28px; + height: 28px; +} + +.wifi2{ + background-position: -157px -208px ; + width: 28px; + height: 28px; +} + +.wifi3{ + background-position: -110px -261px ; + width: 28px; + height: 28px; +} + +.wifi4{ + background-position: -161px -258px ; + width: 28px; + height: 28px; +} + +.status{ + background-position: -109px -64px ; + width: 20px; + height: 20px; +} + +.settings{ + background-position: -64px -64px ; + width: 20px; + height: 20px; +} + +.outage{ + background-position: -14px -65px ; + width: 20px; + height: 20px; +} + +.notifications{ + background-position: -164px -18px ; + width: 20px; + height: 20px; +} + +.monitor{ + background-position: -113px -16px ; + width: 20px; + height: 20px; +} + +.log{ + background-position: -63px -14px ; + width: 20px; + height: 20px; +} + +.maintenance{ + background-position: -15px -15px ; + width: 20px; + height: 20px; +} + +.remove_bin{ + background-position: -22px -111px ; + width: 24px; + height: 24px; +} + +.alert{ + background-position: -14px -211px ; + width: 64px; + height: 64px; +} + + + +/* Classes */ .gauge-grid { display:table; diff --git a/static/genmon.js b/static/genmon.js old mode 100644 new mode 100755 index f02a6b76..3bdf88c7 --- a/static/genmon.js +++ b/static/genmon.js @@ -1,16 +1,15 @@ -// genmon.js - javascrip source for generator monitor // Define header $("#myheader").html('
Generator Monitor
'); // Define main menu $("#navMenu").html('') ; // global base state @@ -21,6 +20,7 @@ var currentClass = "active"; // CSS class for menu color var menuElement = "status"; var ajaxErrors = {errorCount: 0, lastSuccessTime: 0, log: ""}; var windowActive = true; +var latestVersion = ""; var myGenerator = {PowerGraph: false, sitename: "", nominalRPM: 3600, nominalfrequency: 60, Controller: "", model: "", nominalKW: 22, fueltype: "", UnsentFeedback: false, SystemHealth: false, EnhancedExerciseEnabled: false, OldExerciseParameters:[-1,-1,-1,-1,-1,-1]}; var prevStatusValues = {BatteryVoltage: "12V", UnsentFeedback: "False", SystemHealth: "OK", OutputVoltage: "0V", Frequency: "0.0 Hz", UtilityVoltage: "240V", kwOutput: "0kW", RPM: " 0", basestatus: "READY"}; @@ -44,7 +44,7 @@ SetFavIcon(); GetkWHistory(); GetRegisterNames(); $(document).ready(function() { - $("#footer").html('
GenMon Project on GitHub
'); + $("#footer").html('
GenMon Project on GitHub
'); $('#ajaxWarning').tooltipster({minWidth: '280px', maxWidth: '480px', animation: 'fade', updateAnimation: 'null', contentAsHTML: 'true', delay: 100, animationDuration: 200, side: ['top', 'left'], content: "No Communicatikon Errors occured"}); UpdateRegisters(true, false); setInterval(GetBaseStatus, 3000); // Called every 3 sec @@ -323,7 +323,7 @@ function json2html(json, intent, parentkey) { if (json.length > 0) { intent += "    "; for (var i = 0; i < json.length; ++i) { - outstr += json2html(json[i], intent, parentkey+"_"+i); + outstr += intent + json2html(json[i], intent, parentkey+"_"+i); } } } @@ -811,13 +811,57 @@ function DisplayMonitor(){ processAjaxSuccess(); var outstr = json2html(result, "", "root"); - outstr += '

Update Generator Monitor Software:

'; + outstr += '

Update Generator Monitor Software:

'; outstr += '  '; outstr += '

Submit Registers to Developers:

'; outstr += '  '; $("#mydisplay").html(outstr); - // currentVersion = result["Monitor"]["Generator Monitor Stats"]["Generator Monitor Version"]; + + if ($("#CPU_Temperature").length > 0) { + temp_img = "temp1"; + switch (true) { + case (parseInt(result["Monitor"]["Platform Stats"]["CPU Temperature"].replace(/C/g, '').trim()) > 85): + temp_img = "temp4"; + break; + case (parseInt(result["Monitor"]["Platform Stats"]["CPU Temperature"].replace(/C/g, '').trim()) > 75): + temp_img = "temp3"; + break; + case (parseInt(result["Monitor"]["Platform Stats"]["CPU Temperature"].replace(/C/g, '').trim()) > 50): + temp_img = "temp2"; + break; + } + $("#CPU_Temperature").html('
'+result["Monitor"]["Platform Stats"]["CPU Temperature"] + '
'); + } + + if ($("#WLAN_Signal_Level").length > 0) { + wifi_img = "wifi1"; + switch (true) { + case (parseInt(result["Monitor"]["Platform Stats"]["WLAN Signal Level"].replace(/dBm/g, '').trim()) > -67): + wifi_img = "wifi4"; + break; + case (parseInt(result["Monitor"]["Platform Stats"]["WLAN Signal Level"].replace(/dBm/g, '').trim()) > -70): + wifi_img = "wifi3"; + break; + case (parseInt(result["Monitor"]["Platform Stats"]["WLAN Signal Level"].replace(/dBm/g, '').trim()) > -80): + wifi_img = "wifi2"; + break; + } + $("#WLAN_Signal_Level").html('
'+result["Monitor"]["Platform Stats"]["WLAN Signal Level"] + '
'); + } + currentVersion = result["Monitor"]["Generator Monitor Stats"]["Generator Monitor Version"]; + if (latestVersion == "") { + // var url = "https://api.github.com/repos/jgyates/genmon/releases"; + var url = "https://raw.githubusercontent.com/jgyates/genmon/master/genmon.py"; + $.ajax({dataType: "html", url: url, timeout: 4000, error: function(result) {console.log("got an error")}, success: function(result) { + latestVersion = replaceAll((jQuery.grep(result.split("\n"), function( a ) { return (a.indexOf("GENMON_VERSION") >= 0); }))[0].split(" ")[2], '"', ''); + if (latestVersion != currentVersion) { + $('#updateNeeded').hide().html("
    You are not running the latest version.
    Current Version: " + currentVersion+"
    New Version: " + latestVersion+"

").fadeIn(1000); + } + }}); + } else if (latestVersion != currentVersion) { + $('#updateNeeded').html("
    You are not running the latest version.
    Current Version: " + currentVersion+"
    New Version: " + latestVersion+"

"); + } }}); } @@ -862,22 +906,13 @@ function checkNewVersion(){ } }); - // $('.vex-dialog-button-secondary').hide(); - // $('.vex-dialog-button-primary').hide(); - // var url = "https://api.github.com/repos/jgyates/genmon/releases"; - // $.ajax({dataType: "json", url: url, timeout: 4000, error: processAjaxError, success: function(result) { - // processAjaxSuccess(); - // var latestVersion = result[0]["tag_name"]; - // if (latestVersion != currentVersion) { - // $('.vex-dialog-message').html("A new version is available.
Current Version:" + currentVersion+"
New Version:" + latestVersion); - $('.vex-dialog-message').html("Are you sure you want to update to the latest version?"); - // $('.vex-dialog-button-secondary').show(); - // $('.vex-dialog-button-primary').show(); - // } else { - // $('.vex-dialog-message').html("You are runnign the latest version:" + latestVersion); - // $('.vex-dialog-button-secondary').show(); - // } - // }}); + if (latestVersion != currentVersion) { + // $('.vex-dialog-message').html("A new version is available.
Current Version: " + currentVersion+"
New Version: " + latestVersion); + $('.vex-dialog-message').html("Are you sure you want to update to the latest version?"); + } else { + $('.vex-dialog-message').html("You are runnign the latest version:" + latestVersion); + $('.vex-dialog-button-primary').hide(); + } } //***************************************************************************** @@ -956,8 +991,6 @@ function DisplayNotifications(){ outstr += '    '; $("#mydisplay").html(outstr); - $(".msDropDown").msDropDown(); - $(".dataMask").mask('(000) 000-0000', {placeholder: "(___) ___-____"}); $('.notificationTypes').selectize({ plugins: ['remove_button'], @@ -996,7 +1029,7 @@ function DisplayNotifications(){ function renderNotificationLine(rowcount, line_type, line_text, line_perms) { - var outstr = '
'; + var outstr = '
'; outstr += ''; outstr += ''; @@ -1433,9 +1466,9 @@ function DisplayRegistersFull() } } outstr += ''; - outstr += '
   '; - outstr += '   '; - outstr += '
'; + outstr += '
   '; + outstr += '   '; + outstr += '
'; outstr += ''; $("#mydisplay").html(outstr); @@ -1644,25 +1677,25 @@ function printRegisters (type) { var reg_val = data[reg_key][0]; - outstr += ''; + outstr += ''; outstr += ''; - outstr += ''; - outstr += ''; - outstr += ''; + outstr += ''; + outstr += ''; + outstr += ''; if (min != max) { - outstr += ''; + outstr += ''; outstr += ''; plots.push(reg_key); rowHeight = 45; } else { - outstr += ''; + outstr += ''; } outstr += '
' + reg_key + '
' + BaseRegistersDescription[reg_key] + '
Current Value: ' + regHistory["_10m"][reg_key][0] + '
' + reg_key + '
' + BaseRegistersDescription[reg_key] + '
Current Value: ' + regHistory["_10m"][reg_key][0] + '
Minimum Value: '+min+'
Maximum Value: '+max+'
Minimum Value: '+min+'
Maximum Value: '+max+'
no change
no change
'; outstr += ''; }); if ((Object.keys(data).length % 3) > 0) { for (var i = (Object.keys(data).length % 3); i < 3; i++) { - outstr += ''; + outstr += ''; } } outstr += ''; @@ -1801,7 +1834,7 @@ function GetGeneratorModel() //***************************************************************************** function SetHeaderValues() { - var HeaderStr = '
Generator Monitor at ' + myGenerator["sitename"] + '
'; + var HeaderStr = '
Generator Monitor at ' + myGenerator["sitename"] + '
'; $("#myheader").html(HeaderStr); $("#registers").on('click', function() { MenuClick($(this));}); } @@ -1866,7 +1899,7 @@ function GetRegisterNames() function GenmonAlert(msg) { vex.closeAll(); - vex.dialog.alert({ unsafeMessage: '
'+msg+'
'}); + vex.dialog.alert({ unsafeMessage: '
'+msg+'
'}); } //***************************************************************************** diff --git a/static/images/alert.png b/static/images/alert.png deleted file mode 100644 index 3ff51e5b..00000000 Binary files a/static/images/alert.png and /dev/null differ diff --git a/static/images/log.png b/static/images/log.png deleted file mode 100644 index 68e01a89..00000000 Binary files a/static/images/log.png and /dev/null differ diff --git a/static/images/maintenance.png b/static/images/maintenance.png deleted file mode 100644 index 60129dda..00000000 Binary files a/static/images/maintenance.png and /dev/null differ diff --git a/static/images/monitor.png b/static/images/monitor.png deleted file mode 100644 index dcb34169..00000000 Binary files a/static/images/monitor.png and /dev/null differ diff --git a/static/images/notifications.png b/static/images/notifications.png deleted file mode 100644 index 86fa6d9a..00000000 Binary files a/static/images/notifications.png and /dev/null differ diff --git a/static/images/outage.png b/static/images/outage.png deleted file mode 100644 index 8b8453b8..00000000 Binary files a/static/images/outage.png and /dev/null differ diff --git a/static/images/raw/alert.png b/static/images/raw/alert.png new file mode 100755 index 00000000..73fa7f67 Binary files /dev/null and b/static/images/raw/alert.png differ diff --git a/static/images/raw/alert_small.png b/static/images/raw/alert_small.png new file mode 100755 index 00000000..2188fc60 Binary files /dev/null and b/static/images/raw/alert_small.png differ diff --git a/static/images/dd_arrow.gif b/static/images/raw/dd_arrow.gif old mode 100644 new mode 100755 similarity index 100% rename from static/images/dd_arrow.gif rename to static/images/raw/dd_arrow.gif diff --git a/static/images/raw/log.png b/static/images/raw/log.png new file mode 100755 index 00000000..cbeee43b Binary files /dev/null and b/static/images/raw/log.png differ diff --git a/static/images/raw/maintenance.png b/static/images/raw/maintenance.png new file mode 100755 index 00000000..16ea9549 Binary files /dev/null and b/static/images/raw/maintenance.png differ diff --git a/static/images/raw/monitor.png b/static/images/raw/monitor.png new file mode 100755 index 00000000..814af307 Binary files /dev/null and b/static/images/raw/monitor.png differ diff --git a/static/images/raw/notifications.png b/static/images/raw/notifications.png new file mode 100755 index 00000000..961f4815 Binary files /dev/null and b/static/images/raw/notifications.png differ diff --git a/static/images/raw/outage.png b/static/images/raw/outage.png new file mode 100755 index 00000000..fefb03be Binary files /dev/null and b/static/images/raw/outage.png differ diff --git a/static/images/print10.png b/static/images/raw/print10.png old mode 100644 new mode 100755 similarity index 100% rename from static/images/print10.png rename to static/images/raw/print10.png diff --git a/static/images/print24.png b/static/images/raw/print24.png old mode 100644 new mode 100755 similarity index 100% rename from static/images/print24.png rename to static/images/raw/print24.png diff --git a/static/images/print60.png b/static/images/raw/print60.png old mode 100644 new mode 100755 similarity index 100% rename from static/images/print60.png rename to static/images/raw/print60.png diff --git a/static/images/raw/registers.png b/static/images/raw/registers.png new file mode 100755 index 00000000..78e44199 Binary files /dev/null and b/static/images/raw/registers.png differ diff --git a/static/images/raw/remove_bin.png b/static/images/raw/remove_bin.png new file mode 100755 index 00000000..7ce92cb9 Binary files /dev/null and b/static/images/raw/remove_bin.png differ diff --git a/static/images/raw/settings.png b/static/images/raw/settings.png new file mode 100755 index 00000000..1735982d Binary files /dev/null and b/static/images/raw/settings.png differ diff --git a/static/images/raw/status.png b/static/images/raw/status.png new file mode 100755 index 00000000..e7227297 Binary files /dev/null and b/static/images/raw/status.png differ diff --git a/static/images/raw/temp1.png b/static/images/raw/temp1.png new file mode 100755 index 00000000..c7e750f2 Binary files /dev/null and b/static/images/raw/temp1.png differ diff --git a/static/images/raw/temp2.png b/static/images/raw/temp2.png new file mode 100755 index 00000000..5e78f4ee Binary files /dev/null and b/static/images/raw/temp2.png differ diff --git a/static/images/raw/temp3.png b/static/images/raw/temp3.png new file mode 100755 index 00000000..853da001 Binary files /dev/null and b/static/images/raw/temp3.png differ diff --git a/static/images/raw/temp4.png b/static/images/raw/temp4.png new file mode 100755 index 00000000..7aff8b03 Binary files /dev/null and b/static/images/raw/temp4.png differ diff --git a/static/images/title-bg.gif b/static/images/raw/title-bg.gif old mode 100644 new mode 100755 similarity index 100% rename from static/images/title-bg.gif rename to static/images/raw/title-bg.gif diff --git a/static/images/validation.png b/static/images/raw/validation.png old mode 100644 new mode 100755 similarity index 100% rename from static/images/validation.png rename to static/images/raw/validation.png diff --git a/static/images/raw/validation_ok.png b/static/images/raw/validation_ok.png new file mode 100755 index 00000000..7fcf794c Binary files /dev/null and b/static/images/raw/validation_ok.png differ diff --git a/static/images/raw/validation_text.png b/static/images/raw/validation_text.png new file mode 100755 index 00000000..46a329aa Binary files /dev/null and b/static/images/raw/validation_text.png differ diff --git a/static/images/raw/wifi1.png b/static/images/raw/wifi1.png new file mode 100755 index 00000000..452d1645 Binary files /dev/null and b/static/images/raw/wifi1.png differ diff --git a/static/images/raw/wifi2.png b/static/images/raw/wifi2.png new file mode 100755 index 00000000..d52bcc07 Binary files /dev/null and b/static/images/raw/wifi2.png differ diff --git a/static/images/raw/wifi3.png b/static/images/raw/wifi3.png new file mode 100755 index 00000000..d5d71eba Binary files /dev/null and b/static/images/raw/wifi3.png differ diff --git a/static/images/raw/wifi4.png b/static/images/raw/wifi4.png new file mode 100755 index 00000000..57d383d7 Binary files /dev/null and b/static/images/raw/wifi4.png differ diff --git a/static/images/registers.png b/static/images/registers.png deleted file mode 100644 index ccee8d34..00000000 Binary files a/static/images/registers.png and /dev/null differ diff --git a/static/images/remove.png b/static/images/remove.png deleted file mode 100644 index b0b0386a..00000000 Binary files a/static/images/remove.png and /dev/null differ diff --git a/static/images/settings.png b/static/images/settings.png deleted file mode 100644 index b7989d3d..00000000 Binary files a/static/images/settings.png and /dev/null differ diff --git a/static/images/sprites.png b/static/images/sprites.png new file mode 100755 index 00000000..c64542c9 Binary files /dev/null and b/static/images/sprites.png differ diff --git a/static/images/status.png b/static/images/status.png deleted file mode 100644 index 9f83f780..00000000 Binary files a/static/images/status.png and /dev/null differ diff --git a/static/images/transparent.png b/static/images/transparent.png new file mode 100755 index 00000000..9da19eac Binary files /dev/null and b/static/images/transparent.png differ diff --git a/static/index.html b/static/index.html old mode 100644 new mode 100755 index 7dc9ed35..d42fc8d8 --- a/static/index.html +++ b/static/index.html @@ -8,29 +8,9 @@ Generator Monitor - - - - - - - - - - - - - + - - - - - - - - - + diff --git a/static/index_verbose.html b/static/index_verbose.html new file mode 100755 index 00000000..e7e1e55c --- /dev/null +++ b/static/index_verbose.html @@ -0,0 +1,51 @@ + + + + + + + + Generator Monitor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+

+
+
+ + + + + + diff --git a/static/internal.css b/static/internal.css old mode 100644 new mode 100755 diff --git a/static/internal.html b/static/internal.html old mode 100644 new mode 100755 diff --git a/static/internal.js b/static/internal.js old mode 100644 new mode 100755 diff --git a/static/jquery-3.3.1.min.js b/static/jquery-3.3.1.min.js old mode 100644 new mode 100755 diff --git a/static/js/gauge.min.js b/static/js/gauge.min.js old mode 100644 new mode 100755 diff --git a/static/js/jqplot.dateAxisRenderer.js b/static/js/jqplot.dateAxisRenderer.js old mode 100644 new mode 100755 diff --git a/static/js/jquery.CalendarHeatmap.genmon.js b/static/js/jquery.CalendarHeatmap.genmon.js old mode 100644 new mode 100755 diff --git a/static/js/jquery.dd.min.js b/static/js/jquery.dd.min.js deleted file mode 100644 index 2c8647e0..00000000 --- a/static/js/jquery.dd.min.js +++ /dev/null @@ -1,11 +0,0 @@ -// MSDropDown - jquery.dd.js -// author: Marghoob Suleman - http://www.marghoobsuleman.com/ -// Date: 10 Nov, 2012 -// Version: 3.5.2 -// Revision: 27 -// web: www.marghoobsuleman.com -/* -// msDropDown is free jQuery Plugin: you can redistribute it and/or modify -// it under the terms of the either the MIT License or the Gnu General Public License (GPL) Version 2 -*/ -;eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('4 1E=1E||{};(9($){1E={3Y:{2o:\'3.5.2\'},3Z:"5D 5E",3q:20,41:9(v){6(v!==14){$(".2X").1m({1w:\'3r\',2b:\'4L\'})}1d{$(".2X").1m({1w:\'4M\',2b:\'3s\'})}},3t:\'\',3u:9(a,b,c){c=c||"42";4 d;25(c.2p()){1i"42":1i"4N":d=$(a).2o(b).1b("1V");1j}15 d}};$.3v={};$.2o={};$.2Y(11,$.3v,1E);$.2Y(11,$.2o,1E);6($.1P.1M===1B){$.1P.1M=$.1P.5F}6($.1P.18===1B){$.1P.18=$.1P.5G;$.1P.1x=$.1P.5H}6(1y $.3w.4O===\'9\'){$.3w[\':\'].43=$.3w.4O(9(b){15 9(a){15 $(a).1p().3x().3y(b.3x())>=0}})}1d{$.3w[\':\'].43=9(a,i,m){15 $(a).1p().3x().3y(m[3].3x())>=0}}9 1V(q,t){4 t=$.2Y(11,{1N:{1b:1g,1n:0,3z:1g,2c:0,1Q:14,2Z:5I},3A:\'1V\',1w:5J,1W:7,3B:0,30:11,1J:5K,26:14,3C:\'5L\',2q:\'1X\',3D:\'3r\',2d:11,1C:\'\',3E:0.7,44:11,3F:0,1u:14,3G:\'5M\',2e:\'\',2f:\'\',2g:11,1F:11,2r:11,18:{3u:1g,2G:1g,3H:1g,28:1g,1G:1g,2H:1g,2I:1g,1X:1g,45:1g,48:1g,2s:1g,2J:1g,31:1g,2t:1g,2u:1g}},t);4 u=1a;4 x={49:\'5N\',1R:\'5O\',4a:\'5P\',2h:\'5Q\',1l:\'5R\'};4 y={1V:t.3A,32:\'32\',4P:\'5S 5T\',4b:\'4b\',3I:\'3I\',2K:\'2K\',1q:\'1q\',2X:\'2X\',4Q:\'4Q\',4R:\'4R\',19:\'19\',4c:\'4c\',3J:"3J",4d:"4d",1h:"1h",33:"5U",34:\'34\',3K:\'3K\'};4 z={12:\'5V\',2v:\'2v\',4S:\'5W 4T\',3L:"3L"};4 A=14,1Y=14,1k=14,3M={},q,35={},36=14;4 B=40,4e=38,4f=37,4g=39,4U=27,4h=13,3a=47,4i=16,4j=17,4V=8,4W=46;4 C=14,2i=14,3b=1g,2L=14,3c,5X=14;4 D=3d,3e=4k.5Y.5Z,4X=3e.60(/61/i);t.2g=t.2g.2j();t.1F=t.1F.2j();4 E=9(a){15(62.4Y.2j.4Z(a)=="[50 51]")?11:14};4 F=9(){4 a=3e.3y("63");6(a>0){15 2w(3e.64(a+5,3e.3y(".",a)))}1d{15 0}};4 G=9(){t.3A=$("#"+q).1b("65")||t.3A;t.1W=$("#"+q).1b("66")||t.1W;6($("#"+q).1b("52")==14){t.30=$("#"+q).1b("52")};t.26=$("#"+q).1b("53")||t.26;t.3C=$("#"+q).1b("67")||t.3C;t.2q=$("#"+q).1b("2q")||t.2q;t.3D=$("#"+q).1b("68")||t.3D;t.2d=$("#"+q).1b("69")||t.2d;t.3E=$("#"+q).1b("6a")||t.3E;t.3F=$("#"+q).1b("54")||t.3F;t.1u=$("#"+q).1b("6b")||t.1u;t.3G=$("#"+q).1b("6c")||t.3G;t.2e=$("#"+q).1b("2e")||t.2e;t.2f=$("#"+q).1b("2f")||t.2f;t.2g=$("#"+q).1b("6d")||t.2g;t.1F=$("#"+q).1b("6e")||t.1F;t.2r=$("#"+q).1b("6f")||t.2r;t.2g=t.2g.2j();t.1F=t.1F.2j();t.2r=t.2r.2j()};4 H=9(a){6(3M[a]===1B){3M[a]=D.6g(a)}15 3M[a]};4 I=9(a){4 b=L("1l");15 $("#"+b+" 12."+z.12).1o(a)};4 J=9(){6(t.1N.1b){4 a=["1h","1D","1r"];2M{6(!q.1H){q.1H="42"+1E.3q};t.1N.1b=55(t.1N.1b);4 b="6h"+(1E.3q++);4 c={};c.1H=b;c.3z=t.1N.3z||q.1H;6(t.1N.2c>0){c.2c=t.1N.2c};c.1Q=t.1N.1Q;4 d=O("4N",c);1Z(4 i=0;i1||H(q).1Q==11)?11:14;6(A){1Y=H(q).1Q};56();57();1v("58",2k());1v("59",$("#"+q+" 1S:19"));4 b=L("1l");3c=$("#"+b+" 12."+y.19);6(t.2g==="11"){$("#"+q).18("2H",9(){21(1a.1n)})};H(q).4m=9(e){$("#"+q).2o().1b("1V").4m()}};4 L=9(a){15 q+x[a]};4 M=9(a){4 s=(a.1C===1B)?"":a.1C.5a;15 s};4 N=9(a){4 b=\'\',1r=\'\',1h=\'\',1f=-1,1p=\'\',1e=\'\',1z=\'\',1o;6(a!==1B){4 c=a.1r||"";6(c!=""){4 d=/^\\{.*\\}$/;4 e=d.6s(c);6(e&&t.2d){4 f=55("["+c+"]")};1r=(e&&t.2d)?f[0].1r:1r;1h=(e&&t.2d)?f[0].1h:1h;b=(e&&t.2d)?f[0].1D:c;1z=(e&&t.2d)?f[0].1z:1z;1o=a.1o};1p=a.1p||\'\';1f=a.1f||\'\';1e=a.1e||"";1r=$(a).1M("1b-1r")||$(a).1b("1r")||(1r||"");1h=$(a).1M("1b-1h")||$(a).1b("1h")||(1h||"");b=$(a).1M("1b-1D")||$(a).1b("1D")||(b||"");1z=$(a).1M("1b-1z")||$(a).1b("1z")||(1z||"");1o=$(a).1o()};4 o={1D:b,1r:1r,1h:1h,1f:1f,1p:1p,1e:1e,1z:1z,1o:1o};15 o};4 O=9(a,b,c){4 d=D.6t(a);6(b){1Z(4 i 3O b){25(i){1i"1C":d.1C.5a=b[i];1j;2P:d[i]=b[i];1j}}};6(c){d.6u=c};15 d};4 P=9(){4 a=L("49");6($("#"+a).1c==0){4 b={1C:\'1w: 4M;4n: 2x;2b: 3s;\',1e:y.2X};b.1H=a;4 c=O("2Q",b);$("#"+q).5b(c);$("#"+q).6v($("#"+a))}1d{$("#"+a).1m({1w:0,4n:\'2x\',2b:\'3s\'})};H(q).3f=-1};4 Q=9(){4 a=(t.1F=="11")?" 2R":"";4 b={1e:y.1V+" 5c"+a};4 c=M(H(q));4 w=$("#"+q).6w();b.1C="2Z: "+w+"2N;";6(c.1c>0){b.1C=b.1C+""+c};b.1H=L("1R");b.3f=H(q).3f;4 d=O("2Q",b);15 d};4 R=9(){4 a;6(H(q).1n>=0){a=H(q).1K[H(q).1n]}1d{a={1f:\'\',1p:\'\'}}4 b="",4o="";4 c=$("#"+q).1b("53");6(c){t.26=c};6(t.26!=14){b=" "+t.26;4o=" "+a.1e};4 d=(t.1F=="11")?" "+z.2v:"";4 e=O("2Q",{1e:y.32+b+d});4 f=O("2l",{1e:y.4c});4 g=O("2l",{1e:y.4P});4 h=L("4a");4 i=O("2l",{1e:y.3I+4o,1H:h});4 j=N(a);4 k=j.1D;4 l=j.1p||"";6(k!=""&&t.30){4 m=O("3P");m.4p=k;6(j.1z!=""){m.1e=j.1z+" "}};4 n=O("2l",{1e:y.33},l);e.1s(f);e.1s(g);6(m){i.1s(m)};i.1s(n);e.1s(i);4 o=O("2l",{1e:y.1h},j.1h);i.1s(o);15 e};4 S=9(){4 a=L("2h");4 b=(t.1F=="11")?"2R":"";4 c=O("2y",{1H:a,5d:\'1p\',1f:\'\',6x:\'1x\',1e:\'1p 4T \'+b,1C:\'22: 2z\'});15 c};4 T=9(a){4 b={};4 c=M(a);6(c.1c>0){b.1C=c};4 d=(a.2K)?y.2K:y.1q;d=(a.19)?(d+" "+y.19):d;d=d+" "+z.12;b.1e=d;6(t.26!=14){b.1e=d+" "+a.1e};4 e=O("12",b);4 f=N(a);6(f.1r!=""){e.1r=f.1r};4 g=f.1D;6(g!=""&&t.30){4 h=O("3P");h.4p=g;6(f.1z!=""){h.1e=f.1z+" "}};6(f.1h!=""){4 i=O("2l",{1e:y.1h},f.1h)};4 j=a.1p||"";4 k=O("2l",{1e:y.33},j);6(t.1u===11){4 l=O("2y",{5d:\'3g\',3z:q+t.3G+\'[]\',1f:a.1f||"",1e:"3g"});e.1s(l);6(t.1u===11){l.29=(a.19)?11:14}};6(h){e.1s(h)};e.1s(k);6(i){e.1s(i)}1d{6(h){h.1e=h.1e+z.3L}};4 m=O("2Q",{1e:\'6y\'});e.1s(m);15 e};4 U=9(){4 a=L("1l");4 b={1e:y.4b+" 6z "+z.4S,1H:a};6(A==14){b.1C="z-1o: "+t.1J}1d{b.1C="z-1o:1"};4 c=$("#"+q).1b("54")||t.3F;6(c){b.1C=(b.1C||"")+";2Z:"+c};4 d=O("2Q",b);4 e=O("4q");6(t.26!=14){e.1e=t.26};4 f=H(q).23;1Z(4 i=0;it.1W||t.1W){4 e=$("#"+b+" 12:6A");4 f=2w(e.1m("5e-6B"))+2w(e.1m("5e-2a"));6(t.3B===0){$("#"+b).1m({5f:\'2x\',22:\'3Q\'});t.3B=3h.6C(e.1w());$("#"+b).1m({5f:\'1T\'});6(!A||t.1u===11){$("#"+b).1m({22:\'2z\'})}};c=((t.3B+f)*3h.5g(t.1W,d))+3}1d 6(A){c=$("#"+q).1w()};15 c};4 W=9(){4 j=L("1l");$("#"+j).18("1X",9(e){6(1k===11)15 14;e.1U();e.2m();6(A){3R()}});$("#"+j+" 12."+y.1q).18("1X",9(e){6(e.5h.4r.2p()!=="2y"){2A(1a)}});$("#"+j+" 12."+y.1q).18("2t",9(e){6(1k===11)15 14;3c=$("#"+j+" 12."+y.19);3b=1a;e.1U();e.2m();6(t.1u===11){6(e.5h.4r.2p()==="2y"){2i=11}};6(A===11){6(1Y){6(C===11){$(1a).1t(y.19);4 a=$("#"+j+" 12."+y.19);4 b=I(1a);6(a.1c>1){4 c=$("#"+j+" 12."+z.12);4 d=I(a[0]);4 f=I(a[1]);6(b>f){d=(b);f=f+1};1Z(4 i=3h.5g(d,f);i<=3h.6D(d,f);i++){4 g=c[i];6($(g).3S(y.1q)){$(g).1t(y.19)}}}}1d 6(2i===11){$(1a).6E(y.19);6(t.1u===11){4 h=1a.4s[0];h.29=!h.29}}1d{$("#"+j+" 12."+y.19).1I(y.19);$("#"+j+" 2y:3g").1M("29",14);$(1a).1t(y.19);6(t.1u===11){1a.4s[0].29=11}}}1d{$("#"+j+" 12."+y.19).1I(y.19);$(1a).1t(y.19)}}1d{$("#"+j+" 12."+y.19).1I(y.19);$(1a).1t(y.19)}});$("#"+j+" 12."+y.1q).18("3i",9(e){6(1k===11)15 14;e.1U();e.2m();6(3b!=1g){6(1Y){$(1a).1t(y.19);6(t.1u===11){1a.4s[0].29=11}}}});$("#"+j+" 12."+y.1q).18("2s",9(e){6(1k===11)15 14;$(1a).1t(y.34)});$("#"+j+" 12."+y.1q).18("2J",9(e){6(1k===11)15 14;$("#"+j+" 12."+y.34).1I(y.34)});$("#"+j+" 12."+y.1q).18("2u",9(e){6(1k===11)15 14;e.1U();e.2m();6(t.1u===11){2i=14};4 a=$("#"+j+" 12."+y.19).1c;2L=(3c.1c!=a||a==0)?11:14;3j();3k();3R();3b=1g});6(t.44==14){$("#"+j+" 12."+z.12).18("1X",9(e){6(1k===11)15 14;2B(1a,"1X")});$("#"+j+" 12."+z.12).18("3i",9(e){6(1k===11)15 14;2B(1a,"3i")});$("#"+j+" 12."+z.12).18("2s",9(e){6(1k===11)15 14;2B(1a,"2s")});$("#"+j+" 12."+z.12).18("2J",9(e){6(1k===11)15 14;2B(1a,"2J")});$("#"+j+" 12."+z.12).18("2t",9(e){6(1k===11)15 14;2B(1a,"2t")});$("#"+j+" 12."+z.12).18("2u",9(e){6(1k===11)15 14;2B(1a,"2u")})}};4 X=9(){4 a=L("1l");$("#"+a).1x("1X");$("#"+a+" 12."+y.1q).1x("3i");$("#"+a+" 12."+y.1q).1x("1X");$("#"+a+" 12."+y.1q).1x("2s");$("#"+a+" 12."+y.1q).1x("2J");$("#"+a+" 12."+y.1q).1x("2t");$("#"+a+" 12."+y.1q).1x("2u")};4 Y=9(a,b,c){$("#"+a).1x(b,c);$("#"+a).4t(b);$("#"+a).18(b,c)};4 Z=9(){4 a=L("1R");4 b=L("2h");4 c=L("1l");$("#"+a).18(t.2q,9(e){6(1k===11)15 14;1O(t.2q);e.1U();e.2m();3T(e)});$("#"+a).18("2S",9(e){4 k=e.6F;6(!36&&(k==4h||k==4e||k==B||k==4f||k==4g||(k>=3a&&!A))){3T(e);6(k>=3a){4u()}1d{e.1U();e.6G()}}});$("#"+a).18("31",4v);$("#"+a).18("2I",4w);$("#"+b).18("2I",9(e){Y(a,"31",4v)});W();$("#"+a).18("45",5i);$("#"+a).18("48",5j);$("#"+a).18("3i",5k);$("#"+a).18("6H",5l);$("#"+a).18("2t",5m);$("#"+a).18("2u",5n)};4 4v=9(e){1O("31")};4 4w=9(e){1O("2I")};4 3U=9(){4 a=L("1R");4 b=L("1l");6(A===11&&t.1u===14){$("#"+a+" ."+y.32).3l();$("#"+b).1m({22:\'3Q\',2b:\'4L\'})}1d{6(t.1u===14){1Y=14};$("#"+a+" ."+y.32).2C();$("#"+b).1m({22:\'2z\',2b:\'3s\'});4 c=$("#"+b+" 12."+y.19)[0];$("#"+b+" 12."+y.19).1I(y.19);4 d=I($(c).1t(y.19));21(d)};V(V())};4 4x=9(){4 a=L("1R");4 b=(1k==11)?t.3E:1;6(1k===11){$("#"+a).1t(y.3K)}1d{$("#"+a).1I(y.3K)}};4 5o=9(){4 a=L("2h");6(t.2r=="11"){$("#"+a).18("2T",5p)};3U();4x()};4 57=9(){4 a=Q();4 b=R();a.1s(b);4 c=S();a.1s(c);4 d=U();a.1s(d);$("#"+q).5b(a);P();5o();Z();4 e=L("1l");6(t.2e!=\'\'){$("#"+e).2e(t.2e)};6(t.2f!=\'\'){$("#"+e).2f(t.2f)};6(1y t.18.3u=="9"){t.18.3u.24(u,1A)}};4 4y=9(b){4 c=L("1l");$("#"+c+" 12."+z.12).1I(y.19);6(t.1u===11){$("#"+c+" 12."+z.12+" 2y.3g").1M("29",14)};6(E(b)===11){1Z(4 i=0;i1){4A(b)}1d{c=I($("#"+a+" 12."+y.19))};6((H(q).1n!=c||2L)&&b.1c<=1){2L=14;4 e=3n("2H");H(q).1n=c;21(c);6(1y t.18.2H=="9"){4 d=2k();t.18.2H(d.1b,d.1L)};$("#"+q).4t("2H")}};4 21=9(a,b){6(a!==1B){4 c,1f,2D;6(a==-1){c=-1;1f="";2D="";2E(-1)}1d{6(1y a!="50"){4 d=H(q).1K[a];H(q).1n=a;c=a;1f=N(d);2D=(a>=0)?H(q).1K[a].1p:"";2E(1B,1f);1f=1f.1f}1d{c=(b&&b.1o)||H(q).1n;1f=(b&&b.1f)||H(q).1f;2D=(b&&b.1p)||H(q).1K[H(q).1n].1p||"";2E(c)}};1v("1n",c);1v("1f",1f);1v("2D",2D);1v("23",H(q).23);1v("58",2k());1v("59",$("#"+q+" 1S:19"))}};4 3n=9(a){4 b={2U:14,2V:14,2n:14};4 c=$("#"+q);2M{6(c.1M("18"+a)!==1g){b.2n=11;b.2U=11}}2O(e){}4 d;6(1y $.5q=="9"){d=$.5q(c[0],"4B")}1d{d=c.1b("4B")};6(d&&d[a]){b.2n=11;b.2V=11};15 b};4 3R=9(){3k();$("5r").18("1X",2A);$(3d).18("2S",4C);$(3d).18("2T",4D)};4 3k=9(){$("5r").1x("1X",2A);$(3d).1x("2S",4C);$(3d).1x("2T",4D)};4 5p=9(e){6(e.2W<3a&&e.2W!=4V&&e.2W!=4W){15 14};4 a=L("1l");4 b=L("2h");4 c=H(b).1f;6(c.1c==0){$("#"+a+" 12:2x").2C();V(V())}1d{$("#"+a+" 12").3l();4 d=$("#"+a+" 12:43(\'"+c+"\')").2C();6($("#"+a+" 12:1T").1c<=t.1W){V(-1)};6(d.1c>0&&!A||!1Y){$("#"+a+" ."+y.19).1I(y.19);$(d[0]).1t(y.19)}};6(!A){3o()}};4 4u=9(){6(t.2r=="11"){4 a=L("1R");4 b=L("2h");6($("#"+b+":2x").1c>0&&2i==14){$("#"+b+":2x").2C().6I("");Y(a,"2I",4w);H(b).31()}}};4 5s=9(){4 a=L("2h");6($("#"+a+":1T").1c>0){$("#"+a+":1T").3l();H(a).2I()}};4 4C=9(a){4 b=L("2h");4 c=L("1l");25(a.2W){1i B:1i 4g:a.1U();a.2m();5t();1j;1i 4e:1i 4f:a.1U();a.2m();5u();1j;1i 4U:1i 4h:a.1U();a.2m();2A();4 d=$("#"+c+" 12."+y.19).1c;2L=(3c.1c!=d||d==0)?11:14;3j();3k();3b=1g;1j;1i 4i:C=11;1j;1i 4j:2i=11;1j;2P:6(a.2W>=3a&&A===14){4u()};1j};6(1k===11)15 14;1O("2S")};4 4D=9(a){25(a.2W){1i 4i:C=14;1j;1i 4j:2i=14;1j};6(1k===11)15 14;1O("2T")};4 5i=9(a){6(1k===11)15 14;1O("45")};4 5j=9(a){6(1k===11)15 14;1O("48")};4 5k=9(a){6(1k===11)15 14;a.1U();1O("2s")};4 5l=9(a){6(1k===11)15 14;a.1U();1O("2J")};4 5m=9(a){6(1k===11)15 14;1O("2t")};4 5n=9(a){6(1k===11)15 14;1O("2u")};4 3V=9(a,b){4 c={2U:14,2V:14,2n:14};6($(a).1M("18"+b)!=1B){c.2n=11;c.2U=11};4 d=$(a).1b("4B");6(d&&d[b]){c.2n=11;c.2V=11};15 c};4 2B=9(a,b){6(t.44==14){4 c=H(q).1K[I(a)];6(3V(c,b).2n===11){6(3V(c,b).2U===11){c["18"+b]()};6(3V(c,b).2V===11){25(b){1i"2S":1i"2T":1j;2P:$(c).4t(b);1j}};15 14}}};4 1O=9(a){6(1y t.18[a]=="9"){t.18[a].24(1a,1A)};6(3n(a).2n===11){6(3n(a).2U===11){H(q)["18"+a]()}1d 6(3n(a).2V===11){25(a){1i"2S":1i"2T":1j;2P:$("#"+q).6J(a);1j}};15 14}};4 3W=9(a){4 b=L("1l");a=(a!==1B)?a:$("#"+b+" 12."+y.19);6(a.1c>0){4 c=2w(($(a).2b().2a));4 d=2w($("#"+b).1w());6(c>d){4 e=c+$("#"+b).3p()-(d/2);$("#"+b).5v({3p:e},5w)}}};4 5t=9(){4 b=L("1l");4 c=$("#"+b+" 12:1T."+z.12);4 d=$("#"+b+" 12:1T."+y.19);d=(d.1c==0)?c[0]:d;4 e=$("#"+b+" 12:1T."+z.12).1o(d);6((ec.1c){15 a};6($(c[a]).3S(y.1q)===11){15 a};15 a=4E(a)}};4 5u=9(){4 b=L("1l");4 c=$("#"+b+" 12:1T."+y.19);4 d=$("#"+b+" 12:1T."+z.12);4 e=$("#"+b+" 12:1T."+z.12).1o(c[0]);6(e>=0){e=4F(e);6(e>=0){6(!C||!A||!1Y){$("#"+b+" ."+y.19).1I(y.19)};$(d[e]).1t(y.19);2E(e);6(A==11){3j()};6(2w(($(d[e]).2b().2a+$(d[e]).1w()))<=0){4 f=($("#"+b).3p()-$("#"+b).1w())-$(d[e]).1w();$("#"+b).5v({3p:f},5w)}};6(!A){3o()}};9 4F(a){a=a-1;6(a<0){15 a};6($(d[a]).3S(y.1q)===11){15 a};15 a=4F(a)}};4 3o=9(){4 a=L("1R");4 b=L("1l");4 c=$("#"+a).5x();4 d=$("#"+a).1w();4 e=$(4k).1w();4 f=$(4k).3p();4 g=$("#"+b).1w();4 h=$("#"+a).1w();4 i=t.3D.2p();6(((e+f)<3h.6K(g+d+c.2a)||i==\'6L\')&&i!=\'6M\'){h=g;$("#"+b).1m({2a:"-"+h+"2N",22:\'3Q\',1J:t.1J});6(t.1F=="11"){$("#"+a).1I("2R 2v").1t("3X")};4 h=$("#"+b).5x().2a;6(h<-10){$("#"+b).1m({2a:(2w($("#"+b).1m("2a"))-h+20+f)+"2N",1J:t.1J});6(t.1F=="11"){$("#"+a).1I("3X 2v").1t("2R")}}}1d{$("#"+b).1m({2a:h+"2N",1J:t.1J});6(t.1F=="11"){$("#"+a).1I("2R 3X").1t("2v")}};6(4X){6(F()<=7){$(\'2Q.5c\').1m("1J",t.1J-10);$("#"+a).1m("1J",t.1J+5)}}};4 3T=9(e){6(1k===11)15 14;4 a=L("1R");4 b=L("1l");6(!36){36=11;6(1E.3t!=\'\'){$("#"+1E.3t).1m({22:"2z"})};1E.3t=b;$("#"+b+" 12:2x").2C();3o();4 c=t.3C;6(c==""||c=="2z"){$("#"+b).1m({22:"3Q"});3W();6(1y t.18.2G=="9"){4 d=2k();t.18.2G(d.1b,d.1L)}}1d{$("#"+b)[c]("6N",9(){3W();6(1y t.18.2G=="9"){4 d=2k();t.18.2G(d.1b,d.1L)}})};3R()}1d{6(t.2q!==\'2s\'){2A()}}};4 2A=9(e){36=14;4 a=L("1R");4 b=L("1l");6(A===14||t.1u===11){$("#"+b).1m({22:"2z"});6(t.1F=="11"){$("#"+a).1I("2v 3X").1t("2R")}};3k();6(1y t.18.3H=="9"){4 d=2k();t.18.3H(d.1b,d.1L)};5s();V(V());$("#"+b).1m({1J:1});2E(H(q).1n)};4 56=9(){2M{35=$.2Y(11,{},H(q));1Z(4 i 3O 35){6(1y 35[i]!="9"){u[i]=35[i]}}}2O(e){};u.2D=(H(q).1n>=0)?H(q).1K[H(q).1n].1p:"";u.3Y=1E.3Y.2o;u.3Z=1E.3Z};4 4G=9(a){6(a!=1g&&1y a!="1B"){4 b=L("1l");4 c=N(a);4 d=$("#"+b+" 12."+z.12+":4H("+(a.1o)+")");15{1b:c,1L:d,1S:a,1o:a.1o}};15 1g};4 2k=9(){4 a=L("1l");4 b=H(q);4 c,1L,1S,1o;6(b.1n==-1){c=1g;1L=1g;1S=1g;1o=-1}1d{1L=$("#"+a+" 12."+y.19);6(1L.1c>1){4 d=[],4I=[],6O=[];1Z(4 i=0;i<1L.1c;i++){4 e=I(1L[i]);d.5y(e);4I.5y(b.1K[e])};c=d;1S=4I;1o=d}1d{1S=b.1K[b.1n];c=N(1S);1o=b.1n}};15{1b:c,1L:1L,1o:1o,1S:1S}};4 2E=9(a,b){4 c=L("4a");4 d={};6(a==-1){d.1p="&6P;";d.1e="";d.1h="";d.1D=""}1d 6(1y a!="1B"){4 e=H(q).1K[a];d=N(e)}1d{d=b};$("#"+c).3m("."+y.33).4J(d.1p);H(c).1e=y.3I+" "+d.1e;6(d.1h!=""){$("#"+c).3m("."+y.1h).4J(d.1h).2C()}1d{$("#"+c).3m("."+y.1h).4J("").3l()};4 f=$("#"+c).3m("3P");6(f.1c>0){$(f).1G()};6(d.1D!=""&&t.30){f=O("3P",{4p:d.1D});$("#"+c).2f(f);6(d.1z!=""){f.1e=d.1z+" "};6(d.1h==""){f.1e=f.1e+z.3L}}};4 1v=9(p,v){u[p]=v};4 4K=9(a,b,i){4 c=L("1l");4 d=14;25(a){1i"28":4 e=T(b||H(q).1K[i]);4 f;6(1A.1c==3){f=i}1d{f=$("#"+c+" 12."+z.12).1c-1};6(f<0||!f){$("#"+c+" 4q").2e(e)}1d{4 g=$("#"+c+" 12."+z.12)[f];$(g).6Q(e)};X();W();6(t.18.28!=1g){t.18.28.24(1a,1A)};1j;1i"1G":d=$($("#"+c+" 12."+z.12)[i]).3S(y.19);$("#"+c+" 12."+z.12+":4H("+i+")").1G();4 h=$("#"+c+" 12."+y.1q);6(d==11){6(h.1c>0){$(h[0]).1t(y.19);4 j=$("#"+c+" 12."+z.12).1o(h[0]);21(j)}};6(h.1c==0){21(-1)};6($("#"+c+" 12."+z.12).1c1||H(q).1Q==11)?11:14;3U();1j;1i"1Q":H(q)[a]=b;A=(H(q).2c>1||H(q).1Q==11)?11:14;1Y=H(q).1Q;3U();1v(a,b);1j;1i"2K":H(q)[a]=b;1k=b;4x();1j;1i"1n":1i"1f":6(a=="1n"&&E(b)===11){$("#"+q+" 1S").1M("19",14);4A(b,11);4y(b)}1d{H(q)[a]=b;4y(H(q).1n);21(H(q).1n)};1j;1i"1c":4 c=L("1l");6(bd?g=10*e:f>=g&&f!==d?c.maskDigitPosMapOld[g]||(f=g,g=g-(l-h)-a,c.maskDigitPosMap[g]&&(g=f)):g>f&& -(g=g+(h-l)+m)}return g},behaviour:function(f){f=f||window.event;c.invalid=[];var e=b.data("mask-keycode");if(-1===a.inArray(e,m.byPassKeys)){var e=c.getMasked(),g=c.getCaret();setTimeout(function(){c.setCaret(c.calculateCaretPosition())},a.jMaskGlobals.keyStrokeCompensation);c.val(e);c.setCaret(g);return c.callbacks(f)}},getMasked:function(a,b){var g=[],d=void 0===b?c.val():b+"",n=0,h=e.length,q=0,l=d.length,k=1,r="push",p=-1,t=0,y=[],v,z;f.reverse?(r="unshift",k=-1,v=0,n=h-1,q=l-1,z=function(){return-1< -n&&-1 0) { + p = self.__plugins[pluginName]; + } + // otherwise, return the first name that matches + else { + $.each(self.__plugins, function(i, plugin) { + + if (plugin.name.substring(plugin.name.length - pluginName.length - 1) == '.'+ pluginName) { + p = plugin; + return false; + } + }); + } + + return p; + } + // setter + else { + + // force namespaces + if (plugin.name.indexOf('.') < 0) { + throw new Error('Plugins must be namespaced'); + } + + self.__plugins[plugin.name] = plugin; + + // if the plugin has core features + if (plugin.core) { + + // bridge non-private methods onto the core to allow new core methods + self.__bridge(plugin.core, self, plugin.name); + } + + return this; + } + }, + + /** + * Trigger events on the core emitters + * + * @returns {core} + * @protected + */ + _trigger: function() { + + var args = Array.prototype.slice.apply(arguments); + + if (typeof args[0] == 'string') { + args[0] = { type: args[0] }; + } + + // note: the order of emitters matters + this.__$emitterPrivate.trigger.apply(this.__$emitterPrivate, args); + this.__$emitterPublic.trigger.apply(this.__$emitterPublic, args); + + return this; + }, + + /** + * Returns instances of all tooltips in the page or an a given element + * + * @param {string|HTML object collection} selector optional Use this + * parameter to restrict the set of objects that will be inspected + * for the retrieval of instances. By default, all instances in the + * page are returned. + * @return {array} An array of instance objects + * @public + */ + instances: function(selector) { + + var instances = [], + sel = selector || '.tooltipstered'; + + $(sel).each(function() { + + var $this = $(this), + ns = $this.data('tooltipster-ns'); + + if (ns) { + + $.each(ns, function(i, namespace) { + instances.push($this.data(namespace)); + }); + } + }); + + return instances; + }, + + /** + * Returns the Tooltipster objects generated by the last initializing call + * + * @return {array} An array of instance objects + * @public + */ + instancesLatest: function() { + return this.__instancesLatestArr; + }, + + /** + * For public use only, not to be used by plugins (use ::_off() instead) + * + * @return {core} + * @public + */ + off: function() { + this.__$emitterPublic.off.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); + return this; + }, + + /** + * For public use only, not to be used by plugins (use ::_on() instead) + * + * @return {core} + * @public + */ + on: function() { + this.__$emitterPublic.on.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); + return this; + }, + + /** + * For public use only, not to be used by plugins (use ::_one() instead) + * + * @return {core} + * @public + */ + one: function() { + this.__$emitterPublic.one.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); + return this; + }, + + /** + * Returns all HTML elements which have one or more tooltips + * + * @param {string} selector optional Use this to restrict the results + * to the descendants of an element + * @return {array} An array of HTML elements + * @public + */ + origins: function(selector) { + + var sel = selector ? + selector +' ' : + ''; + + return $(sel +'.tooltipstered').toArray(); + }, + + /** + * Change default options for all future instances + * + * @param {object} d The options that should be made defaults + * @return {core} + * @public + */ + setDefaults: function(d) { + $.extend(defaults, d); + return this; + }, + + /** + * For users to trigger their handlers on the public emitter + * + * @returns {core} + * @public + */ + triggerHandler: function() { + this.__$emitterPublic.triggerHandler.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); + return this; + } +}; + +// $.tooltipster will be used to call core methods +$.tooltipster = new core(); + +// the Tooltipster instance class (mind the capital T) +$.Tooltipster = function(element, options) { + + // list of instance variables + + // stack of custom callbacks provided as parameters to API methods + this.__callbacks = { + close: [], + open: [] + }; + // the schedule time of DOM removal + this.__closingTime; + // this will be the user content shown in the tooltip. A capital "C" is used + // because there is also a method called content() + this.__Content; + // for the size tracker + this.__contentBcr; + // to disable the tooltip after destruction + this.__destroyed = false; + // we can't emit directly on the instance because if a method with the same + // name as the event exists, it will be called by jQuery. Se we use a plain + // object as emitter. This emitter is for internal use by plugins, + // if needed. + this.__$emitterPrivate = $({}); + // this emitter is for the user to listen to events without risking to mess + // with our internal listeners + this.__$emitterPublic = $({}); + this.__enabled = true; + // the reference to the gc interval + this.__garbageCollector; + // various position and size data recomputed before each repositioning + this.__Geometry; + // the tooltip position, saved after each repositioning by a plugin + this.__lastPosition; + // a unique namespace per instance + this.__namespace = 'tooltipster-'+ Math.round(Math.random()*1000000); + this.__options; + // will be used to support origins in scrollable areas + this.__$originParents; + this.__pointerIsOverOrigin = false; + // to remove themes if needed + this.__previousThemes = []; + // the state can be either: appearing, stable, disappearing, closed + this.__state = 'closed'; + // timeout references + this.__timeouts = { + close: [], + open: null + }; + // store touch events to be able to detect emulated mouse events + this.__touchEvents = []; + // the reference to the tracker interval + this.__tracker = null; + // the element to which this tooltip is associated + this._$origin; + // this will be the tooltip element (jQuery wrapped HTML element). + // It's the job of a plugin to create it and append it to the DOM + this._$tooltip; + + // launch + this.__init(element, options); +}; + +$.Tooltipster.prototype = { + + /** + * @param origin + * @param options + * @private + */ + __init: function(origin, options) { + + var self = this; + + self._$origin = $(origin); + self.__options = $.extend(true, {}, defaults, options); + + // some options may need to be reformatted + self.__optionsFormat(); + + // don't run on old IE if asked no to + if ( !env.IE + || env.IE >= self.__options.IEmin + ) { + + // note: the content is null (empty) by default and can stay that + // way if the plugin remains initialized but not fed any content. The + // tooltip will just not appear. + + // let's save the initial value of the title attribute for later + // restoration if need be. + var initialTitle = null; + + // it will already have been saved in case of multiple tooltips + if (self._$origin.data('tooltipster-initialTitle') === undefined) { + + initialTitle = self._$origin.attr('title'); + + // we do not want initialTitle to be "undefined" because + // of how jQuery's .data() method works + if (initialTitle === undefined) initialTitle = null; + + self._$origin.data('tooltipster-initialTitle', initialTitle); + } + + // If content is provided in the options, it has precedence over the + // title attribute. + // Note: an empty string is considered content, only 'null' represents + // the absence of content. + // Also, an existing title="" attribute will result in an empty string + // content + if (self.__options.content !== null) { + self.__contentSet(self.__options.content); + } + else { + + var selector = self._$origin.attr('data-tooltip-content'), + $el; + + if (selector){ + $el = $(selector); + } + + if ($el && $el[0]) { + self.__contentSet($el.first()); + } + else { + self.__contentSet(initialTitle); + } + } + + self._$origin + // strip the title off of the element to prevent the default tooltips + // from popping up + .removeAttr('title') + // to be able to find all instances on the page later (upon window + // events in particular) + .addClass('tooltipstered'); + + // set listeners on the origin + self.__prepareOrigin(); + + // set the garbage collector + self.__prepareGC(); + + // init plugins + $.each(self.__options.plugins, function(i, pluginName) { + self._plug(pluginName); + }); + + // to detect swiping + if (env.hasTouchCapability) { + $(env.window.document.body).on('touchmove.'+ self.__namespace +'-triggerOpen', function(event) { + self._touchRecordEvent(event); + }); + } + + self + // prepare the tooltip when it gets created. This event must + // be fired by a plugin + ._on('created', function() { + self.__prepareTooltip(); + }) + // save position information when it's sent by a plugin + ._on('repositioned', function(e) { + self.__lastPosition = e.position; + }); + } + else { + self.__options.disabled = true; + } + }, + + /** + * Insert the content into the appropriate HTML element of the tooltip + * + * @returns {self} + * @private + */ + __contentInsert: function() { + + var self = this, + $el = self._$tooltip.find('.tooltipster-content'), + formattedContent = self.__Content, + format = function(content) { + formattedContent = content; + }; + + self._trigger({ + type: 'format', + content: self.__Content, + format: format + }); + + if (self.__options.functionFormat) { + + formattedContent = self.__options.functionFormat.call( + self, + self, + { origin: self._$origin[0] }, + self.__Content + ); + } + + if (typeof formattedContent === 'string' && !self.__options.contentAsHTML) { + $el.text(formattedContent); + } + else { + $el + .empty() + .append(formattedContent); + } + + return self; + }, + + /** + * Save the content, cloning it beforehand if need be + * + * @param content + * @returns {self} + * @private + */ + __contentSet: function(content) { + + // clone if asked. Cloning the object makes sure that each instance has its + // own version of the content (in case a same object were provided for several + // instances) + // reminder: typeof null === object + if (content instanceof $ && this.__options.contentCloning) { + content = content.clone(true); + } + + this.__Content = content; + + this._trigger({ + type: 'updated', + content: content + }); + + return this; + }, + + /** + * Error message about a method call made after destruction + * + * @private + */ + __destroyError: function() { + throw new Error('This tooltip has been destroyed and cannot execute your method call.'); + }, + + /** + * Gather all information about dimensions and available space, + * called before every repositioning + * + * @private + * @returns {object} + */ + __geometry: function() { + + var self = this, + $target = self._$origin, + originIsArea = self._$origin.is('area'); + + // if this._$origin is a map area, the target we'll need + // the dimensions of is actually the image using the map, + // not the area itself + if (originIsArea) { + + var mapName = self._$origin.parent().attr('name'); + + $target = $('img[usemap="#'+ mapName +'"]'); + } + + var bcr = $target[0].getBoundingClientRect(), + $document = $(env.window.document), + $window = $(env.window), + $parent = $target, + // some useful properties of important elements + geo = { + // available space for the tooltip, see down below + available: { + document: null, + window: null + }, + document: { + size: { + height: $document.height(), + width: $document.width() + } + }, + window: { + scroll: { + // the second ones are for IE compatibility + left: env.window.scrollX || env.window.document.documentElement.scrollLeft, + top: env.window.scrollY || env.window.document.documentElement.scrollTop + }, + size: { + height: $window.height(), + width: $window.width() + } + }, + origin: { + // the origin has a fixed lineage if itself or one of its + // ancestors has a fixed position + fixedLineage: false, + // relative to the document + offset: {}, + size: { + height: bcr.bottom - bcr.top, + width: bcr.right - bcr.left + }, + usemapImage: originIsArea ? $target[0] : null, + // relative to the window + windowOffset: { + bottom: bcr.bottom, + left: bcr.left, + right: bcr.right, + top: bcr.top + } + } + }, + geoFixed = false; + + // if the element is a map area, some properties may need + // to be recalculated + if (originIsArea) { + + var shape = self._$origin.attr('shape'), + coords = self._$origin.attr('coords'); + + if (coords) { + + coords = coords.split(','); + + $.map(coords, function(val, i) { + coords[i] = parseInt(val); + }); + } + + // if the image itself is the area, nothing more to do + if (shape != 'default') { + + switch(shape) { + + case 'circle': + + var circleCenterLeft = coords[0], + circleCenterTop = coords[1], + circleRadius = coords[2], + areaTopOffset = circleCenterTop - circleRadius, + areaLeftOffset = circleCenterLeft - circleRadius; + + geo.origin.size.height = circleRadius * 2; + geo.origin.size.width = geo.origin.size.height; + + geo.origin.windowOffset.left += areaLeftOffset; + geo.origin.windowOffset.top += areaTopOffset; + + break; + + case 'rect': + + var areaLeft = coords[0], + areaTop = coords[1], + areaRight = coords[2], + areaBottom = coords[3]; + + geo.origin.size.height = areaBottom - areaTop; + geo.origin.size.width = areaRight - areaLeft; + + geo.origin.windowOffset.left += areaLeft; + geo.origin.windowOffset.top += areaTop; + + break; + + case 'poly': + + var areaSmallestX = 0, + areaSmallestY = 0, + areaGreatestX = 0, + areaGreatestY = 0, + arrayAlternate = 'even'; + + for (var i = 0; i < coords.length; i++) { + + var areaNumber = coords[i]; + + if (arrayAlternate == 'even') { + + if (areaNumber > areaGreatestX) { + + areaGreatestX = areaNumber; + + if (i === 0) { + areaSmallestX = areaGreatestX; + } + } + + if (areaNumber < areaSmallestX) { + areaSmallestX = areaNumber; + } + + arrayAlternate = 'odd'; + } + else { + if (areaNumber > areaGreatestY) { + + areaGreatestY = areaNumber; + + if (i == 1) { + areaSmallestY = areaGreatestY; + } + } + + if (areaNumber < areaSmallestY) { + areaSmallestY = areaNumber; + } + + arrayAlternate = 'even'; + } + } + + geo.origin.size.height = areaGreatestY - areaSmallestY; + geo.origin.size.width = areaGreatestX - areaSmallestX; + + geo.origin.windowOffset.left += areaSmallestX; + geo.origin.windowOffset.top += areaSmallestY; + + break; + } + } + } + + // user callback through an event + var edit = function(r) { + geo.origin.size.height = r.height, + geo.origin.windowOffset.left = r.left, + geo.origin.windowOffset.top = r.top, + geo.origin.size.width = r.width + }; + + self._trigger({ + type: 'geometry', + edit: edit, + geometry: { + height: geo.origin.size.height, + left: geo.origin.windowOffset.left, + top: geo.origin.windowOffset.top, + width: geo.origin.size.width + } + }); + + // calculate the remaining properties with what we got + + geo.origin.windowOffset.right = geo.origin.windowOffset.left + geo.origin.size.width; + geo.origin.windowOffset.bottom = geo.origin.windowOffset.top + geo.origin.size.height; + + geo.origin.offset.left = geo.origin.windowOffset.left + geo.window.scroll.left; + geo.origin.offset.top = geo.origin.windowOffset.top + geo.window.scroll.top; + geo.origin.offset.bottom = geo.origin.offset.top + geo.origin.size.height; + geo.origin.offset.right = geo.origin.offset.left + geo.origin.size.width; + + // the space that is available to display the tooltip relatively to the document + geo.available.document = { + bottom: { + height: geo.document.size.height - geo.origin.offset.bottom, + width: geo.document.size.width + }, + left: { + height: geo.document.size.height, + width: geo.origin.offset.left + }, + right: { + height: geo.document.size.height, + width: geo.document.size.width - geo.origin.offset.right + }, + top: { + height: geo.origin.offset.top, + width: geo.document.size.width + } + }; + + // the space that is available to display the tooltip relatively to the viewport + // (the resulting values may be negative if the origin overflows the viewport) + geo.available.window = { + bottom: { + // the inner max is here to make sure the available height is no bigger + // than the viewport height (when the origin is off screen at the top). + // The outer max just makes sure that the height is not negative (when + // the origin overflows at the bottom). + height: Math.max(geo.window.size.height - Math.max(geo.origin.windowOffset.bottom, 0), 0), + width: geo.window.size.width + }, + left: { + height: geo.window.size.height, + width: Math.max(geo.origin.windowOffset.left, 0) + }, + right: { + height: geo.window.size.height, + width: Math.max(geo.window.size.width - Math.max(geo.origin.windowOffset.right, 0), 0) + }, + top: { + height: Math.max(geo.origin.windowOffset.top, 0), + width: geo.window.size.width + } + }; + + while ($parent[0].tagName.toLowerCase() != 'html') { + + if ($parent.css('position') == 'fixed') { + geo.origin.fixedLineage = true; + break; + } + + $parent = $parent.parent(); + } + + return geo; + }, + + /** + * Some options may need to be formated before being used + * + * @returns {self} + * @private + */ + __optionsFormat: function() { + + if (typeof this.__options.animationDuration == 'number') { + this.__options.animationDuration = [this.__options.animationDuration, this.__options.animationDuration]; + } + + if (typeof this.__options.delay == 'number') { + this.__options.delay = [this.__options.delay, this.__options.delay]; + } + + if (typeof this.__options.delayTouch == 'number') { + this.__options.delayTouch = [this.__options.delayTouch, this.__options.delayTouch]; + } + + if (typeof this.__options.theme == 'string') { + this.__options.theme = [this.__options.theme]; + } + + // determine the future parent + if (this.__options.parent === null) { + this.__options.parent = $(env.window.document.body); + } + else if (typeof this.__options.parent == 'string') { + this.__options.parent = $(this.__options.parent); + } + + if (this.__options.trigger == 'hover') { + + this.__options.triggerOpen = { + mouseenter: true, + touchstart: true + }; + + this.__options.triggerClose = { + mouseleave: true, + originClick: true, + touchleave: true + }; + } + else if (this.__options.trigger == 'click') { + + this.__options.triggerOpen = { + click: true, + tap: true + }; + + this.__options.triggerClose = { + click: true, + tap: true + }; + } + + // for the plugins + this._trigger('options'); + + return this; + }, + + /** + * Schedules or cancels the garbage collector task + * + * @returns {self} + * @private + */ + __prepareGC: function() { + + var self = this; + + // in case the selfDestruction option has been changed by a method call + if (self.__options.selfDestruction) { + + // the GC task + self.__garbageCollector = setInterval(function() { + + var now = new Date().getTime(); + + // forget the old events + self.__touchEvents = $.grep(self.__touchEvents, function(event, i) { + // 1 minute + return now - event.time > 60000; + }); + + // auto-destruct if the origin is gone + if (!bodyContains(self._$origin)) { + + self.close(function(){ + self.destroy(); + }); + } + }, 20000); + } + else { + clearInterval(self.__garbageCollector); + } + + return self; + }, + + /** + * Sets listeners on the origin if the open triggers require them. + * Unlike the listeners set at opening time, these ones + * remain even when the tooltip is closed. It has been made a + * separate method so it can be called when the triggers are + * changed in the options. Closing is handled in _open() + * because of the bindings that may be needed on the tooltip + * itself + * + * @returns {self} + * @private + */ + __prepareOrigin: function() { + + var self = this; + + // in case we're resetting the triggers + self._$origin.off('.'+ self.__namespace +'-triggerOpen'); + + // if the device is touch capable, even if only mouse triggers + // are asked, we need to listen to touch events to know if the mouse + // events are actually emulated (so we can ignore them) + if (env.hasTouchCapability) { + + self._$origin.on( + 'touchstart.'+ self.__namespace +'-triggerOpen ' + + 'touchend.'+ self.__namespace +'-triggerOpen ' + + 'touchcancel.'+ self.__namespace +'-triggerOpen', + function(event){ + self._touchRecordEvent(event); + } + ); + } + + // mouse click and touch tap work the same way + if ( self.__options.triggerOpen.click + || (self.__options.triggerOpen.tap && env.hasTouchCapability) + ) { + + var eventNames = ''; + if (self.__options.triggerOpen.click) { + eventNames += 'click.'+ self.__namespace +'-triggerOpen '; + } + if (self.__options.triggerOpen.tap && env.hasTouchCapability) { + eventNames += 'touchend.'+ self.__namespace +'-triggerOpen'; + } + + self._$origin.on(eventNames, function(event) { + if (self._touchIsMeaningfulEvent(event)) { + self._open(event); + } + }); + } + + // mouseenter and touch start work the same way + if ( self.__options.triggerOpen.mouseenter + || (self.__options.triggerOpen.touchstart && env.hasTouchCapability) + ) { + + var eventNames = ''; + if (self.__options.triggerOpen.mouseenter) { + eventNames += 'mouseenter.'+ self.__namespace +'-triggerOpen '; + } + if (self.__options.triggerOpen.touchstart && env.hasTouchCapability) { + eventNames += 'touchstart.'+ self.__namespace +'-triggerOpen'; + } + + self._$origin.on(eventNames, function(event) { + if ( self._touchIsTouchEvent(event) + || !self._touchIsEmulatedEvent(event) + ) { + self.__pointerIsOverOrigin = true; + self._openShortly(event); + } + }); + } + + // info for the mouseleave/touchleave close triggers when they use a delay + if ( self.__options.triggerClose.mouseleave + || (self.__options.triggerClose.touchleave && env.hasTouchCapability) + ) { + + var eventNames = ''; + if (self.__options.triggerClose.mouseleave) { + eventNames += 'mouseleave.'+ self.__namespace +'-triggerOpen '; + } + if (self.__options.triggerClose.touchleave && env.hasTouchCapability) { + eventNames += 'touchend.'+ self.__namespace +'-triggerOpen touchcancel.'+ self.__namespace +'-triggerOpen'; + } + + self._$origin.on(eventNames, function(event) { + + if (self._touchIsMeaningfulEvent(event)) { + self.__pointerIsOverOrigin = false; + } + }); + } + + return self; + }, + + /** + * Do the things that need to be done only once after the tooltip + * HTML element it has been created. It has been made a separate + * method so it can be called when options are changed. Remember + * that the tooltip may actually exist in the DOM before it is + * opened, and present after it has been closed: it's the display + * plugin that takes care of handling it. + * + * @returns {self} + * @private + */ + __prepareTooltip: function() { + + var self = this, + p = self.__options.interactive ? 'auto' : ''; + + // this will be useful to know quickly if the tooltip is in + // the DOM or not + self._$tooltip + .attr('id', self.__namespace) + .css({ + // pointer events + 'pointer-events': p, + zIndex: self.__options.zIndex + }); + + // themes + // remove the old ones and add the new ones + $.each(self.__previousThemes, function(i, theme) { + self._$tooltip.removeClass(theme); + }); + $.each(self.__options.theme, function(i, theme) { + self._$tooltip.addClass(theme); + }); + + self.__previousThemes = $.merge([], self.__options.theme); + + return self; + }, + + /** + * Handles the scroll on any of the parents of the origin (when the + * tooltip is open) + * + * @param {object} event + * @returns {self} + * @private + */ + __scrollHandler: function(event) { + + var self = this; + + if (self.__options.triggerClose.scroll) { + self._close(event); + } + else { + + // if the origin or tooltip have been removed: do nothing, the tracker will + // take care of it later + if (bodyContains(self._$origin) && bodyContains(self._$tooltip)) { + + var geo = null; + + // if the scroll happened on the window + if (event.target === env.window.document) { + + // if the origin has a fixed lineage, window scroll will have no + // effect on its position nor on the position of the tooltip + if (!self.__Geometry.origin.fixedLineage) { + + // we don't need to do anything unless repositionOnScroll is true + // because the tooltip will already have moved with the window + // (and of course with the origin) + if (self.__options.repositionOnScroll) { + self.reposition(event); + } + } + } + // if the scroll happened on another parent of the tooltip, it means + // that it's in a scrollable area and now needs to have its position + // adjusted or recomputed, depending ont the repositionOnScroll + // option. Also, if the origin is partly hidden due to a parent that + // hides its overflow, we'll just hide (not close) the tooltip. + else { + + geo = self.__geometry(); + + var overflows = false; + + // a fixed position origin is not affected by the overflow hiding + // of a parent + if (self._$origin.css('position') != 'fixed') { + + self.__$originParents.each(function(i, el) { + + var $el = $(el), + overflowX = $el.css('overflow-x'), + overflowY = $el.css('overflow-y'); + + if (overflowX != 'visible' || overflowY != 'visible') { + + var bcr = el.getBoundingClientRect(); + + if (overflowX != 'visible') { + + if ( geo.origin.windowOffset.left < bcr.left + || geo.origin.windowOffset.right > bcr.right + ) { + overflows = true; + return false; + } + } + + if (overflowY != 'visible') { + + if ( geo.origin.windowOffset.top < bcr.top + || geo.origin.windowOffset.bottom > bcr.bottom + ) { + overflows = true; + return false; + } + } + } + + // no need to go further if fixed, for the same reason as above + if ($el.css('position') == 'fixed') { + return false; + } + }); + } + + if (overflows) { + self._$tooltip.css('visibility', 'hidden'); + } + else { + + self._$tooltip.css('visibility', 'visible'); + + // reposition + if (self.__options.repositionOnScroll) { + self.reposition(event); + } + // or just adjust offset + else { + + // we have to use offset and not windowOffset because this way, + // only the scroll distance of the scrollable areas are taken into + // account (the scrolltop value of the main window must be + // ignored since the tooltip already moves with it) + var offsetLeft = geo.origin.offset.left - self.__Geometry.origin.offset.left, + offsetTop = geo.origin.offset.top - self.__Geometry.origin.offset.top; + + // add the offset to the position initially computed by the display plugin + self._$tooltip.css({ + left: self.__lastPosition.coord.left + offsetLeft, + top: self.__lastPosition.coord.top + offsetTop + }); + } + } + } + + self._trigger({ + type: 'scroll', + event: event, + geo: geo + }); + } + } + + return self; + }, + + /** + * Changes the state of the tooltip + * + * @param {string} state + * @returns {self} + * @private + */ + __stateSet: function(state) { + + this.__state = state; + + this._trigger({ + type: 'state', + state: state + }); + + return this; + }, + + /** + * Clear appearance timeouts + * + * @returns {self} + * @private + */ + __timeoutsClear: function() { + + // there is only one possible open timeout: the delayed opening + // when the mouseenter/touchstart open triggers are used + clearTimeout(this.__timeouts.open); + this.__timeouts.open = null; + + // ... but several close timeouts: the delayed closing when the + // mouseleave close trigger is used and the timer option + $.each(this.__timeouts.close, function(i, timeout) { + clearTimeout(timeout); + }); + this.__timeouts.close = []; + + return this; + }, + + /** + * Start the tracker that will make checks at regular intervals + * + * @returns {self} + * @private + */ + __trackerStart: function() { + + var self = this, + $content = self._$tooltip.find('.tooltipster-content'); + + // get the initial content size + if (self.__options.trackTooltip) { + self.__contentBcr = $content[0].getBoundingClientRect(); + } + + self.__tracker = setInterval(function() { + + // if the origin or tooltip elements have been removed. + // Note: we could destroy the instance now if the origin has + // been removed but we'll leave that task to our garbage collector + if (!bodyContains(self._$origin) || !bodyContains(self._$tooltip)) { + self._close(); + } + // if everything is alright + else { + + // compare the former and current positions of the origin to reposition + // the tooltip if need be + if (self.__options.trackOrigin) { + + var g = self.__geometry(), + identical = false; + + // compare size first (a change requires repositioning too) + if (areEqual(g.origin.size, self.__Geometry.origin.size)) { + + // for elements that have a fixed lineage (see __geometry()), we track the + // top and left properties (relative to window) + if (self.__Geometry.origin.fixedLineage) { + if (areEqual(g.origin.windowOffset, self.__Geometry.origin.windowOffset)) { + identical = true; + } + } + // otherwise, track total offset (relative to document) + else { + if (areEqual(g.origin.offset, self.__Geometry.origin.offset)) { + identical = true; + } + } + } + + if (!identical) { + + // close the tooltip when using the mouseleave close trigger + // (see https://github.com/iamceege/tooltipster/pull/253) + if (self.__options.triggerClose.mouseleave) { + self._close(); + } + else { + self.reposition(); + } + } + } + + if (self.__options.trackTooltip) { + + var currentBcr = $content[0].getBoundingClientRect(); + + if ( currentBcr.height !== self.__contentBcr.height + || currentBcr.width !== self.__contentBcr.width + ) { + self.reposition(); + self.__contentBcr = currentBcr; + } + } + } + }, self.__options.trackerInterval); + + return self; + }, + + /** + * Closes the tooltip (after the closing delay) + * + * @param event + * @param callback + * @param force Set to true to override a potential refusal of the user's function + * @returns {self} + * @protected + */ + _close: function(event, callback, force) { + + var self = this, + ok = true; + + self._trigger({ + type: 'close', + event: event, + stop: function() { + ok = false; + } + }); + + // a destroying tooltip (force == true) may not refuse to close + if (ok || force) { + + // save the method custom callback and cancel any open method custom callbacks + if (callback) self.__callbacks.close.push(callback); + self.__callbacks.open = []; + + // clear open/close timeouts + self.__timeoutsClear(); + + var finishCallbacks = function() { + + // trigger any close method custom callbacks and reset them + $.each(self.__callbacks.close, function(i,c) { + c.call(self, self, { + event: event, + origin: self._$origin[0] + }); + }); + + self.__callbacks.close = []; + }; + + if (self.__state != 'closed') { + + var necessary = true, + d = new Date(), + now = d.getTime(), + newClosingTime = now + self.__options.animationDuration[1]; + + // the tooltip may already already be disappearing, but if a new + // call to close() is made after the animationDuration was changed + // to 0 (for example), we ought to actually close it sooner than + // previously scheduled. In that case it should be noted that the + // browser will not adapt the animation duration to the new + // animationDuration that was set after the start of the closing + // animation. + // Note: the same thing could be considered at opening, but is not + // really useful since the tooltip is actually opened immediately + // upon a call to _open(). Since it would not make the opening + // animation finish sooner, its sole impact would be to trigger the + // state event and the open callbacks sooner than the actual end of + // the opening animation, which is not great. + if (self.__state == 'disappearing') { + + if ( newClosingTime > self.__closingTime + // in case closing is actually overdue because the script + // execution was suspended. See #679 + && self.__options.animationDuration[1] > 0 + ) { + necessary = false; + } + } + + if (necessary) { + + self.__closingTime = newClosingTime; + + if (self.__state != 'disappearing') { + self.__stateSet('disappearing'); + } + + var finish = function() { + + // stop the tracker + clearInterval(self.__tracker); + + // a "beforeClose" option has been asked several times but would + // probably useless since the content element is still accessible + // via ::content(), and because people can always use listeners + // inside their content to track what's going on. For the sake of + // simplicity, this has been denied. Bur for the rare people who + // really need the option (for old browsers or for the case where + // detaching the content is actually destructive, for file or + // password inputs for example), this event will do the work. + self._trigger({ + type: 'closing', + event: event + }); + + // unbind listeners which are no longer needed + + self._$tooltip + .off('.'+ self.__namespace +'-triggerClose') + .removeClass('tooltipster-dying'); + + // orientationchange, scroll and resize listeners + $(env.window).off('.'+ self.__namespace +'-triggerClose'); + + // scroll listeners + self.__$originParents.each(function(i, el) { + $(el).off('scroll.'+ self.__namespace +'-triggerClose'); + }); + // clear the array to prevent memory leaks + self.__$originParents = null; + + $(env.window.document.body).off('.'+ self.__namespace +'-triggerClose'); + + self._$origin.off('.'+ self.__namespace +'-triggerClose'); + + self._off('dismissable'); + + // a plugin that would like to remove the tooltip from the + // DOM when closed should bind on this + self.__stateSet('closed'); + + // trigger event + self._trigger({ + type: 'after', + event: event + }); + + // call our constructor custom callback function + if (self.__options.functionAfter) { + self.__options.functionAfter.call(self, self, { + event: event, + origin: self._$origin[0] + }); + } + + // call our method custom callbacks functions + finishCallbacks(); + }; + + if (env.hasTransitions) { + + self._$tooltip.css({ + '-moz-animation-duration': self.__options.animationDuration[1] + 'ms', + '-ms-animation-duration': self.__options.animationDuration[1] + 'ms', + '-o-animation-duration': self.__options.animationDuration[1] + 'ms', + '-webkit-animation-duration': self.__options.animationDuration[1] + 'ms', + 'animation-duration': self.__options.animationDuration[1] + 'ms', + 'transition-duration': self.__options.animationDuration[1] + 'ms' + }); + + self._$tooltip + // clear both potential open and close tasks + .clearQueue() + .removeClass('tooltipster-show') + // for transitions only + .addClass('tooltipster-dying'); + + if (self.__options.animationDuration[1] > 0) { + self._$tooltip.delay(self.__options.animationDuration[1]); + } + + self._$tooltip.queue(finish); + } + else { + + self._$tooltip + .stop() + .fadeOut(self.__options.animationDuration[1], finish); + } + } + } + // if the tooltip is already closed, we still need to trigger + // the method custom callbacks + else { + finishCallbacks(); + } + } + + return self; + }, + + /** + * For internal use by plugins, if needed + * + * @returns {self} + * @protected + */ + _off: function() { + this.__$emitterPrivate.off.apply(this.__$emitterPrivate, Array.prototype.slice.apply(arguments)); + return this; + }, + + /** + * For internal use by plugins, if needed + * + * @returns {self} + * @protected + */ + _on: function() { + this.__$emitterPrivate.on.apply(this.__$emitterPrivate, Array.prototype.slice.apply(arguments)); + return this; + }, + + /** + * For internal use by plugins, if needed + * + * @returns {self} + * @protected + */ + _one: function() { + this.__$emitterPrivate.one.apply(this.__$emitterPrivate, Array.prototype.slice.apply(arguments)); + return this; + }, + + /** + * Opens the tooltip right away. + * + * @param event + * @param callback Will be called when the opening animation is over + * @returns {self} + * @protected + */ + _open: function(event, callback) { + + var self = this; + + // if the destruction process has not begun and if this was not + // triggered by an unwanted emulated click event + if (!self.__destroying) { + + // check that the origin is still in the DOM + if ( bodyContains(self._$origin) + // if the tooltip is enabled + && self.__enabled + ) { + + var ok = true; + + // if the tooltip is not open yet, we need to call functionBefore. + // otherwise we can jst go on + if (self.__state == 'closed') { + + // trigger an event. The event.stop function allows the callback + // to prevent the opening of the tooltip + self._trigger({ + type: 'before', + event: event, + stop: function() { + ok = false; + } + }); + + if (ok && self.__options.functionBefore) { + + // call our custom function before continuing + ok = self.__options.functionBefore.call(self, self, { + event: event, + origin: self._$origin[0] + }); + } + } + + if (ok !== false) { + + // if there is some content + if (self.__Content !== null) { + + // save the method callback and cancel close method callbacks + if (callback) { + self.__callbacks.open.push(callback); + } + self.__callbacks.close = []; + + // get rid of any appearance timeouts + self.__timeoutsClear(); + + var extraTime, + finish = function() { + + if (self.__state != 'stable') { + self.__stateSet('stable'); + } + + // trigger any open method custom callbacks and reset them + $.each(self.__callbacks.open, function(i,c) { + c.call(self, self, { + origin: self._$origin[0], + tooltip: self._$tooltip[0] + }); + }); + + self.__callbacks.open = []; + }; + + // if the tooltip is already open + if (self.__state !== 'closed') { + + // the timer (if any) will start (or restart) right now + extraTime = 0; + + // if it was disappearing, cancel that + if (self.__state === 'disappearing') { + + self.__stateSet('appearing'); + + if (env.hasTransitions) { + + self._$tooltip + .clearQueue() + .removeClass('tooltipster-dying') + .addClass('tooltipster-show'); + + if (self.__options.animationDuration[0] > 0) { + self._$tooltip.delay(self.__options.animationDuration[0]); + } + + self._$tooltip.queue(finish); + } + else { + // in case the tooltip was currently fading out, bring it back + // to life + self._$tooltip + .stop() + .fadeIn(finish); + } + } + // if the tooltip is already open, we still need to trigger the method + // custom callback + else if (self.__state == 'stable') { + finish(); + } + } + // if the tooltip isn't already open, open it + else { + + // a plugin must bind on this and store the tooltip in this._$tooltip + self.__stateSet('appearing'); + + // the timer (if any) will start when the tooltip has fully appeared + // after its transition + extraTime = self.__options.animationDuration[0]; + + // insert the content inside the tooltip + self.__contentInsert(); + + // reposition the tooltip and attach to the DOM + self.reposition(event, true); + + // animate in the tooltip. If the display plugin wants no css + // animations, it may override the animation option with a + // dummy value that will produce no effect + if (env.hasTransitions) { + + // note: there seems to be an issue with start animations which + // are randomly not played on fast devices in both Chrome and FF, + // couldn't find a way to solve it yet. It seems that applying + // the classes before appending to the DOM helps a little, but + // it messes up some CSS transitions. The issue almost never + // happens when delay[0]==0 though + self._$tooltip + .addClass('tooltipster-'+ self.__options.animation) + .addClass('tooltipster-initial') + .css({ + '-moz-animation-duration': self.__options.animationDuration[0] + 'ms', + '-ms-animation-duration': self.__options.animationDuration[0] + 'ms', + '-o-animation-duration': self.__options.animationDuration[0] + 'ms', + '-webkit-animation-duration': self.__options.animationDuration[0] + 'ms', + 'animation-duration': self.__options.animationDuration[0] + 'ms', + 'transition-duration': self.__options.animationDuration[0] + 'ms' + }); + + setTimeout( + function() { + + // a quick hover may have already triggered a mouseleave + if (self.__state != 'closed') { + + self._$tooltip + .addClass('tooltipster-show') + .removeClass('tooltipster-initial'); + + if (self.__options.animationDuration[0] > 0) { + self._$tooltip.delay(self.__options.animationDuration[0]); + } + + self._$tooltip.queue(finish); + } + }, + 0 + ); + } + else { + + // old browsers will have to live with this + self._$tooltip + .css('display', 'none') + .fadeIn(self.__options.animationDuration[0], finish); + } + + // checks if the origin is removed while the tooltip is open + self.__trackerStart(); + + // NOTE: the listeners below have a '-triggerClose' namespace + // because we'll remove them when the tooltip closes (unlike + // the '-triggerOpen' listeners). So some of them are actually + // not about close triggers, rather about positioning. + + $(env.window) + // reposition on resize + .on('resize.'+ self.__namespace +'-triggerClose', function(e) { + + var $ae = $(document.activeElement); + + // reposition only if the resize event was not triggered upon the opening + // of a virtual keyboard due to an input field being focused within the tooltip + // (otherwise the repositioning would lose the focus) + if ( (!$ae.is('input') && !$ae.is('textarea')) + || !$.contains(self._$tooltip[0], $ae[0]) + ) { + self.reposition(e); + } + }) + // same as below for parents + .on('scroll.'+ self.__namespace +'-triggerClose', function(e) { + self.__scrollHandler(e); + }); + + self.__$originParents = self._$origin.parents(); + + // scrolling may require the tooltip to be moved or even + // repositioned in some cases + self.__$originParents.each(function(i, parent) { + + $(parent).on('scroll.'+ self.__namespace +'-triggerClose', function(e) { + self.__scrollHandler(e); + }); + }); + + if ( self.__options.triggerClose.mouseleave + || (self.__options.triggerClose.touchleave && env.hasTouchCapability) + ) { + + // we use an event to allow users/plugins to control when the mouseleave/touchleave + // close triggers will come to action. It allows to have more triggering elements + // than just the origin and the tooltip for example, or to cancel/delay the closing, + // or to make the tooltip interactive even if it wasn't when it was open, etc. + self._on('dismissable', function(event) { + + if (event.dismissable) { + + if (event.delay) { + + timeout = setTimeout(function() { + // event.event may be undefined + self._close(event.event); + }, event.delay); + + self.__timeouts.close.push(timeout); + } + else { + self._close(event); + } + } + else { + clearTimeout(timeout); + } + }); + + // now set the listeners that will trigger 'dismissable' events + var $elements = self._$origin, + eventNamesIn = '', + eventNamesOut = '', + timeout = null; + + // if we have to allow interaction, bind on the tooltip too + if (self.__options.interactive) { + $elements = $elements.add(self._$tooltip); + } + + if (self.__options.triggerClose.mouseleave) { + eventNamesIn += 'mouseenter.'+ self.__namespace +'-triggerClose '; + eventNamesOut += 'mouseleave.'+ self.__namespace +'-triggerClose '; + } + if (self.__options.triggerClose.touchleave && env.hasTouchCapability) { + eventNamesIn += 'touchstart.'+ self.__namespace +'-triggerClose'; + eventNamesOut += 'touchend.'+ self.__namespace +'-triggerClose touchcancel.'+ self.__namespace +'-triggerClose'; + } + + $elements + // close after some time spent outside of the elements + .on(eventNamesOut, function(event) { + + // it's ok if the touch gesture ended up to be a swipe, + // it's still a "touch leave" situation + if ( self._touchIsTouchEvent(event) + || !self._touchIsEmulatedEvent(event) + ) { + + var delay = (event.type == 'mouseleave') ? + self.__options.delay : + self.__options.delayTouch; + + self._trigger({ + delay: delay[1], + dismissable: true, + event: event, + type: 'dismissable' + }); + } + }) + // suspend the mouseleave timeout when the pointer comes back + // over the elements + .on(eventNamesIn, function(event) { + + // it's also ok if the touch event is a swipe gesture + if ( self._touchIsTouchEvent(event) + || !self._touchIsEmulatedEvent(event) + ) { + self._trigger({ + dismissable: false, + event: event, + type: 'dismissable' + }); + } + }); + } + + // close the tooltip when the origin gets a mouse click (common behavior of + // native tooltips) + if (self.__options.triggerClose.originClick) { + + self._$origin.on('click.'+ self.__namespace + '-triggerClose', function(event) { + + // we could actually let a tap trigger this but this feature just + // does not make sense on touch devices + if ( !self._touchIsTouchEvent(event) + && !self._touchIsEmulatedEvent(event) + ) { + self._close(event); + } + }); + } + + // set the same bindings for click and touch on the body to close the tooltip + if ( self.__options.triggerClose.click + || (self.__options.triggerClose.tap && env.hasTouchCapability) + ) { + + // don't set right away since the click/tap event which triggered this method + // (if it was a click/tap) is going to bubble up to the body, we don't want it + // to close the tooltip immediately after it opened + setTimeout(function() { + + if (self.__state != 'closed') { + + var eventNames = '', + $body = $(env.window.document.body); + + if (self.__options.triggerClose.click) { + eventNames += 'click.'+ self.__namespace +'-triggerClose '; + } + if (self.__options.triggerClose.tap && env.hasTouchCapability) { + eventNames += 'touchend.'+ self.__namespace +'-triggerClose'; + } + + $body.on(eventNames, function(event) { + + if (self._touchIsMeaningfulEvent(event)) { + + self._touchRecordEvent(event); + + if (!self.__options.interactive || !$.contains(self._$tooltip[0], event.target)) { + self._close(event); + } + } + }); + + // needed to detect and ignore swiping + if (self.__options.triggerClose.tap && env.hasTouchCapability) { + + $body.on('touchstart.'+ self.__namespace +'-triggerClose', function(event) { + self._touchRecordEvent(event); + }); + } + } + }, 0); + } + + self._trigger('ready'); + + // call our custom callback + if (self.__options.functionReady) { + self.__options.functionReady.call(self, self, { + origin: self._$origin[0], + tooltip: self._$tooltip[0] + }); + } + } + + // if we have a timer set, let the countdown begin + if (self.__options.timer > 0) { + + var timeout = setTimeout(function() { + self._close(); + }, self.__options.timer + extraTime); + + self.__timeouts.close.push(timeout); + } + } + } + } + } + + return self; + }, + + /** + * When using the mouseenter/touchstart open triggers, this function will + * schedule the opening of the tooltip after the delay, if there is one + * + * @param event + * @returns {self} + * @protected + */ + _openShortly: function(event) { + + var self = this, + ok = true; + + if (self.__state != 'stable' && self.__state != 'appearing') { + + // if a timeout is not already running + if (!self.__timeouts.open) { + + self._trigger({ + type: 'start', + event: event, + stop: function() { + ok = false; + } + }); + + if (ok) { + + var delay = (event.type.indexOf('touch') == 0) ? + self.__options.delayTouch : + self.__options.delay; + + if (delay[0]) { + + self.__timeouts.open = setTimeout(function() { + + self.__timeouts.open = null; + + // open only if the pointer (mouse or touch) is still over the origin. + // The check on the "meaningful event" can only be made here, after some + // time has passed (to know if the touch was a swipe or not) + if (self.__pointerIsOverOrigin && self._touchIsMeaningfulEvent(event)) { + + // signal that we go on + self._trigger('startend'); + + self._open(event); + } + else { + // signal that we cancel + self._trigger('startcancel'); + } + }, delay[0]); + } + else { + // signal that we go on + self._trigger('startend'); + + self._open(event); + } + } + } + } + + return self; + }, + + /** + * Meant for plugins to get their options + * + * @param {string} pluginName The name of the plugin that asks for its options + * @param {object} defaultOptions The default options of the plugin + * @returns {object} The options + * @protected + */ + _optionsExtract: function(pluginName, defaultOptions) { + + var self = this, + options = $.extend(true, {}, defaultOptions); + + // if the plugin options were isolated in a property named after the + // plugin, use them (prevents conflicts with other plugins) + var pluginOptions = self.__options[pluginName]; + + // if not, try to get them as regular options + if (!pluginOptions){ + + pluginOptions = {}; + + $.each(defaultOptions, function(optionName, value) { + + var o = self.__options[optionName]; + + if (o !== undefined) { + pluginOptions[optionName] = o; + } + }); + } + + // let's merge the default options and the ones that were provided. We'd want + // to do a deep copy but not let jQuery merge arrays, so we'll do a shallow + // extend on two levels, that will be enough if options are not more than 1 + // level deep + $.each(options, function(optionName, value) { + + if (pluginOptions[optionName] !== undefined) { + + if (( typeof value == 'object' + && !(value instanceof Array) + && value != null + ) + && + ( typeof pluginOptions[optionName] == 'object' + && !(pluginOptions[optionName] instanceof Array) + && pluginOptions[optionName] != null + ) + ) { + $.extend(options[optionName], pluginOptions[optionName]); + } + else { + options[optionName] = pluginOptions[optionName]; + } + } + }); + + return options; + }, + + /** + * Used at instantiation of the plugin, or afterwards by plugins that activate themselves + * on existing instances + * + * @param {object} pluginName + * @returns {self} + * @protected + */ + _plug: function(pluginName) { + + var plugin = $.tooltipster._plugin(pluginName); + + if (plugin) { + + // if there is a constructor for instances + if (plugin.instance) { + + // proxy non-private methods on the instance to allow new instance methods + $.tooltipster.__bridge(plugin.instance, this, plugin.name); + } + } + else { + throw new Error('The "'+ pluginName +'" plugin is not defined'); + } + + return this; + }, + + /** + * This will return true if the event is a mouse event which was + * emulated by the browser after a touch event. This allows us to + * really dissociate mouse and touch triggers. + * + * There is a margin of error if a real mouse event is fired right + * after (within the delay shown below) a touch event on the same + * element, but hopefully it should not happen often. + * + * @returns {boolean} + * @protected + */ + _touchIsEmulatedEvent: function(event) { + + var isEmulated = false, + now = new Date().getTime(); + + for (var i = this.__touchEvents.length - 1; i >= 0; i--) { + + var e = this.__touchEvents[i]; + + // delay, in milliseconds. It's supposed to be 300ms in + // most browsers (350ms on iOS) to allow a double tap but + // can be less (check out FastClick for more info) + if (now - e.time < 500) { + + if (e.target === event.target) { + isEmulated = true; + } + } + else { + break; + } + } + + return isEmulated; + }, + + /** + * Returns false if the event was an emulated mouse event or + * a touch event involved in a swipe gesture. + * + * @param {object} event + * @returns {boolean} + * @protected + */ + _touchIsMeaningfulEvent: function(event) { + return ( + (this._touchIsTouchEvent(event) && !this._touchSwiped(event.target)) + || (!this._touchIsTouchEvent(event) && !this._touchIsEmulatedEvent(event)) + ); + }, + + /** + * Checks if an event is a touch event + * + * @param {object} event + * @returns {boolean} + * @protected + */ + _touchIsTouchEvent: function(event){ + return event.type.indexOf('touch') == 0; + }, + + /** + * Store touch events for a while to detect swiping and emulated mouse events + * + * @param {object} event + * @returns {self} + * @protected + */ + _touchRecordEvent: function(event) { + + if (this._touchIsTouchEvent(event)) { + event.time = new Date().getTime(); + this.__touchEvents.push(event); + } + + return this; + }, + + /** + * Returns true if a swipe happened after the last touchstart event fired on + * event.target. + * + * We need to differentiate a swipe from a tap before we let the event open + * or close the tooltip. A swipe is when a touchmove (scroll) event happens + * on the body between the touchstart and the touchend events of an element. + * + * @param {object} target The HTML element that may have triggered the swipe + * @returns {boolean} + * @protected + */ + _touchSwiped: function(target) { + + var swiped = false; + + for (var i = this.__touchEvents.length - 1; i >= 0; i--) { + + var e = this.__touchEvents[i]; + + if (e.type == 'touchmove') { + swiped = true; + break; + } + else if ( + e.type == 'touchstart' + && target === e.target + ) { + break; + } + } + + return swiped; + }, + + /** + * Triggers an event on the instance emitters + * + * @returns {self} + * @protected + */ + _trigger: function() { + + var args = Array.prototype.slice.apply(arguments); + + if (typeof args[0] == 'string') { + args[0] = { type: args[0] }; + } + + // add properties to the event + args[0].instance = this; + args[0].origin = this._$origin ? this._$origin[0] : null; + args[0].tooltip = this._$tooltip ? this._$tooltip[0] : null; + + // note: the order of emitters matters + this.__$emitterPrivate.trigger.apply(this.__$emitterPrivate, args); + $.tooltipster._trigger.apply($.tooltipster, args); + this.__$emitterPublic.trigger.apply(this.__$emitterPublic, args); + + return this; + }, + + /** + * Deactivate a plugin on this instance + * + * @returns {self} + * @protected + */ + _unplug: function(pluginName) { + + var self = this; + + // if the plugin has been activated on this instance + if (self[pluginName]) { + + var plugin = $.tooltipster._plugin(pluginName); + + // if there is a constructor for instances + if (plugin.instance) { + + // unbridge + $.each(plugin.instance, function(methodName, fn) { + + // if the method exists (privates methods do not) and comes indeed from + // this plugin (may be missing or come from a conflicting plugin). + if ( self[methodName] + && self[methodName].bridged === self[pluginName] + ) { + delete self[methodName]; + } + }); + } + + // destroy the plugin + if (self[pluginName].__destroy) { + self[pluginName].__destroy(); + } + + // remove the reference to the plugin instance + delete self[pluginName]; + } + + return self; + }, + + /** + * @see self::_close + * @returns {self} + * @public + */ + close: function(callback) { + + if (!this.__destroyed) { + this._close(null, callback); + } + else { + this.__destroyError(); + } + + return this; + }, + + /** + * Sets or gets the content of the tooltip + * + * @returns {mixed|self} + * @public + */ + content: function(content) { + + var self = this; + + // getter method + if (content === undefined) { + return self.__Content; + } + // setter method + else { + + if (!self.__destroyed) { + + // change the content + self.__contentSet(content); + + if (self.__Content !== null) { + + // update the tooltip if it is open + if (self.__state !== 'closed') { + + // reset the content in the tooltip + self.__contentInsert(); + + // reposition and resize the tooltip + self.reposition(); + + // if we want to play a little animation showing the content changed + if (self.__options.updateAnimation) { + + if (env.hasTransitions) { + + // keep the reference in the local scope + var animation = self.__options.updateAnimation; + + self._$tooltip.addClass('tooltipster-update-'+ animation); + + // remove the class after a while. The actual duration of the + // update animation may be shorter, it's set in the CSS rules + setTimeout(function() { + + if (self.__state != 'closed') { + + self._$tooltip.removeClass('tooltipster-update-'+ animation); + } + }, 1000); + } + else { + self._$tooltip.fadeTo(200, 0.5, function() { + if (self.__state != 'closed') { + self._$tooltip.fadeTo(200, 1); + } + }); + } + } + } + } + else { + self._close(); + } + } + else { + self.__destroyError(); + } + + return self; + } + }, + + /** + * Destroys the tooltip + * + * @returns {self} + * @public + */ + destroy: function() { + + var self = this; + + if (!self.__destroyed) { + + if(self.__state != 'closed'){ + + // no closing delay + self.option('animationDuration', 0) + // force closing + ._close(null, null, true); + } + else { + // there might be an open timeout still running + self.__timeoutsClear(); + } + + // send event + self._trigger('destroy'); + + self.__destroyed = true; + + self._$origin + .removeData(self.__namespace) + // remove the open trigger listeners + .off('.'+ self.__namespace +'-triggerOpen'); + + // remove the touch listener + $(env.window.document.body).off('.' + self.__namespace +'-triggerOpen'); + + var ns = self._$origin.data('tooltipster-ns'); + + // if the origin has been removed from DOM, its data may + // well have been destroyed in the process and there would + // be nothing to clean up or restore + if (ns) { + + // if there are no more tooltips on this element + if (ns.length === 1) { + + // optional restoration of a title attribute + var title = null; + if (self.__options.restoration == 'previous') { + title = self._$origin.data('tooltipster-initialTitle'); + } + else if (self.__options.restoration == 'current') { + + // old school technique to stringify when outerHTML is not supported + title = (typeof self.__Content == 'string') ? + self.__Content : + $('
').append(self.__Content).html(); + } + + if (title) { + self._$origin.attr('title', title); + } + + // final cleaning + + self._$origin.removeClass('tooltipstered'); + + self._$origin + .removeData('tooltipster-ns') + .removeData('tooltipster-initialTitle'); + } + else { + // remove the instance namespace from the list of namespaces of + // tooltips present on the element + ns = $.grep(ns, function(el, i) { + return el !== self.__namespace; + }); + self._$origin.data('tooltipster-ns', ns); + } + } + + // last event + self._trigger('destroyed'); + + // unbind private and public event listeners + self._off(); + self.off(); + + // remove external references, just in case + self.__Content = null; + self.__$emitterPrivate = null; + self.__$emitterPublic = null; + self.__options.parent = null; + self._$origin = null; + self._$tooltip = null; + + // make sure the object is no longer referenced in there to prevent + // memory leaks + $.tooltipster.__instancesLatestArr = $.grep($.tooltipster.__instancesLatestArr, function(el, i) { + return self !== el; + }); + + clearInterval(self.__garbageCollector); + } + else { + self.__destroyError(); + } + + // we return the scope rather than true so that the call to + // .tooltipster('destroy') actually returns the matched elements + // and applies to all of them + return self; + }, + + /** + * Disables the tooltip + * + * @returns {self} + * @public + */ + disable: function() { + + if (!this.__destroyed) { + + // close first, in case the tooltip would not disappear on + // its own (no close trigger) + this._close(); + this.__enabled = false; + + return this; + } + else { + this.__destroyError(); + } + + return this; + }, + + /** + * Returns the HTML element of the origin + * + * @returns {self} + * @public + */ + elementOrigin: function() { + + if (!this.__destroyed) { + return this._$origin[0]; + } + else { + this.__destroyError(); + } + }, + + /** + * Returns the HTML element of the tooltip + * + * @returns {self} + * @public + */ + elementTooltip: function() { + return this._$tooltip ? this._$tooltip[0] : null; + }, + + /** + * Enables the tooltip + * + * @returns {self} + * @public + */ + enable: function() { + this.__enabled = true; + return this; + }, + + /** + * Alias, deprecated in 4.0.0 + * + * @param {function} callback + * @returns {self} + * @public + */ + hide: function(callback) { + return this.close(callback); + }, + + /** + * Returns the instance + * + * @returns {self} + * @public + */ + instance: function() { + return this; + }, + + /** + * For public use only, not to be used by plugins (use ::_off() instead) + * + * @returns {self} + * @public + */ + off: function() { + + if (!this.__destroyed) { + this.__$emitterPublic.off.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); + } + + return this; + }, + + /** + * For public use only, not to be used by plugins (use ::_on() instead) + * + * @returns {self} + * @public + */ + on: function() { + + if (!this.__destroyed) { + this.__$emitterPublic.on.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); + } + else { + this.__destroyError(); + } + + return this; + }, + + /** + * For public use only, not to be used by plugins + * + * @returns {self} + * @public + */ + one: function() { + + if (!this.__destroyed) { + this.__$emitterPublic.one.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); + } + else { + this.__destroyError(); + } + + return this; + }, + + /** + * @see self::_open + * @returns {self} + * @public + */ + open: function(callback) { + + if (!this.__destroyed) { + this._open(null, callback); + } + else { + this.__destroyError(); + } + + return this; + }, + + /** + * Get or set options. For internal use and advanced users only. + * + * @param {string} o Option name + * @param {mixed} val optional A new value for the option + * @return {mixed|self} If val is omitted, the value of the option + * is returned, otherwise the instance itself is returned + * @public + */ + option: function(o, val) { + + // getter + if (val === undefined) { + return this.__options[o]; + } + // setter + else { + + if (!this.__destroyed) { + + // change value + this.__options[o] = val; + + // format + this.__optionsFormat(); + + // re-prepare the triggers if needed + if ($.inArray(o, ['trigger', 'triggerClose', 'triggerOpen']) >= 0) { + this.__prepareOrigin(); + } + + if (o === 'selfDestruction') { + this.__prepareGC(); + } + } + else { + this.__destroyError(); + } + + return this; + } + }, + + /** + * This method is in charge of setting the position and size properties of the tooltip. + * All the hard work is delegated to the display plugin. + * Note: The tooltip may be detached from the DOM at the moment the method is called + * but must be attached by the end of the method call. + * + * @param {object} event For internal use only. Defined if an event such as + * window resizing triggered the repositioning + * @param {boolean} tooltipIsDetached For internal use only. Set this to true if you + * know that the tooltip not being in the DOM is not an issue (typically when the + * tooltip element has just been created but has not been added to the DOM yet). + * @returns {self} + * @public + */ + reposition: function(event, tooltipIsDetached) { + + var self = this; + + if (!self.__destroyed) { + + // if the tooltip is still open and the origin is still in the DOM + if (self.__state != 'closed' && bodyContains(self._$origin)) { + + // if the tooltip has not been removed from DOM manually (or if it + // has been detached on purpose) + if (tooltipIsDetached || bodyContains(self._$tooltip)) { + + if (!tooltipIsDetached) { + // detach in case the tooltip overflows the window and adds + // scrollbars to it, so __geometry can be accurate + self._$tooltip.detach(); + } + + // refresh the geometry object before passing it as a helper + self.__Geometry = self.__geometry(); + + // let a plugin fo the rest + self._trigger({ + type: 'reposition', + event: event, + helper: { + geo: self.__Geometry + } + }); + } + } + } + else { + self.__destroyError(); + } + + return self; + }, + + /** + * Alias, deprecated in 4.0.0 + * + * @param callback + * @returns {self} + * @public + */ + show: function(callback) { + return this.open(callback); + }, + + /** + * Returns some properties about the instance + * + * @returns {object} + * @public + */ + status: function() { + + return { + destroyed: this.__destroyed, + enabled: this.__enabled, + open: this.__state !== 'closed', + state: this.__state + }; + }, + + /** + * For public use only, not to be used by plugins + * + * @returns {self} + * @public + */ + triggerHandler: function() { + + if (!this.__destroyed) { + this.__$emitterPublic.triggerHandler.apply(this.__$emitterPublic, Array.prototype.slice.apply(arguments)); + } + else { + this.__destroyError(); + } + + return this; + } +}; + +$.fn.tooltipster = function() { + + // for using in closures + var args = Array.prototype.slice.apply(arguments), + // common mistake: an HTML element can't be in several tooltips at the same time + contentCloningWarning = 'You are using a single HTML element as content for several tooltips. You probably want to set the contentCloning option to TRUE.'; + + // this happens with $(sel).tooltipster(...) when $(sel) does not match anything + if (this.length === 0) { + + // still chainable + return this; + } + // this happens when calling $(sel).tooltipster('methodName or options') + // where $(sel) matches one or more elements + else { + + // method calls + if (typeof args[0] === 'string') { + + var v = '#*$~&'; + + this.each(function() { + + // retrieve the namepaces of the tooltip(s) that exist on that element. + // We will interact with the first tooltip only. + var ns = $(this).data('tooltipster-ns'), + // self represents the instance of the first tooltipster plugin + // associated to the current HTML object of the loop + self = ns ? $(this).data(ns[0]) : null; + + // if the current element holds a tooltipster instance + if (self) { + + if (typeof self[args[0]] === 'function') { + + if ( this.length > 1 + && args[0] == 'content' + && ( args[1] instanceof $ + || (typeof args[1] == 'object' && args[1] != null && args[1].tagName) + ) + && !self.__options.contentCloning + && self.__options.debug + ) { + console.log(contentCloningWarning); + } + + // note : args[1] and args[2] may not be defined + var resp = self[args[0]](args[1], args[2]); + } + else { + throw new Error('Unknown method "'+ args[0] +'"'); + } + + // if the function returned anything other than the instance + // itself (which implies chaining, except for the `instance` method) + if (resp !== self || args[0] === 'instance') { + + v = resp; + + // return false to stop .each iteration on the first element + // matched by the selector + return false; + } + } + else { + throw new Error('You called Tooltipster\'s "'+ args[0] +'" method on an uninitialized element'); + } + }); + + return (v !== '#*$~&') ? v : this; + } + // first argument is undefined or an object: the tooltip is initializing + else { + + // reset the array of last initialized objects + $.tooltipster.__instancesLatestArr = []; + + // is there a defined value for the multiple option in the options object ? + var multipleIsSet = args[0] && args[0].multiple !== undefined, + // if the multiple option is set to true, or if it's not defined but + // set to true in the defaults + multiple = (multipleIsSet && args[0].multiple) || (!multipleIsSet && defaults.multiple), + // same for content + contentIsSet = args[0] && args[0].content !== undefined, + content = (contentIsSet && args[0].content) || (!contentIsSet && defaults.content), + // same for contentCloning + contentCloningIsSet = args[0] && args[0].contentCloning !== undefined, + contentCloning = + (contentCloningIsSet && args[0].contentCloning) + || (!contentCloningIsSet && defaults.contentCloning), + // same for debug + debugIsSet = args[0] && args[0].debug !== undefined, + debug = (debugIsSet && args[0].debug) || (!debugIsSet && defaults.debug); + + if ( this.length > 1 + && ( content instanceof $ + || (typeof content == 'object' && content != null && content.tagName) + ) + && !contentCloning + && debug + ) { + console.log(contentCloningWarning); + } + + // create a tooltipster instance for each element if it doesn't + // already have one or if the multiple option is set, and attach the + // object to it + this.each(function() { + + var go = false, + $this = $(this), + ns = $this.data('tooltipster-ns'), + obj = null; + + if (!ns) { + go = true; + } + else if (multiple) { + go = true; + } + else if (debug) { + console.log('Tooltipster: one or more tooltips are already attached to the element below. Ignoring.'); + console.log(this); + } + + if (go) { + obj = new $.Tooltipster(this, args[0]); + + // save the reference of the new instance + if (!ns) ns = []; + ns.push(obj.__namespace); + $this.data('tooltipster-ns', ns); + + // save the instance itself + $this.data(obj.__namespace, obj); + + // call our constructor custom function. + // we do this here and not in ::init() because we wanted + // the object to be saved in $this.data before triggering + // it + if (obj.__options.functionInit) { + obj.__options.functionInit.call(obj, obj, { + origin: this + }); + } + + // and now the event, for the plugins and core emitter + obj._trigger('init'); + } + + $.tooltipster.__instancesLatestArr.push(obj); + }); + + return this; + } + } +}; + +// Utilities + +/** + * A class to check if a tooltip can fit in given dimensions + * + * @param {object} $tooltip The jQuery wrapped tooltip element, or a clone of it + */ +function Ruler($tooltip) { + + // list of instance variables + + this.$container; + this.constraints = null; + this.__$tooltip; + + this.__init($tooltip); +} + +Ruler.prototype = { + + /** + * Move the tooltip into an invisible div that does not allow overflow to make + * size tests. Note: the tooltip may or may not be attached to the DOM at the + * moment this method is called, it does not matter. + * + * @param {object} $tooltip The object to test. May be just a clone of the + * actual tooltip. + * @private + */ + __init: function($tooltip) { + + this.__$tooltip = $tooltip; + + this.__$tooltip + .css({ + // for some reason we have to specify top and left 0 + left: 0, + // any overflow will be ignored while measuring + overflow: 'hidden', + // positions at (0,0) without the div using 100% of the available width + position: 'absolute', + top: 0 + }) + // overflow must be auto during the test. We re-set this in case + // it were modified by the user + .find('.tooltipster-content') + .css('overflow', 'auto'); + + this.$container = $('
') + .append(this.__$tooltip) + .appendTo(env.window.document.body); + }, + + /** + * Force the browser to redraw (re-render) the tooltip immediately. This is required + * when you changed some CSS properties and need to make something with it + * immediately, without waiting for the browser to redraw at the end of instructions. + * + * @see http://stackoverflow.com/questions/3485365/how-can-i-force-webkit-to-redraw-repaint-to-propagate-style-changes + * @private + */ + __forceRedraw: function() { + + // note: this would work but for Webkit only + //this.__$tooltip.close(); + //this.__$tooltip[0].offsetHeight; + //this.__$tooltip.open(); + + // works in FF too + var $p = this.__$tooltip.parent(); + this.__$tooltip.detach(); + this.__$tooltip.appendTo($p); + }, + + /** + * Set maximum dimensions for the tooltip. A call to ::measure afterwards + * will tell us if the content overflows or if it's ok + * + * @param {int} width + * @param {int} height + * @return {Ruler} + * @public + */ + constrain: function(width, height) { + + this.constraints = { + width: width, + height: height + }; + + this.__$tooltip.css({ + // we disable display:flex, otherwise the content would overflow without + // creating horizontal scrolling (which we need to detect). + display: 'block', + // reset any previous height + height: '', + // we'll check if horizontal scrolling occurs + overflow: 'auto', + // we'll set the width and see what height is generated and if there + // is horizontal overflow + width: width + }); + + return this; + }, + + /** + * Reset the tooltip content overflow and remove the test container + * + * @returns {Ruler} + * @public + */ + destroy: function() { + + // in case the element was not a clone + this.__$tooltip + .detach() + .find('.tooltipster-content') + .css({ + // reset to CSS value + display: '', + overflow: '' + }); + + this.$container.remove(); + }, + + /** + * Removes any constraints + * + * @returns {Ruler} + * @public + */ + free: function() { + + this.constraints = null; + + // reset to natural size + this.__$tooltip.css({ + display: '', + height: '', + overflow: 'visible', + width: '' + }); + + return this; + }, + + /** + * Returns the size of the tooltip. When constraints are applied, also returns + * whether the tooltip fits in the provided dimensions. + * The idea is to see if the new height is small enough and if the content does + * not overflow horizontally. + * + * @param {int} width + * @param {int} height + * @returns {object} An object with a bool `fits` property and a `size` property + * @public + */ + measure: function() { + + this.__forceRedraw(); + + var tooltipBcr = this.__$tooltip[0].getBoundingClientRect(), + result = { size: { + // bcr.width/height are not defined in IE8- but in this + // case, bcr.right/bottom will have the same value + // except in iOS 8+ where tooltipBcr.bottom/right are wrong + // after scrolling for reasons yet to be determined. + // tooltipBcr.top/left might not be 0, see issue #514 + height: tooltipBcr.height || (tooltipBcr.bottom - tooltipBcr.top), + width: tooltipBcr.width || (tooltipBcr.right - tooltipBcr.left) + }}; + + if (this.constraints) { + + // note: we used to use offsetWidth instead of boundingRectClient but + // it returned rounded values, causing issues with sub-pixel layouts. + + // note2: noticed that the bcrWidth of text content of a div was once + // greater than the bcrWidth of its container by 1px, causing the final + // tooltip box to be too small for its content. However, evaluating + // their widths one against the other (below) surprisingly returned + // equality. Happened only once in Chrome 48, was not able to reproduce + // => just having fun with float position values... + + var $content = this.__$tooltip.find('.tooltipster-content'), + height = this.__$tooltip.outerHeight(), + contentBcr = $content[0].getBoundingClientRect(), + fits = { + height: height <= this.constraints.height, + width: ( + // this condition accounts for min-width property that + // may apply + tooltipBcr.width <= this.constraints.width + // the -1 is here because scrollWidth actually returns + // a rounded value, and may be greater than bcr.width if + // it was rounded up. This may cause an issue for contents + // which actually really overflow by 1px or so, but that + // should be rare. Not sure how to solve this efficiently. + // See http://blogs.msdn.com/b/ie/archive/2012/02/17/sub-pixel-rendering-and-the-css-object-model.aspx + && contentBcr.width >= $content[0].scrollWidth - 1 + ) + }; + + result.fits = fits.height && fits.width; + } + + // old versions of IE get the width wrong for some reason and it causes + // the text to be broken to a new line, so we round it up. If the width + // is the width of the screen though, we can assume it is accurate. + if ( env.IE + && env.IE <= 11 + && result.size.width !== env.window.document.documentElement.clientWidth + ) { + result.size.width = Math.ceil(result.size.width) + 1; + } + + return result; + } +}; + +// quick & dirty compare function, not bijective nor multidimensional +function areEqual(a,b) { + var same = true; + $.each(a, function(i, _) { + if (b[i] === undefined || a[i] !== b[i]) { + same = false; + return false; + } + }); + return same; +} + +/** + * A fast function to check if an element is still in the DOM. It + * tries to use an id as ids are indexed by the browser, or falls + * back to jQuery's `contains` method. May fail if two elements + * have the same id, but so be it + * + * @param {object} $obj A jQuery-wrapped HTML element + * @return {boolean} + */ +function bodyContains($obj) { + var id = $obj.attr('id'), + el = id ? env.window.document.getElementById(id) : null; + // must also check that the element with the id is the one we want + return el ? el === $obj[0] : $.contains(env.window.document.body, $obj[0]); +} + +// detect IE versions for dirty fixes +var uA = navigator.userAgent.toLowerCase(); +if (uA.indexOf('msie') != -1) env.IE = parseInt(uA.split('msie')[1]); +else if (uA.toLowerCase().indexOf('trident') !== -1 && uA.indexOf(' rv:11') !== -1) env.IE = 11; +else if (uA.toLowerCase().indexOf('edge/') != -1) env.IE = parseInt(uA.toLowerCase().split('edge/')[1]); + +// detecting support for CSS transitions +function transitionSupport() { + + // env.window is not defined yet when this is called + if (!win) return false; + + var b = win.document.body || win.document.documentElement, + s = b.style, + p = 'transition', + v = ['Moz', 'Webkit', 'Khtml', 'O', 'ms']; + + if (typeof s[p] == 'string') { return true; } + + p = p.charAt(0).toUpperCase() + p.substr(1); + for (var i=0; i' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '' + ); + + // hide arrow if asked + if (!this.__options.arrow) { + $html + .find('.tooltipster-box') + .css('margin', 0) + .end() + .find('.tooltipster-arrow') + .hide(); + } + + // apply min/max width if asked + if (this.__options.minWidth) { + $html.css('min-width', this.__options.minWidth + 'px'); + } + if (this.__options.maxWidth) { + $html.css('max-width', this.__options.maxWidth + 'px'); + } + + this.__instance._$tooltip = $html; + + // tell the instance that the tooltip element has been created + this.__instance._trigger('created'); + }, + + /** + * Used when the plugin is to be unplugged + * + * @private + */ + __destroy: function() { + this.__instance._off('.'+ self.__namespace); + }, + + /** + * (Re)compute this.__options from the options declared to the instance + * + * @private + */ + __optionsFormat: function() { + + var self = this; + + // get the options + self.__options = self.__instance._optionsExtract(pluginName, self.__defaults()); + + // for backward compatibility, deprecated in v4.0.0 + if (self.__options.position) { + self.__options.side = self.__options.position; + } + + // options formatting + + // format distance as a four-cell array if it ain't one yet and then make + // it an object with top/bottom/left/right properties + if (typeof self.__options.distance != 'object') { + self.__options.distance = [self.__options.distance]; + } + if (self.__options.distance.length < 4) { + + if (self.__options.distance[1] === undefined) self.__options.distance[1] = self.__options.distance[0]; + if (self.__options.distance[2] === undefined) self.__options.distance[2] = self.__options.distance[0]; + if (self.__options.distance[3] === undefined) self.__options.distance[3] = self.__options.distance[1]; + + self.__options.distance = { + top: self.__options.distance[0], + right: self.__options.distance[1], + bottom: self.__options.distance[2], + left: self.__options.distance[3] + }; + } + + // let's transform: + // 'top' into ['top', 'bottom', 'right', 'left'] + // 'right' into ['right', 'left', 'top', 'bottom'] + // 'bottom' into ['bottom', 'top', 'right', 'left'] + // 'left' into ['left', 'right', 'top', 'bottom'] + if (typeof self.__options.side == 'string') { + + var opposites = { + 'top': 'bottom', + 'right': 'left', + 'bottom': 'top', + 'left': 'right' + }; + + self.__options.side = [self.__options.side, opposites[self.__options.side]]; + + if (self.__options.side[0] == 'left' || self.__options.side[0] == 'right') { + self.__options.side.push('top', 'bottom'); + } + else { + self.__options.side.push('right', 'left'); + } + } + + // misc + // disable the arrow in IE6 unless the arrow option was explicitly set to true + if ( $.tooltipster._env.IE === 6 + && self.__options.arrow !== true + ) { + self.__options.arrow = false; + } + }, + + /** + * This method must compute and set the positioning properties of the + * tooltip (left, top, width, height, etc.). It must also make sure the + * tooltip is eventually appended to its parent (since the element may be + * detached from the DOM at the moment the method is called). + * + * We'll evaluate positioning scenarios to find which side can contain the + * tooltip in the best way. We'll consider things relatively to the window + * (unless the user asks not to), then to the document (if need be, or if the + * user explicitly requires the tests to run on the document). For each + * scenario, measures are taken, allowing us to know how well the tooltip + * is going to fit. After that, a sorting function will let us know what + * the best scenario is (we also allow the user to choose his favorite + * scenario by using an event). + * + * @param {object} helper An object that contains variables that plugin + * creators may find useful (see below) + * @param {object} helper.geo An object with many layout properties + * about objects of interest (window, document, origin). This should help + * plugin users compute the optimal position of the tooltip + * @private + */ + __reposition: function(event, helper) { + + var self = this, + finalResult, + // to know where to put the tooltip, we need to know on which point + // of the x or y axis we should center it. That coordinate is the target + targets = self.__targetFind(helper), + testResults = []; + + // make sure the tooltip is detached while we make tests on a clone + self.__instance._$tooltip.detach(); + + // we could actually provide the original element to the Ruler and + // not a clone, but it just feels right to keep it out of the + // machinery. + var $clone = self.__instance._$tooltip.clone(), + // start position tests session + ruler = $.tooltipster._getRuler($clone), + satisfied = false, + animation = self.__instance.option('animation'); + + // an animation class could contain properties that distort the size + if (animation) { + $clone.removeClass('tooltipster-'+ animation); + } + + // start evaluating scenarios + $.each(['window', 'document'], function(i, container) { + + var takeTest = null; + + // let the user decide to keep on testing or not + self.__instance._trigger({ + container: container, + helper: helper, + satisfied: satisfied, + takeTest: function(bool) { + takeTest = bool; + }, + results: testResults, + type: 'positionTest' + }); + + if ( takeTest == true + || ( takeTest != false + && satisfied == false + // skip the window scenarios if asked. If they are reintegrated by + // the callback of the positionTest event, they will have to be + // excluded using the callback of positionTested + && (container != 'window' || self.__options.viewportAware) + ) + ) { + + // for each allowed side + for (var i=0; i < self.__options.side.length; i++) { + + var distance = { + horizontal: 0, + vertical: 0 + }, + side = self.__options.side[i]; + + if (side == 'top' || side == 'bottom') { + distance.vertical = self.__options.distance[side]; + } + else { + distance.horizontal = self.__options.distance[side]; + } + + // this may have an effect on the size of the tooltip if there are css + // rules for the arrow or something else + self.__sideChange($clone, side); + + $.each(['natural', 'constrained'], function(i, mode) { + + takeTest = null; + + // emit an event on the instance + self.__instance._trigger({ + container: container, + event: event, + helper: helper, + mode: mode, + results: testResults, + satisfied: satisfied, + side: side, + takeTest: function(bool) { + takeTest = bool; + }, + type: 'positionTest' + }); + + if ( takeTest == true + || ( takeTest != false + && satisfied == false + ) + ) { + + var testResult = { + container: container, + // we let the distance as an object here, it can make things a little easier + // during the user's calculations at positionTest/positionTested + distance: distance, + // whether the tooltip can fit in the size of the viewport (does not mean + // that we'll be able to make it initially entirely visible, see 'whole') + fits: null, + mode: mode, + outerSize: null, + side: side, + size: null, + target: targets[side], + // check if the origin has enough surface on screen for the tooltip to + // aim at it without overflowing the viewport (this is due to the thickness + // of the arrow represented by the minIntersection length). + // If not, the tooltip will have to be partly or entirely off screen in + // order to stay docked to the origin. This value will stay null when the + // container is the document, as it is not relevant + whole: null + }; + + // get the size of the tooltip with or without size constraints + var rulerConfigured = (mode == 'natural') ? + ruler.free() : + ruler.constrain( + helper.geo.available[container][side].width - distance.horizontal, + helper.geo.available[container][side].height - distance.vertical + ), + rulerResults = rulerConfigured.measure(); + + testResult.size = rulerResults.size; + testResult.outerSize = { + height: rulerResults.size.height + distance.vertical, + width: rulerResults.size.width + distance.horizontal + }; + + if (mode == 'natural') { + + if( helper.geo.available[container][side].width >= testResult.outerSize.width + && helper.geo.available[container][side].height >= testResult.outerSize.height + ) { + testResult.fits = true; + } + else { + testResult.fits = false; + } + } + else { + testResult.fits = rulerResults.fits; + } + + if (container == 'window') { + + if (!testResult.fits) { + testResult.whole = false; + } + else { + if (side == 'top' || side == 'bottom') { + + testResult.whole = ( + helper.geo.origin.windowOffset.right >= self.__options.minIntersection + && helper.geo.window.size.width - helper.geo.origin.windowOffset.left >= self.__options.minIntersection + ); + } + else { + testResult.whole = ( + helper.geo.origin.windowOffset.bottom >= self.__options.minIntersection + && helper.geo.window.size.height - helper.geo.origin.windowOffset.top >= self.__options.minIntersection + ); + } + } + } + + testResults.push(testResult); + + // we don't need to compute more positions if we have one fully on screen + if (testResult.whole) { + satisfied = true; + } + else { + // don't run the constrained test unless the natural width was greater + // than the available width, otherwise it's pointless as we know it + // wouldn't fit either + if ( testResult.mode == 'natural' + && ( testResult.fits + || testResult.size.width <= helper.geo.available[container][side].width + ) + ) { + return false; + } + } + } + }); + } + } + }); + + // the user may eliminate the unwanted scenarios from testResults, but he's + // not supposed to alter them at this point. functionPosition and the + // position event serve that purpose. + self.__instance._trigger({ + edit: function(r) { + testResults = r; + }, + event: event, + helper: helper, + results: testResults, + type: 'positionTested' + }); + + /** + * Sort the scenarios to find the favorite one. + * + * The favorite scenario is when we can fully display the tooltip on screen, + * even if it means that the middle of the tooltip is no longer centered on + * the middle of the origin (when the origin is near the edge of the screen + * or even partly off screen). We want the tooltip on the preferred side, + * even if it means that we have to use a constrained size rather than a + * natural one (as long as it fits). When the origin is off screen at the top + * the tooltip will be positioned at the bottom (if allowed), if the origin + * is off screen on the right, it will be positioned on the left, etc. + * If there are no scenarios where the tooltip can fit on screen, or if the + * user does not want the tooltip to fit on screen (viewportAware == false), + * we fall back to the scenarios relative to the document. + * + * When the tooltip is bigger than the viewport in either dimension, we stop + * looking at the window scenarios and consider the document scenarios only, + * with the same logic to find on which side it would fit best. + * + * If the tooltip cannot fit the document on any side, we force it at the + * bottom, so at least the user can scroll to see it. + */ + testResults.sort(function(a, b) { + + // best if it's whole (the tooltip fits and adapts to the viewport) + if (a.whole && !b.whole) { + return -1; + } + else if (!a.whole && b.whole) { + return 1; + } + else if (a.whole && b.whole) { + + var ai = self.__options.side.indexOf(a.side), + bi = self.__options.side.indexOf(b.side); + + // use the user's sides fallback array + if (ai < bi) { + return -1; + } + else if (ai > bi) { + return 1; + } + else { + // will be used if the user forced the tests to continue + return a.mode == 'natural' ? -1 : 1; + } + } + else { + + // better if it fits + if (a.fits && !b.fits) { + return -1; + } + else if (!a.fits && b.fits) { + return 1; + } + else if (a.fits && b.fits) { + + var ai = self.__options.side.indexOf(a.side), + bi = self.__options.side.indexOf(b.side); + + // use the user's sides fallback array + if (ai < bi) { + return -1; + } + else if (ai > bi) { + return 1; + } + else { + // will be used if the user forced the tests to continue + return a.mode == 'natural' ? -1 : 1; + } + } + else { + + // if everything failed, this will give a preference to the case where + // the tooltip overflows the document at the bottom + if ( a.container == 'document' + && a.side == 'bottom' + && a.mode == 'natural' + ) { + return -1; + } + else { + return 1; + } + } + } + }); + + finalResult = testResults[0]; + + + // now let's find the coordinates of the tooltip relatively to the window + finalResult.coord = {}; + + switch (finalResult.side) { + + case 'left': + case 'right': + finalResult.coord.top = Math.floor(finalResult.target - finalResult.size.height / 2); + break; + + case 'bottom': + case 'top': + finalResult.coord.left = Math.floor(finalResult.target - finalResult.size.width / 2); + break; + } + + switch (finalResult.side) { + + case 'left': + finalResult.coord.left = helper.geo.origin.windowOffset.left - finalResult.outerSize.width; + break; + + case 'right': + finalResult.coord.left = helper.geo.origin.windowOffset.right + finalResult.distance.horizontal; + break; + + case 'top': + finalResult.coord.top = helper.geo.origin.windowOffset.top - finalResult.outerSize.height; + break; + + case 'bottom': + finalResult.coord.top = helper.geo.origin.windowOffset.bottom + finalResult.distance.vertical; + break; + } + + // if the tooltip can potentially be contained within the viewport dimensions + // and that we are asked to make it fit on screen + if (finalResult.container == 'window') { + + // if the tooltip overflows the viewport, we'll move it accordingly (then it will + // not be centered on the middle of the origin anymore). We only move horizontally + // for top and bottom tooltips and vice versa. + if (finalResult.side == 'top' || finalResult.side == 'bottom') { + + // if there is an overflow on the left + if (finalResult.coord.left < 0) { + + // prevent the overflow unless the origin itself gets off screen (minus the + // margin needed to keep the arrow pointing at the target) + if (helper.geo.origin.windowOffset.right - this.__options.minIntersection >= 0) { + finalResult.coord.left = 0; + } + else { + finalResult.coord.left = helper.geo.origin.windowOffset.right - this.__options.minIntersection - 1; + } + } + // or an overflow on the right + else if (finalResult.coord.left > helper.geo.window.size.width - finalResult.size.width) { + + if (helper.geo.origin.windowOffset.left + this.__options.minIntersection <= helper.geo.window.size.width) { + finalResult.coord.left = helper.geo.window.size.width - finalResult.size.width; + } + else { + finalResult.coord.left = helper.geo.origin.windowOffset.left + this.__options.minIntersection + 1 - finalResult.size.width; + } + } + } + else { + + // overflow at the top + if (finalResult.coord.top < 0) { + + if (helper.geo.origin.windowOffset.bottom - this.__options.minIntersection >= 0) { + finalResult.coord.top = 0; + } + else { + finalResult.coord.top = helper.geo.origin.windowOffset.bottom - this.__options.minIntersection - 1; + } + } + // or at the bottom + else if (finalResult.coord.top > helper.geo.window.size.height - finalResult.size.height) { + + if (helper.geo.origin.windowOffset.top + this.__options.minIntersection <= helper.geo.window.size.height) { + finalResult.coord.top = helper.geo.window.size.height - finalResult.size.height; + } + else { + finalResult.coord.top = helper.geo.origin.windowOffset.top + this.__options.minIntersection + 1 - finalResult.size.height; + } + } + } + } + else { + + // there might be overflow here too but it's easier to handle. If there has + // to be an overflow, we'll make sure it's on the right side of the screen + // (because the browser will extend the document size if there is an overflow + // on the right, but not on the left). The sort function above has already + // made sure that a bottom document overflow is preferred to a top overflow, + // so we don't have to care about it. + + // if there is an overflow on the right + if (finalResult.coord.left > helper.geo.window.size.width - finalResult.size.width) { + + // this may actually create on overflow on the left but we'll fix it in a sec + finalResult.coord.left = helper.geo.window.size.width - finalResult.size.width; + } + + // if there is an overflow on the left + if (finalResult.coord.left < 0) { + + // don't care if it overflows the right after that, we made our best + finalResult.coord.left = 0; + } + } + + + // submit the positioning proposal to the user function which may choose to change + // the side, size and/or the coordinates + + // first, set the rules that corresponds to the proposed side: it may change + // the size of the tooltip, and the custom functionPosition may want to detect the + // size of something before making a decision. So let's make things easier for the + // implementor + self.__sideChange($clone, finalResult.side); + + // add some variables to the helper + helper.tooltipClone = $clone[0]; + helper.tooltipParent = self.__instance.option('parent').parent[0]; + // move informative values to the helper + helper.mode = finalResult.mode; + helper.whole = finalResult.whole; + // add some variables to the helper for the functionPosition callback (these + // will also be added to the event fired by self.__instance._trigger but that's + // ok, we're just being consistent) + helper.origin = self.__instance._$origin[0]; + helper.tooltip = self.__instance._$tooltip[0]; + + // leave only the actionable values in there for functionPosition + delete finalResult.container; + delete finalResult.fits; + delete finalResult.mode; + delete finalResult.outerSize; + delete finalResult.whole; + + // keep only the distance on the relevant side, for clarity + finalResult.distance = finalResult.distance.horizontal || finalResult.distance.vertical; + + // beginners may not be comfortable with the concept of editing the object + // passed by reference, so we provide an edit function and pass a clone + var finalResultClone = $.extend(true, {}, finalResult); + + // emit an event on the instance + self.__instance._trigger({ + edit: function(result) { + finalResult = result; + }, + event: event, + helper: helper, + position: finalResultClone, + type: 'position' + }); + + if (self.__options.functionPosition) { + + var result = self.__options.functionPosition.call(self, self.__instance, helper, finalResultClone); + + if (result) finalResult = result; + } + + // end the positioning tests session (the user might have had a + // use for it during the position event, now it's over) + ruler.destroy(); + + // compute the position of the target relatively to the tooltip root + // element so we can place the arrow and make the needed adjustments + var arrowCoord, + maxVal; + + if (finalResult.side == 'top' || finalResult.side == 'bottom') { + + arrowCoord = { + prop: 'left', + val: finalResult.target - finalResult.coord.left + }; + maxVal = finalResult.size.width - this.__options.minIntersection; + } + else { + + arrowCoord = { + prop: 'top', + val: finalResult.target - finalResult.coord.top + }; + maxVal = finalResult.size.height - this.__options.minIntersection; + } + + // cannot lie beyond the boundaries of the tooltip, minus the + // arrow margin + if (arrowCoord.val < this.__options.minIntersection) { + arrowCoord.val = this.__options.minIntersection; + } + else if (arrowCoord.val > maxVal) { + arrowCoord.val = maxVal; + } + + var originParentOffset; + + // let's convert the window-relative coordinates into coordinates relative to the + // future positioned parent that the tooltip will be appended to + if (helper.geo.origin.fixedLineage) { + + // same as windowOffset when the position is fixed + originParentOffset = helper.geo.origin.windowOffset; + } + else { + + // this assumes that the parent of the tooltip is located at + // (0, 0) in the document, typically like when the parent is + // . + // If we ever allow other types of parent, .tooltipster-ruler + // will have to be appended to the parent to inherit css style + // values that affect the display of the text and such. + originParentOffset = { + left: helper.geo.origin.windowOffset.left + helper.geo.window.scroll.left, + top: helper.geo.origin.windowOffset.top + helper.geo.window.scroll.top + }; + } + + finalResult.coord = { + left: originParentOffset.left + (finalResult.coord.left - helper.geo.origin.windowOffset.left), + top: originParentOffset.top + (finalResult.coord.top - helper.geo.origin.windowOffset.top) + }; + + // set position values on the original tooltip element + + self.__sideChange(self.__instance._$tooltip, finalResult.side); + + if (helper.geo.origin.fixedLineage) { + self.__instance._$tooltip + .css('position', 'fixed'); + } + else { + // CSS default + self.__instance._$tooltip + .css('position', ''); + } + + self.__instance._$tooltip + .css({ + left: finalResult.coord.left, + top: finalResult.coord.top, + // we need to set a size even if the tooltip is in its natural size + // because when the tooltip is positioned beyond the width of the body + // (which is by default the width of the window; it will happen when + // you scroll the window horizontally to get to the origin), its text + // content will otherwise break lines at each word to keep up with the + // body overflow strategy. + height: finalResult.size.height, + width: finalResult.size.width + }) + .find('.tooltipster-arrow') + .css({ + 'left': '', + 'top': '' + }) + .css(arrowCoord.prop, arrowCoord.val); + + // append the tooltip HTML element to its parent + self.__instance._$tooltip.appendTo(self.__instance.option('parent')); + + self.__instance._trigger({ + type: 'repositioned', + event: event, + position: finalResult + }); + }, + + /** + * Make whatever modifications are needed when the side is changed. This has + * been made an independant method for easy inheritance in custom plugins based + * on this default plugin. + * + * @param {object} $obj + * @param {string} side + * @private + */ + __sideChange: function($obj, side) { + + $obj + .removeClass('tooltipster-bottom') + .removeClass('tooltipster-left') + .removeClass('tooltipster-right') + .removeClass('tooltipster-top') + .addClass('tooltipster-'+ side); + }, + + /** + * Returns the target that the tooltip should aim at for a given side. + * The calculated value is a distance from the edge of the window + * (left edge for top/bottom sides, top edge for left/right side). The + * tooltip will be centered on that position and the arrow will be + * positioned there (as much as possible). + * + * @param {object} helper + * @return {integer} + * @private + */ + __targetFind: function(helper) { + + var target = {}, + rects = this.__instance._$origin[0].getClientRects(); + + // these lines fix a Chrome bug (issue #491) + if (rects.length > 1) { + var opacity = this.__instance._$origin.css('opacity'); + if(opacity == 1) { + this.__instance._$origin.css('opacity', 0.99); + rects = this.__instance._$origin[0].getClientRects(); + this.__instance._$origin.css('opacity', 1); + } + } + + // by default, the target will be the middle of the origin + if (rects.length < 2) { + + target.top = Math.floor(helper.geo.origin.windowOffset.left + (helper.geo.origin.size.width / 2)); + target.bottom = target.top; + + target.left = Math.floor(helper.geo.origin.windowOffset.top + (helper.geo.origin.size.height / 2)); + target.right = target.left; + } + // if multiple client rects exist, the element may be text split + // up into multiple lines and the middle of the origin may not be + // best option anymore. We need to choose the best target client rect + else { + + // top: the first + var targetRect = rects[0]; + target.top = Math.floor(targetRect.left + (targetRect.right - targetRect.left) / 2); + + // right: the middle line, rounded down in case there is an even + // number of lines (looks more centered => check out the + // demo with 4 split lines) + if (rects.length > 2) { + targetRect = rects[Math.ceil(rects.length / 2) - 1]; + } + else { + targetRect = rects[0]; + } + target.right = Math.floor(targetRect.top + (targetRect.bottom - targetRect.top) / 2); + + // bottom: the last + targetRect = rects[rects.length - 1]; + target.bottom = Math.floor(targetRect.left + (targetRect.right - targetRect.left) / 2); + + // left: the middle line, rounded up + if (rects.length > 2) { + targetRect = rects[Math.ceil((rects.length + 1) / 2) - 1]; + } + else { + targetRect = rects[rects.length - 1]; + } + + target.left = Math.floor(targetRect.top + (targetRect.bottom - targetRect.top) / 2); + } + + return target; + } + } +}); + +/* a build task will add "return $;" here */ +return $; + +})); diff --git a/static/js/tooltipster.bundle.min.js b/static/js/tooltipster.bundle.min.js old mode 100644 new mode 100755 diff --git a/static/js/vex.combined.min.js b/static/js/vex.combined.min.js old mode 100644 new mode 100755 diff --git a/static/libraries.min.css b/static/libraries.min.css new file mode 100755 index 00000000..b5044ded --- /dev/null +++ b/static/libraries.min.css @@ -0,0 +1 @@ +.idealforms-field-width{width:619.3333333333334px}form.idealforms{zoom:1;line-height:1.0}form.idealforms:before,form.idealforms:after{content:"";display:table}form.idealforms:after{clear:both}form.idealforms *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}form.idealforms .field{position:relative;float:left;clear:both;margin:.1em 0}form.idealforms label.main,form.idealforms .field>input,form.idealforms select,form.idealforms button,form.idealforms textarea,form.idealforms .field .group{float:left}form.idealforms label.main{width:120px;margin-top:.15em}form.idealforms input,form.idealforms textarea,form.idealforms select,form.idealforms .field .group{margin:0;padding:0;border:0;outline:0;width:290px;padding:.15em;border:1px solid #999;outline:0;background:#fff;-webkit-border-radius:3.01px;border-radius:3.01px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.15)}form.idealforms input{-webkit-transition:background .3s ease-in-out;-moz-transition:background .3s ease-in-out;-o-transition:background .3s ease-in-out;-ms-transition:background .3s ease-in-out;transition:background .3s ease-in-out}form.idealforms textarea{width:435px}form.idealforms select,form.idealforms button{color:#444;background:#eee;background:-webkit-linear-gradient(#fff,#ddd);background:-moz-linear-gradient(#fff,#ddd);background:-o-linear-gradient(#fff,#ddd);background:-ms-linear-gradient(#fff,#ddd);background:linear-gradient(#fff,#ddd);border:1px solid #aaa;border-bottom-color:#919191;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.15);box-shadow:0 1px 2px rgba(0,0,0,0.15);-webkit-border-radius:3.01px;border-radius:3.01px;padding:.15em .5em;cursor:pointer}form.idealforms select:hover,form.idealforms button:hover{background:-webkit-linear-gradient(#fff,#eaeaea);background:-moz-linear-gradient(#fff,#eaeaea);background:-o-linear-gradient(#fff,#eaeaea);background:-ms-linear-gradient(#fff,#eaeaea);background:linear-gradient(#fff,#eaeaea)}form.idealforms select:active,form.idealforms button:active,form.idealforms select:active:focus,form.idealforms button:active:focus{color:#444;background:#eee;background:-webkit-linear-gradient(#fff,#ddd);background:-moz-linear-gradient(#fff,#ddd);background:-o-linear-gradient(#fff,#ddd);background:-ms-linear-gradient(#fff,#ddd);background:linear-gradient(#fff,#ddd);border:1px solid #aaa;border-bottom-color:#919191;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.15);box-shadow:0 1px 2px rgba(0,0,0,0.15);-webkit-border-radius:3.01px;border-radius:3.01px;background:#ddd}form.idealforms select:focus,form.idealforms button:focus{outline:0;border-color:#3f9dcc;-webkit-box-shadow:0 0 1px #3f9dcc;box-shadow:0 0 1px #3f9dcc}form.idealforms button{width:auto}form.idealforms select{padding:.15em}form.idealforms select:focus{border:1px solid #444}form.idealforms input[type="file"]{padding:0}form.idealforms .field .group{position:relative;padding:1.25em;-webkit-box-shadow:none;box-shadow:none}form.idealforms .field .group label{float:left;clear:both;padding:.15em 0}form.idealforms .field .group input,form.idealforms .field .group label{margin:0}form.idealforms .field .group input{width:auto;margin-right:.5em;-webkit-box-shadow:none;box-shadow:none}form.idealforms .field .group label{margin-right:1em}form.idealforms .field .group label:last-of-type{margin:0}form.idealforms .field.valid input,form.idealforms .field.valid select,form.idealforms .field.valid textarea,form.idealforms .field.valid .group{color:#18445a;background:#edf7fc;border-color:#3f9dcc}form.idealforms .field.invalid input,form.idealforms .field.invalid select,form.idealforms .field.invalid textarea,form.idealforms .field.invalid .group{color:#430e08;background:#ffeded;border-color:#cc2a18}form.idealforms .field.valid .group,form.idealforms .field.invalid .group,form.idealforms .field.valid textarea,form.idealforms .field.invalid textarea,form.idealforms .field.valid select,form.idealforms .field.invalid select{color:inherit;background:0}form.idealforms .field.valid select,form.idealforms .field.invalid select{background:-webkit-linear-gradient(#fff,#ddd);background:-moz-linear-gradient(#fff,#ddd);background:-o-linear-gradient(#fff,#ddd);background:-ms-linear-gradient(#fff,#ddd);background:linear-gradient(#fff,#ddd)}form.idealforms .field .icon{position:absolute;width:16px;height:16px;top:50%;left:100%;margin-top:-8px;margin-left:8px;background:url("../images/sprites.png") no-repeat;cursor:pointer}form.idealforms .field.invalid .icon{background-position:-20px -317px;width:16px;height:16px}form.idealforms .field.valid .icon{background-position:-66px -318px;width:16px;height:16px;cursor:default}form.idealforms .field.invalid .group input,form.idealforms .field.valid .group input{border:0;outline:0;-webkit-box-shadow:none;box-shadow:none}form.idealforms .error{display:none;position:absolute;z-index:1;left:100%;top:50%;padding:1em .5em;width:193.33333333333334px;margin-left:40px;background:#faa;background:-webkit-linear-gradient(#faa,#fcc);background:-moz-linear-gradient(#faa,#fcc);background:-o-linear-gradient(#faa,#fcc);background:-ms-linear-gradient(#faa,#fcc);background:linear-gradient(#faa,#fcc);color:#333;font-size:70%;font-weight:bold;line-height:1;border:1px solid #faa;-webkit-border-radius:0 3.01px 3.01px 3.01px;border-radius:0 3.01px 3.01px 3.01px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.15);box-shadow:0 1px 1px rgba(0,0,0,0.15)}form.idealforms .error:after{content:"";position:absolute;z-index:-1;top:-1px;left:-.7em;border-width:.7em;border-style:solid;border-color:transparent;border-top-color:#faa}form.idealforms .tooltip{display:none;position:absolute;z-index:1;left:100%;top:50%;padding:1em .5em;width:193.33333333333334px;margin-left:40px;background:#aaa;background:-webkit-linear-gradient(#aaa,#ccc);background:-moz-linear-gradient(#aaa,#ccc);background:-o-linear-gradient(#aaa,#ccc);background:-ms-linear-gradient(#aaa,#ccc);background:linear-gradient(#aaa,#ccc);color:#333;font-size:70%;font-weight:bold;line-height:1;border:1px solid #aaa;-webkit-border-radius:0 3.01px 3.01px 3.01px;border-radius:0 3.01px 3.01px 3.01px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.15);box-shadow:0 1px 1px rgba(0,0,0,0.15)}form.idealforms .tooltip:after{content:"";position:absolute;z-index:-1;top:-1px;left:-.7em;border-width:.7em;border-style:solid;border-color:transparent;border-top-color:#aaa}form.idealforms .idealforms-field-checkbox .icon,form.idealforms .idealforms-field-radio .icon,form.idealforms .idealforms-field-textarea .icon{top:8px;margin-top:0}form.idealforms .idealforms-field-checkbox .error,form.idealforms .idealforms-field-radio .error,form.idealforms .idealforms-field-textarea .error{top:1.25em}.idealsteps-container *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.idealsteps-step{display:none;zoom:1}.idealsteps-step:before,.idealsteps-step:after{content:"";display:table}.idealsteps-step:after{clear:both}form.idealforms .ideal-file-wrap{float:left}form.idealforms .ideal-file-filename{float:left;width:204px;height:100%;-webkit-border-radius:0;border-radius:0;-webkit-border-top-left-radius:3.01px;border-top-left-radius:3.01px;-webkit-border-bottom-left-radius:3.01px;border-bottom-left-radius:3.01px}form.idealforms .ideal-file-upload{color:#444;background:#eee;background:-webkit-linear-gradient(#fff,#ddd);background:-moz-linear-gradient(#fff,#ddd);background:-o-linear-gradient(#fff,#ddd);background:-ms-linear-gradient(#fff,#ddd);background:linear-gradient(#fff,#ddd);border:1px solid #aaa;border-bottom-color:#919191;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.15);box-shadow:0 1px 2px rgba(0,0,0,0.15);-webkit-border-radius:3.01px;border-radius:3.01px;padding:.15em .5em;cursor:pointer;overflow:visible;position:relative;float:right;left:-1px;width:87px;padding-left:0;padding-right:0;text-align:center;-webkit-border-radius:0;border-radius:0;-webkit-border-top-right-radius:3.01px;border-top-right-radius:3.01px;-webkit-border-bottom-right-radius:3.01px;border-bottom-right-radius:3.01px}form.idealforms .ideal-file-upload:hover{background:-webkit-linear-gradient(#fff,#eaeaea);background:-moz-linear-gradient(#fff,#eaeaea);background:-o-linear-gradient(#fff,#eaeaea);background:-ms-linear-gradient(#fff,#eaeaea);background:linear-gradient(#fff,#eaeaea)}form.idealforms .ideal-file-upload:active,form.idealforms .ideal-file-upload:active:focus{color:#444;background:#eee;background:-webkit-linear-gradient(#fff,#ddd);background:-moz-linear-gradient(#fff,#ddd);background:-o-linear-gradient(#fff,#ddd);background:-ms-linear-gradient(#fff,#ddd);background:linear-gradient(#fff,#ddd);border:1px solid #aaa;border-bottom-color:#919191;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.15);box-shadow:0 1px 2px rgba(0,0,0,0.15);-webkit-border-radius:3.01px;border-radius:3.01px;background:#ddd}form.idealforms .ideal-file-upload:focus{outline:0;border-color:#3f9dcc;-webkit-box-shadow:0 0 1px #3f9dcc;box-shadow:0 0 1px #3f9dcc}form.idealforms.adaptive .ideal-file-wrap{width:100%}form.idealforms.adaptive .ideal-file-filename{width:70%}form.idealforms.adaptive .ideal-file-upload{width:30%}.lcs_wrap{display:inline-block;direction:ltr;height:28px;vertical-align:middle}.lcs_wrap input{display:none}.lcs_switch{display:inline-block;position:relative;width:73px;height:28px;border-radius:30px;background:#ddd;overflow:hidden;cursor:pointer;-webkit-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.lcs_cursor{display:inline-block;position:absolute;top:3px;width:22px;height:22px;border-radius:100%;background:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,0.2),0 3px 4px 0 rgba(0,0,0,0.1);z-index:10;-webkit-transition:all .2s linear;-ms-transition:all .2s linear;transition:all .2s linear}.lcs_label{font-family:"Trebuchet MS",Helvetica,sans-serif;font-size:12px;letter-spacing:1px;line-height:18px;color:#fff;font-weight:bold;position:absolute;width:33px;top:5px;overflow:hidden;text-align:center;opacity:0;-webkit-transition:all .2s ease-in-out .1s;-ms-transition:all .2s ease-in-out .1s;transition:all .2s ease-in-out .1s}.lcs_label.lcs_label_on{left:-70px;z-index:6}.lcs_label.lcs_label_off{right:-70px;z-index:5}.lcs_switch.lcs_on{background:-webkit-linear-gradient(#439547,#4caf50);background:linear-gradient(#439547,#4caf50);text-shadow:0 0 8px rgba(0,0,0,0.5);border-radius:50px;box-shadow:inset 2px 2px 5px rgba(0,0,0,0.4)}.lcs_switch.lcs_on .lcs_cursor{left:48px}.lcs_switch.lcs_on .lcs_label_on{left:10px;opacity:1}.lcs_switch.lcs_off{background:#b2b2b2;box-shadow:0 0 2px #a4a4a4 inset;border-radius:50px}.lcs_switch.lcs_off .lcs_cursor{left:3px}.lcs_switch.lcs_off .lcs_label_off{right:10px;opacity:1}.lcs_switch.lcs_disabled{opacity:.65;filter:alpha(opacity=65);cursor:default}.selectize-control.plugin-drag_drop.multi>.selectize-input>div.ui-sortable-placeholder{visibility:visible !important;background:#f2f2f2 !important;background:rgba(0,0,0,0.06) !important;border:1px solid #999;outline:0;border-radius:3.01px;box-shadow:inset 0 1px 2px rgba(0,0,0,0.15);-webkit-border-radius:3.01px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.15)}.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after{content:'!';visibility:hidden}.selectize-control.plugin-drag_drop .ui-sortable-helper{-webkit-box-shadow:0 2px 5px rgba(0,0,0,0.2);box-shadow:0 2px 5px rgba(0,0,0,0.2)}.selectize-dropdown-header{position:relative;padding:5px 8px;border-bottom:1px solid #d0d0d0;background:#f8f8f8;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.selectize-dropdown-header-close{position:absolute;right:8px;top:50%;color:#303030;opacity:.4;margin-top:-12px;line-height:20px;font-size:20px !important}.selectize-dropdown-header-close:hover{color:#000}.selectize-dropdown.plugin-optgroup_columns .optgroup{border-right:1px solid #f2f2f2;border-top:0 none;float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child{border-right:0 none}.selectize-dropdown.plugin-optgroup_columns .optgroup:before{display:none}.selectize-dropdown.plugin-optgroup_columns .optgroup-header{border-top:0 none}.selectize-control.plugin-remove_button [data-value]{position:relative;padding-right:24px !important}.selectize-control.plugin-remove_button [data-value] .remove{z-index:1;position:absolute;top:0;right:0;bottom:0;width:17px;text-align:center;font-weight:bold;font-size:12px;color:inherit;text-decoration:none;vertical-align:middle;display:inline-block;padding:2px 0 0 0;border-left:1px solid #439646;-webkit-border-radius:0 2px 2px 0;-moz-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-control.plugin-remove_button [data-value] .remove:hover{background:rgba(0,0,0,0.05)}.selectize-control.plugin-remove_button [data-value].active .remove{border-left-color:#00578d}.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover{background:0}.selectize-control.plugin-remove_button .disabled [data-value] .remove{border-left-color:#aaa}.selectize-control.plugin-remove_button .remove-single{position:absolute;right:28px;top:6px;font-size:23px}.selectize-control{position:relative}.selectize-dropdown,.selectize-input,.selectize-input input{color:#303030;font-family:inherit;font-size:13px;line-height:18px;-webkit-font-smoothing:inherit}.selectize-input,.selectize-control.single .selectize-input.input-active{background:#fff;cursor:text;display:inline-block}.selectize-input{border:1px solid #999;outline:0;border-radius:3.01px;box-shadow:inset 0 1px 2px rgba(0,0,0,0.15);-webkit-border-radius:3.01px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.15);padding:4px 4px;display:inline-block;width:300px;margin-top:2px;height:27px;overflow:hidden;position:relative;z-index:1}.selectize-control.multi .selectize-input.has-items{padding:5px 8px 2px}.selectize-input.full{background-color:#fff}.selectize-input.disabled,.selectize-input.disabled *{cursor:default !important}.selectize-input.focus{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.15)}.selectize-input.dropdown-active{-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.selectize-input>*{vertical-align:baseline;display:-moz-inline-stack;display:inline-block;zoom:1;*display:inline}.selectize-control.multi .selectize-input>div{cursor:pointer;margin:0 3px 3px 0;padding:2px 6px;background:#4caf50;color:#fff;border:1px solid #439646}.selectize-control.multi .selectize-input>div.active{background:#444;color:#fff;border:1px solid #3a823c}.selectize-control.multi .selectize-input.disabled>div,.selectize-control.multi .selectize-input.disabled>div.active{color:#fff;background:#d2d2d2;border:1px solid #aaa}.selectize-input>input{display:inline-block !important;padding:0 !important;min-height:0 !important;max-height:none !important;max-width:100% !important;margin:0 1px !important;text-indent:0 !important;border:0 none !important;background:none !important;line-height:inherit !important;-webkit-user-select:auto !important;-webkit-box-shadow:none !important;box-shadow:none !important}.selectize-input>input::-ms-clear{display:none}.selectize-input>input:focus{outline:none !important}.selectize-input::after{content:' ';display:block;clear:left}.selectize-input.dropdown-active::before{content:' ';display:block;position:absolute;background:#f0f0f0;height:1px;bottom:0;left:0;right:0}.selectize-dropdown{position:absolute;z-index:10;border:1px solid #999;background:#fff;margin:-1px 0 0 0;border-top:0 none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1);-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.selectize-dropdown [data-selectable]{cursor:pointer;overflow:hidden}.selectize-dropdown [data-selectable] .highlight{background:rgba(125,168,208,0.2);-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px}.selectize-dropdown [data-selectable],.selectize-dropdown .optgroup-header{padding:5px 8px}.selectize-dropdown .optgroup:first-child .optgroup-header{border-top:0 none}.selectize-dropdown .optgroup-header{color:#303030;background:#fff;cursor:default}.selectize-dropdown .active{background-color:#ccc;color:#495c68}.selectize-dropdown .active.create{color:#495c68}.selectize-dropdown .create{color:rgba(48,48,48,0.5)}.selectize-dropdown-content{overflow-y:auto;overflow-x:hidden;max-height:200px;-webkit-overflow-scrolling:touch}.selectize-control.single .selectize-input,.selectize-control.single .selectize-input input{cursor:pointer}.selectize-control.single .selectize-input.input-active,.selectize-control.single .selectize-input.input-active input{cursor:text}.selectize-control.single .selectize-input:after{content:' ';display:block;position:absolute;top:50%;right:15px;margin-top:-3px;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:#808080 transparent transparent transparent}.selectize-control.single .selectize-input.dropdown-active:after{margin-top:-4px;border-width:0 5px 5px 5px;border-color:transparent transparent #808080 transparent}.selectize-control.rtl.single .selectize-input:after{left:15px;right:auto}.selectize-control.rtl .selectize-input>input{margin:0 4px 0 -2px !important}.selectize-control .selectize-input.disabled{opacity:.5;background-color:#fafafa}.selectize-control.multi .selectize-input.has-items{padding-left:5px;padding-right:5px}.selectize-control.multi .selectize-input.disabled [data-value]{color:#999;text-shadow:none;background:0;-webkit-box-shadow:none;box-shadow:none}.selectize-control.multi .selectize-input.disabled [data-value],.selectize-control.multi .selectize-input.disabled [data-value] .remove{border-color:#439646}.selectize-control.multi .selectize-input.disabled [data-value] .remove{background:0}.selectize-control.multi .selectize-input [data-value]{text-shadow:0 1px 0 rgba(0,51,83,0.3);-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;background-color:#439646;background-image:-moz-linear-gradient(top,#4caf50,#439646);background-image:-webkit-gradient(linear,0 0,0 100%,from(#4caf50),to(#439646));background-image:-webkit-linear-gradient(top,#4caf50,#439646);background-image:-o-linear-gradient(top,#4caf50,#439646);background-image:linear-gradient(to bottom,#4caf50,#439646);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4caf50',endColorstr='#ff439646',GradientType=0);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03);box-shadow:0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03)}.selectize-control.multi .selectize-input [data-value].active{background-color:#3a823c;background-image:-moz-linear-gradient(top,#439646,#3a823c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#439646),to(#3a823c));background-image:-webkit-linear-gradient(top,#439646,#3a823c);background-image:-o-linear-gradient(top,#439646,#3a823c);background-image:linear-gradient(to bottom,#439646,#3a823c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff439646',endColorstr='#ff3a823c',GradientType=0)}.selectize-control.single .selectize-input{-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05),inset 0 1px 0 rgba(255,255,255,0.8);box-shadow:0 1px 0 rgba(0,0,0,0.05),inset 0 1px 0 rgba(255,255,255,0.8);background-color:#f9f9f9;background-image:-moz-linear-gradient(top,#fefefe,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fefefe),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fefefe,#f2f2f2);background-image:-o-linear-gradient(top,#fefefe,#f2f2f2);background-image:linear-gradient(to bottom,#fefefe,#f2f2f2);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffefefe',endColorstr='#fff2f2f2',GradientType=0)}.selectize-control.single .selectize-input,.selectize-dropdown.single{border-color:#b8b8b8}.selectize-dropdown .optgroup-header{padding-top:7px;font-weight:bold;font-size:.85em}.selectize-dropdown .optgroup{border-top:1px solid #f0f0f0}.selectize-dropdown .optgroup:first-child{border-top:0 none}@-webkit-keyframes vex-fadein{0{opacity:0}100%{opacity:1}}@keyframes vex-fadein{0{opacity:0}100%{opacity:1}}@-webkit-keyframes vex-fadeout{0{opacity:1}100%{opacity:0}}@keyframes vex-fadeout{0{opacity:1}100%{opacity:0}}@-webkit-keyframes vex-rotation{0{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes vex-rotation{0{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.vex,.vex *,.vex *:before,.vex *:after{-moz-box-sizing:border-box;box-sizing:border-box}.vex{position:fixed;overflow:auto;-webkit-overflow-scrolling:touch;z-index:1111;top:0;right:0;bottom:0;left:0}.vex-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.vex-overlay{-webkit-animation:vex-fadein .5s;animation:vex-fadein .5s;position:fixed;z-index:1111;background:rgba(0,0,0,0.4);top:0;right:0;bottom:0;left:0}.vex-overlay.vex-closing{-webkit-animation:vex-fadeout .5s forwards;animation:vex-fadeout .5s forwards}.vex-content{-webkit-animation:vex-fadein .5s;animation:vex-fadein .5s;background:#fff}.vex.vex-closing .vex-content{-webkit-animation:vex-fadeout .5s forwards;animation:vex-fadeout .5s forwards}.vex-close:before{font-family:Arial,sans-serif;content:"\00D7"}.vex-dialog-form{margin:0}.vex-dialog-button{text-rendering:optimizeLegibility;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;-webkit-tap-highlight-color:transparent}.vex-loading-spinner{-webkit-animation:vex-rotation .7s linear infinite;animation:vex-rotation .7s linear infinite;box-shadow:0 0 1em rgba(0,0,0,0.1);position:fixed;z-index:1112;margin:auto;top:0;right:0;bottom:0;left:0;height:2em;width:2em;background:#fff}body.vex-open{overflow:hidden}.ch{display:table !important;clear:both}.ch-month,.ch-week-labels{font-size:0;display:inline-block;white-space:normal;margin:0 4px}.ch-week,.ch-day-labels{display:inline-block;width:11px;box-sizing:content-box}.ch-day-labels{width:inherit}.ch-month-label{text-align:center;font-size:12px;margin-top:10px;margin-bottom:10px}.ch-day-label{text-align:center;font-size:10px;display:block;margin:0;line-height:11px;box-sizing:content-box}.ch-day{display:inline-block;width:9px;height:9px;border:1px solid #f3f6f8;background-color:#f1f1f1;margin:0;box-sizing:content-box}.ch-day.is-outside-month,.ch-lvl.is-outside-month,.ch-day.is-outside-month:hover,.ch-lvl.is-outside-month:hover{background-color:transparent;border-color:transparent}.ch-day.lvl-0,.ch-lvl.lvl-0{background-color:#c8d7e1}.ch-day.is-after-today,.ch-lvl.is-after-today{background-color:#d9e3ea}.ch-day.lvl-1,.ch-lvl.lvl-1{background-color:#a6c96a}.ch-day.lvl-2,.ch-lvl.lvl-2{background-color:#5cb85c}.ch-day.lvl-3,.ch-lvl.lvl-3{background-color:#009e47}.ch-day.lvl-4,.ch-lvl.lvl-4{background-color:#00753a}.ch-day:hover,.ch-lvl:hover{border-color:#89a6ba}.ch-legend{padding-top:10px;text-align:right}.ch-legend-left{text-align:left !important}.ch-legend-center{text-align:center !important}.ch-legend:after{content:".";display:block;height:0;width:0;clear:both;visibility:hidden}.ch-lvls{display:inline-block;margin:0;padding:0;list-style-type:none;padding:2px 9px 0 5px}.ch-lvl{width:10px;height:10px;float:left;margin-left:3px}.blue-1{background-color:#ffc !important}.earth-1{background-color:#f4ec15 !important}.electric-1{background-color:#f9d824 !important}.viridis-1{background-color:#dde218 !important}.picknick-1{background-color:#dd2a91 !important}.green-1{background-color:#d1be5a !important}.teal-1{background-color:#becfb6 !important}.red-1{background-color:#deb7af !important}.blue-2{background-color:#41b6c4 !important}.earth-2{background-color:#86bf76 !important}.electric-2{background-color:#f38647 !important}.viridis-2{background-color:#42bd70 !important}.picknick-2{background-color:#b14dec !important}.green-2{background-color:#5f900b !important}.teal-2{background-color:#7db28f !important}.red-2{background-color:#cf8371 !important}.blue-3{background-color:#0868ac !important}.earth-3{background-color:#117bd7 !important}.electric-3{background-color:#8e0ca3 !important}.viridis-3{background-color:#355c8c !important}.picknick-3{background-color:#2e8ebf !important}.green-3{background-color:#39811b !important}.teal-3{background-color:#107d79 !important}.red-3{background-color:#b63b25 !important}.blue-4{background-color:#253494 !important}.earth-4{background-color:#363299 !important}.electric-4{background-color:#2e0495 !important}.viridis-4{background-color:#471164 !important}.picknick-4{background-color:#139863 !important}.green-4{background-color:#0d562c !important}.teal-4{background-color:#1c475d !important}.red-4{background-color:#90131c !important}.genmon-1{background-color:#090 !important}.genmon-2{background-color:#f90 !important}.genmon-3{background-color:#c00 !important}.genmon-4{background-color:#333 !important}.jqplot-xaxis,.jqplot-xaxis-label{margin-top:10px}.jqplot-x2axis,.jqplot-x2axis-label{margin-bottom:10px}.jqplot-target{position:relative;color:#666;font-family:"Trebuchet MS",Arial,Helvetica,sans-serif;font-size:1em}.jqplot-axis{font-size:.75em}.jqplot-yaxis{margin-right:10px}.jqplot-y2axis,.jqplot-y3axis,.jqplot-y4axis,.jqplot-y5axis,.jqplot-y6axis,.jqplot-y7axis,.jqplot-y8axis,.jqplot-y9axis,.jqplot-yMidAxis{margin-left:10px;margin-right:10px}.jqplot-axis-tick,.jqplot-x2axis-tick,.jqplot-xaxis-tick,.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick,.jqplot-yMidAxis-tick,.jqplot-yaxis-tick{position:absolute;white-space:pre}.jqplot-xaxis-tick{top:0;left:15px;vertical-align:top}.jqplot-x2axis-tick{bottom:0;left:15px;vertical-align:bottom}.jqplot-yaxis-tick{right:0;top:15px;text-align:right}.jqplot-yaxis-tick.jqplot-breakTick{right:-20px;margin-right:0;padding:1px 5px;z-index:2;font-size:1.5em}.jqplot-x2axis-label,.jqplot-xaxis-label,.jqplot-yMidAxis-label,.jqplot-yaxis-label{font-size:11pt;position:absolute}.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick{left:0;top:15px;text-align:left}.jqplot-yMidAxis-tick{text-align:center;white-space:nowrap}.jqplot-yaxis-label{margin-right:10px}.jqplot-y2axis-label,.jqplot-y3axis-label,.jqplot-y4axis-label,.jqplot-y5axis-label,.jqplot-y6axis-label,.jqplot-y7axis-label,.jqplot-y8axis-label,.jqplot-y9axis-label{font-size:11pt;margin-left:10px;position:absolute}.jqplot-meterGauge-tick{font-size:.75em;color:#999}.jqplot-meterGauge-label{font-size:1em;color:#999}table.jqplot-table-legend{margin:12px}table.jqplot-cursor-legend,table.jqplot-table-legend{background-color:rgba(255,255,255,.6);border:1px solid #ccc;position:absolute;font-size:.75em}td.jqplot-table-legend{vertical-align:middle}td.jqplot-seriesToggle:active,td.jqplot-seriesToggle:hover{cursor:pointer}.jqplot-table-legend .jqplot-series-hidden{text-decoration:line-through}div.jqplot-table-legend-swatch-outline{border:1px solid #ccc;padding:1px}div.jqplot-table-legend-swatch{width:0;height:0;border-width:5px 6px;border-style:solid}.jqplot-title{top:0;left:0;padding-bottom:.5em;font-size:1.2em}table.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em}.jqplot-canvasOverlay-tooltip,.jqplot-cursor-tooltip,.jqplot-highlighter-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,.5);padding:1px}.jqplot-point-label{font-size:.75em;z-index:2}td.jqplot-cursor-legend-swatch{vertical-align:middle;text-align:center}div.jqplot-cursor-legend-swatch{width:1.2em;height:.7em}.jqplot-error{text-align:center}.jqplot-error-message{position:relative;top:46%;display:inline-block}div.jqplot-bubble-label{font-size:.8em;padding-left:2px;padding-right:2px;color:rgb(20%,20%,20%)}div.jqplot-bubble-label.jqplot-bubble-label-highlight{background:rgba(90%,90%,90%,.7)}div.jqplot-noData-container{text-align:center;background-color:rgba(96%,96%,96%,.3)}.tooltipster-fall,.tooltipster-grow.tooltipster-show{-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1);-moz-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-ms-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-o-transition-timing-function:cubic-bezier(.175,.885,.32,1.15)}.tooltipster-base{display:flex;pointer-events:none;position:absolute}.tooltipster-box{flex:1 1 auto}.tooltipster-content{box-sizing:border-box;max-height:100%;max-width:100%;overflow:auto;font-size:12px}.tooltipster-ruler{bottom:0;left:0;overflow:hidden;position:fixed;right:0;top:0;visibility:hidden}.tooltipster-fade{opacity:0;-webkit-transition-property:opacity;-moz-transition-property:opacity;-o-transition-property:opacity;-ms-transition-property:opacity;transition-property:opacity}.tooltipster-fade.tooltipster-show{opacity:1}.tooltipster-grow{-webkit-transform:scale(0,0);-moz-transform:scale(0,0);-o-transform:scale(0,0);-ms-transform:scale(0,0);transform:scale(0,0);-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform;-webkit-backface-visibility:hidden}.tooltipster-grow.tooltipster-show{-webkit-transform:scale(1,1);-moz-transform:scale(1,1);-o-transform:scale(1,1);-ms-transform:scale(1,1);transform:scale(1,1);-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);transition-timing-function:cubic-bezier(.175,.885,.32,1.15)}.tooltipster-swing{opacity:0;-webkit-transform:rotateZ(4deg);-moz-transform:rotateZ(4deg);-o-transform:rotateZ(4deg);-ms-transform:rotateZ(4deg);transform:rotateZ(4deg);-webkit-transition-property:-webkit-transform,opacity;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform}.tooltipster-swing.tooltipster-show{opacity:1;-webkit-transform:rotateZ(0);-moz-transform:rotateZ(0);-o-transform:rotateZ(0);-ms-transform:rotateZ(0);transform:rotateZ(0);-webkit-transition-timing-function:cubic-bezier(.23,.635,.495,1);-webkit-transition-timing-function:cubic-bezier(.23,.635,.495,2.4);-moz-transition-timing-function:cubic-bezier(.23,.635,.495,2.4);-ms-transition-timing-function:cubic-bezier(.23,.635,.495,2.4);-o-transition-timing-function:cubic-bezier(.23,.635,.495,2.4);transition-timing-function:cubic-bezier(.23,.635,.495,2.4)}.tooltipster-fall{-webkit-transition-property:top;-moz-transition-property:top;-o-transition-property:top;-ms-transition-property:top;transition-property:top;-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);transition-timing-function:cubic-bezier(.175,.885,.32,1.15)}.tooltipster-fall.tooltipster-initial{top:0 !important}.tooltipster-fall.tooltipster-dying{-webkit-transition-property:all;-moz-transition-property:all;-o-transition-property:all;-ms-transition-property:all;transition-property:all;top:0 !important;opacity:0}.tooltipster-slide{-webkit-transition-property:left;-moz-transition-property:left;-o-transition-property:left;-ms-transition-property:left;transition-property:left;-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-moz-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-ms-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-o-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);transition-timing-function:cubic-bezier(.175,.885,.32,1.15)}.tooltipster-slide.tooltipster-initial{left:-40px !important}.tooltipster-slide.tooltipster-dying{-webkit-transition-property:all;-moz-transition-property:all;-o-transition-property:all;-ms-transition-property:all;transition-property:all;left:0 !important;opacity:0}@keyframes tooltipster-fading{0{opacity:0}100%{opacity:1}}.tooltipster-update-fade{animation:tooltipster-fading .4s}@keyframes tooltipster-rotating{25%{transform:rotate(-2deg)}75%{transform:rotate(2deg)}100%{transform:rotate(0)}}.tooltipster-update-rotate{animation:tooltipster-rotating .6s}@keyframes tooltipster-scaling{50%{transform:scale(1.1)}100%{transform:scale(1)}}.tooltipster-update-scale{animation:tooltipster-scaling .6s}.tooltipster-sidetip .tooltipster-box{background:#565656;border:2px solid #000;border-radius:4px}.tooltipster-sidetip.tooltipster-bottom .tooltipster-box{margin-top:8px}.tooltipster-sidetip.tooltipster-left .tooltipster-box{margin-right:8px}.tooltipster-sidetip.tooltipster-right .tooltipster-box{margin-left:8px}.tooltipster-sidetip.tooltipster-top .tooltipster-box{margin-bottom:8px}.tooltipster-sidetip .tooltipster-content{color:#fff;line-height:18px;padding:6px 14px}.tooltipster-sidetip .tooltipster-arrow{overflow:hidden;position:absolute}.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow{height:10px;margin-left:-10px;top:0;width:20px}.tooltipster-sidetip.tooltipster-left .tooltipster-arrow{height:20px;margin-top:-10px;right:0;top:0;width:10px}.tooltipster-sidetip.tooltipster-right .tooltipster-arrow{height:20px;margin-top:-10px;left:0;top:0;width:10px}.tooltipster-sidetip.tooltipster-top .tooltipster-arrow{bottom:0;height:10px;margin-left:-10px;width:20px}.tooltipster-sidetip .tooltipster-arrow-background,.tooltipster-sidetip .tooltipster-arrow-border{height:0;position:absolute;width:0}.tooltipster-sidetip .tooltipster-arrow-background{border:10px solid transparent}.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-background{border-bottom-color:#565656;left:0;top:3px}.tooltipster-sidetip.tooltipster-left .tooltipster-arrow-background{border-left-color:#565656;left:-3px;top:0}.tooltipster-sidetip.tooltipster-right .tooltipster-arrow-background{border-right-color:#565656;left:3px;top:0}.tooltipster-sidetip.tooltipster-top .tooltipster-arrow-background{border-top-color:#565656;left:0;top:-3px}.tooltipster-sidetip .tooltipster-arrow-border{border:10px solid transparent;left:0;top:0}.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-border{border-bottom-color:#000}.tooltipster-sidetip.tooltipster-left .tooltipster-arrow-border{border-left-color:#000}.tooltipster-sidetip.tooltipster-right .tooltipster-arrow-border{border-right-color:#000}.tooltipster-sidetip.tooltipster-top .tooltipster-arrow-border{border-top-color:#000}.tooltipster-sidetip .tooltipster-arrow-uncropped{position:relative}.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-uncropped{top:-10px}.tooltipster-sidetip.tooltipster-right .tooltipster-arrow-uncropped{left:-10px}@-webkit-keyframes vex-flyin{0{opacity:0;-webkit-transform:translateY(-40px);transform:translateY(-40px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes vex-flyin{0{opacity:0;-webkit-transform:translateY(-40px);transform:translateY(-40px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes vex-flyout{0{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-40px);transform:translateY(-40px)}}@keyframes vex-flyout{0{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(-40px);transform:translateY(-40px)}}@-webkit-keyframes vex-pulse{0{box-shadow:inset 0 0 0 300px transparent}70%{box-shadow:inset 0 0 0 300px rgba(255,255,255,0.25)}100%{box-shadow:inset 0 0 0 300px transparent}}@keyframes vex-pulse{0{box-shadow:inset 0 0 0 300px transparent}70%{box-shadow:inset 0 0 0 300px rgba(255,255,255,0.25)}100%{box-shadow:inset 0 0 0 300px transparent}}.vex.vex-theme-os{padding-top:160px;padding-bottom:160px}.vex.vex-theme-os.vex-closing .vex-content{-webkit-animation:vex-flyout .5s forwards;animation:vex-flyout .5s forwards}.vex.vex-theme-os .vex-content{-webkit-animation:vex-flyin .5s;animation:vex-flyin .5s}.vex.vex-theme-os .vex-content{border-radius:5px;box-shadow:inset 0 1px #a6a6a6,0 0 0 1px rgba(0,0,0,0.08);font-family:"Helvetica Neue",sans-serif;border-top:20px solid #bbb;background:#f0f0f0;color:#444;padding:1em;position:relative;margin:0 auto;max-width:100%;width:450px;font-size:1.1em;line-height:1.5em}.vex.vex-theme-os .vex-content h1,.vex.vex-theme-os .vex-content h2,.vex.vex-theme-os .vex-content h3,.vex.vex-theme-os .vex-content h4,.vex.vex-theme-os .vex-content h5,.vex.vex-theme-os .vex-content h6,.vex.vex-theme-os .vex-content p,.vex.vex-theme-os .vex-content ul,.vex.vex-theme-os .vex-content li{color:inherit}.vex.vex-theme-os .vex-close{border-radius:0 5px 0 0;position:absolute;top:0;right:0;cursor:pointer}.vex.vex-theme-os .vex-close:before{border-radius:3px;position:absolute;content:"\00D7";font-size:26px;font-weight:normal;line-height:31px;height:30px;width:30px;text-align:center;top:3px;right:3px;color:#bbb;background:transparent}.vex.vex-theme-os .vex-close:hover:before,.vex.vex-theme-os .vex-close:active:before{color:#777;background:#e0e0e0}.vex.vex-theme-os .vex-dialog-form .vex-dialog-message{margin-bottom:.5em}.vex.vex-theme-os .vex-dialog-form .vex-dialog-input{margin-bottom:1em}.vex.vex-theme-os .vex-dialog-form .vex-dialog-input select,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input textarea,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="date"],.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime"],.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime-local"],.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="email"],.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="month"],.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="number"],.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="password"],.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="search"],.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="tel"],.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="text"],.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="time"],.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="url"],.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="week"]{border-radius:3px;background:#fff;width:100%;padding:.25em .67em;border:0;font-family:inherit;font-weight:inherit;font-size:inherit;min-height:2.5em;margin:0 0 .25em}.vex.vex-theme-os .vex-dialog-form .vex-dialog-input select:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input textarea:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="date"]:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="email"]:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="month"]:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="number"]:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="password"]:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="search"]:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="tel"]:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="text"]:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="time"]:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="url"]:focus,.vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="week"]:focus{box-shadow:inset 0 0 0 1px #3288e6;outline:0}.vex.vex-theme-os .vex-dialog-form .vex-dialog-buttons{*zoom:1}.vex.vex-theme-os .vex-dialog-form .vex-dialog-buttons:after{content:"";display:table;clear:both}.vex.vex-theme-os .vex-dialog-button{border-radius:3px;border:0;float:right;margin:0 0 0 .5em;font-family:Arial;font-size:16px;line-height:1em;padding:.75em .75em}.vex.vex-theme-os .vex-dialog-button.vex-last{margin-left:0}.vex.vex-theme-os .vex-dialog-button.vex-dialog-button-primary{background:#4caf50;color:#fff}.vex.vex-theme-os .vex-dialog-button.vex-dialog-button-secondary{background:#bbb;color:#444}.vex-loading-spinner.vex-theme-os{box-shadow:0 0 0 1px rgba(0,0,0,0.2),0 0 .5em rgba(0,0,0,0.2);border-radius:100%;background:rgba(255,255,255,0.2);width:0;height:0;border:1.2em solid #bbb;border-top-color:#f0f0f0;border-bottom-color:#f0f0f0} \ No newline at end of file diff --git a/static/libraries.min.js b/static/libraries.min.js new file mode 100755 index 00000000..92788b56 --- /dev/null +++ b/static/libraries.min.js @@ -0,0 +1,1672 @@ +(function(a,b){if(typeof define==="function"&&define.amd){define(["jquery"],function(c){return(b(c))})}else{if(typeof exports==="object"){module.exports=b(require("jquery"))}else{b(jQuery)}}}(this,function(d){var c={animation:"fade",animationDuration:350,content:null,contentAsHTML:false,contentCloning:false,debug:true,delay:300,delayTouch:[300,500],functionInit:null,functionBefore:null,functionReady:null,functionAfter:null,functionFormat:null,IEmin:6,interactive:false,multiple:false,parent:null,plugins:["sideTip"],repositionOnScroll:false,restoration:"none",selfDestruction:true,theme:[],timer:0,trackerInterval:500,trackOrigin:false,trackTooltip:false,trigger:"hover",triggerClose:{click:false,mouseleave:false,originClick:false,scroll:false,tap:false,touchleave:false},triggerOpen:{click:false,mouseenter:false,tap:false,touchstart:false},updateAnimation:"rotate",zIndex:9999999},f=(typeof window!="undefined")?window:null,g={hasTouchCapability:!!(f&&("ontouchstart" in f||(f.DocumentTouch&&f.document instanceof f.DocumentTouch)||f.navigator.maxTouchPoints)),hasTransitions:j(),IE:false,semVer:"4.2.6",window:f},b=function(){this.__$emitterPrivate=d({});this.__$emitterPublic=d({});this.__instancesLatestArr=[];this.__plugins={};this._env=g};b.prototype={__bridge:function(n,p,o){if(!p[o]){var m=function(){};m.prototype=n;var l=new m();if(l.__init){l.__init(p)}d.each(n,function(q,r){if(q.indexOf("__")!=0){if(!p[q]){p[q]=function(){return l[q].apply(l,Array.prototype.slice.apply(arguments))};p[q].bridged=l}else{if(c.debug){console.log("The "+q+" method of the "+o+" plugin conflicts with another plugin or native methods")}}}});p[o]=l}return this},__setWindow:function(l){g.window=l;return this},_getRuler:function(l){return new i(l)},_off:function(){this.__$emitterPrivate.off.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments));return this},_on:function(){this.__$emitterPrivate.on.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments));return this},_one:function(){this.__$emitterPrivate.one.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments));return this},_plugin:function(m){var l=this;if(typeof m=="string"){var n=m,o=null;if(n.indexOf(".")>0){o=l.__plugins[n]}else{d.each(l.__plugins,function(p,q){if(q.name.substring(q.name.length-n.length-1)=="."+n){o=q;return false}})}return o}else{if(m.name.indexOf(".")<0){throw new Error("Plugins must be namespaced")}l.__plugins[m.name]=m;if(m.core){l.__bridge(m.core,l,m.name)}return this}},_trigger:function(){var l=Array.prototype.slice.apply(arguments);if(typeof l[0]=="string"){l[0]={type:l[0]}}this.__$emitterPrivate.trigger.apply(this.__$emitterPrivate,l);this.__$emitterPublic.trigger.apply(this.__$emitterPublic,l);return this},instances:function(l){var n=[],m=l||".tooltipstered";d(m).each(function(){var p=d(this),o=p.data("tooltipster-ns");if(o){d.each(o,function(q,r){n.push(p.data(r))})}});return n},instancesLatest:function(){return this.__instancesLatestArr},off:function(){this.__$emitterPublic.off.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments));return this},on:function(){this.__$emitterPublic.on.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments));return this},one:function(){this.__$emitterPublic.one.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments));return this},origins:function(l){var m=l?l+" ":"";return d(m+".tooltipstered").toArray()},setDefaults:function(l){d.extend(c,l);return this},triggerHandler:function(){this.__$emitterPublic.triggerHandler.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments));return this}};d.tooltipster=new b();d.Tooltipster=function(m,l){this.__callbacks={close:[],open:[]};this.__closingTime;this.__Content;this.__contentBcr;this.__destroyed=false;this.__$emitterPrivate=d({});this.__$emitterPublic=d({});this.__enabled=true;this.__garbageCollector;this.__Geometry;this.__lastPosition;this.__namespace="tooltipster-"+Math.round(Math.random()*1000000);this.__options;this.__$originParents;this.__pointerIsOverOrigin=false;this.__previousThemes=[];this.__state="closed";this.__timeouts={close:[],open:null};this.__touchEvents=[];this.__tracker=null;this._$origin;this._$tooltip;this.__init(m,l)};d.Tooltipster.prototype={__init:function(o,p){var n=this;n._$origin=d(o);n.__options=d.extend(true,{},c,p);n.__optionsFormat();if(!g.IE||g.IE>=n.__options.IEmin){var m=null;if(n._$origin.data("tooltipster-initialTitle")===undefined){m=n._$origin.attr("title");if(m===undefined){m=null}n._$origin.data("tooltipster-initialTitle",m)}if(n.__options.content!==null){n.__contentSet(n.__options.content)}else{var l=n._$origin.attr("data-tooltip-content"),q;if(l){q=d(l)}if(q&&q[0]){n.__contentSet(q.first())}else{n.__contentSet(m)}}n._$origin.removeAttr("title").addClass("tooltipstered");n.__prepareOrigin();n.__prepareGC();d.each(n.__options.plugins,function(r,s){n._plug(s)});if(g.hasTouchCapability){d(g.window.document.body).on("touchmove."+n.__namespace+"-triggerOpen",function(r){n._touchRecordEvent(r)})}n._on("created",function(){n.__prepareTooltip()})._on("repositioned",function(r){n.__lastPosition=r.position})}else{n.__options.disabled=true}},__contentInsert:function(){var l=this,m=l._$tooltip.find(".tooltipster-content"),n=l.__Content,o=function(p){n=p};l._trigger({type:"format",content:l.__Content,format:o});if(l.__options.functionFormat){n=l.__options.functionFormat.call(l,l,{origin:l._$origin[0]},l.__Content)}if(typeof n==="string"&&!l.__options.contentAsHTML){m.text(n)}else{m.empty().append(n)}return l},__contentSet:function(l){if(l instanceof d&&this.__options.contentCloning){l=l.clone(true)}this.__Content=l;this._trigger({type:"updated",content:l});return this},__destroyError:function(){throw new Error("This tooltip has been destroyed and cannot execute your method call.")},__geometry:function(){var B=this,q=B._$origin,y=B._$origin.is("area");if(y){var G=B._$origin.parent().attr("name");q=d('img[usemap="#'+G+'"]')}var x=q[0].getBoundingClientRect(),L=d(g.window.document),z=d(g.window),C=q,N={available:{document:null,window:null},document:{size:{height:L.height(),width:L.width()}},window:{scroll:{left:g.window.scrollX||g.window.document.documentElement.scrollLeft,top:g.window.scrollY||g.window.document.documentElement.scrollTop},size:{height:z.height(),width:z.width()}},origin:{fixedLineage:false,offset:{},size:{height:x.bottom-x.top,width:x.right-x.left},usemapImage:y?q[0]:null,windowOffset:{bottom:x.bottom,left:x.left,right:x.right,top:x.top}}},l=false;if(y){var n=B._$origin.attr("shape"),K=B._$origin.attr("coords");if(K){K=K.split(",");d.map(K,function(P,O){K[O]=parseInt(P)})}if(n!="default"){switch(n){case"circle":var s=K[0],t=K[1],m=K[2],I=t-m,u=s-m;N.origin.size.height=m*2;N.origin.size.width=N.origin.size.height;N.origin.windowOffset.left+=u;N.origin.windowOffset.top+=I;break;case"rect":var r=K[0],v=K[1],A=K[2],M=K[3];N.origin.size.height=M-v;N.origin.size.width=A-r;N.origin.windowOffset.left+=r;N.origin.windowOffset.top+=v;break;case"poly":var F=0,D=0,p=0,o=0,w="even";for(var J=0;Jp){p=H;if(J===0){F=p}}if(Ho){o=H;if(J==1){D=o}}if(H60000});if(!a(l._$origin)){l.close(function(){l.destroy()})}},20000)}else{clearInterval(l.__garbageCollector)}return l},__prepareOrigin:function(){var l=this;l._$origin.off("."+l.__namespace+"-triggerOpen");if(g.hasTouchCapability){l._$origin.on("touchstart."+l.__namespace+"-triggerOpen touchend."+l.__namespace+"-triggerOpen touchcancel."+l.__namespace+"-triggerOpen",function(n){l._touchRecordEvent(n)})}if(l.__options.triggerOpen.click||(l.__options.triggerOpen.tap&&g.hasTouchCapability)){var m="";if(l.__options.triggerOpen.click){m+="click."+l.__namespace+"-triggerOpen "}if(l.__options.triggerOpen.tap&&g.hasTouchCapability){m+="touchend."+l.__namespace+"-triggerOpen"}l._$origin.on(m,function(n){if(l._touchIsMeaningfulEvent(n)){l._open(n)}})}if(l.__options.triggerOpen.mouseenter||(l.__options.triggerOpen.touchstart&&g.hasTouchCapability)){var m="";if(l.__options.triggerOpen.mouseenter){m+="mouseenter."+l.__namespace+"-triggerOpen "}if(l.__options.triggerOpen.touchstart&&g.hasTouchCapability){m+="touchstart."+l.__namespace+"-triggerOpen"}l._$origin.on(m,function(n){if(l._touchIsTouchEvent(n)||!l._touchIsEmulatedEvent(n)){l.__pointerIsOverOrigin=true;l._openShortly(n)}})}if(l.__options.triggerClose.mouseleave||(l.__options.triggerClose.touchleave&&g.hasTouchCapability)){var m="";if(l.__options.triggerClose.mouseleave){m+="mouseleave."+l.__namespace+"-triggerOpen "}if(l.__options.triggerClose.touchleave&&g.hasTouchCapability){m+="touchend."+l.__namespace+"-triggerOpen touchcancel."+l.__namespace+"-triggerOpen"}l._$origin.on(m,function(n){if(l._touchIsMeaningfulEvent(n)){l.__pointerIsOverOrigin=false}})}return l},__prepareTooltip:function(){var l=this,m=l.__options.interactive?"auto":"";l._$tooltip.attr("id",l.__namespace).css({"pointer-events":m,zIndex:l.__options.zIndex});d.each(l.__previousThemes,function(n,o){l._$tooltip.removeClass(o)});d.each(l.__options.theme,function(n,o){l._$tooltip.addClass(o)});l.__previousThemes=d.merge([],l.__options.theme);return l},__scrollHandler:function(n){var l=this;if(l.__options.triggerClose.scroll){l._close(n)}else{if(a(l._$origin)&&a(l._$tooltip)){var q=null;if(n.target===g.window.document){if(!l.__Geometry.origin.fixedLineage){if(l.__options.repositionOnScroll){l.reposition(n)}}}else{q=l.__geometry();var p=false;if(l._$origin.css("position")!="fixed"){l.__$originParents.each(function(u,v){var t=d(v),s=t.css("overflow-x"),r=t.css("overflow-y");if(s!="visible"||r!="visible"){var w=v.getBoundingClientRect();if(s!="visible"){if(q.origin.windowOffset.leftw.right){p=true;return false}}if(r!="visible"){if(q.origin.windowOffset.topw.bottom){p=true;return false}}}if(t.css("position")=="fixed"){return false}})}if(p){l._$tooltip.css("visibility","hidden")}else{l._$tooltip.css("visibility","visible");if(l.__options.repositionOnScroll){l.reposition(n)}else{var o=q.origin.offset.left-l.__Geometry.origin.offset.left,m=q.origin.offset.top-l.__Geometry.origin.offset.top;l._$tooltip.css({left:l.__lastPosition.coord.left+o,top:l.__lastPosition.coord.top+m})}}}l._trigger({type:"scroll",event:n,geo:q})}}return l},__stateSet:function(l){this.__state=l;this._trigger({type:"state",state:l});return this},__timeoutsClear:function(){clearTimeout(this.__timeouts.open);this.__timeouts.open=null;d.each(this.__timeouts.close,function(l,m){clearTimeout(m)});this.__timeouts.close=[];return this},__trackerStart:function(){var l=this,m=l._$tooltip.find(".tooltipster-content");if(l.__options.trackTooltip){l.__contentBcr=m[0].getBoundingClientRect()}l.__tracker=setInterval(function(){if(!a(l._$origin)||!a(l._$tooltip)){l._close()}else{if(l.__options.trackOrigin){var o=l.__geometry(),p=false;if(k(o.origin.size,l.__Geometry.origin.size)){if(l.__Geometry.origin.fixedLineage){if(k(o.origin.windowOffset,l.__Geometry.origin.windowOffset)){p=true}}else{if(k(o.origin.offset,l.__Geometry.origin.offset)){p=true}}}if(!p){if(l.__options.triggerClose.mouseleave){l._close()}else{l.reposition()}}}if(l.__options.trackTooltip){var n=m[0].getBoundingClientRect();if(n.height!==l.__contentBcr.height||n.width!==l.__contentBcr.width){l.reposition();l.__contentBcr=n}}}},l.__options.trackerInterval);return l},_close:function(m,t,o){var u=this,r=true;u._trigger({type:"close",event:m,stop:function(){r=false}});if(r||o){if(t){u.__callbacks.close.push(t)}u.__callbacks.open=[];u.__timeoutsClear();var l=function(){d.each(u.__callbacks.close,function(w,x){x.call(u,u,{event:m,origin:u._$origin[0]})});u.__callbacks.close=[]};if(u.__state!="closed"){var p=true,q=new Date(),n=q.getTime(),v=n+u.__options.animationDuration[1];if(u.__state=="disappearing"){if(v>u.__closingTime&&u.__options.animationDuration[1]>0){p=false}}if(p){u.__closingTime=v;if(u.__state!="disappearing"){u.__stateSet("disappearing")}var s=function(){clearInterval(u.__tracker);u._trigger({type:"closing",event:m});u._$tooltip.off("."+u.__namespace+"-triggerClose").removeClass("tooltipster-dying");d(g.window).off("."+u.__namespace+"-triggerClose");u.__$originParents.each(function(w,x){d(x).off("scroll."+u.__namespace+"-triggerClose")});u.__$originParents=null;d(g.window.document.body).off("."+u.__namespace+"-triggerClose");u._$origin.off("."+u.__namespace+"-triggerClose");u._off("dismissable");u.__stateSet("closed");u._trigger({type:"after",event:m});if(u.__options.functionAfter){u.__options.functionAfter.call(u,u,{event:m,origin:u._$origin[0]})}l()};if(g.hasTransitions){u._$tooltip.css({"-moz-animation-duration":u.__options.animationDuration[1]+"ms","-ms-animation-duration":u.__options.animationDuration[1]+"ms","-o-animation-duration":u.__options.animationDuration[1]+"ms","-webkit-animation-duration":u.__options.animationDuration[1]+"ms","animation-duration":u.__options.animationDuration[1]+"ms","transition-duration":u.__options.animationDuration[1]+"ms"});u._$tooltip.clearQueue().removeClass("tooltipster-show").addClass("tooltipster-dying");if(u.__options.animationDuration[1]>0){u._$tooltip.delay(u.__options.animationDuration[1])}u._$tooltip.queue(s)}else{u._$tooltip.stop().fadeOut(u.__options.animationDuration[1],s)}}}else{l()}}return u},_off:function(){this.__$emitterPrivate.off.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments));return this},_on:function(){this.__$emitterPrivate.on.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments));return this},_one:function(){this.__$emitterPrivate.one.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments));return this},_open:function(l,s){var u=this;if(!u.__destroying){if(a(u._$origin)&&u.__enabled){var q=true;if(u.__state=="closed"){u._trigger({type:"before",event:l,stop:function(){q=false}});if(q&&u.__options.functionBefore){q=u.__options.functionBefore.call(u,u,{event:l,origin:u._$origin[0]})}}if(q!==false){if(u.__Content!==null){if(s){u.__callbacks.open.push(s)}u.__callbacks.close=[];u.__timeoutsClear();var m,r=function(){if(u.__state!="stable"){u.__stateSet("stable")}d.each(u.__callbacks.open,function(v,w){w.call(u,u,{origin:u._$origin[0],tooltip:u._$tooltip[0]})});u.__callbacks.open=[]};if(u.__state!=="closed"){m=0;if(u.__state==="disappearing"){u.__stateSet("appearing");if(g.hasTransitions){u._$tooltip.clearQueue().removeClass("tooltipster-dying").addClass("tooltipster-show");if(u.__options.animationDuration[0]>0){u._$tooltip.delay(u.__options.animationDuration[0])}u._$tooltip.queue(r)}else{u._$tooltip.stop().fadeIn(r)}}else{if(u.__state=="stable"){r()}}}else{u.__stateSet("appearing");m=u.__options.animationDuration[0];u.__contentInsert();u.reposition(l,true);if(g.hasTransitions){u._$tooltip.addClass("tooltipster-"+u.__options.animation).addClass("tooltipster-initial").css({"-moz-animation-duration":u.__options.animationDuration[0]+"ms","-ms-animation-duration":u.__options.animationDuration[0]+"ms","-o-animation-duration":u.__options.animationDuration[0]+"ms","-webkit-animation-duration":u.__options.animationDuration[0]+"ms","animation-duration":u.__options.animationDuration[0]+"ms","transition-duration":u.__options.animationDuration[0]+"ms"});setTimeout(function(){if(u.__state!="closed"){u._$tooltip.addClass("tooltipster-show").removeClass("tooltipster-initial");if(u.__options.animationDuration[0]>0){u._$tooltip.delay(u.__options.animationDuration[0])}u._$tooltip.queue(r)}},0)}else{u._$tooltip.css("display","none").fadeIn(u.__options.animationDuration[0],r)}u.__trackerStart();d(g.window).on("resize."+u.__namespace+"-triggerClose",function(w){var v=d(document.activeElement);if((!v.is("input")&&!v.is("textarea"))||!d.contains(u._$tooltip[0],v[0])){u.reposition(w)}}).on("scroll."+u.__namespace+"-triggerClose",function(v){u.__scrollHandler(v)});u.__$originParents=u._$origin.parents();u.__$originParents.each(function(v,w){d(w).on("scroll."+u.__namespace+"-triggerClose",function(x){u.__scrollHandler(x)})});if(u.__options.triggerClose.mouseleave||(u.__options.triggerClose.touchleave&&g.hasTouchCapability)){u._on("dismissable",function(v){if(v.dismissable){if(v.delay){p=setTimeout(function(){u._close(v.event)},v.delay);u.__timeouts.close.push(p)}else{u._close(v)}}else{clearTimeout(p)}});var o=u._$origin,t="",n="",p=null;if(u.__options.interactive){o=o.add(u._$tooltip)}if(u.__options.triggerClose.mouseleave){t+="mouseenter."+u.__namespace+"-triggerClose ";n+="mouseleave."+u.__namespace+"-triggerClose "}if(u.__options.triggerClose.touchleave&&g.hasTouchCapability){t+="touchstart."+u.__namespace+"-triggerClose";n+="touchend."+u.__namespace+"-triggerClose touchcancel."+u.__namespace+"-triggerClose"}o.on(n,function(w){if(u._touchIsTouchEvent(w)||!u._touchIsEmulatedEvent(w)){var v=(w.type=="mouseleave")?u.__options.delay:u.__options.delayTouch;u._trigger({delay:v[1],dismissable:true,event:w,type:"dismissable"})}}).on(t,function(v){if(u._touchIsTouchEvent(v)||!u._touchIsEmulatedEvent(v)){u._trigger({dismissable:false,event:v,type:"dismissable"})}})}if(u.__options.triggerClose.originClick){u._$origin.on("click."+u.__namespace+"-triggerClose",function(v){if(!u._touchIsTouchEvent(v)&&!u._touchIsEmulatedEvent(v)){u._close(v)}})}if(u.__options.triggerClose.click||(u.__options.triggerClose.tap&&g.hasTouchCapability)){setTimeout(function(){if(u.__state!="closed"){var w="",v=d(g.window.document.body);if(u.__options.triggerClose.click){w+="click."+u.__namespace+"-triggerClose "}if(u.__options.triggerClose.tap&&g.hasTouchCapability){w+="touchend."+u.__namespace+"-triggerClose"}v.on(w,function(x){if(u._touchIsMeaningfulEvent(x)){u._touchRecordEvent(x);if(!u.__options.interactive||!d.contains(u._$tooltip[0],x.target)){u._close(x)}}});if(u.__options.triggerClose.tap&&g.hasTouchCapability){v.on("touchstart."+u.__namespace+"-triggerClose",function(x){u._touchRecordEvent(x)})}}},0)}u._trigger("ready");if(u.__options.functionReady){u.__options.functionReady.call(u,u,{origin:u._$origin[0],tooltip:u._$tooltip[0]})}}if(u.__options.timer>0){var p=setTimeout(function(){u._close()},u.__options.timer+m);u.__timeouts.close.push(p)}}}}}return u},_openShortly:function(o){var l=this,n=true;if(l.__state!="stable"&&l.__state!="appearing"){if(!l.__timeouts.open){l._trigger({type:"start",event:o,stop:function(){n=false}});if(n){var m=(o.type.indexOf("touch")==0)?l.__options.delayTouch:l.__options.delay;if(m[0]){l.__timeouts.open=setTimeout(function(){l.__timeouts.open=null;if(l.__pointerIsOverOrigin&&l._touchIsMeaningfulEvent(o)){l._trigger("startend");l._open(o)}else{l._trigger("startcancel")}},m[0])}else{l._trigger("startend");l._open(o)}}}}return l},_optionsExtract:function(p,l){var m=this,n=d.extend(true,{},l);var o=m.__options[p];if(!o){o={};d.each(l,function(q,r){var s=m.__options[q];if(s!==undefined){o[q]=s}})}d.each(n,function(q,r){if(o[q]!==undefined){if((typeof r=="object"&&!(r instanceof Array)&&r!=null)&&(typeof o[q]=="object"&&!(o[q] instanceof Array)&&o[q]!=null)){d.extend(n[q],o[q])}else{n[q]=o[q]}}});return n},_plug:function(m){var l=d.tooltipster._plugin(m);if(l){if(l.instance){d.tooltipster.__bridge(l.instance,this,l.name)}}else{throw new Error('The "'+m+'" plugin is not defined')}return this},_touchIsEmulatedEvent:function(o){var n=false,l=new Date().getTime();for(var m=this.__touchEvents.length-1;m>=0;m--){var p=this.__touchEvents[m];if(l-p.time<500){if(p.target===o.target){n=true}}else{break}}return n},_touchIsMeaningfulEvent:function(l){return((this._touchIsTouchEvent(l)&&!this._touchSwiped(l.target))||(!this._touchIsTouchEvent(l)&&!this._touchIsEmulatedEvent(l)))},_touchIsTouchEvent:function(l){return l.type.indexOf("touch")==0},_touchRecordEvent:function(l){if(this._touchIsTouchEvent(l)){l.time=new Date().getTime();this.__touchEvents.push(l)}return this},_touchSwiped:function(o){var m=false;for(var l=this.__touchEvents.length-1;l>=0;l--){var n=this.__touchEvents[l];if(n.type=="touchmove"){m=true;break}else{if(n.type=="touchstart"&&o===n.target){break}}}return m},_trigger:function(){var l=Array.prototype.slice.apply(arguments);if(typeof l[0]=="string"){l[0]={type:l[0]}}l[0].instance=this;l[0].origin=this._$origin?this._$origin[0]:null;l[0].tooltip=this._$tooltip?this._$tooltip[0]:null;this.__$emitterPrivate.trigger.apply(this.__$emitterPrivate,l);d.tooltipster._trigger.apply(d.tooltipster,l);this.__$emitterPublic.trigger.apply(this.__$emitterPublic,l);return this},_unplug:function(n){var l=this;if(l[n]){var m=d.tooltipster._plugin(n);if(m.instance){d.each(m.instance,function(o,p){if(l[o]&&l[o].bridged===l[n]){delete l[o]}})}if(l[n].__destroy){l[n].__destroy()}delete l[n]}return l},close:function(l){if(!this.__destroyed){this._close(null,l)}else{this.__destroyError()}return this},content:function(m){var l=this;if(m===undefined){return l.__Content}else{if(!l.__destroyed){l.__contentSet(m);if(l.__Content!==null){if(l.__state!=="closed"){l.__contentInsert();l.reposition();if(l.__options.updateAnimation){if(g.hasTransitions){var n=l.__options.updateAnimation;l._$tooltip.addClass("tooltipster-update-"+n);setTimeout(function(){if(l.__state!="closed"){l._$tooltip.removeClass("tooltipster-update-"+n)}},1000)}else{l._$tooltip.fadeTo(200,0.5,function(){if(l.__state!="closed"){l._$tooltip.fadeTo(200,1)}})}}}}else{l._close()}}else{l.__destroyError()}return l}},destroy:function(){var l=this;if(!l.__destroyed){if(l.__state!="closed"){l.option("animationDuration",0)._close(null,null,true)}else{l.__timeoutsClear()}l._trigger("destroy");l.__destroyed=true;l._$origin.removeData(l.__namespace).off("."+l.__namespace+"-triggerOpen");d(g.window.document.body).off("."+l.__namespace+"-triggerOpen");var m=l._$origin.data("tooltipster-ns");if(m){if(m.length===1){var n=null;if(l.__options.restoration=="previous"){n=l._$origin.data("tooltipster-initialTitle")}else{if(l.__options.restoration=="current"){n=(typeof l.__Content=="string")?l.__Content:d("
").append(l.__Content).html()}}if(n){l._$origin.attr("title",n)}l._$origin.removeClass("tooltipstered");l._$origin.removeData("tooltipster-ns").removeData("tooltipster-initialTitle")}else{m=d.grep(m,function(p,o){return p!==l.__namespace});l._$origin.data("tooltipster-ns",m)}}l._trigger("destroyed");l._off();l.off();l.__Content=null;l.__$emitterPrivate=null;l.__$emitterPublic=null;l.__options.parent=null;l._$origin=null;l._$tooltip=null;d.tooltipster.__instancesLatestArr=d.grep(d.tooltipster.__instancesLatestArr,function(p,o){return l!==p});clearInterval(l.__garbageCollector)}else{l.__destroyError()}return l},disable:function(){if(!this.__destroyed){this._close();this.__enabled=false;return this}else{this.__destroyError()}return this},elementOrigin:function(){if(!this.__destroyed){return this._$origin[0]}else{this.__destroyError()}},elementTooltip:function(){return this._$tooltip?this._$tooltip[0]:null},enable:function(){this.__enabled=true;return this},hide:function(l){return this.close(l)},instance:function(){return this},off:function(){if(!this.__destroyed){this.__$emitterPublic.off.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments))}return this},on:function(){if(!this.__destroyed){this.__$emitterPublic.on.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments))}else{this.__destroyError()}return this},one:function(){if(!this.__destroyed){this.__$emitterPublic.one.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments))}else{this.__destroyError()}return this},open:function(l){if(!this.__destroyed){this._open(null,l)}else{this.__destroyError()}return this},option:function(m,l){if(l===undefined){return this.__options[m]}else{if(!this.__destroyed){this.__options[m]=l;this.__optionsFormat();if(d.inArray(m,["trigger","triggerClose","triggerOpen"])>=0){this.__prepareOrigin()}if(m==="selfDestruction"){this.__prepareGC()}}else{this.__destroyError()}return this}},reposition:function(m,n){var l=this;if(!l.__destroyed){if(l.__state!="closed"&&a(l._$origin)){if(n||a(l._$tooltip)){if(!n){l._$tooltip.detach()}l.__Geometry=l.__geometry();l._trigger({type:"reposition",event:m,helper:{geo:l.__Geometry}})}}}else{l.__destroyError()}return l},show:function(l){return this.open(l)},status:function(){return{destroyed:this.__destroyed,enabled:this.__enabled,open:this.__state!=="closed",state:this.__state}},triggerHandler:function(){if(!this.__destroyed){this.__$emitterPublic.triggerHandler.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments))}else{this.__destroyError()}return this}};d.fn.tooltipster=function(){var q=Array.prototype.slice.apply(arguments),n="You are using a single HTML element as content for several tooltips. You probably want to set the contentCloning option to TRUE.";if(this.length===0){return this}else{if(typeof q[0]==="string"){var t="#*$~&";this.each(function(){var x=d(this).data("tooltipster-ns"),v=x?d(this).data(x[0]):null;if(v){if(typeof v[q[0]]==="function"){if(this.length>1&&q[0]=="content"&&(q[1] instanceof d||(typeof q[1]=="object"&&q[1]!=null&&q[1].tagName))&&!v.__options.contentCloning&&v.__options.debug){console.log(n)}var y=v[q[0]](q[1],q[2])}else{throw new Error('Unknown method "'+q[0]+'"')}if(y!==v||q[0]==="instance"){t=y;return false}}else{throw new Error("You called Tooltipster's \""+q[0]+'" method on an uninitialized element')}});return(t!=="#*$~&")?t:this}else{d.tooltipster.__instancesLatestArr=[];var o=q[0]&&q[0].multiple!==undefined,w=(o&&q[0].multiple)||(!o&&c.multiple),r=q[0]&&q[0].content!==undefined,p=(r&&q[0].content)||(!r&&c.content),m=q[0]&&q[0].contentCloning!==undefined,u=(m&&q[0].contentCloning)||(!m&&c.contentCloning),s=q[0]&&q[0].debug!==undefined,l=(s&&q[0].debug)||(!s&&c.debug);if(this.length>1&&(p instanceof d||(typeof p=="object"&&p!=null&&p.tagName))&&!u&&l){console.log(n)}this.each(function(){var x=false,z=d(this),v=z.data("tooltipster-ns"),y=null;if(!v){x=true}else{if(w){x=true}else{if(l){console.log("Tooltipster: one or more tooltips are already attached to the element below. Ignoring.");console.log(this)}}}if(x){y=new d.Tooltipster(this,q[0]);if(!v){v=[]}v.push(y.__namespace);z.data("tooltipster-ns",v);z.data(y.__namespace,y);if(y.__options.functionInit){y.__options.functionInit.call(y,y,{origin:this})}y._trigger("init")}d.tooltipster.__instancesLatestArr.push(y)});return this}}};function i(l){this.$container;this.constraints=null;this.__$tooltip;this.__init(l)}i.prototype={__init:function(l){this.__$tooltip=l;this.__$tooltip.css({left:0,overflow:"hidden",position:"absolute",top:0}).find(".tooltipster-content").css("overflow","auto");this.$container=d('
').append(this.__$tooltip).appendTo(g.window.document.body)},__forceRedraw:function(){var l=this.__$tooltip.parent();this.__$tooltip.detach();this.__$tooltip.appendTo(l)},constrain:function(m,l){this.constraints={width:m,height:l};this.__$tooltip.css({display:"block",height:"",overflow:"auto",width:m});return this},destroy:function(){this.__$tooltip.detach().find(".tooltipster-content").css({display:"",overflow:""});this.$container.remove()},free:function(){this.constraints=null;this.__$tooltip.css({display:"",height:"",overflow:"visible",width:""});return this},measure:function(){this.__forceRedraw();var q=this.__$tooltip[0].getBoundingClientRect(),m={size:{height:q.height||(q.bottom-q.top),width:q.width||(q.right-q.left)}};if(this.constraints){var n=this.__$tooltip.find(".tooltipster-content"),l=this.__$tooltip.outerHeight(),o=n[0].getBoundingClientRect(),p={height:l<=this.constraints.height,width:(q.width<=this.constraints.width&&o.width>=n[0].scrollWidth-1)};m.fits=p.height&&p.width}if(g.IE&&g.IE<=11&&m.size.width!==g.window.document.documentElement.clientWidth){m.size.width=Math.ceil(m.size.width)+1}return m}};function k(m,l){var n=true;d.each(m,function(p,o){if(l[p]===undefined||m[p]!==l[p]){n=false;return false}});return n}function a(n){var m=n.attr("id"),l=m?g.window.document.getElementById(m):null;return l?l===n[0]:d.contains(g.window.document.body,n[0])}var e=navigator.userAgent.toLowerCase();if(e.indexOf("msie")!=-1){g.IE=parseInt(e.split("msie")[1])}else{if(e.toLowerCase().indexOf("trident")!==-1&&e.indexOf(" rv:11")!==-1){g.IE=11}else{if(e.toLowerCase().indexOf("edge/")!=-1){g.IE=parseInt(e.toLowerCase().split("edge/")[1])}}}function j(){if(!f){return false}var l=f.document.body||f.document.documentElement,o=l.style,q="transition",m=["Moz","Webkit","Khtml","O","ms"];if(typeof o[q]=="string"){return true}q=q.charAt(0).toUpperCase()+q.substr(1);for(var n=0;n
');if(!this.__options.arrow){l.find(".tooltipster-box").css("margin",0).end().find(".tooltipster-arrow").hide()}if(this.__options.minWidth){l.css("min-width",this.__options.minWidth+"px")}if(this.__options.maxWidth){l.css("max-width",this.__options.maxWidth+"px")}this.__instance._$tooltip=l;this.__instance._trigger("created")},__destroy:function(){this.__instance._off("."+self.__namespace)},__optionsFormat:function(){var l=this;l.__options=l.__instance._optionsExtract(h,l.__defaults());if(l.__options.position){l.__options.side=l.__options.position}if(typeof l.__options.distance!="object"){l.__options.distance=[l.__options.distance]}if(l.__options.distance.length<4){if(l.__options.distance[1]===undefined){l.__options.distance[1]=l.__options.distance[0]}if(l.__options.distance[2]===undefined){l.__options.distance[2]=l.__options.distance[0]}if(l.__options.distance[3]===undefined){l.__options.distance[3]=l.__options.distance[1]}l.__options.distance={top:l.__options.distance[0],right:l.__options.distance[1],bottom:l.__options.distance[2],left:l.__options.distance[3]}}if(typeof l.__options.side=="string"){var m={top:"bottom",right:"left",bottom:"top",left:"right"};l.__options.side=[l.__options.side,m[l.__options.side]];if(l.__options.side[0]=="left"||l.__options.side[0]=="right"){l.__options.side.push("top","bottom")}else{l.__options.side.push("right","left")}}if(d.tooltipster._env.IE===6&&l.__options.arrow!==true){l.__options.arrow=false}},__reposition:function(l,n){var y=this,p,r=y.__targetFind(n),m=[];y.__instance._$tooltip.detach();var s=y.__instance._$tooltip.clone(),x=d.tooltipster._getRuler(s),o=false,q=y.__instance.option("animation");if(q){s.removeClass("tooltipster-"+q)}d.each(["window","document"],function(D,B){var A=null;y.__instance._trigger({container:B,helper:n,satisfied:o,takeTest:function(F){A=F},results:m,type:"positionTest"});if(A==true||(A!=false&&o==false&&(B!="window"||y.__options.viewportAware))){for(var D=0;D=G.outerSize.width&&n.geo.available[B][C].height>=G.outerSize.height){G.fits=true}else{G.fits=false}}else{G.fits=F.fits}if(B=="window"){if(!G.fits){G.whole=false}else{if(C=="top"||C=="bottom"){G.whole=(n.geo.origin.windowOffset.right>=y.__options.minIntersection&&n.geo.window.size.width-n.geo.origin.windowOffset.left>=y.__options.minIntersection)}else{G.whole=(n.geo.origin.windowOffset.bottom>=y.__options.minIntersection&&n.geo.window.size.height-n.geo.origin.windowOffset.top>=y.__options.minIntersection)}}}m.push(G);if(G.whole){o=true}else{if(G.mode=="natural"&&(G.fits||G.size.width<=n.geo.available[B][C].width)){return false}}}})}}});y.__instance._trigger({edit:function(A){m=A},event:l,helper:n,results:m,type:"positionTested"});m.sort(function(C,B){if(C.whole&&!B.whole){return -1}else{if(!C.whole&&B.whole){return 1}else{if(C.whole&&B.whole){var A=y.__options.side.indexOf(C.side),D=y.__options.side.indexOf(B.side);if(AD){return 1}else{return C.mode=="natural"?-1:1}}}else{if(C.fits&&!B.fits){return -1}else{if(!C.fits&&B.fits){return 1}else{if(C.fits&&B.fits){var A=y.__options.side.indexOf(C.side),D=y.__options.side.indexOf(B.side);if(AD){return 1}else{return C.mode=="natural"?-1:1}}}else{if(C.container=="document"&&C.side=="bottom"&&C.mode=="natural"){return -1}else{return 1}}}}}}}});p=m[0];p.coord={};switch(p.side){case"left":case"right":p.coord.top=Math.floor(p.target-p.size.height/2);break;case"bottom":case"top":p.coord.left=Math.floor(p.target-p.size.width/2);break}switch(p.side){case"left":p.coord.left=n.geo.origin.windowOffset.left-p.outerSize.width;break;case"right":p.coord.left=n.geo.origin.windowOffset.right+p.distance.horizontal;break;case"top":p.coord.top=n.geo.origin.windowOffset.top-p.outerSize.height;break;case"bottom":p.coord.top=n.geo.origin.windowOffset.bottom+p.distance.vertical;break}if(p.container=="window"){if(p.side=="top"||p.side=="bottom"){if(p.coord.left<0){if(n.geo.origin.windowOffset.right-this.__options.minIntersection>=0){p.coord.left=0}else{p.coord.left=n.geo.origin.windowOffset.right-this.__options.minIntersection-1}}else{if(p.coord.left>n.geo.window.size.width-p.size.width){if(n.geo.origin.windowOffset.left+this.__options.minIntersection<=n.geo.window.size.width){p.coord.left=n.geo.window.size.width-p.size.width}else{p.coord.left=n.geo.origin.windowOffset.left+this.__options.minIntersection+1-p.size.width}}}}else{if(p.coord.top<0){if(n.geo.origin.windowOffset.bottom-this.__options.minIntersection>=0){p.coord.top=0}else{p.coord.top=n.geo.origin.windowOffset.bottom-this.__options.minIntersection-1}}else{if(p.coord.top>n.geo.window.size.height-p.size.height){if(n.geo.origin.windowOffset.top+this.__options.minIntersection<=n.geo.window.size.height){p.coord.top=n.geo.window.size.height-p.size.height}else{p.coord.top=n.geo.origin.windowOffset.top+this.__options.minIntersection+1-p.size.height}}}}}else{if(p.coord.left>n.geo.window.size.width-p.size.width){p.coord.left=n.geo.window.size.width-p.size.width}if(p.coord.left<0){p.coord.left=0}}y.__sideChange(s,p.side);n.tooltipClone=s[0];n.tooltipParent=y.__instance.option("parent").parent[0];n.mode=p.mode;n.whole=p.whole;n.origin=y.__instance._$origin[0];n.tooltip=y.__instance._$tooltip[0];delete p.container;delete p.fits;delete p.mode;delete p.outerSize;delete p.whole;p.distance=p.distance.horizontal||p.distance.vertical;var t=d.extend(true,{},p);y.__instance._trigger({edit:function(A){p=A},event:l,helper:n,position:t,type:"position"});if(y.__options.functionPosition){var z=y.__options.functionPosition.call(y,y.__instance,n,t);if(z){p=z}}x.destroy();var u,w;if(p.side=="top"||p.side=="bottom"){u={prop:"left",val:p.target-p.coord.left};w=p.size.width-this.__options.minIntersection}else{u={prop:"top",val:p.target-p.coord.top};w=p.size.height-this.__options.minIntersection}if(u.valw){u.val=w}}var v;if(n.geo.origin.fixedLineage){v=n.geo.origin.windowOffset}else{v={left:n.geo.origin.windowOffset.left+n.geo.window.scroll.left,top:n.geo.origin.windowOffset.top+n.geo.window.scroll.top}}p.coord={left:v.left+(p.coord.left-n.geo.origin.windowOffset.left),top:v.top+(p.coord.top-n.geo.origin.windowOffset.top)};y.__sideChange(y.__instance._$tooltip,p.side);if(n.geo.origin.fixedLineage){y.__instance._$tooltip.css("position","fixed")}else{y.__instance._$tooltip.css("position","")}y.__instance._$tooltip.css({left:p.coord.left,top:p.coord.top,height:p.size.height,width:p.size.width}).find(".tooltipster-arrow").css({left:"",top:""}).css(u.prop,u.val);y.__instance._$tooltip.appendTo(y.__instance.option("parent"));y.__instance._trigger({type:"repositioned",event:l,position:p})},__sideChange:function(m,l){m.removeClass("tooltipster-bottom").removeClass("tooltipster-left").removeClass("tooltipster-right").removeClass("tooltipster-top").addClass("tooltipster-"+l)},__targetFind:function(n){var p={},l=this.__instance._$origin[0].getClientRects();if(l.length>1){var m=this.__instance._$origin.css("opacity");if(m==1){this.__instance._$origin.css("opacity",0.99);l=this.__instance._$origin[0].getClientRects();this.__instance._$origin.css("opacity",1)}}if(l.length<2){p.top=Math.floor(n.geo.origin.windowOffset.left+(n.geo.origin.size.width/2));p.bottom=p.top;p.left=Math.floor(n.geo.origin.windowOffset.top+(n.geo.origin.size.height/2));p.right=p.left}else{var o=l[0];p.top=Math.floor(o.left+(o.right-o.left)/2);if(l.length>2){o=l[Math.ceil(l.length/2)-1]}else{o=l[0]}p.right=Math.floor(o.top+(o.bottom-o.top)/2);o=l[l.length-1];p.bottom=Math.floor(o.left+(o.right-o.left)/2);if(l.length>2){o=l[Math.ceil((l.length+1)/2)-1]}else{o=l[l.length-1]}p.left=Math.floor(o.top+(o.bottom-o.top)/2)}return p}}});return d})); +/*! vex.combined.js: vex 4.1.0, vex-dialog 1.0.7 */ +;!function(a){if("object"==typeof exports&&"undefined"!=typeof module){module.exports=a()}else{if("function"==typeof define&&define.amd){define([],a)}else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).vex=a()}}}(function(){return function a(d,g,f){function c(i,k){if(!g[i]){if(!d[i]){var h="function"==typeof require&&require;if(!k&&h){return h(i,!0)}if(e){return e(i,!0)}var m=new Error("Cannot find module '"+i+"'");throw m.code="MODULE_NOT_FOUND",m}var j=g[i]={exports:{}};d[i][0].call(j.exports,function(l){var o=d[i][1][l];return c(o||l)},j,j.exports,a,d,g,f)}return g[i].exports}for(var e="function"==typeof require&&require,b=0;b
a',b=!g.getElementsByTagName("link").length,g=void 0);var d={legend:[1,"
","
"],tr:[2,"","
"],col:[2,"","
"],_default:b?[1,"X
","
"]:[0,"",""]};d.td=d.th=[3,"","
"],d.option=d.optgroup=[1,'"],d.thead=d.tbody=d.colgroup=d.caption=d.tfoot=[1,"","
"],d.polyline=d.ellipse=d.polygon=d.circle=d.text=d.line=d.path=d.rect=d.g=[1,'',""]},{}],3:[function(c,b,f){function d(p,v){if(null==p){throw new TypeError("Cannot convert first argument to object")}for(var j=Object(p),h=1;h
a',g=!l.getElementsByTagName("link").length,l=void 0);var j={legend:[1,"
","
"],tr:[2,"","
"],col:[2,"","
"],_default:g?[1,"X
","
"]:[0,"",""]};j.td=j.th=[3,"","
"],j.option=j.optgroup=[1,'"],j.thead=j.tbody=j.colgroup=j.caption=j.tfoot=[1,"","
"],j.polyline=j.ellipse=j.polygon=j.circle=j.text=j.line=j.path=j.rect=j.g=[1,'',""]},{}],2:[function(m,j,q){var p=/^(?:submit|button|image|reset|file)$/i,h=/^(?:input|select|textarea|keygen)/i,l=/(\[[^\[\]]*\])/g;function g(r,i,u){if(i.match(l)){!function r(x,B,A){if(0===B.length){return x=A}var w=B.shift(),z=w.match(/^\[(.+?)\]$/);if("[]"===w){return x=x||[],Array.isArray(x)?x.push(r(null,B,A)):(x._values=x._values||[],x._values.push(r(null,B,A))),x}if(z){var v=z[1],y=+v;isNaN(y)?(x=x||{})[v]=r(x[v],B,A):(x=x||[])[y]=r(x[y],B,A)}else{x[w]=r(x[w],B,A)}return x}(r,function(w){var v=[],y=new RegExp(l),x=/^([^\[\]]*)/.exec(w);for(x[1]&&v.push(x[1]);null!==(x=y.exec(w));){v.push(x[1])}return v}(i),u)}else{var s=r[i];s?(Array.isArray(s)||(r[i]=[s]),r[i].push(u)):r[i]=u}return r}function k(o,i,r){return r=r.replace(/(\r)?\n/g,"\r\n"),r=(r=encodeURIComponent(r)).replace(/%20/g,"+"),o+(o?"&":"")+encodeURIComponent(i)+"="+r}j.exports=function(C,J){"object"!=typeof J?J={hash:!!J}:void 0===J.hash&&(J.hash=!0);for(var s=J.hash?{}:"",i=J.serializer||(J.hash?g:k),x=C&&C.elements?C.elements:[],E=Object.create(null),I=0;I'+m._escapeHtml(q.label||s.label)+"",input:''},p=(q=Object.assign(s,r,q)).callback;return q.callback=function(o){if("object"==typeof o){var n=Object.keys(o);o=n.length?o[n[0]]:""}p(o)},this.open(q)},buttons:{YES:{text:"OK",type:"submit",className:"vex-dialog-button-primary",click:function(){this.value=!0}},NO:{text:"Cancel",type:"button",className:"vex-dialog-button-secondary",click:function(){this.value=!1,this.close()}}}};return i.defaultOptions={callback:function(){},afterOpen:function(){},message:"",input:"",buttons:[i.buttons.YES,i.buttons.NO],showCloseButton:!1,onSubmit:function(n){return n.preventDefault(),this.options.input&&(this.value=g(this.form,{hash:!0})),this.close()},focusFirstInput:!0},i.defaultAlertOptions={buttons:[i.buttons.YES]},i.defaultPromptOptions={label:"Prompt:",placeholder:"",value:""},i.defaultConfirmOptions={},i}},{domify:1,"form-serialize":2}]},{},[3])(3)})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{domify:2,"form-serialize":4}],6:[function(c,b,f){var d=c("./vex");d.registerPlugin(c("vex-dialog")),b.exports=d},{"./vex":7,"vex-dialog":5}],7:[function(A,G,k){A("classlist-polyfill"),A("es6-object-assign").polyfill();var j=A("domify"),x=function(d){if(void 0!==d){var c=document.createElement("div");return c.appendChild(document.createTextNode(d)),c.innerHTML}return""},b=function(f,d){if("string"==typeof d&&0!==d.length){for(var l=d.split(" "),h=0;h1&&(h="."+g[1]),a=/(\d+)(\d{3})/;a.test(d);){d=d.replace(a,"$1,$2")}return d+h},v=function(a){return"#"===a.charAt(0)?a.substring(1,7):a},x=function(){function a(d,c){null==d&&(d=!0),this.clear=null==c||c,d&&AnimationUpdater.add(this)}return a.prototype.animationSpeed=32,a.prototype.update=function(d){var c;return null==d&&(d=!1),!(!d&&this.displayedValue===this.value)&&(this.ctx&&this.clear&&this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),c=this.value-this.displayedValue,Math.abs(c/this.animationSpeed)<=0.001?this.displayedValue=this.value:this.displayedValue=this.displayedValue+c/this.animationSpeed,this.render(),!0)},a}(),z=function(c){function a(){return a.__super__.constructor.apply(this,arguments)}return q(a,c),a.prototype.displayScale=1,a.prototype.forceUpdate=!0,a.prototype.setTextField=function(e,d){return this.textField=e instanceof C?e:new C(e,d)},a.prototype.setMinValue=function(h,g){var m,l,r,p,d;if(this.minValue=h,null==g&&(g=!0),g){for(this.displayedValue=this.minValue,p=this.gp||[],d=[],l=0,r=p.length;l0.5&&(this.options.angle=0.5),this.configDisplayScale(),this},a.prototype.configDisplayScale=function(){var g,d,l,h,m;return h=this.displayScale,!1===this.options.highDpiSupport?delete this.displayScale:(d=window.devicePixelRatio||1,g=this.ctx.webkitBackingStorePixelRatio||this.ctx.mozBackingStorePixelRatio||this.ctx.msBackingStorePixelRatio||this.ctx.oBackingStorePixelRatio||this.ctx.backingStorePixelRatio||1,this.displayScale=d/g),this.displayScale!==h&&(m=this.canvas.G__width||this.canvas.width,l=this.canvas.G__height||this.canvas.height,this.canvas.width=m*this.displayScale,this.canvas.height=l*this.displayScale,this.canvas.style.width=m+"px",this.canvas.style.height=l+"px",this.canvas.G__width=m,this.canvas.G__height=l),this},a.prototype.parseValue=function(d){return d=parseFloat(d)||Number(d),isFinite(d)?d:0},a}(x),C=function(){function a(d,c){this.el=d,this.fractionDigits=c}return a.prototype.render=function(c){return this.el.innerHTML=f(c.displayedValue,this.fractionDigits)},a}(),E=function(c){function a(d,g){if(this.elem=d,this.text=null!=g&&g,a.__super__.constructor.call(this),void 0===this.elem){throw new Error("The element isn't defined.")}this.value=1*this.elem.innerHTML,this.text&&(this.value=0)}return q(a,c),a.prototype.displayedValue=0,a.prototype.value=0,a.prototype.setVal=function(d){return this.value=1*d},a.prototype.render=function(){var d;return d=this.text?D(this.displayedValue.toFixed(0)):b(f(this.displayedValue)),this.elem.innerHTML=d},a}(x),j=function(c){function a(d){if(this.gauge=d,void 0===this.gauge){throw new Error("The element isn't defined.")}this.ctx=this.gauge.ctx,this.canvas=this.gauge.canvas,a.__super__.constructor.call(this,!1,!1),this.setOptions()}return q(a,c),a.prototype.displayedValue=0,a.prototype.value=0,a.prototype.options={strokeWidth:0.035,length:0.1,color:"#000000",iconPath:null,iconScale:1,iconAngle:0},a.prototype.img=null,a.prototype.setOptions=function(d){if(null==d&&(d=null),this.options=B(this.options,d),this.length=2*this.gauge.radius*this.gauge.options.radiusScale*this.options.length,this.strokeWidth=this.canvas.height*this.options.strokeWidth,this.maxValue=this.gauge.maxValue,this.minValue=this.gauge.minValue,this.animationSpeed=this.gauge.animationSpeed,this.options.angle=this.gauge.options.angle,this.options.iconPath){return this.img=new Image,this.img.src=this.options.iconPath}},a.prototype.render=function(){var H,m,u,I,l,g,G,p,d;if(H=this.gauge.getAngle.call(this,this.displayedValue),p=Math.round(this.length*Math.cos(H)),d=Math.round(this.length*Math.sin(H)),g=Math.round(this.strokeWidth*Math.cos(H-Math.PI/2)),G=Math.round(this.strokeWidth*Math.sin(H-Math.PI/2)),m=Math.round(this.strokeWidth*Math.cos(H+Math.PI/2)),u=Math.round(this.strokeWidth*Math.sin(H+Math.PI/2)),this.ctx.beginPath(),this.ctx.fillStyle=this.options.color,this.ctx.arc(0,0,this.strokeWidth,0,2*Math.PI,!1),this.ctx.fill(),this.ctx.beginPath(),this.ctx.moveTo(g,G),this.ctx.lineTo(p,d),this.ctx.lineTo(m,u),this.ctx.fill(),this.img){return I=Math.round(this.img.width*this.options.iconScale),l=Math.round(this.img.height*this.options.iconScale),this.ctx.save(),this.ctx.translate(p,d),this.ctx.rotate(H+Math.PI/180*(90+this.options.iconAngle)),this.ctx.drawImage(this.img,-I/2,-l/2,I,l),this.ctx.restore()}},a}(x),function(){function a(c){this.elem=c}a.prototype.updateValues=function(c){return this.value=c[0],this.maxValue=c[1],this.avgValue=c[2],this.render()},a.prototype.render=function(){var d,c;return this.textField&&this.textField.text(f(this.value)),0===this.maxValue&&(this.maxValue=2*this.avgValue),c=this.value/this.maxValue*100,d=this.avgValue/this.maxValue*100,$(".bar-value",this.elem).css({width:c+"%"}),$(".typical-value",this.elem).css({width:d+"%"})}}(),k=function(c){function a(d){var h,g;this.canvas=d,a.__super__.constructor.call(this),this.percentColors=null,"undefined"!=typeof G_vmlCanvasManager&&(this.canvas=window.G_vmlCanvasManager.initElement(this.canvas)),this.ctx=this.canvas.getContext("2d"),h=this.canvas.clientHeight,g=this.canvas.clientWidth,this.canvas.height=h,this.canvas.width=g,this.gp=[new j(this)],this.setOptions()}return q(a,c),a.prototype.elem=null,a.prototype.value=[20],a.prototype.maxValue=80,a.prototype.minValue=0,a.prototype.displayedAngle=0,a.prototype.displayedValue=0,a.prototype.lineWidth=40,a.prototype.paddingTop=0.1,a.prototype.paddingBottom=0.1,a.prototype.percentColors=null,a.prototype.options={colorStart:"#6fadcf",colorStop:void 0,gradientType:0,strokeColor:"#e0e0e0",pointer:{length:0.8,strokeWidth:0.035,iconScale:1},angle:0.15,lineWidth:0.44,radiusScale:1,fontSize:40,limitMax:!1,limitMin:!1},a.prototype.setOptions=function(g){var i,h,m,l,d;for(null==g&&(g=null),a.__super__.setOptions.call(this,g),this.configPercentColors(),this.extraPadding=0,this.options.angle<0&&(l=Math.PI*(1+this.options.angle),this.extraPadding=Math.sin(l)),this.availableHeight=this.canvas.height*(1-this.paddingTop-this.paddingBottom),this.lineWidth=this.availableHeight*this.options.lineWidth,this.radius=(this.availableHeight-this.lineWidth/2)/(1+this.extraPadding),this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),d=this.gp,h=0,m=d.length;h=r;m=0<=r?++l:--l){d=parseInt(v(this.options.percentColors[m][1]).substring(0,2),16),g=parseInt(v(this.options.percentColors[m][1]).substring(2,4),16),h=parseInt(v(this.options.percentColors[m][1]).substring(4,6),16),p.push(this.percentColors[m]={pct:this.options.percentColors[m][0],color:{r:d,g:g,b:h}})}return p}},a.prototype.set=function(J){var u,H,K,m,I,G,d,o,g;for(J instanceof Array||(J=[J]),H=K=0,d=J.length-1;0<=d?K<=d:K>=d;H=0<=d?++K:--K){J[H]=this.parseValue(J[H])}if(J.length>this.gp.length){for(H=m=0,o=J.length-this.gp.length;0<=o?mo;H=0<=o?++m:--m){u=new j(this),u.setOptions(this.options.pointer),this.gp.push(u)}}else{J.lengththis.maxValue?this.options.limitMax?g=this.maxValue:this.maxValue=g+1:g=p;l=0<=p?++g:--g){if(H<=this.percentColors[l].pct){!0===m?(d=this.percentColors[l-1]||this.percentColors[0],I=this.percentColors[l],G=(H-d.pct)/(I.pct-d.pct),u={r:Math.floor(d.color.r*(1-G)+I.color.r*G),g:Math.floor(d.color.g*(1-G)+I.color.g*G),b:Math.floor(d.color.b*(1-G)+I.color.b*G)}):u=this.percentColors[l].color;break}}}return"rgb("+[u.r,u.g,u.b].join(",")+")"},a.prototype.getColorForValue=function(g,d){var h;return h=(g-this.minValue)/(this.maxValue-this.minValue),this.getColorForPercentage(h,d)},a.prototype.renderStaticLabels=function(Q,I,L,R){var G,p,O,J,m,H,N,P,M,K;for(this.ctx.save(),this.ctx.translate(I,L),G=Q.font||"10px Times",H=/\d+\.?\d?/,m=G.match(H)[0],P=G.slice(m.length),p=parseFloat(m)*this.displayScale,this.ctx.font=p+P,this.ctx.fillStyle=Q.color||"#000000",this.ctx.textBaseline="bottom",this.ctx.textAlign="center",N=Q.labels,O=0,J=N.length;O=this.minValue)&&(!this.options.limitMax||K<=this.maxValue)&&(G=K.font||Q.font,m=G.match(H)[0],P=G.slice(m.length),p=parseFloat(m)*this.displayScale,this.ctx.font=p+P,M=this.getAngle(K.label)-3*Math.PI/2,this.ctx.rotate(M),this.ctx.fillText(f(K.label,Q.fractionDigits),0,-R-this.lineWidth/2),this.ctx.rotate(-M)):(!this.options.limitMin||K>=this.minValue)&&(!this.options.limitMax||K<=this.maxValue)&&(M=this.getAngle(K)-3*Math.PI/2,this.ctx.rotate(M),this.ctx.fillText(f(K,Q.fractionDigits),0,-R-this.lineWidth/2),this.ctx.rotate(-M))}return this.ctx.restore()},a.prototype.renderTicks=function(P,aa,ae,Q){var X,W,ah,ab,T,Z,U,ag,O,af,ac,Y,K,ad,N,J,G,L,H,I,R;if(P!=={}){for(Z=P.divisions||0,H=P.subDivisions||0,ah=P.divColor||"#fff",N=P.subColor||"#fff",ab=P.divLength||0.7,G=P.subLength||0.2,O=parseFloat(this.maxValue)-parseFloat(this.minValue),af=parseFloat(O)/parseFloat(P.divisions),J=parseFloat(af)/parseFloat(P.subDivisions),X=parseFloat(this.minValue),W=0+J,ag=O/400,T=ag*(P.divWidth||1),L=ag*(P.subWidth||1),Y=[],I=U=0,ac=Z+1;U0?Y.push(function(){var g,d,h;for(h=[],ad=g=0,d=H-1;gthis.maxValue&&(G=this.maxValue),O=this.radius*this.options.radiusScale,S.height&&(this.ctx.lineWidth=this.lineWidth*S.height,Q=this.lineWidth/2*(S.offset||1-S.height),O=this.radius*this.options.radiusScale+Q),this.ctx.strokeStyle=S.strokeStyle,this.ctx.beginPath(),this.ctx.arc(0,0,O,this.getAngle(L),this.getAngle(G),!1),this.ctx.stroke()}}else{void 0!==this.options.customFillStyle?M=this.options.customFillStyle(this):null!==this.percentColors?M=this.getColorForValue(this.displayedValue,this.options.generateGradient):void 0!==this.options.colorStop?(M=0===this.options.gradientType?this.ctx.createRadialGradient(K,W,9,K,W,70):this.ctx.createLinearGradient(0,0,K,0),M.addColorStop(0,this.options.colorStart),M.addColorStop(1,this.options.colorStop)):M=this.options.colorStart,this.ctx.strokeStyle=M,this.ctx.beginPath(),this.ctx.arc(K,W,H,(1+this.options.angle)*Math.PI,V,!1),this.ctx.lineWidth=this.lineWidth,this.ctx.stroke(),this.ctx.strokeStyle=this.options.strokeColor,this.ctx.beginPath(),this.ctx.arc(K,W,H,V,(2-this.options.angle)*Math.PI,!1),this.ctx.stroke(),this.ctx.save(),this.ctx.translate(K,W)}for(this.options.renderTicks&&this.renderTicks(this.options.renderTicks,K,W,H),this.ctx.restore(),this.ctx.translate(K,W),U=this.gp,I=0,N=U.length;Ithis.maxValue?this.options.limitMax?this.value=this.maxValue:this.maxValue=this.value:this.valuek;k++){if(m=!0,h=l[k],"x"==i[n]._stackAxis){for(var j=0;j0;q--){p=k[q-1],j[p].show&&(l[p]=j[p].series_p2u(m[p.charAt(0)]))}return{offsets:n,gridPos:m,dataPos:l}}function a(bn,bm){function bl(h,g,l){var k=(g[1]-l[1])/(g[0]-l[0]),j=g[1]-k*g[0],i=h+g[1];return[(i-j)/k,i]}var bk,bj,bi,bh,bg,bf,be,bd,bc,bb,ba,a9,a8,a7,a6,a5,a4,a3,Z,Y=bm.series;for(bi=bm.seriesStack.length-1;bi>=0;bi--){switch(bk=bm.seriesStack[bi],bh=Y[bk],a4=bh._highlightThreshold,bh.renderer.constructor){case a1.jqplot.BarRenderer:for(bf=bn.x,be=bn.y,bj=0;bja5[0][0]&&bfa5[2][1]&&bea5[0][1])){return{seriesIndex:bh.index,pointIndex:bj,gridData:a6,data:bh.data[bj],points:bh._barPoints[bj]}}}break;case a1.jqplot.PyramidRenderer:for(bf=bn.x,be=bn.y,bj=0;bja5[0][0]+a4[0][0]&&bfa5[2][1]&&be0&&-be>=0?bd=2*Math.PI-Math.atan(-be/bf):bf>0&&0>-be?bd=-Math.atan(-be/bf):0>bf?bd=Math.PI-Math.atan(-be/bf):0==bf&&-be>0?bd=3*Math.PI/2:0==bf&&0>-be?bd=Math.PI/2:0==bf&&0==be&&(bd=0),bb&&(bd-=bb,0>bd?bd+=2*Math.PI:bd>2*Math.PI&&(bd-=2*Math.PI)),bc=bh.sliceMargin/180*Math.PI,bgbh._innerRadius){for(bj=0;bj0?bh.gridData[bj-1][1]+bc:bc,a9=bh.gridData[bj][1],bd>ba&&a9>bd){return{seriesIndex:bh.index,pointIndex:bj,gridData:[bn.x,bn.y],data:bh.data[bj]}}}}break;case a1.jqplot.PieRenderer:if(bb=bh.startAngle/180*Math.PI,bf=bn.x-bh._center[0],be=bn.y-bh._center[1],bg=Math.sqrt(Math.pow(bf,2)+Math.pow(be,2)),bf>0&&-be>=0?bd=2*Math.PI-Math.atan(-be/bf):bf>0&&0>-be?bd=-Math.atan(-be/bf):0>bf?bd=Math.PI-Math.atan(-be/bf):0==bf&&-be>0?bd=3*Math.PI/2:0==bf&&0>-be?bd=Math.PI/2:0==bf&&0==be&&(bd=0),bb&&(bd-=bb,0>bd?bd+=2*Math.PI:bd>2*Math.PI&&(bd-=2*Math.PI)),bc=bh.sliceMargin/180*Math.PI,bg0?bh.gridData[bj-1][1]+bc:bc,a9=bh.gridData[bj][1],bd>ba&&a9>bd){return{seriesIndex:bh.index,pointIndex:bj,gridData:[bn.x,bn.y],data:bh.data[bj]}}}}break;case a1.jqplot.BubbleRenderer:bf=bn.x,be=bn.y;var X=null;if(bh.show){for(var bj=0;bj=a7||null==a8)&&(a8=a7,X={seriesIndex:bk,pointIndex:bj,gridData:a6,data:bh.data[bj]})}if(null!=X){return X}}break;case a1.jqplot.FunnelRenderer:bf=bn.x,be=bn.y;var W,V,U,T=bh._vertices,S=T[0],R=T[T.length-1];for(W=bl(be,S[0],R[3]),V=bl(be,S[1],R[2]),bj=0;bj=U[0][1]&&be<=U[3][1]&&bf>=W[0]&&bf<=V[0]){return{seriesIndex:bh.index,pointIndex:bj,gridData:null,data:bh.data[bj]}}}break;case a1.jqplot.LineRenderer:if(bf=bn.x,be=bn.y,bg=bh.renderer,bh.show){if(!(!(bh.fill||bh.renderer.bands.show&&bh.renderer.bands.fill)||bm.plugins.highlighter&&bm.plugins.highlighter.show)){var Q=!1;if(bf>bh._boundingBox[0][0]&&bfbh._boundingBox[1][1]&&beP;P++){var N=[bh._areaPoints[P][0],bh._areaPoints[P][1]],M=[bh._areaPoints[bj][0],bh._areaPoints[bj][1]];(N[1]=be||M[1]=be)&&N[0]+(be-N[1])/(M[1]-N[1])*(M[0]-N[0])0?Z:0;for(var bj=0;bj=a6[0]-bg._bodyWidth/2&&bf<=a6[0]+bg._bodyWidth/2&&be>=L(bh.data[bj][2])&&be<=L(bh.data[bj][3])){return{seriesIndex:bk,pointIndex:bj,gridData:a6,data:bh.data[bj]}}}else{if(bg.hlc){var L=bh._yaxis.series_u2p;if(bf>=a6[0]-bg._tickLength&&bf<=a6[0]+bg._tickLength&&be>=L(bh.data[bj][1])&&be<=L(bh.data[bj][2])){return{seriesIndex:bk,pointIndex:bj,gridData:a6,data:bh.data[bj]}}}else{var L=bh._yaxis.series_u2p;if(bf>=a6[0]-bg._tickLength&&bf<=a6[0]+bg._tickLength&&be>=L(bh.data[bj][2])&&be<=L(bh.data[bj][3])){return{seriesIndex:bk,pointIndex:bj,gridData:a6,data:bh.data[bj]}}}}}else{if(null!=a6[0]&&null!=a6[1]&&(a7=Math.sqrt((bf-a6[0])*(bf-a6[0])+(be-a6[1])*(be-a6[1])),a3>=a7&&(a8>=a7||null==a8))){return a8=a7,{seriesIndex:bk,pointIndex:bj,gridData:a6,data:bh.data[bj]}}}}}break;default:if(bf=bn.x,be=bn.y,bg=bh.renderer,bh.show){Z=bh.markerRenderer.size/2+bh.neighborThreshold,a3=Z>0?Z:0;for(var bj=0;bj=a6[0]-bg._bodyWidth/2&&bf<=a6[0]+bg._bodyWidth/2&&be>=L(bh.data[bj][2])&&be<=L(bh.data[bj][3])){return{seriesIndex:bk,pointIndex:bj,gridData:a6,data:bh.data[bj]}}}else{if(bg.hlc){var L=bh._yaxis.series_u2p;if(bf>=a6[0]-bg._tickLength&&bf<=a6[0]+bg._tickLength&&be>=L(bh.data[bj][1])&&be<=L(bh.data[bj][2])){return{seriesIndex:bk,pointIndex:bj,gridData:a6,data:bh.data[bj]}}}else{var L=bh._yaxis.series_u2p;if(bf>=a6[0]-bg._tickLength&&bf<=a6[0]+bg._tickLength&&be>=L(bh.data[bj][2])&&be<=L(bh.data[bj][3])){return{seriesIndex:bk,pointIndex:bj,gridData:a6,data:bh.data[bj]}}}}}else{if(a7=Math.sqrt((bf-a6[0])*(bf-a6[0])+(be-a6[1])*(be-a6[1])),a3>=a7&&(a8>=a7||null==a8)){return a8=a7,{seriesIndex:bk,pointIndex:bj,gridData:a6,data:bh.data[bj]}}}}}}}return null}this.animate=!1,this.animateReplot=!1,this.axes={xaxis:new a0("xaxis"),yaxis:new a0("yaxis"),x2axis:new a0("x2axis"),y2axis:new a0("y2axis"),y3axis:new a0("y3axis"),y4axis:new a0("y4axis"),y5axis:new a0("y5axis"),y6axis:new a0("y6axis"),y7axis:new a0("y7axis"),y8axis:new a0("y8axis"),y9axis:new a0("y9axis"),yMidAxis:new a0("yMidAxis")},this.baseCanvas=new a1.jqplot.GenericCanvas,this.captureRightClick=!1,this.data=[],this.dataRenderer,this.dataRendererOptions,this.defaults={axesDefaults:{},axes:{xaxis:{},yaxis:{},x2axis:{},y2axis:{},y3axis:{},y4axis:{},y5axis:{},y6axis:{},y7axis:{},y8axis:{},y9axis:{},yMidAxis:{}},seriesDefaults:{},series:[]},this.defaultAxisStart=1,this.drawIfHidden=!1,this.eventCanvas=new a1.jqplot.GenericCanvas,this.fillBetween={series1:null,series2:null,color:null,baseSeries:0,fill:!0},this.fontFamily,this.fontSize,this.grid=new aW,this.legend=new aZ,this.noDataIndicator={show:!1,indicator:"Loading Data...",axes:{xaxis:{min:0,max:10,tickInterval:2,show:!0},yaxis:{min:0,max:12,tickInterval:3,show:!0}}},this.negativeSeriesColors=a1.jqplot.config.defaultNegativeColors,this.options={},this.previousSeriesStack=[],this.plugins={},this.series=[],this.seriesStack=[],this.seriesColors=a1.jqplot.config.defaultColors,this.sortData=!0,this.stackSeries=!1,this.syncXTicks=!0,this.syncYTicks=!0,this.target=null,this.targetId=null,this.textColor,this.title=new aY,this._drawCount=0,this._sumy=0,this._sumx=0,this._stackData=[],this._plotData=[],this._width=null,this._height=null,this._plotDimensions={height:null,width:null},this._gridPadding={top:null,right:null,bottom:null,left:null},this._defaultGridPadding={top:10,right:10,bottom:23,left:10},this._addDomReference=a1.jqplot.config.addDomReference,this.preInitHooks=new a1.jqplot.HooksManager,this.postInitHooks=new a1.jqplot.HooksManager,this.preParseOptionsHooks=new a1.jqplot.HooksManager,this.postParseOptionsHooks=new a1.jqplot.HooksManager,this.preDrawHooks=new a1.jqplot.HooksManager,this.postDrawHooks=new a1.jqplot.HooksManager,this.preDrawSeriesHooks=new a1.jqplot.HooksManager,this.postDrawSeriesHooks=new a1.jqplot.HooksManager,this.preDrawLegendHooks=new a1.jqplot.HooksManager,this.addLegendRowHooks=new a1.jqplot.HooksManager,this.preSeriesInitHooks=new a1.jqplot.HooksManager,this.postSeriesInitHooks=new a1.jqplot.HooksManager,this.preParseSeriesOptionsHooks=new a1.jqplot.HooksManager,this.postParseSeriesOptionsHooks=new a1.jqplot.HooksManager,this.eventListenerHooks=new a1.jqplot.EventListenerManager,this.preDrawSeriesShadowHooks=new a1.jqplot.HooksManager,this.postDrawSeriesShadowHooks=new a1.jqplot.HooksManager,this.colorGenerator=new a1.jqplot.ColorGenerator,this.negativeColorGenerator=new a1.jqplot.ColorGenerator,this.canvasManager=new a1.jqplot.CanvasManager,this.themeEngine=new a1.jqplot.ThemeEngine;this.init=function(z,y,x){x=x||{};for(var w=0;ww;w++){this.axes[au[w]]=new a0(au[w])}if(this._plotDimensions.height=this._height,this._plotDimensions.width=this._width,this.grid._plotDimensions=this._plotDimensions,this.title._plotDimensions=this._plotDimensions,this.baseCanvas._plotDimensions=this._plotDimensions,this.eventCanvas._plotDimensions=this._plotDimensions,this.legend._plotDimensions=this._plotDimensions,this._height<=0||this._width<=0||!this._height||!this._width){throw new Error("Canvas dimension not set")}if(x.dataRenderer&&a1.isFunction(x.dataRenderer)&&(x.dataRendererOptions&&(this.dataRendererOptions=x.dataRendererOptions),this.dataRenderer=x.dataRenderer,y=this.dataRenderer(y,this,this.dataRendererOptions)),x.noDataIndicator&&a1.isPlainObject(x.noDataIndicator)&&a1.extend(!0,this.noDataIndicator,x.noDataIndicator),null==y||0==a1.isArray(y)||0==y.length||0==a1.isArray(y[0])||0==y[0].length){if(0==this.noDataIndicator.show){throw new Error("No data specified")}for(var s in this.noDataIndicator.axes){for(var r in this.noDataIndicator.axes[s]){this.axes[s][r]=this.noDataIndicator.axes[s][r]}}this.postDrawHooks.add(function(){var i=this.eventCanvas.getHeight(),n=this.eventCanvas.getWidth(),m=a1('
');this.target.append(m),m.height(i),m.width(n),m.css("top",this.eventCanvas._offsets.top),m.css("left",this.eventCanvas._offsets.left);var l=a1('
');m.append(l),l.html(this.noDataIndicator.indicator);var k=l.height(),j=l.width();l.height(k),l.width(j),l.css("top",(i-k)/2+"px")})}this.data=a1.extend(!0,[],y),this.parseOptions(x),this.textColor&&this.target.css("color",this.textColor),this.fontFamily&&this.target.css("font-family",this.fontFamily),this.fontSize&&this.target.css("font-size",this.fontSize),this.title.init(),this.legend.init(),this._sumy=0,this._sumx=0,this.computePlotData();for(var w=0;ww;w++){p=au[w],h=this.axes[p],h._plotDimensions=this._plotDimensions,h.init(),null==this.axes[p].borderColor&&("x"!==p.charAt(0)&&h.useSeriesColor===!0&&h.show?h.borderColor=h._series[0].color:h.borderColor=this.grid.borderColor)}this.sortData&&c(this.series),this.grid.init(),this.grid._axes=this.axes,this.legend._series=this.series;for(var w=0;ww;w++){v=au[w],s=this.axes[v],u=s._ticks;for(var t=0,q=u.length;q>t;t++){var h=u[t]._elem;h&&(a1.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==av&&window.G_vmlCanvasManager.uninitElement(h.get(0)),h.emptyForce(),h=null,u._elem=null)}u=null,delete s.ticks,delete s._ticks,this.axes[v]=new a0(v),this.axes[v]._plotWidth=this._width,this.axes[v]._plotHeight=this._height}B&&(z.dataRenderer&&a1.isFunction(z.dataRenderer)&&(z.dataRendererOptions&&(this.dataRendererOptions=z.dataRendererOptions),this.dataRenderer=z.dataRenderer,B=this.dataRenderer(B,this,this.dataRendererOptions)),this.data=a1.extend(!0,[],B)),A&&this.parseOptions(z),this.title._plotWidth=this._width,this.textColor&&this.target.css("color",this.textColor),this.fontFamily&&this.target.css("font-family",this.fontFamily),this.fontSize&&this.target.css("font-size",this.fontSize),this.title.init(),this.legend.init(),this._sumy=0,this._sumx=0,this.seriesStack=[],this.previousSeriesStack=[],this.computePlotData();for(var w=0,r=this.series.length;r>w;w++){this.seriesStack.push(w),this.previousSeriesStack.push(w),this.series[w].shadowCanvas._plotDimensions=this._plotDimensions,this.series[w].canvas._plotDimensions=this._plotDimensions;for(var t=0;tw;w++){v=au[w],s=this.axes[v],s._plotDimensions=this._plotDimensions,s.init(),null==s.borderColor&&("x"!==v.charAt(0)&&s.useSeriesColor===!0&&s.show?s.borderColor=s._series[0].color:s.borderColor=this.grid.borderColor)}this.sortData&&c(this.series),this.grid.init(),this.grid._axes=this.axes,this.legend._series=this.series;for(var w=0,r=a1.jqplot.postInitHooks.length;r>w;w++){a1.jqplot.postInitHooks[w].call(this,y,this.data,z)}for(var w=0,r=this.postInitHooks.hooks.length;r>w;w++){this.postInitHooks.hooks[w].call(this,y,this.data,z)}},this.quickInit=function(){if(this._height=this.target.height(),this._width=this.target.width(),this._height<=0||this._width<=0||!this._height||!this._width){throw new Error("Target dimension not set")}this._plotDimensions.height=this._height,this._plotDimensions.width=this._width,this.grid._plotDimensions=this._plotDimensions,this.title._plotDimensions=this._plotDimensions,this.baseCanvas._plotDimensions=this._plotDimensions,this.eventCanvas._plotDimensions=this._plotDimensions,this.legend._plotDimensions=this._plotDimensions;for(var h in this.axes){this.axes[h]._plotWidth=this._width,this.axes[h]._plotHeight=this._height}this.title._plotWidth=this._width,this.textColor&&this.target.css("color",this.textColor),this.fontFamily&&this.target.css("font-family",this.fontFamily),this.fontSize&&this.target.css("font-size",this.fontSize),this._sumy=0,this._sumx=0,this.computePlotData();for(var m=0;mk;k++){l=au[k];for(var j=this.axes[l]._ticks,m=0;mx;x++){y=this.series[x],this._plotData.push([]),this._stackData.push([]);var v=y.data;this._plotData[x]=a1.extend(!0,[],v),this._stackData[x]=a1.extend(!0,[],v),y._plotData=this._plotData[x],y._stackData=this._stackData[x];var u={x:[],y:[]};if(this.stackSeries&&!y.disableStack){y._stack=!0;for(var t="x"===y._stackAxis?0:1,s=0,r=v.length;r>s;s++){var q=v[s][t];if(null==q&&(q=0),this._plotData[x][s][t]=q,this._stackData[x][s][t]=q,x>0){for(var p=x;p--;){var o=this._plotData[p][s][t];if(q*o>=0){this._plotData[x][s][t]+=o,this._stackData[x][s][t]+=o;break}}}}}else{for(var n=0;n0&&(y._prevPlotData=this.series[x-1]._plotData),y._sumy=0,y._sumx=0,n=y.data.length-1;n>-1;n--){y._sumy+=y.data[n][1],y._sumx+=y.data[n][0]}}},this.populatePlotData=function(C,B){this._plotData=[],this._stackData=[],C._stackData=[],C._plotData=[];var A={x:[],y:[]};if(this.stackSeries&&!C.disableStack){C._stack=!0;for(var z,y,x,w,v="x"===C._stackAxis?0:1,u=a1.extend(!0,[],C.data),t=a1.extend(!0,[],C.data),s=0;B>s;s++){for(var r=this.series[s].data,q=0;q=0&&(t[q][v]+=w)}}for(var p=0;p0&&(C._prevPlotData=this.series[B-1]._plotData),C._sumy=0,C._sumx=0,p=C.data.length-1;p>-1;p--){C._sumy+=C.data[p][1],C._sumx+=C.data[p][0]}},this.getNextSeriesColor=function(e){var d=0,f=e.seriesColors;return function(){return dx;x++){v=u[x],null!=w.fillBetween[v]&&(this.fillBetween[v]=w.fillBetween[v])}}w.seriesColors&&(this.seriesColors=w.seriesColors),w.negativeSeriesColors&&(this.negativeSeriesColors=w.negativeSeriesColors),w.captureRightClick&&(this.captureRightClick=w.captureRightClick),this.defaultAxisStart=y&&null!=y.defaultAxisStart?y.defaultAxisStart:this.defaultAxisStart,this.colorGenerator.setColors(this.seriesColors),this.negativeColorGenerator.setColors(this.negativeSeriesColors),a1.extend(!0,this._gridPadding,w.gridPadding),this.sortData=null!=w.sortData?w.sortData:this.sortData;for(var x=0;12>x;x++){var s=au[x],r=this.axes[s];r._options=a1.extend(!0,{},w.axesDefaults,w.axes[s]),a1.extend(!0,r,w.axesDefaults,w.axes[s]),r._plotWidth=this._width,r._plotHeight=this._height}var q=function(h,m,l){var k,j,i=[];if(m=m||"vertical",a1.isArray(h[0])){a1.extend(!0,i,h)}else{for(k=0,j=h.length;j>k;k++){"vertical"==m?i.push([l+k,h[k]]):i.push([h[k],l+k])}}return i};this.series=[];for(var x=0;xx;x++){var s=au[x],r=this.axes[s];null==r.borderWidth&&(r.borderWidth=this.grid.borderWidth)}"string"==typeof this.options.title?this.title.text=this.options.title:"object"==typeof this.options.title&&a1.extend(!0,this.title,this.options.title),this.title._plotWidth=this._width,this.legend.setOptions(this.options.legend);for(var x=0;xh;h++){this._sumy+=this.series[h]._sumy,this._sumx+=this.series[h]._sumx}this.draw(),this.target.trigger("jqplotPostRedraw")},this.draw=function(){if(this.drawIfHidden||this.target.is(":visible")){this.target.trigger("jqplotPreDraw");var a9,a8,a7;for(a9=0,a7=a1.jqplot.preDrawHooks.length;a7>a9;a9++){a1.jqplot.preDrawHooks[a9].call(this)}for(a9=0,a7=this.preDrawHooks.hooks.length;a7>a9;a9++){this.preDrawHooks.hooks[a9].apply(this,this.preDrawSeriesHooks.args[a9])}this.target.append(this.baseCanvas.createElement({left:0,right:0,top:0,bottom:0},"jqplot-base-canvas",null,this)),this.baseCanvas.setContext(),this.target.append(this.title.draw()),this.title.pack({top:0,left:0});var a6=this.legend.draw({},this),a5={top:0,left:0,bottom:0,right:0};if("outsideGrid"==this.legend.placement){switch(this.target.append(a6),this.legend.location){case"n":a5.top+=this.legend.getHeight();break;case"s":a5.bottom+=this.legend.getHeight();break;case"ne":case"e":case"se":a5.right+=this.legend.getWidth();break;case"nw":case"w":case"sw":a5.left+=this.legend.getWidth();break;default:a5.right+=this.legend.getWidth()}a6=a6.detach()}var a4,a3=this.axes;for(a9=0;12>a9;a9++){a4=au[a9],this.target.append(a3[a4].draw(this.baseCanvas._ctx,this)),a3[a4].set()}a3.yaxis.show&&(a5.left+=a3.yaxis.getWidth());var Z,Y=["y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis"],X=[0,0,0,0,0,0,0,0],W=0;for(Z=0;8>Z;Z++){a3[Y[Z]].show&&(W+=a3[Y[Z]].getWidth(),X[Z]=W)}if(a5.right+=W,a3.x2axis.show&&(a5.top+=a3.x2axis.getHeight()),this.title.show&&(a5.top+=this.title.getHeight()),a3.xaxis.show&&(a5.bottom+=a3.xaxis.getHeight()),this.options.gridDimensions&&a1.isPlainObject(this.options.gridDimensions)){var V=parseInt(this.options.gridDimensions.width,10)||0,U=parseInt(this.options.gridDimensions.height,10)||0,T=(this._width-a5.left-a5.right-V)/2,S=(this._height-a5.top-a5.bottom-U)/2;S>=0&&T>=0&&(a5.top+=S,a5.bottom+=S,a5.left+=T,a5.right+=T)}var Q=["top","bottom","left","right"];for(var Z in Q){null==this._gridPadding[Q[Z]]&&a5[Q[Z]]>0?this._gridPadding[Q[Z]]=a5[Q[Z]]:null==this._gridPadding[Q[Z]]&&(this._gridPadding[Q[Z]]=this._defaultGridPadding[Q[Z]])}var O=this._gridPadding;for("outsideGrid"===this.legend.placement&&(O={top:this.title.getHeight(),left:0,right:0,bottom:0},"s"===this.legend.location&&(O.left=this._gridPadding.left,O.right=this._gridPadding.right)),a3.xaxis.pack({position:"absolute",bottom:this._gridPadding.bottom-a3.xaxis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right}),a3.yaxis.pack({position:"absolute",top:0,left:this._gridPadding.left-a3.yaxis.getWidth(),height:this._height},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top}),a3.x2axis.pack({position:"absolute",top:this._gridPadding.top-a3.x2axis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right}),a9=8;a9>0;a9--){a3[Y[a9-1]].pack({position:"absolute",top:0,right:this._gridPadding.right-X[a9-1]},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top})}var M=(this._width-this._gridPadding.left-this._gridPadding.right)/2+this._gridPadding.left-a3.yMidAxis.getWidth()/2;a3.yMidAxis.pack({position:"absolute",top:0,left:M,zIndex:9,textAlign:"center"},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top}),this.target.append(this.grid.createElement(this._gridPadding,this)),this.grid.draw();var K=this.series,J=K.length;for(a9=0,a7=J;a7>a9;a9++){a8=this.seriesStack[a9],this.target.append(K[a8].shadowCanvas.createElement(this._gridPadding,"jqplot-series-shadowCanvas",null,this)),K[a8].shadowCanvas.setContext(),K[a8].shadowCanvas._elem.data("seriesIndex",a8)}for(a9=0,a7=J;a7>a9;a9++){a8=this.seriesStack[a9],this.target.append(K[a8].canvas.createElement(this._gridPadding,"jqplot-series-canvas",null,this)),K[a8].canvas.setContext(),K[a8].canvas._elem.data("seriesIndex",a8)}this.target.append(this.eventCanvas.createElement(this._gridPadding,"jqplot-event-canvas",null,this)),this.eventCanvas.setContext(),this.eventCanvas._ctx.fillStyle="rgba(0,0,0,0)",this.eventCanvas._ctx.fillRect(0,0,this.eventCanvas._ctx.canvas.width,this.eventCanvas._ctx.canvas.height),this.bindCustomEvents(),this.legend.preDraw?(this.eventCanvas._elem.before(a6),this.legend.pack(O),this.legend._elem?this.drawSeries({legendInfo:{location:this.legend.location,placement:this.legend.placement,width:this.legend.getWidth(),height:this.legend.getHeight(),xoffset:this.legend.xoffset,yoffset:this.legend.yoffset}}):this.drawSeries()):(this.drawSeries(),J&&a1(K[J-1].canvas._elem).after(a6),this.legend.pack(O));for(var a9=0,a7=a1.jqplot.eventListenerHooks.length;a7>a9;a9++){this.eventCanvas._elem.bind(a1.jqplot.eventListenerHooks[a9][0],{plot:this},a1.jqplot.eventListenerHooks[a9][1])}for(var a9=0,a7=this.eventListenerHooks.hooks.length;a7>a9;a9++){this.eventCanvas._elem.bind(this.eventListenerHooks.hooks[a9][0],{plot:this},this.eventListenerHooks.hooks[a9][1])}var I=this.fillBetween;if("number"==typeof I.series1){I.fill&&I.series1!==I.series2&&I.series1G&&J>F&&"line"===K[G]._type&&"line"===K[F]._type)){H=!1;break}H=!0}}I.fill&&H&&this.doFillBetweenLines()}}for(var a9=0,a7=a1.jqplot.postDrawHooks.length;a7>a9;a9++){a1.jqplot.postDrawHooks[a9].call(this)}for(var a9=0,a7=this.postDrawHooks.hooks.length;a7>a9;a9++){this.postDrawHooks.hooks[a9].apply(this,this.postDrawHooks.args[a9])}this.target.is(":visible")&&(this._drawCount+=1);var R,P,N,L;for(a9=0,a7=J;a7>a9;a9++){R=K[a9],P=R.renderer,N=".jqplot-point-label.jqplot-series-"+a9,P.animation&&P.animation._supported&&P.animation.show&&(this._drawCount<2||this.animateReplot)&&(L=this.target.find(N),L.stop(!0,!0).hide(),R.canvas._elem.stop(!0,!0).hide(),R.shadowCanvas._elem.stop(!0,!0).hide(),R.canvas._elem.jqplotEffect("blind",{mode:"show",direction:P.animation.direction},P.animation.speed),R.shadowCanvas._elem.jqplotEffect("blind",{mode:"show",direction:P.animation.direction},P.animation.speed),L.fadeIn(0.8*P.animation.speed))}L=null,this.target.trigger("jqplotPostDraw",[this])}},aV.prototype.doFillBetweenLines=function(){function j(y,x){var w=p[y],v=p[x];if(v.renderer.smooth){var u=v.renderer._smoothedData.slice(0).reverse()}else{var u=v.gridData.slice(0).reverse()}if(w.renderer.smooth){var t=w.renderer._smoothedData.concat(u)}else{var t=w.gridData.concat(u)}var s=null!==i.color?i.color:p[o].fillColor,r=null!==i.baseSeries?i.baseSeries:y,q=p[r].renderer.shapeRenderer,d={fillStyle:s,fill:!0,closePath:!0};q.draw(w.shadowCanvas._ctx,t,d)}var i=this.fillBetween,p=this.series,o=i.series1,n=i.series2,m=0,l=0;if("number"==typeof o&&"number"==typeof n){m=n>o?o:n,l=n>o?n:o,j(m,l)}else{for(var k=0;ko[k]?n[k]:o[k],j(m,l)}}},this.bindCustomEvents=function(){this.eventCanvas._elem.bind("click",{plot:this},this.onClick),this.eventCanvas._elem.bind("dblclick",{plot:this},this.onDblClick),this.eventCanvas._elem.bind("mousedown",{plot:this},this.onMouseDown),this.eventCanvas._elem.bind("mousemove",{plot:this},this.onMouseMove),this.eventCanvas._elem.bind("mouseenter",{plot:this},this.onMouseEnter),this.eventCanvas._elem.bind("mouseleave",{plot:this},this.onMouseLeave),this.captureRightClick?(this.eventCanvas._elem.bind("mouseup",{plot:this},this.onRightClick),this.eventCanvas._elem.get(0).oncontextmenu=function(){return !1}):this.eventCanvas._elem.bind("mouseup",{plot:this},this.onMouseUp)},this.onClick=function(g){var k=b(g),j=g.data.plot,i=a(k.gridPos,j),h=a1.Event("jqplotClick");h.pageX=g.pageX,h.pageY=g.pageY,a1(this).trigger(h,[k.gridPos,k.dataPos,i,j])},this.onDblClick=function(g){var k=b(g),j=g.data.plot,i=a(k.gridPos,j),h=a1.Event("jqplotDblClick");h.pageX=g.pageX,h.pageY=g.pageY,a1(this).trigger(h,[k.gridPos,k.dataPos,i,j])},this.onMouseDown=function(g){var k=b(g),j=g.data.plot,i=a(k.gridPos,j),h=a1.Event("jqplotMouseDown");h.pageX=g.pageX,h.pageY=g.pageY,a1(this).trigger(h,[k.gridPos,k.dataPos,i,j])},this.onMouseUp=function(e){var g=b(e),f=a1.Event("jqplotMouseUp");f.pageX=e.pageX,f.pageY=e.pageY,a1(this).trigger(f,[g.gridPos,g.dataPos,null,e.data.plot])},this.onRightClick=function(g){var k=b(g),j=g.data.plot,i=a(k.gridPos,j);if(j.captureRightClick){if(3==g.which){var h=a1.Event("jqplotRightClick");h.pageX=g.pageX,h.pageY=g.pageY,a1(this).trigger(h,[k.gridPos,k.dataPos,i,j])}else{var h=a1.Event("jqplotMouseUp");h.pageX=g.pageX,h.pageY=g.pageY,a1(this).trigger(h,[k.gridPos,k.dataPos,i,j])}}},this.onMouseMove=function(g){var k=b(g),j=g.data.plot,i=a(k.gridPos,j),h=a1.Event("jqplotMouseMove");h.pageX=g.pageX,h.pageY=g.pageY,a1(this).trigger(h,[k.gridPos,k.dataPos,i,j])},this.onMouseEnter=function(f){var i=b(f),h=f.data.plot,g=a1.Event("jqplotMouseEnter");g.pageX=f.pageX,g.pageY=f.pageY,g.relatedTarget=f.relatedTarget,a1(this).trigger(g,[i.gridPos,i.dataPos,null,h])},this.onMouseLeave=function(f){var i=b(f),h=f.data.plot,g=a1.Event("jqplotMouseLeave");g.pageX=f.pageX,g.pageY=f.pageY,g.relatedTarget=f.relatedTarget,a1(this).trigger(g,[i.gridPos,i.dataPos,null,h])},this.drawSeries=function(g,k){var j,i,h;if(k="number"==typeof g&&null==k?g:k,g="object"==typeof g?g:{},k!=av){i=this.series[k],h=i.shadowCanvas._ctx,h.clearRect(0,0,h.canvas.width,h.canvas.height),i.drawShadow(h,g,this),h=i.canvas._ctx,h.clearRect(0,0,h.canvas.width,h.canvas.height),i.draw(h,g,this),i.renderer.constructor==a1.jqplot.BezierCurveRenderer&&kP;P++){R.push(a4[P][1]),Q.push(a4[P][0])}for(var N,L,J,I,H=a4.length-1,G=1,F=a4.length;F>G;G++){for(var E=[],D=[],C=0;2>C;C++){var P=G-1+C;0==P||P==H?E[C]=Math.pow(10,10):R[P+1]-R[P]==0||R[P]-R[P-1]==0?E[C]=0:(Q[P+1]-Q[P])/(R[P+1]-R[P])+(Q[P]-Q[P-1])/(R[P]-R[P-1])==0?E[C]=0:(R[P+1]-R[P])*(R[P]-R[P-1])<0?E[C]=0:E[C]=2/(a3(Q[P+1],Q[P])/(R[P+1]-R[P])+a3(Q[P],Q[P-1])/(R[P]-R[P-1]))}1==G?E[0]=1.5*(R[1]-R[0])/a3(Q[1],Q[0])-E[1]/2:G==H&&(E[1]=1.5*(R[H]-R[H-1])/a3(Q[H],Q[H-1])-E[0]/2),D[0]=-2*(E[1]+2*E[0])/a3(Q[G],Q[G-1])+6*(R[G]-R[G-1])/Math.pow(a3(Q[G],Q[G-1]),2),D[1]=2*(2*E[1]+E[0])/a3(Q[G],Q[G-1])-6*(R[G]-R[G-1])/Math.pow(a3(Q[G],Q[G-1]),2),I=1/6*(D[1]-D[0])/a3(Q[G],Q[G-1]),J=0.5*(Q[G]*D[0]-Q[G-1]*D[1])/a3(Q[G],Q[G-1]),L=(R[G]-R[G-1]-J*(Math.pow(Q[G],2)-Math.pow(Q[G-1],2))-I*(Math.pow(Q[G],3)-Math.pow(Q[G-1],3)))/a3(Q[G],Q[G-1]),N=R[G-1]-L*Q[G-1]-J*Math.pow(Q[G-1],2)-I*Math.pow(Q[G-1],3);for(var h,M,K=(Q[G]-Q[G-1])/V,C=0,O=V;O>C;C++){h=[],M=Q[G-1]+C*K,h.push(M),h.push(N+L*M+J*Math.pow(M,2)+I*Math.pow(M,3)),T.push(h),S.push([X(h[0]),W(h[1])])}}return T.push(a4[P]),S.push([X(a4[P][0]),W(a4[P][1])]),[T,S]}function aR(bm){var bl,bk,bj,bi,bh,bg,bf,be,bd,bc,bb,ba,a9,a8,a7,a6,a5,a4,a3=this.renderer.smooth,Z=this.renderer.tension,Y=this.canvas.getWidth(),X=this._xaxis.series_p2u,W=this._yaxis.series_p2u,V=null,U=null,T=null,S=null,R=null,Q=null,P=null,O=bm.length/Y,N=[],M=[];V=isNaN(parseFloat(a3))?aU(O,0.5):parseFloat(a3),isNaN(parseFloat(Z))||(Z=parseFloat(Z));for(var i=0,h=bm.length-1;h>i;i++){for(null===Z?(R=Math.abs((bm[i+1][1]-bm[i][1])/(bm[i+1][0]-bm[i][0])),a8=0.3,a7=0.6,a6=(a7-a8)/2,a5=2.5,a4=-1.4,P=R/a5+a4,T=a6*aT(P)-a6*aT(a4)+a8,i>0&&(Q=Math.abs((bm[i][1]-bm[i-1][1])/(bm[i][0]-bm[i-1][0]))),P=Q/a5+a4,S=a6*aT(P)-a6*aT(a4)+a8,U=(T+S)/2):U=Z,bl=0;V>bl;bl++){bk=bl/V,bj=(1+2*bk)*Math.pow(1-bk,2),bi=bk*Math.pow(1-bk,2),bh=Math.pow(bk,2)*(3-2*bk),bg=Math.pow(bk,2)*(bk-1),bm[i-1]?(bf=U*(bm[i+1][0]-bm[i-1][0]),be=U*(bm[i+1][1]-bm[i-1][1])):(bf=U*(bm[i+1][0]-bm[i][0]),be=U*(bm[i+1][1]-bm[i][1])),bm[i+2]?(bd=U*(bm[i+2][0]-bm[i][0]),bc=U*(bm[i+2][1]-bm[i][1])):(bd=U*(bm[i+1][0]-bm[i][0]),bc=U*(bm[i+1][1]-bm[i][1])),bb=bj*bm[i][0]+bh*bm[i+1][0]+bi*bf+bg*bd,ba=bj*bm[i][1]+bh*bm[i+1][1]+bi*be+bg*bc,a9=[bb,ba],N.push(a9),M.push([X(bb),W(ba)])}}return N.push(bm[h]),M.push([X(bm[h][0]),W(bm[h][1])]),[N,M]}function aQ(a,h,g){for(var f=0;f=10){d="%d"}else{if(e>1){d=e===parseInt(e,10)?"%d":"%.1f"}else{var f=-Math.floor(Math.log(e)/Math.LN10);d="%."+f+"f"}}return d}function aG(H,G,F){for(var E,D,C,B,A,z,y,x=Math.floor(F/2),w=Math.ceil(1.5*F),v=Number.MAX_VALUE,u=G-H,t=a1.jqplot.getSignificantFigures,s=0,a=w-x+1;a>s;s++){z=x+s,E=u/(z-1),D=t(E),E=Math.abs(F-z)+D.digitsRight,v>E?(v=E,C=z,y=D.digitsRight):E===v&&D.digitsRightj?i>5?10*j:i>2?5*j:i>1?2*j:j:i>5?10*j:i>4?5*j:i>3?4*j:i>2?3*j:i>1?2*j:j}function aE(h,g){g=g||1;var l,k=Math.floor(Math.log(h)/Math.LN10),j=Math.pow(10,k),i=h/j;return i/=g,l=0.38>=i?0.1:1.6>=i?0.2:4>=i?0.5:8>=i?1:16>=i?2:5,l*j}function aD(i,h){var n,m,l=Math.floor(Math.log(i)/Math.LN10),k=Math.pow(10,l),j=i/k;return j/=h,m=0.38>=j?0.1:1.6>=j?0.2:4>=j?0.5:8>=j?1:16>=j?2:5,n=m*k,[n,m,k]}function aC(d,c){return d-c}function aA(e){if(null==e||"object"!=typeof e){return e}var d=new e.constructor;for(var f in e){d[f]=aA(e[f])}return d}function az(e,d){if(null!=d&&"object"==typeof d){for(var f in d){"highlightColors"==f&&(e[f]=aA(d[f])),null!=d[f]&&"object"==typeof d[f]?(e.hasOwnProperty(f)||(e[f]={}),az(e[f],d[f])):e[f]=d[f]}}}function ay(f,e){if(e.indexOf){return e.indexOf(f)}for(var h=0,g=e.length;g>h;h++){if(e[h]===f){return h}}return -1}function ax(b){return null===b?"[object Null]":Object.prototype.toString.call(b)}function aw(a,h,g,f){return a1.isPlainObject(a)?a:(a={effect:a},h===av&&(h={}),a1.isFunction(h)&&(f=h,g=null,h={}),("number"===a1.type(h)||a1.fx.speeds[h])&&(f=g,g=h,h={}),a1.isFunction(g)&&(f=g,g=null),h&&a1.extend(a,h),g=g||h.duration,a.duration=a1.fx.off?0:"number"==typeof g?g:g in a1.fx.speeds?a1.fx.speeds[g]:a1.fx.speeds._default,a.complete=f||h.complete,a)}var av;a1.fn.emptyForce=function(){for(var a,d=0;null!=(a=a1(this)[d]);d++){if(1===a.nodeType&&a1.cleanData(a.getElementsByTagName("*")),a1.jqplot.use_excanvas){a.outerHTML=""}else{for(;a.firstChild;){a.removeChild(a.firstChild)}}a=null}return a1(this)},a1.fn.removeChildForce=function(b){for(;b.firstChild;){this.removeChildForce(b.firstChild),b.removeChild(b.firstChild)}},a1.fn.jqplot=function(){for(var a=[],h=[],g=0,f=arguments.length;f>g;g++){a1.isArray(arguments[g])?a.push(arguments[g]):a1.isPlainObject(arguments[g])&&h.push(arguments[g])}return this.each(function(q){var p,o,n,m,l=a1(this),c=a.length,b=h.length;n=c>q?a[q]:c?a[c-1]:null,m=b>q?h[q]:b?h[b-1]:null,p=l.attr("id"),p===av&&(p="jqplot_target_"+a1.jqplot.targetCounter++,l.attr("id",p)),o=a1.jqplot(p,n,m),l.data("jqplot",o)})},a1.jqplot=function(a,p,o){var n=null,m=null;3===arguments.length?(n=p,m=o):2===arguments.length&&(a1.isArray(p)?n=p:a1.isPlainObject(p)&&(m=p)),null===n&&null!==m&&m.data&&(n=m.data);var l=new aV;if(a1("#"+a).removeClass("jqplot-error"),!a1.jqplot.config.catchErrors){return l.init(a,n,m),l.draw(),l.themeEngine.init.call(l),l}try{return l.init(a,n,m),l.draw(),l.themeEngine.init.call(l),l}catch(k){var g=a1.jqplot.config.errorMessage||k.message;a1("#"+a).append('
'+g+"
"),a1("#"+a).addClass("jqplot-error"),document.getElementById(a).style.background=a1.jqplot.config.errorBackground,document.getElementById(a).style.border=a1.jqplot.config.errorBorder,document.getElementById(a).style.fontFamily=a1.jqplot.config.errorFontFamily,document.getElementById(a).style.fontSize=a1.jqplot.config.errorFontSize,document.getElementById(a).style.fontStyle=a1.jqplot.config.errorFontStyle,document.getElementById(a).style.fontWeight=a1.jqplot.config.errorFontWeight}},a1.jqplot.version="1.0.9",a1.jqplot.revision="d96a669",a1.jqplot.targetCounter=1,a1.jqplot.CanvasManager=function(){"undefined"==typeof a1.jqplot.CanvasManager.canvases&&(a1.jqplot.CanvasManager.canvases=[],a1.jqplot.CanvasManager.free=[]);var a=[];this.getCanvas=function(){var i,h=!0;if(!a1.jqplot.use_excanvas){for(var g=0,b=a1.jqplot.CanvasManager.canvases.length;b>g;g++){if(a1.jqplot.CanvasManager.free[g]===!0){h=!1,i=a1.jqplot.CanvasManager.canvases[g],a1.jqplot.CanvasManager.free[g]=!1,a.push(g);break}}}return h&&(i=document.createElement("canvas"),a.push(a1.jqplot.CanvasManager.canvases.length),a1.jqplot.CanvasManager.canvases.push(i),a1.jqplot.CanvasManager.free.push(!1)),i},this.initCanvas=function(g){if(a1.jqplot.use_excanvas){return window.G_vmlCanvasManager.initElement(g)}var k=g.getContext("2d"),j=1;window.devicePixelRatio>1&&(k.webkitBackingStorePixelRatio===av||k.webkitBackingStorePixelRatio<2)&&(j=window.devicePixelRatio);var i=g.width,h=g.height;return g.width=j*g.width,g.height=j*g.height,g.style.width=i+"px",g.style.height=h+"px",k.save(),k.scale(j,j),g},this.freeAllCanvases=function(){for(var b=0,d=a.length;d>b;b++){this.freeCanvas(a[b])}a=[]},this.freeCanvas=function(d){if(a1.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==av){window.G_vmlCanvasManager.uninitElement(a1.jqplot.CanvasManager.canvases[d]),a1.jqplot.CanvasManager.canvases[d]=null}else{var e=a1.jqplot.CanvasManager.canvases[d];e.getContext("2d").clearRect(0,0,e.width,e.height),a1(e).unbind().removeAttr("class").removeAttr("style"),a1(e).css({left:"",top:"",position:""}),e.width=0,e.height=0,a1.jqplot.CanvasManager.free[d]=!0}}},a1.jqplot.log=function(){window.console&&window.console.log.apply(window.console,arguments)},a1.jqplot.config={addDomReference:!1,enablePlugins:!1,defaultHeight:300,defaultWidth:400,UTCAdjust:!1,timezoneOffset:new Date(60000*(new Date).getTimezoneOffset()),errorMessage:"",errorBackground:"",errorBorder:"",errorFontFamily:"",errorFontSize:"",errorFontStyle:"",errorFontWeight:"",catchErrors:!1,defaultTickFormatString:"%.1f",defaultColors:["#4bb2c5","#EAA228","#c5b47f","#579575","#839557","#958c12","#953579","#4b5de4","#d8b83f","#ff5800","#0085cc","#c747a3","#cddf54","#FBD178","#26B4E3","#bd70c7"],defaultNegativeColors:["#498991","#C08840","#9F9274","#546D61","#646C4A","#6F6621","#6E3F5F","#4F64B0","#A89050","#C45923","#187399","#945381","#959E5C","#C7AF7B","#478396","#907294"],dashLength:4,gapLength:4,dotGapLength:2.5,srcLocation:"jqplot/src/",pluginLocation:"jqplot/src/plugins/"},a1.jqplot.arrayMax=function(b){return Math.max.apply(Math,b)},a1.jqplot.arrayMin=function(b){return Math.min.apply(Math,b)},a1.jqplot.enablePlugins=a1.jqplot.config.enablePlugins,a1.jqplot.support_canvas=function(){return"undefined"==typeof a1.jqplot.support_canvas.result&&(a1.jqplot.support_canvas.result=!!document.createElement("canvas").getContext),a1.jqplot.support_canvas.result},a1.jqplot.support_canvas_text=function(){return"undefined"==typeof a1.jqplot.support_canvas_text.result&&(window.G_vmlCanvasManager!==av&&window.G_vmlCanvasManager._version>887?a1.jqplot.support_canvas_text.result=!0:a1.jqplot.support_canvas_text.result=!(!document.createElement("canvas").getContext||"function"!=typeof document.createElement("canvas").getContext("2d").fillText)),a1.jqplot.support_canvas_text.result},a1.jqplot.use_excanvas=a1.support.boxModel&&a1.support.objectAll&&$support.leadingWhitespace||a1.jqplot.support_canvas()?!1:!0,a1.jqplot.preInitHooks=[],a1.jqplot.postInitHooks=[],a1.jqplot.preParseOptionsHooks=[],a1.jqplot.postParseOptionsHooks=[],a1.jqplot.preDrawHooks=[],a1.jqplot.postDrawHooks=[],a1.jqplot.preDrawSeriesHooks=[],a1.jqplot.postDrawSeriesHooks=[],a1.jqplot.preDrawLegendHooks=[],a1.jqplot.addLegendRowHooks=[],a1.jqplot.preSeriesInitHooks=[],a1.jqplot.postSeriesInitHooks=[],a1.jqplot.preParseSeriesOptionsHooks=[],a1.jqplot.postParseSeriesOptionsHooks=[],a1.jqplot.eventListenerHooks=[],a1.jqplot.preDrawSeriesShadowHooks=[],a1.jqplot.postDrawSeriesShadowHooks=[],a1.jqplot.ElemContainer=function(){this._elem,this._plotWidth,this._plotHeight,this._plotDimensions={height:null,width:null}},a1.jqplot.ElemContainer.prototype.createElement=function(a,n,m,l,k){this._offsets=n;var j=m||"jqplot",i=document.createElement(a);return this._elem=a1(i),this._elem.addClass(j),this._elem.css(l),this._elem.attr(k),i=null,this._elem},a1.jqplot.ElemContainer.prototype.getWidth=function(){return this._elem?this._elem.outerWidth(!0):null},a1.jqplot.ElemContainer.prototype.getHeight=function(){return this._elem?this._elem.outerHeight(!0):null},a1.jqplot.ElemContainer.prototype.getPosition=function(){return this._elem?this._elem.position():{top:null,left:null,bottom:null,right:null}},a1.jqplot.ElemContainer.prototype.getTop=function(){return this.getPosition().top},a1.jqplot.ElemContainer.prototype.getLeft=function(){return this.getPosition().left},a1.jqplot.ElemContainer.prototype.getBottom=function(){return this._elem.css("bottom")},a1.jqplot.ElemContainer.prototype.getRight=function(){return this._elem.css("right")},a0.prototype=new a1.jqplot.ElemContainer,a0.prototype.constructor=a0,a0.prototype.init=function(){a1.isFunction(this.renderer)&&(this.renderer=new this.renderer),this.tickOptions.axis=this.name,null==this.tickOptions.showMark&&(this.tickOptions.showMark=this.showTicks),null==this.tickOptions.showMark&&(this.tickOptions.showMark=this.showTickMarks),null==this.tickOptions.showLabel&&(this.tickOptions.showLabel=this.showTicks),null==this.label||""==this.label?this.showLabel=!1:this.labelOptions.label=this.label,0==this.showLabel&&(this.labelOptions.show=!1),0==this.pad&&(this.pad=1),0==this.padMax&&(this.padMax=1),0==this.padMin&&(this.padMin=1),null==this.padMax&&(this.padMax=(this.pad-1)/2+1),null==this.padMin&&(this.padMin=(this.pad-1)/2+1),this.pad=this.padMax+this.padMin-1,(null!=this.min||null!=this.max)&&(this.autoscale=!1),null==this.syncTicks&&this.name.indexOf("y")>-1?this.syncTicks=!0:null==this.syncTicks&&(this.syncTicks=!1),this.renderer.init.call(this,this.rendererOptions)},a0.prototype.draw=function(d,c){return this.__ticks&&(this.__ticks=null),this.renderer.draw.call(this,d,c)},a0.prototype.set=function(){this.renderer.set.call(this)},a0.prototype.pack=function(d,c){this.show&&this.renderer.pack.call(this,d,c),null==this._min&&(this._min=this.min,this._max=this.max,this._tickInterval=this.tickInterval,this._numberTicks=this.numberTicks,this.__ticks=this._ticks)},a0.prototype.reset=function(){this.renderer.reset.call(this)},a0.prototype.resetScale=function(a){a1.extend(!0,this,{min:null,max:null,numberTicks:null,tickInterval:null,_ticks:[],ticks:[]},a),this.resetDataBounds()},a0.prototype.resetDataBounds=function(){var r=this._dataBounds;r.min=null,r.max=null;for(var q,p,o,n=this.show?!0:!1,m=0;ma;a++){"xaxis"==this.name||"x2axis"==this.name?((null!=o[a][0]&&o[a][0]r.max||null==r.max)&&(r.max=o[a][0])):((null!=o[a][l]&&o[a][l]r.max||null==r.max)&&(r.max=o[a][k]))}n&&p.renderer.constructor!==a1.jqplot.BarRenderer?n=!1:n&&this._options.hasOwnProperty("forceTickAt0")&&0==this._options.forceTickAt0?n=!1:n&&p.renderer.constructor===a1.jqplot.BarRenderer&&("vertical"==p.barDirection&&"xaxis"!=this.name&&"x2axis"!=this.name?(null!=this._options.pad||null!=this._options.padMin)&&(n=!1):"horizontal"!=p.barDirection||"xaxis"!=this.name&&"x2axis"!=this.name||(null!=this._options.pad||null!=this._options.padMin)&&(n=!1))}}n&&this.renderer.constructor===a1.jqplot.LinearAxisRenderer&&r.min>=0&&(this.padMin=1,this.forceTickAt0=!0)},aZ.prototype=new a1.jqplot.ElemContainer,aZ.prototype.constructor=aZ,aZ.prototype.setOptions=function(a){if(a1.extend(!0,this,a),"inside"==this.placement&&(this.placement="insideGrid"),this.xoffset>0){if("insideGrid"==this.placement){switch(this.location){case"nw":case"w":case"sw":null==this.marginLeft&&(this.marginLeft=this.xoffset+"px"),this.marginRight="0px";break;case"ne":case"e":case"se":default:null==this.marginRight&&(this.marginRight=this.xoffset+"px"),this.marginLeft="0px"}}else{if("outside"==this.placement){switch(this.location){case"nw":case"w":case"sw":null==this.marginRight&&(this.marginRight=this.xoffset+"px"),this.marginLeft="0px";break;case"ne":case"e":case"se":default:null==this.marginLeft&&(this.marginLeft=this.xoffset+"px"),this.marginRight="0px"}}}this.xoffset=0}if(this.yoffset>0){if("outside"==this.placement){switch(this.location){case"sw":case"s":case"se":null==this.marginTop&&(this.marginTop=this.yoffset+"px"),this.marginBottom="0px";break;case"ne":case"n":case"nw":default:null==this.marginBottom&&(this.marginBottom=this.yoffset+"px"),this.marginTop="0px"}}else{if("insideGrid"==this.placement){switch(this.location){case"sw":case"s":case"se":null==this.marginBottom&&(this.marginBottom=this.yoffset+"px"),this.marginTop="0px";break;case"ne":case"n":case"nw":default:null==this.marginTop&&(this.marginTop=this.yoffset+"px"),this.marginBottom="0px"}}}this.yoffset=0}},aZ.prototype.init=function(){a1.isFunction(this.renderer)&&(this.renderer=new this.renderer),this.renderer.init.call(this,this.rendererOptions)},aZ.prototype.draw=function(a,f){for(var e=0;en;n++){if(this.breakOnNull){k.push(l[n])}else{if(null==l[n]||null==l[n][0]||null==l[n][1]){continue}k.push(l[n])}}if(this.data=k,this.color||(this.color=o.colorGenerator.get(this.index)),this.negativeColor||(this.negativeColor=o.negativeColorGenerator.get(this.index)),this.fillColor||(this.fillColor=this.color),this.fillAlpha){var j=a1.jqplot.normalize2rgb(this.fillColor),j=a1.jqplot.getColorComponents(j);this.fillColor="rgba("+j[0]+","+j[1]+","+j[2]+","+this.fillAlpha+")"}a1.isFunction(this.renderer)&&(this.renderer=new this.renderer),this.renderer.init.call(this,this.rendererOptions,o),this.markerRenderer=new this.markerRenderer,this.markerOptions.color||(this.markerOptions.color=this.color),null==this.markerOptions.show&&(this.markerOptions.show=this.showMarker),this.showMarker=this.markerOptions.show,this.markerRenderer.init(this.markerOptions)},aX.prototype.draw=function(a,n,m){var l=n==av?{}:n;a=a==av?this.canvas._ctx:a;var k,j,i;for(k=0;ki;i++){this.hooks[i]==g&&(j=!0)}j||(this.hooks.push(g),this.args.push(f))},a1.jqplot.HooksManager.prototype.add=function(d,c){c=c||[],this.hooks.push(d),this.args.push(c)},a1.jqplot.EventListenerManager=function(){this.hooks=[]},a1.jqplot.EventListenerManager.prototype.addOnce=function(h,g){for(var l,k,j=!1,k=0,i=this.hooks.length;i>k;k++){l=this.hooks[k],l[0]==h&&l[1]==g&&(j=!0)}j||this.hooks.push([h,g])},a1.jqplot.EventListenerManager.prototype.add=function(d,c){this.hooks.push([d,c])};var au=["yMidAxis","xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis"];a1.jqplot.computeHighlightColors=function(a){var n;if(a1.isArray(a)){n=[];for(var m=0;mi;i++){k[i]=j>660?0.85*k[i]:0.73*k[i]+90,k[i]=parseInt(k[i],10),k[i]>255?255:k[i]}k[3]=0.3+0.35*l[3],n.push("rgba("+k[0]+","+k[1]+","+k[2]+","+k[3]+")")}}else{for(var l=a1.jqplot.getColorComponents(a),k=[l[0],l[1],l[2]],j=k[0]+k[1]+k[2],i=0;3>i;i++){k[i]=j>660?0.85*k[i]:0.73*k[i]+90,k[i]=parseInt(k[i],10),k[i]>255?255:k[i]}k[3]=0.3+0.35*l[3],n="rgba("+k[0]+","+k[1]+","+k[2]+","+k[3]+")"}return n},a1.jqplot.ColorGenerator=function(a){a=a||a1.jqplot.config.defaultColors;var d=0;this.next=function(){return d0?a[d--]:(d=a.length-1,a[d])},this.get=function(b){var e=b-a.length*Math.floor(b/a.length);return a[e]},this.setColors=function(b){a=b},this.reset=function(){d=0},this.getIndex=function(){return d},this.setIndex=function(b){d=b}},a1.jqplot.hex2rgb=function(e,d){e=e.replace("#",""),3==e.length&&(e=e.charAt(0)+e.charAt(0)+e.charAt(1)+e.charAt(1)+e.charAt(2)+e.charAt(2));var f;return f="rgba("+parseInt(e.slice(0,2),16)+", "+parseInt(e.slice(2,4),16)+", "+parseInt(e.slice(4,6),16),d&&(f+=", "+d),f+=")"},a1.jqplot.rgb2hex=function(h){for(var g=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/,l=h.match(g),k="#",j=1;4>j;j++){var i;-1!=l[j].search(/%/)?(i=parseInt(255*l[j]/100,10).toString(16),1==i.length&&(i="0"+i)):(i=parseInt(l[j],10).toString(16),1==i.length&&(i="0"+i)),k+=i}return k},a1.jqplot.normalize2rgb=function(a,d){if(-1!=a.search(/^ *rgba?\(/)){return a}if(-1!=a.search(/^ *#?[0-9a-fA-F]?[0-9a-fA-F]/)){return a1.jqplot.hex2rgb(a,d)}throw new Error("Invalid color spec")},a1.jqplot.getColorComponents=function(a){a=a1.jqplot.colorKeywordMap[a]||a;for(var l=a1.jqplot.normalize2rgb(a),k=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/,j=l.match(k),i=[],h=1;4>h;h++){-1!=j[h].search(/%/)?i[h-1]=parseInt(255*j[h]/100,10):i[h-1]=parseInt(j[h],10)}return i[3]=parseFloat(j[4])?parseFloat(j[4]):1,i},a1.jqplot.colorKeywordMap={aliceblue:"rgb(240, 248, 255)",antiquewhite:"rgb(250, 235, 215)",aqua:"rgb( 0, 255, 255)",aquamarine:"rgb(127, 255, 212)",azure:"rgb(240, 255, 255)",beige:"rgb(245, 245, 220)",bisque:"rgb(255, 228, 196)",black:"rgb( 0, 0, 0)",blanchedalmond:"rgb(255, 235, 205)",blue:"rgb( 0, 0, 255)",blueviolet:"rgb(138, 43, 226)",brown:"rgb(165, 42, 42)",burlywood:"rgb(222, 184, 135)",cadetblue:"rgb( 95, 158, 160)",chartreuse:"rgb(127, 255, 0)",chocolate:"rgb(210, 105, 30)",coral:"rgb(255, 127, 80)",cornflowerblue:"rgb(100, 149, 237)",cornsilk:"rgb(255, 248, 220)",crimson:"rgb(220, 20, 60)",cyan:"rgb( 0, 255, 255)",darkblue:"rgb( 0, 0, 139)",darkcyan:"rgb( 0, 139, 139)",darkgoldenrod:"rgb(184, 134, 11)",darkgray:"rgb(169, 169, 169)",darkgreen:"rgb( 0, 100, 0)",darkgrey:"rgb(169, 169, 169)",darkkhaki:"rgb(189, 183, 107)",darkmagenta:"rgb(139, 0, 139)",darkolivegreen:"rgb( 85, 107, 47)",darkorange:"rgb(255, 140, 0)",darkorchid:"rgb(153, 50, 204)",darkred:"rgb(139, 0, 0)",darksalmon:"rgb(233, 150, 122)",darkseagreen:"rgb(143, 188, 143)",darkslateblue:"rgb( 72, 61, 139)",darkslategray:"rgb( 47, 79, 79)",darkslategrey:"rgb( 47, 79, 79)",darkturquoise:"rgb( 0, 206, 209)",darkviolet:"rgb(148, 0, 211)",deeppink:"rgb(255, 20, 147)",deepskyblue:"rgb( 0, 191, 255)",dimgray:"rgb(105, 105, 105)",dimgrey:"rgb(105, 105, 105)",dodgerblue:"rgb( 30, 144, 255)",firebrick:"rgb(178, 34, 34)",floralwhite:"rgb(255, 250, 240)",forestgreen:"rgb( 34, 139, 34)",fuchsia:"rgb(255, 0, 255)",gainsboro:"rgb(220, 220, 220)",ghostwhite:"rgb(248, 248, 255)",gold:"rgb(255, 215, 0)",goldenrod:"rgb(218, 165, 32)",gray:"rgb(128, 128, 128)",grey:"rgb(128, 128, 128)",green:"rgb( 0, 128, 0)",greenyellow:"rgb(173, 255, 47)",honeydew:"rgb(240, 255, 240)",hotpink:"rgb(255, 105, 180)",indianred:"rgb(205, 92, 92)",indigo:"rgb( 75, 0, 130)",ivory:"rgb(255, 255, 240)",khaki:"rgb(240, 230, 140)",lavender:"rgb(230, 230, 250)",lavenderblush:"rgb(255, 240, 245)",lawngreen:"rgb(124, 252, 0)",lemonchiffon:"rgb(255, 250, 205)",lightblue:"rgb(173, 216, 230)",lightcoral:"rgb(240, 128, 128)",lightcyan:"rgb(224, 255, 255)",lightgoldenrodyellow:"rgb(250, 250, 210)",lightgray:"rgb(211, 211, 211)",lightgreen:"rgb(144, 238, 144)",lightgrey:"rgb(211, 211, 211)",lightpink:"rgb(255, 182, 193)",lightsalmon:"rgb(255, 160, 122)",lightseagreen:"rgb( 32, 178, 170)",lightskyblue:"rgb(135, 206, 250)",lightslategray:"rgb(119, 136, 153)",lightslategrey:"rgb(119, 136, 153)",lightsteelblue:"rgb(176, 196, 222)",lightyellow:"rgb(255, 255, 224)",lime:"rgb( 0, 255, 0)",limegreen:"rgb( 50, 205, 50)",linen:"rgb(250, 240, 230)",magenta:"rgb(255, 0, 255)",maroon:"rgb(128, 0, 0)",mediumaquamarine:"rgb(102, 205, 170)",mediumblue:"rgb( 0, 0, 205)",mediumorchid:"rgb(186, 85, 211)",mediumpurple:"rgb(147, 112, 219)",mediumseagreen:"rgb( 60, 179, 113)",mediumslateblue:"rgb(123, 104, 238)",mediumspringgreen:"rgb( 0, 250, 154)",mediumturquoise:"rgb( 72, 209, 204)",mediumvioletred:"rgb(199, 21, 133)",midnightblue:"rgb( 25, 25, 112)",mintcream:"rgb(245, 255, 250)",mistyrose:"rgb(255, 228, 225)",moccasin:"rgb(255, 228, 181)",navajowhite:"rgb(255, 222, 173)",navy:"rgb( 0, 0, 128)",oldlace:"rgb(253, 245, 230)",olive:"rgb(128, 128, 0)",olivedrab:"rgb(107, 142, 35)",orange:"rgb(255, 165, 0)",orangered:"rgb(255, 69, 0)",orchid:"rgb(218, 112, 214)",palegoldenrod:"rgb(238, 232, 170)",palegreen:"rgb(152, 251, 152)",paleturquoise:"rgb(175, 238, 238)",palevioletred:"rgb(219, 112, 147)",papayawhip:"rgb(255, 239, 213)",peachpuff:"rgb(255, 218, 185)",peru:"rgb(205, 133, 63)",pink:"rgb(255, 192, 203)",plum:"rgb(221, 160, 221)",powderblue:"rgb(176, 224, 230)",purple:"rgb(128, 0, 128)",red:"rgb(255, 0, 0)",rosybrown:"rgb(188, 143, 143)",royalblue:"rgb( 65, 105, 225)",saddlebrown:"rgb(139, 69, 19)",salmon:"rgb(250, 128, 114)",sandybrown:"rgb(244, 164, 96)",seagreen:"rgb( 46, 139, 87)",seashell:"rgb(255, 245, 238)",sienna:"rgb(160, 82, 45)",silver:"rgb(192, 192, 192)",skyblue:"rgb(135, 206, 235)",slateblue:"rgb(106, 90, 205)",slategray:"rgb(112, 128, 144)",slategrey:"rgb(112, 128, 144)",snow:"rgb(255, 250, 250)",springgreen:"rgb( 0, 255, 127)",steelblue:"rgb( 70, 130, 180)",tan:"rgb(210, 180, 140)",teal:"rgb( 0, 128, 128)",thistle:"rgb(216, 191, 216)",tomato:"rgb(255, 99, 71)",turquoise:"rgb( 64, 224, 208)",violet:"rgb(238, 130, 238)",wheat:"rgb(245, 222, 179)",white:"rgb(255, 255, 255)",whitesmoke:"rgb(245, 245, 245)",yellow:"rgb(255, 255, 0)",yellowgreen:"rgb(154, 205, 50)"},a1.jqplot.AxisLabelRenderer=function(a){a1.jqplot.ElemContainer.call(this),this.axis,this.show=!0,this.label="",this.fontFamily=null,this.fontSize=null,this.textColor=null,this._elem,this.escapeHTML=!1,a1.extend(!0,this,a)},a1.jqplot.AxisLabelRenderer.prototype=new a1.jqplot.ElemContainer,a1.jqplot.AxisLabelRenderer.prototype.constructor=a1.jqplot.AxisLabelRenderer,a1.jqplot.AxisLabelRenderer.prototype.init=function(a){a1.extend(!0,this,a)},a1.jqplot.AxisLabelRenderer.prototype.draw=function(a,d){return this._elem&&(this._elem.emptyForce(),this._elem=null),this._elem=a1('
'),Number(this.label)&&this._elem.css("white-space","nowrap"),this.escapeHTML?this._elem.text(this.label):this._elem.html(this.label),this.fontFamily&&this._elem.css("font-family",this.fontFamily),this.fontSize&&this._elem.css("font-size",this.fontSize),this.textColor&&this._elem.css("color",this.textColor),this._elem},a1.jqplot.AxisLabelRenderer.prototype.pack=function(){},a1.jqplot.AxisTickRenderer=function(a){a1.jqplot.ElemContainer.call(this),this.mark="outside",this.axis,this.showMark=!0,this.showGridline=!0,this.isMinorTick=!1,this.size=4,this.markSize=6,this.show=!0,this.showLabel=!0,this.label=null,this.value=null,this._styles={},this.formatter=a1.jqplot.DefaultTickFormatter,this.prefix="",this.suffix="",this.formatString="",this.fontFamily,this.fontSize,this.textColor,this.escapeHTML=!1,this._elem,this._breakTick=!1,a1.extend(!0,this,a)},a1.jqplot.AxisTickRenderer.prototype.init=function(a){a1.extend(!0,this,a)},a1.jqplot.AxisTickRenderer.prototype=new a1.jqplot.ElemContainer,a1.jqplot.AxisTickRenderer.prototype.constructor=a1.jqplot.AxisTickRenderer,a1.jqplot.AxisTickRenderer.prototype.setTick=function(e,d,f){return this.value=e,this.axis=d,f&&(this.isMinorTick=!0),this},a1.jqplot.AxisTickRenderer.prototype.draw=function(){null===this.label&&(this.label=this.prefix+this.formatter(this.formatString,this.value)+this.suffix);var a={position:"absolute"};Number(this.label)&&(a.whitSpace="nowrap"),this._elem&&(this._elem.emptyForce(),this._elem=null),this._elem=a1(document.createElement("div")),this._elem.addClass("jqplot-"+this.axis+"-tick"),this.escapeHTML?this._elem.text(this.label):this._elem.html(this.label),this._elem.css(a);for(var d in this._styles){this._elem.css(d,this._styles[d])}return this.fontFamily&&this._elem.css("font-family",this.fontFamily),this.fontSize&&this._elem.css("font-size",this.fontSize),this.textColor&&this._elem.css("color",this.textColor),this._breakTick&&this._elem.addClass("jqplot-breakTick"),this._elem},a1.jqplot.DefaultTickFormatter=function(a,d){return"number"==typeof d?(a||(a=a1.jqplot.config.defaultTickFormatString),a1.jqplot.sprintf(a,d)):String(d)},a1.jqplot.PercentTickFormatter=function(a,d){return"number"==typeof d?(d=100*d,a||(a=a1.jqplot.config.defaultTickFormatString),a1.jqplot.sprintf(a,d)):String(d)},a1.jqplot.AxisTickRenderer.prototype.pack=function(){},a1.jqplot.CanvasGridRenderer=function(){this.shadowRenderer=new a1.jqplot.ShadowRenderer},a1.jqplot.CanvasGridRenderer.prototype.init=function(a){this._ctx,a1.extend(!0,this,a);var d={lineJoin:"miter",lineCap:"round",fill:!1,isarc:!1,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.shadowWidth,closePath:!1,strokeStyle:this.shadowColor};this.renderer.shadowRenderer.init(d)},a1.jqplot.CanvasGridRenderer.prototype.createElement=function(a){var h;this._elem&&(a1.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==av&&(h=this._elem.get(0),window.G_vmlCanvasManager.uninitElement(h),h=null),this._elem.emptyForce(),this._elem=null),h=a.canvasManager.getCanvas();var g=this._plotDimensions.width,f=this._plotDimensions.height;return h.width=g,h.height=f,this._elem=a1(h),this._elem.addClass("jqplot-grid-canvas"),this._elem.css({position:"absolute",left:0,top:0}),h=a.canvasManager.initCanvas(h),this._top=this._offsets.top,this._bottom=f-this._offsets.bottom,this._left=this._offsets.left,this._right=g-this._offsets.right,this._width=this._right-this._left,this._height=this._bottom-this._top,h=null,this._elem},a1.jqplot.CanvasGridRenderer.prototype.draw=function(){function P(c,k,j,i,h){O.save(),h=h||{},(null==h.lineWidth||0!=h.lineWidth)&&(a1.extend(!0,O,h),O.beginPath(),O.moveTo(c,k),O.lineTo(j,i),O.stroke(),O.restore())}this._ctx=this._elem.get(0).getContext("2d");var O=this._ctx,N=this._axes;O.save(),O.clearRect(0,0,this._plotDimensions.width,this._plotDimensions.height),O.fillStyle=this.backgroundColor||this.background,O.fillRect(this._left,this._top,this._width,this._height),O.save(),O.lineJoin="miter",O.lineCap="butt",O.lineWidth=this.gridLineWidth,O.strokeStyle=this.gridLineColor;for(var M,L,K,J,I=["xaxis","yaxis","x2axis","y2axis"],H=4;H>0;H--){var G=I[H-1],F=N[G],E=F._ticks,D=E.length;if(F.show){if(F.drawBaseline){var C={};switch(null!==F.baselineWidth&&(C.lineWidth=F.baselineWidth),null!==F.baselineColor&&(C.strokeStyle=F.baselineColor),G){case"xaxis":P(this._left,this._bottom,this._right,this._bottom,C);break;case"yaxis":P(this._left,this._bottom,this._left,this._top,C);break;case"x2axis":P(this._left,this._bottom,this._right,this._bottom,C);break;case"y2axis":P(this._right,this._bottom,this._right,this._top,C)}}for(var B=D;B>0;B--){var A=E[B-1];if(A.show){var z=Math.round(F.u2p(A.value))+0.5;switch(G){case"xaxis":if(A.showGridline&&this.drawGridlines&&(!A.isMinorTick&&F.drawMajorGridlines||A.isMinorTick&&F.drawMinorGridlines)&&P(z,this._top,z,this._bottom),A.showMark&&A.mark&&(!A.isMinorTick&&F.drawMajorTickMarks||A.isMinorTick&&F.drawMinorTickMarks)){K=A.markSize,J=A.mark;var z=Math.round(F.u2p(A.value))+0.5;switch(J){case"outside":M=this._bottom,L=this._bottom+K;break;case"inside":M=this._bottom-K,L=this._bottom;break;case"cross":M=this._bottom-K,L=this._bottom+K;break;default:M=this._bottom,L=this._bottom+K}this.shadow&&this.renderer.shadowRenderer.draw(O,[[z,M],[z,L]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:0.75*this.gridLineWidth,depth:2,fill:!1,closePath:!1}),P(z,M,z,L)}break;case"yaxis":if(A.showGridline&&this.drawGridlines&&(!A.isMinorTick&&F.drawMajorGridlines||A.isMinorTick&&F.drawMinorGridlines)&&P(this._right,z,this._left,z),A.showMark&&A.mark&&(!A.isMinorTick&&F.drawMajorTickMarks||A.isMinorTick&&F.drawMinorTickMarks)){K=A.markSize,J=A.mark;var z=Math.round(F.u2p(A.value))+0.5;switch(J){case"outside":M=this._left-K,L=this._left;break;case"inside":M=this._left,L=this._left+K;break;case"cross":M=this._left-K,L=this._left+K;break;default:M=this._left-K,L=this._left}this.shadow&&this.renderer.shadowRenderer.draw(O,[[M,z],[L,z]],{lineCap:"butt",lineWidth:1.5*this.gridLineWidth,offset:0.75*this.gridLineWidth,fill:!1,closePath:!1}),P(M,z,L,z,{strokeStyle:F.borderColor})}break;case"x2axis":if(A.showGridline&&this.drawGridlines&&(!A.isMinorTick&&F.drawMajorGridlines||A.isMinorTick&&F.drawMinorGridlines)&&P(z,this._bottom,z,this._top),A.showMark&&A.mark&&(!A.isMinorTick&&F.drawMajorTickMarks||A.isMinorTick&&F.drawMinorTickMarks)){K=A.markSize,J=A.mark;var z=Math.round(F.u2p(A.value))+0.5;switch(J){case"outside":M=this._top-K,L=this._top;break;case"inside":M=this._top,L=this._top+K;break;case"cross":M=this._top-K,L=this._top+K;break;default:M=this._top-K,L=this._top}this.shadow&&this.renderer.shadowRenderer.draw(O,[[z,M],[z,L]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:0.75*this.gridLineWidth,depth:2,fill:!1,closePath:!1}),P(z,M,z,L)}break;case"y2axis":if(A.showGridline&&this.drawGridlines&&(!A.isMinorTick&&F.drawMajorGridlines||A.isMinorTick&&F.drawMinorGridlines)&&P(this._left,z,this._right,z),A.showMark&&A.mark&&(!A.isMinorTick&&F.drawMajorTickMarks||A.isMinorTick&&F.drawMinorTickMarks)){K=A.markSize,J=A.mark;var z=Math.round(F.u2p(A.value))+0.5;switch(J){case"outside":M=this._right,L=this._right+K;break;case"inside":M=this._right-K,L=this._right;break;case"cross":M=this._right-K,L=this._right+K;break;default:M=this._right,L=this._right+K}this.shadow&&this.renderer.shadowRenderer.draw(O,[[M,z],[L,z]],{lineCap:"butt",lineWidth:1.5*this.gridLineWidth,offset:0.75*this.gridLineWidth,fill:!1,closePath:!1}),P(M,z,L,z,{strokeStyle:F.borderColor})}}}}A=null}F=null,E=null}I=["y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];for(var H=7;H>0;H--){var F=N[I[H-1]],E=F._ticks;if(F.show){var y=E[F.numberTicks-1],x=E[0],w=F.getLeft(),a=[[w,y.getTop()+y.getHeight()/2],[w,x.getTop()+x.getHeight()/2+1]];this.shadow&&this.renderer.shadowRenderer.draw(O,a,{lineCap:"butt",fill:!1,closePath:!1}),P(a[0][0],a[0][1],a[1][0],a[1][1],{lineCap:"butt",strokeStyle:F.borderColor,lineWidth:F.borderWidth});for(var B=E.length;B>0;B--){var A=E[B-1];K=A.markSize,J=A.mark;var z=Math.round(F.u2p(A.value))+0.5;if(A.showMark&&A.mark){switch(J){case"outside":M=w,L=w+K;break;case"inside":M=w-K,L=w;break;case"cross":M=w-K,L=w+K;break;default:M=w,L=w+K}a=[[M,z],[L,z]],this.shadow&&this.renderer.shadowRenderer.draw(O,a,{lineCap:"butt",lineWidth:1.5*this.gridLineWidth,offset:0.75*this.gridLineWidth,fill:!1,closePath:!1}),P(M,z,L,z,{strokeStyle:F.borderColor})}A=null}x=null}F=null,E=null}if(O.restore(),this.shadow){var a=[[this._left,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(O,a)}0!=this.borderWidth&&this.drawBorder&&(P(this._left,this._top,this._right,this._top,{lineCap:"round",strokeStyle:N.x2axis.borderColor,lineWidth:N.x2axis.borderWidth}),P(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:N.y2axis.borderColor,lineWidth:N.y2axis.borderWidth}),P(this._right,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:N.xaxis.borderColor,lineWidth:N.xaxis.borderWidth}),P(this._left,this._bottom,this._left,this._top,{lineCap:"round",strokeStyle:N.yaxis.borderColor,lineWidth:N.yaxis.borderWidth})),O.restore(),O=null,N=null},a1.jqplot.DivTitleRenderer=function(){},a1.jqplot.DivTitleRenderer.prototype.init=function(a){a1.extend(!0,this,a)},a1.jqplot.DivTitleRenderer.prototype.draw=function(){this._elem&&(this._elem.emptyForce(),this._elem=null);var a=(this.renderer,document.createElement("div"));if(this._elem=a1(a),this._elem.addClass("jqplot-title"),this.text){if(this.text){var f;this.color?f=this.color:this.textColor&&(f=this.textColor);var e={position:"absolute",top:"0px",left:"0px"};this._plotWidth&&(e.width=this._plotWidth+"px"),this.fontSize&&(e.fontSize=this.fontSize),"string"==typeof this.textAlign?e.textAlign=this.textAlign:e.textAlign="center",f&&(e.color=f),this.paddingBottom&&(e.paddingBottom=this.paddingBottom),this.fontFamily&&(e.fontFamily=this.fontFamily),this._elem.css(e),this.escapeHtml?this._elem.text(this.text):this._elem.html(this.text)}}else{this.show=!1,this._elem.height(0),this._elem.width(0)}return a=null,this._elem},a1.jqplot.DivTitleRenderer.prototype.pack=function(){};var at=0.1;a1.jqplot.LinePattern=function(F,E){var D={dotted:[at,a1.jqplot.config.dotGapLength],dashed:[a1.jqplot.config.dashLength,a1.jqplot.config.gapLength],solid:null};if("string"==typeof E){if("."===E[0]||"-"===E[0]){var C=E;E=[];for(var B=0,A=C.length;A>B;B++){if("."===C[B]){E.push(at)}else{if("-"!==C[B]){continue}E.push(a1.jqplot.config.dashLength)}E.push(a1.jqplot.config.gapLength)}}else{E=D[E]}}if(!E||!E.length){return F}var z=0,y=E[0],x=0,w=0,v=0,u=0,t=function(b,d){F.moveTo(b,d),x=b,w=d,v=b,u=d},s=function(h,n){var k=F.lineWidth,j=h-x,i=n-w,c=Math.sqrt(j*j+i*i);if(c>0&&k>0){for(j/=c,i/=c;;){var b=k*y;if(!(c>b)){x=h,w=n,0==(1&z)?F.lineTo(x,w):F.moveTo(x,w),y-=c/k;break}x+=b*j,w+=b*i,0==(1&z)?F.lineTo(x,w):F.moveTo(x,w),c-=b,z++,z>=E.length&&(z=0),y=E[z]}}},r=function(){F.beginPath()},a=function(){s(v,u)};return{moveTo:t,lineTo:s,beginPath:r,closePath:a}},a1.jqplot.LineRenderer=function(){this.shapeRenderer=new a1.jqplot.ShapeRenderer,this.shadowRenderer=new a1.jqplot.ShadowRenderer},a1.jqplot.LineRenderer.prototype.init=function(a,n){a=a||{},this._type="line",this.renderer.animation={show:!1,direction:"left",speed:2500,_supported:!0},this.renderer.smooth=!1,this.renderer.tension=null,this.renderer.constrainSmoothing=!0,this.renderer._smoothedData=[],this.renderer._smoothedPlotData=[],this.renderer._hiBandGridData=[],this.renderer._lowBandGridData=[],this.renderer._hiBandSmoothedData=[],this.renderer._lowBandSmoothedData=[],this.renderer.bandData=[],this.renderer.bands={show:!1,hiData:[],lowData:[],color:this.color,showLines:!1,fill:!0,fillColor:null,_min:null,_max:null,interval:"3%"};var m={highlightMouseOver:a.highlightMouseOver,highlightMouseDown:a.highlightMouseDown,highlightColor:a.highlightColor};delete a.highlightMouseOver,delete a.highlightMouseDown,delete a.highlightColor,a1.extend(!0,this.renderer,a),this.renderer.options=a,this.renderer.bandData.length>1&&(!a.bands||null==a.bands.show)?this.renderer.bands.show=!0:a.bands&&null==a.bands.show&&null!=a.bands.interval&&(this.renderer.bands.show=!0),this.fill&&(this.renderer.bands.show=!1),this.renderer.bands.show&&this.renderer.initBands.call(this,this.renderer.options,n),this._stack&&(this.renderer.smooth=!1);var l={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:!1,strokeStyle:this.color,fillStyle:this.fillColor,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};this.renderer.shapeRenderer.init(l);var k=a.shadowOffset;null==k&&(k=this.lineWidth>2.5?1.25*(1+0.6*(Math.atan(this.lineWidth/2.5)/0.785398163-1)):1.25*Math.atan(this.lineWidth/2.5)/0.785398163);var j={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:!1,angle:this.shadowAngle,offset:k,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};if(this.renderer.shadowRenderer.init(j),this._areaPoints=[],this._boundingBox=[[],[]],!this.isTrendline&&this.fill||this.renderer.bands.show){if(this.highlightMouseOver=!0,this.highlightMouseDown=!1,this.highlightColor=null,m.highlightMouseDown&&null==m.highlightMouseOver&&(m.highlightMouseOver=!1),a1.extend(!0,this,{highlightMouseOver:m.highlightMouseOver,highlightMouseDown:m.highlightMouseDown,highlightColor:m.highlightColor}),!this.highlightColor){var i=this.renderer.bands.show?this.renderer.bands.fillColor:this.fillColor;this.highlightColor=a1.jqplot.computeHighlightColors(i)}this.highlighter&&(this.highlighter.show=!1)}!this.isTrendline&&n&&(n.plugins.lineRenderer={},n.postInitHooks.addOnce(aQ),n.postDrawHooks.addOnce(aP),n.eventListenerHooks.addOnce("jqplotMouseMove",aM),n.eventListenerHooks.addOnce("jqplotMouseDown",aL),n.eventListenerHooks.addOnce("jqplotMouseUp",aK),n.eventListenerHooks.addOnce("jqplotClick",aJ),n.eventListenerHooks.addOnce("jqplotRightClick",aI))},a1.jqplot.LineRenderer.prototype.initBands=function(P,O){var N=P.bandData||[],M=this.renderer.bands;M.hiData=[],M.lowData=[];var L=this.data;if(M._max=null,M._min=null,2==N.length){if(a1.isArray(N[0][0])){for(var K,J=0,I=0,H=0,G=N[0].length;G>H;H++){K=N[0][H],(null!=K[1]&&K[1]>M._max||null==M._max)&&(M._max=K[1]),(null!=K[1]&&K[1]H;H++){K=N[1][H],(null!=K[1]&&K[1]>M._max||null==M._max)&&(M._max=K[1],I=1),(null!=K[1]&&K[1]N[1][0]?0:1,E=F?0:1,H=0,G=L.length;G>H;H++){M.hiData.push([L[H][0],N[F][H]]),M.lowData.push([L[H][0],N[E][H]])}}else{M.show=!1}}}else{if(N.length>2&&!a1.isArray(N[0][0])){for(var F=N[0][0]>N[0][1]?0:1,E=F?0:1,H=0,G=N.length;G>H;H++){M.hiData.push([L[H][0],N[H][F]]),M.lowData.push([L[H][0],N[H][E]])}}else{var D=M.interval,C=null,B=null,A=null,z=null;if(a1.isArray(D)?(C=D[0],B=D[1]):C=D,isNaN(C)?"%"===C.charAt(C.length-1)&&(A="multiply",C=parseFloat(C)/100+1):(C=parseFloat(C),A="add"),null!==B&&isNaN(B)?"%"===B.charAt(B.length-1)&&(z="multiply",B=parseFloat(B)/100+1):null!==B&&(B=parseFloat(B),z="add"),null!==C){if(null===B&&(B=-C,z=A,"multiply"===z&&(B+=2)),B>C){var y=C;C=B,B=y,y=A,A=z,z=y}for(var H=0,G=L.length;G>H;H++){switch(A){case"add":M.hiData.push([L[H][0],L[H][1]+C]);break;case"multiply":M.hiData.push([L[H][0],L[H][1]*C])}switch(z){case"add":M.lowData.push([L[H][0],L[H][1]+B]);break;case"multiply":M.lowData.push([L[H][0],L[H][1]*B])}}}else{M.show=!1}}}for(var x=M.hiData,w=M.lowData,H=0,G=x.length;G>H;H++){(null!=x[H][1]&&x[H][1]>M._max||null==M._max)&&(M._max=x[H][1])}for(var H=0,G=w.length;G>H;H++){(null!=w[H][1]&&w[H][1]m;m++){null!=q[m][0]&&null!=q[m][1]?this.gridData.push([s.call(this._xaxis,q[m][0]),r.call(this._yaxis,q[m][1])]):null==q[m][0]?(n=!0,this.gridData.push([null,r.call(this._yaxis,q[m][1])])):null==q[m][1]&&(n=!0,this.gridData.push([s.call(this._xaxis,q[m][0]),null])),null!=p[m]&&null!=p[m][0]&&null!=p[m][1]?this._prevGridData.push([s.call(this._xaxis,p[m][0]),r.call(this._yaxis,p[m][1])]):null!=p[m]&&null==p[m][0]?this._prevGridData.push([null,r.call(this._yaxis,p[m][1])]):null!=p[m]&&null!=p[m][0]&&null==p[m][1]&&this._prevGridData.push([s.call(this._xaxis,p[m][0]),null])}if(n&&(this.renderer.smooth=!1,"line"===this._type&&(o.show=!1)),"line"===this._type&&o.show){for(var m=0,k=o.hiData.length;k>m;m++){this.renderer._hiBandGridData.push([s.call(this._xaxis,o.hiData[m][0]),r.call(this._yaxis,o.hiData[m][1])])}for(var m=0,k=o.lowData.length;k>m;m++){this.renderer._lowBandGridData.push([s.call(this._xaxis,o.lowData[m][0]),r.call(this._yaxis,o.lowData[m][1])])}}if("line"===this._type&&this.renderer.smooth&&this.gridData.length>2){var j;this.renderer.constrainSmoothing?(j=aS.call(this,this.gridData),this.renderer._smoothedData=j[0],this.renderer._smoothedPlotData=j[1],o.show&&(j=aS.call(this,this.renderer._hiBandGridData),this.renderer._hiBandSmoothedData=j[0],j=aS.call(this,this.renderer._lowBandGridData),this.renderer._lowBandSmoothedData=j[0]),j=null):(j=aR.call(this,this.gridData),this.renderer._smoothedData=j[0],this.renderer._smoothedPlotData=j[1],o.show&&(j=aR.call(this,this.renderer._hiBandGridData),this.renderer._hiBandSmoothedData=j[0],j=aR.call(this,this.renderer._lowBandGridData),this.renderer._lowBandSmoothedData=j[0]),j=null)}},a1.jqplot.LineRenderer.prototype.makeGridData=function(t,s){var r=this._xaxis.series_u2p,q=this._yaxis.series_u2p,p=[];this.renderer._smoothedData=[],this.renderer._smoothedPlotData=[],this.renderer._hiBandGridData=[],this.renderer._lowBandGridData=[],this.renderer._hiBandSmoothedData=[],this.renderer._lowBandSmoothedData=[];for(var o=this.renderer.bands,n=!1,m=0;m0&&p.push([r.call(this._xaxis,t[m][0]),q.call(this._yaxis,t[m-1][1])]),p.push([r.call(this._xaxis,t[m][0]),q.call(this._yaxis,t[m][1])])):null==t[m][0]?(n=!0,p.push([null,q.call(this._yaxis,t[m][1])])):null==t[m][1]&&(n=!0,p.push([r.call(this._xaxis,t[m][0]),null]))}if(n&&(this.renderer.smooth=!1,"line"===this._type&&(o.show=!1)),"line"===this._type&&o.show){for(var m=0,k=o.hiData.length;k>m;m++){this.renderer._hiBandGridData.push([r.call(this._xaxis,o.hiData[m][0]),q.call(this._yaxis,o.hiData[m][1])])}for(var m=0,k=o.lowData.length;k>m;m++){this.renderer._lowBandGridData.push([r.call(this._xaxis,o.lowData[m][0]),q.call(this._yaxis,o.lowData[m][1])])}}if("line"===this._type&&this.renderer.smooth&&p.length>2){var j;this.renderer.constrainSmoothing?(j=aS.call(this,p),this.renderer._smoothedData=j[0],this.renderer._smoothedPlotData=j[1],o.show&&(j=aS.call(this,this.renderer._hiBandGridData),this.renderer._hiBandSmoothedData=j[0],j=aS.call(this,this.renderer._lowBandGridData),this.renderer._lowBandSmoothedData=j[0]),j=null):(j=aR.call(this,p),this.renderer._smoothedData=j[0],this.renderer._smoothedPlotData=j[1],o.show&&(j=aR.call(this,this.renderer._hiBandGridData),this.renderer._hiBandSmoothedData=j[0],j=aR.call(this,this.renderer._lowBandGridData),this.renderer._lowBandSmoothedData=j[0]),j=null)}return p},a1.jqplot.LineRenderer.prototype.draw=function(a8,a7,a6,a5){var a4,a3,Z,Y,X,W=a1.extend(!0,{},a6),V=W.shadow!=av?W.shadow:this.shadow,U=W.showLine!=av?W.showLine:this.showLine,T=W.fill!=av?W.fill:this.fill,S=W.fillAndStroke!=av?W.fillAndStroke:this.fillAndStroke;if(a8.save(),a7.length){if(U){if(T){if(this.fillToZero){var R=this.negativeColor;this.useNegativeColors||(R=W.fillStyle);var P=!1,N=W.fillStyle;if(S){var L=a7.slice(0)}if(0!=this.index&&this._stack){for(var J=this._prevGridData,a4=J.length;a4>0;a4--){a7.push(J[a4-1])}V&&this.renderer.shadowRenderer.draw(a8,a7,W),this._areaPoints=a7,this.renderer.shapeRenderer.draw(a8,a7,W)}else{var I=[],H=this.renderer.smooth?this.renderer._smoothedPlotData:this._plotData;this._areaPoints=[];var G=this._yaxis.series_u2p(this.fillToValue);this._xaxis.series_u2p(this.fillToValue);if(W.closePath=!0,"y"==this.fillAxis){I.push([a7[0][0],G]),this._areaPoints.push([a7[0][0],G]);for(var a4=0;a40;a4--){a7.push(J[a4-1])}}else{var E=a8.canvas.height;a7.unshift([a7[0][0],E]);var a=a7.length;a7.push([a7[a-1][0],E])}this._areaPoints=a7,V&&this.renderer.shadowRenderer.draw(a8,a7,W),this.renderer.shapeRenderer.draw(a8,a7,W)}if(S){var Q=a1.extend(!0,{},W,{fill:!1,closePath:!1});if(this.renderer.shapeRenderer.draw(a8,L,Q),this.markerRenderer.show){for(this.renderer.smooth&&(L=this.gridData),a4=0;a4K[0]||null==a3)&&(a3=K[0]),(XK[1]||null==Z)&&(Z=K[1])}if("line"===this.type&&this.renderer.bands.show&&(X=this._yaxis.series_u2p(this.renderer.bands._min),Z=this._yaxis.series_u2p(this.renderer.bands._max)),this._boundingBox=[[a3,X],[Y,Z]],this.markerRenderer.show&&!T){for(this.renderer.smooth&&(a7=this.gridData),a4=0;a4p&&(p=a))}l=null,k=null,m&&(o=this._label._elem.outerWidth(!0),n=this._label._elem.outerHeight(!0)),"xaxis"==this.name?(p+=n,this._elem.css({height:p+"px",left:"0px",bottom:"0px"})):"x2axis"==this.name?(p+=n,this._elem.css({height:p+"px",left:"0px",top:"0px"})):"yaxis"==this.name?(p+=o,this._elem.css({width:p+"px",left:"0px",top:"0px"}),m&&this._label.constructor==a1.jqplot.AxisLabelRenderer&&this._label._elem.css("width",o+"px")):(p+=o,this._elem.css({width:p+"px",right:"0px",top:"0px"}),m&&this._label.constructor==a1.jqplot.AxisLabelRenderer&&this._label._elem.css("width",o+"px"))}},a1.jqplot.LinearAxisRenderer.prototype.createTicks=function(bQ){var bP,bO,bN,bM,bL=this._ticks,bK=this.ticks,bJ=this.name,bI=this._dataBounds,bH="x"===this.name.charAt(0)?this._plotDimensions.width:this._plotDimensions.height,bG=this.min,bF=this.max,bE=this.numberTicks,bD=this.tickInterval,bC=30;if(this._scalefact=(Math.max(bH,bC+1)-bC)/300,bK.length){for(bM=0;bMthis.breakPoints[0]&&bB[0]<=this.breakPoints[1]?(bA.show=!1,bA.showGridline=!1,bA.label=bB[1]):bA.label=bB[1]:bA.label=bB[1],bA.setTick(bB[0],this.name),this._ticks.push(bA)):a1.isPlainObject(bB)?(a1.extend(!0,bA,bB),bA.axis=this.name,this._ticks.push(bA)):(bA.value=bB,this.breakPoints&&(bB==this.breakPoints[0]?(bA.label=this.breakTickLabel,bA._breakTick=!0,bA.showGridline=!1,bA.showMark=!1):bB>this.breakPoints[0]&&bB<=this.breakPoints[1]&&(bA.show=!1,bA.showGridline=!1)),bA.setTick(bB,this.name),this._ticks.push(bA))}this.numberTicks=bK.length,this.min=this._ticks[0].value,this.max=this._ticks[this.numberTicks-1].value,this.tickInterval=(this.max-this.min)/(this.numberTicks-1)}else{bH="xaxis"==bJ||"x2axis"==bJ?this._plotDimensions.width:this._plotDimensions.height;var bz=this.numberTicks;this.alignTicks&&("x2axis"===this.name&&bQ.axes.xaxis.show?bz=bQ.axes.xaxis.numberTicks:"y"===this.name.charAt(0)&&"yaxis"!==this.name&&"yMidAxis"!==this.name&&bQ.axes.yaxis.show&&(bz=bQ.axes.yaxis.numberTicks)),bP=null!=this.min?this.min:bI.min,bO=null!=this.max?this.max:bI.max;var by,bx,bw,bv=bO-bP;if(null!=this.tickOptions&&this.tickOptions.formatString||(this._overrideFormatString=!0),null==this.min||null==this.max&&null==this.tickInterval&&!this.autoscale){this.forceTickAt0&&(bP>0&&(bP=0),0>bO&&(bO=0)),this.forceTickAt100&&(bP>100&&(bP=100),100>bO&&(bO=100));var bu=!1,bt=!1;null!=this.min?bu=!0:null!=this.max&&(bt=!0);var bs=a1.jqplot.LinearTickGenerator(bP,bO,this._scalefact,bz,bu,bt),br=null!=this.min?bP:bP+bv*(this.padMin-1),bq=null!=this.max?bO:bO-bv*(this.padMax-1);(br>bP||bO>bq)&&(br=null!=this.min?bP:bP-bv*(this.padMin-1),bq=null!=this.max?bO:bO+bv*(this.padMax-1),bs=a1.jqplot.LinearTickGenerator(br,bq,this._scalefact,bz,bu,bt)),this.min=bs[0],this.max=bs[1],this.numberTicks=bs[2],this._autoFormatString=bs[3],this.tickInterval=bs[4]}else{if(bP==bO){var bp=0.05;bP>0&&(bp=Math.max(Math.log(bP)/Math.LN10,0.05)),bP-=bp,bO+=bp}if(this.autoscale&&null==this.min&&null==this.max){for(var bo,bn,bm,bl=!1,bk=!1,bM=0;bMbf&&(bf=bh[be])}var bd=(bf-bg)/bf;bj.renderer.constructor==a1.jqplot.BarRenderer?bg>=0&&(bj.fillToZero||bd>0.1)?bl=!0:(bl=!1,bk=bj.fill&&bj.fillToZero&&0>bg&&bf>0?!0:!1):bj.fill?bg>=0&&(bj.fillToZero||bd>0.1)?bl=!0:0>bg&&bf>0&&bj.fillToZero?(bl=!1,bk=!0):(bl=!1,bk=!1):0>bg&&(bl=!1)}}if(bl){this.numberTicks=2+Math.ceil((bH-(this.tickSpacing-1))/this.tickSpacing),this.min=0,bG=0,bn=bO/(this.numberTicks-1),bw=Math.pow(10,Math.abs(Math.floor(Math.log(bn)/Math.LN10))),bn/bw==parseInt(bn/bw,10)&&(bn+=bw),this.tickInterval=Math.ceil(bn/bw)*bw,this.max=this.tickInterval*(this.numberTicks-1)}else{if(bk){this.numberTicks=2+Math.ceil((bH-(this.tickSpacing-1))/this.tickSpacing);var bc=Math.ceil(Math.abs(bP)/bv*(this.numberTicks-1)),bb=this.numberTicks-1-bc;bn=Math.max(Math.abs(bP/bc),Math.abs(bO/bb)),bw=Math.pow(10,Math.abs(Math.floor(Math.log(bn)/Math.LN10))),this.tickInterval=Math.ceil(bn/bw)*bw,this.max=this.tickInterval*bb,this.min=-this.tickInterval*bc}else{null==this.numberTicks&&(this.tickInterval?this.numberTicks=3+Math.ceil(bv/this.tickInterval):this.numberTicks=2+Math.ceil((bH-(this.tickSpacing-1))/this.tickSpacing)),null==this.tickInterval?(bn=bv/(this.numberTicks-1),bw=1>bn?Math.pow(10,Math.abs(Math.floor(Math.log(bn)/Math.LN10))):1,this.tickInterval=Math.ceil(bn*bw*this.pad)/bw):bw=1/this.tickInterval,bo=this.tickInterval*(this.numberTicks-1),bm=(bo-bv)/2,null==this.min&&(this.min=Math.floor(bw*(bP-bm))/bw),null==this.max&&(this.max=this.min+bo)}}var ba,a9=a1.jqplot.getSignificantFigures(this.tickInterval);if(a9.digitsLeft>=a9.significantDigits){ba="%d"}else{var bw=Math.max(0,5-a9.digitsLeft);bw=Math.min(bw,a9.digitsRight),ba="%."+bw+"f"}this._autoFormatString=ba}else{by=null!=this.min?this.min:bP-bv*(this.padMin-1),bx=null!=this.max?this.max:bO+bv*(this.padMax-1),bv=bx-by,null==this.numberTicks&&(null!=this.tickInterval?this.numberTicks=Math.ceil((bx-by)/this.tickInterval)+1:bH>100?this.numberTicks=parseInt(3+(bH-100)/75,10):this.numberTicks=2),null==this.tickInterval&&(this.tickInterval=bv/(this.numberTicks-1)),null==this.max&&(bx=by+this.tickInterval*(this.numberTicks-1)),null==this.min&&(by=bx-this.tickInterval*(this.numberTicks-1));var ba,a9=a1.jqplot.getSignificantFigures(this.tickInterval);if(a9.digitsLeft>=a9.significantDigits){ba="%d"}else{var bw=Math.max(0,5-a9.digitsLeft);bw=Math.min(bw,a9.digitsRight),ba="%."+bw+"f"}this._autoFormatString=ba,this.min=by,this.max=bx}if(this.renderer.constructor==a1.jqplot.LinearAxisRenderer&&""==this._autoFormatString){bv=this.max-this.min;var a8=new this.tickRenderer(this.tickOptions),a7=a8.formatString||a1.jqplot.config.defaultTickFormatString,a7=a7.match(a1.jqplot.sprintf.regex)[0],a6=0;if(a7){if(a7.search(/[fFeEgGpP]/)>-1){var a5=a7.match(/\%\.(\d{0,})?[eEfFgGpP]/);a6=a5?parseInt(a5[1],10):6}else{a7.search(/[di]/)>-1&&(a6=0)}var a4=Math.pow(10,-a6);if(this.tickIntervalthis.breakPoints[0]&&bthis.breakPoints[0]&&bthis.breakPoints[0]&&b=this.breakPoints[1]?(b-G)*A/z:(b+this.breakPoints[1]-this.breakPoints[0]-G)*A/z},this.series_p2u=function(b){return b*z/A+G})):(this.p2u=function(b){return(b-D)*z/A+F},this.u2p=function(b){return(b-F)*A/z+D},"xaxis"==this.name||"x2axis"==this.name?(this.series_u2p=function(b){return(b-F)*A/z},this.series_p2u=function(b){return b*z/A+F}):(this.series_u2p=function(b){return(b-G)*A/z},this.series_p2u=function(b){return b*z/A+G})),this.show){if("xaxis"==this.name||"x2axis"==this.name){for(var y=0;y0?-x._textRenderer.height*Math.cos(-x._textRenderer.angle)/2:-x.getHeight()+x._textRenderer.height*Math.cos(x._textRenderer.angle)/2;break;case"middle":w=-x.getHeight()/2;break;default:w=-x.getHeight()/2}}else{w=-x.getHeight()/2}var u=this.u2p(x.value)+w+"px";x._elem.css("top",u),x.pack()}}if(C){var a=this._label._elem.outerHeight(!0);this._label._elem.css("top",E-A/2-a/2+"px"),"yaxis"==this.name?this._label._elem.css("left","0px"):this._label._elem.css("right","0px"),this._label.pack()}}}H=null};a1.jqplot.LinearTickGenerator=function(D,C,B,A,z,y){if(z=null===z?!1:z,y=null===y||z?!1:y,D===C&&(C=C?0:1),B=B||1,D>C){var x=C;C=D,D=x}var w=[],v=aE(C-D,B),u=a1.jqplot.getSignificantFigures;if(null==A){if(z||y){if(z){w[0]=D,w[2]=Math.ceil((C-D)/v+1),w[1]=D+(w[2]-1)*v;var t=u(D).digitsRight,s=u(v).digitsRight;s>t?w[3]=aH(v):w[3]="%."+t+"f",w[4]=v}else{if(y){w[1]=C,w[2]=Math.ceil((C-D)/v+1),w[0]=C-(w[2]-1)*v;var r=u(C).digitsRight,s=u(v).digitsRight;s>r?w[3]=aH(v):w[3]="%."+r+"f",w[4]=v}}}else{w[0]=Math.floor(D/v)*v,w[1]=Math.ceil(C/v)*v,w[2]=Math.round((w[1]-w[0])/v+1),w[3]=aH(v),w[4]=v}}else{var q=[];if(q[0]=Math.floor(D/v)*v,q[1]=Math.ceil(C/v)*v,q[2]=Math.round((q[1]-q[0])/v+1),q[3]=aH(v),q[4]=v,q[2]===A){w=q}else{var a=aF(q[1]-q[0],A);w[0]=q[0],w[2]=A,w[4]=a,w[3]=aH(a),w[1]=w[0]+(w[2]-1)*w[4]}}return w},a1.jqplot.LinearTickGenerator.bestLinearInterval=aE,a1.jqplot.LinearTickGenerator.bestInterval=aF,a1.jqplot.LinearTickGenerator.bestLinearComponents=aD,a1.jqplot.LinearTickGenerator.bestConstrainedInterval=aG,a1.jqplot.MarkerRenderer=function(a){this.show=!0,this.style="filledCircle",this.lineWidth=2,this.size=9,this.color="#666666",this.shadow=!0,this.shadowAngle=45,this.shadowOffset=1,this.shadowDepth=3,this.shadowAlpha="0.07",this.shadowRenderer=new a1.jqplot.ShadowRenderer,this.shapeRenderer=new a1.jqplot.ShapeRenderer,a1.extend(!0,this,a)},a1.jqplot.MarkerRenderer.prototype.init=function(a){a1.extend(!0,this,a);var f={angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,lineWidth:this.lineWidth,depth:this.shadowDepth,closePath:!0};-1!=this.style.indexOf("filled")&&(f.fill=!0),-1!=this.style.indexOf("ircle")&&(f.isarc=!0,f.closePath=!1),this.shadowRenderer.init(f);var e={fill:!1,isarc:!1,strokeStyle:this.color,fillStyle:this.color,lineWidth:this.lineWidth,closePath:!0};-1!=this.style.indexOf("filled")&&(e.fill=!0),-1!=this.style.indexOf("ircle")&&(e.isarc=!0,e.closePath=!1),this.shapeRenderer.init(e)},a1.jqplot.MarkerRenderer.prototype.drawDiamond=function(r,q,p,o,n){var m=1.2,l=this.size/2/m,k=this.size/2*m,j=[[r-l,q],[r,q+k],[r+l,q],[r,q-k]];this.shadow&&this.shadowRenderer.draw(p,j),this.shapeRenderer.draw(p,j,n)},a1.jqplot.MarkerRenderer.prototype.drawPlus=function(v,u,t,s,r){var q=1,p=this.size/2*q,o=this.size/2*q,n=[[v,u-o],[v,u+o]],m=[[v+p,u],[v-p,u]],a=a1.extend(!0,{},this.options,{closePath:!1});this.shadow&&(this.shadowRenderer.draw(t,n,{closePath:!1}),this.shadowRenderer.draw(t,m,{closePath:!1})),this.shapeRenderer.draw(t,n,a),this.shapeRenderer.draw(t,m,a)},a1.jqplot.MarkerRenderer.prototype.drawX=function(v,u,t,s,r){var q=1,p=this.size/2*q,o=this.size/2*q,n=a1.extend(!0,{},this.options,{closePath:!1}),m=[[v-p,u-o],[v+p,u+o]],a=[[v-p,u+o],[v+p,u-o]];this.shadow&&(this.shadowRenderer.draw(t,m,{closePath:!1}),this.shadowRenderer.draw(t,a,{closePath:!1})),this.shapeRenderer.draw(t,m,n),this.shapeRenderer.draw(t,a,n)},a1.jqplot.MarkerRenderer.prototype.drawDash=function(j,i,p,o,n){var m=1,l=this.size/2*m,k=(this.size/2*m,[[j-l,i],[j+l,i]]);this.shadow&&this.shadowRenderer.draw(p,k),this.shapeRenderer.draw(p,k,n)},a1.jqplot.MarkerRenderer.prototype.drawLine=function(h,g,l,k,j){var i=[h,g];this.shadow&&this.shadowRenderer.draw(l,i),this.shapeRenderer.draw(l,i,j)},a1.jqplot.MarkerRenderer.prototype.drawSquare=function(r,q,p,o,n){var m=1,l=this.size/2/m,k=this.size/2*m,j=[[r-l,q-k],[r-l,q+k],[r+l,q+k],[r+l,q-k]];this.shadow&&this.shadowRenderer.draw(p,j),this.shapeRenderer.draw(p,j,n)},a1.jqplot.MarkerRenderer.prototype.drawCircle=function(j,i,p,o,n){var m=this.size/2,l=2*Math.PI,k=[j,i,m,0,l,!0];this.shadow&&this.shadowRenderer.draw(p,k),this.shapeRenderer.draw(p,k,n)},a1.jqplot.MarkerRenderer.prototype.draw=function(f,e,h,g){if(g=g||{},null==g.show||0!=g.show){switch(g.color&&!g.fillStyle&&(g.fillStyle=g.color),g.color&&!g.strokeStyle&&(g.strokeStyle=g.color),this.style){case"diamond":this.drawDiamond(f,e,h,!1,g);break;case"filledDiamond":this.drawDiamond(f,e,h,!0,g);break;case"circle":this.drawCircle(f,e,h,!1,g);break;case"filledCircle":this.drawCircle(f,e,h,!0,g);break;case"square":this.drawSquare(f,e,h,!1,g);break;case"filledSquare":this.drawSquare(f,e,h,!0,g);break;case"x":this.drawX(f,e,h,!0,g);break;case"plus":this.drawPlus(f,e,h,!0,g);break;case"dash":this.drawDash(f,e,h,!0,g);break;case"line":this.drawLine(f,e,h,!1,g);break;default:this.drawDiamond(f,e,h,!1,g)}}},a1.jqplot.ShadowRenderer=function(a){this.angle=45,this.offset=1,this.alpha=0.07,this.lineWidth=1.5,this.lineJoin="miter",this.lineCap="round",this.closePath=!1,this.fill=!1,this.depth=3,this.strokeStyle="rgba(0,0,0,0.1)",this.isarc=!1,a1.extend(!0,this,a)},a1.jqplot.ShadowRenderer.prototype.init=function(a){a1.extend(!0,this,a)},a1.jqplot.ShadowRenderer.prototype.draw=function(F,E,D){F.save();var C=null!=D?D:{},B=null!=C.fill?C.fill:this.fill,A=null!=C.fillRect?C.fillRect:this.fillRect,z=null!=C.closePath?C.closePath:this.closePath,y=null!=C.offset?C.offset:this.offset,x=null!=C.alpha?C.alpha:this.alpha,w=null!=C.depth?C.depth:this.depth,v=null!=C.isarc?C.isarc:this.isarc,u=null!=C.linePattern?C.linePattern:this.linePattern;F.lineWidth=null!=C.lineWidth?C.lineWidth:this.lineWidth,F.lineJoin=null!=C.lineJoin?C.lineJoin:this.lineJoin,F.lineCap=null!=C.lineCap?C.lineCap:this.lineCap,F.strokeStyle=C.strokeStyle||this.strokeStyle||"rgba(0,0,0,"+x+")",F.fillStyle=C.fillStyle||this.fillStyle||"rgba(0,0,0,"+x+")";for(var t=0;w>t;t++){var s=a1.jqplot.LinePattern(F,u);if(F.translate(Math.cos(this.angle*Math.PI/180)*y,Math.sin(this.angle*Math.PI/180)*y),s.beginPath(),v){F.arc(E[0],E[1],E[2],E[3],E[4],!0)}else{if(A){A&&F.fillRect(E[0],E[1],E[2],E[3])}else{if(E&&E.length){for(var r=!0,a=0;ao;o++){if(null!=(a=arguments[o])){for(var l in a){var k=p[l],j=a[l];p!==j&&(m&&j&&"object"==typeof j&&!j.nodeType?p[l]=a1.jqplot.extend(m,k||(null!=j.length?[]:{}),j):j!==av&&(p[l]=j))}}}return p},a1.jqplot.ThemeEngine.prototype.rename=function(e,d){if("Default"==e||"Default"==d){throw new Error("jqplot.ThemeEngine Error: Cannot rename from/to Default")}if(this.themes.hasOwnProperty(d)){throw new Error("jqplot.ThemeEngine Error: New name already in use.")}if(this.themes.hasOwnProperty(e)){var f=this.copy(e,d);return this.remove(e),f}throw new Error("jqplot.ThemeEngine Error: Old name or new name invalid")},a1.jqplot.ThemeEngine.prototype.copy=function(a,j,i){if("Default"==j){throw new Error("jqplot.ThemeEngine Error: Cannot copy over Default theme")}if(!this.themes.hasOwnProperty(a)){var h="jqplot.ThemeEngine Error: Source name invalid";throw new Error(h)}if(this.themes.hasOwnProperty(j)){var h="jqplot.ThemeEngine Error: Target name invalid";throw new Error(h)}var g=aA(this.themes[a]);return g._name=j,a1.jqplot.extend(!0,g,i),this._add(g),g},a1.jqplot.Theme=function(a,d){"object"==typeof a&&(d=d||a,a=null),a=a||Date.parse(new Date),this._name=a,this.target={backgroundColor:null},this.legend={textColor:null,fontFamily:null,fontSize:null,border:null,background:null},this.title={textColor:null,fontFamily:null,fontSize:null,textAlign:null},this.seriesStyles={},this.series=[],this.grid={drawGridlines:null,gridLineColor:null,gridLineWidth:null,backgroundColor:null,borderColor:null,borderWidth:null,shadow:null},this.axesStyles={label:{},ticks:{}},this.axes={},"string"==typeof d?this._name=d:"object"==typeof d&&a1.jqplot.extend(!0,this,d)};var ar=function(){this.borderColor=null,this.borderWidth=null,this.ticks=new aq,this.label=new ap},aq=function(){this.show=null,this.showGridline=null,this.showLabel=null,this.showMark=null,this.size=null,this.textColor=null,this.whiteSpace=null,this.fontSize=null,this.fontFamily=null},ap=function(){this.textColor=null,this.whiteSpace=null,this.fontSize=null,this.fontFamily=null,this.fontWeight=null},ao=function(){this.color=null,this.lineWidth=null,this.linePattern=null,this.shadow=null,this.fillColor=null,this.showMarker=null,this.markerOptions=new an},an=function(){this.show=null,this.style=null,this.lineWidth=null,this.size=null,this.color=null,this.shadow=null},am=function(){this.color=null,this.seriesColors=null,this.lineWidth=null,this.shadow=null,this.barPadding=null,this.barMargin=null,this.barWidth=null,this.highlightColors=null},al=function(){this.seriesColors=null,this.padding=null,this.sliceMargin=null,this.fill=null,this.shadow=null,this.startAngle=null,this.lineWidth=null,this.highlightColors=null},ak=function(){this.seriesColors=null,this.padding=null,this.sliceMargin=null,this.fill=null,this.shadow=null,this.startAngle=null,this.lineWidth=null,this.innerDiameter=null,this.thickness=null,this.ringMargin=null,this.highlightColors=null},aj=function(){this.color=null,this.lineWidth=null,this.shadow=null,this.padding=null,this.sectionMargin=null,this.seriesColors=null,this.highlightColors=null},ai=function(){this.padding=null,this.backgroundColor=null,this.ringColor=null,this.tickColor=null,this.ringWidth=null,this.intervalColors=null,this.intervalInnerRadius=null,this.intervalOuterRadius=null,this.hubRadius=null,this.needleThickness=null,this.needlePad=null};a1.fn.jqplotChildText=function(){return a1(this).contents().filter(function(){return 3==this.nodeType}).text()},a1.fn.jqplotGetComputedFontStyle=function(){for(var g=window.getComputedStyle?window.getComputedStyle(this[0],""):this[0].currentStyle,f=g["font-style"]?["font-style","font-weight","font-size","font-family"]:["fontStyle","fontWeight","fontSize","fontFamily"],j=[],i=0;is;s++){w+=T[s],a3.measureText(w).width>U&&w.length>T[s].length&&(v.push(s),w="",s--)}if(0===v.length){"center"===a1(a4).css("textAlign")&&(t=Y+(W-a3.measureText(w).width)/2-A),a3.fillText(Z,t,X)}else{w=T.slice(0,v[0]).join(" "),"center"===a1(a4).css("textAlign")&&(t=Y+(W-a3.measureText(w).width)/2-A),a3.fillText(w,t,u),u+=V;for(var s=1,c=v.length;c>s;s++){w=T.slice(v[s-1],v[s]).join(" "),"center"===a1(a4).css("textAlign")&&(t=Y+(W-a3.measureText(w).width)/2-A),a3.fillText(w,t,u),u+=V}w=T.slice(v[s-1],T.length).join(" "),"center"===a1(a4).css("textAlign")&&(t=Y+(W-a3.measureText(w).width)/2-A),a3.fillText(w,t,u)}}function O(u,t,s){var r=u.tagName.toLowerCase(),q=a1(u).position(),p=window.getComputedStyle?window.getComputedStyle(u,""):u.currentStyle,o=t+q.left+parseInt(p.marginLeft,10)+parseInt(p.borderLeftWidth,10)+parseInt(p.paddingLeft,10),m=s+q.top+parseInt(p.marginTop,10)+parseInt(p.borderTopWidth,10)+parseInt(p.paddingTop,10),e=G.width;if("div"!=r&&"span"!=r||a1(u).hasClass("jqplot-highlighter-tooltip")){if("table"===r&&a1(u).hasClass("jqplot-table-legend")){a.strokeStyle=a1(u).css("border-top-color"),a.fillStyle=a1(u).css("background-color"),a.fillRect(o,m,a1(u).innerWidth(),a1(u).innerHeight()),parseInt(a1(u).css("border-top-width"),10)>0&&a.strokeRect(o,m,a1(u).innerWidth(),a1(u).innerHeight()),a1(u).find("div.jqplot-table-legend-swatch-outline").each(function(){var h=a1(this);a.strokeStyle=h.css("border-top-color");var n=o+h.position().left,l=m+h.position().top;a.strokeRect(n,l,h.innerWidth(),h.innerHeight()),n+=parseInt(h.css("padding-left"),10),l+=parseInt(h.css("padding-top"),10);var k=h.innerHeight()-2*parseInt(h.css("padding-top"),10),j=h.innerWidth()-2*parseInt(h.css("padding-left"),10),i=h.children("div.jqplot-table-legend-swatch");a.fillStyle=i.css("background-color"),a.fillRect(n,l,j,k)}),a1(u).find("td.jqplot-table-legend-label").each(function(){var f=a1(this),h=o+f.position().left,g=m+f.position().top+parseInt(f.css("padding-top"),10);a.font=f.jqplotGetComputedFontStyle(),a.fillStyle=f.css("color"),P(f,a,f.text(),h,g,e)})}else{"canvas"==r&&a.drawImage(u,o,m)}}else{a1(u).children().each(function(){O(this,o,m)});var d=a1(u).jqplotChildText();d&&(a.font=a1(u).jqplotGetComputedFontStyle(),a.fillStyle=a1(u).css("color"),P(u,a,d,o,m,e))}}R=R||{};var N=null==R.x_offset?0:R.x_offset,M=null==R.y_offset?0:R.y_offset,L=null==R.backgroundColor?"rgb(255,255,255)":R.backgroundColor;if(0==a1(this).width()||0==a1(this).height()){return null}if(a1.jqplot.use_excanvas){return null}for(var K,J,I,H,G=document.createElement("canvas"),F=a1(this).outerHeight(!0),E=a1(this).outerWidth(!0),D=a1(this).offset(),C=D.left,B=D.top,A=0,z=0,y=["jqplot-table-legend","jqplot-xaxis-tick","jqplot-x2axis-tick","jqplot-yaxis-tick","jqplot-y2axis-tick","jqplot-y3axis-tick","jqplot-y4axis-tick","jqplot-y5axis-tick","jqplot-y6axis-tick","jqplot-y7axis-tick","jqplot-y8axis-tick","jqplot-y9axis-tick","jqplot-xaxis-label","jqplot-x2axis-label","jqplot-yaxis-label","jqplot-y2axis-label","jqplot-y3axis-label","jqplot-y4axis-label","jqplot-y5axis-label","jqplot-y6axis-label","jqplot-y7axis-label","jqplot-y8axis-label","jqplot-y9axis-label"],x=0;xJ&&(E=E-A-J,A=-J),-z>K&&(F=F-z-K,z=-K),H>E&&(E=H),I>F&&(F=I)})}G.width=E+Number(N),G.height=F+Number(M);var a=G.getContext("2d");return a.save(),a.fillStyle=L,a.fillRect(0,0,G.width,G.height),a.restore(),a.translate(A,z),a.textAlign="left",a.textBaseline="top",a1(this).children().each(function(){O(this,N,M)}),G},a1.fn.jqplotToImageStr=function(a){var d=a1(this).jqplotToImageCanvas(a);return d?d.toDataURL("image/png"):null},a1.fn.jqplotToImageElem=function(a){var f=document.createElement("img"),e=a1(this).jqplotToImageStr(a);return f.src=e,f},a1.fn.jqplotToImageElemStr=function(a){var d="";return d},a1.fn.jqplotSaveImage=function(){var a=a1(this).jqplotToImageStr({});a&&(window.location.href=a.replace("image/png","image/octet-stream"))},a1.fn.jqplotViewImage=function(){var a=a1(this).jqplotToImageElemStr({});a1(this).jqplotToImageStr({});if(a){var d=window.open("");d.document.open("image/png"),d.document.write(a),d.document.close(),d=null}};var ah=function(){switch(this.syntax=ah.config.syntax,this._type="jsDate",this.proxy=new Date,this.options={},this.locale=ah.regional.getLocale(),this.formatString="",this.defaultCentury=ah.config.defaultCentury,arguments.length){case 0:break;case 1:if("[object Object]"==ax(arguments[0])&&"jsDate"!=arguments[0]._type){var e=this.options=arguments[0];this.syntax=e.syntax||this.syntax,this.defaultCentury=e.defaultCentury||this.defaultCentury,this.proxy=ah.createDate(e.date)}else{this.proxy=ah.createDate(arguments[0])}break;default:for(var d=[],f=0;f0?"floor":"ceil"](h)},ah.prototype.getAbbrDayName=function(){return ah.regional[this.locale].dayNamesShort[this.proxy.getDay()]},ah.prototype.getAbbrMonthName=function(){return ah.regional[this.locale].monthNamesShort[this.proxy.getMonth()]},ah.prototype.getAMPM=function(){return this.proxy.getHours()>=12?"PM":"AM"},ah.prototype.getAmPm=function(){return this.proxy.getHours()>=12?"pm":"am"},ah.prototype.getCentury=function(){return parseInt(this.proxy.getFullYear()/100,10)},ah.prototype.getDate=function(){return this.proxy.getDate()},ah.prototype.getDay=function(){return this.proxy.getDay()},ah.prototype.getDayOfWeek=function(){var b=this.proxy.getDay();return 0===b?7:b},ah.prototype.getDayOfYear=function(){var d=this.proxy,c=d-new Date(""+d.getFullYear()+"/1/1 GMT");return c+=60000*d.getTimezoneOffset(),d=null,parseInt(c/60000/60/24,10)+1},ah.prototype.getDayName=function(){return ah.regional[this.locale].dayNames[this.proxy.getDay()]},ah.prototype.getFullWeekOfYear=function(){var f=this.proxy,e=this.getDayOfYear(),h=6-f.getDay(),g=parseInt((e+h)/7,10);return g},ah.prototype.getFullYear=function(){return this.proxy.getFullYear()},ah.prototype.getGmtOffset=function(){var d=this.proxy.getTimezoneOffset()/60,c=0>d?"+":"-";return d=Math.abs(d),c+af(Math.floor(d),2)+":"+af(d%1*60,2)},ah.prototype.getHours=function(){return this.proxy.getHours()},ah.prototype.getHours12=function(){var b=this.proxy.getHours();return b>12?b-12:0==b?12:b},ah.prototype.getIsoWeek=function(){var f=this.proxy,e=this.getWeekOfYear(),h=new Date(""+f.getFullYear()+"/1/1").getDay(),g=e+(h>4||1>=h?0:1);return 53==g&&new Date(""+f.getFullYear()+"/12/31").getDay()<4?g=1:0===g&&(f=new ah(new Date(""+(f.getFullYear()-1)+"/12/31")),g=f.getIsoWeek()),f=null,g},ah.prototype.getMilliseconds=function(){return this.proxy.getMilliseconds()},ah.prototype.getMinutes=function(){return this.proxy.getMinutes()},ah.prototype.getMonth=function(){return this.proxy.getMonth()},ah.prototype.getMonthName=function(){return ah.regional[this.locale].monthNames[this.proxy.getMonth()]},ah.prototype.getMonthNumber=function(){return this.proxy.getMonth()+1},ah.prototype.getSeconds=function(){return this.proxy.getSeconds()},ah.prototype.getShortYear=function(){return this.proxy.getYear()%100},ah.prototype.getTime=function(){return this.proxy.getTime()},ah.prototype.getTimezoneAbbr=function(){return this.proxy.toString().replace(/^.*\(([^)]+)\)$/,"$1")},ah.prototype.getTimezoneName=function(){var b=/(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString());return b[1]||b[2]||"GMT"+this.getGmtOffset()},ah.prototype.getTimezoneOffset=function(){return this.proxy.getTimezoneOffset()},ah.prototype.getWeekOfYear=function(){var e=this.getDayOfYear(),d=7-this.getDayOfWeek(),f=parseInt((e+d)/7,10);return f},ah.prototype.getUnix=function(){return Math.round(this.proxy.getTime()/1000,0)},ah.prototype.getYear=function(){return this.proxy.getYear()},ah.prototype.next=function(b){return b=b||"day",this.clone().add(1,b)},ah.prototype.set=function(){switch(arguments.length){case 0:this.proxy=new Date;break;case 1:if("[object Object]"==ax(arguments[0])&&"jsDate"!=arguments[0]._type){var e=this.options=arguments[0];this.syntax=e.syntax||this.syntax,this.defaultCentury=e.defaultCentury||this.defaultCentury,this.proxy=ah.createDate(e.date)}else{this.proxy=ah.createDate(arguments[0])}break;default:for(var d=[],f=0;f0?"floor":"ceil"](d/12));var f=e.getMonth()+d%12;12==f?(f=0,e.setYear(e.getFullYear()+1)):-1==f&&(f=11,e.setYear(e.getFullYear()-1)),e.setMonth(f)},diff:function(g,f){var j=g.getFullYear()-f.getFullYear(),i=g.getMonth()-f.getMonth()+12*j,h=g.getDate()-f.getDate();return i+h/30}},year:{add:function(d,c){d.setYear(d.getFullYear()+Math[c>0?"floor":"ceil"](c))},diff:function(d,c){return ae.month.diff(d,c)/12}}};for(var ad in ae){"s"!=ad.substring(ad.length-1)&&(ae[ad+"s"]=ae[ad])}var ac=function(g,f,j){if(ah.formats[j].shortcuts[f]){return ah.strftime(g,ah.formats[j].shortcuts[f],j)}var i=(ah.formats[j].codes[f]||"").split("."),h=g["get"+i[0]]?g["get"+i[0]]():"";return i[1]&&(h=af(h,i[1])),h};ah.strftime=function(r,q,p,o){var n="perl",m=ah.regional.getLocale();p&&ah.formats.hasOwnProperty(p)?n=p:p&&ah.regional.hasOwnProperty(p)&&(m=p),o&&ah.formats.hasOwnProperty(o)?n=o:o&&ah.regional.hasOwnProperty(o)&&(m=o),("[object Object]"!=ax(r)||"jsDate"!=r._type)&&(r=new ah(r),r.locale=m),q||(q=r.formatString||ah.regional[m].formatString);for(var l,k=q||"%Y-%m-%d",j="";k.length>0;){(l=k.match(ah.formats[n].codes.matcher))?(j+=k.slice(0,l.index),j+=(l[1]||"")+ac(r,l[2],n),k=k.slice(l.index+l[0].length)):(j+=k,k="")}return j},ah.formats={ISO:"%Y-%m-%dT%H:%M:%S.%N%G",SQL:"%Y-%m-%d %H:%M:%S"},ah.formats.perl={codes:{matcher:/()%(#?(%|[a-z]))/i,Y:"FullYear",y:"ShortYear.2",m:"MonthNumber.2","#m":"MonthNumber",B:"MonthName",b:"AbbrMonthName",d:"Date.2","#d":"Date",e:"Date",A:"DayName",a:"AbbrDayName",w:"Day",H:"Hours.2","#H":"Hours",I:"Hours12.2","#I":"Hours12",p:"AMPM",M:"Minutes.2","#M":"Minutes",S:"Seconds.2","#S":"Seconds",s:"Unix",N:"Milliseconds.3","#N":"Milliseconds",O:"TimezoneOffset",Z:"TimezoneName",G:"GmtOffset"},shortcuts:{F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",D:"%m/%d/%y","#c":"%a %b %e %H:%M:%S %Y",v:"%e-%b-%Y",R:"%H:%M",r:"%I:%M:%S %p",t:" ",n:"\n","%":"%"}},ah.formats.php={codes:{matcher:/()%((%|[a-z]))/i,a:"AbbrDayName",A:"DayName",d:"Date.2",e:"Date",j:"DayOfYear.3",u:"DayOfWeek",w:"Day",U:"FullWeekOfYear.2",V:"IsoWeek.2",W:"WeekOfYear.2",b:"AbbrMonthName",B:"MonthName",m:"MonthNumber.2",h:"AbbrMonthName",C:"Century.2",y:"ShortYear.2",Y:"FullYear",H:"Hours.2",I:"Hours12.2",l:"Hours12",p:"AMPM",P:"AmPm",M:"Minutes.2",S:"Seconds.2",s:"Unix",O:"TimezoneOffset",z:"GmtOffset",Z:"TimezoneAbbr"},shortcuts:{D:"%m/%d/%y",F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",R:"%H:%M",r:"%I:%M:%S %p",t:" ",n:"\n","%":"%"}},ah.createDate=function(x){function w(F,E){var D,C,B,A,z=parseFloat(E[1]),y=parseFloat(E[2]),l=parseFloat(E[3]),k=ah.config.defaultCentury;return z>31?(C=l,B=y,D=k+z):(C=y,B=z,D=k+l),A=B+"/"+C+"/"+D,F.replace(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})/,A)}if(null==x){return new Date}if(x instanceof Date){return x}if("number"==typeof x){return new Date(x)}var v=String(x).replace(/^\s*(.+)\s*$/g,"$1");v=v.replace(/^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,4})/,"$1/$2/$3"),v=v.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{4})/i,"$1 $2 $3");var u=v.match(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i);if(u&&u.length>3){var t=parseFloat(u[3]),s=ah.config.defaultCentury+t;s=String(s),v=v.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i,u[1]+" "+u[2]+" "+s)}u=v.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})[^0-9]/),u&&u.length>3&&(v=w(v,u));var u=v.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})$/);u&&u.length>3&&(v=w(v,u));for(var r,q,p,o=0,n=ah.matchers.length,m=v;n>o;){if(q=Date.parse(m),!isNaN(q)){return new Date(q)}if(r=ah.matchers[o],"function"==typeof r){if(p=r.call(ah,m),p instanceof Date){return p}}else{m=v.replace(r[0],r[1])}o++}return NaN},ah.daysInMonth=function(d,c){return 2==c?29==new Date(d,1,29).getDate()?29:28:[av,31,av,31,30,31,30,31,31,30,31,30,31][c]},ah.matchers=[[/(3[01]|[0-2]\d)\s*\.\s*(1[0-2]|0\d)\s*\.\s*([1-9]\d{3})/,"$2/$1/$3"],[/([1-9]\d{3})\s*-\s*(1[0-2]|0\d)\s*-\s*(3[01]|[0-2]\d)/,"$2/$3/$1"],function(f){var e=f.match(/^(?:(.+)\s+)?([012]?\d)(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d(\.\d*)?))?\s*(am|pm)?\s*$/i);if(e){if(e[1]){var h=this.createDate(e[1]);if(isNaN(h)){return}}else{var h=new Date;h.setMilliseconds(0)}var g=parseFloat(e[2]);return e[6]&&(g="am"==e[6].toLowerCase()?12==g?0:g:12==g?12:g+12),h.setHours(g,parseInt(e[3]||0,10),parseInt(e[4]||0,10),1000*(parseFloat(e[5]||0)||0)),h}return f},function(f){var e=f.match(/^(?:(.+))[T|\s+]([012]\d)(?:\:(\d\d))(?:\:(\d\d))(?:\.\d+)([\+\-]\d\d\:\d\d)$/i);if(e){if(e[1]){var h=this.createDate(e[1]);if(isNaN(h)){return}}else{var h=new Date;h.setMilliseconds(0)}var g=parseFloat(e[2]);return h.setHours(g,parseInt(e[3],10),parseInt(e[4],10),1000*parseFloat(e[5])),h}return f},function(r){var q=r.match(/^([0-3]?\d)\s*[-\/.\s]{1}\s*([a-zA-Z]{3,9})\s*[-\/.\s]{1}\s*([0-3]?\d)$/);if(q){var p,o,n,m=new Date,l=ah.config.defaultCentury,k=parseFloat(q[1]),j=parseFloat(q[3]);k>31?(o=j,p=l+k):(o=k,p=l+j);var n=ay(q[2],ah.regional[ah.regional.getLocale()].monthNamesShort);return -1==n&&(n=ay(q[2],ah.regional[ah.regional.getLocale()].monthNames)),m.setFullYear(p,n,o),m.setHours(0,0,0,0),m}return r}],a1.jsDate=ah,a1.jqplot.sprintf=function(){function a(g,f,q,i){var h=g.length>=f?"":Array(1+f-g.length>>>0).join(q);return i?g+h:h+g}function p(e){for(var g=new String(e),f=10;f>0&&g!=(g=g.replace(/^(\d+)(\d{3})/,"$1"+a1.jqplot.sprintf.thousandsSeparator+"$2"));f--){}return g}function o(b,w,v,u,t,s){var r=u-b.length;if(r>0){var q=" ";s&&(q=" "),b=v||!t?a(b,u,q,v):b.slice(0,w.length)+a("",r,"0",!0)+b.slice(w.length)}return b}function n(w,v,u,t,s,r,q,d){var b=w>>>0;return u=u&&b&&{2:"0b",8:"0",16:"0x"}[v]||"",w=u+a(b.toString(v),r||0,"0",!1),o(w,u,t,s,q,d)}function m(h,d,s,r,q,i){return null!=r&&(h=h.slice(0,r)),o(h,"",d,s,q,i)}var l=arguments,k=0,j=l[k++];return j.replace(a1.jqplot.sprintf.regex,function(Y,X,W,V,U,T,S){if("%%"==Y){return"%"}for(var R=!1,P="",N=!1,L=!1,J=!1,H=!1,g=0;W&&gV&&(V=-V,R=!0),!isFinite(V)){throw new Error("$.jqplot.sprintf: (minimum-)width must be finite")}T=T?"*"==T?+l[k++]:"*"==T.charAt(0)?+l[T.slice(1,-1)]:+T:"fFeE".indexOf(S)>-1?6:"d"==S?0:void 0;var e=X?l[X.slice(0,-1)]:l[k++];switch(S){case"s":return null==e?"":m(String(e),R,V,T,N,J);case"c":return m(String.fromCharCode(+e),R,V,T,N,J);case"b":return n(e,2,L,R,V,T,N,J);case"o":return n(e,8,L,R,V,T,N,J);case"x":return n(e,16,L,R,V,T,N,J);case"X":return n(e,16,L,R,V,T,N,J).toUpperCase();case"u":return n(e,10,L,R,V,T,N,J);case"i":var d=parseInt(+e,10);if(isNaN(d)){return""}var c=0>d?"-":P,b=H?p(String(Math.abs(d))):String(Math.abs(d));return e=c+a(b,T,"0",!1),o(e,c,R,V,N,J);case"d":var d=Math.round(+e);if(isNaN(d)){return""}var c=0>d?"-":P,b=H?p(String(Math.abs(d))):String(Math.abs(d));return e=c+a(b,T,"0",!1),o(e,c,R,V,N,J);case"e":case"E":case"f":case"F":case"g":case"G":var d=+e;if(isNaN(d)){return""}var c=0>d?"-":P,Q=["toExponential","toFixed","toPrecision"]["efg".indexOf(S.toLowerCase())],O=["toString","toUpperCase"]["eEfFgG".indexOf(S)%2],b=Math.abs(d)[Q](T),M=b.toString().split(".");M[0]=H?p(M[0]):M[0],b=M.join(a1.jqplot.sprintf.decimalMark),e=c+b;var K=o(e,c,R,V,N,J)[O]();return K;case"p":case"P":var d=+e;if(isNaN(d)){return""}var c=0>d?"-":P,M=String(Number(Math.abs(d)).toExponential()).split(/e|E/),I=-1!=M[0].indexOf(".")?M[0].length-1:String(d).length,h=M[1]<0?-M[1]-1:0;if(Math.abs(d)<1){e=T>=I+h?c+Math.abs(d).toPrecision(I):T-1>=I?c+Math.abs(d).toExponential(I-1):c+Math.abs(d).toExponential(T-1)}else{var f=T>=I?I:T;e=c+Math.abs(d).toPrecision(f)}var O=["toString","toUpperCase"]["pP".indexOf(S)%2];return o(e,c,R,V,N,J)[O]();case"n":return"";default:return Y}})},a1.jqplot.sprintf.thousandsSeparator=",",a1.jqplot.sprintf.decimalMark=".",a1.jqplot.sprintf.regex=/%%|%(\d+\$)?([-+#0&\' ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g,a1.jqplot.getSignificantFigures=function(i){var h=String(Number(Math.abs(i)).toExponential()).split(/e|E/),n=-1!=h[0].indexOf(".")?h[0].length-1:h[0].length,m=h[1]<0?-h[1]-1:0,l=parseInt(h[1],10),k=l+1>0?l+1:0,j=k>=n?0:n-l-1;return{significantDigits:n,digitsLeft:k,digitsRight:j,zeros:m,exponent:l}},a1.jqplot.getPrecision=function(a){return a1.jqplot.getSignificantFigures(a).digitsRight};var ab=a1.uiBackCompat!==!1;a1.jqplot.effects={effect:{}};var aa="jqplot.storage.";a1.extend(a1.jqplot.effects,{version:"1.9pre",save:function(e,d){for(var f=0;f").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),h={width:a.width(),height:a.height()},g=document.activeElement;return a.wrap(i),(a[0]===g||a1.contains(a[0],g))&&a1(g).focus(),i=a.parent(),"static"===a.css("position")?(i.css({position:"relative"}),a.css({position:"relative"})):(a1.extend(j,{position:a.css("position"),zIndex:a.css("z-index")}),a1.each(["top","left","bottom","right"],function(b,c){j[c]=a.css(c),isNaN(parseInt(j[c],10))&&(j[c]="auto")}),a.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),a.css(h),i.css(j).show()},removeWrapper:function(a){var d=document.activeElement;return a.parent().is(".ui-effects-wrapper")&&(a.parent().replaceWith(a),(a[0]===d||a1.contains(a[0],d))&&a1(d).focus()),a}}),a1.fn.extend({jqplotEffect:function(t,s,r,q){function p(g){function k(){a1.isFunction(i)&&i.call(j[0]),a1.isFunction(g)&&g()}var j=a1(this),i=o.complete,h=o.mode;(j.is(":hidden")?"hide"===h:"show"===h)?k():l.call(j[0],o,k)}var o=aw.apply(this,arguments),n=o.mode,m=o.queue,l=a1.jqplot.effects.effect[o.effect],a=!l&&ab&&a1.jqplot.effects[o.effect];return a1.fx.off||!l&&!a?n?this[n](o.duration,o.complete):this.each(function(){o.complete&&o.complete.call(this)}):l?m===!1?this.each(p):this.queue(m||"fx",p):a.call(this,{options:o,duration:o.duration,callback:o.complete,mode:o.mode})}});var aB=/up|down|vertical/,a2=/up|left|vertical|horizontal/;a1.jqplot.effects.effect.blind=function(D,C){var B,A,z,y=a1(this),x=["position","top","bottom","left","right","height","width"],w=a1.jqplot.effects.setMode(y,D.mode||"hide"),v=D.direction||"up",u=aB.test(v),t=u?"height":"width",s=u?"top":"left",r=a2.test(v),q={},a="show"===w;y.parent().is(".ui-effects-wrapper")?a1.jqplot.effects.save(y.parent(),x):a1.jqplot.effects.save(y,x),y.show(),z=parseInt(y.css("top"),10),B=a1.jqplot.effects.createWrapper(y).css({overflow:"hidden"}),A=u?B[t]()+z:B[t](),q[t]=a?String(A):"0",r||(y.css(u?"bottom":"right",0).css(u?"top":"left","").css({position:"absolute"}),q[s]=a?"0":String(A)),a&&(B.css(t,0),r||B.css(s,A)),B.animate(q,{duration:D.duration,easing:D.easing,queue:!1,complete:function(){"hide"===w&&y.hide(),a1.jqplot.effects.restore(y,x),a1.jqplot.effects.removeWrapper(y),C()}})}}(jQuery);(function(h){h.jqplot.DateAxisRenderer=function(){h.jqplot.LinearAxisRenderer.call(this);this.date=new h.jsDate()};var c=1000;var e=60*c;var f=60*e;var l=24*f;var b=7*l;var j=30.4368499*l;var k=365.242199*l;var g=[31,28,31,30,31,30,31,30,31,30,31,30];var i=["%M:%S.%#N","%M:%S.%#N","%M:%S.%#N","%M:%S","%M:%S","%M:%S","%M:%S","%H:%M:%S","%H:%M:%S","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%a %H:%M","%a %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%v","%v","%v","%v","%v","%v","%v"];var m=[0.1*c,0.2*c,0.5*c,c,2*c,5*c,10*c,15*c,30*c,e,2*e,5*e,10*e,15*e,30*e,f,2*f,4*f,6*f,8*f,12*f,l,2*l,3*l,4*l,5*l,b,2*b];var d=[];function a(p,s,t){var o=Number.MAX_VALUE;var u,r,v;for(var q=0,n=m.length;qC.max)||C.max==null){C.max=y[r][0]}if(r>0){o=Math.abs(y[r][0]-y[r-1][0]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}x+=o}else{y[r][1]=new h.jsDate(y[r][1]).getTime();A[r][1]=new h.jsDate(y[r][1]).getTime();z[r][1]=new h.jsDate(y[r][1]).getTime();if((y[r][1]!=null&&y[r][1]C.max)||C.max==null){C.max=y[r][1]}if(r>0){o=Math.abs(y[r][1]-y[r-1][1]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}}x+=o}if(D.renderer.bands){if(D.renderer.bands.hiData.length){var w=D.renderer.bands.hiData;for(var r=0,q=w.length;rC.max)||C.max==null){C.max=w[r][0]}}else{w[r][1]=new h.jsDate(w[r][1]).getTime();if((w[r][1]!=null&&w[r][1]>C.max)||C.max==null){C.max=w[r][1]}}}}if(D.renderer.bands.lowData.length){var w=D.renderer.bands.lowData;for(var r=0,q=w.length;r6){D=6}}var V=new h.jsDate(ae).setDate(1).setHours(0,0,0,0);var q=new h.jsDate(J);var z=new h.jsDate(J).setDate(1).setHours(0,0,0,0);if(q.getTime()!==z.getTime()){z=z.add(1,"month")}var S=z.diff(V,"month");ab=Math.ceil(S/D)+1;this.min=V.getTime();this.max=V.clone().add((ab-1)*D,"month").getTime();this.numberTicks=ab;for(var aa=0;aa200){this.numberTicks=parseInt(3+(n-200)/100,10)}else{this.numberTicks=2}}}O=B/(this.numberTicks-1)/1000;if(this.daTickInterval==null){this.daTickInterval=[O,"seconds"]}for(var aa=0;aa")';var k=document.createElement("iframe");k.name="printIframe";k.id=i;k.className="MSIE";document.body.appendChild(k);k.src=l}else{var h=b("