diff --git a/.github/workflows/Autogen.yml b/.github/workflows/Autogen.yml index 3cfc74d1b..23595d890 100644 --- a/.github/workflows/Autogen.yml +++ b/.github/workflows/Autogen.yml @@ -10,7 +10,6 @@ concurrency: jobs: canfigurator: - if: false # FIXME Enable when compilation of header files succeeds name: CANfigurator runs-on: ubuntu-latest permissions: diff --git a/Autogen/CAN/Doc/GRCAN.CANdo b/Autogen/CAN/Doc/GRCAN.CANdo index 4724122c0..ff7e1c430 100644 --- a/Autogen/CAN/Doc/GRCAN.CANdo +++ b/Autogen/CAN/Doc/GRCAN.CANdo @@ -1,21 +1,21 @@ Bus ID: - Testing: 0 # Testing Bus - Primary: 1 # Primary Bus - Data: 2 # Data Bus - Charger: 3 # Charger Bus + Testing: 0 + Primary: 1 + Data: 2 + Charger: 3 routing: messages: - ACU: + BCU: CAN1: Debugger: - msg: Debug 2.0 - msg: Ping ECU: - msg: Ping - - msg: ACU Status 1 - - msg: ACU Status 2 - - msg: ACU Status 3 + - msg: BCU Status 1 + - msg: BCU Status 2 + - msg: BCU Status 3 - msg: DC-DC Status CAN2: Debugger: @@ -23,18 +23,18 @@ routing: - msg: Ping ECU: - msg: Ping - - msg: ACU Cell Data 1 - - msg: ACU Cell Data 2 - - msg: ACU Cell Data 3 - - msg: ACU Cell Data 4 - - msg: ACU Cell Data 5 + - msg: BCU Cell Data 1 + - msg: BCU Cell Data 2 + - msg: BCU Cell Data 3 + - msg: BCU Cell Data 4 + - msg: BCU Cell Data 5 CAN3: Charger: - msg: Charger Control can_id_override: 0x1806E5F4 Charger: CAN3: - ACU: + BCU: - msg: Charger Data can_id_override: 0x18FF50E5 Dash Panel: @@ -51,7 +51,7 @@ routing: - msg: Debug 2.0 - msg: Ping - msg: ECU config - ACU: + BCU: - msg: Debug 2.0 - msg: Ping TCM: @@ -60,16 +60,7 @@ routing: Dash Panel: - msg: Debug 2.0 - msg: Ping - GR Inverter 1: - - msg: Debug 2.0 - - msg: Ping - GR Inverter 2: - - msg: Debug 2.0 - - msg: Ping - GR Inverter 3: - - msg: Debug 2.0 - - msg: Ping - GR Inverter 4: + GR Inverter: - msg: Debug 2.0 - msg: Ping Fan Controller 1: @@ -81,98 +72,16 @@ routing: Fan Controller 3: - msg: Debug 2.0 - msg: Ping - Fan Controller 4: - - msg: Debug 2.0 - - msg: Ping - Fan Controller 5: - - msg: Debug 2.0 - - msg: Ping - Fan Controller 6: - - msg: Debug 2.0 - - msg: Ping - Fan Controller 7: - - msg: Debug 2.0 - - msg: Ping - Fan Controller 8: - - msg: Debug 2.0 - - msg: Ping - LV DC-DC: - - msg: Debug 2.0 - - msg: Ping - - msg: Ping CAN2: ECU: - msg: Debug FD - msg: Ping - ACU: + BCU: - msg: Debug FD - msg: Ping TCM: - msg: Debug FD - msg: Ping - Steering Wheel: - - msg: Debug FD - - msg: Ping - SAM1: - - msg: Debug FD - - msg: Ping - SAM2: - - msg: Debug FD - - msg: Ping - SAM3: - - msg: Debug FD - - msg: Ping - SAM4: - - msg: Debug FD - - msg: Ping - SAM5: - - msg: Debug FD - - msg: Ping - SAM6: - - msg: Debug FD - - msg: Ping - SAM7: - - msg: Debug FD - - msg: Ping - SAM8: - - msg: Debug FD - - msg: Ping - SAM9: - - msg: Debug FD - - msg: Ping - SAM10: - - msg: Debug FD - - msg: Ping - SAM11: - - msg: Debug FD - - msg: Ping - SAM12: - - msg: Debug FD - - msg: Ping - SAM13: - - msg: Debug FD - - msg: Ping - SAM14: - - msg: Debug FD - - msg: Ping - SAM15: - - msg: Debug FD - - msg: Ping - SAM16: - - msg: Debug FD - - msg: Ping - SAM17: - - msg: Debug FD - - msg: Ping - SAM18: - - msg: Debug FD - - msg: Ping - SAM19: - - msg: Debug FD - - msg: Ping - SAM20: - - msg: Debug FD - - msg: Ping CAN3: Charging SDC: - msg: Ping @@ -219,62 +128,42 @@ routing: Debugger: - msg: Debug 2.0 - msg: Ping - ECU: + BCU: + - msg: BCU Precharge + - msg: BCU Config Charge Parameters + - msg: BCU Config Operational Parameters - msg: Ping - - msg: ECU Status 1 - - msg: ECU Status 2 - - msg: ECU Status 3 - ACU: - - msg: ACU Precharge - - msg: ACU Config Charge Parameters - - msg: ACU Config Operational Parameters - GR Inverter 1: - - msg: Inverter Config - - msg: Inverter Command - GR Inverter 2: - - msg: Inverter Config - - msg: Inverter Command - GR Inverter 3: - - msg: Inverter Config - - msg: Inverter Command - GR Inverter 4: + GR Inverter: - msg: Inverter Config - msg: Inverter Command + - msg: Ping Fan Controller 1: - msg: Fan Command + - msg: Ping Fan Controller 2: - msg: Fan Command + - msg: Ping Fan Controller 3: - msg: Fan Command - Fan Controller 4: - - msg: Fan Command - Fan Controller 5: - - msg: Fan Command - Fan Controller 6: - - msg: Fan Command - Fan Controller 7: - - msg: Fan Command - Fan Controller 8: - - msg: Fan Command + - msg: Ping Dash Panel: - msg: Dash Config - - msg: Dash Warning Flags - - msg: Specific Brake IR + - msg: Ping + ALL: + - msg: ECU Status 1 + - msg: ECU Status 2 + - msg: ECU Status 3 + TCM: + - msg: Ping CAN2: Debugger: - msg: Debug FD - msg: Ping - ECU: - - msg: Ping - Steering Wheel: - - msg: Steering Config - - msg: ECU Ping Information TCM: - msg: ECU Pedals Data - can_id_override: 0x2020000 Energy Meter: CAN3: - ACU: + BCU: - msg: EM Measurement can_id_override: 0x10d - msg: EM Team Data 1 @@ -285,7 +174,6 @@ routing: can_id_override: 0x40d - msg: EM Temperature can_id_override: 0x60d - Fan Controller 1: CAN1: Debugger: @@ -310,77 +198,7 @@ routing: ECU: - msg: Ping - msg: Fan Status - Fan Controller 4: - CAN1: - Debugger: - - msg: Debug 2.0 - - msg: Ping - ECU: - - msg: Ping - - msg: Fan Status - Fan Controller 5: - CAN1: - Debugger: - - msg: Debug 2.0 - - msg: Ping - ECU: - - msg: Ping - - msg: Fan Status - Fan Controller 6: - CAN1: - Debugger: - - msg: Debug 2.0 - - msg: Ping - ECU: - - msg: Ping - - msg: Fan Status - Fan Controller 7: - CAN1: - Debugger: - - msg: Debug 2.0 - - msg: Ping - ECU: - - msg: Ping - - msg: Fan Status - Fan Controller 8: - CAN1: - Debugger: - - msg: Debug 2.0 - - msg: Ping - ECU: - - msg: Ping - - msg: Fan Status - GR Inverter 1: - CAN1: - Debugger: - - msg: Debug 2.0 - - msg: Ping - ECU: - - msg: Ping - - msg: Inverter Status 1 - - msg: Inverter Status 2 - - msg: Inverter Status 3 - GR Inverter 2: - CAN1: - Debugger: - - msg: Debug 2.0 - - msg: Ping - ECU: - - msg: Ping - - msg: Inverter Status 1 - - msg: Inverter Status 2 - - msg: Inverter Status 3 - GR Inverter 3: - CAN1: - Debugger: - - msg: Debug 2.0 - - msg: Ping - ECU: - - msg: Ping - - msg: Inverter Status 1 - - msg: Inverter Status 2 - - msg: Inverter Status 3 - GR Inverter 4: + GR Inverter: CAN1: Debugger: - msg: Debug 2.0 @@ -392,7 +210,7 @@ routing: - msg: Inverter Status 3 IMD: CAN3: - ACU: + BCU: - msg: IMD response can_id_override: 0x23 - msg: IMD isolation info @@ -407,132 +225,30 @@ routing: can_id_override: 0x18EFF4FE - msg: IMD general can_id_override: 0x18FF01F4 - LV DC-DC: + TCM: CAN1: Debugger: - msg: Ping ECU: - msg: Ping - - msg: DC-DC Status - SAM1: - CAN2: - Debugger: - - msg: Ping - ECU: - - msg: SAM Brake IR - SAM2: - CAN2: - Debugger: - - msg: Ping - ECU: - - msg: SAM Brake IR - SAM3: - CAN2: - Debugger: - - msg: Ping - ECU: - - msg: SAM Brake IR - SAM4: - CAN2: - Debugger: - - msg: Ping - ECU: - - msg: SAM Brake IR - SAM5: - CAN2: - Debugger: - - msg: Ping - ECU: - - msg: SAM IMU - - msg: SAM TOF - SAM6: CAN2: Debugger: - msg: Ping - SAM7: - CAN2: - Debugger: - - msg: Ping - SAM8: - CAN2: - Debugger: - - msg: Ping - SAM9: - CAN2: - Debugger: - - msg: Ping - SAM10: - CAN2: - Debugger: - - msg: Ping - SAM11: - CAN2: - Debugger: - - msg: Ping - SAM12: - CAN2: - Debugger: - - msg: Ping - SAM13: - CAN2: - Debugger: - - msg: Ping - SAM14: - CAN2: - Debugger: - - msg: Ping - SAM15: - CAN2: - Debugger: - - msg: Ping - SAM16: - CAN2: - Debugger: - - msg: Ping - SAM17: - CAN2: - Debugger: - - msg: Ping - SAM18: - CAN2: - Debugger: - - msg: Ping - SAM19: - CAN2: - Debugger: - - msg: Ping - SAM20: - CAN2: - Debugger: - - msg: Ping - Steering Wheel: - CAN2: - Debugger: - - msg: Debug FD - - msg: Ping - ECU: - - msg: Ping - - msg: Steering Status - TCM: - CAN1: - Debugger: - - msg: Ping - CAN2: - Debugger: - - msg: Ping - Steering Wheel: - - msg: TCM Status - - msg: TCM Resource Utilization + CCU: + CAN3: + BCU: + - msg: BCU Precharge + - msg: Debug 2.0 DGPS: CAN2: - ECU: - - msg: UVW DGPS + TCM: + - msg: GPS ALT - msg: GPS LAT - msg: GPS LON - - msg: GPS ALT - msg: GPS PX - msg: GPS QY - msg: GPS RZ + - msg: UVW DGPS byte order: little_endian @@ -542,21 +258,21 @@ Message ID: MSG LENGTH: 8 Debug: bit_start: 0 - # Essentially a print statement up to 8 bytes long that whichever targeted can parse + comment: Essentially a print statement up to 8 bytes long that whichever targeted can parse data type: s Debug FD: MSG ID: 0x001 MSG LENGTH: 64 Debug: bit_start: 0 - # Essentially a print statement up to 64 bytes long that whichever targeted can parse + comment: Essentially a print statement up to 64 bytes long that whichever targeted can parse data type: s Ping: MSG ID: 0x002 MSG LENGTH: 4 Timestamp: bit_start: 0 - # Time in millis + comment: Time in millis data type: u32 units: ms scaled min: 0 @@ -565,170 +281,120 @@ Message ID: ECU Status 1: MSG ID: 0x003 MSG LENGTH: 8 - ECU State: + state_messages: bit_start: 0 - # See diagram - data type: u8 - units: Enum - ACU Node Status: - bit_start: 8 - # 1: OK, 0: Timeout - data type: b - units: Bool - GR Inv 1 Status: - bit_start: 9 - # 1: OK, 0: Timeout - data type: b - units: Bool - GR Inv 2 Status: - bit_start: 10 - # 1: OK, 0: Timeout - data type: b - units: Bool - GR Inv 3 Status: - bit_start: 11 - # 1: OK, 0: Timeout - data type: b - units: Bool - GR Inv 4 Status: - bit_start: 12 - # 1: OK, 0: Timeout - data type: b - units: Bool - Fan Controller 1: - bit_start: 13 - # 1: OK, 0: Timeout - data type: b - units: Bool - Fan Controller 2: - bit_start: 14 - # 1: OK, 0: Timeout - data type: b - units: Bool - Fan Controller 3: - bit_start: 15 - # 1: OK, 0: Timeout - data type: b - units: Bool - Fan Controller 4: - bit_start: 16 - # 1: OK, 0: Timeout - data type: b - units: Bool - Fan Controller 5: - bit_start: 17 - # 1: OK, 0: Timeout - data type: b - units: Bool - Fan Controller 6: - bit_start: 18 - # 1: OK, 0: Timeout - data type: b - units: Bool - Fan Controller 7: - bit_start: 19 - # 1: OK, 0: Timeout - data type: b - units: Bool - Fan Controller 8: - bit_start: 20 - # 1: OK, 0: Timeout - data type: b - units: Bool - Dash: - bit_start: 21 - # 1: OK, 0: Timeout + comment: + [Byte 0 / Bits 0-1] GLV States + 0: GLV Off State, + 1: GLV On State. + See diagram in StateMachine. + [Byte 0 / Bits 2-3] Precharge States + 2: Precharge Engaged State + 3: Precharge Complete State + See diagram in StateMachine.h + [Byte 0 / Bits 4-5] ECU States + 4: Drive Active ECU State + 5: TS Discharge ECU State + 6-7: Reserved + See diagram in StateMachine.h data type: b units: Bool - Steering: - bit_start: 22 - # 1: OK, 0: Timeout + status_flags: + bit_start: 8 + comment: + [Byte 1 / Bits 8-15] + 8: BCU Node Status (1: OK, 0: Timeout) + 9: GR Inverter Status (1: OK, 0: Timeout) + 10: Fan Controller 1 Status (1: OK, 0: Timeout) + 11: Fan Controller 2 Status (1: OK, 0: Timeout) + 12: Fan Controller 3 Status (1: OK, 0: Timeout) + 13: Dash Panel Status (1: OK, 0: Timeout) + 14: TCM Node Status (1: OK, 0: Timeout) + 15: Reserved data type: b - units: Bool - Reserved: - bit_start: 23-31 Power Level: - bit_start: 32 - # Controls the AC current limits to each of the inverters - # Discrete Mapping, actual values TBD (16 possible values) + bit_start: 16 + comment: + Controls the AC current limits to each of the inverters + Discrete Mapping, actual values TBD (16 possible values) data type: u4 Torque Map: - bit_start: 36 - # The torque map selected; torque map is the mapping of the throttle to the torque sent to each motor + bit_start: 20 + comment: The torque map selected; torque map is the mapping of the throttle to the torque sent to each motor data type: u4 Max Cell Temp: - bit_start: 40 - # the temperature of the hottest cell of the accumulator + bit_start: 24 + comment: the temperature of the hottest cell of the accumulator data type: u8 units: Celsius scaled min: 0 scaled max: 63.75 map equation: "0.25x" Accumulator State of Charge: - bit_start: 48 - # % charged of the Accumulator + bit_start: 32 + comment: % charged of the Accumulator data type: u8 units: '%' scaled min: 0 scaled max: 100 map equation: "20x/51" GLV State of Charge: - bit_start: 56 - # % charged of the Low Voltage Bat + bit_start: 40 + comment: % charged of the Low Voltage Bat data type: u8 units: '%' scaled min: 0 scaled max: 100 map equation: "20x/51" - ECU Status 2: - MSG ID: 0x004 - MSG LENGTH: 8 Tractive System Voltage: - bit_start: 0 - # Output terminal voltage of accumulator + bit_start: 48 + comment: Output terminal voltage of accumulator data type: u16 units: Volts scaled min: 0 scaled max: 655.35 map equation: "0.01x" + ECU Status 2: + MSG ID: 0x004 + MSG LENGTH: 8 Vehicle Speed: - bit_start: 16 - # Absolute value of speed + bit_start: 0 + comment: Absolute value of speed data type: u16 units: MPH scaled min: 0 scaled max: 655.35 map equation: "0.01x" FR Wheel RPM: - bit_start: 32 - # Wheel RPM + bit_start: 16 + comment: Wheel RPM data type: u16 units: RPM scaled min: -3276.8 scaled max: 3276.7 map equation: "0.1x-3276.8" FL Wheel RPM: - bit_start: 48 - # Wheel RPM + bit_start: 32 + comment: Wheel RPM data type: u16 units: RPM scaled min: -3276.8 scaled max: 3276.7 map equation: "0.1x-3276.8" - ECU Status 3: - MSG ID: 0x005 - MSG LENGTH: 4 RR Wheel RPM: - bit_start: 0 - # Wheel RPM + bit_start: 48 + comment: Wheel RPM data type: u16 units: RPM scaled min: -3276.8 scaled max: 3276.7 map equation: "0.1x-3276.8" + ECU Status 3: + MSG ID: 0x005 + MSG LENGTH: 2 RL Wheel RPM: - bit_start: 16 - # Wheel RPM + bit_start: 0 + comment: Wheel RPM data type: u16 units: RPM scaled min: -3276.8 @@ -739,12 +405,12 @@ Message ID: MSG LENGTH: 0 Reserved: bit_start: 0 - ACU Status 1: + BCU Status 1: MSG ID: 0x007 MSG LENGTH: 8 Accumulator Voltage: bit_start: 0 - # All cell voltages added up + comment: All cell voltages added up data type: u16 units: Volts scaled min: 0 @@ -752,7 +418,7 @@ Message ID: map equation: "0.01x" TS Voltage: bit_start: 16 - # Output terminal voltage of accumulator + comment: Output terminal voltage of accumulator data type: u16 units: Volts scaled min: 0 @@ -760,15 +426,15 @@ Message ID: map equation: "0.01x" Accumulator Current: bit_start: 32 - # Current output of accumulator - data type: i16 + comment: Current output of accumulator + data type: s16 units: Amps scaled min: -327.68 scaled max: 327.67 map equation: "0.01x" Accumulator SOC: bit_start: 48 - # Accumulator state of charge (Based on lowest cell) + comment: Accumulator state of charge (Based on lowest cell) data type: u8 units: '%' scaled min: 0 @@ -776,123 +442,94 @@ Message ID: map equation: "20x/51" GLV SOC: bit_start: 56 - # GLV state of charge + comment: GLV state of charge data type: u8 units: '%' scaled min: 0 scaled max: 100 map equation: "20x/51" - ACU Status 2: + BCU Status 2: MSG ID: 0x008 MSG LENGTH: 7 20v Voltage: bit_start: 0 - # 20v GLV voltage + comment: + 20v GLV voltage + data type: u8 + units: Volts + scaled min: 0 + scaled max: 25.5 + map equation: "0.1x" data type: u8 - units: Volts - scaled min: 0 - scaled max: 25.5 - map equation: "0.1x" 12v Voltage: bit_start: 8 - # 12v supply voltage + comment: + 12v supply voltage + data type: u8 + units: Volts + scaled min: 0 + scaled max: 25.5 + map equation: "0.1x" data type: u8 - units: Volts - scaled min: 0 - scaled max: 25.5 - map equation: "0.1x" SDC Voltage: bit_start: 16 - # Voltage before ACU Latch + comment: + Voltage before BCU Latch + data type: u8 + units: Volts + scaled min: 0 + scaled max: 25.5 + map equation: "0.1x" data type: u8 - units: Volts - scaled min: 0 - scaled max: 25.5 - map equation: "0.1x" Min Cell Voltage: bit_start: 24 - # Lowest cell voltage in accumulator + comment: + Lowest cell voltage in accumulator + data type: u8 + units: Volts + scaled min: 2 + scaled max: 4.55 + map equation: "0.01x+2" data type: u8 - units: Volts - scaled min: 2 - scaled max: 4.55 - map equation: "0.01x+2" Max Cell Temp: bit_start: 32 - # Hottest cell in accumulator - data type: u8 - units: Celsius - scaled min: 0 - scaled max: 63.75 - map equation: "0.25x" - Over Temp Error: + comment: + Hottest cell in accumulator + data type: u8 + units: Celsius + scaled min: 0 + scaled max: 63.75 + map equation: "0.25x" + data type: u8 + status_flags: bit_start: 40 - # Over temp (>60c) - data type: b - units: Bool - Over Voltage Error: - bit_start: 41 - # Over voltage (>4.2v per cell) - data type: b - units: Bool - Under Voltage Error: - bit_start: 42 - # Under voltage (<2.5v per cell) - data type: b - units: Bool - Over Current Error: - bit_start: 43 - # Over current (discharge) - data type: b - units: Bool - Under Current Error: - bit_start: 44 - # Over current (charging) - data type: b - units: Bool - Under Voltage 20v Warning: - bit_start: 45 - # 20v GLV too low (<15?) + comment: + [Byte 5 / Bits 40-47] + 40: Over Temp (>60C) + 41: Over Voltage (>4.2V/cell) + 42: Under Volt (<2.5V/cell) + 43: Over Current (Discharge) + 44: Under Current (Charge) + 45: 20V GLV Warning + 46: 12V Supply Warning + 47: SDC Warning data type: b - units: Bool - Under Voltage 12v Warning: - bit_start: 46 - # 12v supply too low (<10?) - data type: b - units: Bool - Under Voltage SDC Warning: - bit_start: 47 - # SDC too low (<9?) - data type: b - units: Bool - Precharge Error: + precharge_latch_flags: bit_start: 48 - # Precharge timed out - data type: b - units: Bool - IR- / Precharge State: - bit_start: 49 - # 0: Open 1: Closed + comment: + [Byte 6 / Bits 48-55] + 48: Precharge Timeout + 49: IR- / Precharge State (0:Open, 1:Closed) + 50: IR+ State (0:Open, 1:Closed) + 51: Software Latch (0:Open, 1:Closed) + 52-55: Reserved data type: b - units: Bool - IR+ State: - bit_start: 50 - # 0: Open 1: Closed - data type: b - units: Bool - Software Latch: - bit_start: 51 - # 0: Open 1: Closed - data type: b - units: Bool - Reserved: - bit_start: 52-55 - ACU Status 3: + BCU Status 3: MSG ID: 0x009 MSG LENGTH: 8 HV Input Voltage: bit_start: 0 - # 600v input voltage + comment: 600v input voltage data type: u16 units: Volts scaled min: 0 @@ -900,7 +537,7 @@ Message ID: map equation: "0.01x" HV Output Voltage: bit_start: 16 - # 20v output voltage + comment: 20v output voltage data type: u16 units: Volts scaled min: 0 @@ -908,7 +545,7 @@ Message ID: map equation: "0.01x" HV Input Current: bit_start: 32 - # 600v input current + comment: 600v input current data type: u16 units: Amps scaled min: 0 @@ -916,26 +553,26 @@ Message ID: map equation: "0.001x" HV Output Current: bit_start: 48 - # 20v output current + comment: 20v output current data type: u16 units: Amps scaled min: 0 scaled max: 65.535 map equation: "0.001x" - ACU Precharge: + BCU Precharge: MSG ID: 0x00A MSG LENGTH: 1 Set TS Active: bit_start: 0 - # 0: shutdown, 1: go TS Active/Precharge + comment: 0: shutdown, 1: go TS Active/Precharge data type: b units: Bool - ACU Config Charge Parameters: + BCU Config Charge Parameters: MSG ID: 0x00B MSG LENGTH: 4 Charge Voltage: bit_start: 0 - # Sets the Target Charging voltage + comment: Sets the Target Charging voltage data type: u16 units: Volts scaled min: 0 @@ -943,18 +580,18 @@ Message ID: map equation: "0.1x" Charge Current: bit_start: 16 - # Sets the Target Charging Current + comment: Sets the Target Charging Current data type: u16 units: Amps scaled min: 0 scaled max: 6553.5 map equation: "0.1x" - ACU Config Operational Parameters: + BCU Config Operational Parameters: MSG ID: 0x00C MSG LENGTH: 2 Minimium Cell Voltage: bit_start: 0 - # Sets the threshold for Minimum Cell Voltage before Shutdown + comment: Sets the threshold for Minimum Cell Voltage before Shutdown data type: u8 units: Volts scaled min: 2 @@ -962,18 +599,18 @@ Message ID: map equation: "0.01x+2" Max Cell Temperature: bit_start: 8 - # Sets the threshold for Max Cell Temperature before Shutdown + comment: Sets the threshold for Max Cell Temperature before Shutdown data type: u8 units: Celsius scaled min: 0 scaled max: 63.75 map equation: "0.25x" - ACU Cell Data 1: + BCU Cell Data 1: MSG ID: 0x00D MSG LENGTH: 64 Cell 0 Voltage: bit_start: 0 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -981,7 +618,7 @@ Message ID: map equation: "0.01x+2" Cell 0 Temp: bit_start: 8 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -989,7 +626,7 @@ Message ID: map equation: "0.25x" Cell 1 Voltage: bit_start: 16 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -997,7 +634,7 @@ Message ID: map equation: "0.01x+2" Cell 1 Temp: bit_start: 24 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1005,7 +642,7 @@ Message ID: map equation: "0.25x" Cell 2 Voltage: bit_start: 32 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1013,7 +650,7 @@ Message ID: map equation: "0.01x+2" Cell 2 Temp: bit_start: 40 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1021,7 +658,7 @@ Message ID: map equation: "0.25x" Cell 3 Voltage: bit_start: 48 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1029,7 +666,7 @@ Message ID: map equation: "0.01x+2" Cell 3 Temp: bit_start: 56 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1037,7 +674,7 @@ Message ID: map equation: "0.25x" Cell 4 Voltage: bit_start: 64 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1045,7 +682,7 @@ Message ID: map equation: "0.01x+2" Cell 4 Temp: bit_start: 72 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1053,7 +690,7 @@ Message ID: map equation: "0.25x" Cell 5 Voltage: bit_start: 80 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1061,7 +698,7 @@ Message ID: map equation: "0.01x+2" Cell 5 Temp: bit_start: 88 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1069,7 +706,7 @@ Message ID: map equation: "0.25x" Cell 6 Voltage: bit_start: 96 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1077,7 +714,7 @@ Message ID: map equation: "0.01x+2" Cell 6 Temp: bit_start: 104 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1085,7 +722,7 @@ Message ID: map equation: "0.25x" Cell 7 Voltage: bit_start: 112 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1093,7 +730,7 @@ Message ID: map equation: "0.01x+2" Cell 7 Temp: bit_start: 120 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1101,7 +738,7 @@ Message ID: map equation: "0.25x" Cell 8 Voltage: bit_start: 128 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1109,7 +746,7 @@ Message ID: map equation: "0.01x+2" Cell 8 Temp: bit_start: 136 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1117,7 +754,7 @@ Message ID: map equation: "0.25x" Cell 9 Voltage: bit_start: 144 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1125,7 +762,7 @@ Message ID: map equation: "0.01x+2" Cell 9 Temp: bit_start: 152 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1133,7 +770,7 @@ Message ID: map equation: "0.25x" Cell 10 Voltage: bit_start: 160 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1141,7 +778,7 @@ Message ID: map equation: "0.01x+2" Cell 10 Temp: bit_start: 168 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1149,7 +786,7 @@ Message ID: map equation: "0.25x" Cell 11 Voltage: bit_start: 176 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1157,7 +794,7 @@ Message ID: map equation: "0.01x+2" Cell 11 Temp: bit_start: 184 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1165,7 +802,7 @@ Message ID: map equation: "0.25x" Cell 12 Voltage: bit_start: 192 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1173,7 +810,7 @@ Message ID: map equation: "0.01x+2" Cell 12 Temp: bit_start: 200 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1181,7 +818,7 @@ Message ID: map equation: "0.25x" Cell 13 Voltage: bit_start: 208 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1189,7 +826,7 @@ Message ID: map equation: "0.01x+2" Cell 13 Temp: bit_start: 216 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1197,7 +834,7 @@ Message ID: map equation: "0.25x" Cell 14 Voltage: bit_start: 224 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1205,7 +842,7 @@ Message ID: map equation: "0.01x+2" Cell 14 Temp: bit_start: 232 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1213,7 +850,7 @@ Message ID: map equation: "0.25x" Cell 15 Voltage: bit_start: 240 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1221,7 +858,7 @@ Message ID: map equation: "0.01x+2" Cell 15 Temp: bit_start: 248 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1229,7 +866,7 @@ Message ID: map equation: "0.25x" Cell 16 Voltage: bit_start: 256 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1237,7 +874,7 @@ Message ID: map equation: "0.01x+2" Cell 16 Temp: bit_start: 264 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1245,7 +882,7 @@ Message ID: map equation: "0.25x" Cell 17 Voltage: bit_start: 272 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1253,7 +890,7 @@ Message ID: map equation: "0.01x+2" Cell 17 Temp: bit_start: 280 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1261,7 +898,7 @@ Message ID: map equation: "0.25x" Cell 18 Voltage: bit_start: 288 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1269,7 +906,7 @@ Message ID: map equation: "0.01x+2" Cell 18 Temp: bit_start: 296 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1277,7 +914,7 @@ Message ID: map equation: "0.25x" Cell 19 Voltage: bit_start: 304 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1285,7 +922,7 @@ Message ID: map equation: "0.01x+2" Cell 19 Temp: bit_start: 312 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1293,7 +930,7 @@ Message ID: map equation: "0.25x" Cell 20 Voltage: bit_start: 320 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1301,7 +938,7 @@ Message ID: map equation: "0.01x+2" Cell 20 Temp: bit_start: 328 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1309,7 +946,7 @@ Message ID: map equation: "0.25x" Cell 21 Voltage: bit_start: 336 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1317,7 +954,7 @@ Message ID: map equation: "0.01x+2" Cell 21 Temp: bit_start: 344 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1325,7 +962,7 @@ Message ID: map equation: "0.25x" Cell 22 Voltage: bit_start: 352 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1333,7 +970,7 @@ Message ID: map equation: "0.01x+2" Cell 22 Temp: bit_start: 360 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1341,7 +978,7 @@ Message ID: map equation: "0.25x" Cell 23 Voltage: bit_start: 368 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1349,7 +986,7 @@ Message ID: map equation: "0.01x+2" Cell 23 Temp: bit_start: 376 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1357,7 +994,7 @@ Message ID: map equation: "0.25x" Cell 24 Voltage: bit_start: 384 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1365,7 +1002,7 @@ Message ID: map equation: "0.01x+2" Cell 24 Temp: bit_start: 392 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1373,7 +1010,7 @@ Message ID: map equation: "0.25x" Cell 25 Voltage: bit_start: 400 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1381,7 +1018,7 @@ Message ID: map equation: "0.01x+2" Cell 25 Temp: bit_start: 408 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1389,7 +1026,7 @@ Message ID: map equation: "0.25x" Cell 26 Voltage: bit_start: 416 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1397,7 +1034,7 @@ Message ID: map equation: "0.01x+2" Cell 26 Temp: bit_start: 424 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1405,7 +1042,7 @@ Message ID: map equation: "0.25x" Cell 27 Voltage: bit_start: 432 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1413,7 +1050,7 @@ Message ID: map equation: "0.01x+2" Cell 27 Temp: bit_start: 440 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1421,7 +1058,7 @@ Message ID: map equation: "0.25x" Cell 28 Voltage: bit_start: 448 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1429,7 +1066,7 @@ Message ID: map equation: "0.01x+2" Cell 28 Temp: bit_start: 456 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1437,7 +1074,7 @@ Message ID: map equation: "0.25x" Cell 29 Voltage: bit_start: 464 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1445,7 +1082,7 @@ Message ID: map equation: "0.01x+2" Cell 29 Temp: bit_start: 472 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1453,7 +1090,7 @@ Message ID: map equation: "0.25x" Cell 30 Voltage: bit_start: 480 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1461,7 +1098,7 @@ Message ID: map equation: "0.01x+2" Cell 30 Temp: bit_start: 488 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1469,7 +1106,7 @@ Message ID: map equation: "0.25x" Cell 31 Voltage: bit_start: 496 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1477,18 +1114,18 @@ Message ID: map equation: "0.01x+2" Cell 31 Temp: bit_start: 504 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 scaled max: 63.75 map equation: "0.25x" - ACU Cell Data 2: + BCU Cell Data 2: MSG ID: 0x00E MSG LENGTH: 64 Cell 32 Voltage: bit_start: 0 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1496,7 +1133,7 @@ Message ID: map equation: "0.01x+2" Cell 32 Temp: bit_start: 8 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1504,7 +1141,7 @@ Message ID: map equation: "0.25x" Cell 33 Voltage: bit_start: 16 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1512,7 +1149,7 @@ Message ID: map equation: "0.01x+2" Cell 33 Temp: bit_start: 24 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1520,7 +1157,7 @@ Message ID: map equation: "0.25x" Cell 34 Voltage: bit_start: 32 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1528,7 +1165,7 @@ Message ID: map equation: "0.01x+2" Cell 34 Temp: bit_start: 40 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1536,7 +1173,7 @@ Message ID: map equation: "0.25x" Cell 35 Voltage: bit_start: 48 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1544,7 +1181,7 @@ Message ID: map equation: "0.01x+2" Cell 35 Temp: bit_start: 56 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1552,7 +1189,7 @@ Message ID: map equation: "0.25x" Cell 36 Voltage: bit_start: 64 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1560,7 +1197,7 @@ Message ID: map equation: "0.01x+2" Cell 36 Temp: bit_start: 72 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1568,7 +1205,7 @@ Message ID: map equation: "0.25x" Cell 37 Voltage: bit_start: 80 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1576,7 +1213,7 @@ Message ID: map equation: "0.01x+2" Cell 37 Temp: bit_start: 88 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1584,7 +1221,7 @@ Message ID: map equation: "0.25x" Cell 38 Voltage: bit_start: 96 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1592,7 +1229,7 @@ Message ID: map equation: "0.01x+2" Cell 38 Temp: bit_start: 104 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1600,7 +1237,7 @@ Message ID: map equation: "0.25x" Cell 39 Voltage: bit_start: 112 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1608,7 +1245,7 @@ Message ID: map equation: "0.01x+2" Cell 39 Temp: bit_start: 120 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1616,7 +1253,7 @@ Message ID: map equation: "0.25x" Cell 40 Voltage: bit_start: 128 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1624,7 +1261,7 @@ Message ID: map equation: "0.01x+2" Cell 40 Temp: bit_start: 136 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1632,7 +1269,7 @@ Message ID: map equation: "0.25x" Cell 41 Voltage: bit_start: 144 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1640,7 +1277,7 @@ Message ID: map equation: "0.01x+2" Cell 41 Temp: bit_start: 152 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1648,7 +1285,7 @@ Message ID: map equation: "0.25x" Cell 42 Voltage: bit_start: 160 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1656,7 +1293,7 @@ Message ID: map equation: "0.01x+2" Cell 42 Temp: bit_start: 168 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1664,7 +1301,7 @@ Message ID: map equation: "0.25x" Cell 43 Voltage: bit_start: 176 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1672,7 +1309,7 @@ Message ID: map equation: "0.01x+2" Cell 43 Temp: bit_start: 184 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1680,7 +1317,7 @@ Message ID: map equation: "0.25x" Cell 44 Voltage: bit_start: 192 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1688,7 +1325,7 @@ Message ID: map equation: "0.01x+2" Cell 44 Temp: bit_start: 200 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1696,7 +1333,7 @@ Message ID: map equation: "0.25x" Cell 45 Voltage: bit_start: 208 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1704,7 +1341,7 @@ Message ID: map equation: "0.01x+2" Cell 45 Temp: bit_start: 216 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1712,7 +1349,7 @@ Message ID: map equation: "0.25x" Cell 46 Voltage: bit_start: 224 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1720,7 +1357,7 @@ Message ID: map equation: "0.01x+2" Cell 46 Temp: bit_start: 232 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1728,7 +1365,7 @@ Message ID: map equation: "0.25x" Cell 47 Voltage: bit_start: 240 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1736,7 +1373,7 @@ Message ID: map equation: "0.01x+2" Cell 47 Temp: bit_start: 248 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1744,7 +1381,7 @@ Message ID: map equation: "0.25x" Cell 48 Voltage: bit_start: 256 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1752,7 +1389,7 @@ Message ID: map equation: "0.01x+2" Cell 48 Temp: bit_start: 264 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1760,7 +1397,7 @@ Message ID: map equation: "0.25x" Cell 49 Voltage: bit_start: 272 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1768,7 +1405,7 @@ Message ID: map equation: "0.01x+2" Cell 49 Temp: bit_start: 280 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1776,7 +1413,7 @@ Message ID: map equation: "0.25x" Cell 50 Voltage: bit_start: 288 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1784,7 +1421,7 @@ Message ID: map equation: "0.01x+2" Cell 50 Temp: bit_start: 296 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1792,7 +1429,7 @@ Message ID: map equation: "0.25x" Cell 51 Voltage: bit_start: 304 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1800,7 +1437,7 @@ Message ID: map equation: "0.01x+2" Cell 51 Temp: bit_start: 312 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1808,7 +1445,7 @@ Message ID: map equation: "0.25x" Cell 52 Voltage: bit_start: 320 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1816,7 +1453,7 @@ Message ID: map equation: "0.01x+2" Cell 52 Temp: bit_start: 328 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1824,7 +1461,7 @@ Message ID: map equation: "0.25x" Cell 53 Voltage: bit_start: 336 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1832,7 +1469,7 @@ Message ID: map equation: "0.01x+2" Cell 53 Temp: bit_start: 344 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1840,7 +1477,7 @@ Message ID: map equation: "0.25x" Cell 54 Voltage: bit_start: 352 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1848,7 +1485,7 @@ Message ID: map equation: "0.01x+2" Cell 54 Temp: bit_start: 360 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1856,7 +1493,7 @@ Message ID: map equation: "0.25x" Cell 55 Voltage: bit_start: 368 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1864,7 +1501,7 @@ Message ID: map equation: "0.01x+2" Cell 55 Temp: bit_start: 376 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1872,7 +1509,7 @@ Message ID: map equation: "0.25x" Cell 56 Voltage: bit_start: 384 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1880,7 +1517,7 @@ Message ID: map equation: "0.01x+2" Cell 56 Temp: bit_start: 392 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1888,7 +1525,7 @@ Message ID: map equation: "0.25x" Cell 57 Voltage: bit_start: 400 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1896,7 +1533,7 @@ Message ID: map equation: "0.01x+2" Cell 57 Temp: bit_start: 408 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1904,7 +1541,7 @@ Message ID: map equation: "0.25x" Cell 58 Voltage: bit_start: 416 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1912,7 +1549,7 @@ Message ID: map equation: "0.01x+2" Cell 58 Temp: bit_start: 424 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1920,7 +1557,7 @@ Message ID: map equation: "0.25x" Cell 59 Voltage: bit_start: 432 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1928,7 +1565,7 @@ Message ID: map equation: "0.01x+2" Cell 59 Temp: bit_start: 440 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1936,7 +1573,7 @@ Message ID: map equation: "0.25x" Cell 60 Voltage: bit_start: 448 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1944,7 +1581,7 @@ Message ID: map equation: "0.01x+2" Cell 60 Temp: bit_start: 456 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1952,7 +1589,7 @@ Message ID: map equation: "0.25x" Cell 61 Voltage: bit_start: 464 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1960,7 +1597,7 @@ Message ID: map equation: "0.01x+2" Cell 61 Temp: bit_start: 472 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1968,7 +1605,7 @@ Message ID: map equation: "0.25x" Cell 62 Voltage: bit_start: 480 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1976,7 +1613,7 @@ Message ID: map equation: "0.01x+2" Cell 62 Temp: bit_start: 488 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -1984,7 +1621,7 @@ Message ID: map equation: "0.25x" Cell 63 Voltage: bit_start: 496 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -1992,18 +1629,18 @@ Message ID: map equation: "0.01x+2" Cell 63 Temp: bit_start: 504 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 scaled max: 63.75 map equation: "0.25x" - ACU Cell Data 3: + BCU Cell Data 3: MSG ID: 0x00F MSG LENGTH: 64 Cell 64 Voltage: bit_start: 0 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2011,7 +1648,7 @@ Message ID: map equation: "0.01x+2" Cell 64 Temp: bit_start: 8 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2019,7 +1656,7 @@ Message ID: map equation: "0.25x" Cell 65 Voltage: bit_start: 16 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2027,7 +1664,7 @@ Message ID: map equation: "0.01x+2" Cell 65 Temp: bit_start: 24 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2035,7 +1672,7 @@ Message ID: map equation: "0.25x" Cell 66 Voltage: bit_start: 32 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2043,7 +1680,7 @@ Message ID: map equation: "0.01x+2" Cell 66 Temp: bit_start: 40 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2051,7 +1688,7 @@ Message ID: map equation: "0.25x" Cell 67 Voltage: bit_start: 48 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2059,7 +1696,7 @@ Message ID: map equation: "0.01x+2" Cell 67 Temp: bit_start: 56 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2067,7 +1704,7 @@ Message ID: map equation: "0.25x" Cell 68 Voltage: bit_start: 64 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2075,7 +1712,7 @@ Message ID: map equation: "0.01x+2" Cell 68 Temp: bit_start: 72 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2083,7 +1720,7 @@ Message ID: map equation: "0.25x" Cell 69 Voltage: bit_start: 80 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2091,7 +1728,7 @@ Message ID: map equation: "0.01x+2" Cell 69 Temp: bit_start: 88 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2099,7 +1736,7 @@ Message ID: map equation: "0.25x" Cell 70 Voltage: bit_start: 96 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2107,7 +1744,7 @@ Message ID: map equation: "0.01x+2" Cell 70 Temp: bit_start: 104 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2115,7 +1752,7 @@ Message ID: map equation: "0.25x" Cell 71 Voltage: bit_start: 112 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2123,7 +1760,7 @@ Message ID: map equation: "0.01x+2" Cell 71 Temp: bit_start: 120 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2131,7 +1768,7 @@ Message ID: map equation: "0.25x" Cell 72 Voltage: bit_start: 128 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2139,7 +1776,7 @@ Message ID: map equation: "0.01x+2" Cell 72 Temp: bit_start: 136 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2147,7 +1784,7 @@ Message ID: map equation: "0.25x" Cell 73 Voltage: bit_start: 144 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2155,7 +1792,7 @@ Message ID: map equation: "0.01x+2" Cell 73 Temp: bit_start: 152 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2163,7 +1800,7 @@ Message ID: map equation: "0.25x" Cell 74 Voltage: bit_start: 160 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2171,7 +1808,7 @@ Message ID: map equation: "0.01x+2" Cell 74 Temp: bit_start: 168 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2179,7 +1816,7 @@ Message ID: map equation: "0.25x" Cell 75 Voltage: bit_start: 176 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2187,7 +1824,7 @@ Message ID: map equation: "0.01x+2" Cell 75 Temp: bit_start: 184 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2195,7 +1832,7 @@ Message ID: map equation: "0.25x" Cell 76 Voltage: bit_start: 192 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2203,7 +1840,7 @@ Message ID: map equation: "0.01x+2" Cell 76 Temp: bit_start: 200 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2211,7 +1848,7 @@ Message ID: map equation: "0.25x" Cell 77 Voltage: bit_start: 208 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2219,7 +1856,7 @@ Message ID: map equation: "0.01x+2" Cell 77 Temp: bit_start: 216 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2227,7 +1864,7 @@ Message ID: map equation: "0.25x" Cell 78 Voltage: bit_start: 224 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2235,7 +1872,7 @@ Message ID: map equation: "0.01x+2" Cell 78 Temp: bit_start: 232 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2243,7 +1880,7 @@ Message ID: map equation: "0.25x" Cell 79 Voltage: bit_start: 240 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2251,7 +1888,7 @@ Message ID: map equation: "0.01x+2" Cell 79 Temp: bit_start: 248 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2259,7 +1896,7 @@ Message ID: map equation: "0.25x" Cell 80 Voltage: bit_start: 256 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2267,7 +1904,7 @@ Message ID: map equation: "0.01x+2" Cell 80 Temp: bit_start: 264 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2275,7 +1912,7 @@ Message ID: map equation: "0.25x" Cell 81 Voltage: bit_start: 272 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2283,7 +1920,7 @@ Message ID: map equation: "0.01x+2" Cell 81 Temp: bit_start: 280 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2291,7 +1928,7 @@ Message ID: map equation: "0.25x" Cell 82 Voltage: bit_start: 288 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2299,7 +1936,7 @@ Message ID: map equation: "0.01x+2" Cell 82 Temp: bit_start: 296 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2307,7 +1944,7 @@ Message ID: map equation: "0.25x" Cell 83 Voltage: bit_start: 304 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2315,7 +1952,7 @@ Message ID: map equation: "0.01x+2" Cell 83 Temp: bit_start: 312 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2323,7 +1960,7 @@ Message ID: map equation: "0.25x" Cell 84 Voltage: bit_start: 320 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2331,7 +1968,7 @@ Message ID: map equation: "0.01x+2" Cell 84 Temp: bit_start: 328 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2339,7 +1976,7 @@ Message ID: map equation: "0.25x" Cell 85 Voltage: bit_start: 336 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2347,7 +1984,7 @@ Message ID: map equation: "0.01x+2" Cell 85 Temp: bit_start: 344 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2355,7 +1992,7 @@ Message ID: map equation: "0.25x" Cell 86 Voltage: bit_start: 352 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2363,7 +2000,7 @@ Message ID: map equation: "0.01x+2" Cell 86 Temp: bit_start: 360 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2371,7 +2008,7 @@ Message ID: map equation: "0.25x" Cell 87 Voltage: bit_start: 368 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2379,7 +2016,7 @@ Message ID: map equation: "0.01x+2" Cell 87 Temp: bit_start: 376 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2387,7 +2024,7 @@ Message ID: map equation: "0.25x" Cell 88 Voltage: bit_start: 384 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2395,7 +2032,7 @@ Message ID: map equation: "0.01x+2" Cell 88 Temp: bit_start: 392 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2403,7 +2040,7 @@ Message ID: map equation: "0.25x" Cell 89 Voltage: bit_start: 400 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2411,7 +2048,7 @@ Message ID: map equation: "0.01x+2" Cell 89 Temp: bit_start: 408 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2419,7 +2056,7 @@ Message ID: map equation: "0.25x" Cell 90 Voltage: bit_start: 416 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2427,7 +2064,7 @@ Message ID: map equation: "0.01x+2" Cell 90 Temp: bit_start: 424 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2435,7 +2072,7 @@ Message ID: map equation: "0.25x" Cell 91 Voltage: bit_start: 432 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2443,7 +2080,7 @@ Message ID: map equation: "0.01x+2" Cell 91 Temp: bit_start: 440 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2451,7 +2088,7 @@ Message ID: map equation: "0.25x" Cell 92 Voltage: bit_start: 448 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2459,7 +2096,7 @@ Message ID: map equation: "0.01x+2" Cell 92 Temp: bit_start: 456 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2467,7 +2104,7 @@ Message ID: map equation: "0.25x" Cell 93 Voltage: bit_start: 464 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2475,7 +2112,7 @@ Message ID: map equation: "0.01x+2" Cell 93 Temp: bit_start: 472 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2483,7 +2120,7 @@ Message ID: map equation: "0.25x" Cell 94 Voltage: bit_start: 480 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2491,7 +2128,7 @@ Message ID: map equation: "0.01x+2" Cell 94 Temp: bit_start: 488 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2499,7 +2136,7 @@ Message ID: map equation: "0.25x" Cell 95 Voltage: bit_start: 496 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2507,18 +2144,18 @@ Message ID: map equation: "0.01x+2" Cell 95 Temp: bit_start: 504 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 scaled max: 63.75 map equation: "0.25x" - ACU Cell Data 4: + BCU Cell Data 4: MSG ID: 0x010 MSG LENGTH: 64 Cell 96 Voltage: bit_start: 0 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2526,7 +2163,7 @@ Message ID: map equation: "0.01x+2" Cell 96 Temp: bit_start: 8 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2534,7 +2171,7 @@ Message ID: map equation: "0.25x" Cell 97 Voltage: bit_start: 16 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2542,7 +2179,7 @@ Message ID: map equation: "0.01x+2" Cell 97 Temp: bit_start: 24 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2550,7 +2187,7 @@ Message ID: map equation: "0.25x" Cell 98 Voltage: bit_start: 32 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2558,7 +2195,7 @@ Message ID: map equation: "0.01x+2" Cell 98 Temp: bit_start: 40 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2566,7 +2203,7 @@ Message ID: map equation: "0.25x" Cell 99 Voltage: bit_start: 48 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2574,7 +2211,7 @@ Message ID: map equation: "0.01x+2" Cell 99 Temp: bit_start: 56 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2582,7 +2219,7 @@ Message ID: map equation: "0.25x" Cell 100 Voltage: bit_start: 64 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2590,7 +2227,7 @@ Message ID: map equation: "0.01x+2" Cell 100 Temp: bit_start: 72 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2598,7 +2235,7 @@ Message ID: map equation: "0.25x" Cell 101 Voltage: bit_start: 80 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2606,7 +2243,7 @@ Message ID: map equation: "0.01x+2" Cell 101 Temp: bit_start: 88 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2614,7 +2251,7 @@ Message ID: map equation: "0.25x" Cell 102 Voltage: bit_start: 96 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2622,7 +2259,7 @@ Message ID: map equation: "0.01x+2" Cell 102 Temp: bit_start: 104 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2630,7 +2267,7 @@ Message ID: map equation: "0.25x" Cell 103 Voltage: bit_start: 112 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2638,7 +2275,7 @@ Message ID: map equation: "0.01x+2" Cell 103 Temp: bit_start: 120 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2646,7 +2283,7 @@ Message ID: map equation: "0.25x" Cell 104 Voltage: bit_start: 128 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2654,7 +2291,7 @@ Message ID: map equation: "0.01x+2" Cell 104 Temp: bit_start: 136 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2662,7 +2299,7 @@ Message ID: map equation: "0.25x" Cell 105 Voltage: bit_start: 144 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2670,7 +2307,7 @@ Message ID: map equation: "0.01x+2" Cell 105 Temp: bit_start: 152 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2678,7 +2315,7 @@ Message ID: map equation: "0.25x" Cell 106 Voltage: bit_start: 160 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2686,7 +2323,7 @@ Message ID: map equation: "0.01x+2" Cell 106 Temp: bit_start: 168 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2694,7 +2331,7 @@ Message ID: map equation: "0.25x" Cell 107 Voltage: bit_start: 176 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2702,7 +2339,7 @@ Message ID: map equation: "0.01x+2" Cell 107 Temp: bit_start: 184 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2710,7 +2347,7 @@ Message ID: map equation: "0.25x" Cell 108 Voltage: bit_start: 192 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2718,7 +2355,7 @@ Message ID: map equation: "0.01x+2" Cell 108 Temp: bit_start: 200 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2726,7 +2363,7 @@ Message ID: map equation: "0.25x" Cell 109 Voltage: bit_start: 208 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2734,7 +2371,7 @@ Message ID: map equation: "0.01x+2" Cell 109 Temp: bit_start: 216 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2742,7 +2379,7 @@ Message ID: map equation: "0.25x" Cell 110 Voltage: bit_start: 224 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2750,7 +2387,7 @@ Message ID: map equation: "0.01x+2" Cell 110 Temp: bit_start: 232 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2758,7 +2395,7 @@ Message ID: map equation: "0.25x" Cell 111 Voltage: bit_start: 240 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2766,7 +2403,7 @@ Message ID: map equation: "0.01x+2" Cell 111 Temp: bit_start: 248 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2774,7 +2411,7 @@ Message ID: map equation: "0.25x" Cell 112 Voltage: bit_start: 256 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2782,7 +2419,7 @@ Message ID: map equation: "0.01x+2" Cell 112 Temp: bit_start: 264 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2790,7 +2427,7 @@ Message ID: map equation: "0.25x" Cell 113 Voltage: bit_start: 272 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2798,7 +2435,7 @@ Message ID: map equation: "0.01x+2" Cell 113 Temp: bit_start: 280 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2806,7 +2443,7 @@ Message ID: map equation: "0.25x" Cell 114 Voltage: bit_start: 288 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2814,7 +2451,7 @@ Message ID: map equation: "0.01x+2" Cell 114 Temp: bit_start: 296 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2822,7 +2459,7 @@ Message ID: map equation: "0.25x" Cell 115 Voltage: bit_start: 304 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2830,7 +2467,7 @@ Message ID: map equation: "0.01x+2" Cell 115 Temp: bit_start: 312 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2838,7 +2475,7 @@ Message ID: map equation: "0.25x" Cell 116 Voltage: bit_start: 320 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2846,7 +2483,7 @@ Message ID: map equation: "0.01x+2" Cell 116 Temp: bit_start: 328 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2854,7 +2491,7 @@ Message ID: map equation: "0.25x" Cell 117 Voltage: bit_start: 336 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2862,7 +2499,7 @@ Message ID: map equation: "0.01x+2" Cell 117 Temp: bit_start: 344 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2870,7 +2507,7 @@ Message ID: map equation: "0.25x" Cell 118 Voltage: bit_start: 352 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2878,7 +2515,7 @@ Message ID: map equation: "0.01x+2" Cell 118 Temp: bit_start: 360 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2886,7 +2523,7 @@ Message ID: map equation: "0.25x" Cell 119 Voltage: bit_start: 368 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2894,7 +2531,7 @@ Message ID: map equation: "0.01x+2" Cell 119 Temp: bit_start: 376 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2902,7 +2539,7 @@ Message ID: map equation: "0.25x" Cell 120 Voltage: bit_start: 384 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2910,7 +2547,7 @@ Message ID: map equation: "0.01x+2" Cell 120 Temp: bit_start: 392 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2918,7 +2555,7 @@ Message ID: map equation: "0.25x" Cell 121 Voltage: bit_start: 400 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2926,7 +2563,7 @@ Message ID: map equation: "0.01x+2" Cell 121 Temp: bit_start: 408 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2934,7 +2571,7 @@ Message ID: map equation: "0.25x" Cell 122 Voltage: bit_start: 416 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2942,7 +2579,7 @@ Message ID: map equation: "0.01x+2" Cell 122 Temp: bit_start: 424 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2950,7 +2587,7 @@ Message ID: map equation: "0.25x" Cell 123 Voltage: bit_start: 432 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2958,7 +2595,7 @@ Message ID: map equation: "0.01x+2" Cell 123 Temp: bit_start: 440 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2966,7 +2603,7 @@ Message ID: map equation: "0.25x" Cell 124 Voltage: bit_start: 448 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2974,7 +2611,7 @@ Message ID: map equation: "0.01x+2" Cell 124 Temp: bit_start: 456 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2982,7 +2619,7 @@ Message ID: map equation: "0.25x" Cell 125 Voltage: bit_start: 464 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -2990,7 +2627,7 @@ Message ID: map equation: "0.01x+2" Cell 125 Temp: bit_start: 472 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -2998,7 +2635,7 @@ Message ID: map equation: "0.25x" Cell 126 Voltage: bit_start: 480 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3006,7 +2643,7 @@ Message ID: map equation: "0.01x+2" Cell 126 Temp: bit_start: 488 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3014,7 +2651,7 @@ Message ID: map equation: "0.25x" Cell 127 Voltage: bit_start: 496 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3022,18 +2659,18 @@ Message ID: map equation: "0.01x+2" Cell 127 Temp: bit_start: 504 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 scaled max: 63.75 map equation: "0.25x" - ACU Cell Data 5: + BCU Cell Data 5: MSG ID: 0x011 MSG LENGTH: 64 Cell 128 Voltage: bit_start: 0 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3041,7 +2678,7 @@ Message ID: map equation: "0.01x+2" Cell 128 Temp: bit_start: 8 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3049,7 +2686,7 @@ Message ID: map equation: "0.25x" Cell 129 Voltage: bit_start: 16 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3057,7 +2694,7 @@ Message ID: map equation: "0.01x+2" Cell 129 Temp: bit_start: 24 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3065,7 +2702,7 @@ Message ID: map equation: "0.25x" Cell 130 Voltage: bit_start: 32 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3073,7 +2710,7 @@ Message ID: map equation: "0.01x+2" Cell 130 Temp: bit_start: 40 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3081,7 +2718,7 @@ Message ID: map equation: "0.25x" Cell 131 Voltage: bit_start: 48 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3089,7 +2726,7 @@ Message ID: map equation: "0.01x+2" Cell 131 Temp: bit_start: 56 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3097,7 +2734,7 @@ Message ID: map equation: "0.25x" Cell 132 Voltage: bit_start: 64 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3105,7 +2742,7 @@ Message ID: map equation: "0.01x+2" Cell 132 Temp: bit_start: 72 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3113,7 +2750,7 @@ Message ID: map equation: "0.25x" Cell 133 Voltage: bit_start: 80 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3121,7 +2758,7 @@ Message ID: map equation: "0.01x+2" Cell 133 Temp: bit_start: 88 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3129,7 +2766,7 @@ Message ID: map equation: "0.25x" Cell 134 Voltage: bit_start: 96 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3137,7 +2774,7 @@ Message ID: map equation: "0.01x+2" Cell 134 Temp: bit_start: 104 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3145,7 +2782,7 @@ Message ID: map equation: "0.25x" Cell 135 Voltage: bit_start: 112 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3153,7 +2790,7 @@ Message ID: map equation: "0.01x+2" Cell 135 Temp: bit_start: 120 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3161,7 +2798,7 @@ Message ID: map equation: "0.25x" Cell 136 Voltage: bit_start: 128 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3169,7 +2806,7 @@ Message ID: map equation: "0.01x+2" Cell 136 Temp: bit_start: 136 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3177,7 +2814,7 @@ Message ID: map equation: "0.25x" Cell 137 Voltage: bit_start: 144 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3185,7 +2822,7 @@ Message ID: map equation: "0.01x+2" Cell 137 Temp: bit_start: 152 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3193,7 +2830,7 @@ Message ID: map equation: "0.25x" Cell 138 Voltage: bit_start: 160 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3201,7 +2838,7 @@ Message ID: map equation: "0.01x+2" Cell 138 Temp: bit_start: 168 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3209,7 +2846,7 @@ Message ID: map equation: "0.25x" Cell 139 Voltage: bit_start: 176 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3217,7 +2854,7 @@ Message ID: map equation: "0.01x+2" Cell 139 Temp: bit_start: 184 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3225,7 +2862,7 @@ Message ID: map equation: "0.25x" Cell 140 Voltage: bit_start: 192 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3233,7 +2870,7 @@ Message ID: map equation: "0.01x+2" Cell 140 Temp: bit_start: 200 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3241,7 +2878,7 @@ Message ID: map equation: "0.25x" Cell 141 Voltage: bit_start: 208 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3249,7 +2886,7 @@ Message ID: map equation: "0.01x+2" Cell 141 Temp: bit_start: 216 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3257,7 +2894,7 @@ Message ID: map equation: "0.25x" Cell 142 Voltage: bit_start: 224 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3265,7 +2902,7 @@ Message ID: map equation: "0.01x+2" Cell 142 Temp: bit_start: 232 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3273,7 +2910,7 @@ Message ID: map equation: "0.25x" Cell 143 Voltage: bit_start: 240 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3281,7 +2918,7 @@ Message ID: map equation: "0.01x+2" Cell 143 Temp: bit_start: 248 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3289,7 +2926,7 @@ Message ID: map equation: "0.25x" Cell 144 Voltage: bit_start: 256 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3297,7 +2934,7 @@ Message ID: map equation: "0.01x+2" Cell 144 Temp: bit_start: 264 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3305,7 +2942,7 @@ Message ID: map equation: "0.25x" Cell 145 Voltage: bit_start: 272 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3313,7 +2950,7 @@ Message ID: map equation: "0.01x+2" Cell 145 Temp: bit_start: 280 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3321,7 +2958,7 @@ Message ID: map equation: "0.25x" Cell 146 Voltage: bit_start: 288 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3329,7 +2966,7 @@ Message ID: map equation: "0.01x+2" Cell 146 Temp: bit_start: 296 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3337,7 +2974,7 @@ Message ID: map equation: "0.25x" Cell 147 Voltage: bit_start: 304 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3345,7 +2982,7 @@ Message ID: map equation: "0.01x+2" Cell 147 Temp: bit_start: 312 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3353,7 +2990,7 @@ Message ID: map equation: "0.25x" Cell 148 Voltage: bit_start: 320 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3361,7 +2998,7 @@ Message ID: map equation: "0.01x+2" Cell 148 Temp: bit_start: 328 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3369,7 +3006,7 @@ Message ID: map equation: "0.25x" Cell 149 Voltage: bit_start: 336 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3377,7 +3014,7 @@ Message ID: map equation: "0.01x+2" Cell 149 Temp: bit_start: 344 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3385,7 +3022,7 @@ Message ID: map equation: "0.25x" Cell 150 Voltage: bit_start: 352 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3393,7 +3030,7 @@ Message ID: map equation: "0.01x+2" Cell 150 Temp: bit_start: 360 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3401,7 +3038,7 @@ Message ID: map equation: "0.25x" Cell 151 Voltage: bit_start: 368 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3409,7 +3046,7 @@ Message ID: map equation: "0.01x+2" Cell 151 Temp: bit_start: 376 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3417,7 +3054,7 @@ Message ID: map equation: "0.25x" Cell 152 Voltage: bit_start: 384 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3425,7 +3062,7 @@ Message ID: map equation: "0.01x+2" Cell 152 Temp: bit_start: 392 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3433,7 +3070,7 @@ Message ID: map equation: "0.25x" Cell 153 Voltage: bit_start: 400 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3441,7 +3078,7 @@ Message ID: map equation: "0.01x+2" Cell 153 Temp: bit_start: 408 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3449,7 +3086,7 @@ Message ID: map equation: "0.25x" Cell 154 Voltage: bit_start: 416 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3457,7 +3094,7 @@ Message ID: map equation: "0.01x+2" Cell 154 Temp: bit_start: 424 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3465,7 +3102,7 @@ Message ID: map equation: "0.25x" Cell 155 Voltage: bit_start: 432 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3473,7 +3110,7 @@ Message ID: map equation: "0.01x+2" Cell 155 Temp: bit_start: 440 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3481,7 +3118,7 @@ Message ID: map equation: "0.25x" Cell 156 Voltage: bit_start: 448 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3489,7 +3126,7 @@ Message ID: map equation: "0.01x+2" Cell 156 Temp: bit_start: 456 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3497,7 +3134,7 @@ Message ID: map equation: "0.25x" Cell 157 Voltage: bit_start: 464 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3505,7 +3142,7 @@ Message ID: map equation: "0.01x+2" Cell 157 Temp: bit_start: 472 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3513,7 +3150,7 @@ Message ID: map equation: "0.25x" Cell 158 Voltage: bit_start: 480 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3521,7 +3158,7 @@ Message ID: map equation: "0.01x+2" Cell 158 Temp: bit_start: 488 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3529,7 +3166,7 @@ Message ID: map equation: "0.25x" Cell 159 Voltage: bit_start: 496 - # Cell n voltage + comment: Cell n voltage data type: u8 units: Volts scaled min: 2 @@ -3537,7 +3174,7 @@ Message ID: map equation: "0.01x+2" Cell 159 Temp: bit_start: 504 - # Cell n temperature + comment: Cell n temperature data type: u8 units: Celsius scaled min: 0 @@ -3548,7 +3185,7 @@ Message ID: MSG LENGTH: 7 Input Voltage: bit_start: 0 - # ~20v for LV (LV only. Send 0 for HV) + comment: ~20v for LV (LV only. Send 0 for HV) data type: u16 units: Volts scaled min: 0 @@ -3556,7 +3193,7 @@ Message ID: map equation: "x/1000" Output Voltage: bit_start: 16 - # ~12v for LV and ~20v for HV + comment: ~12v for LV and ~20v for HV data type: u16 units: Volts scaled min: 0 @@ -3564,7 +3201,7 @@ Message ID: map equation: "x/1000" Input Current: bit_start: 32 - # Input current (LV only. Send 0 for HV) + comment: Input current (LV only. Send 0 for HV) data type: u8 units: Amps scaled min: 0 @@ -3572,7 +3209,7 @@ Message ID: map equation: "0.1x" Output Current: bit_start: 40 - # Output current + comment: Output current data type: u8 units: Amps scaled min: 0 @@ -3580,7 +3217,7 @@ Message ID: map equation: "0.1x" DC-DC Temp: bit_start: 48 - # Temp of DC-DC converter + comment: Temp of DC-DC converter data type: u8 units: Celsius scaled min: 0 @@ -3591,7 +3228,7 @@ Message ID: MSG LENGTH: 6 AC current: bit_start: 0 - # 0.01 * current, int16_t + comment: 0.01 * current, int16_t data type: u16 units: Amps scaled min: -327.68 @@ -3599,7 +3236,7 @@ Message ID: map equation: "0.01x-327.68" DC current: bit_start: 16 - # 0.01 * current, int16_t + comment: 0.01 * current, int16_t data type: u16 units: Amps scaled min: 0 @@ -3607,7 +3244,7 @@ Message ID: map equation: "0.01x" Motor RPM: bit_start: 32 - # RPM, int16_t + comment: RPM, int16_t data type: u16 units: RPM scaled min: -32768 @@ -3618,7 +3255,7 @@ Message ID: MSG LENGTH: 6 U MOSFET temperature: bit_start: 0 - # Celsius + 40, uint8_t + comment: Celsius + 40, uint8_t data type: u8 units: Celsius scaled min: -40 @@ -3626,7 +3263,7 @@ Message ID: map equation: "x-40" V MOSFET temperature: bit_start: 16 - # Celsius + 40, uint8_t + comment: Celsius + 40, uint8_t data type: u8 units: Celsius scaled min: -40 @@ -3634,7 +3271,7 @@ Message ID: map equation: "x-40" W MOSFET temperature: bit_start: 32 - # Celsius + 40, uint8_t + comment: Celsius + 40, uint8_t data type: u8 units: Celsius scaled min: -40 @@ -3645,7 +3282,7 @@ Message ID: MSG LENGTH: 2 Motor temperature: bit_start: 0 - # Celsius + 40, uint8_t + comment: Celsius + 40, uint8_t data type: u8 units: Celsius scaled min: -40 @@ -3653,37 +3290,37 @@ Message ID: map equation: "x-40" Over voltage faults: bit_start: 16 - # TS above set max voltage + comment: TS above set max voltage data type: b units: Bool Under voltage fault: bit_start: 17 - # TS below set min voltage + comment: TS below set min voltage data type: b units: Bool Inv. overtemp fault: bit_start: 18 - # Inverter over set max temp + comment: Inverter over set max temp data type: b units: Bool Motor overtemp fault: bit_start: 19 - # Motor over set max temp + comment: Motor over set max temp data type: b units: Bool Transistor fault: bit_start: 20 - # Mosfet or mosfet drive error + comment: Mosfet or mosfet drive error data type: b units: Bool Encoder fault: bit_start: 21 - # Encoder communication or calc error + comment: Encoder communication or calc error data type: b units: Bool CAN fault: bit_start: 22 - # CAN message error or timeout + comment: CAN message error or timeout data type: b units: Bool Future use: @@ -3695,7 +3332,7 @@ Message ID: MSG LENGTH: 7 Max AC Current: bit_start: 0 - # Max AC Current + comment: Max AC Current data type: u16 units: Amps scaled min: -327.68 @@ -3703,7 +3340,7 @@ Message ID: map equation: "0.01x-327.68" Max DC Current: bit_start: 16 - # Max DC Current + comment: Max DC Current data type: u16 units: Amps scaled min: -327.68 @@ -3711,7 +3348,7 @@ Message ID: map equation: "0.01x-327.68" Absolute Max RPM Limit: bit_start: 32 - # 0: No limit n :limited at n RPM + comment: 0: No limit n :limited at n RPM data type: u16 units: RPM scaled min: -32768 @@ -3719,7 +3356,7 @@ Message ID: map equation: "x-32768" Motor direction: bit_start: 48 - # Write 1 inverts direction + comment: Write 1 inverts direction data type: b units: Enable scaled min: "-" @@ -3730,7 +3367,7 @@ Message ID: MSG LENGTH: 8 Set AC Current: bit_start: 0 - # Commanded AC Current + comment: Commanded AC Current data type: u16 units: Amps scaled min: -327.68 @@ -3738,7 +3375,7 @@ Message ID: map equation: "0.01x-327.68" Set DC Current: bit_start: 16 - # Commanded DC Current + comment: Commanded DC Current data type: u16 units: Amps scaled min: -327.68 @@ -3746,7 +3383,7 @@ Message ID: map equation: "0.01x-327.68" RPM Limit: bit_start: 32 - # 0: No limit n :limited at n RPM + comment: 0: No limit n :limited at n RPM data type: u16 units: RPM scaled min: -32768 @@ -3754,7 +3391,7 @@ Message ID: map equation: "x-32768" Field weakening: bit_start: 48 - # Field weakening strength + comment: Field weakening strength data type: u8 units: Amps scaled min: 0 @@ -3762,7 +3399,7 @@ Message ID: map equation: "0.1x" Drive enable: bit_start: 56 - # Write this to 1 every 100ms to enable inverter + comment: Write this to 1 every 100ms to enable inverter data type: b units: Enable scaled min: "-" @@ -3773,7 +3410,7 @@ Message ID: MSG LENGTH: 4 Fan Speed: bit_start: 0 - # Fan RPM + comment: Fan RPM data type: u16 units: RPM scaled min: 0 @@ -3781,7 +3418,7 @@ Message ID: map equation: "1x" Input Voltage: bit_start: 16 - # 0-22 + comment: 0-22 data type: u8 units: Volts scaled min: 0 @@ -3789,7 +3426,7 @@ Message ID: map equation: "0.1x" Input Current: bit_start: 24 - # 0-10 + comment: 0-10 data type: u8 units: Amps scaled min: 0 @@ -3800,7 +3437,7 @@ Message ID: MSG LENGTH: 1 Fan Command: bit_start: 0 - # 0-100 Percent + comment: 0-100 Percent data type: u8 units: '%' scaled min: 0 @@ -3809,55 +3446,30 @@ Message ID: Dash Status: MSG ID: 0x01A MSG LENGTH: 3 - BMS LED: + button_flags: bit_start: 0 - # State of BMS LED - data type: b - units: Bool - IMD LED: - bit_start: 1 - # State of IMD LED - data type: b - units: Bool - BSPD LED: - bit_start: 2 - # State of BSPD LED - data type: b - units: Bool - TS Button Data: + comment: TS Active = bit 0, RTD = bit 1, bits 2–7 reserved + data type: u8 + led_bits: bit_start: 8 - # MSB is state (1: pressed) - # Other 7 bits represent the time in 0.1s that it has been in that state - data type: s8 - units: Seconds - scaled min: 0 - scaled max: 12.7 - map equation: "abs(x)/10" - RTD Button Data: - bit_start: 16 - # MSB is state (1: pressed) - # Other 7 bits represent the time in 0.1s that it has been in that state - data type: s8 - units: Seconds - scaled min: 0 - scaled max: 12.7 - map equation: "abs(x)/10" + comment: BMS = bit 0 of this byte, IMD = bit 1, BSPD = bit 2, bits 3–7 reserved + data type: u8 Dash Config: MSG ID: 0x01B MSG LENGTH: 1 BMS LED: bit_start: 0 - # LED command (0: off, 1: on) + comment: LED command (0: off, 1: on) data type: b units: Bool IMD LED: bit_start: 1 - # LED command (0: off, 1: on) + comment: LED command (0: off, 1: on) data type: b units: Bool BSPD LED: bit_start: 2 - # LED command (0: off, 1: on) + comment: LED command (0: off, 1: on) data type: b units: Bool Steering Status: @@ -3865,7 +3477,7 @@ Message ID: MSG LENGTH: 2 Current Encoder: bit_start: 0 - # Position of knob (1-16) + comment: Position of knob (1-16) data type: u4 units: Position scaled min: 1 @@ -3873,7 +3485,7 @@ Message ID: map equation: "1x" Torque Map Encoder: bit_start: 4 - # Position of knob (1-16) + comment: Position of knob (1-16) data type: u4 units: Position scaled min: 1 @@ -3881,7 +3493,7 @@ Message ID: map equation: "1x" Regen: bit_start: 8 - # Position of knob (1-16) + comment: Position of knob (1-16) data type: u4 units: Position scaled min: 1 @@ -3889,22 +3501,22 @@ Message ID: map equation: "1x" Button 1: bit_start: 12 - # Button State + comment: Button State data type: b units: Bool Button 2: bit_start: 13 - # Button State + comment: Button State data type: b units: Bool Button 3: bit_start: 14 - # Button State + comment: Button State data type: b units: Bool Button 4: bit_start: 15 - # Button State + comment: Button State data type: b units: Bool Steering Config: @@ -3917,7 +3529,7 @@ Message ID: MSG LENGTH: 1 Temp: bit_start: 0 - # IR Temp of Brakes + comment: IR Temp of Brakes data type: u8 units: Celsius scaled min: 0 @@ -3928,7 +3540,7 @@ Message ID: MSG LENGTH: 4 Outside Temp: bit_start: 0 - # Furthest from chassis + comment: Furthest from chassis data type: u8 units: Celsius scaled min: 0 @@ -3936,7 +3548,7 @@ Message ID: map equation: "1x" Outside Middle Temp: bit_start: 8 - # Middle of tire + comment: Middle of tire data type: u8 units: Celsius scaled min: 0 @@ -3944,7 +3556,7 @@ Message ID: map equation: "1x" Inside Middle Temp: bit_start: 16 - # Middle of tire + comment: Middle of tire data type: u8 units: Celsius scaled min: 0 @@ -3952,7 +3564,7 @@ Message ID: map equation: "1x" Inside Temp: bit_start: 24 - # Closest to chassis + comment: Closest to chassis data type: u8 units: Celsius scaled min: 0 @@ -3963,7 +3575,7 @@ Message ID: MSG LENGTH: 12 Accel X: bit_start: 0 - # Acceleration in X-axis + comment: Acceleration in X-axis data type: u16 units: Meters/s^2 scaled min: -327.68 @@ -3971,7 +3583,7 @@ Message ID: map equation: "0.01x-327.68" Accel Y: bit_start: 16 - # Acceleration in Y-axis + comment: Acceleration in Y-axis data type: u16 units: Meters/s^2 scaled min: -327.68 @@ -3979,7 +3591,7 @@ Message ID: map equation: "0.01x-327.68" Accel Z: bit_start: 32 - # Acceleration in Z-axis + comment: Acceleration in Z-axis data type: u16 units: Meters/s^2 scaled min: -327.68 @@ -3987,7 +3599,7 @@ Message ID: map equation: "0.01x-327.68" Gyro X: bit_start: 48 - # Angular velocity in X-axis + comment: Angular velocity in X-axis data type: u16 units: Meters/s^2 scaled min: -32.768 @@ -3995,7 +3607,7 @@ Message ID: map equation: "0.001x-32.768" Gyro Y: bit_start: 64 - # Angular velocity in Y-axis + comment: Angular velocity in Y-axis data type: u16 units: Meters/s^2 scaled min: -32.768 @@ -4003,7 +3615,7 @@ Message ID: map equation: "0.001x-32.768" Gyro Z: bit_start: 80 - # Angular velocity in Z-axis + comment: Angular velocity in Z-axis data type: u16 units: Meters/s^2 scaled min: -32.768 @@ -4014,12 +3626,12 @@ Message ID: MSG LENGTH: 8 Latitude: bit_start: 0 - # Latitude in decimal degrees + comment: Latitude in decimal degrees data type: u32 units: Degrees Longitude: bit_start: 32 - # Longitude in decimal degrees + comment: Longitude in decimal degrees data type: u32 units: Degrees SAM GPS 2: @@ -4027,36 +3639,36 @@ Message ID: MSG LENGTH: 8 Accuracy: bit_start: 0 - # GPS position accuracy + comment: GPS position accuracy data type: u32 Attitude: bit_start: 32 - # Vehicle attitude + comment: Vehicle attitude data type: u32 SAM GPS Time: MSG ID: 0x023 MSG LENGTH: 8 Time: bit_start: 0 - # Time in seconds since GPS Epoch + comment: Time in seconds since GPS Epoch data type: u32 Time of Week Ms: bit_start: 32 - # Time of week in milliseconds + comment: Time of week in milliseconds data type: u32 SAM GPS Heading: MSG ID: 0x024 MSG LENGTH: 4 Heading from North: bit_start: 0 - # Heading angle relative to true North + comment: Heading angle relative to true North data type: u32 SAM Sus Pots: MSG ID: 0x025 MSG LENGTH: 1 Suspension Angle: bit_start: 0 - # Pot Pos + comment: Pot Pos data type: u8 units: degrees scaled min: 0 @@ -4067,7 +3679,7 @@ Message ID: MSG LENGTH: 2 Height: bit_start: 0 - # Ride Height + comment: Ride Height data type: u16 units: mm scaled min: 0 @@ -4078,7 +3690,7 @@ Message ID: MSG LENGTH: 2 Speed: bit_start: 0 - # Wheel RPM + comment: Wheel RPM data type: u16 units: RPM scaled min: -3276.8 @@ -4089,7 +3701,7 @@ Message ID: MSG LENGTH: 2 Load Force: bit_start: 0 - # Pushrod Force + comment: Pushrod Force data type: u16 units: N scaled min: -3276.8 @@ -4100,34 +3712,34 @@ Message ID: MSG LENGTH: 8 Connection Status: bit_start: 0 - # 1: OK, 0: Timeout + comment: 1: OK, 0: Timeout data type: b units: Bool MQTT Status: bit_start: 1 - # 1: OK, 0: Timeout + comment: 1: OK, 0: Timeout data type: b units: Bool Epic Shelter Status: bit_start: 2 - # 1: In Progress, 0: Idle + comment: 1: In Progress, 0: Idle data type: b units: Bool Camera Status: bit_start: 3 - # 1: Recording, 0: Idle + comment: 1: Recording, 0: Idle data type: b units: Bool Reserved: bit_start: 4-7 - Ping: + Mapache Ping: bit_start: 8 - # Mapache ping (upload) + comment: Mapache ping (upload) data type: u16 units: ms Cache Size: bit_start: 24 - # # of messages on cache (non-synced) + comment: # of messages on cache (non-synced) data type: u32 units: # Reserved: @@ -4137,113 +3749,113 @@ Message ID: MSG LENGTH: 44 CPU 0 Freq: bit_start: 0 - # core 0 frequency in MHz + comment: core 0 frequency in MHz data type: u16 units: '%' CPU 0 Util: bit_start: 16 - # core 0 utilization in % + comment: core 0 utilization in % data type: u8 units: '%' CPU 1 Freq: bit_start: 24 - # core 1 frequency in MHz + comment: core 1 frequency in MHz data type: u16 units: '%' CPU 1 Util: bit_start: 40 - # core 1 utilization in % + comment: core 1 utilization in % data type: u8 CPU 2 Freq: bit_start: 48 - # core 2 frequency in MHz + comment: core 2 frequency in MHz data type: u16 units: '%' CPU 2 Util: bit_start: 64 - # core 2 utilization in % + comment: core 2 utilization in % data type: u8 CPU 3 Freq: bit_start: 72 - # core 3 frequency in MHz + comment: core 3 frequency in MHz data type: u16 CPU 3 Util: bit_start: 88 - # core 3 utilization in % + comment: core 3 utilization in % data type: u8 CPU 4 Freq: bit_start: 96 - # core 4 frequency in MHz + comment: core 4 frequency in MHz data type: u16 CPU 4 Util: bit_start: 112 - # core 4 utilization in % + comment: core 4 utilization in % data type: u8 CPU 5 Freq: bit_start: 120 - # core 5 frequency in MHz + comment: core 5 frequency in MHz data type: u16 CPU 5 Util: bit_start: 136 - # core 5 utilization in % + comment: core 5 utilization in % data type: u8 units: Watts CPU Total Util: bit_start: 144 - # total cpu utilization in % + comment: total cpu utilization in % data type: u8 RAM Total: bit_start: 152 - # total memory in MB + comment: total memory in MB data type: u16 RAM Used: bit_start: 168 - # used memory in MB + comment: used memory in MB data type: u16 RAM Util: bit_start: 184 - # memory utilization in % + comment: memory utilization in % data type: u8 GPU Util: bit_start: 192 - # gpu utilization in % + comment: gpu utilization in % data type: u8 GPU Freq: bit_start: 200 - # gpu frequency in MHz + comment: gpu frequency in MHz data type: u16 Disk Total: bit_start: 216 - # total disk space in MB + comment: total disk space in MB data type: u32 Disk Used: bit_start: 248 - # used disk space in MB + comment: used disk space in MB data type: u32 Disk Util: bit_start: 280 - # disk utilization in % + comment: disk utilization in % data type: u8 units: Celsius CPU Temp: bit_start: 288 - # cpu temp in ˚C + comment: cpu temp in ˚C data type: u8 GPU Temp: bit_start: 296 - # gpu temp in ˚C + comment: gpu temp in ˚C data type: u8 Voltage Draw: bit_start: 304 - # voltage draw in mV + comment: voltage draw in mV data type: u16 Current Draw: bit_start: 320 - # current draw in mA + comment: current draw in mA data type: u16 Power Draw: bit_start: 336 - # power draw in mW + comment: power draw in mW data type: u16 units: Celsius Dash Warning Flags: @@ -4251,7 +3863,7 @@ Message ID: MSG LENGTH: 1 BSE APPS Violation: bit_start: 0 - # 1: Violation, 0: OK + comment: 1: Violation, 0: OK data type: b units: Bool Reserved: @@ -4273,11 +3885,11 @@ Message ID: MSG LENGTH: 2 Wheel identifier: bit_start: 0 - # Wheel identifier according to the wiki + comment: Wheel identifier according to the wiki data type: u8 Temp: bit_start: 8 - # IR Temp of Brakes + comment: IR Temp of Brakes data type: u8 units: Celsius scaled min: 0 @@ -4288,49 +3900,73 @@ Message ID: MSG LENGTH: 3 Online pings: bit_start: 0 - # Literal copy of ECU Status's status bit map + comment: Literal copy of ECU Status's status bit map data type: b[24] units: Bool map ECU Pedals Data: MSG ID: 0x02E - MSG LENGTH: 10 - APPS1_SIGNAL: + MSG LENGTH: 16 + BSPD Signal: bit_start: 0 - # APPS 1 Signal + comment: 4-20 mA signal data type: u16 - units: '%' + units: % scaled min: 0 scaled max: 100 map equation: "x/655.35" - APPS2_SIGNAL: + BSE Signal: bit_start: 16 - # APPS 2 Signal + comment: 4-20 mA signal data type: u16 - units: '%' + units: % scaled min: 0 scaled max: 100 map equation: "x/655.35" - BSE_SIGNAL: + APPS 1 Signal: bit_start: 32 - # Brake Force Signal + comment: 4-20 mA signal data type: u16 - units: '%' + units: % scaled min: 0 scaled max: 100 map equation: "x/655.35" - BRAKE_F_SIGNAL: + APPS 2 Signal: bit_start: 48 - # Brake Pressure Signal + comment: 4-20 mA signal data type: u16 - units: '%' + units: % scaled min: 0 scaled max: 100 map equation: "x/655.35" - BRAKE_R_SIGNAL: - bit_start: 48 - # Brake Pressure Signal + Brakeline F Signal: + bit_start: 64 + comment: 4-20 mA signal data type: u16 - units: '%' + units: % + scaled min: 0 + scaled max: 100 + map equation: "x/655.35" + Brakeline R Signal: + bit_start: 80 + comment: 4-20 mA signal + data type: u16 + units: % + scaled min: 0 + scaled max: 100 + map equation: "x/655.35" + Steering Angle Signal: + bit_start: 96 + comment: 4-20 mA signal + data type: u16 + units: % + scaled min: 0 + scaled max: 100 + map equation: "x/655.35" + AUX Signal: + bit_start: 112 + comment: 4-20 mA signal + data type: u16 + units: % scaled min: 0 scaled max: 100 map equation: "x/655.35" @@ -4339,21 +3975,21 @@ Message ID: MSG LENGTH: 8 LAT: bit_start: 0 - # lattitude + comment: lattitude data type: double GPS LON: MSG ID: 0x032 MSG LENGTH: 8 LON: bit_start: 0 - # longitude + comment: longitude data type: double GPS ALT: MSG ID: 0x033 MSG LENGTH: 8 ALT: bit_start: 0 - # altitude + comment: altitude data type: double GPS PX: MSG ID: 0x034 @@ -4402,17 +4038,17 @@ Message ID: MSG LENGTH: 6 DGPS_U: bit_start: 0 - # U + comment: U data type: i16 map equation: "x/100" DGPS_V: bit_start: 16 - # V + comment: V data type: i16 map equation: "x/100" DGPS_W: bit_start: 32 - # W + comment: W data type: i16 map equation: "x/100" @@ -4423,246 +4059,247 @@ Custom CAN ID: signals: - name: "Target AC Current" bit_start: 0 - # This command sets the target motor AC current (peak, not - # RMS). When the controller receives this message, it - # automatically switches to current control mode. - # This value must not be above the limits of the inverter and must - # be multiplied by 10 before sending. This is a signed parameter, - # and the sign represents the direction of the torque which - # correlates with the motor AC current. (For the correlation, please - # refer to the motor parameters) - + comment: + This command sets the target motor AC current (peak, not + RMS). When the controller receives this message, it + automatically switches to current control mode. + This value must not be above the limits of the inverter and must + be multiplied by 10 before sending. This is a signed parameter, + and the sign represents the direction of the torque which + correlates with the motor AC current. (For the correlation, please + refer to the motor parameters) DTI Control 2: CAN ID: 216 Length: 2 signals: - name: "Target Brake Current" bit_start: 0 - # Targets the brake current of the motor. It will result negative - # torque relatively to the forward direction of the motor. - # This value must be multiplied by 10 before sending, only - # positive currents are accepted. - + comment: + Targets the brake current of the motor. It will result negative + torque relatively to the forward direction of the motor. + This value must be multiplied by 10 before sending, only + positive currents are accepted. DTI Control 3: CAN ID: 316 Length: 4 signals: - name: "Target ERPM" bit_start: 0 - # This command enables the speed control of the motor with a - # target ERPM. This is a signed parameter, and the sign - # represents the direction of the spinning. For better operation you - # need to tune the PID of speed control. - # Equation: ERPM = Motor RPM * number of the motor pole pairs - + comment: + This command enables the speed control of the motor with a + target ERPM. This is a signed parameter, and the sign + represents the direction of the spinning. For better operation you + need to tune the PID of speed control. + Equation: ERPM = Motor RPM * number of the motor pole pairs DTI Control 4: CAN ID: 416 Length: 2 signals: - name: "Target Position" bit_start: 0 - # This value targets the desired position of the motor in degrees. - # This command is used to hold a position of the motor. - # This feature is enabled only if encoder is used as position - # sensor. The value has to be multiplied by 10 before sending. - + comment: + This value targets the desired position of the motor in degrees. + This command is used to hold a position of the motor. + This feature is enabled only if encoder is used as position + sensor. The value has to be multiplied by 10 before sending. DTI Control 5: CAN ID: 516 Length: 2 signals: - name: "R-AC Current" bit_start: 0 - # This command sets a relative AC current to the minimum and - # maximum limits set by configuration. This achieves the same - # function as the “Set AC current” command. Gives you a freedom - # to send values between -100,0% and 100,0%. You do not need - # to know the motor limit parameters. - # This value must be between -100 and 100 and must be - # multiplied by 10 before sending. - + comment: + This command sets a relative AC current to the minimum and + maximum limits set by configuration. This achieves the same + function as the “Set AC current” command. Gives you a freedom + to send values between -100,0% and 100,0%. You do not need + to know the motor limit parameters. + This value must be between -100 and 100 and must be + multiplied by 10 before sending. DTI Control 6: CAN ID: 616 Length: 2 signals: - name: "R-AC Brake Current" bit_start: 0 - # Targets the relative brake current of the motor. It will result - # negative torque relatively to the forward direction of the motor. - # This value must be between 0 and 100 and must be multiplied - # by 10 before sending Gives you a freedom to send values - # between 0% and 100,0%. You do not need to know the motor - # limit parameters. - # This value must be between 0 and 100 and has to be multiplied - # by 10 before sending - + comment: + Targets the relative brake current of the motor. It will result + negative torque relatively to the forward direction of the motor. + This value must be between 0 and 100 and must be multiplied + by 10 before sending Gives you a freedom to send values + between 0% and 100,0%. You do not need to know the motor + limit parameters. + This value must be between 0 and 100 and has to be multiplied + by 10 before sending DTI Control 7: CAN ID: 716 Length: 1 signals: - name: "Digital Output 1" bit_start: 0 - # Sets the digital output 1 to HIGH (1) or LOW (0) state + comment: Sets the digital output 1 to HIGH (1) or LOW (0) state - name: "Digital Output 2" bit_start: 1 - # Sets the digital output 1 to HIGH (1) or LOW (0) state + comment: Sets the digital output 1 to HIGH (1) or LOW (0) state - name: "Digital Output 3" bit_start: 2 - # Sets the digital output 1 to HIGH (1) or LOW (0) state + comment: Sets the digital output 1 to HIGH (1) or LOW (0) state - name: "Digital Output 4" bit_start: 3 - # Sets the digital output 1 to HIGH (1) or LOW (0) state - + comment: Sets the digital output 1 to HIGH (1) or LOW (0) state DTI Control 8: CAN ID: 816 Length: 2 signals: - name: "Max AC Current" bit_start: 0 - # This value determines the maximum allowable drive current on - # the AC side. With this function you are able maximize the - # maximum torque on the motor. - # The value must be multiplied by 10 before sending. - + comment: + This value determines the maximum allowable drive current on + the AC side. With this function you are able maximize the + maximum torque on the motor. + The value must be multiplied by 10 before sending. DTI Control 9: CAN ID: 916 Length: 2 signals: - name: "Max Brake AC Current" bit_start: 0 - # This value sets the maximum allowable brake current on the AC - # side. - # This value must be multiplied by 10 before sending, only - # negative currents are accepted. - + comment: + This value sets the maximum allowable brake current on the AC + side. + This value must be multiplied by 10 before sending, only + negative currents are accepted. DTI Control 10: CAN ID: A16 Length: 2 signals: - name: "Max DC Current" bit_start: 0 - # This value determines the maximum allowable drive current on - # the DC side. With this command the BMS can limit the - # maximum allowable battery discharge current. - # The value has to be multiplied by 10 before sending. - + comment: + This value determines the maximum allowable drive current on + the DC side. With this command the BMS can limit the + maximum allowable battery discharge current. + The value has to be multiplied by 10 before sending. DTI Control 11: CAN ID: B16 Length: 2 signals: - name: "Max Brake DC Current" bit_start: 0 - # This value determines the maximum allowable brake current - # on the DC side. With this command the BMS can limit the - # maximum allowable battery charge current. - # The value has to be multiplied by 10 before sending. Only - # negative currents are accepted. - + comment: + This value determines the maximum allowable brake current + on the DC side. With this command the BMS can limit the + maximum allowable battery charge current. + The value has to be multiplied by 10 before sending. Only + negative currents are accepted. DTI Control 12: CAN ID: C16 Length: 1 signals: - name: "Drive Enable" bit_start: 0 - # 0: Drive not allowed - # 1: Drive allowed - # Only 0 and 1 values are accepted. Must be sent periodically to - # be enabled. - + comment: + 0: Drive not allowed + 1: Drive allowed + Only 0 and 1 values are accepted. Must be sent periodically to + be enabled. DTI Data 1: CAN ID: 2016 Length: 8 signals: - name: "ERPM" bit_start: 0 - # Electrical RPM - # Equation: ERPM = Motor RPM * number of the motor pole pairs. + comment: + Electrical RPM + Equation: ERPM = Motor RPM * number of the motor pole pairs. - name: "Duty Cycle" bit_start: 32 - # The controller duty cycle. The sign of this value will represent - # whether the motor is running(positive) current or regenerating - # (negative) current. + comment: + The controller duty cycle. The sign of this value will represent + whether the motor is running(positive) current or regenerating + (negative) current. - name: "Input Voltage" bit_start: 48 - # Input voltage is the DC voltage. - + comment: Input voltage is the DC voltage. DTI Data 2: CAN ID: 2116 Length: 8 signals: - name: "AC Current" bit_start: 0 - # The motor current. The sign of this value represents whether the - # motor is running(positive) current or regenerating (negative) - # current. + comment: + The motor current. The sign of this value represents whether the + motor is running(positive) current or regenerating (negative) + current. - name: "DC Current" bit_start: 16 - # DC Current: Current on DC side. The sign of this value - # represents whether the motor is running(positive) current or - # regenerating (negative) current. + comment: + DC Current: Current on DC side. The sign of this value + represents whether the motor is running(positive) current or + regenerating (negative) current. - name: "RESERVED" bit_start: 32 - # Filled with FF’s. For future use. - + comment: Filled with FF’s. For future use. DTI Data 3: CAN ID: 2216 Length: 8 signals: - name: "Controller Temp" bit_start: 0 - # Temperature of the inverter semiconductors. + comment: Temperature of the inverter semiconductors. - name: "Motor Temp" bit_start: 16 - # Temperature of the motor measured by the inverter + comment: Temperature of the motor measured by the inverter - name: "Fault Codes" bit_start: 32 - # 0x00 : NO FAULTS - # 0x01 : Overvoltage - The input voltage is higher than the set - # maximum. - # 0x02 : Undervoltage - The input voltage is lower than the set - # minimum. - # 0x03 : DRV - Transistor or transistor drive error - # 0x04 : ABS. Overcurrent - The AC current is higher than the - # set absolute maximum current. - # 0x05 : CTLR Overtemp. - The controller temperature is higher - # than the set maximum. - # 0x06 : Motor Overtemp. - The motor temperature is higher than - # the set maximum. - # 0x07 : Sensor wire fault - Something went wrong with the - # sensor differential signals. - # 0x08 : Sensor general fault - An error occurred while - # processing the sensor signals - # 0x09 : CAN Command error - CAN message received contains - # parameter out of boundaries - # 0x0A : Analog input error – Redundant output out of range + comment: + 0x00 : NO FAULTS + 0x01 : Overvoltage - The input voltage is higher than the set + maximum. + 0x02 : Undervoltage - The input voltage is lower than the set + minimum. + 0x03 : DRV - Transistor or transistor drive error + 0x04 : ABS. Overcurrent - The AC current is higher than the + set absolute maximum current. + 0x05 : CTLR Overtemp. - The controller temperature is higher + than the set maximum. + 0x06 : Motor Overtemp. - The motor temperature is higher than + the set maximum. + 0x07 : Sensor wire fault - Something went wrong with the + sensor differential signals. + 0x08 : Sensor general fault - An error occurred while + processing the sensor signals + 0x09 : CAN Command error - CAN message received contains + parameter out of boundaries + 0x0A : Analog input error – Redundant output out of range - name: "RESERVED" bit_start: 40 - # Filled with FF’s. For future use. - + comment: Filled with FF’s. For future use. DTI Data 4: CAN ID: 2316 Length: 8 signals: - name: "FOC Id" bit_start: 0 - # FOC algorithm component Id. + comment: FOC algorithm component Id. - name: "FOC Iq" bit_start: 32 - # FOC algorithm component Id\q. - + comment: FOC algorithm component Id\q. DTI Data 5: CAN ID: 2416 Length: 8 signals: - name: "Throttle" bit_start: 0 - # Throttle signal derived from analog inputs or CAN2 + comment: Throttle signal derived from analog inputs or CAN2 - name: "Brake" bit_start: 8 - # Brake signal derived from analog inputs or CAN2 + comment: Brake signal derived from analog inputs or CAN2 - name: "Digital input 1" bit_start: 16 - # 1: Digital input is active - # 0: Digital input is inactive + comment: + 1: Digital input is active + 0: Digital input is inactive - name: "Digital input 2" bit_start: 17 - name: "Digital input 3" @@ -4671,8 +4308,9 @@ Custom CAN ID: bit_start: 19 - name: "Digital output 1" bit_start: 20 - # 1: Digital output is active - # 0: Digital output is inactive + comment: + 1: Digital output is active + 0: Digital output is inactive - name: "Digital output 2" bit_start: 21 - name: "Digital output 3" @@ -4681,69 +4319,80 @@ Custom CAN ID: bit_start: 23 - name: "Drive Enable" bit_start: 24 - # 1: Drive enabled - # 0: Drive disabled - # Drive can be enabled/disbled by the digital input or/and via - # CAN2 interface + comment: + 1: Drive enabled + 0: Drive disabled + Drive can be enabled/disbled by the digital input or/and via + CAN2 interface - name: "Capacitor temp limit" bit_start: 32 - # 1: Capacitor temperature limit active - # 0: Capacitor temperature limit inactive - # The inverter can limit the output power to not to overheat the - # internal capacitors. (only valid HW version 3.6 or newer) + comment: + 1: Capacitor temperature limit active + 0: Capacitor temperature limit inactive + The inverter can limit the output power to not to overheat the + internal capacitors. (only valid HW version 3.6 or newer) - name: "DC current limit" bit_start: 33 - # 1: DC current limit active - # 0: DC current limit inactive + comment: + 1: DC current limit active + 0: DC current limit inactive - name: "Drive enable limit" bit_start: 34 - # 1: Drive enable limit active - # 0: Drive enable limit inactive - # Indicates whether the drive enable limitation is active or inactive. - # Used for software development purposes. For true indication - # of the drive state please use byte 3, bit 24 of this message. + comment: + 1: Drive enable limit active + 0: Drive enable limit inactive + Indicates whether the drive enable limitation is active or inactive. + Used for software development purposes. For true indication + of the drive state please use byte 3, bit 24 of this message. - name: "IGBT acceleration temperature limit" bit_start: 35 - # 1: IGBT acceleration limit active - # 0: IGBT acceleration limit inactive + comment: + 1: IGBT acceleration limit active + 0: IGBT acceleration limit inactive - name: "IGBT temperature limit" bit_start: 36 - # 1: IGBT temperature limit active - # 0: IGBT temperature limit inactive + comment: + 1: IGBT temperature limit active + 0: IGBT temperature limit inactive - name: "Input voltage limit" bit_start: 37 - # 1: Input voltage limit active - # 0: Input voltage limit inactive + comment: + 1: Input voltage limit active + 0: Input voltage limit inactive - name: "Motor acceleration temperature limit" bit_start: 38 - # 1: Motor acceleration temperature limit active - # 0: Motor acceleration temperature limit inactive + comment: + 1: Motor acceleration temperature limit active + 0: Motor acceleration temperature limit inactive - name: "Motor temperature limit" bit_start: 39 - # 1: Motor temperature limit active - # 0: Motor temperature limit inactive + comment: + 1: Motor temperature limit active + 0: Motor temperature limit inactive - name: "RPM min limit" bit_start: 40 - # 1: RPM min limit active - # 0: RPM min limit inactive + comment: + 1: RPM min limit active + 0: RPM min limit inactive - name: "RPM max limit" bit_start: 41 - # 1: RPM max limit active - # 0: RPM max limit inactive + comment: + 1: RPM max limit active + 0: RPM max limit inactive - name: "Power limit" bit_start: 42 - # 1: Power limit by configuration active - # 0: Power limit by configuration inactive + comment: + 1: Power limit by configuration active + 0: Power limit by configuration inactive - name: "RESERVED" bit_start: 43 - # Set to 0. + comment: Set to 0. - name: "RESERVED" bit_start: 48 - # Filled with FF’s. For future use. + comment: Filled with FF’s. For future use. - name: "CAN Version" bit_start: 56 - # Indicates the CAN map version. For ex: 23 -> 2,3 (V2,3) - + comment: Indicates the CAN map version. For ex: 23 -> 2,3 (V2,3) IMD general: CAN ID: 18FF01F4 Length: 8 @@ -4756,48 +4405,43 @@ Custom CAN ID: bit_start: 24 - name: "Status" bit_start: 32 - # Bit 0: true = Device error active - # Bit 1: true = HV_pos connection failure - # Bit 2: true = HV_neg connection failure - # Bit 3: true = Earth connection failure - # Bit 4: true = Iso Alarm (iso value below threshold error) - # Bit 5: true = Iso Warning (iso value below threshold warning) - # Bit 6: true = Iso Outdated (value „Time elapsed since lst measurement“ > = „measurement timeout“) - # Bit 7: true = Unbalance Alarm (unbalance value below threshold) - # Bit 8: true = Undervoltage Alarm - # Bit 9: true = Unsafe to Start - # Bit 10: true = Earthlift open + comment: + Bit 0: true = Device error active + Bit 1: true = HV_pos connection failure + Bit 2: true = HV_neg connection failure + Bit 3: true = Earth connection failure + Bit 4: true = Iso Alarm (iso value below threshold error) + Bit 5: true = Iso Warning (iso value below threshold warning) + Bit 6: true = Iso Outdated (value „Time elapsed since lst measurement“ > = „measurement timeout“) + Bit 7: true = Unbalance Alarm (unbalance value below threshold) + Bit 8: true = Undervoltage Alarm + Bit 9: true = Unsafe to Start + Bit 10: true = Earthlift open - name: "Activity" bit_start: 48 - name: "RESERVED" bit_start: 56 - # Filled with FF’s - + comment: Filled with FF’s IMD isolation info: CAN ID: 18EFF4FE Length: 0 signals: [] - IMD voltage: CAN ID: 18EFF4FE Length: 0 signals: [] - IMD IT-system: CAN ID: 18EFF4FE Length: 0 signals: [] - IMD request: CAN ID: 18EFF4FE Length: 0 signals: [] - IMD response: CAN ID: 23 Length: 0 signals: [] - Charger Data: CAN ID: 18FF50E5 Length: 8 @@ -4808,22 +4452,21 @@ Custom CAN ID: bit_start: 16 - name: "Hardware Failure" bit_start: 17 - # Bit 0: Hardware Failure: 0-Normal, 1-Error + comment: Bit 0: Hardware Failure: 0-Normal, 1-Error - name: "OverTemp" bit_start: 18 - # Bit 1: OverTemp: 0-Normal, 1-Error + comment: Bit 1: OverTemp: 0-Normal, 1-Error - name: "Input Voltage Error" bit_start: 19 - # Bit 2: Input Voltage: 0-Normal, 1-Wrong input voltage + comment: Bit 2: Input Voltage: 0-Normal, 1-Wrong input voltage - name: "Connection Error" bit_start: 20 - # Bit 3: Starting State: 0-Correct, 1-Wrong polarity or NC + comment: Bit 3: Starting State: 0-Correct, 1-Wrong polarity or NC - name: "Communication State" bit_start: 21 - # Bit 4: Communication State: 0-Normal, 1-Timeout + comment: Bit 4: Communication State: 0-Normal, 1-Timeout - name: "RESERVED" bit_start: 24 - Charger Control: CAN ID: 1806E5F4 Length: 5 @@ -4834,53 +4477,51 @@ Custom CAN ID: bit_start: 16 - name: "Charge Enable" bit_start: 17 - # 1: Start Charging - # 0: Stop Charging - + comment: + 1: Start Charging + 0: Stop Charging EM Measurement: CAN ID: 10d Length: 8 signals: - name: "Current" bit_start: 0 - # TS Current + comment: TS Current - name: "Voltage" bit_start: 32 - # TS Voltage - + comment: TS Voltage EM Status: CAN ID: 40d Length: 8 signals: - name: "Violation" bit_start: 0 - # Violation occured? + comment: Violation occured? - name: "Logging" bit_start: 1 - # Logging enabled? + comment: Logging enabled? - name: "Energy" bit_start: 8 - # Energy used in Wh - + comment: Energy used in Wh EM Temperature: CAN ID: 60d Length: 8 signals: - name: "Mux Signal" bit_start: 0-2 - # n = [0-6] + comment: n = [0-6] - name: "Num Sensors" bit_start: 3-7 - # Number of sensors up to 32 + comment: Number of sensors up to 32 - name: "Min Temp" bit_start: 8 - # Min temp of all sensors + comment: Min temp of all sensors - name: "Max Temp" bit_start: 16 - # Max temp of all sensors + comment: Max temp of all sensors - name: "Temp 5n" bit_start: 24 - # [0,5,10,15,20,25,30] based on n above + comment: [0,5,10,15,20,25,30] based on n above - name: "Temp 5n+1" bit_start: 32 - name: "Temp 5n+2" @@ -4889,28 +4530,26 @@ Custom CAN ID: bit_start: 48 - name: "Temp 5n+4" bit_start: 56 - EM Team Data 1: CAN ID: 30d Length: 8 signals: - name: "Team Signal 1" bit_start: 0 - # Frick if I know + comment: Frick if I know - name: "Team Signal 2" bit_start: 32 - # Frick if I know - + comment: Frick if I know EM Team Data 2: CAN ID: 30e Length: 8 signals: - name: "Team Signal 3" bit_start: 0 - # Frick if I know + comment: Frick if I know - name: "Team Signal 4" bit_start: 32 - # Frick if I know + comment: Frick if I know GR ID: @@ -4919,46 +4558,15 @@ GR ID: Charger: "0x00" IMD: "0x00" Debugger: "0x01" - CCU : "0x2A" + CCU: "0x02" ECU: "0x02" - ACU: "0x03" + BCU: "0x03" TCM: "0x04" Dash Panel: "0x05" - Steering Wheel: "0x06" - GR Inverter 1: "0x08" - GR Inverter 2: "0x09" - GR Inverter 3: "0x0A" - GR Inverter 4: "0x0B" + GR Inverter: "0x08" Charging SDC: "0x0C" Fan Controller 1: "0x0D" Fan Controller 2: "0x0E" Fan Controller 3: "0x0F" - Fan Controller 4: "0x10" - Fan Controller 5: "0x11" - Fan Controller 6: "0x12" - Fan Controller 7: "0x13" - Fan Controller 8: "0x14" - SAM1: "0x15" - SAM2: "0x16" - SAM3: "0x17" - SAM4: "0x18" - SAM5: "0x19" - SAM6: "0x1A" - SAM7: "0x1B" - SAM8: "0x1C" - SAM9: "0x1D" - SAM10: "0x1E" - SAM11: "0x1F" - SAM12: "0x20" - SAM13: "0x21" - SAM14: "0x22" - SAM15: "0x23" - SAM16: "0x24" - SAM17: "0x25" - SAM18: "0x26" - SAM19: "0x27" - SAM20: "0x28" - LV DC-DC: "0x29" - CCU : "0x2A" DGPS: "0x30" ALL: "0xFF" diff --git a/Autogen/CAN/Doc/GRCAN.dbc b/Autogen/CAN/Doc/GRCAN.dbc index 124e25a91..f63b31fcf 100644 --- a/Autogen/CAN/Doc/GRCAN.dbc +++ b/Autogen/CAN/Doc/GRCAN.dbc @@ -4,66 +4,56 @@ NS_ : BS_: -BU_: ACU CCU Charger Charging_SDC DGPS DTI_Inverter Dash_Panel Debugger ECU Energy_Meter Fan_Controller_1 Fan_Controller_2 Fan_Controller_3 Fan_Controller_4 Fan_Controller_5 Fan_Controller_6 Fan_Controller_7 Fan_Controller_8 GR_Inverter_1 GR_Inverter_2 GR_Inverter_3 GR_Inverter_4 IMD LV_DC_DC SAM1 SAM10 SAM11 SAM12 SAM13 SAM14 SAM15 SAM16 SAM17 SAM18 SAM19 SAM2 SAM20 SAM3 SAM4 SAM5 SAM6 SAM7 SAM8 SAM9 Steering_Wheel TCM ALL +BU_: BCU CCU Charger Charging_SDC DGPS DTI_Inverter Dash_Panel Debugger ECU Energy_Meter Fan_Controller_1 Fan_Controller_2 Fan_Controller_3 GR_Inverter IMD TCM ALL -BO_ 2147680257 ACU_Debug_2_0_to_Debugger: 8 ACU +BO_ 2147680257 BCU_Debug_2_0_to_Debugger: 8 BCU SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger -BO_ 2147680769 ACU_Ping_to_Debugger: 4 ACU +BO_ 2147680769 BCU_Ping_to_Debugger: 4 BCU SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger -BO_ 2147680770 ACU_Ping_to_ECU: 4 ACU +BO_ 2147680770 BCU_Ping_to_ECU: 4 BCU SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU -BO_ 2147682050 ACU_ACU_Status_1_to_ECU: 8 ACU +BO_ 2147682050 BCU_BCU_Status_1_to_ECU: 8 BCU SG_ Accumulator_Voltage : 0|16@1+ (0.01,0) [0|655.35] "Volts" ECU SG_ TS_Voltage : 16|16@1+ (0.01,0) [0|655.35] "Volts" ECU SG_ Accumulator_Current : 32|16@1- (0.01,0) [-327.68|327.67] "Amps" ECU SG_ Accumulator_SOC : 48|8@1+ (0.392157,0) [0|100] "%" ECU SG_ GLV_SOC : 56|8@1+ (0.392157,0) [0|100] "%" ECU -BO_ 2147682306 ACU_ACU_Status_2_to_ECU: 7 ACU - SG_ 20v_Voltage : 0|8@1+ (0.1,0) [0|25.5] "Volts" ECU - SG_ 12v_Voltage : 8|8@1+ (0.1,0) [0|25.5] "Volts" ECU - SG_ SDC_Voltage : 16|8@1+ (0.1,0) [0|25.5] "Volts" ECU - SG_ Min_Cell_Voltage : 24|8@1+ (0.01,2) [2|4.55] "Volts" ECU - SG_ Max_Cell_Temp : 32|8@1+ (0.25,0) [0|63.75] "Celsius" ECU - SG_ Over_Temp_Error : 40|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Over_Voltage_Error : 41|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Under_Voltage_Error : 42|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Over_Current_Error : 43|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Under_Current_Error : 44|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Under_Voltage_20v_Warning : 45|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Under_Voltage_12v_Warning : 46|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Under_Voltage_SDC_Warning : 47|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Precharge_Error : 48|1@1+ (1,0) [0|0] "Bool" ECU - SG_ IR__Precharge_State : 49|1@1+ (1,0) [0|0] "Bool" ECU - SG_ IR_State : 50|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Software_Latch : 51|1@1+ (1,0) [0|0] "Bool" ECU - -BO_ 2147682562 ACU_ACU_Status_3_to_ECU: 8 ACU +BO_ 2147682306 BCU_BCU_Status_2_to_ECU: 7 BCU + SG_ 20v_Voltage : 0|8@1+ (1,0) [0|0] "" ECU + SG_ 12v_Voltage : 8|8@1+ (1,0) [0|0] "" ECU + SG_ SDC_Voltage : 16|8@1+ (1,0) [0|0] "" ECU + SG_ Min_Cell_Voltage : 24|8@1+ (1,0) [0|0] "" ECU + SG_ Max_Cell_Temp : 32|8@1+ (1,0) [0|0] "" ECU + SG_ status_flags : 40|1@1+ (1,0) [0|0] "" ECU + SG_ precharge_latch_flags : 48|1@1+ (1,0) [0|0] "" ECU + +BO_ 2147682562 BCU_BCU_Status_3_to_ECU: 8 BCU SG_ HV_Input_Voltage : 0|16@1+ (0.01,0) [0|655.35] "Volts" ECU SG_ HV_Output_Voltage : 16|16@1+ (0.01,0) [0|655.35] "Volts" ECU SG_ HV_Input_Current : 32|16@1+ (0.001,0) [0|65.535] "Amps" ECU SG_ HV_Output_Current : 48|16@1+ (0.001,0) [0|65.535] "Amps" ECU -BO_ 2147684866 ACU_DC_DC_Status_to_ECU: 7 ACU +BO_ 2147684866 BCU_DC_DC_Status_to_ECU: 7 BCU SG_ Input_Voltage : 0|16@1+ (0.001,0) [0|65.535] "Volts" ECU SG_ Output_Voltage : 16|16@1+ (0.001,0) [0|65.535] "Volts" ECU SG_ Input_Current : 32|8@1+ (0.1,0) [0|25.5] "Amps" ECU SG_ Output_Current : 40|8@1+ (0.1,0) [0|25.5] "Amps" ECU SG_ DC_DC_Temp : 48|8@1+ (1,0) [0|255] "Celsius" ECU -BO_ 2147680513 ACU_Debug_FD_to_Debugger: 64 ACU +BO_ 2147680513 BCU_Debug_FD_to_Debugger: 64 BCU SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger -BO_ 2147680769 ACU_Ping_to_Debugger: 4 ACU +BO_ 2147680769 BCU_Ping_to_Debugger: 4 BCU SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger -BO_ 2147680770 ACU_Ping_to_ECU: 4 ACU +BO_ 2147680770 BCU_Ping_to_ECU: 4 BCU SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU -BO_ 2147683586 ACU_ACU_Cell_Data_1_to_ECU: 64 ACU +BO_ 2147683586 BCU_BCU_Cell_Data_1_to_ECU: 64 BCU SG_ Cell_0_Voltage : 0|8@1+ (0.01,2) [2|4.55] "Volts" ECU SG_ Cell_0_Temp : 8|8@1+ (0.25,0) [0|63.75] "Celsius" ECU SG_ Cell_1_Voltage : 16|8@1+ (0.01,2) [2|4.55] "Volts" ECU @@ -129,7 +119,7 @@ BO_ 2147683586 ACU_ACU_Cell_Data_1_to_ECU: 64 ACU SG_ Cell_31_Voltage : 496|8@1+ (0.01,2) [2|4.55] "Volts" ECU SG_ Cell_31_Temp : 504|8@1+ (0.25,0) [0|63.75] "Celsius" ECU -BO_ 2147683842 ACU_ACU_Cell_Data_2_to_ECU: 64 ACU +BO_ 2147683842 BCU_BCU_Cell_Data_2_to_ECU: 64 BCU SG_ Cell_32_Voltage : 0|8@1+ (0.01,2) [2|4.55] "Volts" ECU SG_ Cell_32_Temp : 8|8@1+ (0.25,0) [0|63.75] "Celsius" ECU SG_ Cell_33_Voltage : 16|8@1+ (0.01,2) [2|4.55] "Volts" ECU @@ -195,7 +185,7 @@ BO_ 2147683842 ACU_ACU_Cell_Data_2_to_ECU: 64 ACU SG_ Cell_63_Voltage : 496|8@1+ (0.01,2) [2|4.55] "Volts" ECU SG_ Cell_63_Temp : 504|8@1+ (0.25,0) [0|63.75] "Celsius" ECU -BO_ 2147684098 ACU_ACU_Cell_Data_3_to_ECU: 64 ACU +BO_ 2147684098 BCU_BCU_Cell_Data_3_to_ECU: 64 BCU SG_ Cell_64_Voltage : 0|8@1+ (0.01,2) [2|4.55] "Volts" ECU SG_ Cell_64_Temp : 8|8@1+ (0.25,0) [0|63.75] "Celsius" ECU SG_ Cell_65_Voltage : 16|8@1+ (0.01,2) [2|4.55] "Volts" ECU @@ -261,7 +251,7 @@ BO_ 2147684098 ACU_ACU_Cell_Data_3_to_ECU: 64 ACU SG_ Cell_95_Voltage : 496|8@1+ (0.01,2) [2|4.55] "Volts" ECU SG_ Cell_95_Temp : 504|8@1+ (0.25,0) [0|63.75] "Celsius" ECU -BO_ 2147684354 ACU_ACU_Cell_Data_4_to_ECU: 64 ACU +BO_ 2147684354 BCU_BCU_Cell_Data_4_to_ECU: 64 BCU SG_ Cell_96_Voltage : 0|8@1+ (0.01,2) [2|4.55] "Volts" ECU SG_ Cell_96_Temp : 8|8@1+ (0.25,0) [0|63.75] "Celsius" ECU SG_ Cell_97_Voltage : 16|8@1+ (0.01,2) [2|4.55] "Volts" ECU @@ -327,7 +317,7 @@ BO_ 2147684354 ACU_ACU_Cell_Data_4_to_ECU: 64 ACU SG_ Cell_127_Voltage : 496|8@1+ (0.01,2) [2|4.55] "Volts" ECU SG_ Cell_127_Temp : 504|8@1+ (0.25,0) [0|63.75] "Celsius" ECU -BO_ 2147684610 ACU_ACU_Cell_Data_5_to_ECU: 64 ACU +BO_ 2147684610 BCU_BCU_Cell_Data_5_to_ECU: 64 BCU SG_ Cell_128_Voltage : 0|8@1+ (0.01,2) [2|4.55] "Volts" ECU SG_ Cell_128_Temp : 8|8@1+ (0.25,0) [0|63.75] "Celsius" ECU SG_ Cell_129_Voltage : 16|8@1+ (0.01,2) [2|4.55] "Volts" ECU @@ -393,19 +383,19 @@ BO_ 2147684610 ACU_ACU_Cell_Data_5_to_ECU: 64 ACU SG_ Cell_159_Voltage : 496|8@1+ (0.01,2) [2|4.55] "Volts" ECU SG_ Cell_159_Temp : 504|8@1+ (0.25,0) [0|63.75] "Celsius" ECU -BO_ 2550588916 ACU_Charger_Control_to_Charger: 5 ACU +BO_ 2550588916 BCU_Charger_Control_to_Charger: 5 BCU SG_ Set_Voltage : 0|8@1+ (1,0) [0|0] "" Charger SG_ Set_Current : 16|8@1+ (1,0) [0|0] "" Charger SG_ Charge_Enable : 17|8@1+ (1,0) [0|0] "" Charger -BO_ 2566869221 Charger_Charger_Data_to_ACU: 8 Charger - SG_ Output_Voltage : 0|8@1+ (1,0) [0|0] "" ACU - SG_ Output_Current : 16|8@1+ (1,0) [0|0] "" ACU - SG_ Hardware_Failure : 17|8@1+ (1,0) [0|0] "" ACU - SG_ OverTemp : 18|8@1+ (1,0) [0|0] "" ACU - SG_ Input_Voltage_Error : 19|8@1+ (1,0) [0|0] "" ACU - SG_ Connection_Error : 20|8@1+ (1,0) [0|0] "" ACU - SG_ Communication_State : 21|8@1+ (1,0) [0|0] "" ACU +BO_ 2566869221 Charger_Charger_Data_to_BCU: 8 Charger + SG_ Output_Voltage : 0|8@1+ (1,0) [0|0] "" BCU + SG_ Output_Current : 16|8@1+ (1,0) [0|0] "" BCU + SG_ Hardware_Failure : 17|8@1+ (1,0) [0|0] "" BCU + SG_ OverTemp : 18|8@1+ (1,0) [0|0] "" BCU + SG_ Input_Voltage_Error : 19|8@1+ (1,0) [0|0] "" BCU + SG_ Connection_Error : 20|8@1+ (1,0) [0|0] "" BCU + SG_ Communication_State : 21|8@1+ (1,0) [0|0] "" BCU BO_ 2147811329 Dash_Panel_Debug_2_0_to_Debugger: 8 Dash_Panel SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger @@ -417,11 +407,8 @@ BO_ 2147811842 Dash_Panel_Ping_to_ECU: 4 Dash_Panel SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU BO_ 2147817986 Dash_Panel_Dash_Status_to_ECU: 3 Dash_Panel - SG_ BMS_LED : 0|1@1+ (1,0) [0|0] "Bool" ECU - SG_ IMD_LED : 1|1@1+ (1,0) [0|0] "Bool" ECU - SG_ BSPD_LED : 2|1@1+ (1,0) [0|0] "Bool" ECU - SG_ TS_Button_Data : 8|8@1- (0.1,0) [0|12.7] "Seconds" ECU - SG_ RTD_Button_Data : 16|8@1- (0.1,0) [0|12.7] "Seconds" ECU + SG_ button_flags : 0|8@1+ (1,0) [0|0] "" ECU + SG_ led_bits : 8|8@1+ (1,0) [0|0] "" ECU BO_ 2147549186 Debugger_Debug_2_0_to_ECU: 8 Debugger SG_ Debug : 0|64@1- (1,0) [0|0] "" ECU @@ -431,11 +418,11 @@ BO_ 2147549698 Debugger_Ping_to_ECU: 4 Debugger BO_ 2147550722 Debugger_ECU_config_to_ECU: 0 Debugger -BO_ 2147549187 Debugger_Debug_2_0_to_ACU: 8 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" ACU +BO_ 2147549187 Debugger_Debug_2_0_to_BCU: 8 Debugger + SG_ Debug : 0|64@1- (1,0) [0|0] "" BCU -BO_ 2147549699 Debugger_Ping_to_ACU: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ACU +BO_ 2147549699 Debugger_Ping_to_BCU: 4 Debugger + SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" BCU BO_ 2147549188 Debugger_Debug_2_0_to_TCM: 8 Debugger SG_ Debug : 0|64@1- (1,0) [0|0] "" TCM @@ -449,29 +436,11 @@ BO_ 2147549189 Debugger_Debug_2_0_to_Dash_Panel: 8 Debugger BO_ 2147549701 Debugger_Ping_to_Dash_Panel: 4 Debugger SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Dash_Panel -BO_ 2147549192 Debugger_Debug_2_0_to_GR_Inverter_1: 8 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" GR_Inverter_1 - -BO_ 2147549704 Debugger_Ping_to_GR_Inverter_1: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" GR_Inverter_1 - -BO_ 2147549193 Debugger_Debug_2_0_to_GR_Inverter_2: 8 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" GR_Inverter_2 - -BO_ 2147549705 Debugger_Ping_to_GR_Inverter_2: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" GR_Inverter_2 - -BO_ 2147549194 Debugger_Debug_2_0_to_GR_Inverter_3: 8 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" GR_Inverter_3 +BO_ 2147549192 Debugger_Debug_2_0_to_GR_Inverter: 8 Debugger + SG_ Debug : 0|64@1- (1,0) [0|0] "" GR_Inverter -BO_ 2147549706 Debugger_Ping_to_GR_Inverter_3: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" GR_Inverter_3 - -BO_ 2147549195 Debugger_Debug_2_0_to_GR_Inverter_4: 8 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" GR_Inverter_4 - -BO_ 2147549707 Debugger_Ping_to_GR_Inverter_4: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" GR_Inverter_4 +BO_ 2147549704 Debugger_Ping_to_GR_Inverter: 4 Debugger + SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" GR_Inverter BO_ 2147549197 Debugger_Debug_2_0_to_Fan_Controller_1: 8 Debugger SG_ Debug : 0|64@1- (1,0) [0|0] "" Fan_Controller_1 @@ -491,56 +460,17 @@ BO_ 2147549199 Debugger_Debug_2_0_to_Fan_Controller_3: 8 Debugger BO_ 2147549711 Debugger_Ping_to_Fan_Controller_3: 4 Debugger SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Fan_Controller_3 -BO_ 2147549200 Debugger_Debug_2_0_to_Fan_Controller_4: 8 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" Fan_Controller_4 - -BO_ 2147549712 Debugger_Ping_to_Fan_Controller_4: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Fan_Controller_4 - -BO_ 2147549201 Debugger_Debug_2_0_to_Fan_Controller_5: 8 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" Fan_Controller_5 - -BO_ 2147549713 Debugger_Ping_to_Fan_Controller_5: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Fan_Controller_5 - -BO_ 2147549202 Debugger_Debug_2_0_to_Fan_Controller_6: 8 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" Fan_Controller_6 - -BO_ 2147549714 Debugger_Ping_to_Fan_Controller_6: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Fan_Controller_6 - -BO_ 2147549203 Debugger_Debug_2_0_to_Fan_Controller_7: 8 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" Fan_Controller_7 - -BO_ 2147549715 Debugger_Ping_to_Fan_Controller_7: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Fan_Controller_7 - -BO_ 2147549204 Debugger_Debug_2_0_to_Fan_Controller_8: 8 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" Fan_Controller_8 - -BO_ 2147549716 Debugger_Ping_to_Fan_Controller_8: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Fan_Controller_8 - -BO_ 2147549225 Debugger_Debug_2_0_to_LV_DC_DC: 8 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" LV_DC_DC - -BO_ 2147549737 Debugger_Ping_to_LV_DC_DC: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" LV_DC_DC - -BO_ 2147549737 Debugger_Ping_to_LV_DC_DC: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" LV_DC_DC - BO_ 2147549442 Debugger_Debug_FD_to_ECU: 64 Debugger SG_ Debug : 0|64@1- (1,0) [0|0] "" ECU BO_ 2147549698 Debugger_Ping_to_ECU: 4 Debugger SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU -BO_ 2147549443 Debugger_Debug_FD_to_ACU: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" ACU +BO_ 2147549443 Debugger_Debug_FD_to_BCU: 64 Debugger + SG_ Debug : 0|64@1- (1,0) [0|0] "" BCU -BO_ 2147549699 Debugger_Ping_to_ACU: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ACU +BO_ 2147549699 Debugger_Ping_to_BCU: 4 Debugger + SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" BCU BO_ 2147549444 Debugger_Debug_FD_to_TCM: 64 Debugger SG_ Debug : 0|64@1- (1,0) [0|0] "" TCM @@ -548,132 +478,6 @@ BO_ 2147549444 Debugger_Debug_FD_to_TCM: 64 Debugger BO_ 2147549700 Debugger_Ping_to_TCM: 4 Debugger SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" TCM -BO_ 2147549446 Debugger_Debug_FD_to_Steering_Wheel: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" Steering_Wheel - -BO_ 2147549702 Debugger_Ping_to_Steering_Wheel: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Steering_Wheel - -BO_ 2147549461 Debugger_Debug_FD_to_SAM1: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM1 - -BO_ 2147549717 Debugger_Ping_to_SAM1: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM1 - -BO_ 2147549462 Debugger_Debug_FD_to_SAM2: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM2 - -BO_ 2147549718 Debugger_Ping_to_SAM2: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM2 - -BO_ 2147549463 Debugger_Debug_FD_to_SAM3: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM3 - -BO_ 2147549719 Debugger_Ping_to_SAM3: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM3 - -BO_ 2147549464 Debugger_Debug_FD_to_SAM4: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM4 - -BO_ 2147549720 Debugger_Ping_to_SAM4: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM4 - -BO_ 2147549465 Debugger_Debug_FD_to_SAM5: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM5 - -BO_ 2147549721 Debugger_Ping_to_SAM5: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM5 - -BO_ 2147549466 Debugger_Debug_FD_to_SAM6: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM6 - -BO_ 2147549722 Debugger_Ping_to_SAM6: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM6 - -BO_ 2147549467 Debugger_Debug_FD_to_SAM7: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM7 - -BO_ 2147549723 Debugger_Ping_to_SAM7: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM7 - -BO_ 2147549468 Debugger_Debug_FD_to_SAM8: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM8 - -BO_ 2147549724 Debugger_Ping_to_SAM8: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM8 - -BO_ 2147549469 Debugger_Debug_FD_to_SAM9: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM9 - -BO_ 2147549725 Debugger_Ping_to_SAM9: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM9 - -BO_ 2147549470 Debugger_Debug_FD_to_SAM10: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM10 - -BO_ 2147549726 Debugger_Ping_to_SAM10: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM10 - -BO_ 2147549471 Debugger_Debug_FD_to_SAM11: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM11 - -BO_ 2147549727 Debugger_Ping_to_SAM11: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM11 - -BO_ 2147549472 Debugger_Debug_FD_to_SAM12: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM12 - -BO_ 2147549728 Debugger_Ping_to_SAM12: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM12 - -BO_ 2147549473 Debugger_Debug_FD_to_SAM13: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM13 - -BO_ 2147549729 Debugger_Ping_to_SAM13: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM13 - -BO_ 2147549474 Debugger_Debug_FD_to_SAM14: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM14 - -BO_ 2147549730 Debugger_Ping_to_SAM14: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM14 - -BO_ 2147549475 Debugger_Debug_FD_to_SAM15: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM15 - -BO_ 2147549731 Debugger_Ping_to_SAM15: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM15 - -BO_ 2147549476 Debugger_Debug_FD_to_SAM16: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM16 - -BO_ 2147549732 Debugger_Ping_to_SAM16: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM16 - -BO_ 2147549477 Debugger_Debug_FD_to_SAM17: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM17 - -BO_ 2147549733 Debugger_Ping_to_SAM17: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM17 - -BO_ 2147549478 Debugger_Debug_FD_to_SAM18: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM18 - -BO_ 2147549734 Debugger_Ping_to_SAM18: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM18 - -BO_ 2147549479 Debugger_Debug_FD_to_SAM19: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM19 - -BO_ 2147549735 Debugger_Ping_to_SAM19: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM19 - -BO_ 2147549480 Debugger_Debug_FD_to_SAM20: 64 Debugger - SG_ Debug : 0|64@1- (1,0) [0|0] "" SAM20 - -BO_ 2147549736 Debugger_Ping_to_SAM20: 4 Debugger - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" SAM20 - BO_ 2147549708 Debugger_Ping_to_Charging_SDC: 4 Debugger SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Charging_SDC @@ -765,140 +569,83 @@ BO_ 2147614721 ECU_Debug_2_0_to_Debugger: 8 ECU BO_ 2147615233 ECU_Ping_to_Debugger: 4 ECU SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger -BO_ 2147615234 ECU_Ping_to_ECU: 4 ECU - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU +BO_ 2147617283 ECU_BCU_Precharge_to_BCU: 1 ECU + SG_ Set_TS_Active : 0|1@1+ (1,0) [0|0] "Bool" BCU + +BO_ 2147617539 ECU_BCU_Config_Charge_Parameters_to_BCU: 4 ECU + SG_ Charge_Voltage : 0|16@1+ (0.1,0) [0|6553.5] "Volts" BCU + SG_ Charge_Current : 16|16@1+ (0.1,0) [0|6553.5] "Amps" BCU + +BO_ 2147617795 ECU_BCU_Config_Operational_Parameters_to_BCU: 2 ECU + SG_ Minimium_Cell_Voltage : 0|8@1+ (0.01,2) [2|4.55] "Volts" BCU + SG_ Max_Cell_Temperature : 8|8@1+ (0.25,0) [0|63.75] "Celsius" BCU -BO_ 2147615490 ECU_ECU_Status_1_to_ECU: 8 ECU - SG_ ECU_State : 0|8@1+ (1,0) [0|0] "" ECU - SG_ ACU_Node_Status : 8|1@1+ (1,0) [0|0] "Bool" ECU - SG_ GR_Inv_1_Status : 9|1@1+ (1,0) [0|0] "Bool" ECU - SG_ GR_Inv_2_Status : 10|1@1+ (1,0) [0|0] "Bool" ECU - SG_ GR_Inv_3_Status : 11|1@1+ (1,0) [0|0] "Bool" ECU - SG_ GR_Inv_4_Status : 12|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Fan_Controller_1 : 13|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Fan_Controller_2 : 14|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Fan_Controller_3 : 15|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Fan_Controller_4 : 16|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Fan_Controller_5 : 17|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Fan_Controller_6 : 18|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Fan_Controller_7 : 19|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Fan_Controller_8 : 20|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Dash : 21|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Steering : 22|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Power_Level : 32|4@1+ (1,0) [0|0] "" ECU - SG_ Torque_Map : 36|4@1+ (1,0) [0|0] "" ECU - SG_ Max_Cell_Temp : 40|8@1+ (0.25,0) [0|63.75] "Celsius" ECU - SG_ Accumulator_State_of_Charge : 48|8@1+ (0.392157,0) [0|100] "%" ECU - SG_ GLV_State_of_Charge : 56|8@1+ (0.392157,0) [0|100] "%" ECU - -BO_ 2147615746 ECU_ECU_Status_2_to_ECU: 8 ECU - SG_ Tractive_System_Voltage : 0|16@1+ (0.01,0) [0|655.35] "Volts" ECU - SG_ Vehicle_Speed : 16|16@1+ (0.01,0) [0|655.35] "MPH" ECU - SG_ FR_Wheel_RPM : 32|16@1+ (0.1,-3276.8) [-3276.8|3276.7] "RPM" ECU - SG_ FL_Wheel_RPM : 48|16@1+ (0.1,-3276.8) [-3276.8|3276.7] "RPM" ECU - -BO_ 2147616002 ECU_ECU_Status_3_to_ECU: 4 ECU - SG_ RR_Wheel_RPM : 0|16@1+ (0.1,-3276.8) [-3276.8|3276.7] "RPM" ECU - SG_ RL_Wheel_RPM : 16|16@1+ (0.1,-3276.8) [-3276.8|3276.7] "RPM" ECU - -BO_ 2147617283 ECU_ACU_Precharge_to_ACU: 1 ECU - SG_ Set_TS_Active : 0|1@1+ (1,0) [0|0] "Bool" ACU - -BO_ 2147617539 ECU_ACU_Config_Charge_Parameters_to_ACU: 4 ECU - SG_ Charge_Voltage : 0|16@1+ (0.1,0) [0|6553.5] "Volts" ACU - SG_ Charge_Current : 16|16@1+ (0.1,0) [0|6553.5] "Amps" ACU - -BO_ 2147617795 ECU_ACU_Config_Operational_Parameters_to_ACU: 2 ECU - SG_ Minimium_Cell_Voltage : 0|8@1+ (0.01,2) [2|4.55] "Volts" ACU - SG_ Max_Cell_Temperature : 8|8@1+ (0.25,0) [0|63.75] "Celsius" ACU - -BO_ 2147620360 ECU_Inverter_Config_to_GR_Inverter_1: 7 ECU - SG_ Max_AC_Current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_1 - SG_ Max_DC_Current : 16|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_1 - SG_ Absolute_Max_RPM_Limit : 32|16@1+ (1,-32768) [-32768|32767] "RPM" GR_Inverter_1 - SG_ Motor_direction : 48|1@1+ (1,0) ["-"|"-"] "Enable" GR_Inverter_1 - -BO_ 2147620616 ECU_Inverter_Command_to_GR_Inverter_1: 8 ECU - SG_ Set_AC_Current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_1 - SG_ Set_DC_Current : 16|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_1 - SG_ RPM_Limit : 32|16@1+ (1,-32768) [-32768|32767] "RPM" GR_Inverter_1 - SG_ Field_weakening : 48|8@1+ (0.1,0) [0|25.5] "Amps" GR_Inverter_1 - SG_ Drive_enable : 56|1@1+ (1,0) ["-"|"-"] "Enable" GR_Inverter_1 - -BO_ 2147620361 ECU_Inverter_Config_to_GR_Inverter_2: 7 ECU - SG_ Max_AC_Current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_2 - SG_ Max_DC_Current : 16|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_2 - SG_ Absolute_Max_RPM_Limit : 32|16@1+ (1,-32768) [-32768|32767] "RPM" GR_Inverter_2 - SG_ Motor_direction : 48|1@1+ (1,0) ["-"|"-"] "Enable" GR_Inverter_2 - -BO_ 2147620617 ECU_Inverter_Command_to_GR_Inverter_2: 8 ECU - SG_ Set_AC_Current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_2 - SG_ Set_DC_Current : 16|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_2 - SG_ RPM_Limit : 32|16@1+ (1,-32768) [-32768|32767] "RPM" GR_Inverter_2 - SG_ Field_weakening : 48|8@1+ (0.1,0) [0|25.5] "Amps" GR_Inverter_2 - SG_ Drive_enable : 56|1@1+ (1,0) ["-"|"-"] "Enable" GR_Inverter_2 - -BO_ 2147620362 ECU_Inverter_Config_to_GR_Inverter_3: 7 ECU - SG_ Max_AC_Current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_3 - SG_ Max_DC_Current : 16|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_3 - SG_ Absolute_Max_RPM_Limit : 32|16@1+ (1,-32768) [-32768|32767] "RPM" GR_Inverter_3 - SG_ Motor_direction : 48|1@1+ (1,0) ["-"|"-"] "Enable" GR_Inverter_3 - -BO_ 2147620618 ECU_Inverter_Command_to_GR_Inverter_3: 8 ECU - SG_ Set_AC_Current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_3 - SG_ Set_DC_Current : 16|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_3 - SG_ RPM_Limit : 32|16@1+ (1,-32768) [-32768|32767] "RPM" GR_Inverter_3 - SG_ Field_weakening : 48|8@1+ (0.1,0) [0|25.5] "Amps" GR_Inverter_3 - SG_ Drive_enable : 56|1@1+ (1,0) ["-"|"-"] "Enable" GR_Inverter_3 - -BO_ 2147620363 ECU_Inverter_Config_to_GR_Inverter_4: 7 ECU - SG_ Max_AC_Current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_4 - SG_ Max_DC_Current : 16|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_4 - SG_ Absolute_Max_RPM_Limit : 32|16@1+ (1,-32768) [-32768|32767] "RPM" GR_Inverter_4 - SG_ Motor_direction : 48|1@1+ (1,0) ["-"|"-"] "Enable" GR_Inverter_4 - -BO_ 2147620619 ECU_Inverter_Command_to_GR_Inverter_4: 8 ECU - SG_ Set_AC_Current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_4 - SG_ Set_DC_Current : 16|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter_4 - SG_ RPM_Limit : 32|16@1+ (1,-32768) [-32768|32767] "RPM" GR_Inverter_4 - SG_ Field_weakening : 48|8@1+ (0.1,0) [0|25.5] "Amps" GR_Inverter_4 - SG_ Drive_enable : 56|1@1+ (1,0) ["-"|"-"] "Enable" GR_Inverter_4 +BO_ 2147615235 ECU_Ping_to_BCU: 4 ECU + SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" BCU + +BO_ 2147620360 ECU_Inverter_Config_to_GR_Inverter: 7 ECU + SG_ Max_AC_Current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter + SG_ Max_DC_Current : 16|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter + SG_ Absolute_Max_RPM_Limit : 32|16@1+ (1,-32768) [-32768|32767] "RPM" GR_Inverter + SG_ Motor_direction : 48|1@1+ (1,0) ["-"|"-"] "Enable" GR_Inverter + +BO_ 2147620616 ECU_Inverter_Command_to_GR_Inverter: 8 ECU + SG_ Set_AC_Current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter + SG_ Set_DC_Current : 16|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" GR_Inverter + SG_ RPM_Limit : 32|16@1+ (1,-32768) [-32768|32767] "RPM" GR_Inverter + SG_ Field_weakening : 48|8@1+ (0.1,0) [0|25.5] "Amps" GR_Inverter + SG_ Drive_enable : 56|1@1+ (1,0) ["-"|"-"] "Enable" GR_Inverter + +BO_ 2147615240 ECU_Ping_to_GR_Inverter: 4 ECU + SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" GR_Inverter BO_ 2147621133 ECU_Fan_Command_to_Fan_Controller_1: 1 ECU SG_ Fan_Command : 0|8@1+ (1,0) [0|255] "%" Fan_Controller_1 +BO_ 2147615245 ECU_Ping_to_Fan_Controller_1: 4 ECU + SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Fan_Controller_1 + BO_ 2147621134 ECU_Fan_Command_to_Fan_Controller_2: 1 ECU SG_ Fan_Command : 0|8@1+ (1,0) [0|255] "%" Fan_Controller_2 +BO_ 2147615246 ECU_Ping_to_Fan_Controller_2: 4 ECU + SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Fan_Controller_2 + BO_ 2147621135 ECU_Fan_Command_to_Fan_Controller_3: 1 ECU SG_ Fan_Command : 0|8@1+ (1,0) [0|255] "%" Fan_Controller_3 -BO_ 2147621136 ECU_Fan_Command_to_Fan_Controller_4: 1 ECU - SG_ Fan_Command : 0|8@1+ (1,0) [0|255] "%" Fan_Controller_4 - -BO_ 2147621137 ECU_Fan_Command_to_Fan_Controller_5: 1 ECU - SG_ Fan_Command : 0|8@1+ (1,0) [0|255] "%" Fan_Controller_5 - -BO_ 2147621138 ECU_Fan_Command_to_Fan_Controller_6: 1 ECU - SG_ Fan_Command : 0|8@1+ (1,0) [0|255] "%" Fan_Controller_6 - -BO_ 2147621139 ECU_Fan_Command_to_Fan_Controller_7: 1 ECU - SG_ Fan_Command : 0|8@1+ (1,0) [0|255] "%" Fan_Controller_7 - -BO_ 2147621140 ECU_Fan_Command_to_Fan_Controller_8: 1 ECU - SG_ Fan_Command : 0|8@1+ (1,0) [0|255] "%" Fan_Controller_8 +BO_ 2147615247 ECU_Ping_to_Fan_Controller_3: 4 ECU + SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Fan_Controller_3 BO_ 2147621637 ECU_Dash_Config_to_Dash_Panel: 1 ECU SG_ BMS_LED : 0|1@1+ (1,0) [0|0] "Bool" Dash_Panel SG_ IMD_LED : 1|1@1+ (1,0) [0|0] "Bool" Dash_Panel SG_ BSPD_LED : 2|1@1+ (1,0) [0|0] "Bool" Dash_Panel -BO_ 2147625733 ECU_Dash_Warning_Flags_to_Dash_Panel: 1 ECU - SG_ BSE_APPS_Violation : 0|1@1+ (1,0) [0|0] "Bool" Dash_Panel +BO_ 2147615237 ECU_Ping_to_Dash_Panel: 4 ECU + SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Dash_Panel -BO_ 2147625989 ECU_Specific_Brake_IR_to_Dash_Panel: 2 ECU - SG_ Wheel_identifier : 0|8@1+ (1,0) [0|0] "" Dash_Panel - SG_ Temp : 8|8@1+ (1,0) [0|255] "Celsius" Dash_Panel +BO_ 2147615743 ECU_ECU_Status_1_to_ALL: 8 ECU + SG_ state_messages : 0|1@1+ (1,0) [0|0] "Bool" ALL + SG_ status_flags : 8|1@1+ (1,0) [0|0] "" ALL + SG_ Power_Level : 16|4@1+ (1,0) [0|0] "" ALL + SG_ Torque_Map : 20|4@1+ (1,0) [0|0] "" ALL + SG_ Max_Cell_Temp : 24|8@1+ (0.25,0) [0|63.75] "Celsius" ALL + SG_ Accumulator_State_of_Charge : 32|8@1+ (0.392157,0) [0|100] "%" ALL + SG_ GLV_State_of_Charge : 40|8@1+ (0.392157,0) [0|100] "%" ALL + SG_ Tractive_System_Voltage : 48|16@1+ (0.01,0) [0|655.35] "Volts" ALL + +BO_ 2147615999 ECU_ECU_Status_2_to_ALL: 8 ECU + SG_ Vehicle_Speed : 0|16@1+ (0.01,0) [0|655.35] "MPH" ALL + SG_ FR_Wheel_RPM : 16|16@1+ (0.1,-3276.8) [-3276.8|3276.7] "RPM" ALL + SG_ FL_Wheel_RPM : 32|16@1+ (0.1,-3276.8) [-3276.8|3276.7] "RPM" ALL + SG_ RR_Wheel_RPM : 48|16@1+ (0.1,-3276.8) [-3276.8|3276.7] "RPM" ALL + +BO_ 2147616255 ECU_ECU_Status_3_to_ALL: 2 ECU + SG_ RL_Wheel_RPM : 0|16@1+ (0.1,-3276.8) [-3276.8|3276.7] "RPM" ALL + +BO_ 2147615236 ECU_Ping_to_TCM: 4 ECU + SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" TCM BO_ 2147614977 ECU_Debug_FD_to_Debugger: 64 ECU SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger @@ -906,48 +653,43 @@ BO_ 2147614977 ECU_Debug_FD_to_Debugger: 64 ECU BO_ 2147615233 ECU_Ping_to_Debugger: 4 ECU SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger -BO_ 2147615234 ECU_Ping_to_ECU: 4 ECU - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU - -BO_ 2147622150 ECU_Steering_Config_to_Steering_Wheel: 0 ECU - -BO_ 2147626246 ECU_ECU_Ping_Information_to_Steering_Wheel: 3 ECU - SG_ Online_pings : 0|24@1+ (1,0) [0|0] "Bool map" Steering_Wheel - -BO_ 2181169152 ECU_ECU_Pedals_Data_to_TCM: 10 ECU - SG_ APPS1_SIGNAL : 0|16@1+ (0.0015259,0) [0|100] "%" TCM - SG_ APPS2_SIGNAL : 16|16@1+ (0.0015259,0) [0|100] "%" TCM - SG_ BSE_SIGNAL : 32|16@1+ (0.0015259,0) [0|100] "%" TCM - SG_ BRAKE_F_SIGNAL : 48|16@1+ (0.0015259,0) [0|100] "%" TCM - SG_ BRAKE_R_SIGNAL : 48|16@1+ (0.0015259,0) [0|100] "%" TCM - -BO_ 269 Energy_Meter_EM_Measurement_to_ACU: 8 Energy_Meter - SG_ Current : 0|8@1+ (1,0) [0|0] "" ACU - SG_ Voltage : 32|8@1+ (1,0) [0|0] "" ACU - -BO_ 781 Energy_Meter_EM_Team_Data_1_to_ACU: 8 Energy_Meter - SG_ Team_Signal_1 : 0|8@1+ (1,0) [0|0] "" ACU - SG_ Team_Signal_2 : 32|8@1+ (1,0) [0|0] "" ACU - -BO_ 782 Energy_Meter_EM_Team_Data_2_to_ACU: 8 Energy_Meter - SG_ Team_Signal_3 : 0|8@1+ (1,0) [0|0] "" ACU - SG_ Team_Signal_4 : 32|8@1+ (1,0) [0|0] "" ACU - -BO_ 1037 Energy_Meter_EM_Status_to_ACU: 8 Energy_Meter - SG_ Violation : 0|8@1+ (1,0) [0|0] "" ACU - SG_ Logging : 1|8@1+ (1,0) [0|0] "" ACU - SG_ Energy : 8|8@1+ (1,0) [0|0] "" ACU - -BO_ 1549 Energy_Meter_EM_Temperature_to_ACU: 8 Energy_Meter - SG_ Mux_Signal : 0|8@1+ (1,0) [0|0] "" ACU - SG_ Num_Sensors : 3|8@1+ (1,0) [0|0] "" ACU - SG_ Min_Temp : 8|8@1+ (1,0) [0|0] "" ACU - SG_ Max_Temp : 16|8@1+ (1,0) [0|0] "" ACU - SG_ Temp_5n : 24|8@1+ (1,0) [0|0] "" ACU - SG_ Temp_5n1 : 32|8@1+ (1,0) [0|0] "" ACU - SG_ Temp_5n2 : 40|8@1+ (1,0) [0|0] "" ACU - SG_ Temp_5n3 : 48|8@1+ (1,0) [0|0] "" ACU - SG_ Temp_5n4 : 56|8@1+ (1,0) [0|0] "" ACU +BO_ 2147626500 ECU_ECU_Pedals_Data_to_TCM: 16 ECU + SG_ BSPD_Signal : 0|16@1+ (0.0015259,0) [0|100] "%" TCM + SG_ BSE_Signal : 16|16@1+ (0.0015259,0) [0|100] "%" TCM + SG_ APPS_1_Signal : 32|16@1+ (0.0015259,0) [0|100] "%" TCM + SG_ APPS_2_Signal : 48|16@1+ (0.0015259,0) [0|100] "%" TCM + SG_ Brakeline_F_Signal : 64|16@1+ (0.0015259,0) [0|100] "%" TCM + SG_ Brakeline_R_Signal : 80|16@1+ (0.0015259,0) [0|100] "%" TCM + SG_ Steering_Angle_Signal : 96|16@1+ (0.0015259,0) [0|100] "%" TCM + SG_ AUX_Signal : 112|16@1+ (0.0015259,0) [0|100] "%" TCM + +BO_ 269 Energy_Meter_EM_Measurement_to_BCU: 8 Energy_Meter + SG_ Current : 0|8@1+ (1,0) [0|0] "" BCU + SG_ Voltage : 32|8@1+ (1,0) [0|0] "" BCU + +BO_ 781 Energy_Meter_EM_Team_Data_1_to_BCU: 8 Energy_Meter + SG_ Team_Signal_1 : 0|8@1+ (1,0) [0|0] "" BCU + SG_ Team_Signal_2 : 32|8@1+ (1,0) [0|0] "" BCU + +BO_ 782 Energy_Meter_EM_Team_Data_2_to_BCU: 8 Energy_Meter + SG_ Team_Signal_3 : 0|8@1+ (1,0) [0|0] "" BCU + SG_ Team_Signal_4 : 32|8@1+ (1,0) [0|0] "" BCU + +BO_ 1037 Energy_Meter_EM_Status_to_BCU: 8 Energy_Meter + SG_ Violation : 0|8@1+ (1,0) [0|0] "" BCU + SG_ Logging : 1|8@1+ (1,0) [0|0] "" BCU + SG_ Energy : 8|8@1+ (1,0) [0|0] "" BCU + +BO_ 1549 Energy_Meter_EM_Temperature_to_BCU: 8 Energy_Meter + SG_ Mux_Signal : 0|8@1+ (1,0) [0|0] "" BCU + SG_ Num_Sensors : 3|8@1+ (1,0) [0|0] "" BCU + SG_ Min_Temp : 8|8@1+ (1,0) [0|0] "" BCU + SG_ Max_Temp : 16|8@1+ (1,0) [0|0] "" BCU + SG_ Temp_5n : 24|8@1+ (1,0) [0|0] "" BCU + SG_ Temp_5n1 : 32|8@1+ (1,0) [0|0] "" BCU + SG_ Temp_5n2 : 40|8@1+ (1,0) [0|0] "" BCU + SG_ Temp_5n3 : 48|8@1+ (1,0) [0|0] "" BCU + SG_ Temp_5n4 : 56|8@1+ (1,0) [0|0] "" BCU BO_ 2148335617 Fan_Controller_1_Debug_2_0_to_Debugger: 8 Fan_Controller_1 SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger @@ -991,186 +733,26 @@ BO_ 2148472834 Fan_Controller_3_Fan_Status_to_ECU: 4 Fan_Controller_3 SG_ Input_Voltage : 16|8@1+ (0.1,0) [0|25.5] "Volts" ECU SG_ Input_Current : 24|8@1+ (0.1,0) [0|25.5] "Amps" ECU -BO_ 2148532225 Fan_Controller_4_Debug_2_0_to_Debugger: 8 Fan_Controller_4 - SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger - -BO_ 2148532737 Fan_Controller_4_Ping_to_Debugger: 4 Fan_Controller_4 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2148532738 Fan_Controller_4_Ping_to_ECU: 4 Fan_Controller_4 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU - -BO_ 2148538370 Fan_Controller_4_Fan_Status_to_ECU: 4 Fan_Controller_4 - SG_ Fan_Speed : 0|16@1+ (1,0) [0|65535] "RPM" ECU - SG_ Input_Voltage : 16|8@1+ (0.1,0) [0|25.5] "Volts" ECU - SG_ Input_Current : 24|8@1+ (0.1,0) [0|25.5] "Amps" ECU - -BO_ 2148597761 Fan_Controller_5_Debug_2_0_to_Debugger: 8 Fan_Controller_5 - SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger - -BO_ 2148598273 Fan_Controller_5_Ping_to_Debugger: 4 Fan_Controller_5 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2148598274 Fan_Controller_5_Ping_to_ECU: 4 Fan_Controller_5 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU - -BO_ 2148603906 Fan_Controller_5_Fan_Status_to_ECU: 4 Fan_Controller_5 - SG_ Fan_Speed : 0|16@1+ (1,0) [0|65535] "RPM" ECU - SG_ Input_Voltage : 16|8@1+ (0.1,0) [0|25.5] "Volts" ECU - SG_ Input_Current : 24|8@1+ (0.1,0) [0|25.5] "Amps" ECU - -BO_ 2148663297 Fan_Controller_6_Debug_2_0_to_Debugger: 8 Fan_Controller_6 - SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger - -BO_ 2148663809 Fan_Controller_6_Ping_to_Debugger: 4 Fan_Controller_6 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2148663810 Fan_Controller_6_Ping_to_ECU: 4 Fan_Controller_6 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU - -BO_ 2148669442 Fan_Controller_6_Fan_Status_to_ECU: 4 Fan_Controller_6 - SG_ Fan_Speed : 0|16@1+ (1,0) [0|65535] "RPM" ECU - SG_ Input_Voltage : 16|8@1+ (0.1,0) [0|25.5] "Volts" ECU - SG_ Input_Current : 24|8@1+ (0.1,0) [0|25.5] "Amps" ECU - -BO_ 2148728833 Fan_Controller_7_Debug_2_0_to_Debugger: 8 Fan_Controller_7 - SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger - -BO_ 2148729345 Fan_Controller_7_Ping_to_Debugger: 4 Fan_Controller_7 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2148729346 Fan_Controller_7_Ping_to_ECU: 4 Fan_Controller_7 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU - -BO_ 2148734978 Fan_Controller_7_Fan_Status_to_ECU: 4 Fan_Controller_7 - SG_ Fan_Speed : 0|16@1+ (1,0) [0|65535] "RPM" ECU - SG_ Input_Voltage : 16|8@1+ (0.1,0) [0|25.5] "Volts" ECU - SG_ Input_Current : 24|8@1+ (0.1,0) [0|25.5] "Amps" ECU - -BO_ 2148794369 Fan_Controller_8_Debug_2_0_to_Debugger: 8 Fan_Controller_8 - SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger - -BO_ 2148794881 Fan_Controller_8_Ping_to_Debugger: 4 Fan_Controller_8 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2148794882 Fan_Controller_8_Ping_to_ECU: 4 Fan_Controller_8 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU - -BO_ 2148800514 Fan_Controller_8_Fan_Status_to_ECU: 4 Fan_Controller_8 - SG_ Fan_Speed : 0|16@1+ (1,0) [0|65535] "RPM" ECU - SG_ Input_Voltage : 16|8@1+ (0.1,0) [0|25.5] "Volts" ECU - SG_ Input_Current : 24|8@1+ (0.1,0) [0|25.5] "Amps" ECU - -BO_ 2148007937 GR_Inverter_1_Debug_2_0_to_Debugger: 8 GR_Inverter_1 - SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger - -BO_ 2148008449 GR_Inverter_1_Ping_to_Debugger: 4 GR_Inverter_1 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2148008450 GR_Inverter_1_Ping_to_ECU: 4 GR_Inverter_1 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU - -BO_ 2148012802 GR_Inverter_1_Inverter_Status_1_to_ECU: 6 GR_Inverter_1 - SG_ AC_current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" ECU - SG_ DC_current : 16|16@1+ (0.01,0) [0|655.35] "Amps" ECU - SG_ Motor_RPM : 32|16@1+ (1,-32768) [-32768|32767] "RPM" ECU - -BO_ 2148013058 GR_Inverter_1_Inverter_Status_2_to_ECU: 6 GR_Inverter_1 - SG_ U_MOSFET_temperature : 0|8@1+ (1,-40) [-40|215] "Celsius" ECU - SG_ V_MOSFET_temperature : 16|8@1+ (1,-40) [-40|215] "Celsius" ECU - SG_ W_MOSFET_temperature : 32|8@1+ (1,-40) [-40|215] "Celsius" ECU - -BO_ 2148013314 GR_Inverter_1_Inverter_Status_3_to_ECU: 2 GR_Inverter_1 - SG_ Motor_temperature : 0|8@1+ (1,-40) [-40|215] "Celsius" ECU - SG_ Over_voltage_faults : 16|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Under_voltage_fault : 17|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Inv_overtemp_fault : 18|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Motor_overtemp_fault : 19|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Transistor_fault : 20|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Encoder_fault : 21|1@1+ (1,0) [0|0] "Bool" ECU - SG_ CAN_fault : 22|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Future_use : 23|1@1+ (1,0) [0|0] "Bool" ECU - -BO_ 2148073473 GR_Inverter_2_Debug_2_0_to_Debugger: 8 GR_Inverter_2 - SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger - -BO_ 2148073985 GR_Inverter_2_Ping_to_Debugger: 4 GR_Inverter_2 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2148073986 GR_Inverter_2_Ping_to_ECU: 4 GR_Inverter_2 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU - -BO_ 2148078338 GR_Inverter_2_Inverter_Status_1_to_ECU: 6 GR_Inverter_2 - SG_ AC_current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" ECU - SG_ DC_current : 16|16@1+ (0.01,0) [0|655.35] "Amps" ECU - SG_ Motor_RPM : 32|16@1+ (1,-32768) [-32768|32767] "RPM" ECU - -BO_ 2148078594 GR_Inverter_2_Inverter_Status_2_to_ECU: 6 GR_Inverter_2 - SG_ U_MOSFET_temperature : 0|8@1+ (1,-40) [-40|215] "Celsius" ECU - SG_ V_MOSFET_temperature : 16|8@1+ (1,-40) [-40|215] "Celsius" ECU - SG_ W_MOSFET_temperature : 32|8@1+ (1,-40) [-40|215] "Celsius" ECU - -BO_ 2148078850 GR_Inverter_2_Inverter_Status_3_to_ECU: 2 GR_Inverter_2 - SG_ Motor_temperature : 0|8@1+ (1,-40) [-40|215] "Celsius" ECU - SG_ Over_voltage_faults : 16|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Under_voltage_fault : 17|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Inv_overtemp_fault : 18|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Motor_overtemp_fault : 19|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Transistor_fault : 20|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Encoder_fault : 21|1@1+ (1,0) [0|0] "Bool" ECU - SG_ CAN_fault : 22|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Future_use : 23|1@1+ (1,0) [0|0] "Bool" ECU - -BO_ 2148139009 GR_Inverter_3_Debug_2_0_to_Debugger: 8 GR_Inverter_3 - SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger - -BO_ 2148139521 GR_Inverter_3_Ping_to_Debugger: 4 GR_Inverter_3 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2148139522 GR_Inverter_3_Ping_to_ECU: 4 GR_Inverter_3 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU - -BO_ 2148143874 GR_Inverter_3_Inverter_Status_1_to_ECU: 6 GR_Inverter_3 - SG_ AC_current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" ECU - SG_ DC_current : 16|16@1+ (0.01,0) [0|655.35] "Amps" ECU - SG_ Motor_RPM : 32|16@1+ (1,-32768) [-32768|32767] "RPM" ECU - -BO_ 2148144130 GR_Inverter_3_Inverter_Status_2_to_ECU: 6 GR_Inverter_3 - SG_ U_MOSFET_temperature : 0|8@1+ (1,-40) [-40|215] "Celsius" ECU - SG_ V_MOSFET_temperature : 16|8@1+ (1,-40) [-40|215] "Celsius" ECU - SG_ W_MOSFET_temperature : 32|8@1+ (1,-40) [-40|215] "Celsius" ECU - -BO_ 2148144386 GR_Inverter_3_Inverter_Status_3_to_ECU: 2 GR_Inverter_3 - SG_ Motor_temperature : 0|8@1+ (1,-40) [-40|215] "Celsius" ECU - SG_ Over_voltage_faults : 16|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Under_voltage_fault : 17|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Inv_overtemp_fault : 18|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Motor_overtemp_fault : 19|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Transistor_fault : 20|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Encoder_fault : 21|1@1+ (1,0) [0|0] "Bool" ECU - SG_ CAN_fault : 22|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Future_use : 23|1@1+ (1,0) [0|0] "Bool" ECU - -BO_ 2148204545 GR_Inverter_4_Debug_2_0_to_Debugger: 8 GR_Inverter_4 +BO_ 2148007937 GR_Inverter_Debug_2_0_to_Debugger: 8 GR_Inverter SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger -BO_ 2148205057 GR_Inverter_4_Ping_to_Debugger: 4 GR_Inverter_4 +BO_ 2148008449 GR_Inverter_Ping_to_Debugger: 4 GR_Inverter SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger -BO_ 2148205058 GR_Inverter_4_Ping_to_ECU: 4 GR_Inverter_4 +BO_ 2148008450 GR_Inverter_Ping_to_ECU: 4 GR_Inverter SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU -BO_ 2148209410 GR_Inverter_4_Inverter_Status_1_to_ECU: 6 GR_Inverter_4 +BO_ 2148012802 GR_Inverter_Inverter_Status_1_to_ECU: 6 GR_Inverter SG_ AC_current : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Amps" ECU SG_ DC_current : 16|16@1+ (0.01,0) [0|655.35] "Amps" ECU SG_ Motor_RPM : 32|16@1+ (1,-32768) [-32768|32767] "RPM" ECU -BO_ 2148209666 GR_Inverter_4_Inverter_Status_2_to_ECU: 6 GR_Inverter_4 +BO_ 2148013058 GR_Inverter_Inverter_Status_2_to_ECU: 6 GR_Inverter SG_ U_MOSFET_temperature : 0|8@1+ (1,-40) [-40|215] "Celsius" ECU SG_ V_MOSFET_temperature : 16|8@1+ (1,-40) [-40|215] "Celsius" ECU SG_ W_MOSFET_temperature : 32|8@1+ (1,-40) [-40|215] "Celsius" ECU -BO_ 2148209922 GR_Inverter_4_Inverter_Status_3_to_ECU: 2 GR_Inverter_4 +BO_ 2148013314 GR_Inverter_Inverter_Status_3_to_ECU: 2 GR_Inverter SG_ Motor_temperature : 0|8@1+ (1,-40) [-40|215] "Celsius" ECU SG_ Over_voltage_faults : 16|1@1+ (1,0) [0|0] "Bool" ECU SG_ Under_voltage_fault : 17|1@1+ (1,0) [0|0] "Bool" ECU @@ -1181,207 +763,66 @@ BO_ 2148209922 GR_Inverter_4_Inverter_Status_3_to_ECU: 2 GR_Inverter_4 SG_ CAN_fault : 22|1@1+ (1,0) [0|0] "Bool" ECU SG_ Future_use : 23|1@1+ (1,0) [0|0] "Bool" ECU -BO_ 35 IMD_IMD_response_to_ACU: 0 IMD +BO_ 35 IMD_IMD_response_to_BCU: 0 IMD -BO_ 2565862654 IMD_IMD_isolation_info_to_ACU: 0 IMD +BO_ 2565862654 IMD_IMD_isolation_info_to_BCU: 0 IMD -BO_ 2565862654 IMD_IMD_voltage_to_ACU: 0 IMD +BO_ 2565862654 IMD_IMD_voltage_to_BCU: 0 IMD -BO_ 2565862654 IMD_IMD_IT_system_to_ACU: 0 IMD +BO_ 2565862654 IMD_IMD_IT_system_to_BCU: 0 IMD -BO_ 2565862654 IMD_IMD_request_to_ACU: 0 IMD +BO_ 2565862654 IMD_IMD_request_to_BCU: 0 IMD -BO_ 2565862654 IMD_IMD_request_to_ACU: 0 IMD +BO_ 2565862654 IMD_IMD_request_to_BCU: 0 IMD -BO_ 2566849012 IMD_IMD_general_to_ACU: 8 IMD - SG_ R_Iso_Corrected : 0|8@1+ (1,0) [0|0] "" ACU - SG_ R_Iso_Status : 16|8@1+ (1,0) [0|0] "" ACU - SG_ Iso_Meas_Count : 24|8@1+ (1,0) [0|0] "" ACU - SG_ Status : 32|8@1+ (1,0) [0|0] "" ACU - SG_ Activity : 48|8@1+ (1,0) [0|0] "" ACU +BO_ 2566849012 IMD_IMD_general_to_BCU: 8 IMD + SG_ R_Iso_Corrected : 0|8@1+ (1,0) [0|0] "" BCU + SG_ R_Iso_Status : 16|8@1+ (1,0) [0|0] "" BCU + SG_ Iso_Meas_Count : 24|8@1+ (1,0) [0|0] "" BCU + SG_ Status : 32|8@1+ (1,0) [0|0] "" BCU + SG_ Activity : 48|8@1+ (1,0) [0|0] "" BCU -BO_ 2150171137 LV_DC_DC_Ping_to_Debugger: 4 LV_DC_DC +BO_ 2147746305 TCM_Ping_to_Debugger: 4 TCM SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger -BO_ 2150171138 LV_DC_DC_Ping_to_ECU: 4 LV_DC_DC +BO_ 2147746306 TCM_Ping_to_ECU: 4 TCM SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU -BO_ 2150175234 LV_DC_DC_DC_DC_Status_to_ECU: 7 LV_DC_DC - SG_ Input_Voltage : 0|16@1+ (0.001,0) [0|65.535] "Volts" ECU - SG_ Output_Voltage : 16|16@1+ (0.001,0) [0|65.535] "Volts" ECU - SG_ Input_Current : 32|8@1+ (0.1,0) [0|25.5] "Amps" ECU - SG_ Output_Current : 40|8@1+ (0.1,0) [0|25.5] "Amps" ECU - SG_ DC_DC_Temp : 48|8@1+ (1,0) [0|255] "Celsius" ECU - -BO_ 2148860417 SAM1_Ping_to_Debugger: 4 SAM1 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2148867586 SAM1_SAM_Brake_IR_to_ECU: 1 SAM1 - SG_ Temp : 0|8@1+ (1,0) [0|255] "Celsius" ECU - -BO_ 2148925953 SAM2_Ping_to_Debugger: 4 SAM2 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2148933122 SAM2_SAM_Brake_IR_to_ECU: 1 SAM2 - SG_ Temp : 0|8@1+ (1,0) [0|255] "Celsius" ECU - -BO_ 2148991489 SAM3_Ping_to_Debugger: 4 SAM3 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2148998658 SAM3_SAM_Brake_IR_to_ECU: 1 SAM3 - SG_ Temp : 0|8@1+ (1,0) [0|255] "Celsius" ECU - -BO_ 2149057025 SAM4_Ping_to_Debugger: 4 SAM4 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149064194 SAM4_SAM_Brake_IR_to_ECU: 1 SAM4 - SG_ Temp : 0|8@1+ (1,0) [0|255] "Celsius" ECU - -BO_ 2149122561 SAM5_Ping_to_Debugger: 4 SAM5 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149130242 SAM5_SAM_IMU_to_ECU: 12 SAM5 - SG_ Accel_X : 0|16@1+ (0.01,-327.68) [-327.68|327.67] "Meters/s^2" ECU - SG_ Accel_Y : 16|16@1+ (0.01,-327.68) [-327.68|327.67] "Meters/s^2" ECU - SG_ Accel_Z : 32|16@1+ (0.01,-327.68) [-327.68|327.67] "Meters/s^2" ECU - SG_ Gyro_X : 48|16@1+ (0.001,-32.768) [-32.768|32.767] "Meters/s^2" ECU - SG_ Gyro_Y : 64|16@1+ (0.001,-32.768) [-32.768|32.767] "Meters/s^2" ECU - SG_ Gyro_Z : 80|16@1+ (0.001,-32.768) [-32.768|32.767] "Meters/s^2" ECU - -BO_ 2149131778 SAM5_SAM_TOF_to_ECU: 2 SAM5 - SG_ Height : 0|16@1+ (0.00390625,0) [0|255] "mm" ECU - -BO_ 2149188097 SAM6_Ping_to_Debugger: 4 SAM6 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149253633 SAM7_Ping_to_Debugger: 4 SAM7 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149319169 SAM8_Ping_to_Debugger: 4 SAM8 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149384705 SAM9_Ping_to_Debugger: 4 SAM9 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149450241 SAM10_Ping_to_Debugger: 4 SAM10 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149515777 SAM11_Ping_to_Debugger: 4 SAM11 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149581313 SAM12_Ping_to_Debugger: 4 SAM12 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149646849 SAM13_Ping_to_Debugger: 4 SAM13 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149712385 SAM14_Ping_to_Debugger: 4 SAM14 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149777921 SAM15_Ping_to_Debugger: 4 SAM15 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149843457 SAM16_Ping_to_Debugger: 4 SAM16 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149908993 SAM17_Ping_to_Debugger: 4 SAM17 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger - -BO_ 2149974529 SAM18_Ping_to_Debugger: 4 SAM18 +BO_ 2147746305 TCM_Ping_to_Debugger: 4 TCM SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger -BO_ 2150040065 SAM19_Ping_to_Debugger: 4 SAM19 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger +BO_ 2147617283 CCU_BCU_Precharge_to_BCU: 1 CCU + SG_ Set_TS_Active : 0|1@1+ (1,0) [0|0] "Bool" BCU -BO_ 2150105601 SAM20_Ping_to_Debugger: 4 SAM20 - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger +BO_ 2147614723 CCU_Debug_2_0_to_BCU: 8 CCU + SG_ Debug : 0|64@1- (1,0) [0|0] "" BCU -BO_ 2147877121 Steering_Wheel_Debug_FD_to_Debugger: 64 Steering_Wheel - SG_ Debug : 0|64@1- (1,0) [0|0] "" Debugger +BO_ 2150642436 DGPS_GPS_ALT_to_TCM: 8 DGPS + SG_ ALT : 0|64@1+ (1,0) [0|0] "" TCM -BO_ 2147877377 Steering_Wheel_Ping_to_Debugger: 4 Steering_Wheel - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger +BO_ 2150641924 DGPS_GPS_LAT_to_TCM: 8 DGPS + SG_ LAT : 0|64@1+ (1,0) [0|0] "" TCM -BO_ 2147877378 Steering_Wheel_Ping_to_ECU: 4 Steering_Wheel - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" ECU +BO_ 2150642180 DGPS_GPS_LON_to_TCM: 8 DGPS + SG_ LON : 0|64@1+ (1,0) [0|0] "" TCM -BO_ 2147884034 Steering_Wheel_Steering_Status_to_ECU: 2 Steering_Wheel - SG_ Current_Encoder : 0|4@1+ (1,0) [1|16] "Position" ECU - SG_ Torque_Map_Encoder : 4|4@1+ (1,0) [1|16] "Position" ECU - SG_ Regen : 8|4@1+ (1,0) [1|16] "Position" ECU - SG_ Button_1 : 12|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Button_2 : 13|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Button_3 : 14|1@1+ (1,0) [0|0] "Bool" ECU - SG_ Button_4 : 15|1@1+ (1,0) [0|0] "Bool" ECU +BO_ 2150642692 DGPS_GPS_PX_to_TCM: 8 DGPS + SG_ Theta : 0|16@1- (0.001,0) [0|0] "" TCM + SG_ Acc : 16|16@1- (0.01,0) [0|0] "" TCM + SG_ status : 32|32@1+ (1,0) [0|0] "" TCM -BO_ 2147746305 TCM_Ping_to_Debugger: 4 TCM - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger +BO_ 2150642948 DGPS_GPS_QY_to_TCM: 8 DGPS + SG_ Theta : 0|16@1- (0.001,0) [0|0] "" TCM + SG_ Acc : 16|16@1- (0.01,0) [0|0] "" TCM + SG_ status : 32|32@1+ (1,0) [0|0] "" TCM -BO_ 2147746305 TCM_Ping_to_Debugger: 4 TCM - SG_ Timestamp : 0|32@1+ (1,0) [0|4,294,967,296] "ms" Debugger +BO_ 2150643204 DGPS_GPS_RZ_to_TCM: 8 DGPS + SG_ Theta : 0|16@1- (0.001,0) [0|0] "" TCM + SG_ Acc : 16|16@1- (0.01,0) [0|0] "" TCM + SG_ status : 32|32@1+ (1,0) [0|0] "" TCM -BO_ 2147756294 TCM_TCM_Status_to_Steering_Wheel: 8 TCM - SG_ Connection_Status : 0|1@1+ (1,0) [0|0] "Bool" Steering_Wheel - SG_ MQTT_Status : 1|1@1+ (1,0) [0|0] "Bool" Steering_Wheel - SG_ Epic_Shelter_Status : 2|1@1+ (1,0) [0|0] "Bool" Steering_Wheel - SG_ Camera_Status : 3|1@1+ (1,0) [0|0] "Bool" Steering_Wheel - SG_ Ping : 8|16@1+ (1,0) [0|0] "ms" Steering_Wheel - SG_ Cache_Size : 24|32@1+ (1,0) [0|0] "#" Steering_Wheel - -BO_ 2147756550 TCM_TCM_Resource_Utilization_to_Steering_Wheel: 44 TCM - SG_ CPU_0_Freq : 0|16@1+ (1,0) [0|0] "%" Steering_Wheel - SG_ CPU_0_Util : 16|8@1+ (1,0) [0|0] "%" Steering_Wheel - SG_ CPU_1_Freq : 24|16@1+ (1,0) [0|0] "%" Steering_Wheel - SG_ CPU_1_Util : 40|8@1+ (1,0) [0|0] "" Steering_Wheel - SG_ CPU_2_Freq : 48|16@1+ (1,0) [0|0] "%" Steering_Wheel - SG_ CPU_2_Util : 64|8@1+ (1,0) [0|0] "" Steering_Wheel - SG_ CPU_3_Freq : 72|16@1+ (1,0) [0|0] "" Steering_Wheel - SG_ CPU_3_Util : 88|8@1+ (1,0) [0|0] "" Steering_Wheel - SG_ CPU_4_Freq : 96|16@1+ (1,0) [0|0] "" Steering_Wheel - SG_ CPU_4_Util : 112|8@1+ (1,0) [0|0] "" Steering_Wheel - SG_ CPU_5_Freq : 120|16@1+ (1,0) [0|0] "" Steering_Wheel - SG_ CPU_5_Util : 136|8@1+ (1,0) [0|0] "Watts" Steering_Wheel - SG_ CPU_Total_Util : 144|8@1+ (1,0) [0|0] "" Steering_Wheel - SG_ RAM_Total : 152|16@1+ (1,0) [0|0] "" Steering_Wheel - SG_ RAM_Used : 168|16@1+ (1,0) [0|0] "" Steering_Wheel - SG_ RAM_Util : 184|8@1+ (1,0) [0|0] "" Steering_Wheel - SG_ GPU_Util : 192|8@1+ (1,0) [0|0] "" Steering_Wheel - SG_ GPU_Freq : 200|16@1+ (1,0) [0|0] "" Steering_Wheel - SG_ Disk_Total : 216|32@1+ (1,0) [0|0] "" Steering_Wheel - SG_ Disk_Used : 248|32@1+ (1,0) [0|0] "" Steering_Wheel - SG_ Disk_Util : 280|8@1+ (1,0) [0|0] "Celsius" Steering_Wheel - SG_ CPU_Temp : 288|8@1+ (1,0) [0|0] "" Steering_Wheel - SG_ GPU_Temp : 296|8@1+ (1,0) [0|0] "" Steering_Wheel - SG_ Voltage_Draw : 304|16@1+ (1,0) [0|0] "" Steering_Wheel - SG_ Current_Draw : 320|16@1+ (1,0) [0|0] "" Steering_Wheel - SG_ Power_Draw : 336|16@1+ (1,0) [0|0] "Celsius" Steering_Wheel - -BO_ 2150641666 DGPS_UVW_DGPS_to_ECU: 6 DGPS - SG_ DGPS_U : 0|16@1- (0.01,0) [0|0] "" ECU - SG_ DGPS_V : 16|16@1- (0.01,0) [0|0] "" ECU - SG_ DGPS_W : 32|16@1- (0.01,0) [0|0] "" ECU - -BO_ 2150641922 DGPS_GPS_LAT_to_ECU: 8 DGPS - SG_ LAT : 0|64@1+ (1,0) [0|0] "" ECU - -BO_ 2150642178 DGPS_GPS_LON_to_ECU: 8 DGPS - SG_ LON : 0|64@1+ (1,0) [0|0] "" ECU - -BO_ 2150642434 DGPS_GPS_ALT_to_ECU: 8 DGPS - SG_ ALT : 0|64@1+ (1,0) [0|0] "" ECU - -BO_ 2150642690 DGPS_GPS_PX_to_ECU: 8 DGPS - SG_ Theta : 0|16@1- (0.001,0) [0|0] "" ECU - SG_ Acc : 16|16@1- (0.01,0) [0|0] "" ECU - SG_ status : 32|32@1+ (1,0) [0|0] "" ECU - -BO_ 2150642946 DGPS_GPS_QY_to_ECU: 8 DGPS - SG_ Theta : 0|16@1- (0.001,0) [0|0] "" ECU - SG_ Acc : 16|16@1- (0.01,0) [0|0] "" ECU - SG_ status : 32|32@1+ (1,0) [0|0] "" ECU - -BO_ 2150643202 DGPS_GPS_RZ_to_ECU: 8 DGPS - SG_ Theta : 0|16@1- (0.001,0) [0|0] "" ECU - SG_ Acc : 16|16@1- (0.01,0) [0|0] "" ECU - SG_ status : 32|32@1+ (1,0) [0|0] "" ECU +BO_ 2150641668 DGPS_UVW_DGPS_to_TCM: 6 DGPS + SG_ DGPS_U : 0|16@1- (0.01,0) [0|0] "" TCM + SG_ DGPS_V : 16|16@1- (0.01,0) [0|0] "" TCM + SG_ DGPS_W : 32|16@1- (0.01,0) [0|0] "" TCM diff --git a/Autogen/CAN/Inc/GRCAN_BUS_ID.h b/Autogen/CAN/Inc/GRCAN_BUS_ID.h index 842d3f4c2..77b448659 100644 --- a/Autogen/CAN/Inc/GRCAN_BUS_ID.h +++ b/Autogen/CAN/Inc/GRCAN_BUS_ID.h @@ -4,13 +4,9 @@ /** GR CAN Bus IDs */ typedef enum { - /** Testing Bus */ GR_CAN_BUS_TESTING = 0, - /** Primary Bus */ GR_CAN_BUS_PRIMARY = 1, - /** Data Bus */ GR_CAN_BUS_DATA = 2, - /** Charger Bus */ GR_CAN_BUS_CHARGER = 3, } GR_CAN_BUS_ID; diff --git a/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h b/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h index d97c97d4c..ea81ef8cf 100644 --- a/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h +++ b/Autogen/CAN/Inc/GRCAN_CUSTOM_ID.h @@ -2,6 +2,37 @@ #ifndef CUSTOM_CAN_ID_H #define CUSTOM_CAN_ID_H -// Removed as being broken in `main` is not allowed +typedef enum { + CHARGER_CONTROL_CAN_ID = 0x1806e5f4, + CHARGER_DATA_CAN_ID = 0x18ff50e5, + DTI_CONTROL_1_CAN_ID = 116, + DTI_CONTROL_10_CAN_ID = 0xa16, + DTI_CONTROL_11_CAN_ID = 0xb16, + DTI_CONTROL_12_CAN_ID = 0xc16, + DTI_CONTROL_2_CAN_ID = 216, + DTI_CONTROL_3_CAN_ID = 316, + DTI_CONTROL_4_CAN_ID = 416, + DTI_CONTROL_5_CAN_ID = 516, + DTI_CONTROL_6_CAN_ID = 616, + DTI_CONTROL_7_CAN_ID = 716, + DTI_CONTROL_8_CAN_ID = 816, + DTI_CONTROL_9_CAN_ID = 916, + DTI_DATA_1_CAN_ID = 2016, + DTI_DATA_2_CAN_ID = 2116, + DTI_DATA_3_CAN_ID = 2216, + DTI_DATA_4_CAN_ID = 2316, + DTI_DATA_5_CAN_ID = 2416, + EM_MEASUREMENT_CAN_ID = 0x10d, + EM_STATUS_CAN_ID = 0x40d, + EM_TEAM_DATA_1_CAN_ID = 0x30d, + EM_TEAM_DATA_2_CAN_ID = 0x30e, + EM_TEMPERATURE_CAN_ID = 0x60d, + IMD_IT_SYSTEM_CAN_ID = 0x18eff4fe, + IMD_GENERAL_CAN_ID = 0x18ff01f4, + IMD_ISOLATION_INFO_CAN_ID = 0x18eff4fe, + IMD_REQUEST_CAN_ID = 0x18eff4fe, + IMD_RESPONSE_CAN_ID = 23, + IMD_VOLTAGE_CAN_ID = 0x18eff4fe, +} GRCAN_CUSTOM_ID; #endif // CUSTOM_CAN_ID_H diff --git a/Autogen/CAN/Inc/GRCAN_MSG_DATA.h b/Autogen/CAN/Inc/GRCAN_MSG_DATA.h index 82060a302..5e2e223a8 100644 --- a/Autogen/CAN/Inc/GRCAN_MSG_DATA.h +++ b/Autogen/CAN/Inc/GRCAN_MSG_DATA.h @@ -1,573 +1,564 @@ /* Auto-generated header file */ -#ifndef GR_OLD_MESSAGES_H -#define GR_OLD_MESSAGES_H +#ifndef GRCAN_MESSAGES_H +#define GRCAN_MESSAGES_H #include /** Debug 2.0 */ typedef struct { - /** Essentially a print statement up to 64 bytes long that whichever targeted can parse - (Byte 0) */ + /** Essentially a print statement up to 8 bytes long that whichever targeted can parse (Byte 0) */ uint8_t debug; -} GR_OLD_DEBUG_2_0_MSG; +} GRCAN_DEBUG_2_0_MSG; /** Debug FD */ typedef struct { - /** Essentially a print statement up to 64 bytes long that whichever targeted can parse - (Byte 0) */ + /** Essentially a print statement up to 64 bytes long that whichever targeted can parse (Byte 0) */ uint8_t debug; -} GR_OLD_DEBUG_FD_MSG; +} GRCAN_DEBUG_FD_MSG; /** Ping */ typedef struct { - /** Time in millis - (Byte 0) */ + /** Time in millis (Byte 0) */ uint32_t timestamp; -} GR_OLD_PING_MSG; - -// Removed as being broken in `main` is not allowed +} GRCAN_PING_MSG; + +/** ECU Status 1 */ +typedef struct { + /** [Byte 0 / Bits 0-1] GLV States +0: GLV Off State, +1: GLV On State. +See diagram in StateMachine. +[Byte 0 / Bits 2-3] Precharge States +2: Precharge Engaged State +3: Precharge Complete State +See diagram in StateMachine.h +[Byte 0 / Bits 4-5] ECU States +4: Drive Active ECU State +5: TS Discharge ECU State +6-7: Reserved +See diagram in StateMachine.h (Byte 0) */ + uint8_t state_messages; + /** [Byte 1 / Bits 8-15] +8: BCU Node Status (1: OK, 0: Timeout) +9: GR Inverter Status (1: OK, 0: Timeout) +10: Fan Controller 1 Status (1: OK, 0: Timeout) +11: Fan Controller 2 Status (1: OK, 0: Timeout) +12: Fan Controller 3 Status (1: OK, 0: Timeout) +13: Dash Panel Status (1: OK, 0: Timeout) +14: TCM Node Status (1: OK, 0: Timeout) +15: Reserved (Byte 1) */ + uint8_t status_flags; + /** Controls the AC current limits to each of the inverters +Discrete Mapping, actual values TBD (16 possible values)The torque map selected; torque map is the mapping of the throttle to the torque sent to each motor (Byte 2) */ + uint8_t power_level_torque_map; + /** the temperature of the hottest cell of the accumulator (Byte 3) */ + uint8_t max_cell_temp; + /** % charged of the Accumulator (Byte 4) */ + uint8_t accumulator_state_of_charge; + /** % charged of the Low Voltage Bat (Byte 5) */ + uint8_t glv_state_of_charge; + /** Output terminal voltage of accumulator (Byte 6) */ + uint16_t tractive_system_voltage; +} GRCAN_ECU_STATUS_1_MSG; /** ECU Status 2 */ typedef struct { - /** Output terminal voltage of accumulator - (Byte 0) */ - uint16_t tractive_system_voltage; - /** Absolute value of speed - (Byte 2) */ + /** Absolute value of speed (Byte 0) */ uint16_t vehicle_speed; - /** Wheel RPM - (Byte 4) */ + /** Wheel RPM (Byte 2) */ uint16_t fr_wheel_rpm; - /** Wheel RPM - (Byte 6) */ + /** Wheel RPM (Byte 4) */ uint16_t fl_wheel_rpm; -} GR_OLD_ECU_STATUS_2_MSG; + /** Wheel RPM (Byte 6) */ + uint16_t rr_wheel_rpm; +} GRCAN_ECU_STATUS_2_MSG; /** ECU Status 3 */ typedef struct { - /** Wheel RPM - (Byte 0) */ - uint16_t rr_wheel_rpm; - /** Wheel RPM - (Byte 2) */ + /** Wheel RPM (Byte 0) */ uint16_t rl_wheel_rpm; -} GR_OLD_ECU_STATUS_3_MSG; +} GRCAN_ECU_STATUS_3_MSG; /** ECU config */ typedef struct { /** Byte 0 (Byte 0) */ uint8_t reserved; -} GR_OLD_ECU_CONFIG_MSG; +} GRCAN_ECU_CONFIG_MSG; -/** ACU Status 1 */ +/** BCU Status 1 */ typedef struct { - /** All cell voltages added up - (Byte 0) */ + /** All cell voltages added up (Byte 0) */ uint16_t accumulator_voltage; - /** Output terminal voltage of accumulator - (Byte 2) */ + /** Output terminal voltage of accumulator (Byte 2) */ uint16_t ts_voltage; - /** Current output of accumulator - (Byte 4) */ + /** Current output of accumulator (Byte 4) */ uint16_t accumulator_current; - /** Accumulator state of charge (Based on lowest cell) - (Byte 6) */ + /** Accumulator state of charge (Based on lowest cell) (Byte 6) */ uint8_t accumulator_soc; - /** GLV state of charge - (Byte 7) */ + /** GLV state of charge (Byte 7) */ uint8_t glv_soc; -} GR_OLD_ACU_STATUS_1_MSG; - -// Removed as being broken in `main` is not allowed - -/** ACU Status 3 */ -typedef struct { - /** 600v input voltage - (Byte 0) */ +} GRCAN_BCU_STATUS_1_MSG; + +/** BCU Status 2 */ +typedef struct { + /** 20v GLV voltage +data type: u8 +units: Volts +scaled min: 0 +scaled max: 25.5 +map equation: "0.1x" (Byte 0) */ + uint8_t _20v_voltage; + /** 12v supply voltage +data type: u8 +units: Volts +scaled min: 0 +scaled max: 25.5 +map equation: "0.1x" (Byte 1) */ + uint8_t _12v_voltage; + /** Voltage before BCU Latch +data type: u8 +units: Volts +scaled min: 0 +scaled max: 25.5 +map equation: "0.1x" (Byte 2) */ + uint8_t sdc_voltage; + /** Lowest cell voltage in accumulator +data type: u8 +units: Volts +scaled min: 2 +scaled max: 4.55 +map equation: "0.01x+2" (Byte 3) */ + uint8_t min_cell_voltage; + /** Hottest cell in accumulator +data type: u8 +units: Celsius +scaled min: 0 +scaled max: 63.75 +map equation: "0.25x" (Byte 4) */ + uint8_t max_cell_temp; + /** [Byte 5 / Bits 40-47] +40: Over Temp (>60C) +41: Over Voltage (>4.2V/cell) +42: Under Volt (<2.5V/cell) +43: Over Current (Discharge) +44: Under Current (Charge) +45: 20V GLV Warning +46: 12V Supply Warning +47: SDC Warning (Byte 5) */ + uint8_t status_flags; + /** [Byte 6 / Bits 48-55] +48: Precharge Timeout +49: IR- / Precharge State (0:Open, 1:Closed) +50: IR+ State (0:Open, 1:Closed) +51: Software Latch (0:Open, 1:Closed) +52-55: Reserved (Byte 6) */ + uint8_t precharge_latch_flags; +} GRCAN_BCU_STATUS_2_MSG; + +/** BCU Status 3 */ +typedef struct { + /** 600v input voltage (Byte 0) */ uint16_t hv_input_voltage; - /** 20v output voltage - (Byte 2) */ + /** 20v output voltage (Byte 2) */ uint16_t hv_output_voltage; - /** 600v input current - (Byte 4) */ + /** 600v input current (Byte 4) */ uint16_t hv_input_current; - /** 20v output current - (Byte 6) */ + /** 20v output current (Byte 6) */ uint16_t hv_output_current; -} GR_OLD_ACU_STATUS_3_MSG; +} GRCAN_BCU_STATUS_3_MSG; -/** ACU Precharge */ +/** BCU Precharge */ typedef struct { - /** 0: shutdown, 1: go TS Active/Precharge - (Byte 0) */ + /** 0: shutdown, 1: go TS Active/Precharge (Byte 0) */ uint8_t set_ts_active; -} GR_OLD_ACU_PRECHARGE_MSG; +} GRCAN_BCU_PRECHARGE_MSG; -/** ACU Config Charge Parameters */ +/** BCU Config Charge Parameters */ typedef struct { - /** Sets the Target Charging voltage - (Byte 0) */ + /** Sets the Target Charging voltage (Byte 0) */ uint16_t charge_voltage; - /** Sets the Target Charging Current - (Byte 2) */ + /** Sets the Target Charging Current (Byte 2) */ uint16_t charge_current; -} GR_OLD_ACU_CONFIG_CHARGE_PARAMETERS_MSG; +} GRCAN_BCU_CONFIG_CHARGE_PARAMETERS_MSG; -/** ACU Config Operational Parameters */ +/** BCU Config Operational Parameters */ typedef struct { - /** Sets the threshold for Minimum Cell Voltage before Shutdown - (Byte 0) */ + /** Sets the threshold for Minimum Cell Voltage before Shutdown (Byte 0) */ uint8_t minimium_cell_voltage; - /** Sets the threshold for Max Cell Temperature before Shutdown - (Byte 1) */ + /** Sets the threshold for Max Cell Temperature before Shutdown (Byte 1) */ uint8_t max_cell_temperature; -} GR_OLD_ACU_CONFIG_OPERATIONAL_PARAMETERS_MSG; +} GRCAN_BCU_CONFIG_OPERATIONAL_PARAMETERS_MSG; -/** ACU Cell Data 1 */ +/** BCU Cell Data 1 */ typedef struct { struct { uint8_t voltage; uint8_t temperature; } cells[32]; -} GR_OLD_ACU_CELL_DATA_1_MSG; +} GRCAN_BCU_CELL_DATA_1_MSG; -/** ACU Cell Data 2 */ +/** BCU Cell Data 2 */ typedef struct { struct { uint8_t voltage; uint8_t temperature; } cells[32]; -} GR_OLD_ACU_CELL_DATA_2_MSG; +} GRCAN_BCU_CELL_DATA_2_MSG; -/** ACU Cell Data 3 */ +/** BCU Cell Data 3 */ typedef struct { struct { uint8_t voltage; uint8_t temperature; } cells[32]; -} GR_OLD_ACU_CELL_DATA_3_MSG; +} GRCAN_BCU_CELL_DATA_3_MSG; -/** ACU Cell Data 4 */ +/** BCU Cell Data 4 */ typedef struct { struct { uint8_t voltage; uint8_t temperature; } cells[32]; -} GR_OLD_ACU_CELL_DATA_4_MSG; +} GRCAN_BCU_CELL_DATA_4_MSG; -/** ACU Cell Data 5 */ +/** BCU Cell Data 5 */ typedef struct { struct { uint8_t voltage; uint8_t temperature; } cells[32]; -} GR_OLD_ACU_CELL_DATA_5_MSG; +} GRCAN_BCU_CELL_DATA_5_MSG; /** DC-DC Status */ typedef struct { - /** 0-22 - (Byte 0) */ + /** ~20v for LV (LV only. Send 0 for HV) (Byte 0) */ uint16_t input_voltage; - /** ~12v for LV and ~20v for HV - (Byte 2) */ + /** ~12v for LV and ~20v for HV (Byte 2) */ uint16_t output_voltage; - /** 0-10 - (Byte 4) */ + /** Input current (LV only. Send 0 for HV) (Byte 4) */ uint8_t input_current; - /** Output current - (Byte 5) */ + /** Output current (Byte 5) */ uint8_t output_current; - /** Temp of DC-DC converter - (Byte 6) */ + /** Temp of DC-DC converter (Byte 6) */ uint8_t dc_dc_temp; -} GR_OLD_DC_DC_STATUS_MSG; +} GRCAN_DC_DC_STATUS_MSG; /** Inverter Status 1 */ typedef struct { - /** 0.01 * current, int16_t - (Byte 0) */ + /** 0.01 * current, int16_t (Byte 0) */ uint16_t ac_current; - /** 0.01 * current, int16_t - (Byte 2) */ + /** 0.01 * current, int16_t (Byte 2) */ uint16_t dc_current; - /** RPM, int16_t - (Byte 4) */ + /** RPM, int16_t (Byte 4) */ uint16_t motor_rpm; -} GR_OLD_INVERTER_STATUS_1_MSG; +} GRCAN_INVERTER_STATUS_1_MSG; /** Inverter Status 2 */ typedef struct { - /** Celsius + 40, uint8_t - (Byte 0) */ + /** Celsius + 40, uint8_t (Byte 0) */ uint8_t u_mosfet_temperature; - /** Celsius + 40, uint8_t - (Byte 2) */ + /** Celsius + 40, uint8_t (Byte 2) */ uint8_t v_mosfet_temperature; - /** Celsius + 40, uint8_t - (Byte 4) */ + /** Celsius + 40, uint8_t (Byte 4) */ uint8_t w_mosfet_temperature; -} GR_OLD_INVERTER_STATUS_2_MSG; +} GRCAN_INVERTER_STATUS_2_MSG; /** Inverter Status 3 */ typedef struct { - /** Celsius + 40, uint8_t - (Byte 0) */ + /** Celsius + 40, uint8_t (Byte 0) */ uint8_t motor_temperature; - uint8_t error_fault_violation_bits; -} GR_OLD_INVERTER_STATUS_3_MSG; + /** Packed: bytes 2-2. bit 16: over_voltage_faults; bit 17: under_voltage_fault; + * bit 18: inv_overtemp_fault; bit 19: motor_overtemp_fault; bit 20: transistor_fault; + * bit 21: encoder_fault; bit 22: can_fault; bit 23: future_use; */ + uint8_t error_fault_violation_bits_b2; +} GRCAN_INVERTER_STATUS_3_MSG; /** Inverter Config */ typedef struct { - /** Max AC Current - (Byte 0) */ + /** Max AC Current (Byte 0) */ uint16_t max_ac_current; - /** Max DC Current - (Byte 2) */ + /** Max DC Current (Byte 2) */ uint16_t max_dc_current; - /** 0: No limit n :limited at n RPM - (Byte 4) */ + /** 0: No limit n :limited at n RPM (Byte 4) */ uint16_t absolute_max_rpm_limit; - /** Write 1 inverts direction - (Byte 6) */ + /** Write 1 inverts direction (Byte 6) */ uint8_t motor_direction; -} GR_OLD_INVERTER_CONFIG_MSG; +} GRCAN_INVERTER_CONFIG_MSG; /** Inverter Command */ typedef struct { - /** Commanded AC Current - (Byte 0) */ + /** Commanded AC Current (Byte 0) */ uint16_t set_ac_current; - /** Commanded DC Current - (Byte 2) */ + /** Commanded DC Current (Byte 2) */ uint16_t set_dc_current; - /** 0: No limit n :limited at n RPM - (Byte 4) */ + /** 0: No limit n :limited at n RPM (Byte 4) */ uint16_t rpm_limit; - /** Field weakening strength - (Byte 6) */ + /** Field weakening strength (Byte 6) */ uint8_t field_weakening; - /** Write this to 1 every 100ms to enable inverter - (Byte 7) */ + /** Write this to 1 every 100ms to enable inverter (Byte 7) */ uint8_t drive_enable; -} GR_OLD_INVERTER_COMMAND_MSG; +} GRCAN_INVERTER_COMMAND_MSG; /** Fan Status */ typedef struct { - /** Fan RPM - (Byte 0) */ + /** Fan RPM (Byte 0) */ uint16_t fan_speed; - /** 0-22 - (Byte 2) */ + /** 0-22 (Byte 2) */ uint8_t input_voltage; - /** 0-10 - (Byte 3) */ + /** 0-10 (Byte 3) */ uint8_t input_current; -} GR_OLD_FAN_STATUS_MSG; +} GRCAN_FAN_STATUS_MSG; /** Fan Command */ typedef struct { - /** 0-100 Percent - (Byte 0) */ + /** 0-100 Percent (Byte 0) */ uint8_t fan_command; -} GR_OLD_FAN_COMMAND_MSG; +} GRCAN_FAN_COMMAND_MSG; /** Dash Status */ typedef struct { - uint8_t ping_block; - /** MSB is state (1: pressed) - Other 7 bits represent the time in 0.1s that it has been in that state - (Byte 1) */ - uint8_t ts_button_data; - /** MSB is state (1: pressed) - Other 7 bits represent the time in 0.1s that it has been in that state - (Byte 2) */ - uint8_t rtd_button_data; -} GR_OLD_DASH_STATUS_MSG; + /** TS Active = bit 0, RTD = bit 1, bits 2–7 reserved (Byte 0) */ + uint8_t button_flags; + /** BMS = bit 0 of this byte, IMD = bit 1, BSPD = bit 2, bits 3–7 reserved (Byte 1) */ + uint8_t led_bits; +} GRCAN_DASH_STATUS_MSG; /** Dash Config */ typedef struct { - uint8_t ping_block; -} GR_OLD_DASH_CONFIG_MSG; + /** Packed: bytes 0-0. bit 0: bms_led; bit 1: imd_led; bit 2: bspd_led; */ + uint8_t ping_block_b0; +} GRCAN_DASH_CONFIG_MSG; /** Steering Status */ typedef struct { - /** Position of knob (1-16) - Position of knob (1-16) - (Byte 0) */ + /** Position of knob (1-16)Position of knob (1-16) (Byte 0) */ uint8_t current_encoder_torque_map_encoder; - uint8_t ping_block; -} GR_OLD_STEERING_STATUS_MSG; + /** Packed: bytes 1-1. bit 8: regen; bit 12: button_1; bit 13: button_2; bit 14: button_3; + * bit 15: button_4; */ + uint8_t ping_block_b1; +} GRCAN_STEERING_STATUS_MSG; /** Steering Config */ typedef struct { /** Byte 0 (Byte 0) */ uint8_t reserved; -} GR_OLD_STEERING_CONFIG_MSG; +} GRCAN_STEERING_CONFIG_MSG; /** SAM Brake IR */ typedef struct { - /** IR Temp of Brakes - (Byte 0) */ + /** IR Temp of Brakes (Byte 0) */ uint8_t temp; -} GR_OLD_SAM_BRAKE_IR_MSG; +} GRCAN_SAM_BRAKE_IR_MSG; /** SAM Tire Temp */ typedef struct { - /** Furthest from chassis - (Byte 0) */ + /** Furthest from chassis (Byte 0) */ uint8_t outside_temp; - /** Middle of tire - (Byte 1) */ + /** Middle of tire (Byte 1) */ uint8_t outside_middle_temp; - /** Middle of tire - (Byte 2) */ + /** Middle of tire (Byte 2) */ uint8_t inside_middle_temp; - /** Closest to chassis - (Byte 3) */ + /** Closest to chassis (Byte 3) */ uint8_t inside_temp; -} GR_OLD_SAM_TIRE_TEMP_MSG; +} GRCAN_SAM_TIRE_TEMP_MSG; /** SAM IMU */ typedef struct { - /** Acceleration in X-axis - (Byte 0) */ + /** Acceleration in X-axis (Byte 0) */ uint16_t accel_x; - /** Acceleration in Y-axis - (Byte 2) */ + /** Acceleration in Y-axis (Byte 2) */ uint16_t accel_y; - /** Acceleration in Z-axis - (Byte 4) */ + /** Acceleration in Z-axis (Byte 4) */ uint16_t accel_z; - /** Angular velocity in X-axis - (Byte 6) */ + /** Angular velocity in X-axis (Byte 6) */ uint16_t gyro_x; - /** Angular velocity in Y-axis - (Byte 8) */ + /** Angular velocity in Y-axis (Byte 8) */ uint16_t gyro_y; - /** Angular velocity in Z-axis - (Byte 10) */ + /** Angular velocity in Z-axis (Byte 10) */ uint16_t gyro_z; -} GR_OLD_SAM_IMU_MSG; +} GRCAN_SAM_IMU_MSG; /** SAM GPS 1 */ typedef struct { - /** Latitude in decimal degrees - (Byte 0) */ + /** Latitude in decimal degrees (Byte 0) */ uint32_t latitude; - /** Longitude in decimal degrees - (Byte 4) */ + /** Longitude in decimal degrees (Byte 4) */ uint32_t longitude; -} GR_OLD_SAM_GPS_1_MSG; +} GRCAN_SAM_GPS_1_MSG; /** SAM GPS 2 */ typedef struct { - /** GPS position accuracy - (Byte 0) */ + /** GPS position accuracy (Byte 0) */ uint32_t accuracy; - /** Vehicle attitude - (Byte 4) */ + /** Vehicle attitude (Byte 4) */ uint32_t attitude; -} GR_OLD_SAM_GPS_2_MSG; +} GRCAN_SAM_GPS_2_MSG; /** SAM GPS Time */ typedef struct { - /** Time in seconds since GPS Epoch - (Byte 0) */ + /** Time in seconds since GPS Epoch (Byte 0) */ uint32_t time; - /** Time of week in milliseconds - (Byte 4) */ + /** Time of week in milliseconds (Byte 4) */ uint32_t time_of_week_ms; -} GR_OLD_SAM_GPS_TIME_MSG; +} GRCAN_SAM_GPS_TIME_MSG; /** SAM GPS Heading */ typedef struct { - /** Heading angle relative to true North - (Byte 0) */ + /** Heading angle relative to true North (Byte 0) */ uint32_t heading_from_north; -} GR_OLD_SAM_GPS_HEADING_MSG; +} GRCAN_SAM_GPS_HEADING_MSG; /** SAM Sus Pots */ typedef struct { - /** Pot Pos - (Byte 0) */ + /** Pot Pos (Byte 0) */ uint8_t suspension_angle; -} GR_OLD_SAM_SUS_POTS_MSG; +} GRCAN_SAM_SUS_POTS_MSG; /** SAM TOF */ typedef struct { - /** Ride Height - (Byte 0) */ + /** Ride Height (Byte 0) */ uint16_t height; -} GR_OLD_SAM_TOF_MSG; +} GRCAN_SAM_TOF_MSG; /** SAM Rear Wheelspeed */ typedef struct { - /** Wheel RPM - (Byte 0) */ + /** Wheel RPM (Byte 0) */ uint16_t speed; -} GR_OLD_SAM_REAR_WHEELSPEED_MSG; +} GRCAN_SAM_REAR_WHEELSPEED_MSG; /** SAM Pushrod Force */ typedef struct { - /** Pushrod Force - (Byte 0) */ + /** Pushrod Force (Byte 0) */ uint16_t load_force; -} GR_OLD_SAM_PUSHROD_FORCE_MSG; +} GRCAN_SAM_PUSHROD_FORCE_MSG; /** TCM Status */ typedef struct { - uint8_t ping_block; - /** Mapache ping (upload) - (Byte 1) */ - uint16_t ping; - /** # of messages on cache (non-synced) - (Byte 3) */ + /** Packed: bytes 0-0. bit 0: connection_status; bit 1: mqtt_status; bit 2: epic_shelter_status; + * bit 3: camera_status; bit 4: reserved; */ + uint8_t ping_block_b0; + /** Mapache ping (upload) (Byte 1) */ + uint16_t mapache_ping; + /** # of messages on cache (non-synced) (Byte 3) */ uint32_t cache_size; /** Byte 7 (Byte 7) */ uint8_t reserved; -} GR_OLD_TCM_STATUS_MSG; +} GRCAN_TCM_STATUS_MSG; /** TCM Resource Utilization */ typedef struct { - /** core 0 frequency in MHz - (Byte 0) */ + /** core 0 frequency in MHz (Byte 0) */ uint16_t cpu_0_freq; - /** core 0 utilization in % - (Byte 2) */ + /** core 0 utilization in % (Byte 2) */ uint8_t cpu_0_util; - /** core 1 frequency in MHz - (Byte 3) */ + /** core 1 frequency in MHz (Byte 3) */ uint16_t cpu_1_freq; - /** core 1 utilization in % - (Byte 5) */ + /** core 1 utilization in % (Byte 5) */ uint8_t cpu_1_util; - /** core 2 frequency in MHz - (Byte 6) */ + /** core 2 frequency in MHz (Byte 6) */ uint16_t cpu_2_freq; - /** core 2 utilization in % - (Byte 8) */ + /** core 2 utilization in % (Byte 8) */ uint8_t cpu_2_util; - /** core 3 frequency in MHz - (Byte 9) */ + /** core 3 frequency in MHz (Byte 9) */ uint16_t cpu_3_freq; - /** core 3 utilization in % - (Byte 11) */ + /** core 3 utilization in % (Byte 11) */ uint8_t cpu_3_util; - /** core 4 frequency in MHz - (Byte 12) */ + /** core 4 frequency in MHz (Byte 12) */ uint16_t cpu_4_freq; - /** core 4 utilization in % - (Byte 14) */ + /** core 4 utilization in % (Byte 14) */ uint8_t cpu_4_util; - /** core 5 frequency in MHz - (Byte 15) */ + /** core 5 frequency in MHz (Byte 15) */ uint16_t cpu_5_freq; - /** core 5 utilization in % - (Byte 17) */ + /** core 5 utilization in % (Byte 17) */ uint8_t cpu_5_util; - /** total cpu utilization in % - (Byte 18) */ + /** total cpu utilization in % (Byte 18) */ uint8_t cpu_total_util; - /** total memory in MB - (Byte 19) */ + /** total memory in MB (Byte 19) */ uint16_t ram_total; - /** used memory in MB - (Byte 21) */ + /** used memory in MB (Byte 21) */ uint16_t ram_used; - /** memory utilization in % - (Byte 23) */ + /** memory utilization in % (Byte 23) */ uint8_t ram_util; - /** gpu utilization in % - (Byte 24) */ + /** gpu utilization in % (Byte 24) */ uint8_t gpu_util; - /** gpu frequency in MHz - (Byte 25) */ + /** gpu frequency in MHz (Byte 25) */ uint16_t gpu_freq; - /** total disk space in MB - (Byte 27) */ + /** total disk space in MB (Byte 27) */ uint32_t disk_total; - /** used disk space in MB - (Byte 31) */ + /** used disk space in MB (Byte 31) */ uint32_t disk_used; - /** disk utilization in % - (Byte 35) */ + /** disk utilization in % (Byte 35) */ uint8_t disk_util; - /** cpu temp in ˚C - (Byte 36) */ + /** cpu temp in ˚C (Byte 36) */ uint8_t cpu_temp; - /** gpu temp in ˚C - (Byte 37) */ + /** gpu temp in ˚C (Byte 37) */ uint8_t gpu_temp; - /** voltage draw in mV - (Byte 38) */ + /** voltage draw in mV (Byte 38) */ uint16_t voltage_draw; - /** current draw in mA - (Byte 40) */ + /** current draw in mA (Byte 40) */ uint16_t current_draw; - /** power draw in mW - (Byte 42) */ + /** power draw in mW (Byte 42) */ uint16_t power_draw; -} GR_OLD_TCM_RESOURCE_UTILIZATION_MSG; +} GRCAN_TCM_RESOURCE_UTILIZATION_MSG; /** Dash Warning Flags */ typedef struct { - uint8_t error_fault_violation_bits; -} GR_OLD_DASH_WARNING_FLAGS_MSG; + /** Packed: bytes 0-0. bit 0: bse_apps_violation; bit 1: reserved; bit 2: reserved; bit 3: reserved; + * bit 4: reserved; bit 5: reserved; bit 6: reserved; bit 7: reserved; */ + uint8_t error_fault_violation_bits_b0; +} GRCAN_DASH_WARNING_FLAGS_MSG; /** Specific Brake IR */ typedef struct { - /** Wheel identifier according to the wiki - (Byte 0) */ + /** Wheel identifier according to the wiki (Byte 0) */ uint8_t wheel_identifier; - /** IR Temp of Brakes - (Byte 1) */ + /** IR Temp of Brakes (Byte 1) */ uint8_t temp; -} GR_OLD_SPECIFIC_BRAKE_IR_MSG; +} GRCAN_SPECIFIC_BRAKE_IR_MSG; /** ECU Ping Information */ typedef struct { - /** Literal copy of ECU Status's status bit map - (Byte 0) */ + /** Literal copy of ECU Status's status bit map (Byte 0) */ uint8_t online_pings; -} GR_OLD_ECU_PING_INFORMATION_MSG; +} GRCAN_ECU_PING_INFORMATION_MSG; /** ECU Pedals Data */ typedef struct { - /** APPS 1 Signal - (Byte 0) */ - uint16_t apps1_signal; - /** APPS 2 Signal - (Byte 2) */ - uint16_t apps2_signal; - /** Brake Force Signal - (Byte 4) */ + /** 4-20 mA signal (Byte 0) */ + uint16_t bspd_signal; + /** 4-20 mA signal (Byte 2) */ uint16_t bse_signal; - /** Brake Pressure Signal - Brake Pressure Signal - (Byte 6) */ - uint16_t brake_f_signal_brake_r_signal; -} GR_OLD_ECU_PEDALS_DATA_MSG; + /** 4-20 mA signal (Byte 4) */ + uint16_t apps_1_signal; + /** 4-20 mA signal (Byte 6) */ + uint16_t apps_2_signal; + /** 4-20 mA signal (Byte 8) */ + uint16_t brakeline_f_signal; + /** 4-20 mA signal (Byte 10) */ + uint16_t brakeline_r_signal; + /** 4-20 mA signal (Byte 12) */ + uint16_t steering_angle_signal; + /** 4-20 mA signal (Byte 14) */ + uint16_t aux_signal; +} GRCAN_ECU_PEDALS_DATA_MSG; /** GPS LAT */ typedef struct { - /** lattitude - (Byte 0) */ + /** lattitude (Byte 0) */ uint8_t lat; -} GR_OLD_GPS_LAT_MSG; +} GRCAN_GPS_LAT_MSG; /** GPS LON */ typedef struct { - /** longitude - (Byte 0) */ + /** longitude (Byte 0) */ uint8_t lon; -} GR_OLD_GPS_LON_MSG; +} GRCAN_GPS_LON_MSG; /** GPS ALT */ typedef struct { - /** altitude - (Byte 0) */ + /** altitude (Byte 0) */ uint8_t alt; -} GR_OLD_GPS_ALT_MSG; +} GRCAN_GPS_ALT_MSG; /** GPS PX */ typedef struct { @@ -577,7 +568,7 @@ typedef struct { uint16_t acc; /** Byte 4 (Byte 4) */ uint32_t status; -} GR_OLD_GPS_PX_MSG; +} GRCAN_GPS_PX_MSG; /** GPS QY */ typedef struct { @@ -587,7 +578,7 @@ typedef struct { uint16_t acc; /** Byte 4 (Byte 4) */ uint32_t status; -} GR_OLD_GPS_QY_MSG; +} GRCAN_GPS_QY_MSG; /** GPS RZ */ typedef struct { @@ -597,19 +588,16 @@ typedef struct { uint16_t acc; /** Byte 4 (Byte 4) */ uint32_t status; -} GR_OLD_GPS_RZ_MSG; +} GRCAN_GPS_RZ_MSG; /** UVW DGPS */ typedef struct { - /** U - (Byte 0) */ + /** U (Byte 0) */ uint16_t dgps_u; - /** V - (Byte 2) */ + /** V (Byte 2) */ uint16_t dgps_v; - /** W - (Byte 4) */ + /** W (Byte 4) */ uint16_t dgps_w; -} GR_OLD_UVW_DGPS_MSG; +} GRCAN_UVW_DGPS_MSG; #endif diff --git a/Autogen/CAN/Inc/GRCAN_MSG_ID.h b/Autogen/CAN/Inc/GRCAN_MSG_ID.h index bf075be2e..c13b75a96 100644 --- a/Autogen/CAN/Inc/GRCAN_MSG_ID.h +++ b/Autogen/CAN/Inc/GRCAN_MSG_ID.h @@ -10,17 +10,17 @@ typedef enum { MSG_ECU_STATUS_2 = 0x004, MSG_ECU_STATUS_3 = 0x005, MSG_ECU_CONFIG = 0x006, - MSG_ACU_STATUS_1 = 0x007, - MSG_ACU_STATUS_2 = 0x008, - MSG_ACU_STATUS_3 = 0x009, - MSG_ACU_PRECHARGE = 0x00A, - MSG_ACU_CONFIG_CHARGE_PARAMETERS = 0x00B, - MSG_ACU_CONFIG_OPERATIONAL_PARAMETERS = 0x00C, - MSG_ACU_CELL_DATA_1 = 0x00D, - MSG_ACU_CELL_DATA_2 = 0x00E, - MSG_ACU_CELL_DATA_3 = 0x00F, - MSG_ACU_CELL_DATA_4 = 0x010, - MSG_ACU_CELL_DATA_5 = 0x011, + MSG_BCU_STATUS_1 = 0x007, + MSG_BCU_STATUS_2 = 0x008, + MSG_BCU_STATUS_3 = 0x009, + MSG_BCU_PRECHARGE = 0x00A, + MSG_BCU_CONFIG_CHARGE_PARAMETERS = 0x00B, + MSG_BCU_CONFIG_OPERATIONAL_PARAMETERS = 0x00C, + MSG_BCU_CELL_DATA_1 = 0x00D, + MSG_BCU_CELL_DATA_2 = 0x00E, + MSG_BCU_CELL_DATA_3 = 0x00F, + MSG_BCU_CELL_DATA_4 = 0x010, + MSG_BCU_CELL_DATA_5 = 0x011, MSG_INVERTER_STATUS_1 = 0x013, MSG_INVERTER_STATUS_2 = 0x014, MSG_INVERTER_STATUS_3 = 0x015, diff --git a/Autogen/CAN/Inc/GRCAN_NODE_ID.h b/Autogen/CAN/Inc/GRCAN_NODE_ID.h index 0b1e974fc..f7d34f531 100644 --- a/Autogen/CAN/Inc/GRCAN_NODE_ID.h +++ b/Autogen/CAN/Inc/GRCAN_NODE_ID.h @@ -2,6 +2,20 @@ #ifndef GR_IDS_H #define GR_IDS_H -// Removed as being broken in `main` is not allowed +typedef enum { + ALL = 0xFF, + BCU = 0x03, + CCU = 0x02, + Charger = 0x00, + Charging_SDC = 0x0C, + DGPS = 0x30, + Dash_Panel = 0x05, + Debugger = 0x01, + Fan_Controller_1 = 0x0D, + Fan_Controller_2 = 0x0E, + Fan_Controller_3 = 0x0F, + GR_Inverter = 0x08, + TCM = 0x04, +} GRCAN_NODE_ID; #endif // GR_IDS_H diff --git a/Autogen/CAN/Src/BusParser.pl b/Autogen/CAN/Src/BusParser.pl index 5edeb65ca..0bea44db4 100644 --- a/Autogen/CAN/Src/BusParser.pl +++ b/Autogen/CAN/Src/BusParser.pl @@ -9,8 +9,8 @@ main(); sub main { - my $yaml_path = $ARGV[0] // 'format.CANdo'; - my $output_path = $ARGV[1] // 'GR_CAN_BUS_ID.h'; + my $yaml_path = $ARGV[0] // q{format.CANdo}; + my $output_path = $ARGV[1] // q{GR_CAN_BUS_ID.h}; my $dir = dirname($output_path); if ( $dir && $dir ne q{.} && !-d $dir ) { @@ -42,29 +42,64 @@ sub parse_bus_ids { my @found_ids; my $in_section = 0; - for my $line (@lines) { - if ( $line =~ /^Bus[ ]ID:/smx ) { + for my $i ( 0 .. $#lines ) { + my $line = $lines[$i]; + chomp $line; + + # 1. Detect the "Bus ID:" section header (flexible spacing/case) + if ( $line =~ /^Bus\s*ID\s*:/ix ) { $in_section = 1; next; } - last if $in_section && $line =~ /^\w/smx; + + # 2. Stop if we hit a new top-level section (0 indentation) + last if $in_section && $line =~ /^\S/ && $line !~ /^Bus/i; next if !$in_section; - if ( $line =~ /^ \s+ ([^:]+) : \s* ["']? ( [^"'\s#]+ ) ["']? \s* (?: [#] \s* (.*?) )? \s* $/smx ) { - my $name = $1; - my $val = $2; - my $comment = $3 // q{}; + # 3. Match the Bus Entry: " Name: ID" + # Matches: 2 spaces, captures Name (everything before colon), captures ID (the number) + if ( $line =~ /^\s{2} ([^:#\s][^:]+) : \s* (\d+) /x ) { + my $name = $1; + my $val = $2; + $name =~ s/^\s+|\s+$//g; - $name =~ s/^\s+|\s+$//gsmx; - $val =~ s/^\s+|\s+$//gsmx; - $comment =~ s/^\s+|\s+$//gsmx; + my $entry = { name => $name, id => $val, comment => q{} }; + $entry->{comment} = _extract_comment_block( \@lines, $i, $entry->{comment} ); - push @found_ids, { name => $name, id => $val, comment => $comment }; + push @found_ids, $entry; } } return \@found_ids; } +sub _extract_comment_block { + my ( $lines_ref, $index, $existing ) = @_; + my $comment = $existing // q{}; + my $j = $index + 1; + + while ( $j <= $#{$lines_ref} && ${$lines_ref}[$j] =~ /^\s{4,}/ ) { + my $line = ${$lines_ref}[$j]; + if ( $line =~ /^\s{4} comment: \s* (.*) /ix ) { + my $text = $1; + $text =~ s/^\s+|\s+$//g; + if ( $text ne q{} ) { + $comment = $text; + } + else { + my $k = $j + 1; + while ( $k <= $#{$lines_ref} && ${$lines_ref}[$k] =~ /^\s{6,} (.+) /x ) { + my $sub_text = $1; + $sub_text =~ s/^\s+|\s+$//g; + $comment .= ( $comment ? q{ } : q{} ) . $sub_text; + $k++; + } + } + } + $j++; + } + return $comment; +} + sub generate_bus_header_content { my ($ids_ref) = @_; my @header_lines; @@ -75,18 +110,19 @@ sub generate_bus_header_content { push @header_lines, "/** GR CAN Bus IDs */\n"; push @header_lines, "typedef enum {\n"; - my @sorted = sort { $a->{id} <=> $b->{id} || $a->{name} cmp $b->{name} } @{$ids_ref}; + # Sort by ID (numeric) + my @sorted = sort { ( $a->{id} // 0 ) <=> ( $b->{id} // 0 ) } @{$ids_ref}; for my $item (@sorted) { + next if $item->{id} eq q{}; + my $const_name = $item->{name}; - $const_name =~ s/[[:^alnum:]]/_/gsmx; + $const_name =~ s/[[:^alnum:]]/_/g; # Clean name for C constant - if ( defined $item->{id} && $item->{id} ne q{} ) { - if ( defined $item->{comment} && $item->{comment} ne q{} ) { - push @header_lines, sprintf " /** %s */\n", $item->{comment}; - } - push @header_lines, sprintf " GR_CAN_BUS_%s = %s,\n", uc $const_name, $item->{id}; + if ( $item->{comment} ne q{} ) { + push @header_lines, sprintf " /** %s */\n", $item->{comment}; } + push @header_lines, sprintf " GR_CAN_BUS_%s = %s,\n", uc $const_name, $item->{id}; } push @header_lines, "} GR_CAN_BUS_ID;\n\n"; @@ -100,10 +136,8 @@ sub write_output { my $content = join q{}, @{$lines_ref}; open my $out, '>', $path; - my $success = print {$out} $content; - if ( !$success ) { - die "Failed to write to $path: $OS_ERROR"; - } + print {$out} $content + or die "Failed to write to $path: $OS_ERROR"; close $out; return; diff --git a/Autogen/CAN/Src/CANparser.pl b/Autogen/CAN/Src/CANparser.pl index f8d2cc310..bcd7a1e0c 100755 --- a/Autogen/CAN/Src/CANparser.pl +++ b/Autogen/CAN/Src/CANparser.pl @@ -1,186 +1,241 @@ #!/usr/bin/env perl use strict; use warnings; -use English qw(-no_match_vars); -use YAML::XS qw(LoadFile); +use English qw(-no_match_vars); +use autodie qw(open close); use File::Basename; +use File::Path qw(make_path); -# --- 1. Configuration & Data Loading --- -my $yaml_path = $ARGV[0] // 'format.CANdo'; -my $output_path = $ARGV[1] // 'Custom_CAN_ID.h'; +main(); -if ( !-e $yaml_path ) { - die "Error: $yaml_path not found.\n"; -} - -my $yaml = LoadFile($yaml_path); -my $can_defs = $yaml->{'Custom CAN ID'}; +sub main { + my $yaml_path = $ARGV[0] // q{format.CANdo}; + my $output_path = $ARGV[1] // q{Custom_CAN_ID.h}; -# --- 2. Build the Header Content in Memory --- -# This approach satisfies the 'RequireBriefOpen' linter rule. -my $content = "// Auto-generated Custom CAN ID header\n"; -$content .= "#ifndef CUSTOM_CAN_ID_H\n"; -$content .= "#define CUSTOM_CAN_ID_H\n\n"; -$content .= "typedef enum {\n"; + if ( !-e $yaml_path ) { + die "Error: $yaml_path not found.\n"; + } -for my $msg_name ( sort keys %{$can_defs} ) { - my $entry = $can_defs->{$msg_name}; - if ( ref $entry ne 'HASH' ) { next; } + # 1. Parse the data manually (No YAML::XS dependency needed) + my $can_defs = parse_custom_ids($yaml_path); - my $can_id = $entry->{'CAN ID'}; - if ( !defined $can_id ) { next; } + # 2. Generate the C Header + my $content = "// Auto-generated Custom CAN ID header\n"; + $content .= "#ifndef CUSTOM_CAN_ID_H\n"; + $content .= "#define CUSTOM_CAN_ID_H\n\n"; + $content .= "typedef enum {\n"; - my $enum_name = uc $msg_name; - $enum_name =~ s/[[:^upper:][:digit:]]/_/g; - $enum_name =~ s/_+/_/g; - $enum_name =~ s/^_|_$//g; + # --- TRACKER FOR ISSUE #369 --- + my %seen_enum_names; - my $val = $can_id; - if ( $val =~ /^[[:xdigit:]]+$/ && $val !~ /^[[:digit:]]+$/ ) { - $val = '0x' . lc $val; - } - elsif ( $val =~ /^([[:xdigit:]]+)d$/ ) { - $val = '0x' . lc $1; - } + # Sort keys to keep the header organized + for my $msg_name ( sort keys %{$can_defs} ) { + my $can_id = $can_defs->{$msg_name}; - $content .= " ${enum_name}_CAN_ID = $val,\n"; -} + # Clean the name: spaces to underscores, uppercase + my $enum_name = uc $msg_name; + $enum_name =~ s/[[:^alnum:]]/_/g; + $enum_name =~ s/_+/_/g; + $enum_name =~ s/^_|_$//g; -$content .= "} GRCAN_CUSTOM_ID;\n\n"; -$content .= "#endif // CUSTOM_CAN_ID_H\n"; + # Format the final C identifier + my $full_enum_identifier = "${enum_name}_CAN_ID"; -# --- 3. Brief Open/Write/Close --- -if ( -d $output_path ) { - die "Error: $output_path is a directory."; -} + # --- FIX FOR #369: Skip if this identifier already exists in the enum --- + if ( $seen_enum_names{$full_enum_identifier} ) { + warn "Issue #369: Skipping redefinition of $full_enum_identifier\n"; + next; + } + $seen_enum_names{$full_enum_identifier} = 1; -open my $fh, '>', $output_path or die "Error: $OS_ERROR"; -print {$fh} $content or die "Print failed: $OS_ERROR"; -close $fh or die "Close failed: $OS_ERROR"; + # Format the ID + my $val = $can_id; -# Final print check to satisfy 'RequireCheckedSyscalls' -print "Successfully updated $output_path\n" or die "Final print failed: $OS_ERROR"; + # If it looks like Hex but lacks 0x, add it + if ( $val =~ /^[[:xdigit:]]+$/ && $val !~ /^[[:digit:]]+$/ ) { + $val = '0x' . lc $val; + } -exit 0; + # Handle '10d' style markers + elsif ( $val =~ /^([[:xdigit:]]+)d$/ ) { + $val = '0x' . lc $1; + } -# #!/usr/bin/env perl -# use strict; -# use warnings; -# use fatal qw(open close); # Addresses Linter Error #1 & #5 (Unchecked returns) -# use autodie qw(open close print); -# use YAML::XS 'LoadFile'; -# use File::Basename; + $content .= " $full_enum_identifier = $val,\n"; + } -# # --- Configuration --- -# my $yaml_path = $ARGV[0] // 'format.CANdo'; -# my $output_path = $ARGV[1] // 'Custom_CAN_ID.h'; + $content .= "} GRCAN_CUSTOM_ID;\n\n"; + $content .= "#endif // CUSTOM_CAN_ID_H\n"; -# # 1. Load the data -# if ( !-e $yaml_path ) { -# die "Error: $yaml_path not found.\n"; -# } + # 3. Write out + my $dir = dirname($output_path); + if ( $dir && $dir ne q{.} && !-d $dir ) { + make_path($dir); + } -# my $yaml = LoadFile($yaml_path); -# my $can_defs = $yaml->{'Custom CAN ID'}; - -# # 2. Open the file in WRITE mode -# # autodie handles the "or die" automatically here -# open my $fh, '>', $output_path; - -# print $fh "// Auto-generated Custom CAN ID header\n"; -# print $fh "#ifndef CUSTOM_CAN_ID_H\n"; -# print $fh "#define CUSTOM_CAN_ID_H\n\n"; -# print $fh "typedef enum {\n"; - -# # Sort to keep the header organized -# for my $msg_name ( sort keys %$can_defs ) { -# my $entry = $can_defs->{$msg_name}; -# next unless ref($entry) eq 'HASH'; - -# my $can_id = $entry->{'CAN ID'}; -# next unless defined $can_id; - -# # Clean the name: spaces to underscores, uppercase -# my $enum_name = uc($msg_name); -# $enum_name =~ s/[^A-Z0-9]/_/g; -# $enum_name =~ s/_+/_/g; -# $enum_name =~ s/^_|_$//g; - -# # Format the ID -# my $val = $can_id; -# if ( $val =~ /^[0-9A-Fa-f]+$/ && $val !~ /^\d+$/ ) { -# $val = "0x" . lc($val); -# } -# elsif ( $val =~ /^([0-9A-Fa-f]+)d$/ ) { -# $val = "0x" . lc($1); -# } - -# print $fh " ${enum_name}_CAN_ID = $val,\n"; -# } + open my $fh, '>', $output_path; + print {$fh} $content + or die "Failed to write to $output_path: $OS_ERROR"; + close $fh; -# print $fh "} Custom_CAN_ID_t;\n\n"; -# print $fh "#endif // CUSTOM_CAN_ID_H\n"; + my $log_success = print "Successfully updated $output_path\n"; + if ( !$log_success ) { + die "Failed to write to STDOUT: $OS_ERROR"; + } + return; +} -# close $fh; +sub parse_custom_ids { + my ($path) = @_; + my %defs; + my $in_section = 0; + my $current_msg = q{}; -# print "Successfully updated $output_path\n"; + open my $fh, '<', $path; + _process_custom_id_lines( \%defs, $fh, \$in_section, \$current_msg ); + close $fh; + return \%defs; +} -# # Addresses Linter Error #3 (Explicit return for main script flow) -# exit 0; +sub _process_custom_id_lines { + my ( $defs_ref, $fh, $in_section_ref, $current_msg_ref ) = @_; + + while ( my $line = <$fh> ) { + chomp $line; + + # Detect the start of the "Custom CAN ID" section + if ( $line =~ /^Custom \s CAN \s ID:/ix ) { + ${$in_section_ref} = 1; + next; + } + + # Stop if we hit a different top-level section + if ( ${$in_section_ref} && $line =~ /^\S/ && $line !~ /^Custom/i ) { + last; + } + + if ( !${$in_section_ref} ) { + next; + } + + # Match Message Name (2 spaces) + if ( $line =~ /^\s{2} ([^:#\s][^:]+) :/x ) { + ${$current_msg_ref} = $1; + } + + # Match CAN ID (4 spaces) + elsif ( ${$current_msg_ref} && $line =~ /^\s{4} CAN \s ID: \s* (0x[[:xdigit:]]+ | [[:xdigit:]]+d? | \d+)/ix ) { + $defs_ref->{ ${$current_msg_ref} } = $1; + ${$current_msg_ref} = q{}; # Reset after finding the ID + } + } + return; +} # #!/usr/bin/env perl # use strict; # use warnings; -# use YAML::XS 'LoadFile'; +# use English qw(-no_match_vars); +# use autodie qw(open close); # use File::Basename; +# use File::Path qw(make_path); + +# main(); + +# sub main { +# my $yaml_path = $ARGV[0] // 'format.CANdo'; +# my $output_path = $ARGV[1] // 'Custom_CAN_ID.h'; -# # --- Configuration --- -# my $yaml_path = $ARGV[0] // 'format.CANdo'; -# my $output_path = $ARGV[1] // 'Custom_CAN_ID.h'; +# if ( !-e $yaml_path ) { +# die "Error: $yaml_path not found.\n"; +# } -# # 1. Load the data -# if ( !-e $yaml_path ) { die "Error: $yaml_path not found.\n"; } -# my $yaml = LoadFile($yaml_path); -# my $can_defs = $yaml->{'Custom CAN ID'}; +# # 1. Parse the data manually (No YAML::XS dependency needed) +# my $can_defs = parse_custom_ids($yaml_path); -# # 2. Open the file in WRITE mode ('>') -# # This updates the existing file by overwriting it with fresh data. -# open my $fh, '>', $output_path or die "Error: Cannot open $output_path: $!"; +# # 2. Generate the C Header +# my $content = "// Auto-generated Custom CAN ID header\n"; +# $content .= "#ifndef CUSTOM_CAN_ID_H\n"; +# $content .= "#define CUSTOM_CAN_ID_H\n\n"; +# $content .= "typedef enum {\n"; -# print $fh "// Auto-generated Custom CAN ID header\n"; -# print $fh "#ifndef CUSTOM_CAN_ID_H\n"; -# print $fh "#define CUSTOM_CAN_ID_H\n\n"; +# # Sort keys to keep the header organized +# for my $msg_name ( sort keys %{$can_defs} ) { +# my $can_id = $can_defs->{$msg_name}; -# print $fh "typedef enum {\n"; +# # Clean the name: spaces to underscores, uppercase +# my $enum_name = uc $msg_name; +# $enum_name =~ s/[^A-Z0-9]/_/g; +# $enum_name =~ s/_+/_/g; +# $enum_name =~ s/^_|_$//g; -# # Sort to keep the header organized -# for my $msg_name ( sort keys %$can_defs ) { -# my $entry = $can_defs->{$msg_name}; -# next unless ref($entry) eq 'HASH'; +# # Format the ID +# my $val = $can_id; -# my $can_id = $entry->{'CAN ID'}; -# next unless defined $can_id; +# # If it looks like Hex but lacks 0x, add it +# if ( $val =~ /^[[:xdigit:]]+$/ && $val !~ /^[[:digit:]]+$/ ) { +# $val = '0x' . lc $val; +# } -# # Clean the name: spaces to underscores, uppercase -# my $enum_name = uc($msg_name); -# $enum_name =~ s/[^A-Z0-9]/_/g; -# $enum_name =~ s/_+/_/g; -# $enum_name =~ s/^_|_$//g; +# # Handle '10d' style markers +# elsif ( $val =~ /^([[:xdigit:]]+)d$/ ) { +# $val = '0x' . lc $1; +# } -# # Format the ID (Decimal stays decimal, Hex gets 0x) -# my $val = $can_id; -# if ( $val =~ /^[0-9A-Fa-f]+$/ && $val !~ /^\d+$/ ) { -# $val = "0x" . lc($val); # Handles 'A16' +# $content .= " ${enum_name}_CAN_ID = $val,\n"; # } -# elsif ( $val =~ /^([0-9A-Fa-f]+)d$/ ) { -# $val = "0x" . lc($1); # Handles '10d' + +# $content .= "} GRCAN_CUSTOM_ID;\n\n"; +# $content .= "#endif // CUSTOM_CAN_ID_H\n"; + +# # 3. Write out +# my $dir = dirname($output_path); +# if ( $dir && $dir ne '.' && !-d $dir ) { +# make_path($dir); # } -# print $fh " ${enum_name}_CAN_ID = $val,\n"; -# } +# open my $fh, '>', $output_path; +# print {$fh} $content; +# close $fh; -# print $fh "} Custom_CAN_ID_t;\n\n"; -# print $fh "#endif // CUSTOM_CAN_ID_H\n"; -# close $fh; +# print "Successfully updated $output_path\n"; +# return; +# } -# print "Successfully updated $output_path\n"; +# sub parse_custom_ids { +# my ($path) = @_; +# my %defs; +# my $in_section = 0; +# my $current_msg = ''; + +# open my $fh, '<', $path; +# while ( my $line = <$fh> ) { +# chomp $line; + +# # Detect the start of the "Custom CAN ID" section +# if ( $line =~ /^Custom \s CAN \s ID:/ix ) { +# $in_section = 1; +# next; +# } + +# # Stop if we hit a different top-level section +# if ( $in_section && $line =~ /^\S/ && $line !~ /^Custom/i ) { +# last; +# } + +# next unless $in_section; + +# # Match Message Name (2 spaces) +# if ( $line =~ /^\s{2} ([^:#\s][^:]+) :/x ) { +# $current_msg = $1; +# } + +# # Match CAN ID (4 spaces) +# elsif ( $current_msg && $line =~ /^\s{4} CAN \s ID: \s* (0x[[:xdigit:]]+ | [[:xdigit:]]+d? | \d+)/ix ) { +# $defs{$current_msg} = $1; +# $current_msg = ''; # Reset after finding the ID +# } +# } +# close $fh; +# return \%defs; +# } diff --git a/Autogen/CAN/Src/DBCparser.pl b/Autogen/CAN/Src/DBCparser.pl index f54113d55..a2dab9848 100644 --- a/Autogen/CAN/Src/DBCparser.pl +++ b/Autogen/CAN/Src/DBCparser.pl @@ -373,6 +373,10 @@ sub parse_message_id { if ( $ind == 4 && $line =~ /^ ([^:]+) : /smx ) { my $sig = $1; $sig =~ s/\s+$//smx; + + # Skip if the "signal name" is actually the comment field + return if $sig eq 'comment'; + $state_ref->{cur_sig} = $sig; $data_ref->{messages}{ $state_ref->{cur_msg} }{sigs}{ $state_ref->{cur_sig} } = {}; return; @@ -383,6 +387,9 @@ sub parse_message_id { $k =~ s/\s+$//smx; $v =~ s/\s+$//smx; + # Skip comment fields at the property level + return if $k eq 'comment'; + if ( $k eq 'bit_start' || $k eq 'bit start' ) { $v =~ s/-.*//smx; $data_ref->{messages}{ $state_ref->{cur_msg} }{sigs}{ $state_ref->{cur_sig} }{start} = $v; @@ -417,6 +424,11 @@ sub parse_custom_id { $data_ref->{custom}{ $state_ref->{cur_msg} }{len} = $len; return; } + + # Skip standalone comment fields in custom section + if ( $line =~ /^ comment \s* : /ixsm ) { + return; + } if ( $line =~ /^ [-] \s+ name \s* : \s* ["']? ([^"']+) ["']? /smx ) { my $name = $1; $name =~ s/\s+$//smx; diff --git a/Autogen/CAN/Src/GRparser.pl b/Autogen/CAN/Src/GRparser.pl index 0633f66c0..d79ef535c 100644 --- a/Autogen/CAN/Src/GRparser.pl +++ b/Autogen/CAN/Src/GRparser.pl @@ -73,14 +73,33 @@ sub generate_gr_header_content { push @header_lines, "#define GR_IDS_H\n\n"; push @header_lines, "typedef enum {\n"; + # --- TRACKERS FOR ISSUE #373 --- + my %seen_names; + my %seen_values; + my @sorted = sort { $a->{name} cmp $b->{name} } @{$ids_ref}; for my $item (@sorted) { my $const_name = $item->{name}; $const_name =~ s/[[:^alnum:]]/_/gsmx; + my $val = $item->{id}; + + # --- FIX FOR #373: Skip if name or ID value is already in the list --- + if ( $seen_names{$const_name} ) { + warn "Skipping duplicate Node Name: $const_name\n"; + next; + } + if ( defined $val && $seen_values{$val} ) { + warn "Issue #373: Skipping duplicate Node ID value: $val ($const_name)\n"; + next; + } - if ( defined $item->{id} && $item->{id} ne q{} ) { - push @header_lines, sprintf " %s = %s,\n", $const_name, $item->{id}; + if ( defined $val && $val ne q{} ) { + push @header_lines, sprintf " %s = %s,\n", $const_name, $val; + + # Mark as processed + $seen_names{$const_name} = 1; + $seen_values{$val} = 1; } } @@ -103,3 +122,109 @@ sub write_output_briefly { return; } + +# #!/usr/bin/env perl +# use strict; +# use warnings; +# use File::Basename; +# use File::Path qw(make_path); +# use English qw(-no_match_vars); +# use autodie qw(open close); + +# main(); + +# sub main { +# my $yaml_path = $ARGV[0] // 'format.CANdo'; +# my $output_path = $ARGV[1] // 'GR_IDS.h'; +# my $dir = dirname($output_path); + +# if ( $dir && $dir ne q{.} && !-d $dir ) { +# make_path($dir); +# } + +# if ( !-e $yaml_path ) { +# die "CANfigurator Error: Could not find YAML file at: $yaml_path\n"; +# } + +# my $msg_ids_ref = parse_yaml_briefly($yaml_path); +# my @header_lines = generate_gr_header_content($msg_ids_ref); +# write_output_briefly( $output_path, \@header_lines ); + +# my $log_success = print "CANfigurator: Successfully generated $output_path\n"; +# if ( !$log_success ) { +# die "Failed to write to STDOUT: $OS_ERROR"; +# } +# return; +# } + +# sub parse_yaml_briefly { +# my ($path) = @_; + +# open my $fh, '<', $path; +# my @lines = <$fh>; +# close $fh; + +# my @found_ids; +# my $in_section = 0; + +# for my $line (@lines) { +# if ( $line =~ /^GR[ ]ID:/smx ) { +# $in_section = 1; +# next; +# } +# last if $in_section && $line =~ /^\w/smx; +# next if !$in_section; + +# # Refined regex: match key, colon, then capture value (stripping optional quotes) +# if ( $line =~ /^ \s+ ([^:]+) : \s* ["']? ( [^"'\s#]+ ) ["']? /smx ) { +# my $name = $1; +# my $val = $2; + +# $name =~ s/^\s+|\s+$//gsmx; +# $val =~ s/^\s+|\s+$//gsmx; + +# push @found_ids, { name => $name, id => $val }; +# } +# } +# return \@found_ids; +# } + +# sub generate_gr_header_content { +# my ($ids_ref) = @_; +# my @header_lines; + +# push @header_lines, "// Auto-generated GR ID enum header\n"; +# push @header_lines, "#ifndef GR_IDS_H\n"; +# push @header_lines, "#define GR_IDS_H\n\n"; +# push @header_lines, "typedef enum {\n"; + +# my @sorted = sort { $a->{name} cmp $b->{name} } @{$ids_ref}; + +# for my $item (@sorted) { +# my $const_name = $item->{name}; +# $const_name =~ s/[[:^alnum:]]/_/gsmx; + +# if ( defined $item->{id} && $item->{id} ne q{} ) { +# push @header_lines, sprintf " %s = %s,\n", $const_name, $item->{id}; +# } +# } + +# push @header_lines, "} GRCAN_NODE_ID;\n\n"; +# push @header_lines, "#endif // GR_IDS_H\n"; + +# return @header_lines; +# } + +# sub write_output_briefly { +# my ( $path, $lines_ref ) = @_; +# my $content = join q{}, @{$lines_ref}; + +# open my $out, '>', $path; +# my $success = print {$out} $content; +# if ( !$success ) { +# die "Failed to write to $path: $OS_ERROR"; +# } +# close $out; + +# return; +# } diff --git a/Autogen/CAN/Src/STRUCTparser.pl b/Autogen/CAN/Src/STRUCTparser.pl index 58929f73e..356ce4001 100644 --- a/Autogen/CAN/Src/STRUCTparser.pl +++ b/Autogen/CAN/Src/STRUCTparser.pl @@ -8,17 +8,18 @@ use Readonly; # Brutal-compliant constants -Readonly::Scalar my $BITS_PER_BYTE => 8; -Readonly::Scalar my $CELL_COUNT => 32; -Readonly::Scalar my $EMPTY_STR => q{}; -Readonly::Scalar my $SPACE_STR => q{ }; +Readonly::Scalar my $BITS_PER_BYTE => 8; +Readonly::Scalar my $CELL_COUNT => 32; +Readonly::Scalar my $EMPTY_STR => q{}; +Readonly::Scalar my $SPACE_STR => q{}; +Readonly::Scalar my $PACKED_COMMENT_WRAP => 100; main(); sub main { my $yaml_path = $ARGV[0] // 'format.CANdo'; my $output_path = $ARGV[1] // 'CANDler.h'; - my $prefix = 'GR_OLD'; + my $prefix = 'GRCAN'; ensure_directory_exists($output_path); @@ -41,6 +42,7 @@ sub parse_descriptions { my ($path) = @_; my %map; my $in_msg_section = 0; + my $current_msg = $EMPTY_STR; open my $in, '<', $path; my @lines = <$in>; @@ -61,13 +63,19 @@ sub parse_descriptions { next; } + # Track current message name (matches " Msg Name:") + if ( $line =~ /^\s{2} ([^:#\s][^:]+) :$/smx ) { + $current_msg = $1; + } + # Use explicit \s{2,4} because /x ignores literal spaces if ( $line =~ /^\s{2,4} ([^:#\s][^:]+) :/smx ) { my $raw_name = $1; my $f_name = clean_field_name($raw_name); my ( $desc, $new_i ) = extract_desc_from_array( \@lines, $i ); if ($desc) { - $map{$f_name} = $desc; + my $key = $current_msg . q{::} . $f_name; + $map{$key} = $desc; } $i = $new_i; } @@ -77,23 +85,49 @@ sub parse_descriptions { sub extract_desc_from_array { my ( $lines_ref, $index ) = @_; - my $description = $EMPTY_STR; - my $i = $index; + my $description = q{}; + my $i = $index; + my $in_comment_block = 0; while ( ++$i < scalar @{$lines_ref} ) { my $sub = ${$lines_ref}[$i]; - if ( $sub =~ /^\s+ \# \s* (.*)/smx ) { - my $comment_text = $1; - $description .= $SPACE_STR . $comment_text; + + # 1. Match the start of the comment block + if ( $sub =~ /^\s+ comment: \s* (.*)/smx ) { + my $text = $1; + $in_comment_block = 1; + if ( $text ne q{} ) { + $description .= ( $description ? q{ } : q{} ) . $text; + } + next; } - # Check for new field or message start - if ( $sub =~ /^\s{2,4} [^#\s]/smx || $sub =~ /^\S/smx ) { + # 2. If we are in the block, grab lines that ARE NOT new YAML keys + if ($in_comment_block) { + + # A YAML key usually looks like: " units:" or " data type:" + # This regex says: Stop if the line starts with 4-6 spaces, + # followed by a word, and then a colon + space/newline. + if ( $sub =~ /^\s{4,6} \w+[\w\s]*:(\s|$)/smx ) { + last; + } + + # Otherwise, if it's indented text, it's part of our sentence! + if ( $sub =~ /^\s{6,} (.+)/smx ) { + my $line_text = $1; + $description .= ( $description ? q{ } : q{} ) . $line_text; + next; + } + } + + # 3. Global break if we hit a new message or field entirely + if ( $sub =~ /^\s{0,4} \S/smx ) { last; } } - $description =~ s/^\s+//smx; + # Clean up any trailing/leading whitespace + $description =~ s/^\s+|\s+$//gsmx; return ( $description, $i - 1 ); } @@ -173,7 +207,7 @@ sub parse_field_details { while ( ++$i < scalar @{$lines_ref} ) { my $sub = ${$lines_ref}[$i]; - if ( $sub =~ /bit_start: \s* (\d+)/smx ) { + if ( $sub =~ /bit[\s_]start: \s* (\d+)/smx ) { $start = $1; } if ( $sub =~ /data \s type: \s* (\w+)/smx ) { @@ -198,6 +232,42 @@ sub clean_field_name { return $clean || 'unknown_field'; } +sub _packed_member_comment { + my ( $start_byte, $end_byte, $sorted_fields_ref ) = @_; + my @clauses = map { sprintf 'bit %u: %s;', $_->{start}, clean_field_name( $_->{name} ) } @{$sorted_fields_ref}; + my $head = sprintf 'Packed: bytes %u-%u.', $start_byte, $end_byte; + + if ( !@clauses ) { + return "\t/** $head */\n"; + } + + my @wrap_lines; + my $line = $head; + for my $cl (@clauses) { + my $with = "$line $cl"; + if ( length $with > $PACKED_COMMENT_WRAP && $line !~ /^Packed:/smx ) { + push @wrap_lines, $line; + $line = $cl; + } + elsif ( length $with > $PACKED_COMMENT_WRAP ) { + push @wrap_lines, $line; + $line = $cl; + } + else { + $line = $with; + } + } + push @wrap_lines, $line; + + my $first = shift @wrap_lines; + my $out = "\t/** $first"; + for my $wl (@wrap_lines) { + $out .= "\n\t * $wl"; + } + $out .= " */\n"; + return $out; +} + sub process_message { my ( $name, $f_ref, $d_map, $prefix ) = @_; my @buf; @@ -217,14 +287,14 @@ sub process_message { my @sorted = sort { $a <=> $b } keys %byte_map; for my $i ( 0 .. $#sorted ) { - push @buf, process_byte_entry( \@sorted, \%byte_map, \$i, $d_map ); + push @buf, process_byte_entry( $name, \@sorted, \%byte_map, \$i, $d_map ); } push @buf, "} ${prefix}_${tag}_MSG;\n\n"; return join $EMPTY_STR, @buf; } sub process_byte_entry { - my ( $sorted_ref, $map_ref, $idx_ref, $d_map ) = @_; + my ( $msg_name, $sorted_ref, $map_ref, $idx_ref, $d_map ) = @_; my @out; my $b_idx = ${$sorted_ref}[ ${$idx_ref} ]; my $fields = ${$map_ref}{$b_idx}; @@ -245,7 +315,7 @@ sub process_byte_entry { ( ${$fields}[0]->{type} =~ /32/smx ) ? 'uint32_t' : ( ${$fields}[0]->{type} =~ /16/smx ) ? 'uint16_t' : 'uint8_t'; - my $desc = join $SPACE_STR, map { ${$d_map}{ clean_field_name( $_->{name} ) } // () } @{$fields}; + my $desc = join $SPACE_STR, map { ${$d_map}{ $msg_name . q{::} . clean_field_name( $_->{name} ) } // () } @{$fields}; push @out, sprintf "\t/** %s (Byte %d) */\n\t%-10s %-30s\n", ( $desc || "Byte $b_idx" ), $b_idx, $type, $f_var . q{;}; } @@ -260,17 +330,29 @@ sub handle_multi_field_range { while ( ${$idx_ref} + 1 < scalar @{$bytes_ref} ) { my $next_byte = ${$bytes_ref}[ ${$idx_ref} + 1 ]; my $next_f = ${$map_ref}{$next_byte}; - if ( scalar @{$next_f} <= 2 ) { - my $first_name = ${$next_f}[0]->{name}; - if ( $first_name !~ /reserved/ismx ) { - last; - } + if ( scalar @{$next_f} > 2 || ${$next_f}[0]->{name} =~ /reserved/ismx ) { + ${$idx_ref}++; + } + else { + last; + } + } + + my $end_byte = ${$bytes_ref}[ ${$idx_ref} ]; + my $len = ( $end_byte - $start_byte ) + 1; + + my @span_fields; + for my $b ( $start_byte .. $end_byte ) { + my $bucket = ${$map_ref}{$b}; + if ($bucket) { + push @span_fields, @{$bucket}; } - ${$idx_ref}++; } + my @sorted_span = sort { $a->{start} <=> $b->{start} } @span_fields; - my $len = ( ${$bytes_ref}[ ${$idx_ref} ] - $start_byte ) + 1; - my $v_name = $has_error ? 'error_fault_violation_bits' : 'ping_block'; - my $suffix = ( $len > 1 ) ? "[$len]" : $EMPTY_STR; - return sprintf "\tuint8_t %s%s;\n", $v_name, $suffix; + my $comment = _packed_member_comment( $start_byte, $end_byte, \@sorted_span ); + my $base = $has_error ? 'error_fault_violation_bits' : 'ping_block'; + my $identifier = $base . '_b' . $start_byte; + my $suffix = ( $len > 1 ) ? "[$len]" : $EMPTY_STR; + return $comment . sprintf "\tuint8_t %s%s;\n", $identifier, $suffix; } diff --git a/Web/.gitignore b/Web/.gitignore new file mode 100644 index 000000000..274164774 --- /dev/null +++ b/Web/.gitignore @@ -0,0 +1,2 @@ +WEB_HANDOFF_FULL_SUMMARY.txt +tests/ diff --git a/Web/candoDocument.js b/Web/candoDocument.js new file mode 100644 index 000000000..65df8b27b --- /dev/null +++ b/Web/candoDocument.js @@ -0,0 +1,1308 @@ +// Purpose: Semantic document model for the CANdo format. +// Parses the full file into typed data structures, enforces all cross-section +// invariants (I1–I5 per IMPLEMENTATION_PLAN.md), and exposes atomic operations +// that keep routing + GR ID + Message ID consistent with each other. +// After every mutation, serializes the model back to canonical text and calls +// editor.updateRawText() so editor.js remains the single source of raw text truth. +// +// Sections owned (regenerated on serialize): routing, Message ID, Custom CAN ID, GR ID +// Sections preserved verbatim: Bus ID, byte order +// +// Dual-mode: browser (window.GrcanDocument) or Node.js (module.exports) for tests. + +/* global window, module */ +(function (factory) { + if (typeof module !== "undefined" && module.exports) { + module.exports = factory(); + } else { + window.GrcanDocument = factory(); + } +})(function () { + "use strict"; + + // ==================== Module-level model state ==================== + // All mutable; reset by _parse() at the start of every operation. + + let _devices = new Map(); // Map + let _grIds = new Map(); // Map + let _messageIds = new Map(); // Map + let _busIdsText = ""; // verbatim Bus ID section text + let _byteOrderText = ""; // verbatim byte order line text + let _customCanIds = new Map(); // Map + + // ==================== CAN ID format utilities ==================== + // Custom CAN ID section canonical form: bare uppercase hex, no 0x prefix (e.g. "2416"). + // Routing can_id_override canonical form: 0x-prefixed uppercase hex (e.g. "0x2416"). + // These two utilities are the single point of conversion between the two formats. + + function normalizeCanId(raw) { + const s = String(raw ?? "") + .trim() + .replace(/^0x/i, "") + .toUpperCase(); + return /^[0-9A-F]+$/.test(s) ? s : null; + } + + function toCanIdOverride(bareHex) { + const n = normalizeCanId(bareHex); + return n ? "0x" + n : null; + } + + // ==================== Parser ==================== + + function _parse(rawText) { + _devices = new Map(); + _grIds = new Map(); + _messageIds = new Map(); + _busIdsText = ""; + _byteOrderText = ""; + _customCanIds = new Map(); + + if (!rawText) return; + const lines = rawText.split("\n"); + + // Find 0-indexed start line of each top-level section. + let routingStart = -1, + byteOrderStart = -1, + msgIdStart = -1, + customCanIdStart = -1, + grIdStart = -1; + + for (let i = 0; i < lines.length; i++) { + const l = lines[i]; + if (l.startsWith("routing:")) routingStart = i; + else if (l.startsWith("byte order:")) byteOrderStart = i; + else if (l.startsWith("Message ID:")) msgIdStart = i; + else if (l.startsWith("Custom CAN ID:")) customCanIdStart = i; + else if (l.startsWith("GR ID:")) grIdStart = i; + } + + // Verbatim: Bus ID = everything before routing section header. + if (routingStart > 0) { + _busIdsText = lines.slice(0, routingStart).join("\n").replace(/\n+$/, ""); + } + + // Verbatim: byte order line through the blank line before Message ID. + if (byteOrderStart > -1) { + const end = msgIdStart > -1 ? msgIdStart : lines.length; + _byteOrderText = lines + .slice(byteOrderStart, end) + .join("\n") + .replace(/\n+$/, ""); + } + + // Owned: Custom CAN ID section through the blank line before GR ID. + if (customCanIdStart > -1) { + const end = grIdStart > -1 ? grIdStart : lines.length; + _parseCustomCanIds(lines, customCanIdStart, end); + } + + // Owned sections: parse into model. + if (routingStart > -1) { + const end = + byteOrderStart > -1 + ? byteOrderStart + : msgIdStart > -1 + ? msgIdStart + : lines.length; + _parseRouting(lines, routingStart, end); + } + if (msgIdStart > -1) { + const end = customCanIdStart > -1 ? customCanIdStart : lines.length; + _parseMsgIds(lines, msgIdStart, end); + } + if (grIdStart > -1) { + _parseGrIds(lines, grIdStart, lines.length); + } + } + + function _parseRouting(lines, start, end) { + let curDevice = null, + curBus = null, + curReceiver = null; + + for (let i = start; i < end; i++) { + const line = lines[i]; + if (!line.trim()) continue; + const indent = line.search(/\S/); + const content = line.trim(); + + if (indent === 4 && content.endsWith(":")) { + // Device name. Skip the "messages:" sub-key which is at indent 2. + const name = content.slice(0, -1); + curDevice = { deviceName: name, buses: new Map() }; + _devices.set(name, curDevice); + curBus = null; + curReceiver = null; + } else if (indent === 6 && content.endsWith(":")) { + if (!curDevice) continue; + const busPort = content.slice(0, -1); + curBus = { busPort, receivers: new Map() }; + curDevice.buses.set(busPort, curBus); + curReceiver = null; + } else if (indent === 8 && content.endsWith(":")) { + if (!curBus) continue; + const recName = content.slice(0, -1); + curReceiver = { receiverName: recName, routes: [] }; + curBus.receivers.set(recName, curReceiver); + } else if (indent === 10 && content.startsWith("- msg:")) { + if (!curReceiver) continue; + const msgName = content.slice("- msg:".length).trim(); + let canIdOverride = null; + if (i + 1 < end) { + const next = lines[i + 1]; + const ni = next.search(/\S/); + if (ni === 12 && next.trim().startsWith("can_id_override:")) { + canIdOverride = next.trim().slice("can_id_override:".length).trim(); + i++; + } + } + curReceiver.routes.push({ msgName, canIdOverride }); + } + } + } + + function _parseMsgIds(lines, start, end) { + let curMsg = null, + curField = null; + let _inFieldComment = false; + + function flushField() { + if (curField && curMsg) { + curMsg.fields.push(curField); + } + curField = null; + _inFieldComment = false; + } + function flushMsg() { + flushField(); + if (curMsg) _messageIds.set(curMsg.name, curMsg); + curMsg = null; + } + + for (let i = start; i < end; i++) { + const line = lines[i]; + if (!line.trim()) continue; + const indent = line.search(/\S/); + const content = line.trim(); + + if (indent === 2 && content.endsWith(":")) { + flushMsg(); + _inFieldComment = false; + curMsg = { + name: content.slice(0, -1), + msgId: "", + msgLength: "", + fields: [], + }; + } else if (indent === 4 && curMsg) { + _inFieldComment = false; + if (content.startsWith("MSG ID:")) { + flushField(); + curMsg.msgId = content.slice("MSG ID:".length).trim(); + } else if (content.startsWith("MSG LENGTH:")) { + flushField(); + curMsg.msgLength = content.slice("MSG LENGTH:".length).trim(); + } else if (content.endsWith(":")) { + flushField(); + curField = { + name: content.slice(0, -1), + bitStart: "", + comment: null, + dataType: null, + units: null, + scaledMin: null, + scaledMax: null, + mapEquation: null, + }; + } + } else if (indent >= 6 && curField) { + if (indent === 6) { + // All field keywords live at indent 6 — always reset comment flag here + _inFieldComment = false; + if (content.startsWith("bit_start:")) { + curField.bitStart = content.slice("bit_start:".length).trim(); + } else if (content.startsWith("comment:")) { + const raw = content.slice("comment:".length).trim(); + const inline = raw === "|" || raw === ">" ? "" : raw; + curField.comment = inline || null; + _inFieldComment = true; + } else if (content.startsWith("#")) { + // backward compat: old # comment format + const t = content.slice(1).trim(); + curField.comment = curField.comment + ? curField.comment + "\n" + t + : t; + } else if (content.startsWith("data type:")) { + curField.dataType = content.slice("data type:".length).trim(); + } else if (content.startsWith("units:")) { + curField.units = content.slice("units:".length).trim(); + } else if (content.startsWith("scaled min:")) { + curField.scaledMin = content.slice("scaled min:".length).trim(); + } else if (content.startsWith("scaled max:")) { + curField.scaledMax = content.slice("scaled max:".length).trim(); + } else if (content.startsWith("map equation:")) { + curField.mapEquation = content + .slice("map equation:".length) + .trim() + .replace(/^["']|["']$/g, ""); + } + } else if (_inFieldComment) { + // indent > 6: continuation lines of the comment: block + curField.comment = curField.comment + ? curField.comment + "\n" + content + : content; + } + } + } + flushMsg(); + } + + function _parseGrIds(lines, start, end) { + for (let i = start + 1; i < end; i++) { + const line = lines[i]; + if (!line.trim()) continue; + const indent = line.search(/\S/); + if (indent !== 2) continue; + const colonIdx = line.indexOf(":"); + if (colonIdx <= 0) continue; + const name = line.slice(0, colonIdx).trim(); + if (!name) continue; + const rawVal = line.slice(colonIdx + 1).trim(); + const hexId = rawVal.replace(/^["']|["']$/g, ""); + _grIds.set(name, hexId); + } + } + + function _parseCustomCanIds(lines, start, end) { + let curEntry = null; + let curSignal = null; + let _inSignalComment = false; + + function flushSignal() { + if (curSignal && curEntry) { + curEntry.signals.push(curSignal); + } + curSignal = null; + _inSignalComment = false; + } + function flushEntry() { + flushSignal(); + if (curEntry) _customCanIds.set(curEntry.name, curEntry); + curEntry = null; + } + + for (let i = start; i < end; i++) { + const line = lines[i]; + if (!line.trim()) continue; + const indent = line.search(/\S/); + const content = line.trim(); + + if (indent === 2 && content.endsWith(":")) { + flushEntry(); + _inSignalComment = false; + curEntry = { + name: content.slice(0, -1), + canId: "", + length: "", + signals: [], + }; + } else if (indent === 4 && curEntry) { + _inSignalComment = false; + if (content.startsWith("CAN ID:")) { + curEntry.canId = content.slice("CAN ID:".length).trim(); + } else if (content.startsWith("Length:")) { + curEntry.length = content.slice("Length:".length).trim(); + } else if (content === "signals: []") { + // empty signals array on same line — already empty + } else if (content === "signals:") { + // signals array follows on subsequent lines + } + } else if (indent === 6 && content.startsWith("- name:") && curEntry) { + flushSignal(); // also resets _inSignalComment + let nameVal = content.slice("- name:".length).trim(); + nameVal = nameVal.replace(/^["']|["']$/g, ""); + curSignal = { name: nameVal, bitStart: "", comment: null }; + } else if (indent === 8 && curSignal) { + _inSignalComment = false; + if (content.startsWith("bit_start:")) { + curSignal.bitStart = content.slice("bit_start:".length).trim(); + } else if (content.startsWith("comment:")) { + const raw = content.slice("comment:".length).trim(); + const inline = raw === "|" || raw === ">" ? "" : raw; + curSignal.comment = inline || null; + _inSignalComment = true; + } else if (content.startsWith("#")) { + // backward compat: old # format + const t = content.slice(1).trim(); + curSignal.comment = curSignal.comment + ? curSignal.comment + "\n" + t + : t; + } + } else if (indent > 8 && _inSignalComment && curSignal) { + // continuation lines of the comment: block + curSignal.comment = curSignal.comment + ? curSignal.comment + "\n" + content + : content; + } + } + flushEntry(); + } + + // ==================== Serializer ==================== + + function _serializeRouting() { + let out = "routing:\n messages:\n"; + for (const device of _devices.values()) { + if (device.buses.size === 0) continue; + out += " " + device.deviceName + ":\n"; + for (const bus of device.buses.values()) { + out += " " + bus.busPort + ":\n"; + for (const receiver of bus.receivers.values()) { + out += " " + receiver.receiverName + ":\n"; + for (const route of receiver.routes) { + out += " - msg: " + route.msgName + "\n"; + if (route.canIdOverride) { + out += + " can_id_override: " + route.canIdOverride + "\n"; + } + } + } + } + } + return out; + } + + function _serializeMessageIds() { + let out = "Message ID:\n"; + for (const msg of _messageIds.values()) { + out += " " + msg.name + ":\n"; + out += " MSG ID: " + msg.msgId + "\n"; + out += " MSG LENGTH: " + msg.msgLength + "\n"; + for (const field of msg.fields) { + out += " " + field.name + ":\n"; + out += " bit_start: " + field.bitStart + "\n"; + if (field.comment) { + if (field.comment.includes("\n")) { + out += " comment:\n"; + const lines = field.comment.split("\n"); + if (lines[lines.length - 1] === "") lines.pop(); + for (const line of lines) { + out += " " + line + "\n"; + } + } else { + out += " comment: " + field.comment + "\n"; + } + } + if (field.dataType !== null) { + out += " data type: " + field.dataType + "\n"; + } + if (field.units) out += " units: " + field.units + "\n"; + if (field.scaledMin !== null && field.scaledMin !== "") + out += " scaled min: " + field.scaledMin + "\n"; + if (field.scaledMax !== null && field.scaledMax !== "") + out += " scaled max: " + field.scaledMax + "\n"; + if (field.mapEquation) + out += ' map equation: "' + field.mapEquation + '"\n'; + } + } + return out; + } + + function _serializeCustomCanIds() { + let out = "Custom CAN ID:\n"; + for (const entry of _customCanIds.values()) { + out += " " + entry.name + ":\n"; + out += " CAN ID: " + entry.canId + "\n"; + out += " Length: " + entry.length + "\n"; + if (entry.signals.length === 0) { + out += " signals: []\n"; + } else { + out += " signals:\n"; + for (const sig of entry.signals) { + out += ' - name: "' + sig.name + '"\n'; + out += " bit_start: " + sig.bitStart + "\n"; + if (sig.comment) { + if (sig.comment.includes("\n")) { + out += " comment:\n"; + const lines = sig.comment.split("\n"); + if (lines[lines.length - 1] === "") lines.pop(); + for (const line of lines) { + out += " " + line + "\n"; + } + } else { + out += " comment: " + sig.comment + "\n"; + } + } + } + } + } + return out; + } + + function _serializeGrIds() { + let out = "GR ID:\n\n"; + for (const [name, hexId] of _grIds.entries()) { + out += " " + name + ': "' + hexId + '"\n'; + } + return out; + } + + function _serialize() { + const parts = [ + _busIdsText, + _serializeRouting(), + _byteOrderText, + _serializeMessageIds(), + _serializeCustomCanIds(), + _serializeGrIds(), + ]; + // Strip trailing newlines from each part, join with exactly one blank line, + // add a single trailing newline. + return parts.map((p) => p.replace(/\n+$/, "")).join("\n\n") + "\n"; + } + + // ==================== Validator ==================== + + function _getCustomCanIdNames() { + return new Set(_customCanIds.keys()); + } + + function validate() { + _ensureParsed(); + const results = []; + const customCanIds = _getCustomCanIdNames(); + + // V1: MISSING_GR_ID + for (const name of _devices.keys()) { + if (!_grIds.has(name)) { + results.push({ + severity: "error", + code: "MISSING_GR_ID", + message: `Device "${name}" is in routing but has no GR ID entry`, + context: { device: name }, + }); + } + } + + // V2: ORPHAN_GR_ID + for (const name of _grIds.keys()) { + if (!_devices.has(name)) { + results.push({ + severity: "warning", + code: "ORPHAN_GR_ID", + message: `GR ID entry "${name}" has no corresponding device in routing`, + context: { device: name }, + }); + } + } + + // V3: BROKEN_MSG_REF + for (const device of _devices.values()) { + for (const bus of device.buses.values()) { + for (const receiver of bus.receivers.values()) { + for (const route of receiver.routes) { + if ( + !_messageIds.has(route.msgName) && + !customCanIds.has(route.msgName) + ) { + results.push({ + severity: "error", + code: "BROKEN_MSG_REF", + message: `Route in "${device.deviceName}" > ${bus.busPort} references unknown message "${route.msgName}"`, + context: { + device: device.deviceName, + bus: bus.busPort, + msg: route.msgName, + }, + }); + } + } + } + } + } + + // V4: UNKNOWN_RECEIVER + for (const device of _devices.values()) { + for (const bus of device.buses.values()) { + for (const receiverName of bus.receivers.keys()) { + if (!_grIds.has(receiverName)) { + results.push({ + severity: "warning", + code: "UNKNOWN_RECEIVER", + message: `Receiver "${receiverName}" in "${device.deviceName}" > ${bus.busPort} is not in GR ID`, + context: { + device: device.deviceName, + bus: bus.busPort, + receiver: receiverName, + }, + }); + } + } + } + } + + // V5: DUPLICATE_MSG_ID + const seenMsgIds = new Map(); + for (const msg of _messageIds.values()) { + const norm = msg.msgId.toLowerCase(); + if (seenMsgIds.has(norm)) { + results.push({ + severity: "error", + code: "DUPLICATE_MSG_ID", + message: `MSG ID ${msg.msgId} used by both "${seenMsgIds.get(norm)}" and "${msg.name}"`, + context: { + first: seenMsgIds.get(norm), + second: msg.name, + id: msg.msgId, + }, + }); + } else { + seenMsgIds.set(norm, msg.name); + } + } + + // V6: DUPLICATE_GR_ID + const seenGrIds = new Map(); + for (const [name, hexId] of _grIds.entries()) { + const norm = hexId.toLowerCase(); + if (seenGrIds.has(norm)) { + results.push({ + severity: "warning", + code: "DUPLICATE_GR_ID", + message: `GR ID ${hexId} shared by "${seenGrIds.get(norm)}" and "${name}"`, + context: { first: seenGrIds.get(norm), second: name, id: hexId }, + }); + } else { + seenGrIds.set(norm, name); + } + } + + // V7: EMPTY_DEVICE_BLOCK + for (const device of _devices.values()) { + if (device.buses.size === 0) { + results.push({ + severity: "warning", + code: "EMPTY_DEVICE_BLOCK", + message: `Device "${device.deviceName}" has no bus entries in routing`, + context: { device: device.deviceName }, + }); + } + } + + return results; + } + + // ==================== Editor bridge ==================== + + function _getEditor() { + const g = + typeof window !== "undefined" + ? window + : typeof global !== "undefined" + ? global + : {}; + return g.GrcanEditor || null; + } + + function _ensureParsed() { + const editor = _getEditor(); + if (editor && typeof editor.getRawText === "function") { + _parse(editor.getRawText()); + } + // else: test environment — use state already set by _parseForTest() + } + + // Wraps a mutation fn: parse from editor → run fn → serialize back to editor. + // fn() returns an OpResult. If ok is false, setRawText is NOT called. + function _withEditor(fn) { + const editor = _getEditor(); + if (!editor) { + return { ok: false, error: "GrcanEditor not available" }; + } + _parse(editor.getRawText()); + const result = fn(); + if (result.ok !== false) { + editor.updateRawText(_serialize()); + } + return result; + } + + // ==================== Operations ==================== + + function addDevice(name, grId) { + return _withEditor(() => { + if (!name || !name.trim()) + return { ok: false, error: "Device name is required" }; + if (name.trim().toUpperCase() === "ALL") + return { + ok: false, + error: + '"ALL" is a reserved broadcast receiver and cannot be used as a device name', + }; + if (!grId || !/^0x[0-9a-fA-F]+$/i.test(grId.trim())) + return { + ok: false, + error: "GR ID must be a hex value (e.g. 0x2B)", + }; + const n = name.trim(), + g = grId.trim(); + if (_devices.has(n)) + return { ok: false, error: `Device "${n}" already exists in routing` }; + if (_grIds.has(n)) + return { + ok: false, + error: `A GR ID entry for "${n}" already exists`, + }; + _devices.set(n, { deviceName: n, buses: new Map() }); + _grIds.set(n, g); + return { ok: true, warnings: [] }; + }); + } + + function deleteDevice(name) { + return _withEditor(() => { + if (!name) return { ok: false, error: "Device name is required" }; + const warnings = []; + _devices.delete(name); + _grIds.delete(name); + + // Receiver ref sweep — snapshot keys first to avoid mutation-during-iteration. + for (const device of [..._devices.values()]) { + for (const [busPort, bus] of [...device.buses.entries()]) { + if (bus.receivers.has(name)) { + bus.receivers.delete(name); + warnings.push( + `Removed receiver reference to "${name}" from ${device.deviceName} > ${busPort}`, + ); + if (bus.receivers.size === 0) { + device.buses.delete(busPort); + } + } + } + } + return { ok: true, warnings }; + }); + } + + function renameDevice(oldName, newName) { + return _withEditor(() => { + if (!oldName || !newName) + return { ok: false, error: "Both names are required" }; + if (oldName === newName) return { ok: true, warnings: [] }; + if (!_devices.has(oldName)) + return { ok: false, error: `Device "${oldName}" not found` }; + if (_devices.has(newName)) + return { + ok: false, + error: `Device "${newName}" already exists`, + }; + if (_grIds.has(newName)) + return { + ok: false, + error: `GR ID entry for "${newName}" already exists`, + }; + + // Rebuild _devices map preserving insertion order. + const newDevices = new Map(); + for (const [k, v] of _devices) { + if (k === oldName) { + v.deviceName = newName; + newDevices.set(newName, v); + } else { + newDevices.set(k, v); + } + } + _devices = newDevices; + + // Rebuild _grIds map preserving insertion order. + const newGrIds = new Map(); + for (const [k, v] of _grIds) { + newGrIds.set(k === oldName ? newName : k, v); + } + _grIds = newGrIds; + + // Receiver ref sweep across all remaining devices. + for (const device of _devices.values()) { + for (const bus of device.buses.values()) { + if (bus.receivers.has(oldName)) { + const block = bus.receivers.get(oldName); + block.receiverName = newName; + const newReceivers = new Map(); + for (const [k, v] of bus.receivers) { + newReceivers.set(k === oldName ? newName : k, v); + } + bus.receivers = newReceivers; + } + } + } + + return { ok: true, warnings: [] }; + }); + } + + function addBus(deviceName, busPort) { + return _withEditor(() => { + deviceName = (deviceName || "").trim(); + busPort = (busPort || "").trim(); + if (!deviceName) return { ok: false, error: "Device name is required" }; + if (!["CAN1", "CAN2", "CAN3"].includes(busPort)) + return { ok: false, error: "Bus must be CAN1, CAN2, or CAN3" }; + + const warnings = []; + let device = _devices.get(deviceName); + if (!device) { + // Node exists in GR ID catalog but has no routing block yet — create stub. + _devices.set(deviceName, { deviceName, buses: new Map() }); + device = _devices.get(deviceName); + } + if (!_grIds.has(deviceName)) + warnings.push(`Device "${deviceName}" has no GR ID entry.`); + if (device.buses.has(busPort)) + return { ok: false, error: "Bus already exists for this node" }; + + device.buses.set(busPort, { busPort, receivers: new Map() }); + return { ok: true, warnings }; + }); + } + + function addRoute(deviceName, busPort, receiverName, msgName, canIdOverride) { + return _withEditor(() => { + const warnings = []; + if (!deviceName) return { ok: false, error: "Device name is required" }; + if (deviceName.trim().toUpperCase() === "ALL") + return { + ok: false, + error: + '"ALL" is a reserved broadcast receiver and cannot be used as a sender device', + }; + if (!["CAN1", "CAN2", "CAN3"].includes(busPort)) + return { ok: false, error: "Bus must be CAN1, CAN2, or CAN3" }; + if (!receiverName) + return { ok: false, error: "Receiver name is required" }; + if (!msgName) return { ok: false, error: "Message name is required" }; + + const customCanIds = _getCustomCanIdNames(); + if (!_messageIds.has(msgName) && !customCanIds.has(msgName)) { + return { + ok: false, + error: `Message "${msgName}" not found in Message ID or Custom CAN ID`, + }; + } + if (!_grIds.has(deviceName)) + warnings.push( + `Device "${deviceName}" has no GR ID entry. Use addDevice first.`, + ); + if (!_grIds.has(receiverName)) + warnings.push(`Receiver "${receiverName}" is not a known device.`); + + const ovr = canIdOverride || null; + + // Idempotency check. + const existDev = _devices.get(deviceName); + if (existDev) { + const existBus = existDev.buses.get(busPort); + if (existBus) { + const existRec = existBus.receivers.get(receiverName); + if ( + existRec && + existRec.routes.some( + (r) => + r.msgName === msgName && + normalizeCanId(r.canIdOverride) === normalizeCanId(ovr), + ) + ) { + return { ok: true, warnings }; + } + } + } + + if (!_devices.has(deviceName)) { + _devices.set(deviceName, { deviceName, buses: new Map() }); + } + const device = _devices.get(deviceName); + if (!device.buses.has(busPort)) { + device.buses.set(busPort, { busPort, receivers: new Map() }); + } + const bus = device.buses.get(busPort); + if (!bus.receivers.has(receiverName)) { + bus.receivers.set(receiverName, { receiverName, routes: [] }); + } + bus.receivers + .get(receiverName) + .routes.push({ msgName, canIdOverride: ovr }); + + return { ok: true, warnings }; + }); + } + + function deleteRouteEntry(deviceName, busPort, msgName) { + return _withEditor(() => { + const device = _devices.get(deviceName); + if (!device) return { ok: true, warnings: [] }; + const bus = device.buses.get(busPort); + if (!bus) return { ok: true, warnings: [] }; + + for (const [recName, receiver] of [...bus.receivers.entries()]) { + receiver.routes = receiver.routes.filter((r) => r.msgName !== msgName); + if (receiver.routes.length === 0) { + bus.receivers.delete(recName); + } + } + if (bus.receivers.size === 0) { + device.buses.delete(busPort); + } + return { ok: true, warnings: [] }; + }); + } + + function deleteRouteFromReceiver(deviceName, busPort, receiverName, msgName) { + return _withEditor(() => { + const device = _devices.get(deviceName); + if (!device) return { ok: true, warnings: [] }; + const bus = device.buses.get(busPort); + if (!bus) return { ok: true, warnings: [] }; + const receiver = bus.receivers.get(receiverName); + if (!receiver) return { ok: true, warnings: [] }; + receiver.routes = receiver.routes.filter((r) => r.msgName !== msgName); + if (receiver.routes.length === 0) bus.receivers.delete(receiverName); + if (bus.receivers.size === 0) device.buses.delete(busPort); + return { ok: true, warnings: [] }; + }); + } + + function getRouteReceivers(deviceName, busPort, msgName) { + const editor = _getEditor(); + if (!editor) return []; + _parse(editor.getRawText()); + const device = _devices.get(deviceName); + if (!device) return []; + const bus = device.buses.get(busPort); + if (!bus) return []; + const result = []; + for (const receiver of bus.receivers.values()) { + const route = receiver.routes.find((r) => r.msgName === msgName); + if (route) + result.push({ + receiverName: receiver.receiverName, + canIdOverride: route.canIdOverride, + }); + } + return result; + } + + function deleteBusBlock(deviceName, busPort) { + return _withEditor(() => { + const device = _devices.get(deviceName); + if (!device) return { ok: true, warnings: [] }; + device.buses.delete(busPort); + return { ok: true, warnings: [] }; + }); + } + + function addMessageDef(def) { + return _withEditor(() => { + if (!def || !def.name) + return { ok: false, error: "Message name is required" }; + if (_messageIds.has(def.name)) + return { + ok: false, + error: `Message "${def.name}" already exists`, + }; + if (_customCanIds.has(def.name)) + return { + ok: false, + error: `Name "${def.name}" already exists in Custom CAN ID section`, + }; + if (!/^0x[0-9a-fA-F]+$/i.test(def.msgId)) + return { ok: false, error: "MSG ID must be hex (e.g. 0x003)" }; + const normId = def.msgId.toLowerCase(); + for (const msg of _messageIds.values()) { + if (msg.msgId.toLowerCase() === normId) { + return { + ok: false, + error: `MSG ID ${def.msgId} is already used by "${msg.name}"`, + }; + } + } + _messageIds.set(def.name, def); + return { ok: true, warnings: [] }; + }); + } + + function updateMessageDef(oldName, def) { + return _withEditor(() => { + if (!_messageIds.has(oldName)) + return { ok: false, error: `Message "${oldName}" not found` }; + if (!def || !def.name) + return { ok: false, error: "Message name is required" }; + if (def.name !== oldName && _messageIds.has(def.name)) + return { + ok: false, + error: `Message "${def.name}" already exists`, + }; + + const normId = def.msgId.toLowerCase(); + for (const [k, msg] of _messageIds) { + if (k !== oldName && msg.msgId.toLowerCase() === normId) { + return { + ok: false, + error: `MSG ID ${def.msgId} is already used by "${k}"`, + }; + } + } + + if (def.name === oldName) { + _messageIds.set(oldName, def); + } else { + // Rename: rebuild map preserving insertion order. + const newMsgIds = new Map(); + for (const [k, v] of _messageIds) { + newMsgIds.set(k === oldName ? def.name : k, k === oldName ? def : v); + } + _messageIds = newMsgIds; + + // Route ref sweep. + for (const device of _devices.values()) { + for (const bus of device.buses.values()) { + for (const receiver of bus.receivers.values()) { + for (const route of receiver.routes) { + if (route.msgName === oldName) route.msgName = def.name; + } + } + } + } + } + + return { ok: true, warnings: [] }; + }); + } + + // ==================== Custom CAN ID mutations ==================== + + function addCustomCanIdDef(def) { + return _withEditor(() => { + if (!def || !def.name) + return { ok: false, error: "Message name is required" }; + if (_customCanIds.has(def.name)) + return { + ok: false, + error: `Custom CAN ID "${def.name}" already exists`, + }; + if (_messageIds.has(def.name)) + return { + ok: false, + error: `Name "${def.name}" already exists in Message ID section`, + }; + if (!def.canId || !def.canId.trim()) + return { ok: false, error: "CAN ID is required" }; + if (!/^[0-9a-fA-F]+$/i.test(def.canId.trim())) + return { + ok: false, + error: "CAN ID must be a valid hex value (e.g. 116 or 18FF50E5)", + }; + if ( + !def.length || + isNaN(parseInt(def.length, 10)) || + parseInt(def.length, 10) < 0 + ) + return { ok: false, error: "Length must be a non-negative integer" }; + _customCanIds.set(def.name, { + name: def.name, + canId: normalizeCanId(def.canId), + length: String(parseInt(def.length, 10)), + signals: (def.signals || []).map((s) => ({ + name: s.name, + bitStart: s.bitStart, + comment: s.comment || null, + })), + }); + return { ok: true, warnings: [] }; + }); + } + + function updateCustomCanIdDef(oldName, def) { + return _withEditor(() => { + if (!_customCanIds.has(oldName)) + return { + ok: false, + error: `Custom CAN ID "${oldName}" not found`, + }; + if (!def || !def.name) + return { ok: false, error: "Message name is required" }; + if (def.name !== oldName && _customCanIds.has(def.name)) + return { + ok: false, + error: `Custom CAN ID "${def.name}" already exists`, + }; + if (def.name !== oldName && _messageIds.has(def.name)) + return { + ok: false, + error: `Name "${def.name}" already exists in Message ID section`, + }; + if (!def.canId || !def.canId.trim()) + return { ok: false, error: "CAN ID is required" }; + if (!/^[0-9a-fA-F]+$/i.test(def.canId.trim())) + return { + ok: false, + error: "CAN ID must be a valid hex value (e.g. 116 or 18FF50E5)", + }; + if ( + !def.length || + isNaN(parseInt(def.length, 10)) || + parseInt(def.length, 10) < 0 + ) + return { ok: false, error: "Length must be a non-negative integer" }; + + const oldCanId = normalizeCanId(_customCanIds.get(oldName).canId); + const newCanId = normalizeCanId(def.canId); + + const newEntry = { + name: def.name, + canId: newCanId, + length: String(parseInt(def.length, 10)), + signals: (def.signals || []).map((s) => ({ + name: s.name, + bitStart: s.bitStart, + comment: s.comment || null, + })), + }; + + if (def.name === oldName) { + _customCanIds.set(oldName, newEntry); + } else { + // Rename: rebuild map preserving insertion order. + const newMap = new Map(); + for (const [k, v] of _customCanIds) { + newMap.set( + k === oldName ? def.name : k, + k === oldName ? newEntry : v, + ); + } + _customCanIds = newMap; + + // Route msgName ref sweep. + for (const device of _devices.values()) { + for (const bus of device.buses.values()) { + for (const receiver of bus.receivers.values()) { + for (const route of receiver.routes) { + if (route.msgName === oldName) route.msgName = def.name; + } + } + } + } + } + + // canIdOverride sweep: update all routing overrides that matched the old + // CAN ID so the two sections stay in sync when the CAN ID value changes. + if (oldCanId !== newCanId) { + const oldOverride = toCanIdOverride(oldCanId); + const newOverride = toCanIdOverride(newCanId); + for (const device of _devices.values()) { + for (const bus of device.buses.values()) { + for (const receiver of bus.receivers.values()) { + for (const route of receiver.routes) { + if ( + route.msgName === def.name && + route.canIdOverride === oldOverride + ) { + route.canIdOverride = newOverride; + } + } + } + } + } + } + + return { ok: true, warnings: [] }; + }); + } + + function deleteCustomCanIdDef(name) { + return _withEditor(() => { + if (!name) return { ok: false, error: "Message name is required" }; + const warnings = []; + _customCanIds.delete(name); + + // Sweep routing references. + for (const device of _devices.values()) { + for (const bus of device.buses.values()) { + for (const [recName, receiver] of [...bus.receivers.entries()]) { + const before = receiver.routes.length; + receiver.routes = receiver.routes.filter((r) => r.msgName !== name); + if (receiver.routes.length < before) { + warnings.push( + `Removed route to "${name}" from ${device.deviceName} > ${bus.busPort} > ${recName}`, + ); + } + if (receiver.routes.length === 0) { + bus.receivers.delete(recName); + } + } + if (bus.receivers.size === 0) { + device.buses.delete(bus.busPort); + } + } + } + + return { ok: true, warnings }; + }); + } + + // ==================== Read-only accessors ==================== + + function deviceExists(name) { + _ensureParsed(); + return _devices.has(name); + } + + function grIdExists(name) { + _ensureParsed(); + return _grIds.has(name); + } + + function getDeviceNames() { + _ensureParsed(); + return [..._devices.keys()]; + } + + function getGrIds() { + _ensureParsed(); + return new Map(_grIds); + } + + function getGrId(name) { + _ensureParsed(); + return _grIds.get(name) || null; + } + + function getMessageDef(name) { + _ensureParsed(); + return _messageIds.get(name) || null; + } + + function getMessageIdNames() { + _ensureParsed(); + return [..._messageIds.keys()]; + } + + function getCustomCanIdDef(name) { + _ensureParsed(); + return _customCanIds.get(name) || null; + } + + function getCustomCanIdNames() { + _ensureParsed(); + return [..._customCanIds.keys()]; + } + + function getGraphDataForBus(busPort) { + _ensureParsed(); + const nodeSet = new Set(); + const edgeMap = new Map(); + for (const [senderName, device] of _devices) { + const busBlock = device.buses.get(busPort); + if (!busBlock) continue; + nodeSet.add(senderName); + for (const [receiverName, receiverBlock] of busBlock.receivers) { + nodeSet.add(receiverName); + const key = `${senderName}__${receiverName}`; + const msgs = receiverBlock.routes.map((r) => r.msgName); + edgeMap.set(key, { + id: key, + source: senderName, + target: receiverName, + messages: msgs, + count: msgs.length, + }); + } + } + const nodes = [...nodeSet].map((id) => ({ + id, + label: id, + grId: _grIds.get(id) || null, + })); + const edges = [...edgeMap.values()]; + return { nodes, edges }; + } + + function routeEntryExists(device, bus, receiver, msg, canIdOverride) { + _ensureParsed(); + const dev = _devices.get(device); + if (!dev) return false; + const b = dev.buses.get(bus); + if (!b) return false; + const rec = b.receivers.get(receiver); + if (!rec) return false; + return rec.routes.some( + (r) => + r.msgName === msg && + normalizeCanId(r.canIdOverride) === + normalizeCanId(canIdOverride || null), + ); + } + + // ==================== Test helpers ==================== + // Exposed only for Node.js test environment. + + function _parseForTest(text) { + _parse(text); + return { + devices: _devices, + grIds: _grIds, + messageIds: _messageIds, + customCanIds: _customCanIds, + }; + } + + function _serializeFromState() { + return _serialize(); + } + + // Returns the canonical serialized form of the current editor text. + // Parse → serialize without side effects (does not update editor state). + function getSerializedText() { + const editor = _getEditor(); + if (!editor) return null; + _parse(editor.getRawText()); + return _serialize(); + } + + // ==================== Public API ==================== + + return { + // Mutations + addDevice, + deleteDevice, + renameDevice, + addBus, + addRoute, + deleteRouteEntry, + deleteRouteFromReceiver, + deleteBusBlock, + addMessageDef, + updateMessageDef, + addCustomCanIdDef, + updateCustomCanIdDef, + deleteCustomCanIdDef, + // Validation + validate, + // Read-only + deviceExists, + grIdExists, + getDeviceNames, + getGrIds, + getGrId, + getMessageDef, + getMessageIdNames, + getCustomCanIdDef, + getCustomCanIdNames, + routeEntryExists, + getRouteReceivers, + getGraphDataForBus, + getSerializedText, + // Test hooks + _parseForTest, + _serializeFromState, + }; +}); diff --git a/Web/cytoscape.min.js b/Web/cytoscape.min.js new file mode 100644 index 000000000..5db0c4b6a --- /dev/null +++ b/Web/cytoscape.min.js @@ -0,0 +1,21913 @@ +/** + * Copyright (c) 2016-2024, The Cytoscape Consortium. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the “Software”), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +!(function (e, t) { + "object" == typeof exports && "undefined" != typeof module + ? (module.exports = t()) + : "function" == typeof define && define.amd + ? define(t) + : ((e = + "undefined" != typeof globalThis ? globalThis : e || self).cytoscape = + t()); +})(this, function () { + "use strict"; + function e(t) { + return (e = + "function" == typeof Symbol && "symbol" == typeof Symbol.iterator + ? function (e) { + return typeof e; + } + : function (e) { + return e && + "function" == typeof Symbol && + e.constructor === Symbol && + e !== Symbol.prototype + ? "symbol" + : typeof e; + })(t); + } + function t(e, t) { + if (!(e instanceof t)) + throw new TypeError("Cannot call a class as a function"); + } + function n(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + ((r.enumerable = r.enumerable || !1), + (r.configurable = !0), + "value" in r && (r.writable = !0), + Object.defineProperty(e, r.key, r)); + } + } + function r(e, t, r) { + return ( + t && n(e.prototype, t), + r && n(e, r), + Object.defineProperty(e, "prototype", { writable: !1 }), + e + ); + } + function i(e, t, n) { + return ( + t in e + ? Object.defineProperty(e, t, { + value: n, + enumerable: !0, + configurable: !0, + writable: !0, + }) + : (e[t] = n), + e + ); + } + function a(e, t) { + return ( + (function (e) { + if (Array.isArray(e)) return e; + })(e) || + (function (e, t) { + var n = + null == e + ? null + : ("undefined" != typeof Symbol && e[Symbol.iterator]) || + e["@@iterator"]; + if (null == n) return; + var r, + i, + a = [], + o = !0, + s = !1; + try { + for ( + n = n.call(e); + !(o = (r = n.next()).done) && + (a.push(r.value), !t || a.length !== t); + o = !0 + ); + } catch (e) { + ((s = !0), (i = e)); + } finally { + try { + o || null == n.return || n.return(); + } finally { + if (s) throw i; + } + } + return a; + })(e, t) || + o(e, t) || + (function () { + throw new TypeError( + "Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.", + ); + })() + ); + } + function o(e, t) { + if (e) { + if ("string" == typeof e) return s(e, t); + var n = Object.prototype.toString.call(e).slice(8, -1); + return ( + "Object" === n && e.constructor && (n = e.constructor.name), + "Map" === n || "Set" === n + ? Array.from(e) + : "Arguments" === n || + /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) + ? s(e, t) + : void 0 + ); + } + } + function s(e, t) { + (null == t || t > e.length) && (t = e.length); + for (var n = 0, r = new Array(t); n < t; n++) r[n] = e[n]; + return r; + } + function l(e, t) { + var n = + ("undefined" != typeof Symbol && e[Symbol.iterator]) || e["@@iterator"]; + if (!n) { + if ( + Array.isArray(e) || + (n = o(e)) || + (t && e && "number" == typeof e.length) + ) { + n && (e = n); + var r = 0, + i = function () {}; + return { + s: i, + n: function () { + return r >= e.length ? { done: !0 } : { done: !1, value: e[r++] }; + }, + e: function (e) { + throw e; + }, + f: i, + }; + } + throw new TypeError( + "Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.", + ); + } + var a, + s = !0, + l = !1; + return { + s: function () { + n = n.call(e); + }, + n: function () { + var e = n.next(); + return ((s = e.done), e); + }, + e: function (e) { + ((l = !0), (a = e)); + }, + f: function () { + try { + s || null == n.return || n.return(); + } finally { + if (l) throw a; + } + }, + }; + } + var u = "undefined" == typeof window ? null : window, + c = u ? u.navigator : null; + u && u.document; + var d = e(""), + h = e({}), + p = e(function () {}), + f = "undefined" == typeof HTMLElement ? "undefined" : e(HTMLElement), + g = function (e) { + return e && e.instanceString && y(e.instanceString) + ? e.instanceString() + : null; + }, + v = function (t) { + return null != t && e(t) == d; + }, + y = function (t) { + return null != t && e(t) === p; + }, + m = function (e) { + return ( + !E(e) && + (Array.isArray ? Array.isArray(e) : null != e && e instanceof Array) + ); + }, + b = function (t) { + return null != t && e(t) === h && !m(t) && t.constructor === Object; + }, + x = function (t) { + return null != t && e(t) === e(1) && !isNaN(t); + }, + w = function (e) { + return "undefined" === f ? void 0 : null != e && e instanceof HTMLElement; + }, + E = function (e) { + return k(e) || C(e); + }, + k = function (e) { + return "collection" === g(e) && e._private.single; + }, + C = function (e) { + return "collection" === g(e) && !e._private.single; + }, + S = function (e) { + return "core" === g(e); + }, + P = function (e) { + return "stylesheet" === g(e); + }, + D = function (e) { + return null == e || !("" !== e && !e.match(/^\s+$/)); + }, + T = function (t) { + return ( + (function (t) { + return null != t && e(t) === h; + })(t) && y(t.then) + ); + }, + _ = function (e, t) { + t || + (t = function () { + if (1 === arguments.length) return arguments[0]; + if (0 === arguments.length) return "undefined"; + for (var e = [], t = 0; t < arguments.length; t++) + e.push(arguments[t]); + return e.join("$"); + }); + var n = function n() { + var r, + i = this, + a = arguments, + o = t.apply(i, a), + s = n.cache; + return ((r = s[o]) || (r = s[o] = e.apply(i, a)), r); + }; + return ((n.cache = {}), n); + }, + M = _(function (e) { + return e.replace(/([A-Z])/g, function (e) { + return "-" + e.toLowerCase(); + }); + }), + B = _(function (e) { + return e.replace(/(-\w)/g, function (e) { + return e[1].toUpperCase(); + }); + }), + N = _( + function (e, t) { + return e + t[0].toUpperCase() + t.substring(1); + }, + function (e, t) { + return e + "$" + t; + }, + ), + z = function (e) { + return D(e) ? e : e.charAt(0).toUpperCase() + e.substring(1); + }, + I = "(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))", + A = function (e, t) { + return e < t ? -1 : e > t ? 1 : 0; + }, + L = + null != Object.assign + ? Object.assign.bind(Object) + : function (e) { + for (var t = arguments, n = 1; n < t.length; n++) { + var r = t[n]; + if (null != r) + for (var i = Object.keys(r), a = 0; a < i.length; a++) { + var o = i[a]; + e[o] = r[o]; + } + } + return e; + }, + O = function (e) { + return ( + (m(e) ? e : null) || + (function (e) { + return R[e.toLowerCase()]; + })(e) || + (function (e) { + if ((4 === e.length || 7 === e.length) && "#" === e[0]) { + var t, n, r; + return ( + 4 === e.length + ? ((t = parseInt(e[1] + e[1], 16)), + (n = parseInt(e[2] + e[2], 16)), + (r = parseInt(e[3] + e[3], 16))) + : ((t = parseInt(e[1] + e[2], 16)), + (n = parseInt(e[3] + e[4], 16)), + (r = parseInt(e[5] + e[6], 16))), + [t, n, r] + ); + } + })(e) || + (function (e) { + var t, + n = new RegExp( + "^rgb[a]?\\(((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%]?)\\s*,\\s*((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%]?)\\s*,\\s*((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%]?)(?:\\s*,\\s*((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))))?\\)$", + ).exec(e); + if (n) { + t = []; + for (var r = [], i = 1; i <= 3; i++) { + var a = n[i]; + if ( + ("%" === a[a.length - 1] && (r[i] = !0), + (a = parseFloat(a)), + r[i] && (a = (a / 100) * 255), + a < 0 || a > 255) + ) + return; + t.push(Math.floor(a)); + } + var o = r[1] || r[2] || r[3], + s = r[1] && r[2] && r[3]; + if (o && !s) return; + var l = n[4]; + if (void 0 !== l) { + if ((l = parseFloat(l)) < 0 || l > 1) return; + t.push(l); + } + } + return t; + })(e) || + (function (e) { + var t, n, r, i, a, o, s, l; + function u(e, t, n) { + return ( + n < 0 && (n += 1), + n > 1 && (n -= 1), + n < 1 / 6 + ? e + 6 * (t - e) * n + : n < 0.5 + ? t + : n < 2 / 3 + ? e + (t - e) * (2 / 3 - n) * 6 + : e + ); + } + var c = new RegExp( + "^hsl[a]?\\(((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?)))\\s*,\\s*((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%])\\s*,\\s*((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%])(?:\\s*,\\s*((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))))?\\)$", + ).exec(e); + if (c) { + if ( + ((n = parseInt(c[1])) < 0 + ? (n = (360 - ((-1 * n) % 360)) % 360) + : n > 360 && (n %= 360), + (n /= 360), + (r = parseFloat(c[2])) < 0 || r > 100) + ) + return; + if (((r /= 100), (i = parseFloat(c[3])) < 0 || i > 100)) return; + if ( + ((i /= 100), + void 0 !== (a = c[4]) && ((a = parseFloat(a)) < 0 || a > 1)) + ) + return; + if (0 === r) o = s = l = Math.round(255 * i); + else { + var d = i < 0.5 ? i * (1 + r) : i + r - i * r, + h = 2 * i - d; + ((o = Math.round(255 * u(h, d, n + 1 / 3))), + (s = Math.round(255 * u(h, d, n))), + (l = Math.round(255 * u(h, d, n - 1 / 3)))); + } + t = [o, s, l, a]; + } + return t; + })(e) + ); + }, + R = { + transparent: [0, 0, 0, 0], + aliceblue: [240, 248, 255], + antiquewhite: [250, 235, 215], + aqua: [0, 255, 255], + aquamarine: [127, 255, 212], + azure: [240, 255, 255], + beige: [245, 245, 220], + bisque: [255, 228, 196], + black: [0, 0, 0], + blanchedalmond: [255, 235, 205], + blue: [0, 0, 255], + blueviolet: [138, 43, 226], + brown: [165, 42, 42], + burlywood: [222, 184, 135], + cadetblue: [95, 158, 160], + chartreuse: [127, 255, 0], + chocolate: [210, 105, 30], + coral: [255, 127, 80], + cornflowerblue: [100, 149, 237], + cornsilk: [255, 248, 220], + crimson: [220, 20, 60], + cyan: [0, 255, 255], + darkblue: [0, 0, 139], + darkcyan: [0, 139, 139], + darkgoldenrod: [184, 134, 11], + darkgray: [169, 169, 169], + darkgreen: [0, 100, 0], + darkgrey: [169, 169, 169], + darkkhaki: [189, 183, 107], + darkmagenta: [139, 0, 139], + darkolivegreen: [85, 107, 47], + darkorange: [255, 140, 0], + darkorchid: [153, 50, 204], + darkred: [139, 0, 0], + darksalmon: [233, 150, 122], + darkseagreen: [143, 188, 143], + darkslateblue: [72, 61, 139], + darkslategray: [47, 79, 79], + darkslategrey: [47, 79, 79], + darkturquoise: [0, 206, 209], + darkviolet: [148, 0, 211], + deeppink: [255, 20, 147], + deepskyblue: [0, 191, 255], + dimgray: [105, 105, 105], + dimgrey: [105, 105, 105], + dodgerblue: [30, 144, 255], + firebrick: [178, 34, 34], + floralwhite: [255, 250, 240], + forestgreen: [34, 139, 34], + fuchsia: [255, 0, 255], + gainsboro: [220, 220, 220], + ghostwhite: [248, 248, 255], + gold: [255, 215, 0], + goldenrod: [218, 165, 32], + gray: [128, 128, 128], + grey: [128, 128, 128], + green: [0, 128, 0], + greenyellow: [173, 255, 47], + honeydew: [240, 255, 240], + hotpink: [255, 105, 180], + indianred: [205, 92, 92], + indigo: [75, 0, 130], + ivory: [255, 255, 240], + khaki: [240, 230, 140], + lavender: [230, 230, 250], + lavenderblush: [255, 240, 245], + lawngreen: [124, 252, 0], + lemonchiffon: [255, 250, 205], + lightblue: [173, 216, 230], + lightcoral: [240, 128, 128], + lightcyan: [224, 255, 255], + lightgoldenrodyellow: [250, 250, 210], + lightgray: [211, 211, 211], + lightgreen: [144, 238, 144], + lightgrey: [211, 211, 211], + lightpink: [255, 182, 193], + lightsalmon: [255, 160, 122], + lightseagreen: [32, 178, 170], + lightskyblue: [135, 206, 250], + lightslategray: [119, 136, 153], + lightslategrey: [119, 136, 153], + lightsteelblue: [176, 196, 222], + lightyellow: [255, 255, 224], + lime: [0, 255, 0], + limegreen: [50, 205, 50], + linen: [250, 240, 230], + magenta: [255, 0, 255], + maroon: [128, 0, 0], + mediumaquamarine: [102, 205, 170], + mediumblue: [0, 0, 205], + mediumorchid: [186, 85, 211], + mediumpurple: [147, 112, 219], + mediumseagreen: [60, 179, 113], + mediumslateblue: [123, 104, 238], + mediumspringgreen: [0, 250, 154], + mediumturquoise: [72, 209, 204], + mediumvioletred: [199, 21, 133], + midnightblue: [25, 25, 112], + mintcream: [245, 255, 250], + mistyrose: [255, 228, 225], + moccasin: [255, 228, 181], + navajowhite: [255, 222, 173], + navy: [0, 0, 128], + oldlace: [253, 245, 230], + olive: [128, 128, 0], + olivedrab: [107, 142, 35], + orange: [255, 165, 0], + orangered: [255, 69, 0], + orchid: [218, 112, 214], + palegoldenrod: [238, 232, 170], + palegreen: [152, 251, 152], + paleturquoise: [175, 238, 238], + palevioletred: [219, 112, 147], + papayawhip: [255, 239, 213], + peachpuff: [255, 218, 185], + peru: [205, 133, 63], + pink: [255, 192, 203], + plum: [221, 160, 221], + powderblue: [176, 224, 230], + purple: [128, 0, 128], + red: [255, 0, 0], + rosybrown: [188, 143, 143], + royalblue: [65, 105, 225], + saddlebrown: [139, 69, 19], + salmon: [250, 128, 114], + sandybrown: [244, 164, 96], + seagreen: [46, 139, 87], + seashell: [255, 245, 238], + sienna: [160, 82, 45], + silver: [192, 192, 192], + skyblue: [135, 206, 235], + slateblue: [106, 90, 205], + slategray: [112, 128, 144], + slategrey: [112, 128, 144], + snow: [255, 250, 250], + springgreen: [0, 255, 127], + steelblue: [70, 130, 180], + tan: [210, 180, 140], + teal: [0, 128, 128], + thistle: [216, 191, 216], + tomato: [255, 99, 71], + turquoise: [64, 224, 208], + violet: [238, 130, 238], + wheat: [245, 222, 179], + white: [255, 255, 255], + whitesmoke: [245, 245, 245], + yellow: [255, 255, 0], + yellowgreen: [154, 205, 50], + }, + V = function (e) { + for (var t = e.map, n = e.keys, r = n.length, i = 0; i < r; i++) { + var a = n[i]; + if (b(a)) throw Error("Tried to set map with object key"); + i < n.length - 1 + ? (null == t[a] && (t[a] = {}), (t = t[a])) + : (t[a] = e.value); + } + }, + F = function (e) { + for (var t = e.map, n = e.keys, r = n.length, i = 0; i < r; i++) { + var a = n[i]; + if (b(a)) throw Error("Tried to get map with object key"); + if (null == (t = t[a])) return t; + } + return t; + }; + var j = function (e) { + var t = typeof e; + return null != e && ("object" == t || "function" == t); + }, + q = + "undefined" != typeof globalThis + ? globalThis + : "undefined" != typeof window + ? window + : "undefined" != typeof global + ? global + : "undefined" != typeof self + ? self + : {}; + var Y = "object" == typeof q && q && q.Object === Object && q, + X = "object" == typeof self && self && self.Object === Object && self, + W = Y || X || Function("return this")(), + H = function () { + return W.Date.now(); + }, + K = /\s/; + var G = function (e) { + for (var t = e.length; t-- && K.test(e.charAt(t)); ); + return t; + }, + U = /^\s+/; + var Z = function (e) { + return e ? e.slice(0, G(e) + 1).replace(U, "") : e; + }, + $ = W.Symbol, + Q = Object.prototype, + J = Q.hasOwnProperty, + ee = Q.toString, + te = $ ? $.toStringTag : void 0; + var ne = function (e) { + var t = J.call(e, te), + n = e[te]; + try { + e[te] = void 0; + var r = !0; + } catch (e) {} + var i = ee.call(e); + return (r && (t ? (e[te] = n) : delete e[te]), i); + }, + re = Object.prototype.toString; + var ie = function (e) { + return re.call(e); + }, + ae = $ ? $.toStringTag : void 0; + var oe = function (e) { + return null == e + ? void 0 === e + ? "[object Undefined]" + : "[object Null]" + : ae && ae in Object(e) + ? ne(e) + : ie(e); + }; + var se = function (e) { + return null != e && "object" == typeof e; + }; + var le = function (e) { + return "symbol" == typeof e || (se(e) && "[object Symbol]" == oe(e)); + }, + ue = /^[-+]0x[0-9a-f]+$/i, + ce = /^0b[01]+$/i, + de = /^0o[0-7]+$/i, + he = parseInt; + var pe = function (e) { + if ("number" == typeof e) return e; + if (le(e)) return NaN; + if (j(e)) { + var t = "function" == typeof e.valueOf ? e.valueOf() : e; + e = j(t) ? t + "" : t; + } + if ("string" != typeof e) return 0 === e ? e : +e; + e = Z(e); + var n = ce.test(e); + return n || de.test(e) + ? he(e.slice(2), n ? 2 : 8) + : ue.test(e) + ? NaN + : +e; + }, + fe = Math.max, + ge = Math.min; + var ve = function (e, t, n) { + var r, + i, + a, + o, + s, + l, + u = 0, + c = !1, + d = !1, + h = !0; + if ("function" != typeof e) throw new TypeError("Expected a function"); + function p(t) { + var n = r, + a = i; + return ((r = i = void 0), (u = t), (o = e.apply(a, n))); + } + function f(e) { + return ((u = e), (s = setTimeout(v, t)), c ? p(e) : o); + } + function g(e) { + var n = e - l; + return void 0 === l || n >= t || n < 0 || (d && e - u >= a); + } + function v() { + var e = H(); + if (g(e)) return y(e); + s = setTimeout( + v, + (function (e) { + var n = t - (e - l); + return d ? ge(n, a - (e - u)) : n; + })(e), + ); + } + function y(e) { + return ((s = void 0), h && r ? p(e) : ((r = i = void 0), o)); + } + function m() { + var e = H(), + n = g(e); + if (((r = arguments), (i = this), (l = e), n)) { + if (void 0 === s) return f(l); + if (d) return (clearTimeout(s), (s = setTimeout(v, t)), p(l)); + } + return (void 0 === s && (s = setTimeout(v, t)), o); + } + return ( + (t = pe(t) || 0), + j(n) && + ((c = !!n.leading), + (a = (d = "maxWait" in n) ? fe(pe(n.maxWait) || 0, t) : a), + (h = "trailing" in n ? !!n.trailing : h)), + (m.cancel = function () { + (void 0 !== s && clearTimeout(s), (u = 0), (r = l = i = s = void 0)); + }), + (m.flush = function () { + return void 0 === s ? o : y(H()); + }), + m + ); + }, + ye = u ? u.performance : null, + me = + ye && ye.now + ? function () { + return ye.now(); + } + : function () { + return Date.now(); + }, + be = (function () { + if (u) { + if (u.requestAnimationFrame) + return function (e) { + u.requestAnimationFrame(e); + }; + if (u.mozRequestAnimationFrame) + return function (e) { + u.mozRequestAnimationFrame(e); + }; + if (u.webkitRequestAnimationFrame) + return function (e) { + u.webkitRequestAnimationFrame(e); + }; + if (u.msRequestAnimationFrame) + return function (e) { + u.msRequestAnimationFrame(e); + }; + } + return function (e) { + e && + setTimeout(function () { + e(me()); + }, 1e3 / 60); + }; + })(), + xe = function (e) { + return be(e); + }, + we = me, + Ee = 65599, + ke = function (e) { + for ( + var t, + n = + arguments.length > 1 && void 0 !== arguments[1] + ? arguments[1] + : 9261, + r = n; + !(t = e.next()).done; + ) + r = (r * Ee + t.value) | 0; + return r; + }, + Ce = function (e) { + var t = + arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 9261; + return (t * Ee + e) | 0; + }, + Se = function (e) { + var t = + arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 5381; + return ((t << 5) + t + e) | 0; + }, + Pe = function (e) { + return 2097152 * e[0] + e[1]; + }, + De = function (e, t) { + return [Ce(e[0], t[0]), Se(e[1], t[1])]; + }, + Te = function (e, t) { + var n = { value: 0, done: !1 }, + r = 0, + i = e.length; + return ke( + { + next: function () { + return (r < i ? (n.value = e.charCodeAt(r++)) : (n.done = !0), n); + }, + }, + t, + ); + }, + _e = function () { + return Me(arguments); + }, + Me = function (e) { + for (var t, n = 0; n < e.length; n++) { + var r = e[n]; + t = 0 === n ? Te(r) : Te(r, t); + } + return t; + }, + Be = !0, + Ne = null != console.warn, + ze = null != console.trace, + Ie = Number.MAX_SAFE_INTEGER || 9007199254740991, + Ae = function () { + return !0; + }, + Le = function () { + return !1; + }, + Oe = function () { + return 0; + }, + Re = function () {}, + Ve = function (e) { + throw new Error(e); + }, + Fe = function (e) { + if (void 0 === e) return Be; + Be = !!e; + }, + je = function (e) { + Fe() && (Ne ? console.warn(e) : (console.log(e), ze && console.trace())); + }, + qe = function (e) { + return null == e + ? e + : m(e) + ? e.slice() + : b(e) + ? (function (e) { + return L({}, e); + })(e) + : e; + }, + Ye = function (e, t) { + for ( + t = e = ""; + e++ < 36; + t += + (51 * e) & 52 + ? (15 ^ e ? 8 ^ (Math.random() * (20 ^ e ? 16 : 4)) : 4).toString( + 16, + ) + : "-" + ); + return t; + }, + Xe = {}, + We = function () { + return Xe; + }, + He = function (e) { + var t = Object.keys(e); + return function (n) { + for (var r = {}, i = 0; i < t.length; i++) { + var a = t[i], + o = null == n ? void 0 : n[a]; + r[a] = void 0 === o ? e[a] : o; + } + return r; + }; + }, + Ke = function (e, t, n) { + for ( + var r = e.length - 1; + r >= 0 && (e[r] !== t || (e.splice(r, 1), !n)); + r-- + ); + }, + Ge = function (e) { + e.splice(0, e.length); + }, + Ue = function (e, t, n) { + return (n && (t = N(n, t)), e[t]); + }, + Ze = function (e, t, n, r) { + (n && (t = N(n, t)), (e[t] = r)); + }, + $e = + "undefined" != typeof Map + ? Map + : (function () { + function e() { + (t(this, e), (this._obj = {})); + } + return ( + r(e, [ + { + key: "set", + value: function (e, t) { + return ((this._obj[e] = t), this); + }, + }, + { + key: "delete", + value: function (e) { + return ((this._obj[e] = void 0), this); + }, + }, + { + key: "clear", + value: function () { + this._obj = {}; + }, + }, + { + key: "has", + value: function (e) { + return void 0 !== this._obj[e]; + }, + }, + { + key: "get", + value: function (e) { + return this._obj[e]; + }, + }, + ]), + e + ); + })(), + Qe = (function () { + function e(n) { + if ( + (t(this, e), + (this._obj = Object.create(null)), + (this.size = 0), + null != n) + ) { + var r; + r = + null != n.instanceString && + n.instanceString() === this.instanceString() + ? n.toArray() + : n; + for (var i = 0; i < r.length; i++) this.add(r[i]); + } + } + return ( + r(e, [ + { + key: "instanceString", + value: function () { + return "set"; + }, + }, + { + key: "add", + value: function (e) { + var t = this._obj; + 1 !== t[e] && ((t[e] = 1), this.size++); + }, + }, + { + key: "delete", + value: function (e) { + var t = this._obj; + 1 === t[e] && ((t[e] = 0), this.size--); + }, + }, + { + key: "clear", + value: function () { + this._obj = Object.create(null); + }, + }, + { + key: "has", + value: function (e) { + return 1 === this._obj[e]; + }, + }, + { + key: "toArray", + value: function () { + var e = this; + return Object.keys(this._obj).filter(function (t) { + return e.has(t); + }); + }, + }, + { + key: "forEach", + value: function (e, t) { + return this.toArray().forEach(e, t); + }, + }, + ]), + e + ); + })(), + Je = + "undefined" !== ("undefined" == typeof Set ? "undefined" : e(Set)) + ? Set + : Qe, + et = function (e, t) { + var n = + !(arguments.length > 2 && void 0 !== arguments[2]) || arguments[2]; + if (void 0 !== e && void 0 !== t && S(e)) { + var r = t.group; + if ( + (null == r && + (r = + t.data && null != t.data.source && null != t.data.target + ? "edges" + : "nodes"), + "nodes" === r || "edges" === r) + ) { + ((this.length = 1), (this[0] = this)); + var i = (this._private = { + cy: e, + single: !0, + data: t.data || {}, + position: t.position || { x: 0, y: 0 }, + autoWidth: void 0, + autoHeight: void 0, + autoPadding: void 0, + compoundBoundsClean: !1, + listeners: [], + group: r, + style: {}, + rstyle: {}, + styleCxts: [], + styleKeys: {}, + removed: !0, + selected: !!t.selected, + selectable: void 0 === t.selectable || !!t.selectable, + locked: !!t.locked, + grabbed: !1, + grabbable: void 0 === t.grabbable || !!t.grabbable, + pannable: void 0 === t.pannable ? "edges" === r : !!t.pannable, + active: !1, + classes: new Je(), + animation: { current: [], queue: [] }, + rscratch: {}, + scratch: t.scratch || {}, + edges: [], + children: [], + parent: t.parent && t.parent.isNode() ? t.parent : null, + traversalCache: {}, + backgrounding: !1, + bbCache: null, + bbCacheShift: { x: 0, y: 0 }, + bodyBounds: null, + overlayBounds: null, + labelBounds: { all: null, source: null, target: null, main: null }, + arrowBounds: { + source: null, + target: null, + "mid-source": null, + "mid-target": null, + }, + }); + if ( + (null == i.position.x && (i.position.x = 0), + null == i.position.y && (i.position.y = 0), + t.renderedPosition) + ) { + var a = t.renderedPosition, + o = e.pan(), + s = e.zoom(); + i.position = { x: (a.x - o.x) / s, y: (a.y - o.y) / s }; + } + var l = []; + m(t.classes) + ? (l = t.classes) + : v(t.classes) && (l = t.classes.split(/\s+/)); + for (var u = 0, c = l.length; u < c; u++) { + var d = l[u]; + d && "" !== d && i.classes.add(d); + } + this.createEmitter(); + var h = t.style || t.css; + (h && + (je( + "Setting a `style` bypass at element creation should be done only when absolutely necessary. Try to use the stylesheet instead.", + ), + this.style(h)), + (void 0 === n || n) && this.restore()); + } else + Ve( + "An element must be of type `nodes` or `edges`; you specified `" + + r + + "`", + ); + } else Ve("An element must have a core reference and parameters set"); + }, + tt = function (e) { + return ( + (e = { bfs: e.bfs || !e.dfs, dfs: e.dfs || !e.bfs }), + function (t, n, r) { + var i; + (b(t) && + !E(t) && + ((t = (i = t).roots || i.root), (n = i.visit), (r = i.directed)), + (r = 2 !== arguments.length || y(n) ? r : n), + (n = y(n) ? n : function () {})); + for ( + var a, + o = this._private.cy, + s = (t = v(t) ? this.filter(t) : t), + l = [], + u = [], + c = {}, + d = {}, + h = {}, + p = 0, + f = this.byGroup(), + g = f.nodes, + m = f.edges, + x = 0; + x < s.length; + x++ + ) { + var w = s[x], + k = w.id(); + w.isNode() && + (l.unshift(w), e.bfs && ((h[k] = !0), u.push(w)), (d[k] = 0)); + } + for ( + var C = function () { + var t = e.bfs ? l.shift() : l.pop(), + i = t.id(); + if (e.dfs) { + if (h[i]) return "continue"; + ((h[i] = !0), u.push(t)); + } + var o, + s = d[i], + f = c[i], + v = null != f ? f.source() : null, + y = null != f ? f.target() : null, + b = null == f ? void 0 : t.same(v) ? y[0] : v[0]; + if (!0 === (o = n(t, f, b, p++, s))) return ((a = t), "break"); + if (!1 === o) return "break"; + for ( + var x = t.connectedEdges().filter(function (e) { + return (!r || e.source().same(t)) && m.has(e); + }), + w = 0; + w < x.length; + w++ + ) { + var E = x[w], + k = E.connectedNodes().filter(function (e) { + return !e.same(t) && g.has(e); + }), + C = k.id(); + 0 === k.length || + h[C] || + ((k = k[0]), + l.push(k), + e.bfs && ((h[C] = !0), u.push(k)), + (c[C] = E), + (d[C] = d[i] + 1)); + } + }; + 0 !== l.length; + ) { + var S = C(); + if ("continue" !== S && "break" === S) break; + } + for (var P = o.collection(), D = 0; D < u.length; D++) { + var T = u[D], + _ = c[T.id()]; + (null != _ && P.push(_), P.push(T)); + } + return { path: o.collection(P), found: o.collection(a) }; + } + ); + }, + nt = { + breadthFirstSearch: tt({ bfs: !0 }), + depthFirstSearch: tt({ dfs: !0 }), + }; + ((nt.bfs = nt.breadthFirstSearch), (nt.dfs = nt.depthFirstSearch)); + var rt = (function (e, t) { + return (e((t = { exports: {} }), t.exports), t.exports); + })(function (e, t) { + (function () { + var t, n, r, i, a, o, s, l, u, c, d, h, p, f, g; + ((r = Math.floor), + (c = Math.min), + (n = function (e, t) { + return e < t ? -1 : e > t ? 1 : 0; + }), + (u = function (e, t, i, a, o) { + var s; + if ((null == i && (i = 0), null == o && (o = n), i < 0)) + throw new Error("lo must be non-negative"); + for (null == a && (a = e.length); i < a; ) + o(t, e[(s = r((i + a) / 2))]) < 0 ? (a = s) : (i = s + 1); + return ([].splice.apply(e, [i, i - i].concat(t)), t); + }), + (o = function (e, t, r) { + return (null == r && (r = n), e.push(t), f(e, 0, e.length - 1, r)); + }), + (a = function (e, t) { + var r, i; + return ( + null == t && (t = n), + (r = e.pop()), + e.length ? ((i = e[0]), (e[0] = r), g(e, 0, t)) : (i = r), + i + ); + }), + (l = function (e, t, r) { + var i; + return ( + null == r && (r = n), + (i = e[0]), + (e[0] = t), + g(e, 0, r), + i + ); + }), + (s = function (e, t, r) { + var i; + return ( + null == r && (r = n), + e.length && + r(e[0], t) < 0 && + ((t = (i = [e[0], t])[0]), (e[0] = i[1]), g(e, 0, r)), + t + ); + }), + (i = function (e, t) { + var i, a, o, s, l, u; + for ( + null == t && (t = n), + l = [], + a = 0, + o = (s = function () { + u = []; + for ( + var t = 0, n = r(e.length / 2); + 0 <= n ? t < n : t > n; + 0 <= n ? t++ : t-- + ) + u.push(t); + return u; + } + .apply(this) + .reverse()).length; + a < o; + a++ + ) + ((i = s[a]), l.push(g(e, i, t))); + return l; + }), + (p = function (e, t, r) { + var i; + if ((null == r && (r = n), -1 !== (i = e.indexOf(t)))) + return (f(e, 0, i, r), g(e, i, r)); + }), + (d = function (e, t, r) { + var a, o, l, u, c; + if ((null == r && (r = n), !(o = e.slice(0, t)).length)) return o; + for (i(o, r), l = 0, u = (c = e.slice(t)).length; l < u; l++) + ((a = c[l]), s(o, a, r)); + return o.sort(r).reverse(); + }), + (h = function (e, t, r) { + var o, s, l, d, h, p, f, g, v; + if ((null == r && (r = n), 10 * t <= e.length)) { + if (!(l = e.slice(0, t).sort(r)).length) return l; + for ( + s = l[l.length - 1], d = 0, p = (f = e.slice(t)).length; + d < p; + d++ + ) + r((o = f[d]), s) < 0 && + (u(l, o, 0, null, r), l.pop(), (s = l[l.length - 1])); + return l; + } + for ( + i(e, r), v = [], h = 0, g = c(t, e.length); + 0 <= g ? h < g : h > g; + 0 <= g ? ++h : --h + ) + v.push(a(e, r)); + return v; + }), + (f = function (e, t, r, i) { + var a, o, s; + for ( + null == i && (i = n), a = e[r]; + r > t && i(a, (o = e[(s = (r - 1) >> 1)])) < 0; + ) + ((e[r] = o), (r = s)); + return (e[r] = a); + }), + (g = function (e, t, r) { + var i, a, o, s, l; + for ( + null == r && (r = n), + a = e.length, + l = t, + o = e[t], + i = 2 * t + 1; + i < a; + ) + ((s = i + 1) < a && !(r(e[i], e[s]) < 0) && (i = s), + (e[t] = e[i]), + (i = 2 * (t = i) + 1)); + return ((e[t] = o), f(e, l, t, r)); + }), + (t = (function () { + function e(e) { + ((this.cmp = null != e ? e : n), (this.nodes = [])); + } + return ( + (e.push = o), + (e.pop = a), + (e.replace = l), + (e.pushpop = s), + (e.heapify = i), + (e.updateItem = p), + (e.nlargest = d), + (e.nsmallest = h), + (e.prototype.push = function (e) { + return o(this.nodes, e, this.cmp); + }), + (e.prototype.pop = function () { + return a(this.nodes, this.cmp); + }), + (e.prototype.peek = function () { + return this.nodes[0]; + }), + (e.prototype.contains = function (e) { + return -1 !== this.nodes.indexOf(e); + }), + (e.prototype.replace = function (e) { + return l(this.nodes, e, this.cmp); + }), + (e.prototype.pushpop = function (e) { + return s(this.nodes, e, this.cmp); + }), + (e.prototype.heapify = function () { + return i(this.nodes, this.cmp); + }), + (e.prototype.updateItem = function (e) { + return p(this.nodes, e, this.cmp); + }), + (e.prototype.clear = function () { + return (this.nodes = []); + }), + (e.prototype.empty = function () { + return 0 === this.nodes.length; + }), + (e.prototype.size = function () { + return this.nodes.length; + }), + (e.prototype.clone = function () { + var t; + return (((t = new e()).nodes = this.nodes.slice(0)), t); + }), + (e.prototype.toArray = function () { + return this.nodes.slice(0); + }), + (e.prototype.insert = e.prototype.push), + (e.prototype.top = e.prototype.peek), + (e.prototype.front = e.prototype.peek), + (e.prototype.has = e.prototype.contains), + (e.prototype.copy = e.prototype.clone), + e + ); + })()), + (e.exports = t)); + }).call(q); + }), + it = He({ + root: null, + weight: function (e) { + return 1; + }, + directed: !1, + }), + at = { + dijkstra: function (e) { + if (!b(e)) { + var t = arguments; + e = { root: t[0], weight: t[1], directed: t[2] }; + } + var n = it(e), + r = n.root, + i = n.weight, + a = n.directed, + o = this, + s = i, + l = v(r) ? this.filter(r)[0] : r[0], + u = {}, + c = {}, + d = {}, + h = this.byGroup(), + p = h.nodes, + f = h.edges; + f.unmergeBy(function (e) { + return e.isLoop(); + }); + for ( + var g = function (e) { + return u[e.id()]; + }, + y = function (e, t) { + ((u[e.id()] = t), m.updateItem(e)); + }, + m = new rt(function (e, t) { + return g(e) - g(t); + }), + x = 0; + x < p.length; + x++ + ) { + var w = p[x]; + ((u[w.id()] = w.same(l) ? 0 : 1 / 0), m.push(w)); + } + for ( + var E = function (e, t) { + for ( + var n, + r = (a ? e.edgesTo(t) : e.edgesWith(t)).intersect(f), + i = 1 / 0, + o = 0; + o < r.length; + o++ + ) { + var l = r[o], + u = s(l); + (u < i || !n) && ((i = u), (n = l)); + } + return { edge: n, dist: i }; + }; + m.size() > 0; + ) { + var k = m.pop(), + C = g(k), + S = k.id(); + if (((d[S] = C), C !== 1 / 0)) + for ( + var P = k.neighborhood().intersect(p), D = 0; + D < P.length; + D++ + ) { + var T = P[D], + _ = T.id(), + M = E(k, T), + B = C + M.dist; + B < g(T) && (y(T, B), (c[_] = { node: k, edge: M.edge })); + } + } + return { + distanceTo: function (e) { + var t = v(e) ? p.filter(e)[0] : e[0]; + return d[t.id()]; + }, + pathTo: function (e) { + var t = v(e) ? p.filter(e)[0] : e[0], + n = [], + r = t, + i = r.id(); + if (t.length > 0) + for (n.unshift(t); c[i]; ) { + var a = c[i]; + (n.unshift(a.edge), n.unshift(a.node), (i = (r = a.node).id())); + } + return o.spawn(n); + }, + }; + }, + }, + ot = { + kruskal: function (e) { + e = + e || + function (e) { + return 1; + }; + for ( + var t = this.byGroup(), + n = t.nodes, + r = t.edges, + i = n.length, + a = new Array(i), + o = n, + s = function (e) { + for (var t = 0; t < a.length; t++) { + if (a[t].has(e)) return t; + } + }, + l = 0; + l < i; + l++ + ) + a[l] = this.spawn(n[l]); + for ( + var u = r.sort(function (t, n) { + return e(t) - e(n); + }), + c = 0; + c < u.length; + c++ + ) { + var d = u[c], + h = d.source()[0], + p = d.target()[0], + f = s(h), + g = s(p), + v = a[f], + y = a[g]; + f !== g && (o.merge(d), v.merge(y), a.splice(g, 1)); + } + return o; + }, + }, + st = He({ + root: null, + goal: null, + weight: function (e) { + return 1; + }, + heuristic: function (e) { + return 0; + }, + directed: !1, + }), + lt = { + aStar: function (e) { + var t = this.cy(), + n = st(e), + r = n.root, + i = n.goal, + a = n.heuristic, + o = n.directed, + s = n.weight; + ((r = t.collection(r)[0]), (i = t.collection(i)[0])); + var l, + u, + c = r.id(), + d = i.id(), + h = {}, + p = {}, + f = {}, + g = new rt(function (e, t) { + return p[e.id()] - p[t.id()]; + }), + v = new Je(), + y = {}, + m = {}, + b = function (e, t) { + (g.push(e), v.add(t)); + }; + (b(r, c), (h[c] = 0), (p[c] = a(r))); + for (var x, w = 0; g.size() > 0; ) { + if (((l = g.pop()), (u = l.id()), v.delete(u), w++, u === d)) { + for ( + var E = [], k = i, C = d, S = m[C]; + E.unshift(k), null != S && E.unshift(S), null != (k = y[C]); + ) + S = m[(C = k.id())]; + return { found: !0, distance: h[u], path: this.spawn(E), steps: w }; + } + f[u] = !0; + for (var P = l._private.edges, D = 0; D < P.length; D++) { + var T = P[D]; + if ( + this.hasElementWithId(T.id()) && + (!o || T.data("source") === u) + ) { + var _ = T.source(), + M = T.target(), + B = _.id() !== u ? _ : M, + N = B.id(); + if (this.hasElementWithId(N) && !f[N]) { + var z = h[u] + s(T); + ((x = N), + v.has(x) + ? z < h[N] && + ((h[N] = z), (p[N] = z + a(B)), (y[N] = l), (m[N] = T)) + : ((h[N] = z), + (p[N] = z + a(B)), + b(B, N), + (y[N] = l), + (m[N] = T))); + } + } + } + } + return { found: !1, distance: void 0, path: void 0, steps: w }; + }, + }, + ut = He({ + weight: function (e) { + return 1; + }, + directed: !1, + }), + ct = { + floydWarshall: function (e) { + for ( + var t = this.cy(), + n = ut(e), + r = n.weight, + i = n.directed, + a = r, + o = this.byGroup(), + s = o.nodes, + l = o.edges, + u = s.length, + c = u * u, + d = function (e) { + return s.indexOf(e); + }, + h = function (e) { + return s[e]; + }, + p = new Array(c), + f = 0; + f < c; + f++ + ) { + var g = f % u, + y = (f - g) / u; + p[f] = y === g ? 0 : 1 / 0; + } + for (var m = new Array(c), b = new Array(c), x = 0; x < l.length; x++) { + var w = l[x], + E = w.source()[0], + k = w.target()[0]; + if (E !== k) { + var C = d(E), + S = d(k), + P = C * u + S, + D = a(w); + if ((p[P] > D && ((p[P] = D), (m[P] = S), (b[P] = w)), !i)) { + var T = S * u + C; + !i && p[T] > D && ((p[T] = D), (m[T] = C), (b[T] = w)); + } + } + } + for (var _ = 0; _ < u; _++) + for (var M = 0; M < u; M++) + for (var B = M * u + _, N = 0; N < u; N++) { + var z = M * u + N, + I = _ * u + N; + p[B] + p[I] < p[z] && ((p[z] = p[B] + p[I]), (m[z] = m[B])); + } + var A = function (e) { + return d( + (function (e) { + return (v(e) ? t.filter(e) : e)[0]; + })(e), + ); + }; + return { + distance: function (e, t) { + var n = A(e), + r = A(t); + return p[n * u + r]; + }, + path: function (e, n) { + var r = A(e), + i = A(n), + a = h(r); + if (r === i) return a.collection(); + if (null == m[r * u + i]) return t.collection(); + var o, + s = t.collection(), + l = r; + for (s.merge(a); r !== i; ) + ((l = r), + (r = m[r * u + i]), + (o = b[l * u + r]), + s.merge(o), + s.merge(h(r))); + return s; + }, + }; + }, + }, + dt = He({ + weight: function (e) { + return 1; + }, + directed: !1, + root: null, + }), + ht = { + bellmanFord: function (e) { + var t = this, + n = dt(e), + r = n.weight, + i = n.directed, + a = n.root, + o = r, + s = this, + l = this.cy(), + u = this.byGroup(), + c = u.edges, + d = u.nodes, + h = d.length, + p = new $e(), + f = !1, + g = []; + ((a = l.collection(a)[0]), + c.unmergeBy(function (e) { + return e.isLoop(); + })); + for ( + var y = c.length, + m = function (e) { + var t = p.get(e.id()); + return (t || ((t = {}), p.set(e.id(), t)), t); + }, + b = function (e) { + return (v(e) ? l.$(e) : e)[0]; + }, + x = 0; + x < h; + x++ + ) { + var w = d[x], + E = m(w); + (w.same(a) ? (E.dist = 0) : (E.dist = 1 / 0), + (E.pred = null), + (E.edge = null)); + } + for ( + var k = !1, + C = function (e, t, n, r, i, a) { + var o = r.dist + a; + o < i.dist && + !n.same(r.edge) && + ((i.dist = o), (i.pred = e), (i.edge = n), (k = !0)); + }, + S = 1; + S < h; + S++ + ) { + k = !1; + for (var P = 0; P < y; P++) { + var D = c[P], + T = D.source(), + _ = D.target(), + M = o(D), + B = m(T), + N = m(_); + (C(T, 0, D, B, N, M), i || C(_, 0, D, N, B, M)); + } + if (!k) break; + } + if (k) + for (var z = [], I = 0; I < y; I++) { + var A = c[I], + L = A.source(), + O = A.target(), + R = o(A), + V = m(L).dist, + F = m(O).dist; + if (V + R < F || (!i && F + R < V)) { + if ( + (f || + (je( + "Graph contains a negative weight cycle for Bellman-Ford", + ), + (f = !0)), + !1 === e.findNegativeWeightCycles) + ) + break; + var j = []; + (V + R < F && j.push(L), !i && F + R < V && j.push(O)); + for (var q = j.length, Y = 0; Y < q; Y++) { + var X = j[Y], + W = [X]; + W.push(m(X).edge); + for (var H = m(X).pred; -1 === W.indexOf(H); ) + (W.push(H), W.push(m(H).edge), (H = m(H).pred)); + for ( + var K = (W = W.slice(W.indexOf(H)))[0].id(), G = 0, U = 2; + U < W.length; + U += 2 + ) + W[U].id() < K && ((K = W[U].id()), (G = U)); + (W = W.slice(G).concat(W.slice(0, G))).push(W[0]); + var Z = W.map(function (e) { + return e.id(); + }).join(","); + -1 === z.indexOf(Z) && (g.push(s.spawn(W)), z.push(Z)); + } + } + } + return { + distanceTo: function (e) { + return m(b(e)).dist; + }, + pathTo: function (e) { + for ( + var n = + arguments.length > 1 && void 0 !== arguments[1] + ? arguments[1] + : a, + r = b(e), + i = [], + o = r; + ; + ) { + if (null == o) return t.spawn(); + var l = m(o), + u = l.edge, + c = l.pred; + if ((i.unshift(o[0]), o.same(n) && i.length > 0)) break; + (null != u && i.unshift(u), (o = c)); + } + return s.spawn(i); + }, + hasNegativeWeightCycle: f, + negativeWeightCycles: g, + }; + }, + }, + pt = Math.sqrt(2), + ft = function (e, t, n) { + 0 === n.length && + Ve("Karger-Stein must be run on a connected (sub)graph"); + for ( + var r = n[e], + i = r[1], + a = r[2], + o = t[i], + s = t[a], + l = n, + u = l.length - 1; + u >= 0; + u-- + ) { + var c = l[u], + d = c[1], + h = c[2]; + ((t[d] === o && t[h] === s) || (t[d] === s && t[h] === o)) && + l.splice(u, 1); + } + for (var p = 0; p < l.length; p++) { + var f = l[p]; + f[1] === s + ? ((l[p] = f.slice()), (l[p][1] = o)) + : f[2] === s && ((l[p] = f.slice()), (l[p][2] = o)); + } + for (var g = 0; g < t.length; g++) t[g] === s && (t[g] = o); + return l; + }, + gt = function (e, t, n, r) { + for (; n > r; ) { + var i = Math.floor(Math.random() * t.length); + ((t = ft(i, e, t)), n--); + } + return t; + }, + vt = { + kargerStein: function () { + var e = this, + t = this.byGroup(), + n = t.nodes, + r = t.edges; + r.unmergeBy(function (e) { + return e.isLoop(); + }); + var i = n.length, + a = r.length, + o = Math.ceil(Math.pow(Math.log(i) / Math.LN2, 2)), + s = Math.floor(i / pt); + if (!(i < 2)) { + for (var l = [], u = 0; u < a; u++) { + var c = r[u]; + l.push([u, n.indexOf(c.source()), n.indexOf(c.target())]); + } + for ( + var d = 1 / 0, + h = [], + p = new Array(i), + f = new Array(i), + g = new Array(i), + v = function (e, t) { + for (var n = 0; n < i; n++) t[n] = e[n]; + }, + y = 0; + y <= o; + y++ + ) { + for (var m = 0; m < i; m++) f[m] = m; + var b = gt(f, l.slice(), i, s), + x = b.slice(); + v(f, g); + var w = gt(f, b, s, 2), + E = gt(g, x, s, 2); + w.length <= E.length && w.length < d + ? ((d = w.length), (h = w), v(f, p)) + : E.length <= w.length && + E.length < d && + ((d = E.length), (h = E), v(g, p)); + } + for ( + var k = this.spawn( + h.map(function (e) { + return r[e[0]]; + }), + ), + C = this.spawn(), + S = this.spawn(), + P = p[0], + D = 0; + D < p.length; + D++ + ) { + var T = p[D], + _ = n[D]; + T === P ? C.merge(_) : S.merge(_); + } + var M = function (t) { + var n = e.spawn(); + return ( + t.forEach(function (t) { + (n.merge(t), + t.connectedEdges().forEach(function (t) { + e.contains(t) && !k.contains(t) && n.merge(t); + })); + }), + n + ); + }, + B = [M(C), M(S)]; + return { cut: k, components: B, partition1: C, partition2: S }; + } + Ve("At least 2 nodes are required for Karger-Stein algorithm"); + }, + }, + yt = function (e, t, n) { + return { x: e.x * t + n.x, y: e.y * t + n.y }; + }, + mt = function (e, t, n) { + return { x: (e.x - n.x) / t, y: (e.y - n.y) / t }; + }, + bt = function (e) { + return { x: e[0], y: e[1] }; + }, + xt = function (e, t) { + return Math.atan2(t, e) - Math.PI / 2; + }, + wt = + Math.log2 || + function (e) { + return Math.log(e) / Math.log(2); + }, + Et = function (e) { + return e > 0 ? 1 : e < 0 ? -1 : 0; + }, + kt = function (e, t) { + return Math.sqrt(Ct(e, t)); + }, + Ct = function (e, t) { + var n = t.x - e.x, + r = t.y - e.y; + return n * n + r * r; + }, + St = function (e) { + for (var t = e.length, n = 0, r = 0; r < t; r++) n += e[r]; + for (var i = 0; i < t; i++) e[i] = e[i] / n; + return e; + }, + Pt = function (e, t, n, r) { + return (1 - r) * (1 - r) * e + 2 * (1 - r) * r * t + r * r * n; + }, + Dt = function (e, t, n, r) { + return { x: Pt(e.x, t.x, n.x, r), y: Pt(e.y, t.y, n.y, r) }; + }, + Tt = function (e, t, n) { + return Math.max(e, Math.min(n, t)); + }, + _t = function (e) { + if (null == e) + return { x1: 1 / 0, y1: 1 / 0, x2: -1 / 0, y2: -1 / 0, w: 0, h: 0 }; + if (null != e.x1 && null != e.y1) { + if (null != e.x2 && null != e.y2 && e.x2 >= e.x1 && e.y2 >= e.y1) + return { + x1: e.x1, + y1: e.y1, + x2: e.x2, + y2: e.y2, + w: e.x2 - e.x1, + h: e.y2 - e.y1, + }; + if (null != e.w && null != e.h && e.w >= 0 && e.h >= 0) + return { + x1: e.x1, + y1: e.y1, + x2: e.x1 + e.w, + y2: e.y1 + e.h, + w: e.w, + h: e.h, + }; + } + }, + Mt = function (e, t) { + ((e.x1 = Math.min(e.x1, t.x1)), + (e.x2 = Math.max(e.x2, t.x2)), + (e.w = e.x2 - e.x1), + (e.y1 = Math.min(e.y1, t.y1)), + (e.y2 = Math.max(e.y2, t.y2)), + (e.h = e.y2 - e.y1)); + }, + Bt = function (e, t, n) { + ((e.x1 = Math.min(e.x1, t)), + (e.x2 = Math.max(e.x2, t)), + (e.w = e.x2 - e.x1), + (e.y1 = Math.min(e.y1, n)), + (e.y2 = Math.max(e.y2, n)), + (e.h = e.y2 - e.y1)); + }, + Nt = function (e) { + var t = + arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 0; + return ( + (e.x1 -= t), + (e.x2 += t), + (e.y1 -= t), + (e.y2 += t), + (e.w = e.x2 - e.x1), + (e.h = e.y2 - e.y1), + e + ); + }, + zt = function (e) { + var t, + n, + r, + i, + o = + arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : [0]; + if (1 === o.length) t = n = r = i = o[0]; + else if (2 === o.length) ((t = r = o[0]), (i = n = o[1])); + else if (4 === o.length) { + var s = a(o, 4); + ((t = s[0]), (n = s[1]), (r = s[2]), (i = s[3])); + } + return ( + (e.x1 -= i), + (e.x2 += n), + (e.y1 -= t), + (e.y2 += r), + (e.w = e.x2 - e.x1), + (e.h = e.y2 - e.y1), + e + ); + }, + It = function (e, t) { + ((e.x1 = t.x1), + (e.y1 = t.y1), + (e.x2 = t.x2), + (e.y2 = t.y2), + (e.w = e.x2 - e.x1), + (e.h = e.y2 - e.y1)); + }, + At = function (e, t) { + return ( + !(e.x1 > t.x2) && + !(t.x1 > e.x2) && + !(e.x2 < t.x1) && + !(t.x2 < e.x1) && + !(e.y2 < t.y1) && + !(t.y2 < e.y1) && + !(e.y1 > t.y2) && + !(t.y1 > e.y2) + ); + }, + Lt = function (e, t, n) { + return e.x1 <= t && t <= e.x2 && e.y1 <= n && n <= e.y2; + }, + Ot = function (e, t) { + return Lt(e, t.x1, t.y1) && Lt(e, t.x2, t.y2); + }, + Rt = function (e, t, n, r, i, a, o) { + var s, + l, + u = + arguments.length > 7 && void 0 !== arguments[7] + ? arguments[7] + : "auto", + c = "auto" === u ? nn(i, a) : u, + d = i / 2, + h = a / 2, + p = (c = Math.min(c, d, h)) !== d, + f = c !== h; + if (p) { + var g = n - d + c - o, + v = r - h - o, + y = n + d - c + o, + m = v; + if ((s = Zt(e, t, n, r, g, v, y, m, !1)).length > 0) return s; + } + if (f) { + var b = n + d + o, + x = r - h + c - o, + w = b, + E = r + h - c + o; + if ((s = Zt(e, t, n, r, b, x, w, E, !1)).length > 0) return s; + } + if (p) { + var k = n - d + c - o, + C = r + h + o, + S = n + d - c + o, + P = C; + if ((s = Zt(e, t, n, r, k, C, S, P, !1)).length > 0) return s; + } + if (f) { + var D = n - d - o, + T = r - h + c - o, + _ = D, + M = r + h - c + o; + if ((s = Zt(e, t, n, r, D, T, _, M, !1)).length > 0) return s; + } + var B = n - d + c, + N = r - h + c; + if ( + (l = Gt(e, t, n, r, B, N, c + o)).length > 0 && + l[0] <= B && + l[1] <= N + ) + return [l[0], l[1]]; + var z = n + d - c, + I = r - h + c; + if ( + (l = Gt(e, t, n, r, z, I, c + o)).length > 0 && + l[0] >= z && + l[1] <= I + ) + return [l[0], l[1]]; + var A = n + d - c, + L = r + h - c; + if ( + (l = Gt(e, t, n, r, A, L, c + o)).length > 0 && + l[0] >= A && + l[1] >= L + ) + return [l[0], l[1]]; + var O = n - d + c, + R = r + h - c; + return (l = Gt(e, t, n, r, O, R, c + o)).length > 0 && + l[0] <= O && + l[1] >= R + ? [l[0], l[1]] + : []; + }, + Vt = function (e, t, n, r, i, a, o) { + var s = o, + l = Math.min(n, i), + u = Math.max(n, i), + c = Math.min(r, a), + d = Math.max(r, a); + return l - s <= e && e <= u + s && c - s <= t && t <= d + s; + }, + Ft = function (e, t, n, r, i, a, o, s, l) { + var u = Math.min(n, o, i) - l, + c = Math.max(n, o, i) + l, + d = Math.min(r, s, a) - l, + h = Math.max(r, s, a) + l; + return !(e < u || e > c || t < d || t > h); + }, + jt = function (e, t, n, r, i, a, o, s) { + var l = []; + !(function (e, t, n, r, i) { + var a, o, s, l, u, c, d, h; + (0 === e && (e = 1e-5), + (s = -27 * (r /= e) + (t /= e) * (9 * (n /= e) - t * t * 2)), + (a = (o = (3 * n - t * t) / 9) * o * o + (s /= 54) * s), + (i[1] = 0), + (d = t / 3), + a > 0 + ? ((u = + (u = s + Math.sqrt(a)) < 0 + ? -Math.pow(-u, 1 / 3) + : Math.pow(u, 1 / 3)), + (c = + (c = s - Math.sqrt(a)) < 0 + ? -Math.pow(-c, 1 / 3) + : Math.pow(c, 1 / 3)), + (i[0] = -d + u + c), + (d += (u + c) / 2), + (i[4] = i[2] = -d), + (d = (Math.sqrt(3) * (-c + u)) / 2), + (i[3] = d), + (i[5] = -d)) + : ((i[5] = i[3] = 0), + 0 === a + ? ((h = s < 0 ? -Math.pow(-s, 1 / 3) : Math.pow(s, 1 / 3)), + (i[0] = 2 * h - d), + (i[4] = i[2] = -(h + d))) + : ((l = (o = -o) * o * o), + (l = Math.acos(s / Math.sqrt(l))), + (h = 2 * Math.sqrt(o)), + (i[0] = -d + h * Math.cos(l / 3)), + (i[2] = -d + h * Math.cos((l + 2 * Math.PI) / 3)), + (i[4] = -d + h * Math.cos((l + 4 * Math.PI) / 3))))); + })( + 1 * n * n - + 4 * n * i + + 2 * n * o + + 4 * i * i - + 4 * i * o + + o * o + + r * r - + 4 * r * a + + 2 * r * s + + 4 * a * a - + 4 * a * s + + s * s, + 9 * n * i - + 3 * n * n - + 3 * n * o - + 6 * i * i + + 3 * i * o + + 9 * r * a - + 3 * r * r - + 3 * r * s - + 6 * a * a + + 3 * a * s, + 3 * n * n - + 6 * n * i + + n * o - + n * e + + 2 * i * i + + 2 * i * e - + o * e + + 3 * r * r - + 6 * r * a + + r * s - + r * t + + 2 * a * a + + 2 * a * t - + s * t, + 1 * n * i - n * n + n * e - i * e + r * a - r * r + r * t - a * t, + l, + ); + for (var u = [], c = 0; c < 6; c += 2) + Math.abs(l[c + 1]) < 1e-7 && l[c] >= 0 && l[c] <= 1 && u.push(l[c]); + (u.push(1), u.push(0)); + for (var d, h, p, f = -1, g = 0; g < u.length; g++) + ((d = + Math.pow(1 - u[g], 2) * n + + 2 * (1 - u[g]) * u[g] * i + + u[g] * u[g] * o), + (h = + Math.pow(1 - u[g], 2) * r + + 2 * (1 - u[g]) * u[g] * a + + u[g] * u[g] * s), + (p = Math.pow(d - e, 2) + Math.pow(h - t, 2)), + f >= 0 ? p < f && (f = p) : (f = p)); + return f; + }, + qt = function (e, t, n, r, i, a) { + var o = [e - n, t - r], + s = [i - n, a - r], + l = s[0] * s[0] + s[1] * s[1], + u = o[0] * o[0] + o[1] * o[1], + c = o[0] * s[0] + o[1] * s[1], + d = (c * c) / l; + return c < 0 ? u : d > l ? (e - i) * (e - i) + (t - a) * (t - a) : u - d; + }, + Yt = function (e, t, n) { + for (var r, i, a, o, s = 0, l = 0; l < n.length / 2; l++) + if ( + ((r = n[2 * l]), + (i = n[2 * l + 1]), + l + 1 < n.length / 2 + ? ((a = n[2 * (l + 1)]), (o = n[2 * (l + 1) + 1])) + : ((a = n[2 * (l + 1 - n.length / 2)]), + (o = n[2 * (l + 1 - n.length / 2) + 1])), + r == e && a == e) + ); + else { + if (!((r >= e && e >= a) || (r <= e && e <= a))) continue; + ((e - r) / (a - r)) * (o - i) + i > t && s++; + } + return s % 2 != 0; + }, + Xt = function (e, t, n, r, i, a, o, s, l) { + var u, + c = new Array(n.length); + null != s[0] + ? ((u = Math.atan(s[1] / s[0])), + s[0] < 0 ? (u += Math.PI / 2) : (u = -u - Math.PI / 2)) + : (u = s); + for ( + var d, h = Math.cos(-u), p = Math.sin(-u), f = 0; + f < c.length / 2; + f++ + ) + ((c[2 * f] = (a / 2) * (n[2 * f] * h - n[2 * f + 1] * p)), + (c[2 * f + 1] = (o / 2) * (n[2 * f + 1] * h + n[2 * f] * p)), + (c[2 * f] += r), + (c[2 * f + 1] += i)); + if (l > 0) { + var g = Ht(c, -l); + d = Wt(g); + } else d = c; + return Yt(e, t, d); + }, + Wt = function (e) { + for ( + var t, n, r, i, a, o, s, l, u = new Array(e.length / 2), c = 0; + c < e.length / 4; + c++ + ) { + ((t = e[4 * c]), + (n = e[4 * c + 1]), + (r = e[4 * c + 2]), + (i = e[4 * c + 3]), + c < e.length / 4 - 1 + ? ((a = e[4 * (c + 1)]), + (o = e[4 * (c + 1) + 1]), + (s = e[4 * (c + 1) + 2]), + (l = e[4 * (c + 1) + 3])) + : ((a = e[0]), (o = e[1]), (s = e[2]), (l = e[3]))); + var d = Zt(t, n, r, i, a, o, s, l, !0); + ((u[2 * c] = d[0]), (u[2 * c + 1] = d[1])); + } + return u; + }, + Ht = function (e, t) { + for ( + var n, r, i, a, o = new Array(2 * e.length), s = 0; + s < e.length / 2; + s++ + ) { + ((n = e[2 * s]), + (r = e[2 * s + 1]), + s < e.length / 2 - 1 + ? ((i = e[2 * (s + 1)]), (a = e[2 * (s + 1) + 1])) + : ((i = e[0]), (a = e[1]))); + var l = a - r, + u = -(i - n), + c = Math.sqrt(l * l + u * u), + d = l / c, + h = u / c; + ((o[4 * s] = n + d * t), + (o[4 * s + 1] = r + h * t), + (o[4 * s + 2] = i + d * t), + (o[4 * s + 3] = a + h * t)); + } + return o; + }, + Kt = function (e, t, n, r, i, a, o) { + return ( + (e -= i), + (t -= a), + (e /= n / 2 + o) * e + (t /= r / 2 + o) * t <= 1 + ); + }, + Gt = function (e, t, n, r, i, a, o) { + var s = [n - e, r - t], + l = [e - i, t - a], + u = s[0] * s[0] + s[1] * s[1], + c = 2 * (l[0] * s[0] + l[1] * s[1]), + d = c * c - 4 * u * (l[0] * l[0] + l[1] * l[1] - o * o); + if (d < 0) return []; + var h = (-c + Math.sqrt(d)) / (2 * u), + p = (-c - Math.sqrt(d)) / (2 * u), + f = Math.min(h, p), + g = Math.max(h, p), + v = []; + if ( + (f >= 0 && f <= 1 && v.push(f), + g >= 0 && g <= 1 && v.push(g), + 0 === v.length) + ) + return []; + var y = v[0] * s[0] + e, + m = v[0] * s[1] + t; + return v.length > 1 + ? v[0] == v[1] + ? [y, m] + : [y, m, v[1] * s[0] + e, v[1] * s[1] + t] + : [y, m]; + }, + Ut = function (e, t, n) { + return (t <= e && e <= n) || (n <= e && e <= t) + ? e + : (e <= t && t <= n) || (n <= t && t <= e) + ? t + : n; + }, + Zt = function (e, t, n, r, i, a, o, s, l) { + var u = e - i, + c = n - e, + d = o - i, + h = t - a, + p = r - t, + f = s - a, + g = d * h - f * u, + v = c * h - p * u, + y = f * c - d * p; + if (0 !== y) { + var m = g / y, + b = v / y; + return (-0.001 <= m && m <= 1.001 && -0.001 <= b && b <= 1.001) || l + ? [e + m * c, t + m * p] + : []; + } + return 0 === g || 0 === v + ? Ut(e, n, o) === o + ? [o, s] + : Ut(e, n, i) === i + ? [i, a] + : Ut(i, o, n) === n + ? [n, r] + : [] + : []; + }, + $t = function (e, t, n, r, i, a, o, s) { + var l, + u, + c, + d, + h, + p, + f = [], + g = new Array(n.length), + v = !0; + if ((null == a && (v = !1), v)) { + for (var y = 0; y < g.length / 2; y++) + ((g[2 * y] = n[2 * y] * a + r), + (g[2 * y + 1] = n[2 * y + 1] * o + i)); + if (s > 0) { + var m = Ht(g, -s); + u = Wt(m); + } else u = g; + } else u = n; + for (var b = 0; b < u.length / 2; b++) + ((c = u[2 * b]), + (d = u[2 * b + 1]), + b < u.length / 2 - 1 + ? ((h = u[2 * (b + 1)]), (p = u[2 * (b + 1) + 1])) + : ((h = u[0]), (p = u[1])), + 0 !== (l = Zt(e, t, r, i, c, d, h, p)).length && f.push(l[0], l[1])); + return f; + }, + Qt = function (e, t, n) { + var r = [e[0] - t[0], e[1] - t[1]], + i = Math.sqrt(r[0] * r[0] + r[1] * r[1]), + a = (i - n) / i; + return (a < 0 && (a = 1e-5), [t[0] + a * r[0], t[1] + a * r[1]]); + }, + Jt = function (e, t) { + var n = tn(e, t); + return (n = en(n)); + }, + en = function (e) { + for ( + var t, + n, + r = e.length / 2, + i = 1 / 0, + a = 1 / 0, + o = -1 / 0, + s = -1 / 0, + l = 0; + l < r; + l++ + ) + ((t = e[2 * l]), + (n = e[2 * l + 1]), + (i = Math.min(i, t)), + (o = Math.max(o, t)), + (a = Math.min(a, n)), + (s = Math.max(s, n))); + for (var u = 2 / (o - i), c = 2 / (s - a), d = 0; d < r; d++) + ((t = e[2 * d] = e[2 * d] * u), + (n = e[2 * d + 1] = e[2 * d + 1] * c), + (i = Math.min(i, t)), + (o = Math.max(o, t)), + (a = Math.min(a, n)), + (s = Math.max(s, n))); + if (a < -1) + for (var h = 0; h < r; h++) n = e[2 * h + 1] = e[2 * h + 1] + (-1 - a); + return e; + }, + tn = function (e, t) { + var n = (1 / e) * 2 * Math.PI, + r = e % 2 == 0 ? Math.PI / 2 + n / 2 : Math.PI / 2; + r += t; + for (var i, a = new Array(2 * e), o = 0; o < e; o++) + ((i = o * n + r), + (a[2 * o] = Math.cos(i)), + (a[2 * o + 1] = Math.sin(-i))); + return a; + }, + nn = function (e, t) { + return Math.min(e / 4, t / 4, 8); + }, + rn = function (e, t) { + return Math.min(e / 10, t / 10, 8); + }, + an = function (e, t) { + return { + heightOffset: Math.min(15, 0.05 * t), + widthOffset: Math.min(100, 0.25 * e), + ctrlPtOffsetPct: 0.05, + }; + }, + on = He({ + dampingFactor: 0.8, + precision: 1e-6, + iterations: 200, + weight: function (e) { + return 1; + }, + }), + sn = { + pageRank: function (e) { + for ( + var t = on(e), + n = t.dampingFactor, + r = t.precision, + i = t.iterations, + a = t.weight, + o = this._private.cy, + s = this.byGroup(), + l = s.nodes, + u = s.edges, + c = l.length, + d = c * c, + h = u.length, + p = new Array(d), + f = new Array(c), + g = (1 - n) / c, + v = 0; + v < c; + v++ + ) { + for (var y = 0; y < c; y++) { + p[v * c + y] = 0; + } + f[v] = 0; + } + for (var m = 0; m < h; m++) { + var b = u[m], + x = b.data("source"), + w = b.data("target"); + if (x !== w) { + var E = l.indexOfId(x), + k = l.indexOfId(w), + C = a(b); + ((p[k * c + E] += C), (f[E] += C)); + } + } + for (var S = 1 / c + g, P = 0; P < c; P++) + if (0 === f[P]) + for (var D = 0; D < c; D++) { + p[D * c + P] = S; + } + else + for (var T = 0; T < c; T++) { + var _ = T * c + P; + p[_] = p[_] / f[P] + g; + } + for (var M, B = new Array(c), N = new Array(c), z = 0; z < c; z++) + B[z] = 1; + for (var I = 0; I < i; I++) { + for (var A = 0; A < c; A++) N[A] = 0; + for (var L = 0; L < c; L++) + for (var O = 0; O < c; O++) { + var R = L * c + O; + N[L] += p[R] * B[O]; + } + (St(N), (M = B), (B = N), (N = M)); + for (var V = 0, F = 0; F < c; F++) { + var j = M[F] - B[F]; + V += j * j; + } + if (V < r) break; + } + return { + rank: function (e) { + return ((e = o.collection(e)[0]), B[l.indexOf(e)]); + }, + }; + }, + }, + ln = He({ + root: null, + weight: function (e) { + return 1; + }, + directed: !1, + alpha: 0, + }), + un = { + degreeCentralityNormalized: function (e) { + e = ln(e); + var t = this.cy(), + n = this.nodes(), + r = n.length; + if (e.directed) { + for (var i = {}, a = {}, o = 0, s = 0, l = 0; l < r; l++) { + var u = n[l], + c = u.id(); + e.root = u; + var d = this.degreeCentrality(e); + (o < d.indegree && (o = d.indegree), + s < d.outdegree && (s = d.outdegree), + (i[c] = d.indegree), + (a[c] = d.outdegree)); + } + return { + indegree: function (e) { + return 0 == o ? 0 : (v(e) && (e = t.filter(e)), i[e.id()] / o); + }, + outdegree: function (e) { + return 0 === s ? 0 : (v(e) && (e = t.filter(e)), a[e.id()] / s); + }, + }; + } + for (var h = {}, p = 0, f = 0; f < r; f++) { + var g = n[f]; + e.root = g; + var y = this.degreeCentrality(e); + (p < y.degree && (p = y.degree), (h[g.id()] = y.degree)); + } + return { + degree: function (e) { + return 0 === p ? 0 : (v(e) && (e = t.filter(e)), h[e.id()] / p); + }, + }; + }, + degreeCentrality: function (e) { + e = ln(e); + var t = this.cy(), + n = this, + r = e, + i = r.root, + a = r.weight, + o = r.directed, + s = r.alpha; + if (((i = t.collection(i)[0]), o)) { + for ( + var l = i.connectedEdges(), + u = l.filter(function (e) { + return e.target().same(i) && n.has(e); + }), + c = l.filter(function (e) { + return e.source().same(i) && n.has(e); + }), + d = u.length, + h = c.length, + p = 0, + f = 0, + g = 0; + g < u.length; + g++ + ) + p += a(u[g]); + for (var v = 0; v < c.length; v++) f += a(c[v]); + return { + indegree: Math.pow(d, 1 - s) * Math.pow(p, s), + outdegree: Math.pow(h, 1 - s) * Math.pow(f, s), + }; + } + for ( + var y = i.connectedEdges().intersection(n), + m = y.length, + b = 0, + x = 0; + x < y.length; + x++ + ) + b += a(y[x]); + return { degree: Math.pow(m, 1 - s) * Math.pow(b, s) }; + }, + }; + ((un.dc = un.degreeCentrality), + (un.dcn = un.degreeCentralityNormalised = un.degreeCentralityNormalized)); + var cn = He({ + harmonic: !0, + weight: function () { + return 1; + }, + directed: !1, + root: null, + }), + dn = { + closenessCentralityNormalized: function (e) { + for ( + var t = cn(e), + n = t.harmonic, + r = t.weight, + i = t.directed, + a = this.cy(), + o = {}, + s = 0, + l = this.nodes(), + u = this.floydWarshall({ weight: r, directed: i }), + c = 0; + c < l.length; + c++ + ) { + for (var d = 0, h = l[c], p = 0; p < l.length; p++) + if (c !== p) { + var f = u.distance(h, l[p]); + d += n ? 1 / f : f; + } + (n || (d = 1 / d), s < d && (s = d), (o[h.id()] = d)); + } + return { + closeness: function (e) { + return 0 == s + ? 0 + : ((e = v(e) ? a.filter(e)[0].id() : e.id()), o[e] / s); + }, + }; + }, + closenessCentrality: function (e) { + var t = cn(e), + n = t.root, + r = t.weight, + i = t.directed, + a = t.harmonic; + n = this.filter(n)[0]; + for ( + var o = this.dijkstra({ root: n, weight: r, directed: i }), + s = 0, + l = this.nodes(), + u = 0; + u < l.length; + u++ + ) { + var c = l[u]; + if (!c.same(n)) { + var d = o.distanceTo(c); + s += a ? 1 / d : d; + } + } + return a ? s : 1 / s; + }, + }; + ((dn.cc = dn.closenessCentrality), + (dn.ccn = dn.closenessCentralityNormalised = + dn.closenessCentralityNormalized)); + var hn = He({ weight: null, directed: !1 }), + pn = { + betweennessCentrality: function (e) { + for ( + var t = hn(e), + n = t.directed, + r = t.weight, + i = null != r, + a = this.cy(), + o = this.nodes(), + s = {}, + l = {}, + u = 0, + c = function (e, t) { + ((l[e] = t), t > u && (u = t)); + }, + d = function (e) { + return l[e]; + }, + h = 0; + h < o.length; + h++ + ) { + var p = o[h], + f = p.id(); + ((s[f] = n ? p.outgoers().nodes() : p.openNeighborhood().nodes()), + c(f, 0)); + } + for ( + var g = function (e) { + for ( + var t = o[e].id(), + n = [], + l = {}, + u = {}, + h = {}, + p = new rt(function (e, t) { + return h[e] - h[t]; + }), + f = 0; + f < o.length; + f++ + ) { + var g = o[f].id(); + ((l[g] = []), (u[g] = 0), (h[g] = 1 / 0)); + } + for (u[t] = 1, h[t] = 0, p.push(t); !p.empty(); ) { + var v = p.pop(); + if ((n.push(v), i)) + for (var y = 0; y < s[v].length; y++) { + var m = s[v][y], + b = a.getElementById(v), + x = void 0; + x = + b.edgesTo(m).length > 0 + ? b.edgesTo(m)[0] + : m.edgesTo(b)[0]; + var w = r(x); + ((m = m.id()), + h[m] > h[v] + w && + ((h[m] = h[v] + w), + p.nodes.indexOf(m) < 0 ? p.push(m) : p.updateItem(m), + (u[m] = 0), + (l[m] = [])), + h[m] == h[v] + w && ((u[m] = u[m] + u[v]), l[m].push(v))); + } + else + for (var E = 0; E < s[v].length; E++) { + var k = s[v][E].id(); + (h[k] == 1 / 0 && (p.push(k), (h[k] = h[v] + 1)), + h[k] == h[v] + 1 && ((u[k] = u[k] + u[v]), l[k].push(v))); + } + } + for (var C = {}, S = 0; S < o.length; S++) C[o[S].id()] = 0; + for (; n.length > 0; ) { + for (var P = n.pop(), D = 0; D < l[P].length; D++) { + var T = l[P][D]; + C[T] = C[T] + (u[T] / u[P]) * (1 + C[P]); + } + P != o[e].id() && c(P, d(P) + C[P]); + } + }, + v = 0; + v < o.length; + v++ + ) + g(v); + var y = { + betweenness: function (e) { + var t = a.collection(e).id(); + return d(t); + }, + betweennessNormalized: function (e) { + if (0 == u) return 0; + var t = a.collection(e).id(); + return d(t) / u; + }, + }; + return ((y.betweennessNormalised = y.betweennessNormalized), y); + }, + }; + pn.bc = pn.betweennessCentrality; + var fn = He({ + expandFactor: 2, + inflateFactor: 2, + multFactor: 1, + maxIterations: 20, + attributes: [ + function (e) { + return 1; + }, + ], + }), + gn = function (e, t) { + for (var n = 0, r = 0; r < t.length; r++) n += t[r](e); + return n; + }, + vn = function (e, t) { + for (var n, r = 0; r < t; r++) { + n = 0; + for (var i = 0; i < t; i++) n += e[i * t + r]; + for (var a = 0; a < t; a++) e[a * t + r] = e[a * t + r] / n; + } + }, + yn = function (e, t, n) { + for (var r = new Array(n * n), i = 0; i < n; i++) { + for (var a = 0; a < n; a++) r[i * n + a] = 0; + for (var o = 0; o < n; o++) + for (var s = 0; s < n; s++) + r[i * n + s] += e[i * n + o] * t[o * n + s]; + } + return r; + }, + mn = function (e, t, n) { + for (var r = e.slice(0), i = 1; i < n; i++) e = yn(e, r, t); + return e; + }, + bn = function (e, t, n) { + for (var r = new Array(t * t), i = 0; i < t * t; i++) + r[i] = Math.pow(e[i], n); + return (vn(r, t), r); + }, + xn = function (e, t, n, r) { + for (var i = 0; i < n; i++) { + if ( + Math.round(e[i] * Math.pow(10, r)) / Math.pow(10, r) !== + Math.round(t[i] * Math.pow(10, r)) / Math.pow(10, r) + ) + return !1; + } + return !0; + }, + wn = function (e, t) { + for (var n = 0; n < e.length; n++) + if (!t[n] || e[n].id() !== t[n].id()) return !1; + return !0; + }, + En = function (e) { + for ( + var t = this.nodes(), + n = this.edges(), + r = this.cy(), + i = (function (e) { + return fn(e); + })(e), + a = {}, + o = 0; + o < t.length; + o++ + ) + a[t[o].id()] = o; + for (var s, l = t.length, u = l * l, c = new Array(u), d = 0; d < u; d++) + c[d] = 0; + for (var h = 0; h < n.length; h++) { + var p = n[h], + f = a[p.source().id()], + g = a[p.target().id()], + v = gn(p, i.attributes); + ((c[f * l + g] += v), (c[g * l + f] += v)); + } + (!(function (e, t, n) { + for (var r = 0; r < t; r++) e[r * t + r] = n; + })(c, l, i.multFactor), + vn(c, l)); + for (var y = !0, m = 0; y && m < i.maxIterations; ) + ((y = !1), + (s = mn(c, l, i.expandFactor)), + (c = bn(s, l, i.inflateFactor)), + xn(c, s, u, 4) || (y = !0), + m++); + var b = (function (e, t, n, r) { + for (var i = [], a = 0; a < t; a++) { + for (var o = [], s = 0; s < t; s++) + Math.round(1e3 * e[a * t + s]) / 1e3 > 0 && o.push(n[s]); + 0 !== o.length && i.push(r.collection(o)); + } + return i; + })(c, l, t, r); + return (b = (function (e) { + for (var t = 0; t < e.length; t++) + for (var n = 0; n < e.length; n++) + t != n && wn(e[t], e[n]) && e.splice(n, 1); + return e; + })(b)); + }, + kn = { markovClustering: En, mcl: En }, + Cn = function (e) { + return e; + }, + Sn = function (e, t) { + return Math.abs(t - e); + }, + Pn = function (e, t, n) { + return e + Sn(t, n); + }, + Dn = function (e, t, n) { + return e + Math.pow(n - t, 2); + }, + Tn = function (e) { + return Math.sqrt(e); + }, + _n = function (e, t, n) { + return Math.max(e, Sn(t, n)); + }, + Mn = function (e, t, n, r, i) { + for ( + var a = + arguments.length > 5 && void 0 !== arguments[5] ? arguments[5] : Cn, + o = r, + s = 0; + s < e; + s++ + ) + o = i(o, t(s), n(s)); + return a(o); + }, + Bn = { + euclidean: function (e, t, n) { + return e >= 2 ? Mn(e, t, n, 0, Dn, Tn) : Mn(e, t, n, 0, Pn); + }, + squaredEuclidean: function (e, t, n) { + return Mn(e, t, n, 0, Dn); + }, + manhattan: function (e, t, n) { + return Mn(e, t, n, 0, Pn); + }, + max: function (e, t, n) { + return Mn(e, t, n, -1 / 0, _n); + }, + }; + function Nn(e, t, n, r, i, a) { + var o; + return ( + (o = y(e) ? e : Bn[e] || Bn.euclidean), + 0 === t && y(e) ? o(i, a) : o(t, n, r, i, a) + ); + } + ((Bn["squared-euclidean"] = Bn.squaredEuclidean), + (Bn.squaredeuclidean = Bn.squaredEuclidean)); + var zn = He({ + k: 2, + m: 2, + sensitivityThreshold: 1e-4, + distance: "euclidean", + maxIterations: 10, + attributes: [], + testMode: !1, + testCentroids: null, + }), + In = function (e) { + return zn(e); + }, + An = function (e, t, n, r, i) { + var a = + "kMedoids" !== i + ? function (e) { + return n[e]; + } + : function (e) { + return r[e](n); + }, + o = n, + s = t; + return Nn( + e, + r.length, + a, + function (e) { + return r[e](t); + }, + o, + s, + ); + }, + Ln = function (e, t, n) { + for ( + var r = n.length, + i = new Array(r), + a = new Array(r), + o = new Array(t), + s = null, + l = 0; + l < r; + l++ + ) + ((i[l] = e.min(n[l]).value), (a[l] = e.max(n[l]).value)); + for (var u = 0; u < t; u++) { + s = []; + for (var c = 0; c < r; c++) s[c] = Math.random() * (a[c] - i[c]) + i[c]; + o[u] = s; + } + return o; + }, + On = function (e, t, n, r, i) { + for (var a = 1 / 0, o = 0, s = 0; s < t.length; s++) { + var l = An(n, e, t[s], r, i); + l < a && ((a = l), (o = s)); + } + return o; + }, + Rn = function (e, t, n) { + for (var r = [], i = null, a = 0; a < t.length; a++) + n[(i = t[a]).id()] === e && r.push(i); + return r; + }, + Vn = function (e, t, n) { + return Math.abs(t - e) <= n; + }, + Fn = function (e, t, n) { + for (var r = 0; r < e.length; r++) + for (var i = 0; i < e[r].length; i++) { + if (Math.abs(e[r][i] - t[r][i]) > n) return !1; + } + return !0; + }, + jn = function (e, t, n) { + for (var r = 0; r < n; r++) if (e === t[r]) return !0; + return !1; + }, + qn = function (e, t) { + var n = new Array(t); + if (e.length < 50) + for (var r = 0; r < t; r++) { + for (var i = e[Math.floor(Math.random() * e.length)]; jn(i, n, r); ) + i = e[Math.floor(Math.random() * e.length)]; + n[r] = i; + } + else + for (var a = 0; a < t; a++) + n[a] = e[Math.floor(Math.random() * e.length)]; + return n; + }, + Yn = function (e, t, n) { + for (var r = 0, i = 0; i < t.length; i++) + r += An("manhattan", t[i], e, n, "kMedoids"); + return r; + }, + Xn = function (e, t, n, r, i) { + for (var a, o, s = 0; s < t.length; s++) + for (var l = 0; l < e.length; l++) r[s][l] = Math.pow(n[s][l], i.m); + for (var u = 0; u < e.length; u++) + for (var c = 0; c < i.attributes.length; c++) { + ((a = 0), (o = 0)); + for (var d = 0; d < t.length; d++) + ((a += r[d][u] * i.attributes[c](t[d])), (o += r[d][u])); + e[u][c] = a / o; + } + }, + Wn = function (e, t, n, r, i) { + for (var a = 0; a < e.length; a++) t[a] = e[a].slice(); + for (var o, s, l, u = 2 / (i.m - 1), c = 0; c < n.length; c++) + for (var d = 0; d < r.length; d++) { + o = 0; + for (var h = 0; h < n.length; h++) + ((s = An(i.distance, r[d], n[c], i.attributes, "cmeans")), + (l = An(i.distance, r[d], n[h], i.attributes, "cmeans")), + (o += Math.pow(s / l, u))); + e[d][c] = 1 / o; + } + }, + Hn = function (e) { + var t, + n, + r, + i, + a = this.cy(), + o = this.nodes(), + s = In(e); + r = new Array(o.length); + for (var l = 0; l < o.length; l++) r[l] = new Array(s.k); + n = new Array(o.length); + for (var u = 0; u < o.length; u++) n[u] = new Array(s.k); + for (var c = 0; c < o.length; c++) { + for (var d = 0, h = 0; h < s.k; h++) + ((n[c][h] = Math.random()), (d += n[c][h])); + for (var p = 0; p < s.k; p++) n[c][p] = n[c][p] / d; + } + t = new Array(s.k); + for (var f = 0; f < s.k; f++) t[f] = new Array(s.attributes.length); + i = new Array(o.length); + for (var g = 0; g < o.length; g++) i[g] = new Array(s.k); + for (var v = !0, y = 0; v && y < s.maxIterations; ) + ((v = !1), + Xn(t, o, n, i, s), + Wn(n, r, t, o, s), + Fn(n, r, s.sensitivityThreshold) || (v = !0), + y++); + return { + clusters: (function (e, t, n, r) { + for (var i, a, o = new Array(n.k), s = 0; s < o.length; s++) + o[s] = []; + for (var l = 0; l < t.length; l++) { + ((i = -1 / 0), (a = -1)); + for (var u = 0; u < t[0].length; u++) + t[l][u] > i && ((i = t[l][u]), (a = u)); + o[a].push(e[l]); + } + for (var c = 0; c < o.length; c++) o[c] = r.collection(o[c]); + return o; + })(o, n, s, a), + degreeOfMembership: n, + }; + }, + Kn = { + kMeans: function (t) { + var n, + r = this.cy(), + i = this.nodes(), + a = null, + o = In(t), + s = new Array(o.k), + l = {}; + o.testMode + ? "number" == typeof o.testCentroids + ? (o.testCentroids, (n = Ln(i, o.k, o.attributes))) + : (n = + "object" === e(o.testCentroids) + ? o.testCentroids + : Ln(i, o.k, o.attributes)) + : (n = Ln(i, o.k, o.attributes)); + for (var u = !0, c = 0; u && c < o.maxIterations; ) { + for (var d = 0; d < i.length; d++) + l[(a = i[d]).id()] = On(a, n, o.distance, o.attributes, "kMeans"); + u = !1; + for (var h = 0; h < o.k; h++) { + var p = Rn(h, i, l); + if (0 !== p.length) { + for ( + var f = o.attributes.length, + g = n[h], + v = new Array(f), + y = new Array(f), + m = 0; + m < f; + m++ + ) { + y[m] = 0; + for (var b = 0; b < p.length; b++) + ((a = p[b]), (y[m] += o.attributes[m](a))); + ((v[m] = y[m] / p.length), + Vn(v[m], g[m], o.sensitivityThreshold) || (u = !0)); + } + ((n[h] = v), (s[h] = r.collection(p))); + } + } + c++; + } + return s; + }, + kMedoids: function (t) { + var n, + r, + i = this.cy(), + a = this.nodes(), + o = null, + s = In(t), + l = new Array(s.k), + u = {}, + c = new Array(s.k); + s.testMode + ? "number" == typeof s.testCentroids || + (n = "object" === e(s.testCentroids) ? s.testCentroids : qn(a, s.k)) + : (n = qn(a, s.k)); + for (var d = !0, h = 0; d && h < s.maxIterations; ) { + for (var p = 0; p < a.length; p++) + u[(o = a[p]).id()] = On(o, n, s.distance, s.attributes, "kMedoids"); + d = !1; + for (var f = 0; f < n.length; f++) { + var g = Rn(f, a, u); + if (0 !== g.length) { + c[f] = Yn(n[f], g, s.attributes); + for (var v = 0; v < g.length; v++) + (r = Yn(g[v], g, s.attributes)) < c[f] && + ((c[f] = r), (n[f] = g[v]), (d = !0)); + l[f] = i.collection(g); + } + } + h++; + } + return l; + }, + fuzzyCMeans: Hn, + fcm: Hn, + }, + Gn = He({ + distance: "euclidean", + linkage: "min", + mode: "threshold", + threshold: 1 / 0, + addDendrogram: !1, + dendrogramDepth: 0, + attributes: [], + }), + Un = { single: "min", complete: "max" }, + Zn = function (e, t, n, r, i) { + for ( + var a, + o = 0, + s = 1 / 0, + l = i.attributes, + u = function (e, t) { + return Nn( + i.distance, + l.length, + function (t) { + return l[t](e); + }, + function (e) { + return l[e](t); + }, + e, + t, + ); + }, + c = 0; + c < e.length; + c++ + ) { + var d = e[c].key, + h = n[d][r[d]]; + h < s && ((o = d), (s = h)); + } + if ( + ("threshold" === i.mode && s >= i.threshold) || + ("dendrogram" === i.mode && 1 === e.length) + ) + return !1; + var p, + f = t[o], + g = t[r[o]]; + ((p = + "dendrogram" === i.mode + ? { left: f, right: g, key: f.key } + : { value: f.value.concat(g.value), key: f.key }), + (e[f.index] = p), + e.splice(g.index, 1), + (t[f.key] = p)); + for (var v = 0; v < e.length; v++) { + var y = e[v]; + (f.key === y.key + ? (a = 1 / 0) + : "min" === i.linkage + ? ((a = n[f.key][y.key]), + n[f.key][y.key] > n[g.key][y.key] && (a = n[g.key][y.key])) + : "max" === i.linkage + ? ((a = n[f.key][y.key]), + n[f.key][y.key] < n[g.key][y.key] && (a = n[g.key][y.key])) + : (a = + "mean" === i.linkage + ? (n[f.key][y.key] * f.size + n[g.key][y.key] * g.size) / + (f.size + g.size) + : "dendrogram" === i.mode + ? u(y.value, f.value) + : u(y.value[0], f.value[0])), + (n[f.key][y.key] = n[y.key][f.key] = a)); + } + for (var m = 0; m < e.length; m++) { + var b = e[m].key; + if (r[b] === f.key || r[b] === g.key) { + for (var x = b, w = 0; w < e.length; w++) { + var E = e[w].key; + n[b][E] < n[b][x] && (x = E); + } + r[b] = x; + } + e[m].index = m; + } + return ((f.key = g.key = f.index = g.index = null), !0); + }, + $n = function e(t, n, r) { + t && + (t.value + ? n.push(t.value) + : (t.left && e(t.left, n), t.right && e(t.right, n))); + }, + Qn = function (e) { + for ( + var t = this.cy(), + n = this.nodes(), + r = (function (e) { + var t = Gn(e), + n = Un[t.linkage]; + return (null != n && (t.linkage = n), t); + })(e), + i = r.attributes, + a = function (e, t) { + return Nn( + r.distance, + i.length, + function (t) { + return i[t](e); + }, + function (e) { + return i[e](t); + }, + e, + t, + ); + }, + o = [], + s = [], + l = [], + u = [], + c = 0; + c < n.length; + c++ + ) { + var d = { + value: "dendrogram" === r.mode ? n[c] : [n[c]], + key: c, + index: c, + }; + ((o[c] = d), (u[c] = d), (s[c] = []), (l[c] = 0)); + } + for (var h = 0; h < o.length; h++) + for (var p = 0; p <= h; p++) { + var f = void 0; + ((f = + "dendrogram" === r.mode + ? h === p + ? 1 / 0 + : a(o[h].value, o[p].value) + : h === p + ? 1 / 0 + : a(o[h].value[0], o[p].value[0])), + (s[h][p] = f), + (s[p][h] = f), + f < s[h][l[h]] && (l[h] = p)); + } + for (var g, v = Zn(o, u, s, l, r); v; ) v = Zn(o, u, s, l, r); + return ( + "dendrogram" === r.mode + ? ((g = (function e(t, n, r) { + if (!t) return []; + var i = [], + a = [], + o = []; + return 0 === n + ? (t.left && $n(t.left, i), + t.right && $n(t.right, a), + (o = i.concat(a)), + [r.collection(o)]) + : 1 === n + ? t.value + ? [r.collection(t.value)] + : (t.left && $n(t.left, i), + t.right && $n(t.right, a), + [r.collection(i), r.collection(a)]) + : t.value + ? [r.collection(t.value)] + : (t.left && (i = e(t.left, n - 1, r)), + t.right && (a = e(t.right, n - 1, r)), + i.concat(a)); + })(o[0], r.dendrogramDepth, t)), + r.addDendrogram && + (function e(t, n) { + if (!t) return ""; + if (t.left && t.right) { + var r = e(t.left, n), + i = e(t.right, n), + a = n.add({ group: "nodes", data: { id: r + "," + i } }); + return ( + n.add({ + group: "edges", + data: { source: r, target: a.id() }, + }), + n.add({ + group: "edges", + data: { source: i, target: a.id() }, + }), + a.id() + ); + } + return t.value ? t.value.id() : void 0; + })(o[0], t)) + : ((g = new Array(o.length)), + o.forEach(function (e, n) { + ((e.key = e.index = null), (g[n] = t.collection(e.value))); + })), + g + ); + }, + Jn = { hierarchicalClustering: Qn, hca: Qn }, + er = He({ + distance: "euclidean", + preference: "median", + damping: 0.8, + maxIterations: 1e3, + minIterations: 100, + attributes: [], + }), + tr = function (e, t, n, r) { + var i = function (e, t) { + return r[t](e); + }; + return -Nn( + e, + r.length, + function (e) { + return i(t, e); + }, + function (e) { + return i(n, e); + }, + t, + n, + ); + }, + nr = function (e, t) { + return "median" === t + ? (function (e) { + var t = + arguments.length > 1 && void 0 !== arguments[1] + ? arguments[1] + : 0, + n = + arguments.length > 2 && void 0 !== arguments[2] + ? arguments[2] + : e.length, + r = + !(arguments.length > 3 && void 0 !== arguments[3]) || + arguments[3], + i = + !(arguments.length > 4 && void 0 !== arguments[4]) || + arguments[4], + a = + !(arguments.length > 5 && void 0 !== arguments[5]) || + arguments[5]; + r + ? (e = e.slice(t, n)) + : (n < e.length && e.splice(n, e.length - n), + t > 0 && e.splice(0, t)); + for (var o = 0, s = e.length - 1; s >= 0; s--) { + var l = e[s]; + a ? isFinite(l) || ((e[s] = -1 / 0), o++) : e.splice(s, 1); + } + i && + e.sort(function (e, t) { + return e - t; + }); + var u = e.length, + c = Math.floor(u / 2); + return u % 2 != 0 ? e[c + 1 + o] : (e[c - 1 + o] + e[c + o]) / 2; + })(e) + : "mean" === t + ? (function (e) { + for ( + var t = + arguments.length > 1 && void 0 !== arguments[1] + ? arguments[1] + : 0, + n = + arguments.length > 2 && void 0 !== arguments[2] + ? arguments[2] + : e.length, + r = 0, + i = 0, + a = t; + a < n; + a++ + ) { + var o = e[a]; + isFinite(o) && ((r += o), i++); + } + return r / i; + })(e) + : "min" === t + ? (function (e) { + for ( + var t = + arguments.length > 1 && void 0 !== arguments[1] + ? arguments[1] + : 0, + n = + arguments.length > 2 && void 0 !== arguments[2] + ? arguments[2] + : e.length, + r = 1 / 0, + i = t; + i < n; + i++ + ) { + var a = e[i]; + isFinite(a) && (r = Math.min(a, r)); + } + return r; + })(e) + : "max" === t + ? (function (e) { + for ( + var t = + arguments.length > 1 && void 0 !== arguments[1] + ? arguments[1] + : 0, + n = + arguments.length > 2 && void 0 !== arguments[2] + ? arguments[2] + : e.length, + r = -1 / 0, + i = t; + i < n; + i++ + ) { + var a = e[i]; + isFinite(a) && (r = Math.max(a, r)); + } + return r; + })(e) + : t; + }, + rr = function (e, t, n) { + for (var r = [], i = 0; i < e; i++) { + for (var a = -1, o = -1 / 0, s = 0; s < n.length; s++) { + var l = n[s]; + t[i * e + l] > o && ((a = l), (o = t[i * e + l])); + } + a > 0 && r.push(a); + } + for (var u = 0; u < n.length; u++) r[n[u]] = n[u]; + return r; + }, + ir = function (e) { + for ( + var t, + n, + r, + i, + a, + o, + s = this.cy(), + l = this.nodes(), + u = (function (e) { + var t = e.damping, + n = e.preference; + (0.5 <= t && t < 1) || + Ve("Damping must range on [0.5, 1). Got: ".concat(t)); + var r = ["median", "mean", "min", "max"]; + return ( + r.some(function (e) { + return e === n; + }) || + x(n) || + Ve( + "Preference must be one of [" + .concat( + r + .map(function (e) { + return "'".concat(e, "'"); + }) + .join(", "), + "] or a number. Got: ", + ) + .concat(n), + ), + er(e) + ); + })(e), + c = {}, + d = 0; + d < l.length; + d++ + ) + c[l[d].id()] = d; + ((n = (t = l.length) * t), (r = new Array(n))); + for (var h = 0; h < n; h++) r[h] = -1 / 0; + for (var p = 0; p < t; p++) + for (var f = 0; f < t; f++) + p !== f && (r[p * t + f] = tr(u.distance, l[p], l[f], u.attributes)); + i = nr(r, u.preference); + for (var g = 0; g < t; g++) r[g * t + g] = i; + a = new Array(n); + for (var v = 0; v < n; v++) a[v] = 0; + o = new Array(n); + for (var y = 0; y < n; y++) o[y] = 0; + for ( + var m = new Array(t), b = new Array(t), w = new Array(t), E = 0; + E < t; + E++ + ) + ((m[E] = 0), (b[E] = 0), (w[E] = 0)); + for (var k, C = new Array(t * u.minIterations), S = 0; S < C.length; S++) + C[S] = 0; + for (k = 0; k < u.maxIterations; k++) { + for (var P = 0; P < t; P++) { + for (var D = -1 / 0, T = -1 / 0, _ = -1, M = 0, B = 0; B < t; B++) + ((m[B] = a[P * t + B]), + (M = o[P * t + B] + r[P * t + B]) >= D + ? ((T = D), (D = M), (_ = B)) + : M > T && (T = M)); + for (var N = 0; N < t; N++) + a[P * t + N] = + (1 - u.damping) * (r[P * t + N] - D) + u.damping * m[N]; + a[P * t + _] = + (1 - u.damping) * (r[P * t + _] - T) + u.damping * m[_]; + } + for (var z = 0; z < t; z++) { + for (var I = 0, A = 0; A < t; A++) + ((m[A] = o[A * t + z]), + (b[A] = Math.max(0, a[A * t + z])), + (I += b[A])); + ((I -= b[z]), (b[z] = a[z * t + z]), (I += b[z])); + for (var L = 0; L < t; L++) + o[L * t + z] = + (1 - u.damping) * Math.min(0, I - b[L]) + u.damping * m[L]; + o[z * t + z] = (1 - u.damping) * (I - b[z]) + u.damping * m[z]; + } + for (var O = 0, R = 0; R < t; R++) { + var V = o[R * t + R] + a[R * t + R] > 0 ? 1 : 0; + ((C[(k % u.minIterations) * t + R] = V), (O += V)); + } + if (O > 0 && (k >= u.minIterations - 1 || k == u.maxIterations - 1)) { + for (var F = 0, j = 0; j < t; j++) { + w[j] = 0; + for (var q = 0; q < u.minIterations; q++) w[j] += C[q * t + j]; + (0 !== w[j] && w[j] !== u.minIterations) || F++; + } + if (F === t) break; + } + } + for ( + var Y = (function (e, t, n) { + for (var r = [], i = 0; i < e; i++) + t[i * e + i] + n[i * e + i] > 0 && r.push(i); + return r; + })(t, a, o), + X = (function (e, t, n) { + for (var r = rr(e, t, n), i = 0; i < n.length; i++) { + for (var a = [], o = 0; o < r.length; o++) + r[o] === n[i] && a.push(o); + for (var s = -1, l = -1 / 0, u = 0; u < a.length; u++) { + for (var c = 0, d = 0; d < a.length; d++) + c += t[a[d] * e + a[u]]; + c > l && ((s = u), (l = c)); + } + n[i] = a[s]; + } + return (r = rr(e, t, n)); + })(t, r, Y), + W = {}, + H = 0; + H < Y.length; + H++ + ) + W[Y[H]] = []; + for (var K = 0; K < l.length; K++) { + var G = X[c[l[K].id()]]; + null != G && W[G].push(l[K]); + } + for (var U = new Array(Y.length), Z = 0; Z < Y.length; Z++) + U[Z] = s.collection(W[Y[Z]]); + return U; + }, + ar = { affinityPropagation: ir, ap: ir }, + or = He({ root: void 0, directed: !1 }), + sr = function () { + var e = this, + t = {}, + n = 0, + r = 0, + i = [], + a = [], + o = {}, + s = function s(l, u, c) { + (l === c && (r += 1), (t[u] = { id: n, low: n++, cutVertex: !1 })); + var d, + h, + p, + f, + g = e.getElementById(u).connectedEdges().intersection(e); + 0 === g.size() + ? i.push(e.spawn(e.getElementById(u))) + : g.forEach(function (n) { + ((d = n.source().id()), + (h = n.target().id()), + (p = d === u ? h : d) !== c && + ((f = n.id()), + o[f] || ((o[f] = !0), a.push({ x: u, y: p, edge: n })), + p in t + ? (t[u].low = Math.min(t[u].low, t[p].id)) + : (s(l, p, u), + (t[u].low = Math.min(t[u].low, t[p].low)), + t[u].id <= t[p].low && + ((t[u].cutVertex = !0), + (function (n, r) { + for ( + var o = a.length - 1, s = [], l = e.spawn(); + a[o].x != n || a[o].y != r; + ) + (s.push(a.pop().edge), o--); + (s.push(a.pop().edge), + s.forEach(function (n) { + var r = n.connectedNodes().intersection(e); + (l.merge(n), + r.forEach(function (n) { + var r = n.id(), + i = n.connectedEdges().intersection(e); + (l.merge(n), + t[r].cutVertex + ? l.merge( + i.filter(function (e) { + return e.isLoop(); + }), + ) + : l.merge(i)); + })); + }), + i.push(l)); + })(u, p))))); + }); + }; + e.forEach(function (e) { + if (e.isNode()) { + var n = e.id(); + n in t || ((r = 0), s(n, n), (t[n].cutVertex = r > 1)); + } + }); + var l = Object.keys(t) + .filter(function (e) { + return t[e].cutVertex; + }) + .map(function (t) { + return e.getElementById(t); + }); + return { cut: e.spawn(l), components: i }; + }, + lr = function () { + var e = this, + t = {}, + n = 0, + r = [], + i = [], + a = e.spawn(e); + return ( + e.forEach(function (o) { + if (o.isNode()) { + var s = o.id(); + s in t || + (function o(s) { + if ( + (i.push(s), + (t[s] = { index: n, low: n++, explored: !1 }), + e + .getElementById(s) + .connectedEdges() + .intersection(e) + .forEach(function (e) { + var n = e.target().id(); + n !== s && + (n in t || o(n), + t[n].explored || + (t[s].low = Math.min(t[s].low, t[n].low))); + }), + t[s].index === t[s].low) + ) { + for (var l = e.spawn(); ; ) { + var u = i.pop(); + if ( + (l.merge(e.getElementById(u)), + (t[u].low = t[s].index), + (t[u].explored = !0), + u === s) + ) + break; + } + var c = l.edgesWith(l), + d = l.merge(c); + (r.push(d), (a = a.difference(d))); + } + })(s); + } + }), + { cut: a, components: r } + ); + }, + ur = {}; + [ + nt, + at, + ot, + lt, + ct, + ht, + vt, + sn, + un, + dn, + pn, + kn, + Kn, + Jn, + ar, + { + hierholzer: function (e) { + if (!b(e)) { + var t = arguments; + e = { root: t[0], directed: t[1] }; + } + var n, + r, + i, + a = or(e), + o = a.root, + s = a.directed, + l = this, + u = !1; + o && (i = v(o) ? this.filter(o)[0].id() : o[0].id()); + var c = {}, + d = {}; + s + ? l.forEach(function (e) { + var t = e.id(); + if (e.isNode()) { + var i = e.indegree(!0), + a = e.outdegree(!0), + o = i - a, + s = a - i; + (1 == o + ? n + ? (u = !0) + : (n = t) + : 1 == s + ? r + ? (u = !0) + : (r = t) + : (s > 1 || o > 1) && (u = !0), + (c[t] = []), + e.outgoers().forEach(function (e) { + e.isEdge() && c[t].push(e.id()); + })); + } else d[t] = [void 0, e.target().id()]; + }) + : l.forEach(function (e) { + var t = e.id(); + e.isNode() + ? (e.degree(!0) % 2 && (n ? (r ? (u = !0) : (r = t)) : (n = t)), + (c[t] = []), + e.connectedEdges().forEach(function (e) { + return c[t].push(e.id()); + })) + : (d[t] = [e.source().id(), e.target().id()]); + }); + var h = { found: !1, trail: void 0 }; + if (u) return h; + if (r && n) + if (s) { + if (i && r != i) return h; + i = r; + } else { + if (i && r != i && n != i) return h; + i || (i = r); + } + else i || (i = l[0].id()); + var p = function (e) { + for (var t, n, r, i = e, a = [e]; c[i].length; ) + ((t = c[i].shift()), + (n = d[t][0]), + i != (r = d[t][1]) + ? ((c[r] = c[r].filter(function (e) { + return e != t; + })), + (i = r)) + : s || + i == n || + ((c[n] = c[n].filter(function (e) { + return e != t; + })), + (i = n)), + a.unshift(t), + a.unshift(i)); + return a; + }, + f = [], + g = []; + for (g = p(i); 1 != g.length; ) + 0 == c[g[0]].length + ? (f.unshift(l.getElementById(g.shift())), + f.unshift(l.getElementById(g.shift()))) + : (g = p(g.shift()).concat(g)); + for (var y in (f.unshift(l.getElementById(g.shift())), c)) + if (c[y].length) return h; + return ((h.found = !0), (h.trail = this.spawn(f, !0)), h); + }, + }, + { + hopcroftTarjanBiconnected: sr, + htbc: sr, + htb: sr, + hopcroftTarjanBiconnectedComponents: sr, + }, + { + tarjanStronglyConnected: lr, + tsc: lr, + tscc: lr, + tarjanStronglyConnectedComponents: lr, + }, + ].forEach(function (e) { + L(ur, e); + }); + /*! + Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable + Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com) + Licensed under The MIT License (http://opensource.org/licenses/MIT) + */ + var cr = function e(t) { + if (!(this instanceof e)) return new e(t); + ((this.id = "Thenable/1.0.7"), + (this.state = 0), + (this.fulfillValue = void 0), + (this.rejectReason = void 0), + (this.onFulfilled = []), + (this.onRejected = []), + (this.proxy = { then: this.then.bind(this) }), + "function" == typeof t && + t.call(this, this.fulfill.bind(this), this.reject.bind(this))); + }; + cr.prototype = { + fulfill: function (e) { + return dr(this, 1, "fulfillValue", e); + }, + reject: function (e) { + return dr(this, 2, "rejectReason", e); + }, + then: function (e, t) { + var n = new cr(); + return ( + this.onFulfilled.push(fr(e, n, "fulfill")), + this.onRejected.push(fr(t, n, "reject")), + hr(this), + n.proxy + ); + }, + }; + var dr = function (e, t, n, r) { + return (0 === e.state && ((e.state = t), (e[n] = r), hr(e)), e); + }, + hr = function (e) { + 1 === e.state + ? pr(e, "onFulfilled", e.fulfillValue) + : 2 === e.state && pr(e, "onRejected", e.rejectReason); + }, + pr = function (e, t, n) { + if (0 !== e[t].length) { + var r = e[t]; + e[t] = []; + var i = function () { + for (var e = 0; e < r.length; e++) r[e](n); + }; + "function" == typeof setImmediate ? setImmediate(i) : setTimeout(i, 0); + } + }, + fr = function (e, t, n) { + return function (r) { + if ("function" != typeof e) t[n].call(t, r); + else { + var i; + try { + i = e(r); + } catch (e) { + return void t.reject(e); + } + gr(t, i); + } + }; + }, + gr = function t(n, r) { + if (n !== r && n.proxy !== r) { + var i; + if (("object" === e(r) && null !== r) || "function" == typeof r) + try { + i = r.then; + } catch (e) { + return void n.reject(e); + } + if ("function" != typeof i) n.fulfill(r); + else { + var a = !1; + try { + i.call( + r, + function (e) { + a || + ((a = !0), + e === r + ? n.reject(new TypeError("circular thenable chain")) + : t(n, e)); + }, + function (e) { + a || ((a = !0), n.reject(e)); + }, + ); + } catch (e) { + a || n.reject(e); + } + } + } else n.reject(new TypeError("cannot resolve promise with itself")); + }; + ((cr.all = function (e) { + return new cr(function (t, n) { + for ( + var r = new Array(e.length), + i = 0, + a = function (n, a) { + ((r[n] = a), ++i === e.length && t(r)); + }, + o = 0; + o < e.length; + o++ + ) + !(function (t) { + var r = e[t]; + null != r && null != r.then + ? r.then( + function (e) { + a(t, e); + }, + function (e) { + n(e); + }, + ) + : a(t, r); + })(o); + }); + }), + (cr.resolve = function (e) { + return new cr(function (t, n) { + t(e); + }); + }), + (cr.reject = function (e) { + return new cr(function (t, n) { + n(e); + }); + })); + var vr = "undefined" != typeof Promise ? Promise : cr, + yr = function (e, t, n) { + var r = S(e), + i = !r, + a = (this._private = L({ duration: 1e3 }, t, n)); + if ( + ((a.target = e), + (a.style = a.style || a.css), + (a.started = !1), + (a.playing = !1), + (a.hooked = !1), + (a.applying = !1), + (a.progress = 0), + (a.completes = []), + (a.frames = []), + a.complete && y(a.complete) && a.completes.push(a.complete), + i) + ) { + var o = e.position(); + ((a.startPosition = a.startPosition || { x: o.x, y: o.y }), + (a.startStyle = + a.startStyle || e.cy().style().getAnimationStartStyle(e, a.style))); + } + if (r) { + var s = e.pan(); + ((a.startPan = { x: s.x, y: s.y }), (a.startZoom = e.zoom())); + } + ((this.length = 1), (this[0] = this)); + }, + mr = yr.prototype; + (L(mr, { + instanceString: function () { + return "animation"; + }, + hook: function () { + var e = this._private; + if (!e.hooked) { + var t = e.target._private.animation; + ((e.queue ? t.queue : t.current).push(this), + E(e.target) && e.target.cy().addToAnimationPool(e.target), + (e.hooked = !0)); + } + return this; + }, + play: function () { + var e = this._private; + return ( + 1 === e.progress && (e.progress = 0), + (e.playing = !0), + (e.started = !1), + (e.stopped = !1), + this.hook(), + this + ); + }, + playing: function () { + return this._private.playing; + }, + apply: function () { + var e = this._private; + return ( + (e.applying = !0), + (e.started = !1), + (e.stopped = !1), + this.hook(), + this + ); + }, + applying: function () { + return this._private.applying; + }, + pause: function () { + var e = this._private; + return ((e.playing = !1), (e.started = !1), this); + }, + stop: function () { + var e = this._private; + return ((e.playing = !1), (e.started = !1), (e.stopped = !0), this); + }, + rewind: function () { + return this.progress(0); + }, + fastforward: function () { + return this.progress(1); + }, + time: function (e) { + var t = this._private; + return void 0 === e + ? t.progress * t.duration + : this.progress(e / t.duration); + }, + progress: function (e) { + var t = this._private, + n = t.playing; + return void 0 === e + ? t.progress + : (n && this.pause(), + (t.progress = e), + (t.started = !1), + n && this.play(), + this); + }, + completed: function () { + return 1 === this._private.progress; + }, + reverse: function () { + var e = this._private, + t = e.playing; + (t && this.pause(), (e.progress = 1 - e.progress), (e.started = !1)); + var n = function (t, n) { + var r = e[t]; + null != r && ((e[t] = e[n]), (e[n] = r)); + }; + if ( + (n("zoom", "startZoom"), + n("pan", "startPan"), + n("position", "startPosition"), + e.style) + ) + for (var r = 0; r < e.style.length; r++) { + var i = e.style[r], + a = i.name, + o = e.startStyle[a]; + ((e.startStyle[a] = i), (e.style[r] = o)); + } + return (t && this.play(), this); + }, + promise: function (e) { + var t, + n = this._private; + switch (e) { + case "frame": + t = n.frames; + break; + default: + case "complete": + case "completed": + t = n.completes; + } + return new vr(function (e, n) { + t.push(function () { + e(); + }); + }); + }, + }), + (mr.complete = mr.completed), + (mr.run = mr.play), + (mr.running = mr.playing)); + var br = { + animated: function () { + return function () { + var e = void 0 !== this.length ? this : [this]; + if (!(this._private.cy || this).styleEnabled()) return !1; + var t = e[0]; + return t ? t._private.animation.current.length > 0 : void 0; + }; + }, + clearQueue: function () { + return function () { + var e = void 0 !== this.length ? this : [this]; + if (!(this._private.cy || this).styleEnabled()) return this; + for (var t = 0; t < e.length; t++) { + e[t]._private.animation.queue = []; + } + return this; + }; + }, + delay: function () { + return function (e, t) { + return (this._private.cy || this).styleEnabled() + ? this.animate({ delay: e, duration: e, complete: t }) + : this; + }; + }, + delayAnimation: function () { + return function (e, t) { + return (this._private.cy || this).styleEnabled() + ? this.animation({ delay: e, duration: e, complete: t }) + : this; + }; + }, + animation: function () { + return function (e, t) { + var n = void 0 !== this.length, + r = n ? this : [this], + i = this._private.cy || this, + a = !n, + o = !a; + if (!i.styleEnabled()) return this; + var s = i.style(); + if (((e = L({}, e, t)), 0 === Object.keys(e).length)) + return new yr(r[0], e); + switch ((void 0 === e.duration && (e.duration = 400), e.duration)) { + case "slow": + e.duration = 600; + break; + case "fast": + e.duration = 200; + } + if ( + (o && + ((e.style = s.getPropsList(e.style || e.css)), (e.css = void 0)), + o && null != e.renderedPosition) + ) { + var l = e.renderedPosition, + u = i.pan(), + c = i.zoom(); + e.position = mt(l, c, u); + } + if (a && null != e.panBy) { + var d = e.panBy, + h = i.pan(); + e.pan = { x: h.x + d.x, y: h.y + d.y }; + } + var p = e.center || e.centre; + if (a && null != p) { + var f = i.getCenterPan(p.eles, e.zoom); + null != f && (e.pan = f); + } + if (a && null != e.fit) { + var g = e.fit, + v = i.getFitViewport(g.eles || g.boundingBox, g.padding); + null != v && ((e.pan = v.pan), (e.zoom = v.zoom)); + } + if (a && b(e.zoom)) { + var y = i.getZoomedViewport(e.zoom); + null != y + ? (y.zoomed && (e.zoom = y.zoom), y.panned && (e.pan = y.pan)) + : (e.zoom = null); + } + return new yr(r[0], e); + }; + }, + animate: function () { + return function (e, t) { + var n = void 0 !== this.length ? this : [this]; + if (!(this._private.cy || this).styleEnabled()) return this; + t && (e = L({}, e, t)); + for (var r = 0; r < n.length; r++) { + var i = n[r], + a = i.animated() && (void 0 === e.queue || e.queue); + i.animation(e, a ? { queue: !0 } : void 0).play(); + } + return this; + }; + }, + stop: function () { + return function (e, t) { + var n = void 0 !== this.length ? this : [this], + r = this._private.cy || this; + if (!r.styleEnabled()) return this; + for (var i = 0; i < n.length; i++) { + for ( + var a = n[i]._private, o = a.animation.current, s = 0; + s < o.length; + s++ + ) { + var l = o[s]._private; + t && (l.duration = 0); + } + (e && (a.animation.queue = []), t || (a.animation.current = [])); + } + return (r.notify("draw"), this); + }; + }, + }, + xr = Array.isArray, + wr = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + Er = /^\w*$/; + var kr = function (e, t) { + if (xr(e)) return !1; + var n = typeof e; + return ( + !( + "number" != n && + "symbol" != n && + "boolean" != n && + null != e && + !le(e) + ) || + Er.test(e) || + !wr.test(e) || + (null != t && e in Object(t)) + ); + }; + var Cr, + Sr = function (e) { + if (!j(e)) return !1; + var t = oe(e); + return ( + "[object Function]" == t || + "[object GeneratorFunction]" == t || + "[object AsyncFunction]" == t || + "[object Proxy]" == t + ); + }, + Pr = W["__core-js_shared__"], + Dr = (Cr = /[^.]+$/.exec((Pr && Pr.keys && Pr.keys.IE_PROTO) || "")) + ? "Symbol(src)_1." + Cr + : ""; + var Tr = function (e) { + return !!Dr && Dr in e; + }, + _r = Function.prototype.toString; + var Mr = function (e) { + if (null != e) { + try { + return _r.call(e); + } catch (e) {} + try { + return e + ""; + } catch (e) {} + } + return ""; + }, + Br = /^\[object .+?Constructor\]$/, + Nr = Function.prototype, + zr = Object.prototype, + Ir = Nr.toString, + Ar = zr.hasOwnProperty, + Lr = RegExp( + "^" + + Ir.call(Ar) + .replace(/[\\^$.*+?()[\]{}|]/g, "\\$&") + .replace( + /hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, + "$1.*?", + ) + + "$", + ); + var Or = function (e) { + return !(!j(e) || Tr(e)) && (Sr(e) ? Lr : Br).test(Mr(e)); + }; + var Rr = function (e, t) { + return null == e ? void 0 : e[t]; + }; + var Vr = function (e, t) { + var n = Rr(e, t); + return Or(n) ? n : void 0; + }, + Fr = Vr(Object, "create"); + var jr = function () { + ((this.__data__ = Fr ? Fr(null) : {}), (this.size = 0)); + }; + var qr = function (e) { + var t = this.has(e) && delete this.__data__[e]; + return ((this.size -= t ? 1 : 0), t); + }, + Yr = Object.prototype.hasOwnProperty; + var Xr = function (e) { + var t = this.__data__; + if (Fr) { + var n = t[e]; + return "__lodash_hash_undefined__" === n ? void 0 : n; + } + return Yr.call(t, e) ? t[e] : void 0; + }, + Wr = Object.prototype.hasOwnProperty; + var Hr = function (e) { + var t = this.__data__; + return Fr ? void 0 !== t[e] : Wr.call(t, e); + }; + var Kr = function (e, t) { + var n = this.__data__; + return ( + (this.size += this.has(e) ? 0 : 1), + (n[e] = Fr && void 0 === t ? "__lodash_hash_undefined__" : t), + this + ); + }; + function Gr(e) { + var t = -1, + n = null == e ? 0 : e.length; + for (this.clear(); ++t < n; ) { + var r = e[t]; + this.set(r[0], r[1]); + } + } + ((Gr.prototype.clear = jr), + (Gr.prototype.delete = qr), + (Gr.prototype.get = Xr), + (Gr.prototype.has = Hr), + (Gr.prototype.set = Kr)); + var Ur = Gr; + var Zr = function () { + ((this.__data__ = []), (this.size = 0)); + }; + var $r = function (e, t) { + return e === t || (e != e && t != t); + }; + var Qr = function (e, t) { + for (var n = e.length; n--; ) if ($r(e[n][0], t)) return n; + return -1; + }, + Jr = Array.prototype.splice; + var ei = function (e) { + var t = this.__data__, + n = Qr(t, e); + return ( + !(n < 0) && + (n == t.length - 1 ? t.pop() : Jr.call(t, n, 1), --this.size, !0) + ); + }; + var ti = function (e) { + var t = this.__data__, + n = Qr(t, e); + return n < 0 ? void 0 : t[n][1]; + }; + var ni = function (e) { + return Qr(this.__data__, e) > -1; + }; + var ri = function (e, t) { + var n = this.__data__, + r = Qr(n, e); + return (r < 0 ? (++this.size, n.push([e, t])) : (n[r][1] = t), this); + }; + function ii(e) { + var t = -1, + n = null == e ? 0 : e.length; + for (this.clear(); ++t < n; ) { + var r = e[t]; + this.set(r[0], r[1]); + } + } + ((ii.prototype.clear = Zr), + (ii.prototype.delete = ei), + (ii.prototype.get = ti), + (ii.prototype.has = ni), + (ii.prototype.set = ri)); + var ai = ii, + oi = Vr(W, "Map"); + var si = function () { + ((this.size = 0), + (this.__data__ = { + hash: new Ur(), + map: new (oi || ai)(), + string: new Ur(), + })); + }; + var li = function (e) { + var t = typeof e; + return "string" == t || "number" == t || "symbol" == t || "boolean" == t + ? "__proto__" !== e + : null === e; + }; + var ui = function (e, t) { + var n = e.__data__; + return li(t) ? n["string" == typeof t ? "string" : "hash"] : n.map; + }; + var ci = function (e) { + var t = ui(this, e).delete(e); + return ((this.size -= t ? 1 : 0), t); + }; + var di = function (e) { + return ui(this, e).get(e); + }; + var hi = function (e) { + return ui(this, e).has(e); + }; + var pi = function (e, t) { + var n = ui(this, e), + r = n.size; + return (n.set(e, t), (this.size += n.size == r ? 0 : 1), this); + }; + function fi(e) { + var t = -1, + n = null == e ? 0 : e.length; + for (this.clear(); ++t < n; ) { + var r = e[t]; + this.set(r[0], r[1]); + } + } + ((fi.prototype.clear = si), + (fi.prototype.delete = ci), + (fi.prototype.get = di), + (fi.prototype.has = hi), + (fi.prototype.set = pi)); + var gi = fi; + function vi(e, t) { + if ("function" != typeof e || (null != t && "function" != typeof t)) + throw new TypeError("Expected a function"); + var n = function () { + var r = arguments, + i = t ? t.apply(this, r) : r[0], + a = n.cache; + if (a.has(i)) return a.get(i); + var o = e.apply(this, r); + return ((n.cache = a.set(i, o) || a), o); + }; + return ((n.cache = new (vi.Cache || gi)()), n); + } + vi.Cache = gi; + var yi = vi; + var mi = + /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g, + bi = /\\(\\)?/g, + xi = (function (e) { + var t = yi(e, function (e) { + return (500 === n.size && n.clear(), e); + }), + n = t.cache; + return t; + })(function (e) { + var t = []; + return ( + 46 === e.charCodeAt(0) && t.push(""), + e.replace(mi, function (e, n, r, i) { + t.push(r ? i.replace(bi, "$1") : n || e); + }), + t + ); + }); + var wi = function (e, t) { + for (var n = -1, r = null == e ? 0 : e.length, i = Array(r); ++n < r; ) + i[n] = t(e[n], n, e); + return i; + }, + Ei = $ ? $.prototype : void 0, + ki = Ei ? Ei.toString : void 0; + var Ci = function e(t) { + if ("string" == typeof t) return t; + if (xr(t)) return wi(t, e) + ""; + if (le(t)) return ki ? ki.call(t) : ""; + var n = t + ""; + return "0" == n && 1 / t == -1 / 0 ? "-0" : n; + }; + var Si = function (e) { + return null == e ? "" : Ci(e); + }; + var Pi = function (e, t) { + return xr(e) ? e : kr(e, t) ? [e] : xi(Si(e)); + }; + var Di = function (e) { + if ("string" == typeof e || le(e)) return e; + var t = e + ""; + return "0" == t && 1 / e == -1 / 0 ? "-0" : t; + }; + var Ti = function (e, t) { + for (var n = 0, r = (t = Pi(t, e)).length; null != e && n < r; ) + e = e[Di(t[n++])]; + return n && n == r ? e : void 0; + }; + var _i = function (e, t, n) { + var r = null == e ? void 0 : Ti(e, t); + return void 0 === r ? n : r; + }, + Mi = (function () { + try { + var e = Vr(Object, "defineProperty"); + return (e({}, "", {}), e); + } catch (e) {} + })(); + var Bi = function (e, t, n) { + "__proto__" == t && Mi + ? Mi(e, t, { configurable: !0, enumerable: !0, value: n, writable: !0 }) + : (e[t] = n); + }, + Ni = Object.prototype.hasOwnProperty; + var zi = function (e, t, n) { + var r = e[t]; + (Ni.call(e, t) && $r(r, n) && (void 0 !== n || t in e)) || Bi(e, t, n); + }, + Ii = /^(?:0|[1-9]\d*)$/; + var Ai = function (e, t) { + var n = typeof e; + return ( + !!(t = null == t ? 9007199254740991 : t) && + ("number" == n || ("symbol" != n && Ii.test(e))) && + e > -1 && + e % 1 == 0 && + e < t + ); + }; + var Li = function (e, t, n, r) { + if (!j(e)) return e; + for ( + var i = -1, a = (t = Pi(t, e)).length, o = a - 1, s = e; + null != s && ++i < a; + ) { + var l = Di(t[i]), + u = n; + if ("__proto__" === l || "constructor" === l || "prototype" === l) + return e; + if (i != o) { + var c = s[l]; + void 0 === (u = r ? r(c, l, s) : void 0) && + (u = j(c) ? c : Ai(t[i + 1]) ? [] : {}); + } + (zi(s, l, u), (s = s[l])); + } + return e; + }; + var Oi = function (e, t, n) { + return null == e ? e : Li(e, t, n); + }; + var Ri = function (e, t) { + var n = -1, + r = e.length; + for (t || (t = Array(r)); ++n < r; ) t[n] = e[n]; + return t; + }; + var Vi = function (e) { + return xr(e) ? wi(e, Di) : le(e) ? [e] : Ri(xi(Si(e))); + }, + Fi = {}; + [ + br, + { + data: function (e) { + return ( + (e = L( + {}, + { + field: "data", + bindingEvent: "data", + allowBinding: !1, + allowSetting: !1, + allowGetting: !1, + settingEvent: "data", + settingTriggersEvent: !1, + triggerFnName: "trigger", + immutableKeys: {}, + updateStyle: !1, + beforeGet: function (e) {}, + beforeSet: function (e, t) {}, + onSet: function (e) {}, + canSet: function (e) { + return !0; + }, + }, + e, + )), + function (t, n) { + var r = e, + a = void 0 !== this.length, + o = a ? this : [this], + s = a ? this[0] : this; + if (v(t)) { + var l, + u = -1 !== t.indexOf(".") && Vi(t); + if (r.allowGetting && void 0 === n) + return ( + s && + (r.beforeGet(s), + (l = + u && void 0 === s._private[r.field][t] + ? _i(s._private[r.field], u) + : s._private[r.field][t])), + l + ); + if (r.allowSetting && void 0 !== n && !r.immutableKeys[t]) { + var c = i({}, t, n); + r.beforeSet(this, c); + for (var d = 0, h = o.length; d < h; d++) { + var p = o[d]; + r.canSet(p) && + (u && void 0 === s._private[r.field][t] + ? Oi(p._private[r.field], u, n) + : (p._private[r.field][t] = n)); + } + (r.updateStyle && this.updateStyle(), + r.onSet(this), + r.settingTriggersEvent && + this[r.triggerFnName](r.settingEvent)); + } + } else if (r.allowSetting && b(t)) { + var f, + g, + m = t, + x = Object.keys(m); + r.beforeSet(this, m); + for (var w = 0; w < x.length; w++) { + if (((g = m[(f = x[w])]), !r.immutableKeys[f])) + for (var E = 0; E < o.length; E++) { + var k = o[E]; + r.canSet(k) && (k._private[r.field][f] = g); + } + } + (r.updateStyle && this.updateStyle(), + r.onSet(this), + r.settingTriggersEvent && + this[r.triggerFnName](r.settingEvent)); + } else if (r.allowBinding && y(t)) { + var C = t; + this.on(r.bindingEvent, C); + } else if (r.allowGetting && void 0 === t) { + var S; + return (s && (r.beforeGet(s), (S = s._private[r.field])), S); + } + return this; + } + ); + }, + removeData: function (e) { + return ( + (e = L( + {}, + { + field: "data", + event: "data", + triggerFnName: "trigger", + triggerEvent: !1, + immutableKeys: {}, + }, + e, + )), + function (t) { + var n = e, + r = void 0 !== this.length ? this : [this]; + if (v(t)) { + for (var i = t.split(/\s+/), a = i.length, o = 0; o < a; o++) { + var s = i[o]; + if (!D(s)) + if (!n.immutableKeys[s]) + for (var l = 0, u = r.length; l < u; l++) + r[l]._private[n.field][s] = void 0; + } + n.triggerEvent && this[n.triggerFnName](n.event); + } else if (void 0 === t) { + for (var c = 0, d = r.length; c < d; c++) + for ( + var h = r[c]._private[n.field], p = Object.keys(h), f = 0; + f < p.length; + f++ + ) { + var g = p[f]; + !n.immutableKeys[g] && (h[g] = void 0); + } + n.triggerEvent && this[n.triggerFnName](n.event); + } + return this; + } + ); + }, + }, + { + eventAliasesOn: function (e) { + var t = e; + ((t.addListener = t.listen = t.bind = t.on), + (t.unlisten = t.unbind = t.off = t.removeListener), + (t.trigger = t.emit), + (t.pon = t.promiseOn = + function (e, t) { + var n = this, + r = Array.prototype.slice.call(arguments, 0); + return new vr(function (e, t) { + var i = r.concat([ + function (t) { + (n.off.apply(n, a), e(t)); + }, + ]), + a = i.concat([]); + n.on.apply(n, i); + }); + })); + }, + }, + ].forEach(function (e) { + L(Fi, e); + }); + var ji = { + animate: Fi.animate(), + animation: Fi.animation(), + animated: Fi.animated(), + clearQueue: Fi.clearQueue(), + delay: Fi.delay(), + delayAnimation: Fi.delayAnimation(), + stop: Fi.stop(), + }, + qi = { + classes: function (e) { + if (void 0 === e) { + var t = []; + return ( + this[0]._private.classes.forEach(function (e) { + return t.push(e); + }), + t + ); + } + m(e) || (e = (e || "").match(/\S+/g) || []); + for (var n = [], r = new Je(e), i = 0; i < this.length; i++) { + for ( + var a = this[i], o = a._private, s = o.classes, l = !1, u = 0; + u < e.length; + u++ + ) { + var c = e[u]; + if (!s.has(c)) { + l = !0; + break; + } + } + (l || (l = s.size !== e.length), l && ((o.classes = r), n.push(a))); + } + return ( + n.length > 0 && this.spawn(n).updateStyle().emit("class"), + this + ); + }, + addClass: function (e) { + return this.toggleClass(e, !0); + }, + hasClass: function (e) { + var t = this[0]; + return null != t && t._private.classes.has(e); + }, + toggleClass: function (e, t) { + m(e) || (e = e.match(/\S+/g) || []); + for (var n = void 0 === t, r = [], i = 0, a = this.length; i < a; i++) + for ( + var o = this[i], s = o._private.classes, l = !1, u = 0; + u < e.length; + u++ + ) { + var c = e[u], + d = s.has(c), + h = !1; + (t || (n && !d) + ? (s.add(c), (h = !0)) + : (!t || (n && d)) && (s.delete(c), (h = !0)), + !l && h && (r.push(o), (l = !0))); + } + return ( + r.length > 0 && this.spawn(r).updateStyle().emit("class"), + this + ); + }, + removeClass: function (e) { + return this.toggleClass(e, !1); + }, + flashClass: function (e, t) { + var n = this; + if (null == t) t = 250; + else if (0 === t) return n; + return ( + n.addClass(e), + setTimeout(function () { + n.removeClass(e); + }, t), + n + ); + }, + }; + qi.className = qi.classNames = qi.classes; + var Yi = { + metaChar: + "[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]", + comparatorOp: "=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=", + boolOp: "\\?|\\!|\\^", + string: "\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*'", + number: I, + meta: "degree|indegree|outdegree", + separator: "\\s*,\\s*", + descendant: "\\s+", + child: "\\s+>\\s+", + subject: "\\$", + group: "node|edge|\\*", + directedEdge: "\\s+->\\s+", + undirectedEdge: "\\s+<->\\s+", + }; + ((Yi.variable = "(?:[\\w-.]|(?:\\\\" + Yi.metaChar + "))+"), + (Yi.className = "(?:[\\w-]|(?:\\\\" + Yi.metaChar + "))+"), + (Yi.value = Yi.string + "|" + Yi.number), + (Yi.id = Yi.variable), + (function () { + var e, t, n; + for (e = Yi.comparatorOp.split("|"), n = 0; n < e.length; n++) + ((t = e[n]), (Yi.comparatorOp += "|@" + t)); + for (e = Yi.comparatorOp.split("|"), n = 0; n < e.length; n++) + (t = e[n]).indexOf("!") >= 0 || + ("=" !== t && (Yi.comparatorOp += "|\\!" + t)); + })()); + var Xi = 0, + Wi = 1, + Hi = 2, + Ki = 3, + Gi = 4, + Ui = 5, + Zi = 6, + $i = 7, + Qi = 8, + Ji = 9, + ea = 10, + ta = 11, + na = 12, + ra = 13, + ia = 14, + aa = 15, + oa = 16, + sa = 17, + la = 18, + ua = 19, + ca = 20, + da = [ + { + selector: ":selected", + matches: function (e) { + return e.selected(); + }, + }, + { + selector: ":unselected", + matches: function (e) { + return !e.selected(); + }, + }, + { + selector: ":selectable", + matches: function (e) { + return e.selectable(); + }, + }, + { + selector: ":unselectable", + matches: function (e) { + return !e.selectable(); + }, + }, + { + selector: ":locked", + matches: function (e) { + return e.locked(); + }, + }, + { + selector: ":unlocked", + matches: function (e) { + return !e.locked(); + }, + }, + { + selector: ":visible", + matches: function (e) { + return e.visible(); + }, + }, + { + selector: ":hidden", + matches: function (e) { + return !e.visible(); + }, + }, + { + selector: ":transparent", + matches: function (e) { + return e.transparent(); + }, + }, + { + selector: ":grabbed", + matches: function (e) { + return e.grabbed(); + }, + }, + { + selector: ":free", + matches: function (e) { + return !e.grabbed(); + }, + }, + { + selector: ":removed", + matches: function (e) { + return e.removed(); + }, + }, + { + selector: ":inside", + matches: function (e) { + return !e.removed(); + }, + }, + { + selector: ":grabbable", + matches: function (e) { + return e.grabbable(); + }, + }, + { + selector: ":ungrabbable", + matches: function (e) { + return !e.grabbable(); + }, + }, + { + selector: ":animated", + matches: function (e) { + return e.animated(); + }, + }, + { + selector: ":unanimated", + matches: function (e) { + return !e.animated(); + }, + }, + { + selector: ":parent", + matches: function (e) { + return e.isParent(); + }, + }, + { + selector: ":childless", + matches: function (e) { + return e.isChildless(); + }, + }, + { + selector: ":child", + matches: function (e) { + return e.isChild(); + }, + }, + { + selector: ":orphan", + matches: function (e) { + return e.isOrphan(); + }, + }, + { + selector: ":nonorphan", + matches: function (e) { + return e.isChild(); + }, + }, + { + selector: ":compound", + matches: function (e) { + return e.isNode() + ? e.isParent() + : e.source().isParent() || e.target().isParent(); + }, + }, + { + selector: ":loop", + matches: function (e) { + return e.isLoop(); + }, + }, + { + selector: ":simple", + matches: function (e) { + return e.isSimple(); + }, + }, + { + selector: ":active", + matches: function (e) { + return e.active(); + }, + }, + { + selector: ":inactive", + matches: function (e) { + return !e.active(); + }, + }, + { + selector: ":backgrounding", + matches: function (e) { + return e.backgrounding(); + }, + }, + { + selector: ":nonbackgrounding", + matches: function (e) { + return !e.backgrounding(); + }, + }, + ].sort(function (e, t) { + return (function (e, t) { + return -1 * A(e, t); + })(e.selector, t.selector); + }), + ha = (function () { + for (var e, t = {}, n = 0; n < da.length; n++) + t[(e = da[n]).selector] = e.matches; + return t; + })(), + pa = + "(" + + da + .map(function (e) { + return e.selector; + }) + .join("|") + + ")", + fa = function (e) { + return e.replace( + new RegExp("\\\\(" + Yi.metaChar + ")", "g"), + function (e, t) { + return t; + }, + ); + }, + ga = function (e, t, n) { + e[e.length - 1] = n; + }, + va = [ + { + name: "group", + query: !0, + regex: "(" + Yi.group + ")", + populate: function (e, t, n) { + var r = a(n, 1)[0]; + t.checks.push({ type: Xi, value: "*" === r ? r : r + "s" }); + }, + }, + { + name: "state", + query: !0, + regex: pa, + populate: function (e, t, n) { + var r = a(n, 1)[0]; + t.checks.push({ type: $i, value: r }); + }, + }, + { + name: "id", + query: !0, + regex: "\\#(" + Yi.id + ")", + populate: function (e, t, n) { + var r = a(n, 1)[0]; + t.checks.push({ type: Qi, value: fa(r) }); + }, + }, + { + name: "className", + query: !0, + regex: "\\.(" + Yi.className + ")", + populate: function (e, t, n) { + var r = a(n, 1)[0]; + t.checks.push({ type: Ji, value: fa(r) }); + }, + }, + { + name: "dataExists", + query: !0, + regex: "\\[\\s*(" + Yi.variable + ")\\s*\\]", + populate: function (e, t, n) { + var r = a(n, 1)[0]; + t.checks.push({ type: Gi, field: fa(r) }); + }, + }, + { + name: "dataCompare", + query: !0, + regex: + "\\[\\s*(" + + Yi.variable + + ")\\s*(" + + Yi.comparatorOp + + ")\\s*(" + + Yi.value + + ")\\s*\\]", + populate: function (e, t, n) { + var r = a(n, 3), + i = r[0], + o = r[1], + s = r[2]; + ((s = + null != new RegExp("^" + Yi.string + "$").exec(s) + ? s.substring(1, s.length - 1) + : parseFloat(s)), + t.checks.push({ type: Ki, field: fa(i), operator: o, value: s })); + }, + }, + { + name: "dataBool", + query: !0, + regex: "\\[\\s*(" + Yi.boolOp + ")\\s*(" + Yi.variable + ")\\s*\\]", + populate: function (e, t, n) { + var r = a(n, 2), + i = r[0], + o = r[1]; + t.checks.push({ type: Ui, field: fa(o), operator: i }); + }, + }, + { + name: "metaCompare", + query: !0, + regex: + "\\[\\[\\s*(" + + Yi.meta + + ")\\s*(" + + Yi.comparatorOp + + ")\\s*(" + + Yi.number + + ")\\s*\\]\\]", + populate: function (e, t, n) { + var r = a(n, 3), + i = r[0], + o = r[1], + s = r[2]; + t.checks.push({ + type: Zi, + field: fa(i), + operator: o, + value: parseFloat(s), + }); + }, + }, + { + name: "nextQuery", + separator: !0, + regex: Yi.separator, + populate: function (e, t) { + var n = e.currentSubject, + r = e.edgeCount, + i = e.compoundCount, + a = e[e.length - 1]; + return ( + null != n && ((a.subject = n), (e.currentSubject = null)), + (a.edgeCount = r), + (a.compoundCount = i), + (e.edgeCount = 0), + (e.compoundCount = 0), + (e[e.length++] = { checks: [] }) + ); + }, + }, + { + name: "directedEdge", + separator: !0, + regex: Yi.directedEdge, + populate: function (e, t) { + if (null == e.currentSubject) { + var n = { checks: [] }, + r = t, + i = { checks: [] }; + return ( + n.checks.push({ type: ta, source: r, target: i }), + ga(e, 0, n), + e.edgeCount++, + i + ); + } + var a = { checks: [] }, + o = t, + s = { checks: [] }; + return ( + a.checks.push({ type: na, source: o, target: s }), + ga(e, 0, a), + e.edgeCount++, + s + ); + }, + }, + { + name: "undirectedEdge", + separator: !0, + regex: Yi.undirectedEdge, + populate: function (e, t) { + if (null == e.currentSubject) { + var n = { checks: [] }, + r = t, + i = { checks: [] }; + return ( + n.checks.push({ type: ea, nodes: [r, i] }), + ga(e, 0, n), + e.edgeCount++, + i + ); + } + var a = { checks: [] }, + o = t, + s = { checks: [] }; + return ( + a.checks.push({ type: ia, node: o, neighbor: s }), + ga(e, 0, a), + s + ); + }, + }, + { + name: "child", + separator: !0, + regex: Yi.child, + populate: function (e, t) { + if (null == e.currentSubject) { + var n = { checks: [] }, + r = { checks: [] }, + i = e[e.length - 1]; + return ( + n.checks.push({ type: aa, parent: i, child: r }), + ga(e, 0, n), + e.compoundCount++, + r + ); + } + if (e.currentSubject === t) { + var a = { checks: [] }, + o = e[e.length - 1], + s = { checks: [] }, + l = { checks: [] }, + u = { checks: [] }, + c = { checks: [] }; + return ( + a.checks.push({ type: ua, left: o, right: s, subject: l }), + (l.checks = t.checks), + (t.checks = [{ type: ca }]), + c.checks.push({ type: ca }), + s.checks.push({ type: sa, parent: c, child: u }), + ga(e, 0, a), + (e.currentSubject = l), + e.compoundCount++, + u + ); + } + var d = { checks: [] }, + h = { checks: [] }, + p = [{ type: sa, parent: d, child: h }]; + return ((d.checks = t.checks), (t.checks = p), e.compoundCount++, h); + }, + }, + { + name: "descendant", + separator: !0, + regex: Yi.descendant, + populate: function (e, t) { + if (null == e.currentSubject) { + var n = { checks: [] }, + r = { checks: [] }, + i = e[e.length - 1]; + return ( + n.checks.push({ type: oa, ancestor: i, descendant: r }), + ga(e, 0, n), + e.compoundCount++, + r + ); + } + if (e.currentSubject === t) { + var a = { checks: [] }, + o = e[e.length - 1], + s = { checks: [] }, + l = { checks: [] }, + u = { checks: [] }, + c = { checks: [] }; + return ( + a.checks.push({ type: ua, left: o, right: s, subject: l }), + (l.checks = t.checks), + (t.checks = [{ type: ca }]), + c.checks.push({ type: ca }), + s.checks.push({ type: la, ancestor: c, descendant: u }), + ga(e, 0, a), + (e.currentSubject = l), + e.compoundCount++, + u + ); + } + var d = { checks: [] }, + h = { checks: [] }, + p = [{ type: la, ancestor: d, descendant: h }]; + return ((d.checks = t.checks), (t.checks = p), e.compoundCount++, h); + }, + }, + { + name: "subject", + modifier: !0, + regex: Yi.subject, + populate: function (e, t) { + if (null != e.currentSubject && e.currentSubject !== t) + return ( + je("Redefinition of subject in selector `" + e.toString() + "`"), + !1 + ); + e.currentSubject = t; + var n = e[e.length - 1].checks[0], + r = null == n ? null : n.type; + r === ta + ? (n.type = ra) + : r === ea && + ((n.type = ia), + (n.node = n.nodes[1]), + (n.neighbor = n.nodes[0]), + (n.nodes = null)); + }, + }, + ]; + va.forEach(function (e) { + return (e.regexObj = new RegExp("^" + e.regex)); + }); + var ya = function (e) { + for (var t, n, r, i = 0; i < va.length; i++) { + var a = va[i], + o = a.name, + s = e.match(a.regexObj); + if (null != s) { + ((n = s), (t = a), (r = o)); + var l = s[0]; + e = e.substring(l.length); + break; + } + } + return { expr: t, match: n, name: r, remaining: e }; + }, + ma = { + parse: function (e) { + var t = (this.inputText = e), + n = (this[0] = { checks: [] }); + for ( + this.length = 1, + t = (function (e) { + var t = e.match(/^\s+/); + if (t) { + var n = t[0]; + e = e.substring(n.length); + } + return e; + })(t); + ; + ) { + var r = ya(t); + if (null == r.expr) + return (je("The selector `" + e + "`is invalid"), !1); + var i = r.match.slice(1), + a = r.expr.populate(this, n, i); + if (!1 === a) return !1; + if ((null != a && (n = a), (t = r.remaining).match(/^\s*$/))) break; + } + var o = this[this.length - 1]; + (null != this.currentSubject && (o.subject = this.currentSubject), + (o.edgeCount = this.edgeCount), + (o.compoundCount = this.compoundCount)); + for (var s = 0; s < this.length; s++) { + var l = this[s]; + if (l.compoundCount > 0 && l.edgeCount > 0) + return ( + je( + "The selector `" + + e + + "` is invalid because it uses both a compound selector and an edge selector", + ), + !1 + ); + if (l.edgeCount > 1) + return ( + je( + "The selector `" + + e + + "` is invalid because it uses multiple edge selectors", + ), + !1 + ); + 1 === l.edgeCount && + je( + "The selector `" + + e + + "` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.", + ); + } + return !0; + }, + toString: function () { + if (null != this.toStringCache) return this.toStringCache; + for ( + var e = function (e) { + return null == e ? "" : e; + }, + t = function (t) { + return v(t) ? '"' + t + '"' : e(t); + }, + n = function (e) { + return " " + e + " "; + }, + r = function (r, a) { + var o = r.type, + s = r.value; + switch (o) { + case Xi: + var l = e(s); + return l.substring(0, l.length - 1); + case Ki: + var u = r.field, + c = r.operator; + return "[" + u + n(e(c)) + t(s) + "]"; + case Ui: + var d = r.operator, + h = r.field; + return "[" + e(d) + h + "]"; + case Gi: + return "[" + r.field + "]"; + case Zi: + var p = r.operator; + return "[[" + r.field + n(e(p)) + t(s) + "]]"; + case $i: + return s; + case Qi: + return "#" + s; + case Ji: + return "." + s; + case sa: + case aa: + return i(r.parent, a) + n(">") + i(r.child, a); + case la: + case oa: + return i(r.ancestor, a) + " " + i(r.descendant, a); + case ua: + var f = i(r.left, a), + g = i(r.subject, a), + v = i(r.right, a); + return f + (f.length > 0 ? " " : "") + g + v; + case ca: + return ""; + } + }, + i = function (e, t) { + return e.checks.reduce(function (n, i, a) { + return n + (t === e && 0 === a ? "$" : "") + r(i, t); + }, ""); + }, + a = "", + o = 0; + o < this.length; + o++ + ) { + var s = this[o]; + ((a += i(s, s.subject)), + this.length > 1 && o < this.length - 1 && (a += ", ")); + } + return ((this.toStringCache = a), a); + }, + }, + ba = function (e, t, n) { + var r, + i, + a, + o = v(e), + s = x(e), + l = v(n), + u = !1, + c = !1, + d = !1; + switch ( + (t.indexOf("!") >= 0 && ((t = t.replace("!", "")), (c = !0)), + t.indexOf("@") >= 0 && ((t = t.replace("@", "")), (u = !0)), + (o || l || u) && ((i = o || s ? "" + e : ""), (a = "" + n)), + u && ((e = i = i.toLowerCase()), (n = a = a.toLowerCase())), + t) + ) { + case "*=": + r = i.indexOf(a) >= 0; + break; + case "$=": + r = i.indexOf(a, i.length - a.length) >= 0; + break; + case "^=": + r = 0 === i.indexOf(a); + break; + case "=": + r = e === n; + break; + case ">": + ((d = !0), (r = e > n)); + break; + case ">=": + ((d = !0), (r = e >= n)); + break; + case "<": + ((d = !0), (r = e < n)); + break; + case "<=": + ((d = !0), (r = e <= n)); + break; + default: + r = !1; + } + return (!c || (null == e && d) || (r = !r), r); + }, + xa = function (e, t) { + return e.data(t); + }, + wa = [], + Ea = function (e, t) { + return e.checks.every(function (e) { + return wa[e.type](e, t); + }); + }; + ((wa[Xi] = function (e, t) { + var n = e.value; + return "*" === n || n === t.group(); + }), + (wa[$i] = function (e, t) { + return (function (e, t) { + return ha[e](t); + })(e.value, t); + }), + (wa[Qi] = function (e, t) { + var n = e.value; + return t.id() === n; + }), + (wa[Ji] = function (e, t) { + var n = e.value; + return t.hasClass(n); + }), + (wa[Zi] = function (e, t) { + var n = e.field, + r = e.operator, + i = e.value; + return ba( + (function (e, t) { + return e[t](); + })(t, n), + r, + i, + ); + }), + (wa[Ki] = function (e, t) { + var n = e.field, + r = e.operator, + i = e.value; + return ba(xa(t, n), r, i); + }), + (wa[Ui] = function (e, t) { + var n = e.field, + r = e.operator; + return (function (e, t) { + switch (t) { + case "?": + return !!e; + case "!": + return !e; + case "^": + return void 0 === e; + } + })(xa(t, n), r); + }), + (wa[Gi] = function (e, t) { + var n = e.field; + return (e.operator, void 0 !== xa(t, n)); + }), + (wa[ea] = function (e, t) { + var n = e.nodes[0], + r = e.nodes[1], + i = t.source(), + a = t.target(); + return (Ea(n, i) && Ea(r, a)) || (Ea(r, i) && Ea(n, a)); + }), + (wa[ia] = function (e, t) { + return ( + Ea(e.node, t) && + t.neighborhood().some(function (t) { + return t.isNode() && Ea(e.neighbor, t); + }) + ); + }), + (wa[ta] = function (e, t) { + return Ea(e.source, t.source()) && Ea(e.target, t.target()); + }), + (wa[na] = function (e, t) { + return ( + Ea(e.source, t) && + t.outgoers().some(function (t) { + return t.isNode() && Ea(e.target, t); + }) + ); + }), + (wa[ra] = function (e, t) { + return ( + Ea(e.target, t) && + t.incomers().some(function (t) { + return t.isNode() && Ea(e.source, t); + }) + ); + }), + (wa[aa] = function (e, t) { + return Ea(e.child, t) && Ea(e.parent, t.parent()); + }), + (wa[sa] = function (e, t) { + return ( + Ea(e.parent, t) && + t.children().some(function (t) { + return Ea(e.child, t); + }) + ); + }), + (wa[oa] = function (e, t) { + return ( + Ea(e.descendant, t) && + t.ancestors().some(function (t) { + return Ea(e.ancestor, t); + }) + ); + }), + (wa[la] = function (e, t) { + return ( + Ea(e.ancestor, t) && + t.descendants().some(function (t) { + return Ea(e.descendant, t); + }) + ); + }), + (wa[ua] = function (e, t) { + return Ea(e.subject, t) && Ea(e.left, t) && Ea(e.right, t); + }), + (wa[ca] = function () { + return !0; + }), + (wa[Wi] = function (e, t) { + return e.value.has(t); + }), + (wa[Hi] = function (e, t) { + return (0, e.value)(t); + })); + var ka = function (e) { + ((this.inputText = e), + (this.currentSubject = null), + (this.compoundCount = 0), + (this.edgeCount = 0), + (this.length = 0), + null == e || + (v(e) && e.match(/^\s*$/)) || + (E(e) + ? this.addQuery({ checks: [{ type: Wi, value: e.collection() }] }) + : y(e) + ? this.addQuery({ checks: [{ type: Hi, value: e }] }) + : v(e) + ? this.parse(e) || (this.invalid = !0) + : Ve("A selector must be created from a string; found "))); + }, + Ca = ka.prototype; + ([ + ma, + { + matches: function (e) { + for (var t = 0; t < this.length; t++) { + var n = this[t]; + if (Ea(n, e)) return !0; + } + return !1; + }, + filter: function (e) { + var t = this; + if ( + 1 === t.length && + 1 === t[0].checks.length && + t[0].checks[0].type === Qi + ) + return e.getElementById(t[0].checks[0].value).collection(); + var n = function (e) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + if (Ea(r, e)) return !0; + } + return !1; + }; + return ( + null == t.text() && + (n = function () { + return !0; + }), + e.filter(n) + ); + }, + }, + ].forEach(function (e) { + return L(Ca, e); + }), + (Ca.text = function () { + return this.inputText; + }), + (Ca.size = function () { + return this.length; + }), + (Ca.eq = function (e) { + return this[e]; + }), + (Ca.sameText = function (e) { + return !this.invalid && !e.invalid && this.text() === e.text(); + }), + (Ca.addQuery = function (e) { + this[this.length++] = e; + }), + (Ca.selector = Ca.toString)); + var Sa = { + allAre: function (e) { + var t = new ka(e); + return this.every(function (e) { + return t.matches(e); + }); + }, + is: function (e) { + var t = new ka(e); + return this.some(function (e) { + return t.matches(e); + }); + }, + some: function (e, t) { + for (var n = 0; n < this.length; n++) { + if (t ? e.apply(t, [this[n], n, this]) : e(this[n], n, this)) return !0; + } + return !1; + }, + every: function (e, t) { + for (var n = 0; n < this.length; n++) { + if (!(t ? e.apply(t, [this[n], n, this]) : e(this[n], n, this))) + return !1; + } + return !0; + }, + same: function (e) { + if (this === e) return !0; + e = this.cy().collection(e); + var t = this.length; + return ( + t === e.length && + (1 === t + ? this[0] === e[0] + : this.every(function (t) { + return e.hasElementWithId(t.id()); + })) + ); + }, + anySame: function (e) { + return ( + (e = this.cy().collection(e)), + this.some(function (t) { + return e.hasElementWithId(t.id()); + }) + ); + }, + allAreNeighbors: function (e) { + e = this.cy().collection(e); + var t = this.neighborhood(); + return e.every(function (e) { + return t.hasElementWithId(e.id()); + }); + }, + contains: function (e) { + e = this.cy().collection(e); + var t = this; + return e.every(function (e) { + return t.hasElementWithId(e.id()); + }); + }, + }; + ((Sa.allAreNeighbours = Sa.allAreNeighbors), + (Sa.has = Sa.contains), + (Sa.equal = Sa.equals = Sa.same)); + var Pa, + Da, + Ta = function (e, t) { + return function (n, r, i, a) { + var o, + s = n; + if ( + (null == s ? (o = "") : E(s) && 1 === s.length && (o = s.id()), + 1 === this.length && o) + ) { + var l = this[0]._private, + u = (l.traversalCache = l.traversalCache || {}), + c = (u[t] = u[t] || []), + d = Te(o), + h = c[d]; + return h || (c[d] = e.call(this, n, r, i, a)); + } + return e.call(this, n, r, i, a); + }; + }, + _a = { + parent: function (e) { + var t = []; + if (1 === this.length) { + var n = this[0]._private.parent; + if (n) return n; + } + for (var r = 0; r < this.length; r++) { + var i = this[r]._private.parent; + i && t.push(i); + } + return this.spawn(t, !0).filter(e); + }, + parents: function (e) { + for (var t = [], n = this.parent(); n.nonempty(); ) { + for (var r = 0; r < n.length; r++) { + var i = n[r]; + t.push(i); + } + n = n.parent(); + } + return this.spawn(t, !0).filter(e); + }, + commonAncestors: function (e) { + for (var t, n = 0; n < this.length; n++) { + var r = this[n].parents(); + t = (t = t || r).intersect(r); + } + return t.filter(e); + }, + orphans: function (e) { + return this.stdFilter(function (e) { + return e.isOrphan(); + }).filter(e); + }, + nonorphans: function (e) { + return this.stdFilter(function (e) { + return e.isChild(); + }).filter(e); + }, + children: Ta(function (e) { + for (var t = [], n = 0; n < this.length; n++) + for (var r = this[n]._private.children, i = 0; i < r.length; i++) + t.push(r[i]); + return this.spawn(t, !0).filter(e); + }, "children"), + siblings: function (e) { + return this.parent().children().not(this).filter(e); + }, + isParent: function () { + var e = this[0]; + if (e) return e.isNode() && 0 !== e._private.children.length; + }, + isChildless: function () { + var e = this[0]; + if (e) return e.isNode() && 0 === e._private.children.length; + }, + isChild: function () { + var e = this[0]; + if (e) return e.isNode() && null != e._private.parent; + }, + isOrphan: function () { + var e = this[0]; + if (e) return e.isNode() && null == e._private.parent; + }, + descendants: function (e) { + var t = []; + return ( + (function e(n) { + for (var r = 0; r < n.length; r++) { + var i = n[r]; + (t.push(i), i.children().nonempty() && e(i.children())); + } + })(this.children()), + this.spawn(t, !0).filter(e) + ); + }, + }; + function Ma(e, t, n, r) { + for ( + var i = [], a = new Je(), o = e.cy().hasCompoundNodes(), s = 0; + s < e.length; + s++ + ) { + var l = e[s]; + n ? i.push(l) : o && r(i, a, l); + } + for (; i.length > 0; ) { + var u = i.shift(); + (t(u), a.add(u.id()), o && r(i, a, u)); + } + return e; + } + function Ba(e, t, n) { + if (n.isParent()) + for (var r = n._private.children, i = 0; i < r.length; i++) { + var a = r[i]; + t.has(a.id()) || e.push(a); + } + } + function Na(e, t, n) { + if (n.isChild()) { + var r = n._private.parent; + t.has(r.id()) || e.push(r); + } + } + function za(e, t, n) { + (Na(e, t, n), Ba(e, t, n)); + } + ((_a.forEachDown = function (e) { + var t = !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1]; + return Ma(this, e, t, Ba); + }), + (_a.forEachUp = function (e) { + var t = + !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1]; + return Ma(this, e, t, Na); + }), + (_a.forEachUpAndDown = function (e) { + var t = + !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1]; + return Ma(this, e, t, za); + }), + (_a.ancestors = _a.parents), + ((Pa = Da = + { + data: Fi.data({ + field: "data", + bindingEvent: "data", + allowBinding: !0, + allowSetting: !0, + settingEvent: "data", + settingTriggersEvent: !0, + triggerFnName: "trigger", + allowGetting: !0, + immutableKeys: { id: !0, source: !0, target: !0, parent: !0 }, + updateStyle: !0, + }), + removeData: Fi.removeData({ + field: "data", + event: "data", + triggerFnName: "trigger", + triggerEvent: !0, + immutableKeys: { id: !0, source: !0, target: !0, parent: !0 }, + updateStyle: !0, + }), + scratch: Fi.data({ + field: "scratch", + bindingEvent: "scratch", + allowBinding: !0, + allowSetting: !0, + settingEvent: "scratch", + settingTriggersEvent: !0, + triggerFnName: "trigger", + allowGetting: !0, + updateStyle: !0, + }), + removeScratch: Fi.removeData({ + field: "scratch", + event: "scratch", + triggerFnName: "trigger", + triggerEvent: !0, + updateStyle: !0, + }), + rscratch: Fi.data({ + field: "rscratch", + allowBinding: !1, + allowSetting: !0, + settingTriggersEvent: !1, + allowGetting: !0, + }), + removeRscratch: Fi.removeData({ field: "rscratch", triggerEvent: !1 }), + id: function () { + var e = this[0]; + if (e) return e._private.data.id; + }, + }).attr = Pa.data), + (Pa.removeAttr = Pa.removeData)); + var Ia, + Aa, + La = Da, + Oa = {}; + function Ra(e) { + return function (t) { + if ( + (void 0 === t && (t = !0), + 0 !== this.length && this.isNode() && !this.removed()) + ) { + for ( + var n = 0, r = this[0], i = r._private.edges, a = 0; + a < i.length; + a++ + ) { + var o = i[a]; + (!t && o.isLoop()) || (n += e(r, o)); + } + return n; + } + }; + } + function Va(e, t) { + return function (n) { + for (var r, i = this.nodes(), a = 0; a < i.length; a++) { + var o = i[a][e](n); + void 0 === o || (void 0 !== r && !t(o, r)) || (r = o); + } + return r; + }; + } + (L(Oa, { + degree: Ra(function (e, t) { + return t.source().same(t.target()) ? 2 : 1; + }), + indegree: Ra(function (e, t) { + return t.target().same(e) ? 1 : 0; + }), + outdegree: Ra(function (e, t) { + return t.source().same(e) ? 1 : 0; + }), + }), + L(Oa, { + minDegree: Va("degree", function (e, t) { + return e < t; + }), + maxDegree: Va("degree", function (e, t) { + return e > t; + }), + minIndegree: Va("indegree", function (e, t) { + return e < t; + }), + maxIndegree: Va("indegree", function (e, t) { + return e > t; + }), + minOutdegree: Va("outdegree", function (e, t) { + return e < t; + }), + maxOutdegree: Va("outdegree", function (e, t) { + return e > t; + }), + }), + L(Oa, { + totalDegree: function (e) { + for (var t = 0, n = this.nodes(), r = 0; r < n.length; r++) + t += n[r].degree(e); + return t; + }, + })); + var Fa = function (e, t, n) { + for (var r = 0; r < e.length; r++) { + var i = e[r]; + if (!i.locked()) { + var a = i._private.position, + o = { + x: null != t.x ? t.x - a.x : 0, + y: null != t.y ? t.y - a.y : 0, + }; + (!i.isParent() || + (0 === o.x && 0 === o.y) || + i.children().shift(o, n), + i.dirtyBoundingBoxCache()); + } + } + }, + ja = { + field: "position", + bindingEvent: "position", + allowBinding: !0, + allowSetting: !0, + settingEvent: "position", + settingTriggersEvent: !0, + triggerFnName: "emitAndNotify", + allowGetting: !0, + validKeys: ["x", "y"], + beforeGet: function (e) { + e.updateCompoundBounds(); + }, + beforeSet: function (e, t) { + Fa(e, t, !1); + }, + onSet: function (e) { + e.dirtyCompoundBoundsCache(); + }, + canSet: function (e) { + return !e.locked(); + }, + }; + (((Ia = Aa = + { + position: Fi.data(ja), + silentPosition: Fi.data( + L({}, ja, { + allowBinding: !1, + allowSetting: !0, + settingTriggersEvent: !1, + allowGetting: !1, + beforeSet: function (e, t) { + Fa(e, t, !0); + }, + onSet: function (e) { + e.dirtyCompoundBoundsCache(); + }, + }), + ), + positions: function (e, t) { + if (b(e)) t ? this.silentPosition(e) : this.position(e); + else if (y(e)) { + var n = e, + r = this.cy(); + r.startBatch(); + for (var i = 0; i < this.length; i++) { + var a, + o = this[i]; + (a = n(o, i)) && (t ? o.silentPosition(a) : o.position(a)); + } + r.endBatch(); + } + return this; + }, + silentPositions: function (e) { + return this.positions(e, !0); + }, + shift: function (e, t, n) { + var r; + if ( + (b(e) + ? ((r = { x: x(e.x) ? e.x : 0, y: x(e.y) ? e.y : 0 }), (n = t)) + : v(e) && x(t) && ((r = { x: 0, y: 0 })[e] = t), + null != r) + ) { + var i = this.cy(); + i.startBatch(); + for (var a = 0; a < this.length; a++) { + var o = this[a]; + if ( + !( + i.hasCompoundNodes() && + o.isChild() && + o.ancestors().anySame(this) + ) + ) { + var s = o.position(), + l = { x: s.x + r.x, y: s.y + r.y }; + n ? o.silentPosition(l) : o.position(l); + } + } + i.endBatch(); + } + return this; + }, + silentShift: function (e, t) { + return ( + b(e) ? this.shift(e, !0) : v(e) && x(t) && this.shift(e, t, !0), + this + ); + }, + renderedPosition: function (e, t) { + var n = this[0], + r = this.cy(), + i = r.zoom(), + a = r.pan(), + o = b(e) ? e : void 0, + s = void 0 !== o || (void 0 !== t && v(e)); + if (n && n.isNode()) { + if (!s) { + var l = n.position(); + return ((o = yt(l, i, a)), void 0 === e ? o : o[e]); + } + for (var u = 0; u < this.length; u++) { + var c = this[u]; + void 0 !== t + ? c.position(e, (t - a[e]) / i) + : void 0 !== o && c.position(mt(o, i, a)); + } + } else if (!s) return; + return this; + }, + relativePosition: function (e, t) { + var n = this[0], + r = this.cy(), + i = b(e) ? e : void 0, + a = void 0 !== i || (void 0 !== t && v(e)), + o = r.hasCompoundNodes(); + if (n && n.isNode()) { + if (!a) { + var s = n.position(), + l = o ? n.parent() : null, + u = l && l.length > 0, + c = u; + u && (l = l[0]); + var d = c ? l.position() : { x: 0, y: 0 }; + return ( + (i = { x: s.x - d.x, y: s.y - d.y }), + void 0 === e ? i : i[e] + ); + } + for (var h = 0; h < this.length; h++) { + var p = this[h], + f = o ? p.parent() : null, + g = f && f.length > 0, + y = g; + g && (f = f[0]); + var m = y ? f.position() : { x: 0, y: 0 }; + void 0 !== t + ? p.position(e, t + m[e]) + : void 0 !== i && p.position({ x: i.x + m.x, y: i.y + m.y }); + } + } else if (!a) return; + return this; + }, + }).modelPosition = Ia.point = + Ia.position), + (Ia.modelPositions = Ia.points = Ia.positions), + (Ia.renderedPoint = Ia.renderedPosition), + (Ia.relativePoint = Ia.relativePosition)); + var qa, + Ya, + Xa = Aa; + ((qa = Ya = {}), + (Ya.renderedBoundingBox = function (e) { + var t = this.boundingBox(e), + n = this.cy(), + r = n.zoom(), + i = n.pan(), + a = t.x1 * r + i.x, + o = t.x2 * r + i.x, + s = t.y1 * r + i.y, + l = t.y2 * r + i.y; + return { x1: a, x2: o, y1: s, y2: l, w: o - a, h: l - s }; + }), + (Ya.dirtyCompoundBoundsCache = function () { + var e = arguments.length > 0 && void 0 !== arguments[0] && arguments[0], + t = this.cy(); + return t.styleEnabled() && t.hasCompoundNodes() + ? (this.forEachUp(function (t) { + if (t.isParent()) { + var n = t._private; + ((n.compoundBoundsClean = !1), + (n.bbCache = null), + e || t.emitAndNotify("bounds")); + } + }), + this) + : this; + }), + (Ya.updateCompoundBounds = function () { + var e = arguments.length > 0 && void 0 !== arguments[0] && arguments[0], + t = this.cy(); + if (!t.styleEnabled() || !t.hasCompoundNodes()) return this; + if (!e && t.batching()) return this; + function n(e) { + if (e.isParent()) { + var t = e._private, + n = e.children(), + r = "include" === e.pstyle("compound-sizing-wrt-labels").value, + i = { + width: { + val: e.pstyle("min-width").pfValue, + left: e.pstyle("min-width-bias-left"), + right: e.pstyle("min-width-bias-right"), + }, + height: { + val: e.pstyle("min-height").pfValue, + top: e.pstyle("min-height-bias-top"), + bottom: e.pstyle("min-height-bias-bottom"), + }, + }, + a = n.boundingBox({ + includeLabels: r, + includeOverlays: !1, + useCache: !1, + }), + o = t.position; + (0 !== a.w && 0 !== a.h) || + (((a = { + w: e.pstyle("width").pfValue, + h: e.pstyle("height").pfValue, + }).x1 = o.x - a.w / 2), + (a.x2 = o.x + a.w / 2), + (a.y1 = o.y - a.h / 2), + (a.y2 = o.y + a.h / 2)); + var s = i.width.left.value; + "px" === i.width.left.units && + i.width.val > 0 && + (s = (100 * s) / i.width.val); + var l = i.width.right.value; + "px" === i.width.right.units && + i.width.val > 0 && + (l = (100 * l) / i.width.val); + var u = i.height.top.value; + "px" === i.height.top.units && + i.height.val > 0 && + (u = (100 * u) / i.height.val); + var c = i.height.bottom.value; + "px" === i.height.bottom.units && + i.height.val > 0 && + (c = (100 * c) / i.height.val); + var d = y(i.width.val - a.w, s, l), + h = d.biasDiff, + p = d.biasComplementDiff, + f = y(i.height.val - a.h, u, c), + g = f.biasDiff, + v = f.biasComplementDiff; + ((t.autoPadding = (function (e, t, n, r) { + if ("%" !== n.units) return "px" === n.units ? n.pfValue : 0; + switch (r) { + case "width": + return e > 0 ? n.pfValue * e : 0; + case "height": + return t > 0 ? n.pfValue * t : 0; + case "average": + return e > 0 && t > 0 ? (n.pfValue * (e + t)) / 2 : 0; + case "min": + return e > 0 && t > 0 + ? e > t + ? n.pfValue * t + : n.pfValue * e + : 0; + case "max": + return e > 0 && t > 0 + ? e > t + ? n.pfValue * e + : n.pfValue * t + : 0; + default: + return 0; + } + })( + a.w, + a.h, + e.pstyle("padding"), + e.pstyle("padding-relative-to").value, + )), + (t.autoWidth = Math.max(a.w, i.width.val)), + (o.x = (-h + a.x1 + a.x2 + p) / 2), + (t.autoHeight = Math.max(a.h, i.height.val)), + (o.y = (-g + a.y1 + a.y2 + v) / 2)); + } + function y(e, t, n) { + var r = 0, + i = 0, + a = t + n; + return ( + e > 0 && a > 0 && ((r = (t / a) * e), (i = (n / a) * e)), + { biasDiff: r, biasComplementDiff: i } + ); + } + } + for (var r = 0; r < this.length; r++) { + var i = this[r], + a = i._private; + (a.compoundBoundsClean && !e) || + (n(i), t.batching() || (a.compoundBoundsClean = !0)); + } + return this; + })); + var Wa = function (e) { + return e === 1 / 0 || e === -1 / 0 ? 0 : e; + }, + Ha = function (e, t, n, r, i) { + r - t != 0 && + i - n != 0 && + null != t && + null != n && + null != r && + null != i && + ((e.x1 = t < e.x1 ? t : e.x1), + (e.x2 = r > e.x2 ? r : e.x2), + (e.y1 = n < e.y1 ? n : e.y1), + (e.y2 = i > e.y2 ? i : e.y2), + (e.w = e.x2 - e.x1), + (e.h = e.y2 - e.y1)); + }, + Ka = function (e, t) { + return null == t ? e : Ha(e, t.x1, t.y1, t.x2, t.y2); + }, + Ga = function (e, t, n) { + return Ue(e, t, n); + }, + Ua = function (e, t, n) { + if (!t.cy().headless()) { + var r, + i, + a = t._private, + o = a.rstyle, + s = o.arrowWidth / 2; + if ("none" !== t.pstyle(n + "-arrow-shape").value) { + "source" === n + ? ((r = o.srcX), (i = o.srcY)) + : "target" === n + ? ((r = o.tgtX), (i = o.tgtY)) + : ((r = o.midX), (i = o.midY)); + var l = (a.arrowBounds = a.arrowBounds || {}), + u = (l[n] = l[n] || {}); + ((u.x1 = r - s), + (u.y1 = i - s), + (u.x2 = r + s), + (u.y2 = i + s), + (u.w = u.x2 - u.x1), + (u.h = u.y2 - u.y1), + Nt(u, 1), + Ha(e, u.x1, u.y1, u.x2, u.y2)); + } + } + }, + Za = function (e, t, n) { + if (!t.cy().headless()) { + var r; + r = n ? n + "-" : ""; + var i = t._private, + a = i.rstyle; + if (t.pstyle(r + "label").strValue) { + var o, + s, + l, + u, + c = t.pstyle("text-halign"), + d = t.pstyle("text-valign"), + h = Ga(a, "labelWidth", n), + p = Ga(a, "labelHeight", n), + f = Ga(a, "labelX", n), + g = Ga(a, "labelY", n), + v = t.pstyle(r + "text-margin-x").pfValue, + y = t.pstyle(r + "text-margin-y").pfValue, + m = t.isEdge(), + b = t.pstyle(r + "text-rotation"), + x = t.pstyle("text-outline-width").pfValue, + w = t.pstyle("text-border-width").pfValue / 2, + E = t.pstyle("text-background-padding").pfValue, + k = p, + C = h, + S = C / 2, + P = k / 2; + if (m) ((o = f - S), (s = f + S), (l = g - P), (u = g + P)); + else { + switch (c.value) { + case "left": + ((o = f - C), (s = f)); + break; + case "center": + ((o = f - S), (s = f + S)); + break; + case "right": + ((o = f), (s = f + C)); + } + switch (d.value) { + case "top": + ((l = g - k), (u = g)); + break; + case "center": + ((l = g - P), (u = g + P)); + break; + case "bottom": + ((l = g), (u = g + k)); + } + } + ((o += v - Math.max(x, w) - E - 2), + (s += v + Math.max(x, w) + E + 2), + (l += y - Math.max(x, w) - E - 2), + (u += y + Math.max(x, w) + E + 2)); + var D = n || "main", + T = i.labelBounds, + _ = (T[D] = T[D] || {}); + ((_.x1 = o), + (_.y1 = l), + (_.x2 = s), + (_.y2 = u), + (_.w = s - o), + (_.h = u - l)); + var M = m && "autorotate" === b.strValue, + B = null != b.pfValue && 0 !== b.pfValue; + if (M || B) { + var N = M ? Ga(i.rstyle, "labelAngle", n) : b.pfValue, + z = Math.cos(N), + I = Math.sin(N), + A = (o + s) / 2, + L = (l + u) / 2; + if (!m) { + switch (c.value) { + case "left": + A = s; + break; + case "right": + A = o; + } + switch (d.value) { + case "top": + L = u; + break; + case "bottom": + L = l; + } + } + var O = function (e, t) { + return { + x: (e -= A) * z - (t -= L) * I + A, + y: e * I + t * z + L, + }; + }, + R = O(o, l), + V = O(o, u), + F = O(s, l), + j = O(s, u); + ((o = Math.min(R.x, V.x, F.x, j.x)), + (s = Math.max(R.x, V.x, F.x, j.x)), + (l = Math.min(R.y, V.y, F.y, j.y)), + (u = Math.max(R.y, V.y, F.y, j.y))); + } + var q = D + "Rot", + Y = (T[q] = T[q] || {}); + ((Y.x1 = o), + (Y.y1 = l), + (Y.x2 = s), + (Y.y2 = u), + (Y.w = s - o), + (Y.h = u - l), + Ha(e, o, l, s, u), + Ha(i.labelBounds.all, o, l, s, u)); + } + return e; + } + }, + $a = function (e, t) { + var n, + r, + i, + a, + o, + s, + l, + u = e._private.cy, + c = u.styleEnabled(), + d = u.headless(), + h = _t(), + p = e._private, + f = e.isNode(), + g = e.isEdge(), + v = p.rstyle, + y = f && c ? e.pstyle("bounds-expansion").pfValue : [0], + m = function (e) { + return "none" !== e.pstyle("display").value; + }, + b = !c || (m(e) && (!g || (m(e.source()) && m(e.target())))); + if (b) { + var x = 0; + c && + t.includeOverlays && + 0 !== e.pstyle("overlay-opacity").value && + (x = e.pstyle("overlay-padding").value); + var w = 0; + c && + t.includeUnderlays && + 0 !== e.pstyle("underlay-opacity").value && + (w = e.pstyle("underlay-padding").value); + var E = Math.max(x, w), + k = 0; + if ((c && (k = e.pstyle("width").pfValue / 2), f && t.includeNodes)) { + var C = e.position(); + ((o = C.x), (s = C.y)); + var S = e.outerWidth() / 2, + P = e.outerHeight() / 2; + (Ha(h, (n = o - S), (i = s - P), (r = o + S), (a = s + P)), + c && + t.includeOutlines && + (function (e, t) { + if (!t.cy().headless()) { + var n, + r, + i, + a = t.pstyle("outline-opacity").value, + o = t.pstyle("outline-width").value; + if (a > 0 && o > 0) { + var s = t.pstyle("outline-offset").value, + l = t.pstyle("shape").value, + u = o + s, + c = (e.w + 2 * u) / e.w, + d = (e.h + 2 * u) / e.h, + h = 0; + ["diamond", "pentagon", "round-triangle"].includes(l) + ? ((c = (e.w + 2.4 * u) / e.w), (h = -u / 3.6)) + : [ + "concave-hexagon", + "rhomboid", + "right-rhomboid", + ].includes(l) + ? (c = (e.w + 2.4 * u) / e.w) + : "star" === l + ? ((c = (e.w + 2.8 * u) / e.w), + (d = (e.h + 2.6 * u) / e.h), + (h = -u / 3.8)) + : "triangle" === l + ? ((c = (e.w + 2.8 * u) / e.w), + (d = (e.h + 2.4 * u) / e.h), + (h = -u / 1.4)) + : "vee" === l && + ((c = (e.w + 4.4 * u) / e.w), + (d = (e.h + 3.8 * u) / e.h), + (h = 0.5 * -u)); + var p = e.h * d - e.h, + f = e.w * c - e.w; + if ( + (zt(e, [Math.ceil(p / 2), Math.ceil(f / 2)]), 0 !== h) + ) { + var g = + ((r = 0), + (i = h), + { + x1: (n = e).x1 + r, + x2: n.x2 + r, + y1: n.y1 + i, + y2: n.y2 + i, + w: n.w, + h: n.h, + }); + Mt(e, g); + } + } + } + })(h, e)); + } else if (g && t.includeEdges) + if (c && !d) { + var D = e.pstyle("curve-style").strValue; + if ( + ((n = Math.min(v.srcX, v.midX, v.tgtX)), + (r = Math.max(v.srcX, v.midX, v.tgtX)), + (i = Math.min(v.srcY, v.midY, v.tgtY)), + (a = Math.max(v.srcY, v.midY, v.tgtY)), + Ha(h, (n -= k), (i -= k), (r += k), (a += k)), + "haystack" === D) + ) { + var T = v.haystackPts; + if (T && 2 === T.length) { + if (((n = T[0].x), (i = T[0].y), n > (r = T[1].x))) { + var _ = n; + ((n = r), (r = _)); + } + if (i > (a = T[1].y)) { + var M = i; + ((i = a), (a = M)); + } + Ha(h, n - k, i - k, r + k, a + k); + } + } else if ( + "bezier" === D || + "unbundled-bezier" === D || + D.endsWith("segments") || + D.endsWith("taxi") + ) { + var B; + switch (D) { + case "bezier": + case "unbundled-bezier": + B = v.bezierPts; + break; + case "segments": + case "taxi": + case "round-segments": + case "round-taxi": + B = v.linePts; + } + if (null != B) + for (var N = 0; N < B.length; N++) { + var z = B[N]; + ((n = z.x - k), + (r = z.x + k), + (i = z.y - k), + (a = z.y + k), + Ha(h, n, i, r, a)); + } + } + } else { + var I = e.source().position(), + A = e.target().position(); + if ((n = I.x) > (r = A.x)) { + var L = n; + ((n = r), (r = L)); + } + if ((i = I.y) > (a = A.y)) { + var O = i; + ((i = a), (a = O)); + } + Ha(h, (n -= k), (i -= k), (r += k), (a += k)); + } + if ( + (c && + t.includeEdges && + g && + (Ua(h, e, "mid-source"), + Ua(h, e, "mid-target"), + Ua(h, e, "source"), + Ua(h, e, "target")), + c) + ) + if ("yes" === e.pstyle("ghost").value) { + var R = e.pstyle("ghost-offset-x").pfValue, + V = e.pstyle("ghost-offset-y").pfValue; + Ha(h, h.x1 + R, h.y1 + V, h.x2 + R, h.y2 + V); + } + var F = (p.bodyBounds = p.bodyBounds || {}); + (It(F, h), + zt(F, y), + Nt(F, 1), + c && + ((n = h.x1), + (r = h.x2), + (i = h.y1), + (a = h.y2), + Ha(h, n - E, i - E, r + E, a + E))); + var j = (p.overlayBounds = p.overlayBounds || {}); + (It(j, h), zt(j, y), Nt(j, 1)); + var q = (p.labelBounds = p.labelBounds || {}); + (null != q.all + ? (((l = q.all).x1 = 1 / 0), + (l.y1 = 1 / 0), + (l.x2 = -1 / 0), + (l.y2 = -1 / 0), + (l.w = 0), + (l.h = 0)) + : (q.all = _t()), + c && + t.includeLabels && + (t.includeMainLabels && Za(h, e, null), + g && + (t.includeSourceLabels && Za(h, e, "source"), + t.includeTargetLabels && Za(h, e, "target")))); + } + return ( + (h.x1 = Wa(h.x1)), + (h.y1 = Wa(h.y1)), + (h.x2 = Wa(h.x2)), + (h.y2 = Wa(h.y2)), + (h.w = Wa(h.x2 - h.x1)), + (h.h = Wa(h.y2 - h.y1)), + h.w > 0 && h.h > 0 && b && (zt(h, y), Nt(h, 1)), + h + ); + }, + Qa = function (e) { + var t = 0, + n = function (e) { + return (e ? 1 : 0) << t++; + }, + r = 0; + return ( + (r += n(e.incudeNodes)), + (r += n(e.includeEdges)), + (r += n(e.includeLabels)), + (r += n(e.includeMainLabels)), + (r += n(e.includeSourceLabels)), + (r += n(e.includeTargetLabels)), + (r += n(e.includeOverlays)), + (r += n(e.includeOutlines)) + ); + }, + Ja = function (e) { + if (e.isEdge()) { + var t = e.source().position(), + n = e.target().position(), + r = function (e) { + return Math.round(e); + }; + return (function (e, t) { + var n = { value: 0, done: !1 }, + r = 0, + i = e.length; + return ke( + { + next: function () { + return (r < i ? (n.value = e[r++]) : (n.done = !0), n); + }, + }, + t, + ); + })([r(t.x), r(t.y), r(n.x), r(n.y)]); + } + return 0; + }, + eo = function (e, t) { + var n, + r = e._private, + i = e.isEdge(), + a = (null == t ? no : Qa(t)) === no, + o = Ja(e), + s = r.bbCachePosKey === o, + l = t.useCache && s, + u = function (e) { + return null == e._private.bbCache || e._private.styleDirty; + }; + if ( + (!l || u(e) || (i && u(e.source())) || u(e.target()) + ? (s || e.recalculateRenderedStyle(l), + (n = $a(e, to)), + (r.bbCache = n), + (r.bbCachePosKey = o)) + : (n = r.bbCache), + !a) + ) { + var c = e.isNode(); + ((n = _t()), + ((t.includeNodes && c) || (t.includeEdges && !c)) && + (t.includeOverlays ? Ka(n, r.overlayBounds) : Ka(n, r.bodyBounds)), + t.includeLabels && + (t.includeMainLabels && + (!i || (t.includeSourceLabels && t.includeTargetLabels)) + ? Ka(n, r.labelBounds.all) + : (t.includeMainLabels && Ka(n, r.labelBounds.mainRot), + t.includeSourceLabels && Ka(n, r.labelBounds.sourceRot), + t.includeTargetLabels && Ka(n, r.labelBounds.targetRot))), + (n.w = n.x2 - n.x1), + (n.h = n.y2 - n.y1)); + } + return n; + }, + to = { + includeNodes: !0, + includeEdges: !0, + includeLabels: !0, + includeMainLabels: !0, + includeSourceLabels: !0, + includeTargetLabels: !0, + includeOverlays: !0, + includeUnderlays: !0, + includeOutlines: !0, + useCache: !0, + }, + no = Qa(to), + ro = He(to); + ((Ya.boundingBox = function (e) { + var t; + if ( + 1 !== this.length || + null == this[0]._private.bbCache || + this[0]._private.styleDirty || + (void 0 !== e && void 0 !== e.useCache && !0 !== e.useCache) + ) { + t = _t(); + var n = ro((e = e || to)); + if (this.cy().styleEnabled()) + for (var r = 0; r < this.length; r++) { + var i = this[r], + a = i._private, + o = Ja(i), + s = a.bbCachePosKey === o, + l = n.useCache && s && !a.styleDirty; + i.recalculateRenderedStyle(l); + } + this.updateCompoundBounds(!e.useCache); + for (var u = 0; u < this.length; u++) { + var c = this[u]; + Ka(t, eo(c, n)); + } + } else ((e = void 0 === e ? to : ro(e)), (t = eo(this[0], e))); + return ( + (t.x1 = Wa(t.x1)), + (t.y1 = Wa(t.y1)), + (t.x2 = Wa(t.x2)), + (t.y2 = Wa(t.y2)), + (t.w = Wa(t.x2 - t.x1)), + (t.h = Wa(t.y2 - t.y1)), + t + ); + }), + (Ya.dirtyBoundingBoxCache = function () { + for (var e = 0; e < this.length; e++) { + var t = this[e]._private; + ((t.bbCache = null), + (t.bbCachePosKey = null), + (t.bodyBounds = null), + (t.overlayBounds = null), + (t.labelBounds.all = null), + (t.labelBounds.source = null), + (t.labelBounds.target = null), + (t.labelBounds.main = null), + (t.labelBounds.sourceRot = null), + (t.labelBounds.targetRot = null), + (t.labelBounds.mainRot = null), + (t.arrowBounds.source = null), + (t.arrowBounds.target = null), + (t.arrowBounds["mid-source"] = null), + (t.arrowBounds["mid-target"] = null)); + } + return (this.emitAndNotify("bounds"), this); + }), + (Ya.boundingBoxAt = function (e) { + var t = this.nodes(), + n = this.cy(), + r = n.hasCompoundNodes(), + i = n.collection(); + if ( + (r && + ((i = t.filter(function (e) { + return e.isParent(); + })), + (t = t.not(i))), + b(e)) + ) { + var a = e; + e = function () { + return a; + }; + } + (n.startBatch(), + t + .forEach(function (t, n) { + return (t._private.bbAtOldPos = e(t, n)); + }) + .silentPositions(e), + r && + (i.dirtyCompoundBoundsCache(), + i.dirtyBoundingBoxCache(), + i.updateCompoundBounds(!0))); + var o = (function (e) { + return { x1: e.x1, x2: e.x2, w: e.w, y1: e.y1, y2: e.y2, h: e.h }; + })(this.boundingBox({ useCache: !1 })); + return ( + t.silentPositions(function (e) { + return e._private.bbAtOldPos; + }), + r && + (i.dirtyCompoundBoundsCache(), + i.dirtyBoundingBoxCache(), + i.updateCompoundBounds(!0)), + n.endBatch(), + o + ); + }), + (qa.boundingbox = qa.bb = qa.boundingBox), + (qa.renderedBoundingbox = qa.renderedBoundingBox)); + var io, + ao, + oo = Ya; + io = ao = {}; + var so = function (e) { + ((e.uppercaseName = z(e.name)), + (e.autoName = "auto" + e.uppercaseName), + (e.labelName = "label" + e.uppercaseName), + (e.outerName = "outer" + e.uppercaseName), + (e.uppercaseOuterName = z(e.outerName)), + (io[e.name] = function () { + var t = this[0], + n = t._private, + r = n.cy._private.styleEnabled; + if (t) { + if (!r) return 1; + if (t.isParent()) + return (t.updateCompoundBounds(), n[e.autoName] || 0); + var i = t.pstyle(e.name); + switch (i.strValue) { + case "label": + return (t.recalculateRenderedStyle(), n.rstyle[e.labelName] || 0); + default: + return i.pfValue; + } + } + }), + (io["outer" + e.uppercaseName] = function () { + var t = this[0], + n = t._private.cy._private.styleEnabled; + if (t) + return n + ? t[e.name]() + t.pstyle("border-width").pfValue + 2 * t.padding() + : 1; + }), + (io["rendered" + e.uppercaseName] = function () { + var t = this[0]; + if (t) return t[e.name]() * this.cy().zoom(); + }), + (io["rendered" + e.uppercaseOuterName] = function () { + var t = this[0]; + if (t) return t[e.outerName]() * this.cy().zoom(); + })); + }; + (so({ name: "width" }), + so({ name: "height" }), + (ao.padding = function () { + var e = this[0], + t = e._private; + return e.isParent() + ? (e.updateCompoundBounds(), + void 0 !== t.autoPadding + ? t.autoPadding + : e.pstyle("padding").pfValue) + : e.pstyle("padding").pfValue; + }), + (ao.paddedHeight = function () { + var e = this[0]; + return e.height() + 2 * e.padding(); + }), + (ao.paddedWidth = function () { + var e = this[0]; + return e.width() + 2 * e.padding(); + })); + var lo = ao, + uo = { + controlPoints: { + get: function (e) { + return e.renderer().getControlPoints(e); + }, + mult: !0, + }, + segmentPoints: { + get: function (e) { + return e.renderer().getSegmentPoints(e); + }, + mult: !0, + }, + sourceEndpoint: { + get: function (e) { + return e.renderer().getSourceEndpoint(e); + }, + }, + targetEndpoint: { + get: function (e) { + return e.renderer().getTargetEndpoint(e); + }, + }, + midpoint: { + get: function (e) { + return e.renderer().getEdgeMidpoint(e); + }, + }, + }, + co = Object.keys(uo).reduce(function (e, t) { + var n = uo[t], + r = (function (e) { + return "rendered" + e[0].toUpperCase() + e.substr(1); + })(t); + return ( + (e[t] = function () { + return (function (e, t) { + if (e.isEdge()) return t(e); + })(this, n.get); + }), + n.mult + ? (e[r] = function () { + return (function (e, t) { + if (e.isEdge()) { + var n = e.cy(), + r = n.pan(), + i = n.zoom(); + return t(e).map(function (e) { + return yt(e, i, r); + }); + } + })(this, n.get); + }) + : (e[r] = function () { + return (function (e, t) { + if (e.isEdge()) { + var n = e.cy(); + return yt(t(e), n.zoom(), n.pan()); + } + })(this, n.get); + }), + e + ); + }, {}), + ho = L({}, Xa, oo, lo, co), + po = function (e, t) { + this.recycle(e, t); + }; + function fo() { + return !1; + } + function go() { + return !0; + } + po.prototype = { + instanceString: function () { + return "event"; + }, + recycle: function (e, t) { + if ( + ((this.isImmediatePropagationStopped = + this.isPropagationStopped = + this.isDefaultPrevented = + fo), + null != e && e.preventDefault + ? ((this.type = e.type), + (this.isDefaultPrevented = e.defaultPrevented ? go : fo)) + : null != e && e.type + ? (t = e) + : (this.type = e), + null != t && + ((this.originalEvent = t.originalEvent), + (this.type = null != t.type ? t.type : this.type), + (this.cy = t.cy), + (this.target = t.target), + (this.position = t.position), + (this.renderedPosition = t.renderedPosition), + (this.namespace = t.namespace), + (this.layout = t.layout)), + null != this.cy && + null != this.position && + null == this.renderedPosition) + ) { + var n = this.position, + r = this.cy.zoom(), + i = this.cy.pan(); + this.renderedPosition = { x: n.x * r + i.x, y: n.y * r + i.y }; + } + this.timeStamp = (e && e.timeStamp) || Date.now(); + }, + preventDefault: function () { + this.isDefaultPrevented = go; + var e = this.originalEvent; + e && e.preventDefault && e.preventDefault(); + }, + stopPropagation: function () { + this.isPropagationStopped = go; + var e = this.originalEvent; + e && e.stopPropagation && e.stopPropagation(); + }, + stopImmediatePropagation: function () { + ((this.isImmediatePropagationStopped = go), this.stopPropagation()); + }, + isDefaultPrevented: fo, + isPropagationStopped: fo, + isImmediatePropagationStopped: fo, + }; + var vo = /^([^.]+)(\.(?:[^.]+))?$/, + yo = { + qualifierCompare: function (e, t) { + return e === t; + }, + eventMatches: function () { + return !0; + }, + addEventFields: function () {}, + callbackContext: function (e) { + return e; + }, + beforeEmit: function () {}, + afterEmit: function () {}, + bubble: function () { + return !1; + }, + parent: function () { + return null; + }, + context: null, + }, + mo = Object.keys(yo), + bo = {}; + function xo() { + for ( + var e = + arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : bo, + t = arguments.length > 1 ? arguments[1] : void 0, + n = 0; + n < mo.length; + n++ + ) { + var r = mo[n]; + this[r] = e[r] || yo[r]; + } + ((this.context = t || this.context), + (this.listeners = []), + (this.emitting = 0)); + } + var wo = xo.prototype, + Eo = function (e, t, n, r, i, a, o) { + (y(r) && ((i = r), (r = null)), o && (a = null == a ? o : L({}, a, o))); + for (var s = m(n) ? n : n.split(/\s+/), l = 0; l < s.length; l++) { + var u = s[l]; + if (!D(u)) { + var c = u.match(vo); + if (c) if (!1 === t(e, u, c[1], c[2] ? c[2] : null, r, i, a)) break; + } + } + }, + ko = function (e, t) { + return (e.addEventFields(e.context, t), new po(t.type, t)); + }, + Co = function (e, t, n) { + if ("event" !== g(n)) + if (b(n)) t(e, ko(e, n)); + else + for (var r = m(n) ? n : n.split(/\s+/), i = 0; i < r.length; i++) { + var a = r[i]; + if (!D(a)) { + var o = a.match(vo); + if (o) { + var s = o[1], + l = o[2] ? o[2] : null; + t(e, ko(e, { type: s, namespace: l, target: e.context })); + } + } + } + else t(e, n); + }; + ((wo.on = wo.addListener = + function (e, t, n, r, i) { + return ( + Eo( + this, + function (e, t, n, r, i, a, o) { + y(a) && + e.listeners.push({ + event: t, + callback: a, + type: n, + namespace: r, + qualifier: i, + conf: o, + }); + }, + e, + t, + n, + r, + i, + ), + this + ); + }), + (wo.one = function (e, t, n, r) { + return this.on(e, t, n, r, { one: !0 }); + }), + (wo.removeListener = wo.off = + function (e, t, n, r) { + var i = this; + 0 !== this.emitting && (this.listeners = this.listeners.slice()); + for ( + var a = this.listeners, + o = function (o) { + var s = a[o]; + Eo( + i, + function (t, n, r, i, l, u) { + if ( + (s.type === r || "*" === e) && + ((!i && ".*" !== s.namespace) || s.namespace === i) && + (!l || t.qualifierCompare(s.qualifier, l)) && + (!u || s.callback === u) + ) + return (a.splice(o, 1), !1); + }, + e, + t, + n, + r, + ); + }, + s = a.length - 1; + s >= 0; + s-- + ) + o(s); + return this; + }), + (wo.removeAllListeners = function () { + return this.removeListener("*"); + }), + (wo.emit = wo.trigger = + function (e, t, n) { + var r = this.listeners, + i = r.length; + return ( + this.emitting++, + m(t) || (t = [t]), + Co( + this, + function (e, a) { + null != n && + ((r = [ + { + event: a.event, + type: a.type, + namespace: a.namespace, + callback: n, + }, + ]), + (i = r.length)); + for ( + var o = function (n) { + var i = r[n]; + if ( + i.type === a.type && + (!i.namespace || + i.namespace === a.namespace || + ".*" === i.namespace) && + e.eventMatches(e.context, i, a) + ) { + var o = [a]; + (null != t && + (function (e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + e.push(r); + } + })(o, t), + e.beforeEmit(e.context, i, a), + i.conf && + i.conf.one && + (e.listeners = e.listeners.filter(function (e) { + return e !== i; + }))); + var s = e.callbackContext(e.context, i, a), + l = i.callback.apply(s, o); + (e.afterEmit(e.context, i, a), + !1 === l && (a.stopPropagation(), a.preventDefault())); + } + }, + s = 0; + s < i; + s++ + ) + o(s); + e.bubble(e.context) && + !a.isPropagationStopped() && + e.parent(e.context).emit(a, t); + }, + e, + ), + this.emitting--, + this + ); + })); + var So = { + qualifierCompare: function (e, t) { + return null == e || null == t ? null == e && null == t : e.sameText(t); + }, + eventMatches: function (e, t, n) { + var r = t.qualifier; + return ( + null == r || (e !== n.target && k(n.target) && r.matches(n.target)) + ); + }, + addEventFields: function (e, t) { + ((t.cy = e.cy()), (t.target = e)); + }, + callbackContext: function (e, t, n) { + return null != t.qualifier ? n.target : e; + }, + beforeEmit: function (e, t) { + t.conf && + t.conf.once && + t.conf.onceCollection.removeListener( + t.event, + t.qualifier, + t.callback, + ); + }, + bubble: function () { + return !0; + }, + parent: function (e) { + return e.isChild() ? e.parent() : e.cy(); + }, + }, + Po = function (e) { + return v(e) ? new ka(e) : e; + }, + Do = { + createEmitter: function () { + for (var e = 0; e < this.length; e++) { + var t = this[e], + n = t._private; + n.emitter || (n.emitter = new xo(So, t)); + } + return this; + }, + emitter: function () { + return this._private.emitter; + }, + on: function (e, t, n) { + for (var r = Po(t), i = 0; i < this.length; i++) { + this[i].emitter().on(e, r, n); + } + return this; + }, + removeListener: function (e, t, n) { + for (var r = Po(t), i = 0; i < this.length; i++) { + this[i].emitter().removeListener(e, r, n); + } + return this; + }, + removeAllListeners: function () { + for (var e = 0; e < this.length; e++) { + this[e].emitter().removeAllListeners(); + } + return this; + }, + one: function (e, t, n) { + for (var r = Po(t), i = 0; i < this.length; i++) { + this[i].emitter().one(e, r, n); + } + return this; + }, + once: function (e, t, n) { + for (var r = Po(t), i = 0; i < this.length; i++) { + this[i].emitter().on(e, r, n, { once: !0, onceCollection: this }); + } + }, + emit: function (e, t) { + for (var n = 0; n < this.length; n++) { + this[n].emitter().emit(e, t); + } + return this; + }, + emitAndNotify: function (e, t) { + if (0 !== this.length) + return (this.cy().notify(e, this), this.emit(e, t), this); + }, + }; + Fi.eventAliasesOn(Do); + var To = { + nodes: function (e) { + return this.filter(function (e) { + return e.isNode(); + }).filter(e); + }, + edges: function (e) { + return this.filter(function (e) { + return e.isEdge(); + }).filter(e); + }, + byGroup: function () { + for ( + var e = this.spawn(), t = this.spawn(), n = 0; + n < this.length; + n++ + ) { + var r = this[n]; + r.isNode() ? e.push(r) : t.push(r); + } + return { nodes: e, edges: t }; + }, + filter: function (e, t) { + if (void 0 === e) return this; + if (v(e) || E(e)) return new ka(e).filter(this); + if (y(e)) { + for (var n = this.spawn(), r = 0; r < this.length; r++) { + var i = this[r]; + (t ? e.apply(t, [i, r, this]) : e(i, r, this)) && n.push(i); + } + return n; + } + return this.spawn(); + }, + not: function (e) { + if (e) { + v(e) && (e = this.filter(e)); + for (var t = this.spawn(), n = 0; n < this.length; n++) { + var r = this[n]; + e.has(r) || t.push(r); + } + return t; + } + return this; + }, + absoluteComplement: function () { + return this.cy().mutableElements().not(this); + }, + intersect: function (e) { + if (v(e)) { + var t = e; + return this.filter(t); + } + for ( + var n = this.spawn(), + r = e, + i = this.length < e.length, + a = i ? this : r, + o = i ? r : this, + s = 0; + s < a.length; + s++ + ) { + var l = a[s]; + o.has(l) && n.push(l); + } + return n; + }, + xor: function (e) { + var t = this._private.cy; + v(e) && (e = t.$(e)); + var n = this.spawn(), + r = e, + i = function (e, t) { + for (var r = 0; r < e.length; r++) { + var i = e[r], + a = i._private.data.id; + t.hasElementWithId(a) || n.push(i); + } + }; + return (i(this, r), i(r, this), n); + }, + diff: function (e) { + var t = this._private.cy; + v(e) && (e = t.$(e)); + var n = this.spawn(), + r = this.spawn(), + i = this.spawn(), + a = e, + o = function (e, t, n) { + for (var r = 0; r < e.length; r++) { + var a = e[r], + o = a._private.data.id; + t.hasElementWithId(o) ? i.merge(a) : n.push(a); + } + }; + return (o(this, a, n), o(a, this, r), { left: n, right: r, both: i }); + }, + add: function (e) { + var t = this._private.cy; + if (!e) return this; + if (v(e)) { + var n = e; + e = t.mutableElements().filter(n); + } + for (var r = this.spawnSelf(), i = 0; i < e.length; i++) { + var a = e[i], + o = !this.has(a); + o && r.push(a); + } + return r; + }, + merge: function (e) { + var t = this._private, + n = t.cy; + if (!e) return this; + if (e && v(e)) { + var r = e; + e = n.mutableElements().filter(r); + } + for (var i = t.map, a = 0; a < e.length; a++) { + var o = e[a], + s = o._private.data.id; + if (!i.has(s)) { + var l = this.length++; + ((this[l] = o), i.set(s, { ele: o, index: l })); + } + } + return this; + }, + unmergeAt: function (e) { + var t = this[e].id(), + n = this._private.map; + ((this[e] = void 0), n.delete(t)); + var r = e === this.length - 1; + if (this.length > 1 && !r) { + var i = this.length - 1, + a = this[i], + o = a._private.data.id; + ((this[i] = void 0), (this[e] = a), n.set(o, { ele: a, index: e })); + } + return (this.length--, this); + }, + unmergeOne: function (e) { + e = e[0]; + var t = this._private, + n = e._private.data.id, + r = t.map.get(n); + if (!r) return this; + var i = r.index; + return (this.unmergeAt(i), this); + }, + unmerge: function (e) { + var t = this._private.cy; + if (!e) return this; + if (e && v(e)) { + var n = e; + e = t.mutableElements().filter(n); + } + for (var r = 0; r < e.length; r++) this.unmergeOne(e[r]); + return this; + }, + unmergeBy: function (e) { + for (var t = this.length - 1; t >= 0; t--) { + e(this[t]) && this.unmergeAt(t); + } + return this; + }, + map: function (e, t) { + for (var n = [], r = 0; r < this.length; r++) { + var i = this[r], + a = t ? e.apply(t, [i, r, this]) : e(i, r, this); + n.push(a); + } + return n; + }, + reduce: function (e, t) { + for (var n = t, r = 0; r < this.length; r++) n = e(n, this[r], r, this); + return n; + }, + max: function (e, t) { + for (var n, r = -1 / 0, i = 0; i < this.length; i++) { + var a = this[i], + o = t ? e.apply(t, [a, i, this]) : e(a, i, this); + o > r && ((r = o), (n = a)); + } + return { value: r, ele: n }; + }, + min: function (e, t) { + for (var n, r = 1 / 0, i = 0; i < this.length; i++) { + var a = this[i], + o = t ? e.apply(t, [a, i, this]) : e(a, i, this); + o < r && ((r = o), (n = a)); + } + return { value: r, ele: n }; + }, + }, + _o = To; + ((_o.u = _o["|"] = _o["+"] = _o.union = _o.or = _o.add), + (_o["\\"] = + _o["!"] = + _o["-"] = + _o.difference = + _o.relativeComplement = + _o.subtract = + _o.not), + (_o.n = _o["&"] = _o["."] = _o.and = _o.intersection = _o.intersect), + (_o["^"] = + _o["(+)"] = + _o["(-)"] = + _o.symmetricDifference = + _o.symdiff = + _o.xor), + (_o.fnFilter = _o.filterFn = _o.stdFilter = _o.filter), + (_o.complement = _o.abscomp = _o.absoluteComplement)); + var Mo = function (e, t) { + var n = e.cy().hasCompoundNodes(); + function r(e) { + var t = e.pstyle("z-compound-depth"); + return "auto" === t.value + ? n + ? e.zDepth() + : 0 + : "bottom" === t.value + ? -1 + : "top" === t.value + ? Ie + : 0; + } + var i = r(e) - r(t); + if (0 !== i) return i; + function a(e) { + return "auto" === e.pstyle("z-index-compare").value && e.isNode() + ? 1 + : 0; + } + var o = a(e) - a(t); + if (0 !== o) return o; + var s = e.pstyle("z-index").value - t.pstyle("z-index").value; + return 0 !== s ? s : e.poolIndex() - t.poolIndex(); + }, + Bo = { + forEach: function (e, t) { + if (y(e)) + for (var n = this.length, r = 0; r < n; r++) { + var i = this[r]; + if (!1 === (t ? e.apply(t, [i, r, this]) : e(i, r, this))) break; + } + return this; + }, + toArray: function () { + for (var e = [], t = 0; t < this.length; t++) e.push(this[t]); + return e; + }, + slice: function (e, t) { + var n = [], + r = this.length; + (null == t && (t = r), + null == e && (e = 0), + e < 0 && (e = r + e), + t < 0 && (t = r + t)); + for (var i = e; i >= 0 && i < t && i < r; i++) n.push(this[i]); + return this.spawn(n); + }, + size: function () { + return this.length; + }, + eq: function (e) { + return this[e] || this.spawn(); + }, + first: function () { + return this[0] || this.spawn(); + }, + last: function () { + return this[this.length - 1] || this.spawn(); + }, + empty: function () { + return 0 === this.length; + }, + nonempty: function () { + return !this.empty(); + }, + sort: function (e) { + if (!y(e)) return this; + var t = this.toArray().sort(e); + return this.spawn(t); + }, + sortByZIndex: function () { + return this.sort(Mo); + }, + zDepth: function () { + var e = this[0]; + if (e) { + var t = e._private; + if ("nodes" === t.group) { + var n = t.data.parent ? e.parents().size() : 0; + return e.isParent() ? n : Ie - 1; + } + var r = t.source, + i = t.target, + a = r.zDepth(), + o = i.zDepth(); + return Math.max(a, o, 0); + } + }, + }; + Bo.each = Bo.forEach; + "undefined" != ("undefined" == typeof Symbol ? "undefined" : e(Symbol)) && + "undefined" != e(Symbol.iterator) && + (Bo[Symbol.iterator] = function () { + var e = this, + t = { value: void 0, done: !1 }, + n = 0, + r = this.length; + return i( + { + next: function () { + return ( + n < r ? (t.value = e[n++]) : ((t.value = void 0), (t.done = !0)), + t + ); + }, + }, + Symbol.iterator, + function () { + return this; + }, + ); + }); + var No = He({ nodeDimensionsIncludeLabels: !1 }), + zo = { + layoutDimensions: function (e) { + var t; + if (((e = No(e)), this.takesUpSpace())) + if (e.nodeDimensionsIncludeLabels) { + var n = this.boundingBox(); + t = { w: n.w, h: n.h }; + } else t = { w: this.outerWidth(), h: this.outerHeight() }; + else t = { w: 0, h: 0 }; + return ((0 !== t.w && 0 !== t.h) || (t.w = t.h = 1), t); + }, + layoutPositions: function (e, t, n) { + var r = this.nodes().filter(function (e) { + return !e.isParent(); + }), + i = this.cy(), + a = t.eles, + o = function (e) { + return e.id(); + }, + s = _(n, o); + (e.emit({ type: "layoutstart", layout: e }), (e.animations = [])); + var l = t.spacingFactor && 1 !== t.spacingFactor, + u = (function () { + if (!l) return null; + for (var e = _t(), t = 0; t < r.length; t++) { + var n = r[t], + i = s(n, t); + Bt(e, i.x, i.y); + } + return e; + })(), + c = _(function (e, n) { + var r = s(e, n); + l && + (r = (function (e, t, n) { + var r = t.x1 + t.w / 2, + i = t.y1 + t.h / 2; + return { x: r + (n.x - r) * e, y: i + (n.y - i) * e }; + })(Math.abs(t.spacingFactor), u, r)); + return (null != t.transform && (r = t.transform(e, r)), r); + }, o); + if (t.animate) { + for (var d = 0; d < r.length; d++) { + var h = r[d], + p = c(h, d); + if (null == t.animateFilter || t.animateFilter(h, d)) { + var f = h.animation({ + position: p, + duration: t.animationDuration, + easing: t.animationEasing, + }); + e.animations.push(f); + } else h.position(p); + } + if (t.fit) { + var g = i.animation({ + fit: { boundingBox: a.boundingBoxAt(c), padding: t.padding }, + duration: t.animationDuration, + easing: t.animationEasing, + }); + e.animations.push(g); + } else if (void 0 !== t.zoom && void 0 !== t.pan) { + var v = i.animation({ + zoom: t.zoom, + pan: t.pan, + duration: t.animationDuration, + easing: t.animationEasing, + }); + e.animations.push(v); + } + (e.animations.forEach(function (e) { + return e.play(); + }), + e.one("layoutready", t.ready), + e.emit({ type: "layoutready", layout: e }), + vr + .all( + e.animations.map(function (e) { + return e.promise(); + }), + ) + .then(function () { + (e.one("layoutstop", t.stop), + e.emit({ type: "layoutstop", layout: e })); + })); + } else + (r.positions(c), + t.fit && i.fit(t.eles, t.padding), + null != t.zoom && i.zoom(t.zoom), + t.pan && i.pan(t.pan), + e.one("layoutready", t.ready), + e.emit({ type: "layoutready", layout: e }), + e.one("layoutstop", t.stop), + e.emit({ type: "layoutstop", layout: e })); + return this; + }, + layout: function (e) { + return this.cy().makeLayout(L({}, e, { eles: this })); + }, + }; + function Io(e, t, n) { + var r, + i = n._private, + a = (i.styleCache = i.styleCache || []); + return null != (r = a[e]) ? r : (r = a[e] = t(n)); + } + function Ao(e, t) { + return ( + (e = Te(e)), + function (n) { + return Io(e, t, n); + } + ); + } + function Lo(e, t) { + e = Te(e); + var n = function (e) { + return t.call(e); + }; + return function () { + var t = this[0]; + if (t) return Io(e, n, t); + }; + } + zo.createLayout = zo.makeLayout = zo.layout; + var Oo = { + recalculateRenderedStyle: function (e) { + var t = this.cy(), + n = t.renderer(), + r = t.styleEnabled(); + return (n && r && n.recalculateRenderedStyle(this, e), this); + }, + dirtyStyleCache: function () { + var e, + t = this.cy(), + n = function (e) { + return (e._private.styleCache = null); + }; + t.hasCompoundNodes() + ? ((e = this.spawnSelf() + .merge(this.descendants()) + .merge(this.parents())).merge(e.connectedEdges()), + e.forEach(n)) + : this.forEach(function (e) { + (n(e), e.connectedEdges().forEach(n)); + }); + return this; + }, + updateStyle: function (e) { + var t = this._private.cy; + if (!t.styleEnabled()) return this; + if (t.batching()) return (t._private.batchStyleEles.merge(this), this); + var n = this; + ((e = !(!e && void 0 !== e)), + t.hasCompoundNodes() && + (n = this.spawnSelf() + .merge(this.descendants()) + .merge(this.parents()))); + var r = n; + return ( + e ? r.emitAndNotify("style") : r.emit("style"), + n.forEach(function (e) { + return (e._private.styleDirty = !0); + }), + this + ); + }, + cleanStyle: function () { + var e = this.cy(); + if (e.styleEnabled()) + for (var t = 0; t < this.length; t++) { + var n = this[t]; + n._private.styleDirty && + ((n._private.styleDirty = !1), e.style().apply(n)); + } + }, + parsedStyle: function (e) { + var t = + !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1], + n = this[0], + r = n.cy(); + if (r.styleEnabled() && n) { + this.cleanStyle(); + var i = n._private.style[e]; + return null != i ? i : t ? r.style().getDefaultProperty(e) : null; + } + }, + numericStyle: function (e) { + var t = this[0]; + if (t.cy().styleEnabled() && t) { + var n = t.pstyle(e); + return void 0 !== n.pfValue ? n.pfValue : n.value; + } + }, + numericStyleUnits: function (e) { + var t = this[0]; + if (t.cy().styleEnabled()) return t ? t.pstyle(e).units : void 0; + }, + renderedStyle: function (e) { + var t = this.cy(); + if (!t.styleEnabled()) return this; + var n = this[0]; + return n ? t.style().getRenderedStyle(n, e) : void 0; + }, + style: function (e, t) { + var n = this.cy(); + if (!n.styleEnabled()) return this; + var r = n.style(); + if (b(e)) { + var i = e; + (r.applyBypass(this, i, !1), this.emitAndNotify("style")); + } else if (v(e)) { + if (void 0 === t) { + var a = this[0]; + return a ? r.getStylePropertyValue(a, e) : void 0; + } + (r.applyBypass(this, e, t, !1), this.emitAndNotify("style")); + } else if (void 0 === e) { + var o = this[0]; + return o ? r.getRawStyle(o) : void 0; + } + return this; + }, + removeStyle: function (e) { + var t = this.cy(); + if (!t.styleEnabled()) return this; + var n = t.style(); + if (void 0 === e) + for (var r = 0; r < this.length; r++) { + var i = this[r]; + n.removeAllBypasses(i, !1); + } + else { + e = e.split(/\s+/); + for (var a = 0; a < this.length; a++) { + var o = this[a]; + n.removeBypasses(o, e, !1); + } + } + return (this.emitAndNotify("style"), this); + }, + show: function () { + return (this.css("display", "element"), this); + }, + hide: function () { + return (this.css("display", "none"), this); + }, + effectiveOpacity: function () { + var e = this.cy(); + if (!e.styleEnabled()) return 1; + var t = e.hasCompoundNodes(), + n = this[0]; + if (n) { + var r = n._private, + i = n.pstyle("opacity").value; + if (!t) return i; + var a = r.data.parent ? n.parents() : null; + if (a) + for (var o = 0; o < a.length; o++) { + i *= a[o].pstyle("opacity").value; + } + return i; + } + }, + transparent: function () { + if (!this.cy().styleEnabled()) return !1; + var e = this[0], + t = e.cy().hasCompoundNodes(); + return e + ? t + ? 0 === e.effectiveOpacity() + : 0 === e.pstyle("opacity").value + : void 0; + }, + backgrounding: function () { + return !!this.cy().styleEnabled() && !!this[0]._private.backgrounding; + }, + }; + function Ro(e, t) { + var n = e._private.data.parent ? e.parents() : null; + if (n) + for (var r = 0; r < n.length; r++) { + if (!t(n[r])) return !1; + } + return !0; + } + function Vo(e) { + var t = e.ok, + n = e.edgeOkViaNode || e.ok, + r = e.parentOk || e.ok; + return function () { + var e = this.cy(); + if (!e.styleEnabled()) return !0; + var i = this[0], + a = e.hasCompoundNodes(); + if (i) { + var o = i._private; + if (!t(i)) return !1; + if (i.isNode()) return !a || Ro(i, r); + var s = o.source, + l = o.target; + return ( + n(s) && (!a || Ro(s, n)) && (s === l || (n(l) && (!a || Ro(l, n)))) + ); + } + }; + } + var Fo = Ao("eleTakesUpSpace", function (e) { + return ( + "element" === e.pstyle("display").value && + 0 !== e.width() && + (!e.isNode() || 0 !== e.height()) + ); + }); + Oo.takesUpSpace = Lo("takesUpSpace", Vo({ ok: Fo })); + var jo = Ao("eleInteractive", function (e) { + return ( + "yes" === e.pstyle("events").value && + "visible" === e.pstyle("visibility").value && + Fo(e) + ); + }), + qo = Ao("parentInteractive", function (e) { + return "visible" === e.pstyle("visibility").value && Fo(e); + }); + ((Oo.interactive = Lo( + "interactive", + Vo({ ok: jo, parentOk: qo, edgeOkViaNode: Fo }), + )), + (Oo.noninteractive = function () { + var e = this[0]; + if (e) return !e.interactive(); + })); + var Yo = Ao("eleVisible", function (e) { + return ( + "visible" === e.pstyle("visibility").value && + 0 !== e.pstyle("opacity").pfValue && + Fo(e) + ); + }), + Xo = Fo; + ((Oo.visible = Lo("visible", Vo({ ok: Yo, edgeOkViaNode: Xo }))), + (Oo.hidden = function () { + var e = this[0]; + if (e) return !e.visible(); + }), + (Oo.isBundledBezier = Lo("isBundledBezier", function () { + return ( + !!this.cy().styleEnabled() && + !this.removed() && + "bezier" === this.pstyle("curve-style").value && + this.takesUpSpace() + ); + })), + (Oo.bypass = Oo.css = Oo.style), + (Oo.renderedCss = Oo.renderedStyle), + (Oo.removeBypass = Oo.removeCss = Oo.removeStyle), + (Oo.pstyle = Oo.parsedStyle)); + var Wo = {}; + function Ho(e) { + return function () { + var t = arguments, + n = []; + if (2 === t.length) { + var r = t[0], + i = t[1]; + this.on(e.event, r, i); + } else if (1 === t.length && y(t[0])) { + var a = t[0]; + this.on(e.event, a); + } else if (0 === t.length || (1 === t.length && m(t[0]))) { + for ( + var o = 1 === t.length ? t[0] : null, s = 0; + s < this.length; + s++ + ) { + var l = this[s], + u = !e.ableField || l._private[e.ableField], + c = l._private[e.field] != e.value; + if (e.overrideAble) { + var d = e.overrideAble(l); + if (void 0 !== d && ((u = d), !d)) return this; + } + u && ((l._private[e.field] = e.value), c && n.push(l)); + } + var h = this.spawn(n); + (h.updateStyle(), h.emit(e.event), o && h.emit(o)); + } + return this; + }; + } + function Ko(e) { + ((Wo[e.field] = function () { + var t = this[0]; + if (t) { + if (e.overrideField) { + var n = e.overrideField(t); + if (void 0 !== n) return n; + } + return t._private[e.field]; + } + }), + (Wo[e.on] = Ho({ + event: e.on, + field: e.field, + ableField: e.ableField, + overrideAble: e.overrideAble, + value: !0, + })), + (Wo[e.off] = Ho({ + event: e.off, + field: e.field, + ableField: e.ableField, + overrideAble: e.overrideAble, + value: !1, + }))); + } + (Ko({ + field: "locked", + overrideField: function (e) { + return !!e.cy().autolock() || void 0; + }, + on: "lock", + off: "unlock", + }), + Ko({ + field: "grabbable", + overrideField: function (e) { + return !e.cy().autoungrabify() && !e.pannable() && void 0; + }, + on: "grabify", + off: "ungrabify", + }), + Ko({ + field: "selected", + ableField: "selectable", + overrideAble: function (e) { + return !e.cy().autounselectify() && void 0; + }, + on: "select", + off: "unselect", + }), + Ko({ + field: "selectable", + overrideField: function (e) { + return !e.cy().autounselectify() && void 0; + }, + on: "selectify", + off: "unselectify", + }), + (Wo.deselect = Wo.unselect), + (Wo.grabbed = function () { + var e = this[0]; + if (e) return e._private.grabbed; + }), + Ko({ field: "active", on: "activate", off: "unactivate" }), + Ko({ field: "pannable", on: "panify", off: "unpanify" }), + (Wo.inactive = function () { + var e = this[0]; + if (e) return !e._private.active; + })); + var Go = {}, + Uo = function (e) { + return function (t) { + for (var n = [], r = 0; r < this.length; r++) { + var i = this[r]; + if (i.isNode()) { + for (var a = !1, o = i.connectedEdges(), s = 0; s < o.length; s++) { + var l = o[s], + u = l.source(), + c = l.target(); + if ( + (e.noIncomingEdges && c === i && u !== i) || + (e.noOutgoingEdges && u === i && c !== i) + ) { + a = !0; + break; + } + } + a || n.push(i); + } + } + return this.spawn(n, !0).filter(t); + }; + }, + Zo = function (e) { + return function (t) { + for (var n = [], r = 0; r < this.length; r++) { + var i = this[r]; + if (i.isNode()) + for (var a = i.connectedEdges(), o = 0; o < a.length; o++) { + var s = a[o], + l = s.source(), + u = s.target(); + e.outgoing && l === i + ? (n.push(s), n.push(u)) + : e.incoming && u === i && (n.push(s), n.push(l)); + } + } + return this.spawn(n, !0).filter(t); + }; + }, + $o = function (e) { + return function (t) { + for (var n = this, r = [], i = {}; ; ) { + var a = e.outgoing ? n.outgoers() : n.incomers(); + if (0 === a.length) break; + for (var o = !1, s = 0; s < a.length; s++) { + var l = a[s], + u = l.id(); + i[u] || ((i[u] = !0), r.push(l), (o = !0)); + } + if (!o) break; + n = a; + } + return this.spawn(r, !0).filter(t); + }; + }; + function Qo(e) { + return function (t) { + for (var n = [], r = 0; r < this.length; r++) { + var i = this[r]._private[e.attr]; + i && n.push(i); + } + return this.spawn(n, !0).filter(t); + }; + } + function Jo(e) { + return function (t) { + var n = [], + r = this._private.cy, + i = e || {}; + v(t) && (t = r.$(t)); + for (var a = 0; a < t.length; a++) + for (var o = t[a]._private.edges, s = 0; s < o.length; s++) { + var l = o[s], + u = l._private.data, + c = this.hasElementWithId(u.source) && t.hasElementWithId(u.target), + d = t.hasElementWithId(u.source) && this.hasElementWithId(u.target); + if (c || d) { + if (i.thisIsSrc || i.thisIsTgt) { + if (i.thisIsSrc && !c) continue; + if (i.thisIsTgt && !d) continue; + } + n.push(l); + } + } + return this.spawn(n, !0); + }; + } + function es(e) { + return ( + (e = L({}, { codirected: !1 }, e)), + function (t) { + for (var n = [], r = this.edges(), i = e, a = 0; a < r.length; a++) + for ( + var o = r[a]._private, + s = o.source, + l = s._private.data.id, + u = o.data.target, + c = s._private.edges, + d = 0; + d < c.length; + d++ + ) { + var h = c[d], + p = h._private.data, + f = p.target, + g = p.source, + v = f === u && g === l, + y = l === f && u === g; + ((i.codirected && v) || (!i.codirected && (v || y))) && n.push(h); + } + return this.spawn(n, !0).filter(t); + } + ); + } + ((Go.clearTraversalCache = function () { + for (var e = 0; e < this.length; e++) + this[e]._private.traversalCache = null; + }), + L(Go, { + roots: Uo({ noIncomingEdges: !0 }), + leaves: Uo({ noOutgoingEdges: !0 }), + outgoers: Ta(Zo({ outgoing: !0 }), "outgoers"), + successors: $o({ outgoing: !0 }), + incomers: Ta(Zo({ incoming: !0 }), "incomers"), + predecessors: $o({ incoming: !0 }), + }), + L(Go, { + neighborhood: Ta(function (e) { + for (var t = [], n = this.nodes(), r = 0; r < n.length; r++) + for (var i = n[r], a = i.connectedEdges(), o = 0; o < a.length; o++) { + var s = a[o], + l = s.source(), + u = s.target(), + c = i === l ? u : l; + (c.length > 0 && t.push(c[0]), t.push(s[0])); + } + return this.spawn(t, !0).filter(e); + }, "neighborhood"), + closedNeighborhood: function (e) { + return this.neighborhood().add(this).filter(e); + }, + openNeighborhood: function (e) { + return this.neighborhood(e); + }, + }), + (Go.neighbourhood = Go.neighborhood), + (Go.closedNeighbourhood = Go.closedNeighborhood), + (Go.openNeighbourhood = Go.openNeighborhood), + L(Go, { + source: Ta(function (e) { + var t, + n = this[0]; + return ( + n && (t = n._private.source || n.cy().collection()), + t && e ? t.filter(e) : t + ); + }, "source"), + target: Ta(function (e) { + var t, + n = this[0]; + return ( + n && (t = n._private.target || n.cy().collection()), + t && e ? t.filter(e) : t + ); + }, "target"), + sources: Qo({ attr: "source" }), + targets: Qo({ attr: "target" }), + }), + L(Go, { + edgesWith: Ta(Jo(), "edgesWith"), + edgesTo: Ta(Jo({ thisIsSrc: !0 }), "edgesTo"), + }), + L(Go, { + connectedEdges: Ta(function (e) { + for (var t = [], n = 0; n < this.length; n++) { + var r = this[n]; + if (r.isNode()) + for (var i = r._private.edges, a = 0; a < i.length; a++) { + var o = i[a]; + t.push(o); + } + } + return this.spawn(t, !0).filter(e); + }, "connectedEdges"), + connectedNodes: Ta(function (e) { + for (var t = [], n = 0; n < this.length; n++) { + var r = this[n]; + r.isEdge() && (t.push(r.source()[0]), t.push(r.target()[0])); + } + return this.spawn(t, !0).filter(e); + }, "connectedNodes"), + parallelEdges: Ta(es(), "parallelEdges"), + codirectedEdges: Ta(es({ codirected: !0 }), "codirectedEdges"), + }), + L(Go, { + components: function (e) { + var t = this, + n = t.cy(), + r = n.collection(), + i = null == e ? t.nodes() : e.nodes(), + a = []; + null != e && i.empty() && (i = e.sources()); + var o = function (e, t) { + (r.merge(e), i.unmerge(e), t.merge(e)); + }; + if (i.empty()) return t.spawn(); + var s = function () { + var e = n.collection(); + a.push(e); + var r = i[0]; + (o(r, e), + t.bfs({ + directed: !1, + roots: r, + visit: function (t) { + return o(t, e); + }, + }), + e.forEach(function (n) { + n.connectedEdges().forEach(function (n) { + t.has(n) && + e.has(n.source()) && + e.has(n.target()) && + e.merge(n); + }); + })); + }; + do { + s(); + } while (i.length > 0); + return a; + }, + component: function () { + var e = this[0]; + return e.cy().mutableElements().components(e)[0]; + }, + }), + (Go.componentsOf = Go.components)); + var ts = function (e, t) { + var n = arguments.length > 2 && void 0 !== arguments[2] && arguments[2], + r = arguments.length > 3 && void 0 !== arguments[3] && arguments[3]; + if (void 0 !== e) { + var i = new $e(), + a = !1; + if (t) { + if (t.length > 0 && b(t[0]) && !k(t[0])) { + a = !0; + for (var o = [], s = new Je(), l = 0, u = t.length; l < u; l++) { + var c = t[l]; + null == c.data && (c.data = {}); + var d = c.data; + if (null == d.id) d.id = Ye(); + else if (e.hasElementWithId(d.id) || s.has(d.id)) continue; + var h = new et(e, c, !1); + (o.push(h), s.add(d.id)); + } + t = o; + } + } else t = []; + this.length = 0; + for (var p = 0, f = t.length; p < f; p++) { + var g = t[p][0]; + if (null != g) { + var v = g._private.data.id; + (n && i.has(v)) || + (n && i.set(v, { index: this.length, ele: g }), + (this[this.length] = g), + this.length++); + } + } + ((this._private = { + eles: this, + cy: e, + get map() { + return (null == this.lazyMap && this.rebuildMap(), this.lazyMap); + }, + set map(e) { + this.lazyMap = e; + }, + rebuildMap: function () { + for ( + var e = (this.lazyMap = new $e()), t = this.eles, n = 0; + n < t.length; + n++ + ) { + var r = t[n]; + e.set(r.id(), { index: n, ele: r }); + } + }, + }), + n && (this._private.map = i), + a && !r && this.restore()); + } else Ve("A collection must have a reference to the core"); + }, + ns = (et.prototype = ts.prototype = Object.create(Array.prototype)); + ((ns.instanceString = function () { + return "collection"; + }), + (ns.spawn = function (e, t) { + return new ts(this.cy(), e, t); + }), + (ns.spawnSelf = function () { + return this.spawn(this); + }), + (ns.cy = function () { + return this._private.cy; + }), + (ns.renderer = function () { + return this._private.cy.renderer(); + }), + (ns.element = function () { + return this[0]; + }), + (ns.collection = function () { + return C(this) ? this : new ts(this._private.cy, [this]); + }), + (ns.unique = function () { + return new ts(this._private.cy, this, !0); + }), + (ns.hasElementWithId = function (e) { + return ((e = "" + e), this._private.map.has(e)); + }), + (ns.getElementById = function (e) { + e = "" + e; + var t = this._private.cy, + n = this._private.map.get(e); + return n ? n.ele : new ts(t); + }), + (ns.$id = ns.getElementById), + (ns.poolIndex = function () { + var e = this._private.cy._private.elements, + t = this[0]._private.data.id; + return e._private.map.get(t).index; + }), + (ns.indexOf = function (e) { + var t = e[0]._private.data.id; + return this._private.map.get(t).index; + }), + (ns.indexOfId = function (e) { + return ((e = "" + e), this._private.map.get(e).index); + }), + (ns.json = function (e) { + var t = this.element(), + n = this.cy(); + if (null == t && e) return this; + if (null != t) { + var r = t._private; + if (b(e)) { + if ((n.startBatch(), e.data)) { + t.data(e.data); + var i = r.data; + if (t.isEdge()) { + var a = !1, + o = {}, + s = e.data.source, + l = e.data.target; + (null != s && s != i.source && ((o.source = "" + s), (a = !0)), + null != l && l != i.target && ((o.target = "" + l), (a = !0)), + a && (t = t.move(o))); + } else { + var u = "parent" in e.data, + c = e.data.parent; + !u || + (null == c && null == i.parent) || + c == i.parent || + (void 0 === c && (c = null), + null != c && (c = "" + c), + (t = t.move({ parent: c }))); + } + } + e.position && t.position(e.position); + var d = function (n, i, a) { + var o = e[n]; + null != o && o !== r[n] && (o ? t[i]() : t[a]()); + }; + return ( + d("removed", "remove", "restore"), + d("selected", "select", "unselect"), + d("selectable", "selectify", "unselectify"), + d("locked", "lock", "unlock"), + d("grabbable", "grabify", "ungrabify"), + d("pannable", "panify", "unpanify"), + null != e.classes && t.classes(e.classes), + n.endBatch(), + this + ); + } + if (void 0 === e) { + var h = { + data: qe(r.data), + position: qe(r.position), + group: r.group, + removed: r.removed, + selected: r.selected, + selectable: r.selectable, + locked: r.locked, + grabbable: r.grabbable, + pannable: r.pannable, + classes: null, + }; + h.classes = ""; + var p = 0; + return ( + r.classes.forEach(function (e) { + return (h.classes += 0 == p++ ? e : " " + e); + }), + h + ); + } + } + }), + (ns.jsons = function () { + for (var e = [], t = 0; t < this.length; t++) { + var n = this[t].json(); + e.push(n); + } + return e; + }), + (ns.clone = function () { + for (var e = this.cy(), t = [], n = 0; n < this.length; n++) { + var r = this[n].json(), + i = new et(e, r, !1); + t.push(i); + } + return new ts(e, t); + }), + (ns.copy = ns.clone), + (ns.restore = function () { + for ( + var e, + t, + n = + !(arguments.length > 0 && void 0 !== arguments[0]) || arguments[0], + r = + !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1], + i = this, + a = i.cy(), + o = a._private, + s = [], + l = [], + u = 0, + c = i.length; + u < c; + u++ + ) { + var d = i[u]; + (r && !d.removed()) || (d.isNode() ? s.push(d) : l.push(d)); + } + e = s.concat(l); + var h = function () { + (e.splice(t, 1), t--); + }; + for (t = 0; t < e.length; t++) { + var p = e[t], + f = p._private, + g = f.data; + if ((p.clearTraversalCache(), r || f.removed)) + if (void 0 === g.id) g.id = Ye(); + else if (x(g.id)) g.id = "" + g.id; + else { + if (D(g.id) || !v(g.id)) { + (Ve( + "Can not create element with invalid string ID `" + g.id + "`", + ), + h()); + continue; + } + if (a.hasElementWithId(g.id)) { + (Ve("Can not create second element with ID `" + g.id + "`"), h()); + continue; + } + } + else; + var y = g.id; + if (p.isNode()) { + var m = f.position; + (null == m.x && (m.x = 0), null == m.y && (m.y = 0)); + } + if (p.isEdge()) { + for ( + var b = p, w = ["source", "target"], E = w.length, k = !1, C = 0; + C < E; + C++ + ) { + var S = w[C], + P = g[S]; + (x(P) && (P = g[S] = "" + g[S]), + null == P || "" === P + ? (Ve("Can not create edge `" + y + "` with unspecified " + S), + (k = !0)) + : a.hasElementWithId(P) || + (Ve( + "Can not create edge `" + + y + + "` with nonexistant " + + S + + " `" + + P + + "`", + ), + (k = !0))); + } + if (k) { + h(); + continue; + } + var T = a.getElementById(g.source), + _ = a.getElementById(g.target); + (T.same(_) + ? T._private.edges.push(b) + : (T._private.edges.push(b), _._private.edges.push(b)), + (b._private.source = T), + (b._private.target = _)); + } + ((f.map = new $e()), + f.map.set(y, { ele: p, index: 0 }), + (f.removed = !1), + r && a.addToPool(p)); + } + for (var M = 0; M < s.length; M++) { + var B = s[M], + N = B._private.data; + x(N.parent) && (N.parent = "" + N.parent); + var z = N.parent, + I = null != z; + if (I || B._private.parent) { + var A = B._private.parent + ? a.collection().merge(B._private.parent) + : a.getElementById(z); + if (A.empty()) N.parent = void 0; + else if (A[0].removed()) + (je("Node added with missing parent, reference to parent removed"), + (N.parent = void 0), + (B._private.parent = null)); + else { + for (var L = !1, O = A; !O.empty(); ) { + if (B.same(O)) { + ((L = !0), (N.parent = void 0)); + break; + } + O = O.parent(); + } + L || + (A[0]._private.children.push(B), + (B._private.parent = A[0]), + (o.hasCompoundNodes = !0)); + } + } + } + if (e.length > 0) { + for ( + var R = e.length === i.length ? i : new ts(a, e), V = 0; + V < R.length; + V++ + ) { + var F = R[V]; + F.isNode() || + (F.parallelEdges().clearTraversalCache(), + F.source().clearTraversalCache(), + F.target().clearTraversalCache()); + } + ((o.hasCompoundNodes + ? a.collection().merge(R).merge(R.connectedNodes()).merge(R.parent()) + : R + ) + .dirtyCompoundBoundsCache() + .dirtyBoundingBoxCache() + .updateStyle(n), + n ? R.emitAndNotify("add") : r && R.emit("add")); + } + return i; + }), + (ns.removed = function () { + var e = this[0]; + return e && e._private.removed; + }), + (ns.inside = function () { + var e = this[0]; + return e && !e._private.removed; + }), + (ns.remove = function () { + var e = + !(arguments.length > 0 && void 0 !== arguments[0]) || arguments[0], + t = !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1], + n = this, + r = [], + i = {}, + a = n._private.cy; + function o(e) { + for (var t = e._private.edges, n = 0; n < t.length; n++) l(t[n]); + } + function s(e) { + for (var t = e._private.children, n = 0; n < t.length; n++) l(t[n]); + } + function l(e) { + var n = i[e.id()]; + (t && e.removed()) || + n || + ((i[e.id()] = !0), + e.isNode() ? (r.push(e), o(e), s(e)) : r.unshift(e)); + } + for (var u = 0, c = n.length; u < c; u++) { + var d = n[u]; + l(d); + } + function h(e, t) { + var n = e._private.edges; + (Ke(n, t), e.clearTraversalCache()); + } + function p(e) { + e.clearTraversalCache(); + } + var f = []; + function g(e, t) { + t = t[0]; + var n = (e = e[0])._private.children, + r = e.id(); + (Ke(n, t), + (t._private.parent = null), + f.ids[r] || ((f.ids[r] = !0), f.push(e))); + } + ((f.ids = {}), n.dirtyCompoundBoundsCache(), t && a.removeFromPool(r)); + for (var v = 0; v < r.length; v++) { + var y = r[v]; + if (y.isEdge()) { + var m = y.source()[0], + b = y.target()[0]; + (h(m, y), h(b, y)); + for (var x = y.parallelEdges(), w = 0; w < x.length; w++) { + var E = x[w]; + (p(E), E.isBundledBezier() && E.dirtyBoundingBoxCache()); + } + } else { + var k = y.parent(); + 0 !== k.length && g(k, y); + } + t && (y._private.removed = !0); + } + var C = a._private.elements; + a._private.hasCompoundNodes = !1; + for (var S = 0; S < C.length; S++) { + var P = C[S]; + if (P.isParent()) { + a._private.hasCompoundNodes = !0; + break; + } + } + var D = new ts(this.cy(), r); + D.size() > 0 && (e ? D.emitAndNotify("remove") : t && D.emit("remove")); + for (var T = 0; T < f.length; T++) { + var _ = f[T]; + (t && _.removed()) || _.updateStyle(); + } + return D; + }), + (ns.move = function (e) { + var t = this._private.cy, + n = this, + r = function (e) { + return null == e ? e : "" + e; + }; + if (void 0 !== e.source || void 0 !== e.target) { + var i = r(e.source), + a = r(e.target), + o = null != i && t.hasElementWithId(i), + s = null != a && t.hasElementWithId(a); + (o || s) && + (t.batch(function () { + (n.remove(!1, !1), n.emitAndNotify("moveout")); + for (var e = 0; e < n.length; e++) { + var t = n[e], + r = t._private.data; + t.isEdge() && (o && (r.source = i), s && (r.target = a)); + } + n.restore(!1, !1); + }), + n.emitAndNotify("move")); + } else if (void 0 !== e.parent) { + var l = r(e.parent); + if (null === l || t.hasElementWithId(l)) { + var u = null === l ? void 0 : l; + (t.batch(function () { + var e = n.remove(!1, !1); + e.emitAndNotify("moveout"); + for (var t = 0; t < n.length; t++) { + var r = n[t], + i = r._private.data; + r.isNode() && (i.parent = u); + } + e.restore(!1, !1); + }), + n.emitAndNotify("move")); + } + } + return this; + }), + [ + ur, + ji, + qi, + Sa, + _a, + La, + Oa, + ho, + Do, + To, + { + isNode: function () { + return "nodes" === this.group(); + }, + isEdge: function () { + return "edges" === this.group(); + }, + isLoop: function () { + return this.isEdge() && this.source()[0] === this.target()[0]; + }, + isSimple: function () { + return this.isEdge() && this.source()[0] !== this.target()[0]; + }, + group: function () { + var e = this[0]; + if (e) return e._private.group; + }, + }, + Bo, + zo, + Oo, + Wo, + Go, + ].forEach(function (e) { + L(ns, e); + })); + var rs = { + add: function (e) { + var t, + n = this; + if (E(e)) { + var r = e; + if (r._private.cy === n) t = r.restore(); + else { + for (var i = [], a = 0; a < r.length; a++) { + var o = r[a]; + i.push(o.json()); + } + t = new ts(n, i); + } + } else if (m(e)) { + t = new ts(n, e); + } else if (b(e) && (m(e.nodes) || m(e.edges))) { + for ( + var s = e, l = [], u = ["nodes", "edges"], c = 0, d = u.length; + c < d; + c++ + ) { + var h = u[c], + p = s[h]; + if (m(p)) + for (var f = 0, g = p.length; f < g; f++) { + var v = L({ group: h }, p[f]); + l.push(v); + } + } + t = new ts(n, l); + } else { + t = new et(n, e).collection(); + } + return t; + }, + remove: function (e) { + if (E(e)); + else if (v(e)) { + var t = e; + e = this.$(t); + } + return e.remove(); + }, + }; + /*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */ + /*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */ + var is = (function () { + function e(e) { + return -e.tension * e.x - e.friction * e.v; + } + function t(t, n, r) { + var i = { + x: t.x + r.dx * n, + v: t.v + r.dv * n, + tension: t.tension, + friction: t.friction, + }; + return { dx: i.v, dv: e(i) }; + } + function n(n, r) { + var i = { dx: n.v, dv: e(n) }, + a = t(n, 0.5 * r, i), + o = t(n, 0.5 * r, a), + s = t(n, r, o), + l = (1 / 6) * (i.dx + 2 * (a.dx + o.dx) + s.dx), + u = (1 / 6) * (i.dv + 2 * (a.dv + o.dv) + s.dv); + return ((n.x = n.x + l * r), (n.v = n.v + u * r), n); + } + return function e(t, r, i) { + var a, + o, + s, + l = { x: -1, v: 0, tension: null, friction: null }, + u = [0], + c = 0; + for ( + t = parseFloat(t) || 500, + r = parseFloat(r) || 20, + i = i || null, + l.tension = t, + l.friction = r, + o = (a = null !== i) ? ((c = e(t, r)) / i) * 0.016 : 0.016; + (s = n(s || l, o)), + u.push(1 + s.x), + (c += 16), + Math.abs(s.x) > 1e-4 && Math.abs(s.v) > 1e-4; + ); + return a + ? function (e) { + return u[(e * (u.length - 1)) | 0]; + } + : c; + }; + })(), + as = function (e, t, n, r) { + var i = (function (e, t, n, r) { + var i = 4, + a = 0.001, + o = 1e-7, + s = 10, + l = 11, + u = 1 / (l - 1), + c = "undefined" != typeof Float32Array; + if (4 !== arguments.length) return !1; + for (var d = 0; d < 4; ++d) + if ( + "number" != typeof arguments[d] || + isNaN(arguments[d]) || + !isFinite(arguments[d]) + ) + return !1; + ((e = Math.min(e, 1)), + (n = Math.min(n, 1)), + (e = Math.max(e, 0)), + (n = Math.max(n, 0))); + var h = c ? new Float32Array(l) : new Array(l); + function p(e, t) { + return 1 - 3 * t + 3 * e; + } + function f(e, t) { + return 3 * t - 6 * e; + } + function g(e) { + return 3 * e; + } + function v(e, t, n) { + return ((p(t, n) * e + f(t, n)) * e + g(t)) * e; + } + function y(e, t, n) { + return 3 * p(t, n) * e * e + 2 * f(t, n) * e + g(t); + } + function m(t, r) { + for (var a = 0; a < i; ++a) { + var o = y(r, e, n); + if (0 === o) return r; + r -= (v(r, e, n) - t) / o; + } + return r; + } + function b() { + for (var t = 0; t < l; ++t) h[t] = v(t * u, e, n); + } + function x(t, r, i) { + var a, + l, + u = 0; + do { + (a = v((l = r + (i - r) / 2), e, n) - t) > 0 ? (i = l) : (r = l); + } while (Math.abs(a) > o && ++u < s); + return l; + } + function w(t) { + for (var r = 0, i = 1, o = l - 1; i !== o && h[i] <= t; ++i) r += u; + --i; + var s = r + ((t - h[i]) / (h[i + 1] - h[i])) * u, + c = y(s, e, n); + return c >= a ? m(t, s) : 0 === c ? s : x(t, r, r + u); + } + var E = !1; + function k() { + ((E = !0), (e === t && n === r) || b()); + } + var C = function (i) { + return ( + E || k(), + e === t && n === r ? i : 0 === i ? 0 : 1 === i ? 1 : v(w(i), t, r) + ); + }; + C.getControlPoints = function () { + return [ + { x: e, y: t }, + { x: n, y: r }, + ]; + }; + var S = "generateBezier(" + [e, t, n, r] + ")"; + return ( + (C.toString = function () { + return S; + }), + C + ); + })(e, t, n, r); + return function (e, t, n) { + return e + (t - e) * i(n); + }; + }, + os = { + linear: function (e, t, n) { + return e + (t - e) * n; + }, + ease: as(0.25, 0.1, 0.25, 1), + "ease-in": as(0.42, 0, 1, 1), + "ease-out": as(0, 0, 0.58, 1), + "ease-in-out": as(0.42, 0, 0.58, 1), + "ease-in-sine": as(0.47, 0, 0.745, 0.715), + "ease-out-sine": as(0.39, 0.575, 0.565, 1), + "ease-in-out-sine": as(0.445, 0.05, 0.55, 0.95), + "ease-in-quad": as(0.55, 0.085, 0.68, 0.53), + "ease-out-quad": as(0.25, 0.46, 0.45, 0.94), + "ease-in-out-quad": as(0.455, 0.03, 0.515, 0.955), + "ease-in-cubic": as(0.55, 0.055, 0.675, 0.19), + "ease-out-cubic": as(0.215, 0.61, 0.355, 1), + "ease-in-out-cubic": as(0.645, 0.045, 0.355, 1), + "ease-in-quart": as(0.895, 0.03, 0.685, 0.22), + "ease-out-quart": as(0.165, 0.84, 0.44, 1), + "ease-in-out-quart": as(0.77, 0, 0.175, 1), + "ease-in-quint": as(0.755, 0.05, 0.855, 0.06), + "ease-out-quint": as(0.23, 1, 0.32, 1), + "ease-in-out-quint": as(0.86, 0, 0.07, 1), + "ease-in-expo": as(0.95, 0.05, 0.795, 0.035), + "ease-out-expo": as(0.19, 1, 0.22, 1), + "ease-in-out-expo": as(1, 0, 0, 1), + "ease-in-circ": as(0.6, 0.04, 0.98, 0.335), + "ease-out-circ": as(0.075, 0.82, 0.165, 1), + "ease-in-out-circ": as(0.785, 0.135, 0.15, 0.86), + spring: function (e, t, n) { + if (0 === n) return os.linear; + var r = is(e, t, n); + return function (e, t, n) { + return e + (t - e) * r(n); + }; + }, + "cubic-bezier": as, + }; + function ss(e, t, n, r, i) { + if (1 === r) return n; + if (t === n) return n; + var a = i(t, n, r); + return ( + null == e || + ((e.roundValue || e.color) && (a = Math.round(a)), + void 0 !== e.min && (a = Math.max(a, e.min)), + void 0 !== e.max && (a = Math.min(a, e.max))), + a + ); + } + function ls(e, t) { + return null != e.pfValue || null != e.value + ? null == e.pfValue || (null != t && "%" === t.type.units) + ? e.value + : e.pfValue + : e; + } + function us(e, t, n, r, i) { + var a = null != i ? i.type : null; + n < 0 ? (n = 0) : n > 1 && (n = 1); + var o = ls(e, i), + s = ls(t, i); + if (x(o) && x(s)) return ss(a, o, s, n, r); + if (m(o) && m(s)) { + for (var l = [], u = 0; u < s.length; u++) { + var c = o[u], + d = s[u]; + if (null != c && null != d) { + var h = ss(a, c, d, n, r); + l.push(h); + } else l.push(d); + } + return l; + } + } + function cs(e, t, n, r) { + var i = !r, + a = e._private, + o = t._private, + s = o.easing, + l = o.startTime, + u = (r ? e : e.cy()).style(); + if (!o.easingImpl) + if (null == s) o.easingImpl = os.linear; + else { + var c, d, h; + if (v(s)) c = u.parse("transition-timing-function", s).value; + else c = s; + (v(c) + ? ((d = c), (h = [])) + : ((d = c[1]), + (h = c.slice(2).map(function (e) { + return +e; + }))), + h.length > 0 + ? ("spring" === d && h.push(o.duration), + (o.easingImpl = os[d].apply(null, h))) + : (o.easingImpl = os[d])); + } + var p, + f = o.easingImpl; + if ( + ((p = 0 === o.duration ? 1 : (n - l) / o.duration), + o.applying && (p = o.progress), + p < 0 ? (p = 0) : p > 1 && (p = 1), + null == o.delay) + ) { + var g = o.startPosition, + y = o.position; + if (y && i && !e.locked()) { + var m = {}; + (ds(g.x, y.x) && (m.x = us(g.x, y.x, p, f)), + ds(g.y, y.y) && (m.y = us(g.y, y.y, p, f)), + e.position(m)); + } + var b = o.startPan, + x = o.pan, + w = a.pan, + E = null != x && r; + E && + (ds(b.x, x.x) && (w.x = us(b.x, x.x, p, f)), + ds(b.y, x.y) && (w.y = us(b.y, x.y, p, f)), + e.emit("pan")); + var k = o.startZoom, + C = o.zoom, + S = null != C && r; + (S && + (ds(k, C) && (a.zoom = Tt(a.minZoom, us(k, C, p, f), a.maxZoom)), + e.emit("zoom")), + (E || S) && e.emit("viewport")); + var P = o.style; + if (P && P.length > 0 && i) { + for (var D = 0; D < P.length; D++) { + var T = P[D], + _ = T.name, + M = T, + B = o.startStyle[_], + N = us(B, M, p, f, u.properties[B.name]); + u.overrideBypass(e, _, N); + } + e.emit("style"); + } + } + return ((o.progress = p), p); + } + function ds(e, t) { + return null != e && null != t && (!(!x(e) || !x(t)) || !(!e || !t)); + } + function hs(e, t, n, r) { + var i = t._private; + ((i.started = !0), (i.startTime = n - i.progress * i.duration)); + } + function ps(e, t) { + var n = t._private.aniEles, + r = []; + function i(t, n) { + var i = t._private, + a = i.animation.current, + o = i.animation.queue, + s = !1; + if (0 === a.length) { + var l = o.shift(); + l && a.push(l); + } + for ( + var u = function (e) { + for (var t = e.length - 1; t >= 0; t--) { + (0, e[t])(); + } + e.splice(0, e.length); + }, + c = a.length - 1; + c >= 0; + c-- + ) { + var d = a[c], + h = d._private; + h.stopped + ? (a.splice(c, 1), + (h.hooked = !1), + (h.playing = !1), + (h.started = !1), + u(h.frames)) + : (h.playing || h.applying) && + (h.playing && h.applying && (h.applying = !1), + h.started || hs(0, d, e), + cs(t, d, e, n), + h.applying && (h.applying = !1), + u(h.frames), + null != h.step && h.step(e), + d.completed() && + (a.splice(c, 1), + (h.hooked = !1), + (h.playing = !1), + (h.started = !1), + u(h.completes)), + (s = !0)); + } + return (n || 0 !== a.length || 0 !== o.length || r.push(t), s); + } + for (var a = !1, o = 0; o < n.length; o++) { + var s = i(n[o]); + a = a || s; + } + var l = i(t, !0); + ((a || l) && (n.length > 0 ? t.notify("draw", n) : t.notify("draw")), + n.unmerge(r), + t.emit("step")); + } + var fs = { + animate: Fi.animate(), + animation: Fi.animation(), + animated: Fi.animated(), + clearQueue: Fi.clearQueue(), + delay: Fi.delay(), + delayAnimation: Fi.delayAnimation(), + stop: Fi.stop(), + addToAnimationPool: function (e) { + this.styleEnabled() && this._private.aniEles.merge(e); + }, + stopAnimationLoop: function () { + this._private.animationsRunning = !1; + }, + startAnimationLoop: function () { + var e = this; + if (((e._private.animationsRunning = !0), e.styleEnabled())) { + var t = e.renderer(); + t && t.beforeRender + ? t.beforeRender(function (t, n) { + ps(n, e); + }, t.beforeRenderPriorities.animations) + : (function t() { + e._private.animationsRunning && + xe(function (n) { + (ps(n, e), t()); + }); + })(); + } + }, + }, + gs = { + qualifierCompare: function (e, t) { + return null == e || null == t ? null == e && null == t : e.sameText(t); + }, + eventMatches: function (e, t, n) { + var r = t.qualifier; + return ( + null == r || (e !== n.target && k(n.target) && r.matches(n.target)) + ); + }, + addEventFields: function (e, t) { + ((t.cy = e), (t.target = e)); + }, + callbackContext: function (e, t, n) { + return null != t.qualifier ? n.target : e; + }, + }, + vs = function (e) { + return v(e) ? new ka(e) : e; + }, + ys = { + createEmitter: function () { + var e = this._private; + return (e.emitter || (e.emitter = new xo(gs, this)), this); + }, + emitter: function () { + return this._private.emitter; + }, + on: function (e, t, n) { + return (this.emitter().on(e, vs(t), n), this); + }, + removeListener: function (e, t, n) { + return (this.emitter().removeListener(e, vs(t), n), this); + }, + removeAllListeners: function () { + return (this.emitter().removeAllListeners(), this); + }, + one: function (e, t, n) { + return (this.emitter().one(e, vs(t), n), this); + }, + once: function (e, t, n) { + return (this.emitter().one(e, vs(t), n), this); + }, + emit: function (e, t) { + return (this.emitter().emit(e, t), this); + }, + emitAndNotify: function (e, t) { + return (this.emit(e), this.notify(e, t), this); + }, + }; + Fi.eventAliasesOn(ys); + var ms = { + png: function (e) { + return ((e = e || {}), this._private.renderer.png(e)); + }, + jpg: function (e) { + var t = this._private.renderer; + return (((e = e || {}).bg = e.bg || "#fff"), t.jpg(e)); + }, + }; + ms.jpeg = ms.jpg; + var bs = { + layout: function (e) { + if (null != e) + if (null != e.name) { + var t = e.name, + n = this.extension("layout", t); + if (null != n) { + var r; + r = v(e.eles) ? this.$(e.eles) : null != e.eles ? e.eles : this.$(); + var i = new n(L({}, e, { cy: this, eles: r })); + return i; + } + Ve( + "No such layout `" + + t + + "` found. Did you forget to import it and `cytoscape.use()` it?", + ); + } else Ve("A `name` must be specified to make a layout"); + else Ve("Layout options must be specified to make a layout"); + }, + }; + bs.createLayout = bs.makeLayout = bs.layout; + var xs = { + notify: function (e, t) { + var n = this._private; + if (this.batching()) { + n.batchNotifications = n.batchNotifications || {}; + var r = (n.batchNotifications[e] = + n.batchNotifications[e] || this.collection()); + null != t && r.merge(t); + } else if (n.notificationsEnabled) { + var i = this.renderer(); + !this.destroyed() && i && i.notify(e, t); + } + }, + notifications: function (e) { + var t = this._private; + return void 0 === e + ? t.notificationsEnabled + : ((t.notificationsEnabled = !!e), this); + }, + noNotifications: function (e) { + (this.notifications(!1), e(), this.notifications(!0)); + }, + batching: function () { + return this._private.batchCount > 0; + }, + startBatch: function () { + var e = this._private; + return ( + null == e.batchCount && (e.batchCount = 0), + 0 === e.batchCount && + ((e.batchStyleEles = this.collection()), + (e.batchNotifications = {})), + e.batchCount++, + this + ); + }, + endBatch: function () { + var e = this._private; + if (0 === e.batchCount) return this; + if ((e.batchCount--, 0 === e.batchCount)) { + e.batchStyleEles.updateStyle(); + var t = this.renderer(); + Object.keys(e.batchNotifications).forEach(function (n) { + var r = e.batchNotifications[n]; + r.empty() ? t.notify(n) : t.notify(n, r); + }); + } + return this; + }, + batch: function (e) { + return (this.startBatch(), e(), this.endBatch(), this); + }, + batchData: function (e) { + var t = this; + return this.batch(function () { + for (var n = Object.keys(e), r = 0; r < n.length; r++) { + var i = n[r], + a = e[i]; + t.getElementById(i).data(a); + } + }); + }, + }, + ws = He({ + hideEdgesOnViewport: !1, + textureOnViewport: !1, + motionBlur: !1, + motionBlurOpacity: 0.05, + pixelRatio: void 0, + desktopTapThreshold: 4, + touchTapThreshold: 8, + wheelSensitivity: 1, + debug: !1, + showFps: !1, + }), + Es = { + renderTo: function (e, t, n, r) { + return (this._private.renderer.renderTo(e, t, n, r), this); + }, + renderer: function () { + return this._private.renderer; + }, + forceRender: function () { + return (this.notify("draw"), this); + }, + resize: function () { + return (this.invalidateSize(), this.emitAndNotify("resize"), this); + }, + initRenderer: function (e) { + var t = this.extension("renderer", e.name); + if (null != t) { + void 0 !== e.wheelSensitivity && + je( + "You have set a custom wheel sensitivity. This will make your app zoom unnaturally when using mainstream mice. You should change this value from the default only if you can guarantee that all your users will use the same hardware and OS configuration as your current machine.", + ); + var n = ws(e); + ((n.cy = this), + (this._private.renderer = new t(n)), + this.notify("init")); + } else + Ve( + "Can not initialise: No such renderer `".concat( + e.name, + "` found. Did you forget to import it and `cytoscape.use()` it?", + ), + ); + }, + destroyRenderer: function () { + this.notify("destroy"); + var e = this.container(); + if (e) + for (e._cyreg = null; e.childNodes.length > 0; ) + e.removeChild(e.childNodes[0]); + ((this._private.renderer = null), + this.mutableElements().forEach(function (e) { + var t = e._private; + ((t.rscratch = {}), + (t.rstyle = {}), + (t.animation.current = []), + (t.animation.queue = [])); + })); + }, + onRender: function (e) { + return this.on("render", e); + }, + offRender: function (e) { + return this.off("render", e); + }, + }; + Es.invalidateDimensions = Es.resize; + var ks = { + collection: function (e, t) { + return v(e) + ? this.$(e) + : E(e) + ? e.collection() + : m(e) + ? (t || (t = {}), new ts(this, e, t.unique, t.removed)) + : new ts(this); + }, + nodes: function (e) { + var t = this.$(function (e) { + return e.isNode(); + }); + return e ? t.filter(e) : t; + }, + edges: function (e) { + var t = this.$(function (e) { + return e.isEdge(); + }); + return e ? t.filter(e) : t; + }, + $: function (e) { + var t = this._private.elements; + return e ? t.filter(e) : t.spawnSelf(); + }, + mutableElements: function () { + return this._private.elements; + }, + }; + ks.elements = ks.filter = ks.$; + var Cs = {}; + ((Cs.apply = function (e) { + for (var t = this._private.cy.collection(), n = 0; n < e.length; n++) { + var r = e[n], + i = this.getContextMeta(r); + if (!i.empty) { + var a = this.getContextStyle(i), + o = this.applyContextStyle(i, a, r); + (r._private.appliedInitStyle + ? this.updateTransitions(r, o.diffProps) + : (r._private.appliedInitStyle = !0), + this.updateStyleHints(r) && t.push(r)); + } + } + return t; + }), + (Cs.getPropertiesDiff = function (e, t) { + var n = (this._private.propDiffs = this._private.propDiffs || {}), + r = e + "-" + t, + i = n[r]; + if (i) return i; + for (var a = [], o = {}, s = 0; s < this.length; s++) { + var l = this[s], + u = "t" === e[s], + c = "t" === t[s], + d = u !== c, + h = l.mappedProperties.length > 0; + if (d || (c && h)) { + var p = void 0; + (d && h) || d ? (p = l.properties) : h && (p = l.mappedProperties); + for (var f = 0; f < p.length; f++) { + for ( + var g = p[f], v = g.name, y = !1, m = s + 1; + m < this.length; + m++ + ) { + var b = this[m]; + if ("t" === t[m] && (y = null != b.properties[g.name])) break; + } + o[v] || y || ((o[v] = !0), a.push(v)); + } + } + } + return ((n[r] = a), a); + }), + (Cs.getContextMeta = function (e) { + for ( + var t, n = "", r = e._private.styleCxtKey || "", i = 0; + i < this.length; + i++ + ) { + var a = this[i]; + n += a.selector && a.selector.matches(e) ? "t" : "f"; + } + return ( + (t = this.getPropertiesDiff(r, n)), + (e._private.styleCxtKey = n), + { key: n, diffPropNames: t, empty: 0 === t.length } + ); + }), + (Cs.getContextStyle = function (e) { + var t = e.key, + n = (this._private.contextStyles = this._private.contextStyles || {}); + if (n[t]) return n[t]; + for (var r = { _private: { key: t } }, i = 0; i < this.length; i++) { + var a = this[i]; + if ("t" === t[i]) + for (var o = 0; o < a.properties.length; o++) { + var s = a.properties[o]; + r[s.name] = s; + } + } + return ((n[t] = r), r); + }), + (Cs.applyContextStyle = function (e, t, n) { + for ( + var r = e.diffPropNames, i = {}, a = this.types, o = 0; + o < r.length; + o++ + ) { + var s = r[o], + l = t[s], + u = n.pstyle(s); + if (!l) { + if (!u) continue; + l = u.bypass + ? { name: s, deleteBypassed: !0 } + : { name: s, delete: !0 }; + } + if (u !== l) { + if ( + l.mapped === a.fn && + null != u && + null != u.mapping && + u.mapping.value === l.value + ) { + var c = u.mapping; + if ((c.fnValue = l.value(n)) === c.prevFnValue) continue; + } + var d = (i[s] = { prev: u }); + (this.applyParsedProperty(n, l), + (d.next = n.pstyle(s)), + d.next && d.next.bypass && (d.next = d.next.bypassed)); + } + } + return { diffProps: i }; + }), + (Cs.updateStyleHints = function (e) { + var t = e._private, + n = this, + r = n.propertyGroupNames, + i = n.propertyGroupKeys, + a = function (e, t, r) { + return n.getPropertiesHash(e, t, r); + }, + o = t.styleKey; + if (e.removed()) return !1; + var s = "nodes" === t.group, + l = e._private.style; + r = Object.keys(l); + for (var u = 0; u < i.length; u++) { + var c = i[u]; + t.styleKeys[c] = [9261, 5381]; + } + for ( + var d, + h = function (e, n) { + return (t.styleKeys[n][0] = Ce(e, t.styleKeys[n][0])); + }, + p = function (e, n) { + return (t.styleKeys[n][1] = Se(e, t.styleKeys[n][1])); + }, + f = function (e, t) { + (h(e, t), p(e, t)); + }, + g = function (e, t) { + for (var n = 0; n < e.length; n++) { + var r = e.charCodeAt(n); + (h(r, t), p(r, t)); + } + }, + v = 0; + v < r.length; + v++ + ) { + var y = r[v], + m = l[y]; + if (null != m) { + var b = this.properties[y], + x = b.type, + w = b.groupKey, + E = void 0; + null != b.hashOverride + ? (E = b.hashOverride(e, m)) + : null != m.pfValue && (E = m.pfValue); + var k = null == b.enums ? m.value : null, + C = null != E, + S = C || null != k, + P = m.units; + if (x.number && S && !x.multiple) + (f( + -128 < (d = C ? E : k) && d < 128 && Math.floor(d) !== d + ? 2e9 - ((1024 * d) | 0) + : d, + w, + ), + C || null == P || g(P, w)); + else g(m.strValue, w); + } + } + for (var D, T, _ = [9261, 5381], M = 0; M < i.length; M++) { + var B = i[M], + N = t.styleKeys[B]; + ((_[0] = Ce(N[0], _[0])), (_[1] = Se(N[1], _[1]))); + } + t.styleKey = ((D = _[0]), (T = _[1]), 2097152 * D + T); + var z = t.styleKeys; + t.labelDimsKey = Pe(z.labelDimensions); + var I = a(e, ["label"], z.labelDimensions); + if ( + ((t.labelKey = Pe(I)), (t.labelStyleKey = Pe(De(z.commonLabel, I))), !s) + ) { + var A = a(e, ["source-label"], z.labelDimensions); + ((t.sourceLabelKey = Pe(A)), + (t.sourceLabelStyleKey = Pe(De(z.commonLabel, A)))); + var L = a(e, ["target-label"], z.labelDimensions); + ((t.targetLabelKey = Pe(L)), + (t.targetLabelStyleKey = Pe(De(z.commonLabel, L)))); + } + if (s) { + var O = t.styleKeys, + R = O.nodeBody, + V = O.nodeBorder, + F = O.nodeOutline, + j = O.backgroundImage, + q = O.compound, + Y = O.pie, + X = [R, V, F, j, q, Y] + .filter(function (e) { + return null != e; + }) + .reduce(De, [9261, 5381]); + ((t.nodeKey = Pe(X)), + (t.hasPie = null != Y && 9261 !== Y[0] && 5381 !== Y[1])); + } + return o !== t.styleKey; + }), + (Cs.clearStyleHints = function (e) { + var t = e._private; + ((t.styleCxtKey = ""), + (t.styleKeys = {}), + (t.styleKey = null), + (t.labelKey = null), + (t.labelStyleKey = null), + (t.sourceLabelKey = null), + (t.sourceLabelStyleKey = null), + (t.targetLabelKey = null), + (t.targetLabelStyleKey = null), + (t.nodeKey = null), + (t.hasPie = null)); + }), + (Cs.applyParsedProperty = function (e, t) { + var n, + r = this, + i = t, + a = e._private.style, + o = r.types, + s = r.properties[i.name].type, + l = i.bypass, + u = a[i.name], + c = u && u.bypass, + d = e._private, + h = function (e) { + return null == e ? null : null != e.pfValue ? e.pfValue : e.value; + }, + p = function () { + var t = h(u), + n = h(i); + r.checkTriggers(e, i.name, t, n); + }; + if ( + ("curve-style" === t.name && + e.isEdge() && + (("bezier" !== t.value && e.isLoop()) || + ("haystack" === t.value && + (e.source().isParent() || e.target().isParent()))) && + (i = t = this.parse(t.name, "bezier", l)), + i.delete) + ) + return ((a[i.name] = void 0), p(), !0); + if (i.deleteBypassed) + return u ? !!u.bypass && ((u.bypassed = void 0), p(), !0) : (p(), !0); + if (i.deleteBypass) + return u + ? !!u.bypass && ((a[i.name] = u.bypassed), p(), !0) + : (p(), !0); + var f = function () { + je( + "Do not assign mappings to elements without corresponding data (i.e. ele `" + + e.id() + + "` has no mapping for property `" + + i.name + + "` with data field `" + + i.field + + "`); try a `[" + + i.field + + "]` selector to limit scope to elements with `" + + i.field + + "` defined", + ); + }; + switch (i.mapped) { + case o.mapData: + for ( + var g, v = i.field.split("."), y = d.data, m = 0; + m < v.length && y; + m++ + ) { + y = y[v[m]]; + } + if (null == y) return (f(), !1); + if (!x(y)) + return ( + je( + "Do not use continuous mappers without specifying numeric data (i.e. `" + + i.field + + ": " + + y + + "` for `" + + e.id() + + "` is non-numeric)", + ), + !1 + ); + var b = i.fieldMax - i.fieldMin; + if ( + ((g = 0 === b ? 0 : (y - i.fieldMin) / b) < 0 + ? (g = 0) + : g > 1 && (g = 1), + s.color) + ) { + var w = i.valueMin[0], + E = i.valueMax[0], + k = i.valueMin[1], + C = i.valueMax[1], + S = i.valueMin[2], + P = i.valueMax[2], + D = null == i.valueMin[3] ? 1 : i.valueMin[3], + T = null == i.valueMax[3] ? 1 : i.valueMax[3], + _ = [ + Math.round(w + (E - w) * g), + Math.round(k + (C - k) * g), + Math.round(S + (P - S) * g), + Math.round(D + (T - D) * g), + ]; + n = { + bypass: i.bypass, + name: i.name, + value: _, + strValue: "rgb(" + _[0] + ", " + _[1] + ", " + _[2] + ")", + }; + } else { + if (!s.number) return !1; + var M = i.valueMin + (i.valueMax - i.valueMin) * g; + n = this.parse(i.name, M, i.bypass, "mapping"); + } + if (!n) return (f(), !1); + ((n.mapping = i), (i = n)); + break; + case o.data: + for ( + var B = i.field.split("."), N = d.data, z = 0; + z < B.length && N; + z++ + ) { + N = N[B[z]]; + } + if ( + (null != N && (n = this.parse(i.name, N, i.bypass, "mapping")), !n) + ) + return (f(), !1); + ((n.mapping = i), (i = n)); + break; + case o.fn: + var I = i.value, + A = null != i.fnValue ? i.fnValue : I(e); + if (((i.prevFnValue = A), null == A)) + return ( + je( + "Custom function mappers may not return null (i.e. `" + + i.name + + "` for ele `" + + e.id() + + "` is null)", + ), + !1 + ); + if (!(n = this.parse(i.name, A, i.bypass, "mapping"))) + return ( + je( + "Custom function mappers may not return invalid values for the property type (i.e. `" + + i.name + + "` for ele `" + + e.id() + + "` is invalid)", + ), + !1 + ); + ((n.mapping = qe(i)), (i = n)); + break; + case void 0: + break; + default: + return !1; + } + return ( + l + ? ((i.bypassed = c ? u.bypassed : u), (a[i.name] = i)) + : c + ? (u.bypassed = i) + : (a[i.name] = i), + p(), + !0 + ); + }), + (Cs.cleanElements = function (e, t) { + for (var n = 0; n < e.length; n++) { + var r = e[n]; + if ( + (this.clearStyleHints(r), + r.dirtyCompoundBoundsCache(), + r.dirtyBoundingBoxCache(), + t) + ) + for ( + var i = r._private.style, a = Object.keys(i), o = 0; + o < a.length; + o++ + ) { + var s = a[o], + l = i[s]; + null != l && (l.bypass ? (l.bypassed = null) : (i[s] = null)); + } + else r._private.style = {}; + } + }), + (Cs.update = function () { + this._private.cy.mutableElements().updateStyle(); + }), + (Cs.updateTransitions = function (e, t) { + var n = this, + r = e._private, + i = e.pstyle("transition-property").value, + a = e.pstyle("transition-duration").pfValue, + o = e.pstyle("transition-delay").pfValue; + if (i.length > 0 && a > 0) { + for (var s = {}, l = !1, u = 0; u < i.length; u++) { + var c = i[u], + d = e.pstyle(c), + h = t[c]; + if (h) { + var p = h.prev, + f = null != h.next ? h.next : d, + g = !1, + v = void 0; + p && + (x(p.pfValue) && x(f.pfValue) + ? ((g = f.pfValue - p.pfValue), (v = p.pfValue + 1e-6 * g)) + : x(p.value) && x(f.value) + ? ((g = f.value - p.value), (v = p.value + 1e-6 * g)) + : m(p.value) && + m(f.value) && + ((g = + p.value[0] !== f.value[0] || + p.value[1] !== f.value[1] || + p.value[2] !== f.value[2]), + (v = p.strValue)), + g && ((s[c] = f.strValue), this.applyBypass(e, c, v), (l = !0))); + } + } + if (!l) return; + ((r.transitioning = !0), + new vr(function (t) { + o > 0 ? e.delayAnimation(o).play().promise().then(t) : t(); + }) + .then(function () { + return e + .animation({ + style: s, + duration: a, + easing: e.pstyle("transition-timing-function").value, + queue: !1, + }) + .play() + .promise(); + }) + .then(function () { + (n.removeBypasses(e, i), + e.emitAndNotify("style"), + (r.transitioning = !1)); + })); + } else + r.transitioning && + (this.removeBypasses(e, i), + e.emitAndNotify("style"), + (r.transitioning = !1)); + }), + (Cs.checkTrigger = function (e, t, n, r, i, a) { + var o = this.properties[t], + s = i(o); + null != s && s(n, r) && a(o); + }), + (Cs.checkZOrderTrigger = function (e, t, n, r) { + var i = this; + this.checkTrigger( + e, + t, + n, + r, + function (e) { + return e.triggersZOrder; + }, + function () { + i._private.cy.notify("zorder", e); + }, + ); + }), + (Cs.checkBoundsTrigger = function (e, t, n, r) { + this.checkTrigger( + e, + t, + n, + r, + function (e) { + return e.triggersBounds; + }, + function (i) { + (e.dirtyCompoundBoundsCache(), + e.dirtyBoundingBoxCache(), + !i.triggersBoundsOfParallelBeziers || + "curve-style" !== t || + ("bezier" !== n && "bezier" !== r) || + e.parallelEdges().forEach(function (e) { + e.isBundledBezier() && e.dirtyBoundingBoxCache(); + }), + !i.triggersBoundsOfConnectedEdges || + "display" !== t || + ("none" !== n && "none" !== r) || + e.connectedEdges().forEach(function (e) { + e.dirtyBoundingBoxCache(); + })); + }, + ); + }), + (Cs.checkTriggers = function (e, t, n, r) { + (e.dirtyStyleCache(), + this.checkZOrderTrigger(e, t, n, r), + this.checkBoundsTrigger(e, t, n, r)); + })); + var Ss = { + applyBypass: function (e, t, n, r) { + var i = []; + if ("*" === t || "**" === t) { + if (void 0 !== n) + for (var a = 0; a < this.properties.length; a++) { + var o = this.properties[a].name, + s = this.parse(o, n, !0); + s && i.push(s); + } + } else if (v(t)) { + var l = this.parse(t, n, !0); + l && i.push(l); + } else { + if (!b(t)) return !1; + var u = t; + r = n; + for (var c = Object.keys(u), d = 0; d < c.length; d++) { + var h = c[d], + p = u[h]; + if ((void 0 === p && (p = u[B(h)]), void 0 !== p)) { + var f = this.parse(h, p, !0); + f && i.push(f); + } + } + } + if (0 === i.length) return !1; + for (var g = !1, y = 0; y < e.length; y++) { + for (var m = e[y], x = {}, w = void 0, E = 0; E < i.length; E++) { + var k = i[E]; + if (r) { + var C = m.pstyle(k.name); + w = x[k.name] = { prev: C }; + } + ((g = this.applyParsedProperty(m, qe(k)) || g), + r && (w.next = m.pstyle(k.name))); + } + (g && this.updateStyleHints(m), + r && this.updateTransitions(m, x, !0)); + } + return g; + }, + overrideBypass: function (e, t, n) { + t = M(t); + for (var r = 0; r < e.length; r++) { + var i = e[r], + a = i._private.style[t], + o = this.properties[t].type, + s = o.color, + l = o.mutiple, + u = a ? (null != a.pfValue ? a.pfValue : a.value) : null; + (a && a.bypass + ? ((a.value = n), + null != a.pfValue && (a.pfValue = n), + (a.strValue = s + ? "rgb(" + n.join(",") + ")" + : l + ? n.join(" ") + : "" + n), + this.updateStyleHints(i)) + : this.applyBypass(i, t, n), + this.checkTriggers(i, t, u, n)); + } + }, + removeAllBypasses: function (e, t) { + return this.removeBypasses(e, this.propertyNames, t); + }, + removeBypasses: function (e, t, n) { + for (var r = 0; r < e.length; r++) { + for (var i = e[r], a = {}, o = 0; o < t.length; o++) { + var s = t[o], + l = this.properties[s], + u = i.pstyle(l.name); + if (u && u.bypass) { + var c = this.parse(s, "", !0), + d = (a[l.name] = { prev: u }); + (this.applyParsedProperty(i, c), (d.next = i.pstyle(l.name))); + } + } + (this.updateStyleHints(i), n && this.updateTransitions(i, a, !0)); + } + }, + }, + Ps = { + getEmSizeInPixels: function () { + var e = this.containerCss("font-size"); + return null != e ? parseFloat(e) : 1; + }, + containerCss: function (e) { + var t = this._private.cy, + n = t.container(), + r = t.window(); + if (r && n && r.getComputedStyle) + return r.getComputedStyle(n).getPropertyValue(e); + }, + }, + Ds = { + getRenderedStyle: function (e, t) { + return t + ? this.getStylePropertyValue(e, t, !0) + : this.getRawStyle(e, !0); + }, + getRawStyle: function (e, t) { + if ((e = e[0])) { + for (var n = {}, r = 0; r < this.properties.length; r++) { + var i = this.properties[r], + a = this.getStylePropertyValue(e, i.name, t); + null != a && ((n[i.name] = a), (n[B(i.name)] = a)); + } + return n; + } + }, + getIndexedStyle: function (e, t, n, r) { + var i = e.pstyle(t)[n][r]; + return null != i ? i : e.cy().style().getDefaultProperty(t)[n][0]; + }, + getStylePropertyValue: function (e, t, n) { + if ((e = e[0])) { + var r = this.properties[t]; + r.alias && (r = r.pointsTo); + var i = r.type, + a = e.pstyle(r.name); + if (a) { + var o = a.value, + s = a.units, + l = a.strValue; + if (n && i.number && null != o && x(o)) { + var u = e.cy().zoom(), + c = function (e) { + return e * u; + }, + d = function (e, t) { + return c(e) + t; + }, + h = m(o); + return ( + h + ? s.every(function (e) { + return null != e; + }) + : null != s + ) + ? h + ? o + .map(function (e, t) { + return d(e, s[t]); + }) + .join(" ") + : d(o, s) + : h + ? o + .map(function (e) { + return v(e) ? e : "" + c(e); + }) + .join(" ") + : "" + c(o); + } + if (null != l) return l; + } + return null; + } + }, + getAnimationStartStyle: function (e, t) { + for (var n = {}, r = 0; r < t.length; r++) { + var i = t[r].name, + a = e.pstyle(i); + (void 0 !== a && + (a = b(a) ? this.parse(i, a.strValue) : this.parse(i, a)), + a && (n[i] = a)); + } + return n; + }, + getPropsList: function (e) { + var t = [], + n = e, + r = this.properties; + if (n) + for (var i = Object.keys(n), a = 0; a < i.length; a++) { + var o = i[a], + s = n[o], + l = r[o] || r[M(o)], + u = this.parse(l.name, s); + u && t.push(u); + } + return t; + }, + getNonDefaultPropertiesHash: function (e, t, n) { + var r, + i, + a, + o, + s, + l, + u = n.slice(); + for (s = 0; s < t.length; s++) + if (((r = t[s]), null != (i = e.pstyle(r, !1)))) + if (null != i.pfValue) ((u[0] = Ce(o, u[0])), (u[1] = Se(o, u[1]))); + else + for (a = i.strValue, l = 0; l < a.length; l++) + ((o = a.charCodeAt(l)), + (u[0] = Ce(o, u[0])), + (u[1] = Se(o, u[1]))); + return u; + }, + }; + Ds.getPropertiesHash = Ds.getNonDefaultPropertiesHash; + var Ts = { + appendFromJson: function (e) { + for (var t = 0; t < e.length; t++) { + var n = e[t], + r = n.selector, + i = n.style || n.css, + a = Object.keys(i); + this.selector(r); + for (var o = 0; o < a.length; o++) { + var s = a[o], + l = i[s]; + this.css(s, l); + } + } + return this; + }, + fromJson: function (e) { + return (this.resetToDefault(), this.appendFromJson(e), this); + }, + json: function () { + for (var e = [], t = this.defaultLength; t < this.length; t++) { + for ( + var n = this[t], r = n.selector, i = n.properties, a = {}, o = 0; + o < i.length; + o++ + ) { + var s = i[o]; + a[s.name] = s.strValue; + } + e.push({ selector: r ? r.toString() : "core", style: a }); + } + return e; + }, + }, + _s = { + appendFromString: function (e) { + var t, + n, + r, + i = "" + e; + function a() { + i = i.length > t.length ? i.substr(t.length) : ""; + } + function o() { + n = n.length > r.length ? n.substr(r.length) : ""; + } + for (i = i.replace(/[/][*](\s|.)+?[*][/]/g, ""); ; ) { + if (i.match(/^\s*$/)) break; + var s = i.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/); + if (!s) { + je( + "Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: " + + i, + ); + break; + } + t = s[0]; + var l = s[1]; + if ("core" !== l) + if (new ka(l).invalid) { + (je( + "Skipping parsing of block: Invalid selector found in string stylesheet: " + + l, + ), + a()); + continue; + } + var u = s[2], + c = !1; + n = u; + for (var d = []; ; ) { + if (n.match(/^\s*$/)) break; + var h = n.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/); + if (!h) { + (je( + "Skipping parsing of block: Invalid formatting of style property and value definitions found in:" + + u, + ), + (c = !0)); + break; + } + r = h[0]; + var p = h[1], + f = h[2]; + if (this.properties[p]) + this.parse(p, f) + ? (d.push({ name: p, val: f }), o()) + : (je( + "Skipping property: Invalid property definition in: " + r, + ), + o()); + else (je("Skipping property: Invalid property name in: " + r), o()); + } + if (c) { + a(); + break; + } + this.selector(l); + for (var g = 0; g < d.length; g++) { + var v = d[g]; + this.css(v.name, v.val); + } + a(); + } + return this; + }, + fromString: function (e) { + return (this.resetToDefault(), this.appendFromString(e), this); + }, + }, + Ms = {}; + (!(function () { + var e = I, + t = function (e) { + return "^" + e + "\\s*\\(\\s*([\\w\\.]+)\\s*\\)$"; + }, + n = function (t) { + var n = + e + + "|\\w+|rgb[a]?\\((?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%]?)\\s*,\\s*(?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%]?)\\s*,\\s*(?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%]?)(?:\\s*,\\s*(?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))))?\\)|hsl[a]?\\((?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?)))\\s*,\\s*(?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%])\\s*,\\s*(?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%])(?:\\s*,\\s*(?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))))?\\)|\\#[0-9a-fA-F]{3}|\\#[0-9a-fA-F]{6}"; + return ( + "^" + + t + + "\\s*\\(([\\w\\.]+)\\s*\\,\\s*(" + + e + + ")\\s*\\,\\s*(" + + e + + ")\\s*,\\s*(" + + n + + ")\\s*\\,\\s*(" + + n + + ")\\)$" + ); + }, + r = ["^url\\s*\\(\\s*['\"]?(.+?)['\"]?\\s*\\)$", "^(none)$", "^(.+)$"]; + Ms.types = { + time: { number: !0, min: 0, units: "s|ms", implicitUnits: "ms" }, + percent: { number: !0, min: 0, max: 100, units: "%", implicitUnits: "%" }, + percentages: { + number: !0, + min: 0, + max: 100, + units: "%", + implicitUnits: "%", + multiple: !0, + }, + zeroOneNumber: { number: !0, min: 0, max: 1, unitless: !0 }, + zeroOneNumbers: { + number: !0, + min: 0, + max: 1, + unitless: !0, + multiple: !0, + }, + nOneOneNumber: { number: !0, min: -1, max: 1, unitless: !0 }, + nonNegativeInt: { number: !0, min: 0, integer: !0, unitless: !0 }, + nonNegativeNumber: { number: !0, min: 0, unitless: !0 }, + position: { enums: ["parent", "origin"] }, + nodeSize: { number: !0, min: 0, enums: ["label"] }, + number: { number: !0, unitless: !0 }, + numbers: { number: !0, unitless: !0, multiple: !0 }, + positiveNumber: { number: !0, unitless: !0, min: 0, strictMin: !0 }, + size: { number: !0, min: 0 }, + bidirectionalSize: { number: !0 }, + bidirectionalSizeMaybePercent: { number: !0, allowPercent: !0 }, + bidirectionalSizes: { number: !0, multiple: !0 }, + sizeMaybePercent: { number: !0, min: 0, allowPercent: !0 }, + axisDirection: { + enums: [ + "horizontal", + "leftward", + "rightward", + "vertical", + "upward", + "downward", + "auto", + ], + }, + paddingRelativeTo: { + enums: ["width", "height", "average", "min", "max"], + }, + bgWH: { + number: !0, + min: 0, + allowPercent: !0, + enums: ["auto"], + multiple: !0, + }, + bgPos: { number: !0, allowPercent: !0, multiple: !0 }, + bgRelativeTo: { enums: ["inner", "include-padding"], multiple: !0 }, + bgRepeat: { + enums: ["repeat", "repeat-x", "repeat-y", "no-repeat"], + multiple: !0, + }, + bgFit: { enums: ["none", "contain", "cover"], multiple: !0 }, + bgCrossOrigin: { + enums: ["anonymous", "use-credentials", "null"], + multiple: !0, + }, + bgClip: { enums: ["none", "node"], multiple: !0 }, + bgContainment: { enums: ["inside", "over"], multiple: !0 }, + color: { color: !0 }, + colors: { color: !0, multiple: !0 }, + fill: { enums: ["solid", "linear-gradient", "radial-gradient"] }, + bool: { enums: ["yes", "no"] }, + bools: { enums: ["yes", "no"], multiple: !0 }, + lineStyle: { enums: ["solid", "dotted", "dashed"] }, + lineCap: { enums: ["butt", "round", "square"] }, + linePosition: { enums: ["center", "inside", "outside"] }, + lineJoin: { enums: ["round", "bevel", "miter"] }, + borderStyle: { enums: ["solid", "dotted", "dashed", "double"] }, + curveStyle: { + enums: [ + "bezier", + "unbundled-bezier", + "haystack", + "segments", + "straight", + "straight-triangle", + "taxi", + "round-segments", + "round-taxi", + ], + }, + radiusType: { enums: ["arc-radius", "influence-radius"], multiple: !0 }, + fontFamily: { regex: '^([\\w- \\"]+(?:\\s*,\\s*[\\w- \\"]+)*)$' }, + fontStyle: { enums: ["italic", "normal", "oblique"] }, + fontWeight: { + enums: [ + "normal", + "bold", + "bolder", + "lighter", + "100", + "200", + "300", + "400", + "500", + "600", + "800", + "900", + 100, + 200, + 300, + 400, + 500, + 600, + 700, + 800, + 900, + ], + }, + textDecoration: { + enums: ["none", "underline", "overline", "line-through"], + }, + textTransform: { enums: ["none", "uppercase", "lowercase"] }, + textWrap: { enums: ["none", "wrap", "ellipsis"] }, + textOverflowWrap: { enums: ["whitespace", "anywhere"] }, + textBackgroundShape: { + enums: ["rectangle", "roundrectangle", "round-rectangle"], + }, + nodeShape: { + enums: [ + "rectangle", + "roundrectangle", + "round-rectangle", + "cutrectangle", + "cut-rectangle", + "bottomroundrectangle", + "bottom-round-rectangle", + "barrel", + "ellipse", + "triangle", + "round-triangle", + "square", + "pentagon", + "round-pentagon", + "hexagon", + "round-hexagon", + "concavehexagon", + "concave-hexagon", + "heptagon", + "round-heptagon", + "octagon", + "round-octagon", + "tag", + "round-tag", + "star", + "diamond", + "round-diamond", + "vee", + "rhomboid", + "right-rhomboid", + "polygon", + ], + }, + overlayShape: { enums: ["roundrectangle", "round-rectangle", "ellipse"] }, + cornerRadius: { + number: !0, + min: 0, + units: "px|em", + implicitUnits: "px", + enums: ["auto"], + }, + compoundIncludeLabels: { enums: ["include", "exclude"] }, + arrowShape: { + enums: [ + "tee", + "triangle", + "triangle-tee", + "circle-triangle", + "triangle-cross", + "triangle-backcurve", + "vee", + "square", + "circle", + "diamond", + "chevron", + "none", + ], + }, + arrowFill: { enums: ["filled", "hollow"] }, + arrowWidth: { + number: !0, + units: "%|px|em", + implicitUnits: "px", + enums: ["match-line"], + }, + display: { enums: ["element", "none"] }, + visibility: { enums: ["hidden", "visible"] }, + zCompoundDepth: { enums: ["bottom", "orphan", "auto", "top"] }, + zIndexCompare: { enums: ["auto", "manual"] }, + valign: { enums: ["top", "center", "bottom"] }, + halign: { enums: ["left", "center", "right"] }, + justification: { enums: ["left", "center", "right", "auto"] }, + text: { string: !0 }, + data: { mapping: !0, regex: t("data") }, + layoutData: { mapping: !0, regex: t("layoutData") }, + scratch: { mapping: !0, regex: t("scratch") }, + mapData: { mapping: !0, regex: n("mapData") }, + mapLayoutData: { mapping: !0, regex: n("mapLayoutData") }, + mapScratch: { mapping: !0, regex: n("mapScratch") }, + fn: { mapping: !0, fn: !0 }, + url: { regexes: r, singleRegexMatchValue: !0 }, + urls: { regexes: r, singleRegexMatchValue: !0, multiple: !0 }, + propList: { propList: !0 }, + angle: { number: !0, units: "deg|rad", implicitUnits: "rad" }, + textRotation: { + number: !0, + units: "deg|rad", + implicitUnits: "rad", + enums: ["none", "autorotate"], + }, + polygonPointList: { + number: !0, + multiple: !0, + evenMultiple: !0, + min: -1, + max: 1, + unitless: !0, + }, + edgeDistances: { enums: ["intersection", "node-position", "endpoints"] }, + edgeEndpoint: { + number: !0, + multiple: !0, + units: "%|px|em|deg|rad", + implicitUnits: "px", + enums: [ + "inside-to-node", + "outside-to-node", + "outside-to-node-or-label", + "outside-to-line", + "outside-to-line-or-label", + ], + singleEnum: !0, + validate: function (e, t) { + switch (e.length) { + case 2: + return ( + "deg" !== t[0] && + "rad" !== t[0] && + "deg" !== t[1] && + "rad" !== t[1] + ); + case 1: + return v(e[0]) || "deg" === t[0] || "rad" === t[0]; + default: + return !1; + } + }, + }, + easing: { + regexes: [ + "^(spring)\\s*\\(\\s*(" + e + ")\\s*,\\s*(" + e + ")\\s*\\)$", + "^(cubic-bezier)\\s*\\(\\s*(" + + e + + ")\\s*,\\s*(" + + e + + ")\\s*,\\s*(" + + e + + ")\\s*,\\s*(" + + e + + ")\\s*\\)$", + ], + enums: [ + "linear", + "ease", + "ease-in", + "ease-out", + "ease-in-out", + "ease-in-sine", + "ease-out-sine", + "ease-in-out-sine", + "ease-in-quad", + "ease-out-quad", + "ease-in-out-quad", + "ease-in-cubic", + "ease-out-cubic", + "ease-in-out-cubic", + "ease-in-quart", + "ease-out-quart", + "ease-in-out-quart", + "ease-in-quint", + "ease-out-quint", + "ease-in-out-quint", + "ease-in-expo", + "ease-out-expo", + "ease-in-out-expo", + "ease-in-circ", + "ease-out-circ", + "ease-in-out-circ", + ], + }, + gradientDirection: { + enums: [ + "to-bottom", + "to-top", + "to-left", + "to-right", + "to-bottom-right", + "to-bottom-left", + "to-top-right", + "to-top-left", + "to-right-bottom", + "to-left-bottom", + "to-right-top", + "to-left-top", + ], + }, + boundsExpansion: { + number: !0, + multiple: !0, + min: 0, + validate: function (e) { + var t = e.length; + return 1 === t || 2 === t || 4 === t; + }, + }, + }; + var i = { + zeroNonZero: function (e, t) { + return ( + ((null == e || null == t) && e !== t) || + (0 == e && 0 != t) || + (0 != e && 0 == t) + ); + }, + any: function (e, t) { + return e != t; + }, + emptyNonEmpty: function (e, t) { + var n = D(e), + r = D(t); + return (n && !r) || (!n && r); + }, + }, + a = Ms.types, + o = [ + { + name: "label", + type: a.text, + triggersBounds: i.any, + triggersZOrder: i.emptyNonEmpty, + }, + { name: "text-rotation", type: a.textRotation, triggersBounds: i.any }, + { + name: "text-margin-x", + type: a.bidirectionalSize, + triggersBounds: i.any, + }, + { + name: "text-margin-y", + type: a.bidirectionalSize, + triggersBounds: i.any, + }, + ], + s = [ + { name: "source-label", type: a.text, triggersBounds: i.any }, + { + name: "source-text-rotation", + type: a.textRotation, + triggersBounds: i.any, + }, + { + name: "source-text-margin-x", + type: a.bidirectionalSize, + triggersBounds: i.any, + }, + { + name: "source-text-margin-y", + type: a.bidirectionalSize, + triggersBounds: i.any, + }, + { name: "source-text-offset", type: a.size, triggersBounds: i.any }, + ], + l = [ + { name: "target-label", type: a.text, triggersBounds: i.any }, + { + name: "target-text-rotation", + type: a.textRotation, + triggersBounds: i.any, + }, + { + name: "target-text-margin-x", + type: a.bidirectionalSize, + triggersBounds: i.any, + }, + { + name: "target-text-margin-y", + type: a.bidirectionalSize, + triggersBounds: i.any, + }, + { name: "target-text-offset", type: a.size, triggersBounds: i.any }, + ], + u = [ + { name: "font-family", type: a.fontFamily, triggersBounds: i.any }, + { name: "font-style", type: a.fontStyle, triggersBounds: i.any }, + { name: "font-weight", type: a.fontWeight, triggersBounds: i.any }, + { name: "font-size", type: a.size, triggersBounds: i.any }, + { + name: "text-transform", + type: a.textTransform, + triggersBounds: i.any, + }, + { name: "text-wrap", type: a.textWrap, triggersBounds: i.any }, + { + name: "text-overflow-wrap", + type: a.textOverflowWrap, + triggersBounds: i.any, + }, + { name: "text-max-width", type: a.size, triggersBounds: i.any }, + { name: "text-outline-width", type: a.size, triggersBounds: i.any }, + { name: "line-height", type: a.positiveNumber, triggersBounds: i.any }, + ], + c = [ + { name: "text-valign", type: a.valign, triggersBounds: i.any }, + { name: "text-halign", type: a.halign, triggersBounds: i.any }, + { name: "color", type: a.color }, + { name: "text-outline-color", type: a.color }, + { name: "text-outline-opacity", type: a.zeroOneNumber }, + { name: "text-background-color", type: a.color }, + { name: "text-background-opacity", type: a.zeroOneNumber }, + { + name: "text-background-padding", + type: a.size, + triggersBounds: i.any, + }, + { name: "text-border-opacity", type: a.zeroOneNumber }, + { name: "text-border-color", type: a.color }, + { name: "text-border-width", type: a.size, triggersBounds: i.any }, + { + name: "text-border-style", + type: a.borderStyle, + triggersBounds: i.any, + }, + { + name: "text-background-shape", + type: a.textBackgroundShape, + triggersBounds: i.any, + }, + { name: "text-justification", type: a.justification }, + ], + d = [ + { name: "events", type: a.bool, triggersZOrder: i.any }, + { name: "text-events", type: a.bool, triggersZOrder: i.any }, + ], + h = [ + { + name: "display", + type: a.display, + triggersZOrder: i.any, + triggersBounds: i.any, + triggersBoundsOfConnectedEdges: !0, + }, + { name: "visibility", type: a.visibility, triggersZOrder: i.any }, + { + name: "opacity", + type: a.zeroOneNumber, + triggersZOrder: i.zeroNonZero, + }, + { name: "text-opacity", type: a.zeroOneNumber }, + { name: "min-zoomed-font-size", type: a.size }, + { + name: "z-compound-depth", + type: a.zCompoundDepth, + triggersZOrder: i.any, + }, + { + name: "z-index-compare", + type: a.zIndexCompare, + triggersZOrder: i.any, + }, + { name: "z-index", type: a.number, triggersZOrder: i.any }, + ], + p = [ + { name: "overlay-padding", type: a.size, triggersBounds: i.any }, + { name: "overlay-color", type: a.color }, + { + name: "overlay-opacity", + type: a.zeroOneNumber, + triggersBounds: i.zeroNonZero, + }, + { name: "overlay-shape", type: a.overlayShape, triggersBounds: i.any }, + { name: "overlay-corner-radius", type: a.cornerRadius }, + ], + f = [ + { name: "underlay-padding", type: a.size, triggersBounds: i.any }, + { name: "underlay-color", type: a.color }, + { + name: "underlay-opacity", + type: a.zeroOneNumber, + triggersBounds: i.zeroNonZero, + }, + { name: "underlay-shape", type: a.overlayShape, triggersBounds: i.any }, + { name: "underlay-corner-radius", type: a.cornerRadius }, + ], + g = [ + { name: "transition-property", type: a.propList }, + { name: "transition-duration", type: a.time }, + { name: "transition-delay", type: a.time }, + { name: "transition-timing-function", type: a.easing }, + ], + y = function (e, t) { + return "label" === t.value ? -e.poolIndex() : t.pfValue; + }, + m = [ + { + name: "height", + type: a.nodeSize, + triggersBounds: i.any, + hashOverride: y, + }, + { + name: "width", + type: a.nodeSize, + triggersBounds: i.any, + hashOverride: y, + }, + { name: "shape", type: a.nodeShape, triggersBounds: i.any }, + { + name: "shape-polygon-points", + type: a.polygonPointList, + triggersBounds: i.any, + }, + { name: "corner-radius", type: a.cornerRadius }, + { name: "background-color", type: a.color }, + { name: "background-fill", type: a.fill }, + { name: "background-opacity", type: a.zeroOneNumber }, + { name: "background-blacken", type: a.nOneOneNumber }, + { name: "background-gradient-stop-colors", type: a.colors }, + { name: "background-gradient-stop-positions", type: a.percentages }, + { name: "background-gradient-direction", type: a.gradientDirection }, + { name: "padding", type: a.sizeMaybePercent, triggersBounds: i.any }, + { + name: "padding-relative-to", + type: a.paddingRelativeTo, + triggersBounds: i.any, + }, + { + name: "bounds-expansion", + type: a.boundsExpansion, + triggersBounds: i.any, + }, + ], + b = [ + { name: "border-color", type: a.color }, + { name: "border-opacity", type: a.zeroOneNumber }, + { name: "border-width", type: a.size, triggersBounds: i.any }, + { name: "border-style", type: a.borderStyle }, + { name: "border-cap", type: a.lineCap }, + { name: "border-join", type: a.lineJoin }, + { name: "border-dash-pattern", type: a.numbers }, + { name: "border-dash-offset", type: a.number }, + { name: "border-position", type: a.linePosition }, + ], + x = [ + { name: "outline-color", type: a.color }, + { name: "outline-opacity", type: a.zeroOneNumber }, + { name: "outline-width", type: a.size, triggersBounds: i.any }, + { name: "outline-style", type: a.borderStyle }, + { name: "outline-offset", type: a.size, triggersBounds: i.any }, + ], + w = [ + { name: "background-image", type: a.urls }, + { name: "background-image-crossorigin", type: a.bgCrossOrigin }, + { name: "background-image-opacity", type: a.zeroOneNumbers }, + { name: "background-image-containment", type: a.bgContainment }, + { name: "background-image-smoothing", type: a.bools }, + { name: "background-position-x", type: a.bgPos }, + { name: "background-position-y", type: a.bgPos }, + { name: "background-width-relative-to", type: a.bgRelativeTo }, + { name: "background-height-relative-to", type: a.bgRelativeTo }, + { name: "background-repeat", type: a.bgRepeat }, + { name: "background-fit", type: a.bgFit }, + { name: "background-clip", type: a.bgClip }, + { name: "background-width", type: a.bgWH }, + { name: "background-height", type: a.bgWH }, + { name: "background-offset-x", type: a.bgPos }, + { name: "background-offset-y", type: a.bgPos }, + ], + E = [ + { name: "position", type: a.position, triggersBounds: i.any }, + { + name: "compound-sizing-wrt-labels", + type: a.compoundIncludeLabels, + triggersBounds: i.any, + }, + { name: "min-width", type: a.size, triggersBounds: i.any }, + { + name: "min-width-bias-left", + type: a.sizeMaybePercent, + triggersBounds: i.any, + }, + { + name: "min-width-bias-right", + type: a.sizeMaybePercent, + triggersBounds: i.any, + }, + { name: "min-height", type: a.size, triggersBounds: i.any }, + { + name: "min-height-bias-top", + type: a.sizeMaybePercent, + triggersBounds: i.any, + }, + { + name: "min-height-bias-bottom", + type: a.sizeMaybePercent, + triggersBounds: i.any, + }, + ], + k = [ + { name: "line-style", type: a.lineStyle }, + { name: "line-color", type: a.color }, + { name: "line-fill", type: a.fill }, + { name: "line-cap", type: a.lineCap }, + { name: "line-opacity", type: a.zeroOneNumber }, + { name: "line-dash-pattern", type: a.numbers }, + { name: "line-dash-offset", type: a.number }, + { name: "line-outline-width", type: a.size }, + { name: "line-outline-color", type: a.color }, + { name: "line-gradient-stop-colors", type: a.colors }, + { name: "line-gradient-stop-positions", type: a.percentages }, + { + name: "curve-style", + type: a.curveStyle, + triggersBounds: i.any, + triggersBoundsOfParallelBeziers: !0, + }, + { + name: "haystack-radius", + type: a.zeroOneNumber, + triggersBounds: i.any, + }, + { + name: "source-endpoint", + type: a.edgeEndpoint, + triggersBounds: i.any, + }, + { + name: "target-endpoint", + type: a.edgeEndpoint, + triggersBounds: i.any, + }, + { + name: "control-point-step-size", + type: a.size, + triggersBounds: i.any, + }, + { + name: "control-point-distances", + type: a.bidirectionalSizes, + triggersBounds: i.any, + }, + { + name: "control-point-weights", + type: a.numbers, + triggersBounds: i.any, + }, + { + name: "segment-distances", + type: a.bidirectionalSizes, + triggersBounds: i.any, + }, + { name: "segment-weights", type: a.numbers, triggersBounds: i.any }, + { name: "segment-radii", type: a.numbers, triggersBounds: i.any }, + { name: "radius-type", type: a.radiusType, triggersBounds: i.any }, + { + name: "taxi-turn", + type: a.bidirectionalSizeMaybePercent, + triggersBounds: i.any, + }, + { name: "taxi-turn-min-distance", type: a.size, triggersBounds: i.any }, + { + name: "taxi-direction", + type: a.axisDirection, + triggersBounds: i.any, + }, + { name: "taxi-radius", type: a.number, triggersBounds: i.any }, + { + name: "edge-distances", + type: a.edgeDistances, + triggersBounds: i.any, + }, + { name: "arrow-scale", type: a.positiveNumber, triggersBounds: i.any }, + { name: "loop-direction", type: a.angle, triggersBounds: i.any }, + { name: "loop-sweep", type: a.angle, triggersBounds: i.any }, + { + name: "source-distance-from-node", + type: a.size, + triggersBounds: i.any, + }, + { + name: "target-distance-from-node", + type: a.size, + triggersBounds: i.any, + }, + ], + C = [ + { name: "ghost", type: a.bool, triggersBounds: i.any }, + { + name: "ghost-offset-x", + type: a.bidirectionalSize, + triggersBounds: i.any, + }, + { + name: "ghost-offset-y", + type: a.bidirectionalSize, + triggersBounds: i.any, + }, + { name: "ghost-opacity", type: a.zeroOneNumber }, + ], + S = [ + { name: "selection-box-color", type: a.color }, + { name: "selection-box-opacity", type: a.zeroOneNumber }, + { name: "selection-box-border-color", type: a.color }, + { name: "selection-box-border-width", type: a.size }, + { name: "active-bg-color", type: a.color }, + { name: "active-bg-opacity", type: a.zeroOneNumber }, + { name: "active-bg-size", type: a.size }, + { name: "outside-texture-bg-color", type: a.color }, + { name: "outside-texture-bg-opacity", type: a.zeroOneNumber }, + ], + P = []; + ((Ms.pieBackgroundN = 16), + P.push({ name: "pie-size", type: a.sizeMaybePercent })); + for (var T = 1; T <= Ms.pieBackgroundN; T++) + (P.push({ name: "pie-" + T + "-background-color", type: a.color }), + P.push({ name: "pie-" + T + "-background-size", type: a.percent }), + P.push({ + name: "pie-" + T + "-background-opacity", + type: a.zeroOneNumber, + })); + var _ = [], + M = (Ms.arrowPrefixes = ["source", "mid-source", "target", "mid-target"]); + [ + { name: "arrow-shape", type: a.arrowShape, triggersBounds: i.any }, + { name: "arrow-color", type: a.color }, + { name: "arrow-fill", type: a.arrowFill }, + { name: "arrow-width", type: a.arrowWidth }, + ].forEach(function (e) { + M.forEach(function (t) { + var n = t + "-" + e.name, + r = e.type, + i = e.triggersBounds; + _.push({ name: n, type: r, triggersBounds: i }); + }); + }, {}); + var B = (Ms.properties = [].concat( + d, + g, + h, + p, + f, + C, + c, + u, + o, + s, + l, + m, + b, + x, + w, + P, + E, + k, + _, + S, + )), + N = (Ms.propertyGroups = { + behavior: d, + transition: g, + visibility: h, + overlay: p, + underlay: f, + ghost: C, + commonLabel: c, + labelDimensions: u, + mainLabel: o, + sourceLabel: s, + targetLabel: l, + nodeBody: m, + nodeBorder: b, + nodeOutline: x, + backgroundImage: w, + pie: P, + compound: E, + edgeLine: k, + edgeArrow: _, + core: S, + }), + z = (Ms.propertyGroupNames = {}); + (Ms.propertyGroupKeys = Object.keys(N)).forEach(function (e) { + ((z[e] = N[e].map(function (e) { + return e.name; + })), + N[e].forEach(function (t) { + return (t.groupKey = e); + })); + }); + var A = (Ms.aliases = [ + { name: "content", pointsTo: "label" }, + { name: "control-point-distance", pointsTo: "control-point-distances" }, + { name: "control-point-weight", pointsTo: "control-point-weights" }, + { name: "segment-distance", pointsTo: "segment-distances" }, + { name: "segment-weight", pointsTo: "segment-weights" }, + { name: "segment-radius", pointsTo: "segment-radii" }, + { name: "edge-text-rotation", pointsTo: "text-rotation" }, + { name: "padding-left", pointsTo: "padding" }, + { name: "padding-right", pointsTo: "padding" }, + { name: "padding-top", pointsTo: "padding" }, + { name: "padding-bottom", pointsTo: "padding" }, + ]); + Ms.propertyNames = B.map(function (e) { + return e.name; + }); + for (var L = 0; L < B.length; L++) { + var O = B[L]; + B[O.name] = O; + } + for (var R = 0; R < A.length; R++) { + var V = A[R], + F = B[V.pointsTo], + j = { name: V.name, alias: !0, pointsTo: F }; + (B.push(j), (B[V.name] = j)); + } + })(), + (Ms.getDefaultProperty = function (e) { + return this.getDefaultProperties()[e]; + }), + (Ms.getDefaultProperties = function () { + var e = this._private; + if (null != e.defaultProperties) return e.defaultProperties; + for ( + var t = L( + { + "selection-box-color": "#ddd", + "selection-box-opacity": 0.65, + "selection-box-border-color": "#aaa", + "selection-box-border-width": 1, + "active-bg-color": "black", + "active-bg-opacity": 0.15, + "active-bg-size": 30, + "outside-texture-bg-color": "#000", + "outside-texture-bg-opacity": 0.125, + events: "yes", + "text-events": "no", + "text-valign": "top", + "text-halign": "center", + "text-justification": "auto", + "line-height": 1, + color: "#000", + "text-outline-color": "#000", + "text-outline-width": 0, + "text-outline-opacity": 1, + "text-opacity": 1, + "text-decoration": "none", + "text-transform": "none", + "text-wrap": "none", + "text-overflow-wrap": "whitespace", + "text-max-width": 9999, + "text-background-color": "#000", + "text-background-opacity": 0, + "text-background-shape": "rectangle", + "text-background-padding": 0, + "text-border-opacity": 0, + "text-border-width": 0, + "text-border-style": "solid", + "text-border-color": "#000", + "font-family": "Helvetica Neue, Helvetica, sans-serif", + "font-style": "normal", + "font-weight": "normal", + "font-size": 16, + "min-zoomed-font-size": 0, + "text-rotation": "none", + "source-text-rotation": "none", + "target-text-rotation": "none", + visibility: "visible", + display: "element", + opacity: 1, + "z-compound-depth": "auto", + "z-index-compare": "auto", + "z-index": 0, + label: "", + "text-margin-x": 0, + "text-margin-y": 0, + "source-label": "", + "source-text-offset": 0, + "source-text-margin-x": 0, + "source-text-margin-y": 0, + "target-label": "", + "target-text-offset": 0, + "target-text-margin-x": 0, + "target-text-margin-y": 0, + "overlay-opacity": 0, + "overlay-color": "#000", + "overlay-padding": 10, + "overlay-shape": "round-rectangle", + "overlay-corner-radius": "auto", + "underlay-opacity": 0, + "underlay-color": "#000", + "underlay-padding": 10, + "underlay-shape": "round-rectangle", + "underlay-corner-radius": "auto", + "transition-property": "none", + "transition-duration": 0, + "transition-delay": 0, + "transition-timing-function": "linear", + "background-blacken": 0, + "background-color": "#999", + "background-fill": "solid", + "background-opacity": 1, + "background-image": "none", + "background-image-crossorigin": "anonymous", + "background-image-opacity": 1, + "background-image-containment": "inside", + "background-image-smoothing": "yes", + "background-position-x": "50%", + "background-position-y": "50%", + "background-offset-x": 0, + "background-offset-y": 0, + "background-width-relative-to": "include-padding", + "background-height-relative-to": "include-padding", + "background-repeat": "no-repeat", + "background-fit": "none", + "background-clip": "node", + "background-width": "auto", + "background-height": "auto", + "border-color": "#000", + "border-opacity": 1, + "border-width": 0, + "border-style": "solid", + "border-dash-pattern": [4, 2], + "border-dash-offset": 0, + "border-cap": "butt", + "border-join": "miter", + "border-position": "center", + "outline-color": "#999", + "outline-opacity": 1, + "outline-width": 0, + "outline-offset": 0, + "outline-style": "solid", + height: 30, + width: 30, + shape: "ellipse", + "shape-polygon-points": "-1, -1, 1, -1, 1, 1, -1, 1", + "corner-radius": "auto", + "bounds-expansion": 0, + "background-gradient-direction": "to-bottom", + "background-gradient-stop-colors": "#999", + "background-gradient-stop-positions": "0%", + ghost: "no", + "ghost-offset-y": 0, + "ghost-offset-x": 0, + "ghost-opacity": 0, + padding: 0, + "padding-relative-to": "width", + position: "origin", + "compound-sizing-wrt-labels": "include", + "min-width": 0, + "min-width-bias-left": 0, + "min-width-bias-right": 0, + "min-height": 0, + "min-height-bias-top": 0, + "min-height-bias-bottom": 0, + }, + { "pie-size": "100%" }, + [ + { name: "pie-{{i}}-background-color", value: "black" }, + { name: "pie-{{i}}-background-size", value: "0%" }, + { name: "pie-{{i}}-background-opacity", value: 1 }, + ].reduce(function (e, t) { + for (var n = 1; n <= Ms.pieBackgroundN; n++) { + var r = t.name.replace("{{i}}", n), + i = t.value; + e[r] = i; + } + return e; + }, {}), + { + "line-style": "solid", + "line-color": "#999", + "line-fill": "solid", + "line-cap": "butt", + "line-opacity": 1, + "line-outline-width": 0, + "line-outline-color": "#000", + "line-gradient-stop-colors": "#999", + "line-gradient-stop-positions": "0%", + "control-point-step-size": 40, + "control-point-weights": 0.5, + "segment-weights": 0.5, + "segment-distances": 20, + "segment-radii": 15, + "radius-type": "arc-radius", + "taxi-turn": "50%", + "taxi-radius": 15, + "taxi-turn-min-distance": 10, + "taxi-direction": "auto", + "edge-distances": "intersection", + "curve-style": "haystack", + "haystack-radius": 0, + "arrow-scale": 1, + "loop-direction": "-45deg", + "loop-sweep": "-90deg", + "source-distance-from-node": 0, + "target-distance-from-node": 0, + "source-endpoint": "outside-to-node", + "target-endpoint": "outside-to-node", + "line-dash-pattern": [6, 3], + "line-dash-offset": 0, + }, + [ + { name: "arrow-shape", value: "none" }, + { name: "arrow-color", value: "#999" }, + { name: "arrow-fill", value: "filled" }, + { name: "arrow-width", value: 1 }, + ].reduce(function (e, t) { + return ( + Ms.arrowPrefixes.forEach(function (n) { + var r = n + "-" + t.name, + i = t.value; + e[r] = i; + }), + e + ); + }, {}), + ), + n = {}, + r = 0; + r < this.properties.length; + r++ + ) { + var i = this.properties[r]; + if (!i.pointsTo) { + var a = i.name, + o = t[a], + s = this.parse(a, o); + n[a] = s; + } + } + return ((e.defaultProperties = n), e.defaultProperties); + }), + (Ms.addDefaultStylesheet = function () { + (this.selector(":parent") + .css({ + shape: "rectangle", + padding: 10, + "background-color": "#eee", + "border-color": "#ccc", + "border-width": 1, + }) + .selector("edge") + .css({ width: 3 }) + .selector(":loop") + .css({ "curve-style": "bezier" }) + .selector("edge:compound") + .css({ + "curve-style": "bezier", + "source-endpoint": "outside-to-line", + "target-endpoint": "outside-to-line", + }) + .selector(":selected") + .css({ + "background-color": "#0169D9", + "line-color": "#0169D9", + "source-arrow-color": "#0169D9", + "target-arrow-color": "#0169D9", + "mid-source-arrow-color": "#0169D9", + "mid-target-arrow-color": "#0169D9", + }) + .selector(":parent:selected") + .css({ "background-color": "#CCE1F9", "border-color": "#aec8e5" }) + .selector(":active") + .css({ + "overlay-color": "black", + "overlay-padding": 10, + "overlay-opacity": 0.25, + }), + (this.defaultLength = this.length)); + })); + var Bs = { + parse: function (e, t, n, r) { + if (y(t)) return this.parseImplWarn(e, t, n, r); + var i, + a = _e( + e, + "" + t, + n ? "t" : "f", + "mapping" === r || !0 === r || !1 === r || null == r ? "dontcare" : r, + ), + o = (this.propCache = this.propCache || []); + return ( + (i = o[a]) || (i = o[a] = this.parseImplWarn(e, t, n, r)), + (n || "mapping" === r) && (i = qe(i)) && (i.value = qe(i.value)), + i + ); + }, + parseImplWarn: function (e, t, n, r) { + var i = this.parseImpl(e, t, n, r); + return ( + i || + null == t || + je("The style property `".concat(e, ": ").concat(t, "` is invalid")), + !i || + ("width" !== i.name && "height" !== i.name) || + "label" !== t || + je("The style value of `label` is deprecated for `" + i.name + "`"), + i + ); + }, + }; + Bs.parseImpl = function (e, t, n, r) { + e = M(e); + var i = this.properties[e], + a = t, + o = this.types; + if (!i) return null; + if (void 0 === t) return null; + i.alias && ((i = i.pointsTo), (e = i.name)); + var s = v(t); + s && (t = t.trim()); + var l, + u, + c = i.type; + if (!c) return null; + if (n && ("" === t || null === t)) + return { name: e, value: t, bypass: !0, deleteBypass: !0 }; + if (y(t)) + return { name: e, value: t, strValue: "fn", mapped: o.fn, bypass: n }; + if (!s || r || t.length < 7 || "a" !== t[1]); + else { + if ( + t.length >= 7 && + "d" === t[0] && + (l = new RegExp(o.data.regex).exec(t)) + ) { + if (n) return !1; + var d = o.data; + return { + name: e, + value: l, + strValue: "" + t, + mapped: d, + field: l[1], + bypass: n, + }; + } + if ( + t.length >= 10 && + "m" === t[0] && + (u = new RegExp(o.mapData.regex).exec(t)) + ) { + if (n) return !1; + if (c.multiple) return !1; + var h = o.mapData; + if (!c.color && !c.number) return !1; + var p = this.parse(e, u[4]); + if (!p || p.mapped) return !1; + var f = this.parse(e, u[5]); + if (!f || f.mapped) return !1; + if (p.pfValue === f.pfValue || p.strValue === f.strValue) + return ( + je( + "`" + + e + + ": " + + t + + "` is not a valid mapper because the output range is zero; converting to `" + + e + + ": " + + p.strValue + + "`", + ), + this.parse(e, p.strValue) + ); + if (c.color) { + var g = p.value, + b = f.value; + if ( + !( + g[0] !== b[0] || + g[1] !== b[1] || + g[2] !== b[2] || + (g[3] !== b[3] && + ((null != g[3] && 1 !== g[3]) || (null != b[3] && 1 !== b[3]))) + ) + ) + return !1; + } + return { + name: e, + value: u, + strValue: "" + t, + mapped: h, + field: u[1], + fieldMin: parseFloat(u[2]), + fieldMax: parseFloat(u[3]), + valueMin: p.value, + valueMax: f.value, + bypass: n, + }; + } + } + if (c.multiple && "multiple" !== r) { + var w; + if ( + ((w = s ? t.split(/\s+/) : m(t) ? t : [t]), + c.evenMultiple && w.length % 2 != 0) + ) + return null; + for ( + var E = [], k = [], C = [], S = "", P = !1, D = 0; + D < w.length; + D++ + ) { + var T = this.parse(e, w[D], n, "multiple"); + ((P = P || v(T.value)), + E.push(T.value), + C.push(null != T.pfValue ? T.pfValue : T.value), + k.push(T.units), + (S += (D > 0 ? " " : "") + T.strValue)); + } + return c.validate && !c.validate(E, k) + ? null + : c.singleEnum && P + ? 1 === E.length && v(E[0]) + ? { name: e, value: E[0], strValue: E[0], bypass: n } + : null + : { name: e, value: E, pfValue: C, strValue: S, bypass: n, units: k }; + } + var _, + B, + N = function () { + for (var r = 0; r < c.enums.length; r++) { + if (c.enums[r] === t) + return { name: e, value: t, strValue: "" + t, bypass: n }; + } + return null; + }; + if (c.number) { + var z, + A = "px"; + if ( + (c.units && (z = c.units), + c.implicitUnits && (A = c.implicitUnits), + !c.unitless) + ) + if (s) { + var L = "px|em" + (c.allowPercent ? "|\\%" : ""); + z && (L = z); + var R = t.match("^(" + I + ")(" + L + ")?$"); + R && ((t = R[1]), (z = R[2] || A)); + } else (z && !c.implicitUnits) || (z = A); + if (((t = parseFloat(t)), isNaN(t) && void 0 === c.enums)) return null; + if (isNaN(t) && void 0 !== c.enums) return ((t = a), N()); + if (c.integer && (!x((B = t)) || Math.floor(B) !== B)) return null; + if ( + (void 0 !== c.min && (t < c.min || (c.strictMin && t === c.min))) || + (void 0 !== c.max && (t > c.max || (c.strictMax && t === c.max))) + ) + return null; + var V = { + name: e, + value: t, + strValue: "" + t + (z || ""), + units: z, + bypass: n, + }; + return ( + c.unitless || ("px" !== z && "em" !== z) + ? (V.pfValue = t) + : (V.pfValue = "px" !== z && z ? this.getEmSizeInPixels() * t : t), + ("ms" !== z && "s" !== z) || (V.pfValue = "ms" === z ? t : 1e3 * t), + ("deg" !== z && "rad" !== z) || + (V.pfValue = "rad" === z ? t : ((_ = t), (Math.PI * _) / 180)), + "%" === z && (V.pfValue = t / 100), + V + ); + } + if (c.propList) { + var F = [], + j = "" + t; + if ("none" === j); + else { + for (var q = j.split(/\s*,\s*|\s+/), Y = 0; Y < q.length; Y++) { + var X = q[Y].trim(); + this.properties[X] + ? F.push(X) + : je("`" + X + "` is not a valid property name"); + } + if (0 === F.length) return null; + } + return { + name: e, + value: F, + strValue: 0 === F.length ? "none" : F.join(" "), + bypass: n, + }; + } + if (c.color) { + var W = O(t); + return W + ? { + name: e, + value: W, + pfValue: W, + strValue: "rgb(" + W[0] + "," + W[1] + "," + W[2] + ")", + bypass: n, + } + : null; + } + if (c.regex || c.regexes) { + if (c.enums) { + var H = N(); + if (H) return H; + } + for ( + var K = c.regexes ? c.regexes : [c.regex], G = 0; + G < K.length; + G++ + ) { + var U = new RegExp(K[G]).exec(t); + if (U) + return { + name: e, + value: c.singleRegexMatchValue ? U[1] : U, + strValue: "" + t, + bypass: n, + }; + } + return null; + } + return c.string + ? { name: e, value: "" + t, strValue: "" + t, bypass: n } + : c.enums + ? N() + : null; + }; + var Ns = function e(t) { + if (!(this instanceof e)) return new e(t); + S(t) + ? ((this._private = { cy: t, coreStyle: {} }), + (this.length = 0), + this.resetToDefault()) + : Ve("A style must have a core reference"); + }, + zs = Ns.prototype; + ((zs.instanceString = function () { + return "style"; + }), + (zs.clear = function () { + for ( + var e = this._private, t = e.cy.elements(), n = 0; + n < this.length; + n++ + ) + this[n] = void 0; + return ( + (this.length = 0), + (e.contextStyles = {}), + (e.propDiffs = {}), + this.cleanElements(t, !0), + t.forEach(function (e) { + var t = e[0]._private; + ((t.styleDirty = !0), (t.appliedInitStyle = !1)); + }), + this + ); + }), + (zs.resetToDefault = function () { + return (this.clear(), this.addDefaultStylesheet(), this); + }), + (zs.core = function (e) { + return this._private.coreStyle[e] || this.getDefaultProperty(e); + }), + (zs.selector = function (e) { + var t = "core" === e ? null : new ka(e), + n = this.length++; + return ( + (this[n] = { + selector: t, + properties: [], + mappedProperties: [], + index: n, + }), + this + ); + }), + (zs.css = function () { + var e = this, + t = arguments; + if (1 === t.length) + for (var n = t[0], r = 0; r < e.properties.length; r++) { + var i = e.properties[r], + a = n[i.name]; + (void 0 === a && (a = n[B(i.name)]), + void 0 !== a && this.cssRule(i.name, a)); + } + else 2 === t.length && this.cssRule(t[0], t[1]); + return this; + }), + (zs.style = zs.css), + (zs.cssRule = function (e, t) { + var n = this.parse(e, t); + if (n) { + var r = this.length - 1; + (this[r].properties.push(n), + (this[r].properties[n.name] = n), + n.name.match(/pie-(\d+)-background-size/) && + n.value && + (this._private.hasPie = !0), + n.mapped && this[r].mappedProperties.push(n), + !this[r].selector && (this._private.coreStyle[n.name] = n)); + } + return this; + }), + (zs.append = function (e) { + return ( + P(e) + ? e.appendToStyle(this) + : m(e) + ? this.appendFromJson(e) + : v(e) && this.appendFromString(e), + this + ); + }), + (Ns.fromJson = function (e, t) { + var n = new Ns(e); + return (n.fromJson(t), n); + }), + (Ns.fromString = function (e, t) { + return new Ns(e).fromString(t); + }), + [Cs, Ss, Ps, Ds, Ts, _s, Ms, Bs].forEach(function (e) { + L(zs, e); + }), + (Ns.types = zs.types), + (Ns.properties = zs.properties), + (Ns.propertyGroups = zs.propertyGroups), + (Ns.propertyGroupNames = zs.propertyGroupNames), + (Ns.propertyGroupKeys = zs.propertyGroupKeys)); + var Is = { + style: function (e) { + e && this.setStyle(e).update(); + return this._private.style; + }, + setStyle: function (e) { + var t = this._private; + return ( + P(e) + ? (t.style = e.generateStyle(this)) + : m(e) + ? (t.style = Ns.fromJson(this, e)) + : v(e) + ? (t.style = Ns.fromString(this, e)) + : (t.style = Ns(this)), + t.style + ); + }, + updateStyle: function () { + this.mutableElements().updateStyle(); + }, + }, + As = { + autolock: function (e) { + return void 0 === e + ? this._private.autolock + : ((this._private.autolock = !!e), this); + }, + autoungrabify: function (e) { + return void 0 === e + ? this._private.autoungrabify + : ((this._private.autoungrabify = !!e), this); + }, + autounselectify: function (e) { + return void 0 === e + ? this._private.autounselectify + : ((this._private.autounselectify = !!e), this); + }, + selectionType: function (e) { + var t = this._private; + return ( + null == t.selectionType && (t.selectionType = "single"), + void 0 === e + ? t.selectionType + : (("additive" !== e && "single" !== e) || (t.selectionType = e), + this) + ); + }, + panningEnabled: function (e) { + return void 0 === e + ? this._private.panningEnabled + : ((this._private.panningEnabled = !!e), this); + }, + userPanningEnabled: function (e) { + return void 0 === e + ? this._private.userPanningEnabled + : ((this._private.userPanningEnabled = !!e), this); + }, + zoomingEnabled: function (e) { + return void 0 === e + ? this._private.zoomingEnabled + : ((this._private.zoomingEnabled = !!e), this); + }, + userZoomingEnabled: function (e) { + return void 0 === e + ? this._private.userZoomingEnabled + : ((this._private.userZoomingEnabled = !!e), this); + }, + boxSelectionEnabled: function (e) { + return void 0 === e + ? this._private.boxSelectionEnabled + : ((this._private.boxSelectionEnabled = !!e), this); + }, + pan: function () { + var e, + t, + n, + r, + i, + a = arguments, + o = this._private.pan; + switch (a.length) { + case 0: + return o; + case 1: + if (v(a[0])) return o[(e = a[0])]; + if (b(a[0])) { + if (!this._private.panningEnabled) return this; + ((r = (n = a[0]).x), + (i = n.y), + x(r) && (o.x = r), + x(i) && (o.y = i), + this.emit("pan viewport")); + } + break; + case 2: + if (!this._private.panningEnabled) return this; + ((e = a[0]), + (t = a[1]), + ("x" !== e && "y" !== e) || !x(t) || (o[e] = t), + this.emit("pan viewport")); + } + return (this.notify("viewport"), this); + }, + panBy: function (e, t) { + var n, + r, + i, + a, + o, + s = arguments, + l = this._private.pan; + if (!this._private.panningEnabled) return this; + switch (s.length) { + case 1: + b(e) && + ((a = (i = s[0]).x), + (o = i.y), + x(a) && (l.x += a), + x(o) && (l.y += o), + this.emit("pan viewport")); + break; + case 2: + ((r = t), + ("x" !== (n = e) && "y" !== n) || !x(r) || (l[n] += r), + this.emit("pan viewport")); + } + return (this.notify("viewport"), this); + }, + fit: function (e, t) { + var n = this.getFitViewport(e, t); + if (n) { + var r = this._private; + ((r.zoom = n.zoom), + (r.pan = n.pan), + this.emit("pan zoom viewport"), + this.notify("viewport")); + } + return this; + }, + getFitViewport: function (e, t) { + if ( + (x(e) && void 0 === t && ((t = e), (e = void 0)), + this._private.panningEnabled && this._private.zoomingEnabled) + ) { + var n, r; + if (v(e)) { + var i = e; + e = this.$(i); + } else if (b((r = e)) && x(r.x1) && x(r.x2) && x(r.y1) && x(r.y2)) { + var a = e; + (((n = { x1: a.x1, y1: a.y1, x2: a.x2, y2: a.y2 }).w = n.x2 - n.x1), + (n.h = n.y2 - n.y1)); + } else E(e) || (e = this.mutableElements()); + if (!E(e) || !e.empty()) { + n = n || e.boundingBox(); + var o, + s = this.width(), + l = this.height(); + if ( + ((t = x(t) ? t : 0), + !isNaN(s) && + !isNaN(l) && + s > 0 && + l > 0 && + !isNaN(n.w) && + !isNaN(n.h) && + n.w > 0 && + n.h > 0) + ) + return { + zoom: (o = + (o = + (o = Math.min((s - 2 * t) / n.w, (l - 2 * t) / n.h)) > + this._private.maxZoom + ? this._private.maxZoom + : o) < this._private.minZoom + ? this._private.minZoom + : o), + pan: { + x: (s - o * (n.x1 + n.x2)) / 2, + y: (l - o * (n.y1 + n.y2)) / 2, + }, + }; + } + } + }, + zoomRange: function (e, t) { + var n = this._private; + if (null == t) { + var r = e; + ((e = r.min), (t = r.max)); + } + return ( + x(e) && x(t) && e <= t + ? ((n.minZoom = e), (n.maxZoom = t)) + : x(e) && void 0 === t && e <= n.maxZoom + ? (n.minZoom = e) + : x(t) && void 0 === e && t >= n.minZoom && (n.maxZoom = t), + this + ); + }, + minZoom: function (e) { + return void 0 === e + ? this._private.minZoom + : this.zoomRange({ min: e }); + }, + maxZoom: function (e) { + return void 0 === e + ? this._private.maxZoom + : this.zoomRange({ max: e }); + }, + getZoomedViewport: function (e) { + var t, + n, + r = this._private, + i = r.pan, + a = r.zoom, + o = !1; + if ( + (r.zoomingEnabled || (o = !0), + x(e) + ? (n = e) + : b(e) && + ((n = e.level), + null != e.position + ? (t = yt(e.position, a, i)) + : null != e.renderedPosition && (t = e.renderedPosition), + null == t || r.panningEnabled || (o = !0)), + (n = (n = n > r.maxZoom ? r.maxZoom : n) < r.minZoom ? r.minZoom : n), + o || !x(n) || n === a || (null != t && (!x(t.x) || !x(t.y)))) + ) + return null; + if (null != t) { + var s = i, + l = a, + u = n; + return { + zoomed: !0, + panned: !0, + zoom: u, + pan: { + x: (-u / l) * (t.x - s.x) + t.x, + y: (-u / l) * (t.y - s.y) + t.y, + }, + }; + } + return { zoomed: !0, panned: !1, zoom: n, pan: i }; + }, + zoom: function (e) { + if (void 0 === e) return this._private.zoom; + var t = this.getZoomedViewport(e), + n = this._private; + return null != t && t.zoomed + ? ((n.zoom = t.zoom), + t.panned && ((n.pan.x = t.pan.x), (n.pan.y = t.pan.y)), + this.emit("zoom" + (t.panned ? " pan" : "") + " viewport"), + this.notify("viewport"), + this) + : this; + }, + viewport: function (e) { + var t = this._private, + n = !0, + r = !0, + i = [], + a = !1, + o = !1; + if (!e) return this; + if ((x(e.zoom) || (n = !1), b(e.pan) || (r = !1), !n && !r)) + return this; + if (n) { + var s = e.zoom; + s < t.minZoom || s > t.maxZoom || !t.zoomingEnabled + ? (a = !0) + : ((t.zoom = s), i.push("zoom")); + } + if (r && (!a || !e.cancelOnFailedZoom) && t.panningEnabled) { + var l = e.pan; + (x(l.x) && ((t.pan.x = l.x), (o = !1)), + x(l.y) && ((t.pan.y = l.y), (o = !1)), + o || i.push("pan")); + } + return ( + i.length > 0 && + (i.push("viewport"), + this.emit(i.join(" ")), + this.notify("viewport")), + this + ); + }, + center: function (e) { + var t = this.getCenterPan(e); + return ( + t && + ((this._private.pan = t), + this.emit("pan viewport"), + this.notify("viewport")), + this + ); + }, + getCenterPan: function (e, t) { + if (this._private.panningEnabled) { + if (v(e)) { + var n = e; + e = this.mutableElements().filter(n); + } else E(e) || (e = this.mutableElements()); + if (0 !== e.length) { + var r = e.boundingBox(), + i = this.width(), + a = this.height(); + return { + x: + (i - + (t = void 0 === t ? this._private.zoom : t) * (r.x1 + r.x2)) / + 2, + y: (a - t * (r.y1 + r.y2)) / 2, + }; + } + } + }, + reset: function () { + return this._private.panningEnabled && this._private.zoomingEnabled + ? (this.viewport({ pan: { x: 0, y: 0 }, zoom: 1 }), this) + : this; + }, + invalidateSize: function () { + this._private.sizeCache = null; + }, + size: function () { + var e, + t, + n = this._private, + r = n.container, + i = this; + return (n.sizeCache = + n.sizeCache || + (r + ? ((e = i.window().getComputedStyle(r)), + (t = function (t) { + return parseFloat(e.getPropertyValue(t)); + }), + { + width: r.clientWidth - t("padding-left") - t("padding-right"), + height: r.clientHeight - t("padding-top") - t("padding-bottom"), + }) + : { width: 1, height: 1 })); + }, + width: function () { + return this.size().width; + }, + height: function () { + return this.size().height; + }, + extent: function () { + var e = this._private.pan, + t = this._private.zoom, + n = this.renderedExtent(), + r = { + x1: (n.x1 - e.x) / t, + x2: (n.x2 - e.x) / t, + y1: (n.y1 - e.y) / t, + y2: (n.y2 - e.y) / t, + }; + return ((r.w = r.x2 - r.x1), (r.h = r.y2 - r.y1), r); + }, + renderedExtent: function () { + var e = this.width(), + t = this.height(); + return { x1: 0, y1: 0, x2: e, y2: t, w: e, h: t }; + }, + multiClickDebounceTime: function (e) { + return e + ? ((this._private.multiClickDebounceTime = e), this) + : this._private.multiClickDebounceTime; + }, + }; + ((As.centre = As.center), + (As.autolockNodes = As.autolock), + (As.autoungrabifyNodes = As.autoungrabify)); + var Ls = { + data: Fi.data({ + field: "data", + bindingEvent: "data", + allowBinding: !0, + allowSetting: !0, + settingEvent: "data", + settingTriggersEvent: !0, + triggerFnName: "trigger", + allowGetting: !0, + updateStyle: !0, + }), + removeData: Fi.removeData({ + field: "data", + event: "data", + triggerFnName: "trigger", + triggerEvent: !0, + updateStyle: !0, + }), + scratch: Fi.data({ + field: "scratch", + bindingEvent: "scratch", + allowBinding: !0, + allowSetting: !0, + settingEvent: "scratch", + settingTriggersEvent: !0, + triggerFnName: "trigger", + allowGetting: !0, + updateStyle: !0, + }), + removeScratch: Fi.removeData({ + field: "scratch", + event: "scratch", + triggerFnName: "trigger", + triggerEvent: !0, + updateStyle: !0, + }), + }; + ((Ls.attr = Ls.data), (Ls.removeAttr = Ls.removeData)); + var Os = function (e) { + var t = this, + n = (e = L({}, e)).container; + n && !w(n) && w(n[0]) && (n = n[0]); + var r = n ? n._cyreg : null; + (r = r || {}) && r.cy && (r.cy.destroy(), (r = {})); + var i = (r.readies = r.readies || []); + (n && (n._cyreg = r), (r.cy = t)); + var a = void 0 !== u && void 0 !== n && !e.headless, + o = e; + ((o.layout = L({ name: a ? "grid" : "null" }, o.layout)), + (o.renderer = L({ name: a ? "canvas" : "null" }, o.renderer))); + var s = function (e, t, n) { + return void 0 !== t ? t : void 0 !== n ? n : e; + }, + l = (this._private = { + container: n, + ready: !1, + options: o, + elements: new ts(this), + listeners: [], + aniEles: new ts(this), + data: o.data || {}, + scratch: {}, + layout: null, + renderer: null, + destroyed: !1, + notificationsEnabled: !0, + minZoom: 1e-50, + maxZoom: 1e50, + zoomingEnabled: s(!0, o.zoomingEnabled), + userZoomingEnabled: s(!0, o.userZoomingEnabled), + panningEnabled: s(!0, o.panningEnabled), + userPanningEnabled: s(!0, o.userPanningEnabled), + boxSelectionEnabled: s(!0, o.boxSelectionEnabled), + autolock: s(!1, o.autolock, o.autolockNodes), + autoungrabify: s(!1, o.autoungrabify, o.autoungrabifyNodes), + autounselectify: s(!1, o.autounselectify), + styleEnabled: void 0 === o.styleEnabled ? a : o.styleEnabled, + zoom: x(o.zoom) ? o.zoom : 1, + pan: { + x: b(o.pan) && x(o.pan.x) ? o.pan.x : 0, + y: b(o.pan) && x(o.pan.y) ? o.pan.y : 0, + }, + animation: { current: [], queue: [] }, + hasCompoundNodes: !1, + multiClickDebounceTime: s(250, o.multiClickDebounceTime), + }); + (this.createEmitter(), + this.selectionType(o.selectionType), + this.zoomRange({ min: o.minZoom, max: o.maxZoom })); + l.styleEnabled && t.setStyle([]); + var c = L({}, o, o.renderer); + t.initRenderer(c); + !(function (e, t) { + if (e.some(T)) return vr.all(e).then(t); + t(e); + })([o.style, o.elements], function (e) { + var n = e[0], + a = e[1]; + (l.styleEnabled && t.style().append(n), + (function (e, n, r) { + t.notifications(!1); + var i = t.mutableElements(); + (i.length > 0 && i.remove(), + null != e && (b(e) || m(e)) && t.add(e), + t + .one("layoutready", function (e) { + (t.notifications(!0), + t.emit(e), + t.one("load", n), + t.emitAndNotify("load")); + }) + .one("layoutstop", function () { + (t.one("done", r), t.emit("done")); + })); + var a = L({}, t._private.options.layout); + ((a.eles = t.elements()), t.layout(a).run()); + })( + a, + function () { + (t.startAnimationLoop(), + (l.ready = !0), + y(o.ready) && t.on("ready", o.ready)); + for (var e = 0; e < i.length; e++) { + var n = i[e]; + t.on("ready", n); + } + (r && (r.readies = []), t.emit("ready")); + }, + o.done, + )); + }); + }, + Rs = Os.prototype; + (L(Rs, { + instanceString: function () { + return "core"; + }, + isReady: function () { + return this._private.ready; + }, + destroyed: function () { + return this._private.destroyed; + }, + ready: function (e) { + return ( + this.isReady() + ? this.emitter().emit("ready", [], e) + : this.on("ready", e), + this + ); + }, + destroy: function () { + var e = this; + if (!e.destroyed()) + return ( + e.stopAnimationLoop(), + e.destroyRenderer(), + this.emit("destroy"), + (e._private.destroyed = !0), + e + ); + }, + hasElementWithId: function (e) { + return this._private.elements.hasElementWithId(e); + }, + getElementById: function (e) { + return this._private.elements.getElementById(e); + }, + hasCompoundNodes: function () { + return this._private.hasCompoundNodes; + }, + headless: function () { + return this._private.renderer.isHeadless(); + }, + styleEnabled: function () { + return this._private.styleEnabled; + }, + addToPool: function (e) { + return (this._private.elements.merge(e), this); + }, + removeFromPool: function (e) { + return (this._private.elements.unmerge(e), this); + }, + container: function () { + return this._private.container || null; + }, + window: function () { + if (null == this._private.container) return u; + var e = this._private.container.ownerDocument; + return void 0 === e || null == e ? u : e.defaultView || u; + }, + mount: function (e) { + if (null != e) { + var t = this, + n = t._private, + r = n.options; + return ( + !w(e) && w(e[0]) && (e = e[0]), + t.stopAnimationLoop(), + t.destroyRenderer(), + (n.container = e), + (n.styleEnabled = !0), + t.invalidateSize(), + t.initRenderer( + L({}, r, r.renderer, { + name: "null" === r.renderer.name ? "canvas" : r.renderer.name, + }), + ), + t.startAnimationLoop(), + t.style(r.style), + t.emit("mount"), + t + ); + } + }, + unmount: function () { + var e = this; + return ( + e.stopAnimationLoop(), + e.destroyRenderer(), + e.initRenderer({ name: "null" }), + e.emit("unmount"), + e + ); + }, + options: function () { + return qe(this._private.options); + }, + json: function (e) { + var t = this, + n = t._private, + r = t.mutableElements(); + if (b(e)) { + if ((t.startBatch(), e.elements)) { + var i = {}, + a = function (e, n) { + for (var r = [], a = [], o = 0; o < e.length; o++) { + var s = e[o]; + if (s.data.id) { + var l = "" + s.data.id, + u = t.getElementById(l); + ((i[l] = !0), + 0 !== u.length + ? a.push({ ele: u, json: s }) + : n + ? ((s.group = n), r.push(s)) + : r.push(s)); + } else + je( + "cy.json() cannot handle elements without an ID attribute", + ); + } + t.add(r); + for (var c = 0; c < a.length; c++) { + var d = a[c], + h = d.ele, + p = d.json; + h.json(p); + } + }; + if (m(e.elements)) a(e.elements); + else + for (var o = ["nodes", "edges"], s = 0; s < o.length; s++) { + var l = o[s], + u = e.elements[l]; + m(u) && a(u, l); + } + var c = t.collection(); + (r + .filter(function (e) { + return !i[e.id()]; + }) + .forEach(function (e) { + e.isParent() ? c.merge(e) : e.remove(); + }), + c.forEach(function (e) { + return e.children().move({ parent: null }); + }), + c.forEach(function (e) { + return (function (e) { + return t.getElementById(e.id()); + })(e).remove(); + })); + } + (e.style && t.style(e.style), + null != e.zoom && e.zoom !== n.zoom && t.zoom(e.zoom), + e.pan && + ((e.pan.x === n.pan.x && e.pan.y === n.pan.y) || t.pan(e.pan)), + e.data && t.data(e.data)); + for ( + var d = [ + "minZoom", + "maxZoom", + "zoomingEnabled", + "userZoomingEnabled", + "panningEnabled", + "userPanningEnabled", + "boxSelectionEnabled", + "autolock", + "autoungrabify", + "autounselectify", + "multiClickDebounceTime", + ], + h = 0; + h < d.length; + h++ + ) { + var p = d[h]; + null != e[p] && t[p](e[p]); + } + return (t.endBatch(), this); + } + var f = {}; + (!!e + ? (f.elements = this.elements().map(function (e) { + return e.json(); + })) + : ((f.elements = {}), + r.forEach(function (e) { + var t = e.group(); + (f.elements[t] || (f.elements[t] = []), + f.elements[t].push(e.json())); + })), + this._private.styleEnabled && (f.style = t.style().json()), + (f.data = qe(t.data()))); + var g = n.options; + return ( + (f.zoomingEnabled = n.zoomingEnabled), + (f.userZoomingEnabled = n.userZoomingEnabled), + (f.zoom = n.zoom), + (f.minZoom = n.minZoom), + (f.maxZoom = n.maxZoom), + (f.panningEnabled = n.panningEnabled), + (f.userPanningEnabled = n.userPanningEnabled), + (f.pan = qe(n.pan)), + (f.boxSelectionEnabled = n.boxSelectionEnabled), + (f.renderer = qe(g.renderer)), + (f.hideEdgesOnViewport = g.hideEdgesOnViewport), + (f.textureOnViewport = g.textureOnViewport), + (f.wheelSensitivity = g.wheelSensitivity), + (f.motionBlur = g.motionBlur), + (f.multiClickDebounceTime = g.multiClickDebounceTime), + f + ); + }, + }), + (Rs.$id = Rs.getElementById), + [rs, fs, ys, ms, bs, xs, Es, ks, Is, As, Ls].forEach(function (e) { + L(Rs, e); + })); + var Vs = { + fit: !0, + directed: !1, + padding: 30, + circle: !1, + grid: !1, + spacingFactor: 1.75, + boundingBox: void 0, + avoidOverlap: !0, + nodeDimensionsIncludeLabels: !1, + roots: void 0, + depthSort: void 0, + animate: !1, + animationDuration: 500, + animationEasing: void 0, + animateFilter: function (e, t) { + return !0; + }, + ready: void 0, + stop: void 0, + transform: function (e, t) { + return t; + }, + }, + Fs = { maximal: !1, acyclic: !1 }, + js = function (e) { + return e.scratch("breadthfirst"); + }, + qs = function (e, t) { + return e.scratch("breadthfirst", t); + }; + function Ys(e) { + this.options = L({}, Vs, Fs, e); + } + Ys.prototype.run = function () { + var e, + t = this.options, + n = t, + r = t.cy, + i = n.eles, + a = i.nodes().filter(function (e) { + return !e.isParent(); + }), + o = i, + s = n.directed, + l = n.acyclic || n.maximal || n.maximalAdjustments > 0, + u = _t( + n.boundingBox + ? n.boundingBox + : { x1: 0, y1: 0, w: r.width(), h: r.height() }, + ); + if (E(n.roots)) e = n.roots; + else if (m(n.roots)) { + for (var c = [], d = 0; d < n.roots.length; d++) { + var h = n.roots[d], + p = r.getElementById(h); + c.push(p); + } + e = r.collection(c); + } else if (v(n.roots)) e = r.$(n.roots); + else if (s) e = a.roots(); + else { + var f = i.components(); + e = r.collection(); + for ( + var g = function (t) { + var n = f[t], + r = n.maxDegree(!1), + i = n.filter(function (e) { + return e.degree(!1) === r; + }); + e = e.add(i); + }, + y = 0; + y < f.length; + y++ + ) + g(y); + } + var b = [], + x = {}, + w = function (e, t) { + null == b[t] && (b[t] = []); + var n = b[t].length; + (b[t].push(e), qs(e, { index: n, depth: t })); + }; + o.bfs({ + roots: e, + directed: n.directed, + visit: function (e, t, n, r, i) { + var a = e[0], + o = a.id(); + (w(a, i), (x[o] = !0)); + }, + }); + for (var k = [], C = 0; C < a.length; C++) { + var S = a[C]; + x[S.id()] || k.push(S); + } + var P = function (e) { + for (var t = b[e], n = 0; n < t.length; n++) { + var r = t[n]; + null != r ? qs(r, { depth: e, index: n }) : (t.splice(n, 1), n--); + } + }, + D = function () { + for (var e = 0; e < b.length; e++) P(e); + }, + T = function (e, t) { + for ( + var r = js(e), + a = e.incomers().filter(function (e) { + return e.isNode() && i.has(e); + }), + o = -1, + s = e.id(), + l = 0; + l < a.length; + l++ + ) { + var u = a[l], + c = js(u); + o = Math.max(o, c.depth); + } + if (r.depth <= o) { + if (!n.acyclic && t[s]) return null; + var d = o + 1; + return ( + (function (e, t) { + var n = js(e), + r = n.depth, + i = n.index; + ((b[r][i] = null), w(e, t)); + })(e, d), + (t[s] = d), + !0 + ); + } + return !1; + }; + if (s && l) { + var _ = [], + M = {}, + B = function (e) { + return _.push(e); + }; + for ( + a.forEach(function (e) { + return _.push(e); + }); + _.length > 0; + ) { + var N = _.shift(), + z = T(N, M); + if (z) + N.outgoers() + .filter(function (e) { + return e.isNode() && i.has(e); + }) + .forEach(B); + else if (null === z) { + je( + "Detected double maximal shift for node `" + + N.id() + + "`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.", + ); + break; + } + } + } + D(); + var I = 0; + if (n.avoidOverlap) + for (var L = 0; L < a.length; L++) { + var O = a[L].layoutDimensions(n), + R = O.w, + V = O.h; + I = Math.max(I, R, V); + } + var F = {}, + j = function (e) { + if (F[e.id()]) return F[e.id()]; + for ( + var t = js(e).depth, n = e.neighborhood(), r = 0, i = 0, o = 0; + o < n.length; + o++ + ) { + var s = n[o]; + if (!s.isEdge() && !s.isParent() && a.has(s)) { + var l = js(s); + if (null != l) { + var u = l.index, + c = l.depth; + if (null != u && null != c) { + var d = b[c].length; + c < t && ((r += u / d), i++); + } + } + } + } + return ( + (r /= i = Math.max(1, i)), + 0 === i && (r = 0), + (F[e.id()] = r), + r + ); + }, + q = function (e, t) { + var n = j(e) - j(t); + return 0 === n ? A(e.id(), t.id()) : n; + }; + void 0 !== n.depthSort && (q = n.depthSort); + for (var Y = 0; Y < b.length; Y++) (b[Y].sort(q), P(Y)); + for (var X = [], W = 0; W < k.length; W++) X.push(k[W]); + (b.unshift(X), D()); + for (var H = 0, K = 0; K < b.length; K++) H = Math.max(b[K].length, H); + var G = u.x1 + u.w / 2, + U = u.x1 + u.h / 2, + Z = b.reduce(function (e, t) { + return Math.max(e, t.length); + }, 0); + return ( + i.nodes().layoutPositions(this, n, function (e) { + var t = js(e), + r = t.depth, + i = t.index, + a = b[r].length, + o = Math.max(u.w / ((n.grid ? Z : a) + 1), I), + s = Math.max(u.h / (b.length + 1), I), + l = Math.min(u.w / 2 / b.length, u.h / 2 / b.length); + if (((l = Math.max(l, I)), n.circle)) { + var c = l * r + l - (b.length > 0 && b[0].length <= 3 ? l / 2 : 0), + d = ((2 * Math.PI) / b[r].length) * i; + return ( + 0 === r && 1 === b[0].length && (c = 1), + { x: G + c * Math.cos(d), y: U + c * Math.sin(d) } + ); + } + return { x: G + (i + 1 - (a + 1) / 2) * o, y: (r + 1) * s }; + }), + this + ); + }; + var Xs = { + fit: !0, + padding: 30, + boundingBox: void 0, + avoidOverlap: !0, + nodeDimensionsIncludeLabels: !1, + spacingFactor: void 0, + radius: void 0, + startAngle: 1.5 * Math.PI, + sweep: void 0, + clockwise: !0, + sort: void 0, + animate: !1, + animationDuration: 500, + animationEasing: void 0, + animateFilter: function (e, t) { + return !0; + }, + ready: void 0, + stop: void 0, + transform: function (e, t) { + return t; + }, + }; + function Ws(e) { + this.options = L({}, Xs, e); + } + Ws.prototype.run = function () { + var e = this.options, + t = e, + n = e.cy, + r = t.eles, + i = void 0 !== t.counterclockwise ? !t.counterclockwise : t.clockwise, + a = r.nodes().not(":parent"); + t.sort && (a = a.sort(t.sort)); + for ( + var o, + s = _t( + t.boundingBox + ? t.boundingBox + : { x1: 0, y1: 0, w: n.width(), h: n.height() }, + ), + l = s.x1 + s.w / 2, + u = s.y1 + s.h / 2, + c = + (void 0 === t.sweep + ? 2 * Math.PI - (2 * Math.PI) / a.length + : t.sweep) / Math.max(1, a.length - 1), + d = 0, + h = 0; + h < a.length; + h++ + ) { + var p = a[h].layoutDimensions(t), + f = p.w, + g = p.h; + d = Math.max(d, f, g); + } + if ( + ((o = x(t.radius) + ? t.radius + : a.length <= 1 + ? 0 + : Math.min(s.h, s.w) / 2 - d), + a.length > 1 && t.avoidOverlap) + ) { + d *= 1.75; + var v = Math.cos(c) - Math.cos(0), + y = Math.sin(c) - Math.sin(0), + m = Math.sqrt((d * d) / (v * v + y * y)); + o = Math.max(m, o); + } + return ( + r.nodes().layoutPositions(this, t, function (e, n) { + var r = t.startAngle + n * c * (i ? 1 : -1), + a = o * Math.cos(r), + s = o * Math.sin(r); + return { x: l + a, y: u + s }; + }), + this + ); + }; + var Hs, + Ks = { + fit: !0, + padding: 30, + startAngle: 1.5 * Math.PI, + sweep: void 0, + clockwise: !0, + equidistant: !1, + minNodeSpacing: 10, + boundingBox: void 0, + avoidOverlap: !0, + nodeDimensionsIncludeLabels: !1, + height: void 0, + width: void 0, + spacingFactor: void 0, + concentric: function (e) { + return e.degree(); + }, + levelWidth: function (e) { + return e.maxDegree() / 4; + }, + animate: !1, + animationDuration: 500, + animationEasing: void 0, + animateFilter: function (e, t) { + return !0; + }, + ready: void 0, + stop: void 0, + transform: function (e, t) { + return t; + }, + }; + function Gs(e) { + this.options = L({}, Ks, e); + } + Gs.prototype.run = function () { + for ( + var e = this.options, + t = e, + n = void 0 !== t.counterclockwise ? !t.counterclockwise : t.clockwise, + r = e.cy, + i = t.eles, + a = i.nodes().not(":parent"), + o = _t( + t.boundingBox + ? t.boundingBox + : { x1: 0, y1: 0, w: r.width(), h: r.height() }, + ), + s = o.x1 + o.w / 2, + l = o.y1 + o.h / 2, + u = [], + c = 0, + d = 0; + d < a.length; + d++ + ) { + var h, + p = a[d]; + ((h = t.concentric(p)), + u.push({ value: h, node: p }), + (p._private.scratch.concentric = h)); + } + a.updateStyle(); + for (var f = 0; f < a.length; f++) { + var g = a[f].layoutDimensions(t); + c = Math.max(c, g.w, g.h); + } + u.sort(function (e, t) { + return t.value - e.value; + }); + for ( + var v = t.levelWidth(a), y = [[]], m = y[0], b = 0; + b < u.length; + b++ + ) { + var x = u[b]; + if (m.length > 0) + Math.abs(m[0].value - x.value) >= v && ((m = []), y.push(m)); + m.push(x); + } + var w = c + t.minNodeSpacing; + if (!t.avoidOverlap) { + var E = y.length > 0 && y[0].length > 1, + k = (Math.min(o.w, o.h) / 2 - w) / (y.length + E ? 1 : 0); + w = Math.min(w, k); + } + for (var C = 0, S = 0; S < y.length; S++) { + var P = y[S], + D = + void 0 === t.sweep ? 2 * Math.PI - (2 * Math.PI) / P.length : t.sweep, + T = (P.dTheta = D / Math.max(1, P.length - 1)); + if (P.length > 1 && t.avoidOverlap) { + var _ = Math.cos(T) - Math.cos(0), + M = Math.sin(T) - Math.sin(0), + B = Math.sqrt((w * w) / (_ * _ + M * M)); + C = Math.max(B, C); + } + ((P.r = C), (C += w)); + } + if (t.equidistant) { + for (var N = 0, z = 0, I = 0; I < y.length; I++) { + var A = y[I].r - z; + N = Math.max(N, A); + } + z = 0; + for (var L = 0; L < y.length; L++) { + var O = y[L]; + (0 === L && (z = O.r), (O.r = z), (z += N)); + } + } + for (var R = {}, V = 0; V < y.length; V++) + for (var F = y[V], j = F.dTheta, q = F.r, Y = 0; Y < F.length; Y++) { + var X = F[Y], + W = t.startAngle + (n ? 1 : -1) * j * Y, + H = { x: s + q * Math.cos(W), y: l + q * Math.sin(W) }; + R[X.node.id()] = H; + } + return ( + i.nodes().layoutPositions(this, t, function (e) { + var t = e.id(); + return R[t]; + }), + this + ); + }; + var Us = { + ready: function () {}, + stop: function () {}, + animate: !0, + animationEasing: void 0, + animationDuration: void 0, + animateFilter: function (e, t) { + return !0; + }, + animationThreshold: 250, + refresh: 20, + fit: !0, + padding: 30, + boundingBox: void 0, + nodeDimensionsIncludeLabels: !1, + randomize: !1, + componentSpacing: 40, + nodeRepulsion: function (e) { + return 2048; + }, + nodeOverlap: 4, + idealEdgeLength: function (e) { + return 32; + }, + edgeElasticity: function (e) { + return 32; + }, + nestingFactor: 1.2, + gravity: 1, + numIter: 1e3, + initialTemp: 1e3, + coolingFactor: 0.99, + minTemp: 1, + }; + function Zs(e) { + ((this.options = L({}, Us, e)), (this.options.layout = this)); + var t = this.options.eles.nodes(), + n = this.options.eles.edges().filter(function (e) { + var n = e.source().data("id"), + r = e.target().data("id"), + i = t.some(function (e) { + return e.data("id") === n; + }), + a = t.some(function (e) { + return e.data("id") === r; + }); + return !i || !a; + }); + this.options.eles = this.options.eles.not(n); + } + ((Zs.prototype.run = function () { + var e = this.options, + t = e.cy, + n = this; + ((n.stopped = !1), + (!0 !== e.animate && !1 !== e.animate) || + n.emit({ type: "layoutstart", layout: n }), + (Hs = !0 === e.debug)); + var r = $s(t, n, e); + (Hs && (void 0)(r), e.randomize && el(r)); + var i = we(), + a = function () { + (nl(r, t, e), !0 === e.fit && t.fit(e.padding)); + }, + o = function (t) { + return ( + !(n.stopped || t >= e.numIter) && + (rl(r, e), + (r.temperature = r.temperature * e.coolingFactor), + !(r.temperature < e.minTemp)) + ); + }, + s = function () { + if (!0 === e.animate || !1 === e.animate) + (a(), + n.one("layoutstop", e.stop), + n.emit({ type: "layoutstop", layout: n })); + else { + var t = e.eles.nodes(), + i = tl(r, e, t); + t.layoutPositions(n, e, i); + } + }, + l = 0, + u = !0; + if (!0 === e.animate) { + !(function t() { + for (var n = 0; u && n < e.refresh; ) ((u = o(l)), l++, n++); + u ? (we() - i >= e.animationThreshold && a(), xe(t)) : (gl(r, e), s()); + })(); + } else { + for (; u; ) ((u = o(l)), l++); + (gl(r, e), s()); + } + return this; + }), + (Zs.prototype.stop = function () { + return ( + (this.stopped = !0), + this.thread && this.thread.stop(), + this.emit("layoutstop"), + this + ); + }), + (Zs.prototype.destroy = function () { + return (this.thread && this.thread.stop(), this); + })); + var $s = function (e, t, n) { + for ( + var r = n.eles.edges(), + i = n.eles.nodes(), + a = _t( + n.boundingBox + ? n.boundingBox + : { x1: 0, y1: 0, w: e.width(), h: e.height() }, + ), + o = { + isCompound: e.hasCompoundNodes(), + layoutNodes: [], + idToIndex: {}, + nodeSize: i.size(), + graphSet: [], + indexToGraph: [], + layoutEdges: [], + edgeSize: r.size(), + temperature: n.initialTemp, + clientWidth: a.w, + clientHeight: a.h, + boundingBox: a, + }, + s = n.eles.components(), + l = {}, + u = 0; + u < s.length; + u++ + ) + for (var c = s[u], d = 0; d < c.length; d++) { + l[c[d].id()] = u; + } + for (u = 0; u < o.nodeSize; u++) { + var h = (m = i[u]).layoutDimensions(n); + (((I = {}).isLocked = m.locked()), + (I.id = m.data("id")), + (I.parentId = m.data("parent")), + (I.cmptId = l[m.id()]), + (I.children = []), + (I.positionX = m.position("x")), + (I.positionY = m.position("y")), + (I.offsetX = 0), + (I.offsetY = 0), + (I.height = h.w), + (I.width = h.h), + (I.maxX = I.positionX + I.width / 2), + (I.minX = I.positionX - I.width / 2), + (I.maxY = I.positionY + I.height / 2), + (I.minY = I.positionY - I.height / 2), + (I.padLeft = parseFloat(m.style("padding"))), + (I.padRight = parseFloat(m.style("padding"))), + (I.padTop = parseFloat(m.style("padding"))), + (I.padBottom = parseFloat(m.style("padding"))), + (I.nodeRepulsion = y(n.nodeRepulsion) + ? n.nodeRepulsion(m) + : n.nodeRepulsion), + o.layoutNodes.push(I), + (o.idToIndex[I.id] = u)); + } + var p = [], + f = 0, + g = -1, + v = []; + for (u = 0; u < o.nodeSize; u++) { + var m, + b = (m = o.layoutNodes[u]).parentId; + null != b + ? o.layoutNodes[o.idToIndex[b]].children.push(m.id) + : ((p[++g] = m.id), v.push(m.id)); + } + for (o.graphSet.push(v); f <= g; ) { + var x = p[f++], + w = o.idToIndex[x], + E = o.layoutNodes[w].children; + if (E.length > 0) { + o.graphSet.push(E); + for (u = 0; u < E.length; u++) p[++g] = E[u]; + } + } + for (u = 0; u < o.graphSet.length; u++) { + var k = o.graphSet[u]; + for (d = 0; d < k.length; d++) { + var C = o.idToIndex[k[d]]; + o.indexToGraph[C] = u; + } + } + for (u = 0; u < o.edgeSize; u++) { + var S = r[u], + P = {}; + ((P.id = S.data("id")), + (P.sourceId = S.data("source")), + (P.targetId = S.data("target"))); + var D = y(n.idealEdgeLength) ? n.idealEdgeLength(S) : n.idealEdgeLength, + T = y(n.edgeElasticity) ? n.edgeElasticity(S) : n.edgeElasticity, + _ = o.idToIndex[P.sourceId], + M = o.idToIndex[P.targetId]; + if (o.indexToGraph[_] != o.indexToGraph[M]) { + for ( + var B = Qs(P.sourceId, P.targetId, o), + N = o.graphSet[B], + z = 0, + I = o.layoutNodes[_]; + -1 === N.indexOf(I.id); + ) + ((I = o.layoutNodes[o.idToIndex[I.parentId]]), z++); + for (I = o.layoutNodes[M]; -1 === N.indexOf(I.id); ) + ((I = o.layoutNodes[o.idToIndex[I.parentId]]), z++); + D *= z * n.nestingFactor; + } + ((P.idealLength = D), (P.elasticity = T), o.layoutEdges.push(P)); + } + return o; + }, + Qs = function (e, t, n) { + var r = Js(e, t, 0, n); + return 2 > r.count ? 0 : r.graph; + }, + Js = function e(t, n, r, i) { + var a = i.graphSet[r]; + if (-1 < a.indexOf(t) && -1 < a.indexOf(n)) return { count: 2, graph: r }; + for (var o = 0, s = 0; s < a.length; s++) { + var l = a[s], + u = i.idToIndex[l], + c = i.layoutNodes[u].children; + if (0 !== c.length) { + var d = e(t, n, i.indexToGraph[i.idToIndex[c[0]]], i); + if (0 !== d.count) { + if (1 !== d.count) return d; + if (2 === ++o) break; + } + } + } + return { count: o, graph: r }; + }, + el = function (e, t) { + for ( + var n = e.clientWidth, r = e.clientHeight, i = 0; + i < e.nodeSize; + i++ + ) { + var a = e.layoutNodes[i]; + 0 !== a.children.length || + a.isLocked || + ((a.positionX = Math.random() * n), + (a.positionY = Math.random() * r)); + } + }, + tl = function (e, t, n) { + var r = e.boundingBox, + i = { x1: 1 / 0, x2: -1 / 0, y1: 1 / 0, y2: -1 / 0 }; + return ( + t.boundingBox && + (n.forEach(function (t) { + var n = e.layoutNodes[e.idToIndex[t.data("id")]]; + ((i.x1 = Math.min(i.x1, n.positionX)), + (i.x2 = Math.max(i.x2, n.positionX)), + (i.y1 = Math.min(i.y1, n.positionY)), + (i.y2 = Math.max(i.y2, n.positionY))); + }), + (i.w = i.x2 - i.x1), + (i.h = i.y2 - i.y1)), + function (n, a) { + var o = e.layoutNodes[e.idToIndex[n.data("id")]]; + if (t.boundingBox) { + var s = (o.positionX - i.x1) / i.w, + l = (o.positionY - i.y1) / i.h; + return { x: r.x1 + s * r.w, y: r.y1 + l * r.h }; + } + return { x: o.positionX, y: o.positionY }; + } + ); + }, + nl = function (e, t, n) { + var r = n.layout, + i = n.eles.nodes(), + a = tl(e, n, i); + (i.positions(a), + !0 !== e.ready && + ((e.ready = !0), + r.one("layoutready", n.ready), + r.emit({ type: "layoutready", layout: this }))); + }, + rl = function (e, t, n) { + (il(e, t), ul(e), cl(e, t), dl(e), hl(e)); + }, + il = function (e, t) { + for (var n = 0; n < e.graphSet.length; n++) + for (var r = e.graphSet[n], i = r.length, a = 0; a < i; a++) + for ( + var o = e.layoutNodes[e.idToIndex[r[a]]], s = a + 1; + s < i; + s++ + ) { + var l = e.layoutNodes[e.idToIndex[r[s]]]; + ol(o, l, e, t); + } + }, + al = function (e) { + return -e + 2 * e * Math.random(); + }, + ol = function (e, t, n, r) { + if (e.cmptId === t.cmptId || n.isCompound) { + var i = t.positionX - e.positionX, + a = t.positionY - e.positionY; + 0 === i && 0 === a && ((i = al(1)), (a = al(1))); + var o = sl(e, t, i, a); + if (o > 0) + var s = + ((u = r.nodeOverlap * o) * i) / (g = Math.sqrt(i * i + a * a)), + l = (u * a) / g; + else { + var u, + c = ll(e, i, a), + d = ll(t, -1 * i, -1 * a), + h = d.x - c.x, + p = d.y - c.y, + f = h * h + p * p, + g = Math.sqrt(f); + ((s = ((u = (e.nodeRepulsion + t.nodeRepulsion) / f) * h) / g), + (l = (u * p) / g)); + } + (e.isLocked || ((e.offsetX -= s), (e.offsetY -= l)), + t.isLocked || ((t.offsetX += s), (t.offsetY += l))); + } + }, + sl = function (e, t, n, r) { + if (n > 0) var i = e.maxX - t.minX; + else i = t.maxX - e.minX; + if (r > 0) var a = e.maxY - t.minY; + else a = t.maxY - e.minY; + return i >= 0 && a >= 0 ? Math.sqrt(i * i + a * a) : 0; + }, + ll = function (e, t, n) { + var r = e.positionX, + i = e.positionY, + a = e.height || 1, + o = e.width || 1, + s = n / t, + l = a / o, + u = {}; + return (0 === t && 0 < n) || (0 === t && 0 > n) + ? ((u.x = r), (u.y = i + a / 2), u) + : 0 < t && -1 * l <= s && s <= l + ? ((u.x = r + o / 2), (u.y = i + (o * n) / 2 / t), u) + : 0 > t && -1 * l <= s && s <= l + ? ((u.x = r - o / 2), (u.y = i - (o * n) / 2 / t), u) + : 0 < n && (s <= -1 * l || s >= l) + ? ((u.x = r + (a * t) / 2 / n), (u.y = i + a / 2), u) + : 0 > n && (s <= -1 * l || s >= l) + ? ((u.x = r - (a * t) / 2 / n), (u.y = i - a / 2), u) + : u; + }, + ul = function (e, t) { + for (var n = 0; n < e.edgeSize; n++) { + var r = e.layoutEdges[n], + i = e.idToIndex[r.sourceId], + a = e.layoutNodes[i], + o = e.idToIndex[r.targetId], + s = e.layoutNodes[o], + l = s.positionX - a.positionX, + u = s.positionY - a.positionY; + if (0 !== l || 0 !== u) { + var c = ll(a, l, u), + d = ll(s, -1 * l, -1 * u), + h = d.x - c.x, + p = d.y - c.y, + f = Math.sqrt(h * h + p * p), + g = Math.pow(r.idealLength - f, 2) / r.elasticity; + if (0 !== f) + var v = (g * h) / f, + y = (g * p) / f; + else ((v = 0), (y = 0)); + (a.isLocked || ((a.offsetX += v), (a.offsetY += y)), + s.isLocked || ((s.offsetX -= v), (s.offsetY -= y))); + } + } + }, + cl = function (e, t) { + if (0 !== t.gravity) + for (var n = 0; n < e.graphSet.length; n++) { + var r = e.graphSet[n], + i = r.length; + if (0 === n) + var a = e.clientHeight / 2, + o = e.clientWidth / 2; + else { + var s = e.layoutNodes[e.idToIndex[r[0]]], + l = e.layoutNodes[e.idToIndex[s.parentId]]; + ((a = l.positionX), (o = l.positionY)); + } + for (var u = 0; u < i; u++) { + var c = e.layoutNodes[e.idToIndex[r[u]]]; + if (!c.isLocked) { + var d = a - c.positionX, + h = o - c.positionY, + p = Math.sqrt(d * d + h * h); + if (p > 1) { + var f = (t.gravity * d) / p, + g = (t.gravity * h) / p; + ((c.offsetX += f), (c.offsetY += g)); + } + } + } + } + }, + dl = function (e, t) { + var n = [], + r = 0, + i = -1; + for ( + n.push.apply(n, e.graphSet[0]), i += e.graphSet[0].length; + r <= i; + ) { + var a = n[r++], + o = e.idToIndex[a], + s = e.layoutNodes[o], + l = s.children; + if (0 < l.length && !s.isLocked) { + for (var u = s.offsetX, c = s.offsetY, d = 0; d < l.length; d++) { + var h = e.layoutNodes[e.idToIndex[l[d]]]; + ((h.offsetX += u), (h.offsetY += c), (n[++i] = l[d])); + } + ((s.offsetX = 0), (s.offsetY = 0)); + } + } + }, + hl = function (e, t) { + for (var n = 0; n < e.nodeSize; n++) { + 0 < (i = e.layoutNodes[n]).children.length && + ((i.maxX = void 0), + (i.minX = void 0), + (i.maxY = void 0), + (i.minY = void 0)); + } + for (n = 0; n < e.nodeSize; n++) { + if (!(0 < (i = e.layoutNodes[n]).children.length || i.isLocked)) { + var r = pl(i.offsetX, i.offsetY, e.temperature); + ((i.positionX += r.x), + (i.positionY += r.y), + (i.offsetX = 0), + (i.offsetY = 0), + (i.minX = i.positionX - i.width), + (i.maxX = i.positionX + i.width), + (i.minY = i.positionY - i.height), + (i.maxY = i.positionY + i.height), + fl(i, e)); + } + } + for (n = 0; n < e.nodeSize; n++) { + var i; + 0 < (i = e.layoutNodes[n]).children.length && + !i.isLocked && + ((i.positionX = (i.maxX + i.minX) / 2), + (i.positionY = (i.maxY + i.minY) / 2), + (i.width = i.maxX - i.minX), + (i.height = i.maxY - i.minY)); + } + }, + pl = function (e, t, n) { + var r = Math.sqrt(e * e + t * t); + if (r > n) var i = { x: (n * e) / r, y: (n * t) / r }; + else i = { x: e, y: t }; + return i; + }, + fl = function e(t, n) { + var r = t.parentId; + if (null != r) { + var i = n.layoutNodes[n.idToIndex[r]], + a = !1; + return ( + (null == i.maxX || t.maxX + i.padRight > i.maxX) && + ((i.maxX = t.maxX + i.padRight), (a = !0)), + (null == i.minX || t.minX - i.padLeft < i.minX) && + ((i.minX = t.minX - i.padLeft), (a = !0)), + (null == i.maxY || t.maxY + i.padBottom > i.maxY) && + ((i.maxY = t.maxY + i.padBottom), (a = !0)), + (null == i.minY || t.minY - i.padTop < i.minY) && + ((i.minY = t.minY - i.padTop), (a = !0)), + a ? e(i, n) : void 0 + ); + } + }, + gl = function (e, t) { + for (var n = e.layoutNodes, r = [], i = 0; i < n.length; i++) { + var a = n[i], + o = a.cmptId; + (r[o] = r[o] || []).push(a); + } + var s = 0; + for (i = 0; i < r.length; i++) { + if ((g = r[i])) { + ((g.x1 = 1 / 0), (g.x2 = -1 / 0), (g.y1 = 1 / 0), (g.y2 = -1 / 0)); + for (var l = 0; l < g.length; l++) { + var u = g[l]; + ((g.x1 = Math.min(g.x1, u.positionX - u.width / 2)), + (g.x2 = Math.max(g.x2, u.positionX + u.width / 2)), + (g.y1 = Math.min(g.y1, u.positionY - u.height / 2)), + (g.y2 = Math.max(g.y2, u.positionY + u.height / 2))); + } + ((g.w = g.x2 - g.x1), (g.h = g.y2 - g.y1), (s += g.w * g.h)); + } + } + r.sort(function (e, t) { + return t.w * t.h - e.w * e.h; + }); + var c = 0, + d = 0, + h = 0, + p = 0, + f = (Math.sqrt(s) * e.clientWidth) / e.clientHeight; + for (i = 0; i < r.length; i++) { + var g; + if ((g = r[i])) { + for (l = 0; l < g.length; l++) { + (u = g[l]).isLocked || + ((u.positionX += c - g.x1), (u.positionY += d - g.y1)); + } + ((c += g.w + t.componentSpacing), + (h += g.w + t.componentSpacing), + (p = Math.max(p, g.h)), + h > f && + ((d += p + t.componentSpacing), (c = 0), (h = 0), (p = 0))); + } + } + }, + vl = { + fit: !0, + padding: 30, + boundingBox: void 0, + avoidOverlap: !0, + avoidOverlapPadding: 10, + nodeDimensionsIncludeLabels: !1, + spacingFactor: void 0, + condense: !1, + rows: void 0, + cols: void 0, + position: function (e) {}, + sort: void 0, + animate: !1, + animationDuration: 500, + animationEasing: void 0, + animateFilter: function (e, t) { + return !0; + }, + ready: void 0, + stop: void 0, + transform: function (e, t) { + return t; + }, + }; + function yl(e) { + this.options = L({}, vl, e); + } + yl.prototype.run = function () { + var e = this.options, + t = e, + n = e.cy, + r = t.eles, + i = r.nodes().not(":parent"); + t.sort && (i = i.sort(t.sort)); + var a = _t( + t.boundingBox + ? t.boundingBox + : { x1: 0, y1: 0, w: n.width(), h: n.height() }, + ); + if (0 === a.h || 0 === a.w) + r.nodes().layoutPositions(this, t, function (e) { + return { x: a.x1, y: a.y1 }; + }); + else { + var o = i.size(), + s = Math.sqrt((o * a.h) / a.w), + l = Math.round(s), + u = Math.round((a.w / a.h) * s), + c = function (e) { + if (null == e) return Math.min(l, u); + Math.min(l, u) == l ? (l = e) : (u = e); + }, + d = function (e) { + if (null == e) return Math.max(l, u); + Math.max(l, u) == l ? (l = e) : (u = e); + }, + h = t.rows, + p = null != t.cols ? t.cols : t.columns; + if (null != h && null != p) ((l = h), (u = p)); + else if (null != h && null == p) ((l = h), (u = Math.ceil(o / l))); + else if (null == h && null != p) ((u = p), (l = Math.ceil(o / u))); + else if (u * l > o) { + var f = c(), + g = d(); + (f - 1) * g >= o ? c(f - 1) : (g - 1) * f >= o && d(g - 1); + } else + for (; u * l < o; ) { + var v = c(), + y = d(); + (y + 1) * v >= o ? d(y + 1) : c(v + 1); + } + var m = a.w / u, + b = a.h / l; + if ((t.condense && ((m = 0), (b = 0)), t.avoidOverlap)) + for (var x = 0; x < i.length; x++) { + var w = i[x], + E = w._private.position; + (null != E.x && null != E.y) || ((E.x = 0), (E.y = 0)); + var k = w.layoutDimensions(t), + C = t.avoidOverlapPadding, + S = k.w + C, + P = k.h + C; + ((m = Math.max(m, S)), (b = Math.max(b, P))); + } + for ( + var D = {}, + T = function (e, t) { + return !!D["c-" + e + "-" + t]; + }, + _ = function (e, t) { + D["c-" + e + "-" + t] = !0; + }, + M = 0, + B = 0, + N = function () { + ++B >= u && ((B = 0), M++); + }, + z = {}, + I = 0; + I < i.length; + I++ + ) { + var A = i[I], + L = t.position(A); + if (L && (void 0 !== L.row || void 0 !== L.col)) { + var O = { row: L.row, col: L.col }; + if (void 0 === O.col) for (O.col = 0; T(O.row, O.col); ) O.col++; + else if (void 0 === O.row) for (O.row = 0; T(O.row, O.col); ) O.row++; + ((z[A.id()] = O), _(O.row, O.col)); + } + } + i.layoutPositions(this, t, function (e, t) { + var n, r; + if (e.locked() || e.isParent()) return !1; + var i = z[e.id()]; + if (i) ((n = i.col * m + m / 2 + a.x1), (r = i.row * b + b / 2 + a.y1)); + else { + for (; T(M, B); ) N(); + ((n = B * m + m / 2 + a.x1), + (r = M * b + b / 2 + a.y1), + _(M, B), + N()); + } + return { x: n, y: r }; + }); + } + return this; + }; + var ml = { ready: function () {}, stop: function () {} }; + function bl(e) { + this.options = L({}, ml, e); + } + ((bl.prototype.run = function () { + var e = this.options, + t = e.eles; + return ( + e.cy, + this.emit("layoutstart"), + t.nodes().positions(function () { + return { x: 0, y: 0 }; + }), + this.one("layoutready", e.ready), + this.emit("layoutready"), + this.one("layoutstop", e.stop), + this.emit("layoutstop"), + this + ); + }), + (bl.prototype.stop = function () { + return this; + })); + var xl = { + positions: void 0, + zoom: void 0, + pan: void 0, + fit: !0, + padding: 30, + spacingFactor: void 0, + animate: !1, + animationDuration: 500, + animationEasing: void 0, + animateFilter: function (e, t) { + return !0; + }, + ready: void 0, + stop: void 0, + transform: function (e, t) { + return t; + }, + }; + function wl(e) { + this.options = L({}, xl, e); + } + wl.prototype.run = function () { + var e = this.options, + t = e.eles.nodes(), + n = y(e.positions); + return ( + t.layoutPositions(this, e, function (t, r) { + var i = (function (t) { + if (null == e.positions) + return (function (e) { + return { x: e.x, y: e.y }; + })(t.position()); + if (n) return e.positions(t); + var r = e.positions[t._private.data.id]; + return null == r ? null : r; + })(t); + return !t.locked() && null != i && i; + }), + this + ); + }; + var El = { + fit: !0, + padding: 30, + boundingBox: void 0, + animate: !1, + animationDuration: 500, + animationEasing: void 0, + animateFilter: function (e, t) { + return !0; + }, + ready: void 0, + stop: void 0, + transform: function (e, t) { + return t; + }, + }; + function kl(e) { + this.options = L({}, El, e); + } + kl.prototype.run = function () { + var e = this.options, + t = e.cy, + n = e.eles, + r = _t( + e.boundingBox + ? e.boundingBox + : { x1: 0, y1: 0, w: t.width(), h: t.height() }, + ); + return ( + n.nodes().layoutPositions(this, e, function (e, t) { + return { + x: r.x1 + Math.round(Math.random() * r.w), + y: r.y1 + Math.round(Math.random() * r.h), + }; + }), + this + ); + }; + var Cl = [ + { name: "breadthfirst", impl: Ys }, + { name: "circle", impl: Ws }, + { name: "concentric", impl: Gs }, + { name: "cose", impl: Zs }, + { name: "grid", impl: yl }, + { name: "null", impl: bl }, + { name: "preset", impl: wl }, + { name: "random", impl: kl }, + ]; + function Sl(e) { + ((this.options = e), (this.notifications = 0)); + } + var Pl = function () {}, + Dl = function () { + throw new Error("A headless instance can not render images"); + }; + Sl.prototype = { + recalculateRenderedStyle: Pl, + notify: function () { + this.notifications++; + }, + init: Pl, + isHeadless: function () { + return !0; + }, + png: Dl, + jpg: Dl, + }; + var Tl = { + arrowShapeWidth: 0.3, + registerArrowShapes: function () { + var e = (this.arrowShapes = {}), + t = this, + n = function (e, t, n, r, i, a, o) { + var s = i.x - n / 2 - o, + l = i.x + n / 2 + o, + u = i.y - n / 2 - o, + c = i.y + n / 2 + o; + return s <= e && e <= l && u <= t && t <= c; + }, + r = function (e, t, n, r, i) { + var a = e * Math.cos(r) - t * Math.sin(r), + o = (e * Math.sin(r) + t * Math.cos(r)) * n; + return { x: a * n + i.x, y: o + i.y }; + }, + i = function (e, t, n, i) { + for (var a = [], o = 0; o < e.length; o += 2) { + var s = e[o], + l = e[o + 1]; + a.push(r(s, l, t, n, i)); + } + return a; + }, + a = function (e) { + for (var t = [], n = 0; n < e.length; n++) { + var r = e[n]; + t.push(r.x, r.y); + } + return t; + }, + o = function (e) { + return ( + e.pstyle("width").pfValue * e.pstyle("arrow-scale").pfValue * 2 + ); + }, + s = function (r, s) { + (v(s) && (s = e[s]), + (e[r] = L( + { + name: r, + points: [-0.15, -0.3, 0.15, -0.3, 0.15, 0.3, -0.15, 0.3], + collide: function (e, t, n, r, o, s) { + var l = a(i(this.points, n + 2 * s, r, o)); + return Yt(e, t, l); + }, + roughCollide: n, + draw: function (e, n, r, a) { + var o = i(this.points, n, r, a); + t.arrowShapeImpl("polygon")(e, o); + }, + spacing: function (e) { + return 0; + }, + gap: o, + }, + s, + ))); + }; + (s("none", { + collide: Le, + roughCollide: Le, + draw: Re, + spacing: Oe, + gap: Oe, + }), + s("triangle", { points: [-0.15, -0.3, 0, 0, 0.15, -0.3] }), + s("arrow", "triangle"), + s("triangle-backcurve", { + points: e.triangle.points, + controlPoint: [0, -0.15], + roughCollide: n, + draw: function (e, n, a, o, s) { + var l = i(this.points, n, a, o), + u = this.controlPoint, + c = r(u[0], u[1], n, a, o); + t.arrowShapeImpl(this.name)(e, l, c); + }, + gap: function (e) { + return 0.8 * o(e); + }, + }), + s("triangle-tee", { + points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0], + pointsTee: [-0.15, -0.4, -0.15, -0.5, 0.15, -0.5, 0.15, -0.4], + collide: function (e, t, n, r, o, s, l) { + var u = a(i(this.points, n + 2 * l, r, o)), + c = a(i(this.pointsTee, n + 2 * l, r, o)); + return Yt(e, t, u) || Yt(e, t, c); + }, + draw: function (e, n, r, a, o) { + var s = i(this.points, n, r, a), + l = i(this.pointsTee, n, r, a); + t.arrowShapeImpl(this.name)(e, s, l); + }, + }), + s("circle-triangle", { + radius: 0.15, + pointsTr: [0, -0.15, 0.15, -0.45, -0.15, -0.45, 0, -0.15], + collide: function (e, t, n, r, o, s, l) { + var u = o, + c = + Math.pow(u.x - e, 2) + Math.pow(u.y - t, 2) <= + Math.pow((n + 2 * l) * this.radius, 2), + d = a(i(this.points, n + 2 * l, r, o)); + return Yt(e, t, d) || c; + }, + draw: function (e, n, r, a, o) { + var s = i(this.pointsTr, n, r, a); + t.arrowShapeImpl(this.name)(e, s, a.x, a.y, this.radius * n); + }, + spacing: function (e) { + return ( + t.getArrowWidth( + e.pstyle("width").pfValue, + e.pstyle("arrow-scale").value, + ) * this.radius + ); + }, + }), + s("triangle-cross", { + points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0], + baseCrossLinePts: [ + -0.15, -0.4, -0.15, -0.4, 0.15, -0.4, 0.15, -0.4, + ], + crossLinePts: function (e, t) { + var n = this.baseCrossLinePts.slice(), + r = t / e; + return ((n[3] = n[3] - r), (n[5] = n[5] - r), n); + }, + collide: function (e, t, n, r, o, s, l) { + var u = a(i(this.points, n + 2 * l, r, o)), + c = a(i(this.crossLinePts(n, s), n + 2 * l, r, o)); + return Yt(e, t, u) || Yt(e, t, c); + }, + draw: function (e, n, r, a, o) { + var s = i(this.points, n, r, a), + l = i(this.crossLinePts(n, o), n, r, a); + t.arrowShapeImpl(this.name)(e, s, l); + }, + }), + s("vee", { + points: [-0.15, -0.3, 0, 0, 0.15, -0.3, 0, -0.15], + gap: function (e) { + return 0.525 * o(e); + }, + }), + s("circle", { + radius: 0.15, + collide: function (e, t, n, r, i, a, o) { + var s = i; + return ( + Math.pow(s.x - e, 2) + Math.pow(s.y - t, 2) <= + Math.pow((n + 2 * o) * this.radius, 2) + ); + }, + draw: function (e, n, r, i, a) { + t.arrowShapeImpl(this.name)(e, i.x, i.y, this.radius * n); + }, + spacing: function (e) { + return ( + t.getArrowWidth( + e.pstyle("width").pfValue, + e.pstyle("arrow-scale").value, + ) * this.radius + ); + }, + }), + s("tee", { + points: [-0.15, 0, -0.15, -0.1, 0.15, -0.1, 0.15, 0], + spacing: function (e) { + return 1; + }, + gap: function (e) { + return 1; + }, + }), + s("square", { points: [-0.15, 0, 0.15, 0, 0.15, -0.3, -0.15, -0.3] }), + s("diamond", { + points: [-0.15, -0.15, 0, -0.3, 0.15, -0.15, 0, 0], + gap: function (e) { + return e.pstyle("width").pfValue * e.pstyle("arrow-scale").value; + }, + }), + s("chevron", { + points: [ + 0, 0, -0.15, -0.15, -0.1, -0.2, 0, -0.1, 0.1, -0.2, 0.15, -0.15, + ], + gap: function (e) { + return ( + 0.95 * e.pstyle("width").pfValue * e.pstyle("arrow-scale").value + ); + }, + })); + }, + }, + _l = { + projectIntoViewport: function (e, t) { + var n = this.cy, + r = this.findContainerClientCoords(), + i = r[0], + a = r[1], + o = r[4], + s = n.pan(), + l = n.zoom(); + return [((e - i) / o - s.x) / l, ((t - a) / o - s.y) / l]; + }, + findContainerClientCoords: function () { + if (this.containerBB) return this.containerBB; + var e = this.container, + t = e.getBoundingClientRect(), + n = this.cy.window().getComputedStyle(e), + r = function (e) { + return parseFloat(n.getPropertyValue(e)); + }, + i = r("padding-left"), + a = r("padding-right"), + o = r("padding-top"), + s = r("padding-bottom"), + l = r("border-left-width"), + u = r("border-right-width"), + c = r("border-top-width"), + d = (r("border-bottom-width"), e.clientWidth), + h = e.clientHeight, + p = i + a, + f = o + s, + g = l + u, + v = t.width / (d + g), + y = d - p, + m = h - f, + b = t.left + i + l, + x = t.top + o + c; + return (this.containerBB = [b, x, y, m, v]); + }, + invalidateContainerClientCoordsCache: function () { + this.containerBB = null; + }, + findNearestElement: function (e, t, n, r) { + return this.findNearestElements(e, t, n, r)[0]; + }, + findNearestElements: function (e, t, n, r) { + var i, + a, + o = this, + s = this, + l = s.getCachedZSortedEles(), + u = [], + c = s.cy.zoom(), + d = s.cy.hasCompoundNodes(), + h = (r ? 24 : 8) / c, + p = (r ? 8 : 2) / c, + f = (r ? 8 : 2) / c, + g = 1 / 0; + function v(e, t) { + if (e.isNode()) { + if (a) return; + ((a = e), u.push(e)); + } + if (e.isEdge() && (null == t || t < g)) + if (i) { + if ( + i.pstyle("z-compound-depth").value === + e.pstyle("z-compound-depth").value && + i.pstyle("z-compound-depth").value === + e.pstyle("z-compound-depth").value + ) + for (var n = 0; n < u.length; n++) + if (u[n].isEdge()) { + ((u[n] = e), (i = e), (g = null != t ? t : g)); + break; + } + } else (u.push(e), (i = e), (g = null != t ? t : g)); + } + function y(n) { + var r = n.outerWidth() + 2 * p, + i = n.outerHeight() + 2 * p, + a = r / 2, + l = i / 2, + u = n.position(), + c = + "auto" === n.pstyle("corner-radius").value + ? "auto" + : n.pstyle("corner-radius").pfValue, + d = n._private.rscratch; + if ( + u.x - a <= e && + e <= u.x + a && + u.y - l <= t && + t <= u.y + l && + s.nodeShapes[o.getNodeShape(n)].checkPoint( + e, + t, + 0, + r, + i, + u.x, + u.y, + c, + d, + ) + ) + return (v(n, 0), !0); + } + function m(n) { + var r, + i = n._private, + a = i.rscratch, + l = n.pstyle("width").pfValue, + c = n.pstyle("arrow-scale").value, + p = l / 2 + h, + f = p * p, + g = 2 * p, + m = i.source, + b = i.target; + if ( + "segments" === a.edgeType || + "straight" === a.edgeType || + "haystack" === a.edgeType + ) { + for (var x = a.allpts, w = 0; w + 3 < x.length; w += 2) + if ( + Vt(e, t, x[w], x[w + 1], x[w + 2], x[w + 3], g) && + f > (r = qt(e, t, x[w], x[w + 1], x[w + 2], x[w + 3])) + ) + return (v(n, r), !0); + } else if ( + "bezier" === a.edgeType || + "multibezier" === a.edgeType || + "self" === a.edgeType || + "compound" === a.edgeType + ) + for (x = a.allpts, w = 0; w + 5 < a.allpts.length; w += 4) + if ( + Ft( + e, + t, + x[w], + x[w + 1], + x[w + 2], + x[w + 3], + x[w + 4], + x[w + 5], + g, + ) && + f > + (r = jt( + e, + t, + x[w], + x[w + 1], + x[w + 2], + x[w + 3], + x[w + 4], + x[w + 5], + )) + ) + return (v(n, r), !0); + ((m = m || i.source), (b = b || i.target)); + var E = o.getArrowWidth(l, c), + k = [ + { + name: "source", + x: a.arrowStartX, + y: a.arrowStartY, + angle: a.srcArrowAngle, + }, + { + name: "target", + x: a.arrowEndX, + y: a.arrowEndY, + angle: a.tgtArrowAngle, + }, + { + name: "mid-source", + x: a.midX, + y: a.midY, + angle: a.midsrcArrowAngle, + }, + { + name: "mid-target", + x: a.midX, + y: a.midY, + angle: a.midtgtArrowAngle, + }, + ]; + for (w = 0; w < k.length; w++) { + var C = k[w], + S = s.arrowShapes[n.pstyle(C.name + "-arrow-shape").value], + P = n.pstyle("width").pfValue; + if ( + S.roughCollide(e, t, E, C.angle, { x: C.x, y: C.y }, P, h) && + S.collide(e, t, E, C.angle, { x: C.x, y: C.y }, P, h) + ) + return (v(n), !0); + } + d && u.length > 0 && (y(m), y(b)); + } + function b(e, t, n) { + return Ue(e, t, n); + } + function x(n, r) { + var i, + a = n._private, + o = f; + ((i = r ? r + "-" : ""), n.boundingBox()); + var s = a.labelBounds[r || "main"], + l = n.pstyle(i + "label").value; + if ("yes" === n.pstyle("text-events").strValue && l) { + var u = b(a.rscratch, "labelX", r), + c = b(a.rscratch, "labelY", r), + d = b(a.rscratch, "labelAngle", r), + h = n.pstyle(i + "text-margin-x").pfValue, + p = n.pstyle(i + "text-margin-y").pfValue, + g = s.x1 - o - h, + y = s.x2 + o - h, + m = s.y1 - o - p, + x = s.y2 + o - p; + if (d) { + var w = Math.cos(d), + E = Math.sin(d), + k = function (e, t) { + return { + x: (e -= u) * w - (t -= c) * E + u, + y: e * E + t * w + c, + }; + }, + C = k(g, m), + S = k(g, x), + P = k(y, m), + D = k(y, x), + T = [ + C.x + h, + C.y + p, + P.x + h, + P.y + p, + D.x + h, + D.y + p, + S.x + h, + S.y + p, + ]; + if (Yt(e, t, T)) return (v(n), !0); + } else if (Lt(s, e, t)) return (v(n), !0); + } + } + n && (l = l.interactive); + for (var w = l.length - 1; w >= 0; w--) { + var E = l[w]; + E.isNode() + ? y(E) || x(E) + : m(E) || x(E) || x(E, "source") || x(E, "target"); + } + return u; + }, + getAllInBox: function (e, t, n, r) { + for ( + var i, + a, + o = this.getCachedZSortedEles().interactive, + s = [], + l = Math.min(e, n), + u = Math.max(e, n), + c = Math.min(t, r), + d = Math.max(t, r), + h = _t({ x1: (e = l), y1: (t = c), x2: (n = u), y2: (r = d) }), + p = 0; + p < o.length; + p++ + ) { + var f = o[p]; + if (f.isNode()) { + var g = f, + v = g.boundingBox({ + includeNodes: !0, + includeEdges: !1, + includeLabels: !1, + }); + At(h, v) && !Ot(v, h) && s.push(g); + } else { + var y = f, + m = y._private, + b = m.rscratch; + if ( + null != b.startX && + null != b.startY && + !Lt(h, b.startX, b.startY) + ) + continue; + if (null != b.endX && null != b.endY && !Lt(h, b.endX, b.endY)) + continue; + if ( + "bezier" === b.edgeType || + "multibezier" === b.edgeType || + "self" === b.edgeType || + "compound" === b.edgeType || + "segments" === b.edgeType || + "haystack" === b.edgeType + ) { + for ( + var x = + m.rstyle.bezierPts || + m.rstyle.linePts || + m.rstyle.haystackPts, + w = !0, + E = 0; + E < x.length; + E++ + ) + if (((i = h), (a = x[E]), !Lt(i, a.x, a.y))) { + w = !1; + break; + } + w && s.push(y); + } else + ("haystack" !== b.edgeType && "straight" !== b.edgeType) || + s.push(y); + } + } + return s; + }, + }, + Ml = { + calculateArrowAngles: function (e) { + var t, + n, + r, + i, + a, + o, + s = e._private.rscratch, + l = "haystack" === s.edgeType, + u = "bezier" === s.edgeType, + c = "multibezier" === s.edgeType, + d = "segments" === s.edgeType, + h = "compound" === s.edgeType, + p = "self" === s.edgeType; + if ( + (l + ? ((r = s.haystackPts[0]), + (i = s.haystackPts[1]), + (a = s.haystackPts[2]), + (o = s.haystackPts[3])) + : ((r = s.arrowStartX), + (i = s.arrowStartY), + (a = s.arrowEndX), + (o = s.arrowEndY)), + (g = s.midX), + (v = s.midY), + d) + ) + ((t = r - s.segpts[0]), (n = i - s.segpts[1])); + else if (c || h || p || u) { + var f = s.allpts; + ((t = r - Pt(f[0], f[2], f[4], 0.1)), + (n = i - Pt(f[1], f[3], f[5], 0.1))); + } else ((t = r - g), (n = i - v)); + s.srcArrowAngle = xt(t, n); + var g = s.midX, + v = s.midY; + if ( + (l && ((g = (r + a) / 2), (v = (i + o) / 2)), + (t = a - r), + (n = o - i), + d) + ) + if (((f = s.allpts).length / 2) % 2 == 0) { + var y = (S = f.length / 2) - 2; + ((t = f[S] - f[y]), (n = f[S + 1] - f[y + 1])); + } else if (s.isRound) ((t = s.midVector[1]), (n = -s.midVector[0])); + else { + y = (S = f.length / 2 - 1) - 2; + ((t = f[S] - f[y]), (n = f[S + 1] - f[y + 1])); + } + else if (c || h || p) { + var m, + b, + x, + w, + f = s.allpts; + if ((s.ctrlpts.length / 2) % 2 == 0) { + var E = (k = (C = f.length / 2 - 1) + 2) + 2; + ((m = Pt(f[C], f[k], f[E], 0)), + (b = Pt(f[C + 1], f[k + 1], f[E + 1], 0)), + (x = Pt(f[C], f[k], f[E], 1e-4)), + (w = Pt(f[C + 1], f[k + 1], f[E + 1], 1e-4))); + } else { + var k, C; + E = (k = f.length / 2 - 1) + 2; + ((m = Pt(f[(C = k - 2)], f[k], f[E], 0.4999)), + (b = Pt(f[C + 1], f[k + 1], f[E + 1], 0.4999)), + (x = Pt(f[C], f[k], f[E], 0.5)), + (w = Pt(f[C + 1], f[k + 1], f[E + 1], 0.5))); + } + ((t = x - m), (n = w - b)); + } + if ( + ((s.midtgtArrowAngle = xt(t, n)), + (s.midDispX = t), + (s.midDispY = n), + (t *= -1), + (n *= -1), + d) + ) + if (((f = s.allpts).length / 2) % 2 == 0); + else if (!s.isRound) { + var S, + P = (S = f.length / 2 - 1) + 2; + ((t = -(f[P] - f[S])), (n = -(f[P + 1] - f[S + 1]))); + } + if (((s.midsrcArrowAngle = xt(t, n)), d)) + ((t = a - s.segpts[s.segpts.length - 2]), + (n = o - s.segpts[s.segpts.length - 1])); + else if (c || h || p || u) { + var D = (f = s.allpts).length; + ((t = a - Pt(f[D - 6], f[D - 4], f[D - 2], 0.9)), + (n = o - Pt(f[D - 5], f[D - 3], f[D - 1], 0.9))); + } else ((t = a - g), (n = o - v)); + s.tgtArrowAngle = xt(t, n); + }, + }; + Ml.getArrowWidth = Ml.getArrowHeight = function (e, t) { + var n = (this.arrowWidthCache = this.arrowWidthCache || {}), + r = n[e + ", " + t]; + return ( + r || + ((r = Math.max(Math.pow(13.37 * e, 0.9), 29) * t), + (n[e + ", " + t] = r), + r) + ); + }; + var Bl, + Nl, + zl, + Il, + Al, + Ll, + Ol, + Rl, + Vl, + Fl, + jl, + ql, + Yl, + Xl, + Wl, + Hl, + Kl, + Gl = {}, + Ul = {}, + Zl = function (e, t, n) { + ((n.x = t.x - e.x), + (n.y = t.y - e.y), + (n.len = Math.sqrt(n.x * n.x + n.y * n.y)), + (n.nx = n.x / n.len), + (n.ny = n.y / n.len), + (n.ang = Math.atan2(n.ny, n.nx))); + }, + $l = function (e, t, n, r, i) { + var a, o; + if ( + (e !== Kl + ? Zl(t, e, Gl) + : (((o = Gl).x = -1 * (a = Ul).x), + (o.y = -1 * a.y), + (o.nx = -1 * a.nx), + (o.ny = -1 * a.ny), + (o.ang = a.ang > 0 ? -(Math.PI - a.ang) : Math.PI + a.ang)), + Zl(t, n, Ul), + (zl = Gl.nx * Ul.ny - Gl.ny * Ul.nx), + (Il = Gl.nx * Ul.nx - Gl.ny * -Ul.ny), + (Ol = Math.asin(Math.max(-1, Math.min(1, zl)))), + Math.abs(Ol) < 1e-6) + ) + return ((Bl = t.x), (Nl = t.y), void (Vl = jl = 0)); + ((Al = 1), + (Ll = !1), + Il < 0 + ? Ol < 0 + ? (Ol = Math.PI + Ol) + : ((Ol = Math.PI - Ol), (Al = -1), (Ll = !0)) + : Ol > 0 && ((Al = -1), (Ll = !0)), + (jl = void 0 !== t.radius ? t.radius : r), + (Rl = Ol / 2), + (ql = Math.min(Gl.len / 2, Ul.len / 2)), + i + ? (Fl = Math.abs((Math.cos(Rl) * jl) / Math.sin(Rl))) > ql + ? ((Fl = ql), (Vl = Math.abs((Fl * Math.sin(Rl)) / Math.cos(Rl)))) + : (Vl = jl) + : ((Fl = Math.min(ql, jl)), + (Vl = Math.abs((Fl * Math.sin(Rl)) / Math.cos(Rl)))), + (Wl = t.x + Ul.nx * Fl), + (Hl = t.y + Ul.ny * Fl), + (Bl = Wl - Ul.ny * Vl * Al), + (Nl = Hl + Ul.nx * Vl * Al), + (Yl = t.x + Gl.nx * Fl), + (Xl = t.y + Gl.ny * Fl), + (Kl = t)); + }; + function Ql(e, t) { + 0 === t.radius + ? e.lineTo(t.cx, t.cy) + : e.arc( + t.cx, + t.cy, + t.radius, + t.startAngle, + t.endAngle, + t.counterClockwise, + ); + } + function Jl(e, t, n, r) { + var i = !(arguments.length > 4 && void 0 !== arguments[4]) || arguments[4]; + return 0 === r || 0 === t.radius + ? { + cx: t.x, + cy: t.y, + radius: 0, + startX: t.x, + startY: t.y, + stopX: t.x, + stopY: t.y, + startAngle: void 0, + endAngle: void 0, + counterClockwise: void 0, + } + : ($l(e, t, n, r, i), + { + cx: Bl, + cy: Nl, + radius: Vl, + startX: Yl, + startY: Xl, + stopX: Wl, + stopY: Hl, + startAngle: Gl.ang + (Math.PI / 2) * Al, + endAngle: Ul.ang - (Math.PI / 2) * Al, + counterClockwise: Ll, + }); + } + var eu = {}; + function tu(e) { + var t = []; + if (null != e) { + for (var n = 0; n < e.length; n += 2) { + var r = e[n], + i = e[n + 1]; + t.push({ x: r, y: i }); + } + return t; + } + } + ((eu.findMidptPtsEtc = function (e, t) { + var n, + r = t.posPts, + i = t.intersectionPts, + o = t.vectorNormInverse, + s = e.pstyle("source-endpoint"), + l = e.pstyle("target-endpoint"), + u = null != s.units && null != l.units; + switch (e.pstyle("edge-distances").value) { + case "node-position": + n = r; + break; + case "intersection": + n = i; + break; + case "endpoints": + if (u) { + var c = a(this.manualEndptToPx(e.source()[0], s), 2), + d = c[0], + h = c[1], + p = a(this.manualEndptToPx(e.target()[0], l), 2), + f = p[0], + g = p[1], + v = { x1: d, y1: h, x2: f, y2: g }; + ((o = (function (e, t, n, r) { + var i = r - t, + a = n - e, + o = Math.sqrt(a * a + i * i); + return { x: -i / o, y: a / o }; + })(d, h, f, g)), + (n = v)); + } else + (je( + "Edge ".concat( + e.id(), + " has edge-distances:endpoints specified without manual endpoints specified via source-endpoint and target-endpoint. Falling back on edge-distances:intersection (default).", + ), + ), + (n = i)); + } + return { midptPts: n, vectorNormInverse: o }; + }), + (eu.findHaystackPoints = function (e) { + for (var t = 0; t < e.length; t++) { + var n = e[t], + r = n._private, + i = r.rscratch; + if (!i.haystack) { + var a = 2 * Math.random() * Math.PI; + ((i.source = { x: Math.cos(a), y: Math.sin(a) }), + (a = 2 * Math.random() * Math.PI), + (i.target = { x: Math.cos(a), y: Math.sin(a) })); + } + var o = r.source, + s = r.target, + l = o.position(), + u = s.position(), + c = o.width(), + d = s.width(), + h = o.height(), + p = s.height(), + f = n.pstyle("haystack-radius").value / 2; + ((i.haystackPts = i.allpts = + [ + i.source.x * c * f + l.x, + i.source.y * h * f + l.y, + i.target.x * d * f + u.x, + i.target.y * p * f + u.y, + ]), + (i.midX = (i.allpts[0] + i.allpts[2]) / 2), + (i.midY = (i.allpts[1] + i.allpts[3]) / 2), + (i.edgeType = "haystack"), + (i.haystack = !0), + this.storeEdgeProjections(n), + this.calculateArrowAngles(n), + this.recalculateEdgeLabelProjections(n), + this.calculateLabelAngles(n)); + } + }), + (eu.findSegmentsPoints = function (e, t) { + var n = e._private.rscratch, + r = e.pstyle("segment-weights"), + i = e.pstyle("segment-distances"), + a = e.pstyle("segment-radii"), + o = e.pstyle("radius-type"), + s = Math.min(r.pfValue.length, i.pfValue.length), + l = a.pfValue[a.pfValue.length - 1], + u = o.pfValue[o.pfValue.length - 1]; + ((n.edgeType = "segments"), + (n.segpts = []), + (n.radii = []), + (n.isArcRadius = [])); + for (var c = 0; c < s; c++) { + var d = r.pfValue[c], + h = i.pfValue[c], + p = 1 - d, + f = d, + g = this.findMidptPtsEtc(e, t), + v = g.midptPts, + y = g.vectorNormInverse, + m = { x: v.x1 * p + v.x2 * f, y: v.y1 * p + v.y2 * f }; + (n.segpts.push(m.x + y.x * h, m.y + y.y * h), + n.radii.push(void 0 !== a.pfValue[c] ? a.pfValue[c] : l), + n.isArcRadius.push( + "arc-radius" === (void 0 !== o.pfValue[c] ? o.pfValue[c] : u), + )); + } + }), + (eu.findLoopPoints = function (e, t, n, r) { + var i = e._private.rscratch, + a = t.dirCounts, + o = t.srcPos, + s = e.pstyle("control-point-distances"), + l = s ? s.pfValue[0] : void 0, + u = e.pstyle("loop-direction").pfValue, + c = e.pstyle("loop-sweep").pfValue, + d = e.pstyle("control-point-step-size").pfValue; + i.edgeType = "self"; + var h = n, + p = d; + r && ((h = 0), (p = l)); + var f = u - Math.PI / 2, + g = f - c / 2, + v = f + c / 2, + y = String(u + "_" + c); + ((h = void 0 === a[y] ? (a[y] = 0) : ++a[y]), + (i.ctrlpts = [ + o.x + 1.4 * Math.cos(g) * p * (h / 3 + 1), + o.y + 1.4 * Math.sin(g) * p * (h / 3 + 1), + o.x + 1.4 * Math.cos(v) * p * (h / 3 + 1), + o.y + 1.4 * Math.sin(v) * p * (h / 3 + 1), + ])); + }), + (eu.findCompoundLoopPoints = function (e, t, n, r) { + var i = e._private.rscratch; + i.edgeType = "compound"; + var a = t.srcPos, + o = t.tgtPos, + s = t.srcW, + l = t.srcH, + u = t.tgtW, + c = t.tgtH, + d = e.pstyle("control-point-step-size").pfValue, + h = e.pstyle("control-point-distances"), + p = h ? h.pfValue[0] : void 0, + f = n, + g = d; + r && ((f = 0), (g = p)); + var v = { x: a.x - s / 2, y: a.y - l / 2 }, + y = { x: o.x - u / 2, y: o.y - c / 2 }, + m = { x: Math.min(v.x, y.x), y: Math.min(v.y, y.y) }, + b = Math.max(0.5, Math.log(0.01 * s)), + x = Math.max(0.5, Math.log(0.01 * u)); + i.ctrlpts = [ + m.x, + m.y - (1 + Math.pow(50, 1.12) / 100) * g * (f / 3 + 1) * b, + m.x - (1 + Math.pow(50, 1.12) / 100) * g * (f / 3 + 1) * x, + m.y, + ]; + }), + (eu.findStraightEdgePoints = function (e) { + e._private.rscratch.edgeType = "straight"; + }), + (eu.findBezierPoints = function (e, t, n, r, i) { + var a = e._private.rscratch, + o = e.pstyle("control-point-step-size").pfValue, + s = e.pstyle("control-point-distances"), + l = e.pstyle("control-point-weights"), + u = s && l ? Math.min(s.value.length, l.value.length) : 1, + c = s ? s.pfValue[0] : void 0, + d = l.value[0], + h = r; + ((a.edgeType = h ? "multibezier" : "bezier"), (a.ctrlpts = [])); + for (var p = 0; p < u; p++) { + var f = (0.5 - t.eles.length / 2 + n) * o * (i ? -1 : 1), + g = void 0, + v = Et(f); + h && ((c = s ? s.pfValue[p] : o), (d = l.value[p])); + var y = void 0 !== (g = r ? c : void 0 !== c ? v * c : void 0) ? g : f, + m = 1 - d, + b = d, + x = this.findMidptPtsEtc(e, t), + w = x.midptPts, + E = x.vectorNormInverse, + k = { x: w.x1 * m + w.x2 * b, y: w.y1 * m + w.y2 * b }; + a.ctrlpts.push(k.x + E.x * y, k.y + E.y * y); + } + }), + (eu.findTaxiPoints = function (e, t) { + var n = e._private.rscratch; + n.edgeType = "segments"; + var r = t.posPts, + i = t.srcW, + a = t.srcH, + o = t.tgtW, + s = t.tgtH, + l = "node-position" !== e.pstyle("edge-distances").value, + u = e.pstyle("taxi-direction").value, + c = u, + d = e.pstyle("taxi-turn"), + h = "%" === d.units, + p = d.pfValue, + f = p < 0, + g = e.pstyle("taxi-turn-min-distance").pfValue, + v = l ? (i + o) / 2 : 0, + y = l ? (a + s) / 2 : 0, + m = r.x2 - r.x1, + b = r.y2 - r.y1, + x = function (e, t) { + return e > 0 ? Math.max(e - t, 0) : Math.min(e + t, 0); + }, + w = x(m, v), + E = x(b, y), + k = !1; + "auto" === c + ? (u = Math.abs(w) > Math.abs(E) ? "horizontal" : "vertical") + : "upward" === c || "downward" === c + ? ((u = "vertical"), (k = !0)) + : ("leftward" !== c && "rightward" !== c) || + ((u = "horizontal"), (k = !0)); + var C, + S = "vertical" === u, + P = S ? E : w, + D = S ? b : m, + T = Et(D), + _ = !1; + ((k && (h || f)) || + !( + ("downward" === c && D < 0) || + ("upward" === c && D > 0) || + ("leftward" === c && D > 0) || + ("rightward" === c && D < 0) + ) || + ((P = (T *= -1) * Math.abs(P)), (_ = !0)), + h) + ? (C = (p < 0 ? 1 + p : p) * P) + : (C = (p < 0 ? P : 0) + p * T); + var M = function (e) { + return Math.abs(e) < g || Math.abs(e) >= Math.abs(P); + }, + B = M(C), + N = M(Math.abs(P) - Math.abs(C)); + if ((B || N) && !_) + if (S) { + var z = Math.abs(D) <= a / 2, + I = Math.abs(m) <= o / 2; + if (z) { + var A = (r.x1 + r.x2) / 2, + L = r.y1, + O = r.y2; + n.segpts = [A, L, A, O]; + } else if (I) { + var R = (r.y1 + r.y2) / 2, + V = r.x1, + F = r.x2; + n.segpts = [V, R, F, R]; + } else n.segpts = [r.x1, r.y2]; + } else { + var j = Math.abs(D) <= i / 2, + q = Math.abs(b) <= s / 2; + if (j) { + var Y = (r.y1 + r.y2) / 2, + X = r.x1, + W = r.x2; + n.segpts = [X, Y, W, Y]; + } else if (q) { + var H = (r.x1 + r.x2) / 2, + K = r.y1, + G = r.y2; + n.segpts = [H, K, H, G]; + } else n.segpts = [r.x2, r.y1]; + } + else if (S) { + var U = r.y1 + C + (l ? (a / 2) * T : 0), + Z = r.x1, + $ = r.x2; + n.segpts = [Z, U, $, U]; + } else { + var Q = r.x1 + C + (l ? (i / 2) * T : 0), + J = r.y1, + ee = r.y2; + n.segpts = [Q, J, Q, ee]; + } + if (n.isRound) { + var te = e.pstyle("taxi-radius").value, + ne = "arc-radius" === e.pstyle("radius-type").value[0]; + ((n.radii = new Array(n.segpts.length / 2).fill(te)), + (n.isArcRadius = new Array(n.segpts.length / 2).fill(ne))); + } + }), + (eu.tryToCorrectInvalidPoints = function (e, t) { + var n = e._private.rscratch; + if ("bezier" === n.edgeType) { + var r = t.srcPos, + i = t.tgtPos, + a = t.srcW, + o = t.srcH, + s = t.tgtW, + l = t.tgtH, + u = t.srcShape, + c = t.tgtShape, + d = t.srcCornerRadius, + h = t.tgtCornerRadius, + p = t.srcRs, + f = t.tgtRs, + g = !x(n.startX) || !x(n.startY), + v = !x(n.arrowStartX) || !x(n.arrowStartY), + y = !x(n.endX) || !x(n.endY), + m = !x(n.arrowEndX) || !x(n.arrowEndY), + b = + 3 * + (this.getArrowWidth( + e.pstyle("width").pfValue, + e.pstyle("arrow-scale").value, + ) * + this.arrowShapeWidth), + w = kt( + { x: n.ctrlpts[0], y: n.ctrlpts[1] }, + { x: n.startX, y: n.startY }, + ), + E = w < b, + k = kt( + { x: n.ctrlpts[0], y: n.ctrlpts[1] }, + { x: n.endX, y: n.endY }, + ), + C = k < b, + S = !1; + if (g || v || E) { + S = !0; + var P = { x: n.ctrlpts[0] - r.x, y: n.ctrlpts[1] - r.y }, + D = Math.sqrt(P.x * P.x + P.y * P.y), + T = { x: P.x / D, y: P.y / D }, + _ = Math.max(a, o), + M = { + x: n.ctrlpts[0] + 2 * T.x * _, + y: n.ctrlpts[1] + 2 * T.y * _, + }, + B = u.intersectLine(r.x, r.y, a, o, M.x, M.y, 0, d, p); + E + ? ((n.ctrlpts[0] = n.ctrlpts[0] + T.x * (b - w)), + (n.ctrlpts[1] = n.ctrlpts[1] + T.y * (b - w))) + : ((n.ctrlpts[0] = B[0] + T.x * b), + (n.ctrlpts[1] = B[1] + T.y * b)); + } + if (y || m || C) { + S = !0; + var N = { x: n.ctrlpts[0] - i.x, y: n.ctrlpts[1] - i.y }, + z = Math.sqrt(N.x * N.x + N.y * N.y), + I = { x: N.x / z, y: N.y / z }, + A = Math.max(a, o), + L = { + x: n.ctrlpts[0] + 2 * I.x * A, + y: n.ctrlpts[1] + 2 * I.y * A, + }, + O = c.intersectLine(i.x, i.y, s, l, L.x, L.y, 0, h, f); + C + ? ((n.ctrlpts[0] = n.ctrlpts[0] + I.x * (b - k)), + (n.ctrlpts[1] = n.ctrlpts[1] + I.y * (b - k))) + : ((n.ctrlpts[0] = O[0] + I.x * b), + (n.ctrlpts[1] = O[1] + I.y * b)); + } + S && this.findEndpoints(e); + } + }), + (eu.storeAllpts = function (e) { + var t = e._private.rscratch; + if ( + "multibezier" === t.edgeType || + "bezier" === t.edgeType || + "self" === t.edgeType || + "compound" === t.edgeType + ) { + ((t.allpts = []), t.allpts.push(t.startX, t.startY)); + for (var n = 0; n + 1 < t.ctrlpts.length; n += 2) + (t.allpts.push(t.ctrlpts[n], t.ctrlpts[n + 1]), + n + 3 < t.ctrlpts.length && + t.allpts.push( + (t.ctrlpts[n] + t.ctrlpts[n + 2]) / 2, + (t.ctrlpts[n + 1] + t.ctrlpts[n + 3]) / 2, + )); + var r; + (t.allpts.push(t.endX, t.endY), + (t.ctrlpts.length / 2) % 2 == 0 + ? ((r = t.allpts.length / 2 - 1), + (t.midX = t.allpts[r]), + (t.midY = t.allpts[r + 1])) + : ((r = t.allpts.length / 2 - 3), + 0.5, + (t.midX = Pt(t.allpts[r], t.allpts[r + 2], t.allpts[r + 4], 0.5)), + (t.midY = Pt( + t.allpts[r + 1], + t.allpts[r + 3], + t.allpts[r + 5], + 0.5, + )))); + } else if ("straight" === t.edgeType) + ((t.allpts = [t.startX, t.startY, t.endX, t.endY]), + (t.midX = (t.startX + t.endX + t.arrowStartX + t.arrowEndX) / 4), + (t.midY = (t.startY + t.endY + t.arrowStartY + t.arrowEndY) / 4)); + else if ("segments" === t.edgeType) { + if ( + ((t.allpts = []), + t.allpts.push(t.startX, t.startY), + t.allpts.push.apply(t.allpts, t.segpts), + t.allpts.push(t.endX, t.endY), + t.isRound) + ) { + t.roundCorners = []; + for (var i = 2; i + 3 < t.allpts.length; i += 2) { + var a = t.radii[i / 2 - 1], + o = t.isArcRadius[i / 2 - 1]; + t.roundCorners.push( + Jl( + { x: t.allpts[i - 2], y: t.allpts[i - 1] }, + { x: t.allpts[i], y: t.allpts[i + 1], radius: a }, + { x: t.allpts[i + 2], y: t.allpts[i + 3] }, + a, + o, + ), + ); + } + } + if (t.segpts.length % 4 == 0) { + var s = t.segpts.length / 2, + l = s - 2; + ((t.midX = (t.segpts[l] + t.segpts[s]) / 2), + (t.midY = (t.segpts[l + 1] + t.segpts[s + 1]) / 2)); + } else { + var u = t.segpts.length / 2 - 1; + if (t.isRound) { + var c = { x: t.segpts[u], y: t.segpts[u + 1] }, + d = t.roundCorners[u / 2], + h = [c.x - d.cx, c.y - d.cy], + p = d.radius / Math.sqrt(Math.pow(h[0], 2) + Math.pow(h[1], 2)); + ((h = h.map(function (e) { + return e * p; + })), + (t.midX = d.cx + h[0]), + (t.midY = d.cy + h[1]), + (t.midVector = h)); + } else ((t.midX = t.segpts[u]), (t.midY = t.segpts[u + 1])); + } + } + }), + (eu.checkForInvalidEdgeWarning = function (e) { + var t = e[0]._private.rscratch; + t.nodesOverlap || (x(t.startX) && x(t.startY) && x(t.endX) && x(t.endY)) + ? (t.loggedErr = !1) + : t.loggedErr || + ((t.loggedErr = !0), + je( + "Edge `" + + e.id() + + "` has invalid endpoints and so it is impossible to draw. Adjust your edge style (e.g. control points) accordingly or use an alternative edge type. This is expected behaviour when the source node and the target node overlap.", + )); + }), + (eu.findEdgeControlPoints = function (e) { + var t = this; + if (e && 0 !== e.length) { + for ( + var n = this, + r = n.cy.hasCompoundNodes(), + i = { + map: new $e(), + get: function (e) { + var t = this.map.get(e[0]); + return null != t ? t.get(e[1]) : null; + }, + set: function (e, t) { + var n = this.map.get(e[0]); + (null == n && ((n = new $e()), this.map.set(e[0], n)), + n.set(e[1], t)); + }, + }, + a = [], + o = [], + s = 0; + s < e.length; + s++ + ) { + var l = e[s], + u = l._private, + c = l.pstyle("curve-style").value; + if (!l.removed() && l.takesUpSpace()) + if ("haystack" !== c) { + var d = + "unbundled-bezier" === c || + c.endsWith("segments") || + "straight" === c || + "straight-triangle" === c || + c.endsWith("taxi"), + h = "unbundled-bezier" === c || "bezier" === c, + p = u.source, + f = u.target, + g = [p.poolIndex(), f.poolIndex()].sort(), + v = i.get(g); + (null == v && ((v = { eles: [] }), i.set(g, v), a.push(g)), + v.eles.push(l), + d && (v.hasUnbundled = !0), + h && (v.hasBezier = !0)); + } else o.push(l); + } + for ( + var y = function (e) { + var o = a[e], + s = i.get(o), + l = void 0; + if (!s.hasUnbundled) { + var u = s.eles[0].parallelEdges().filter(function (e) { + return e.isBundledBezier(); + }); + (Ge(s.eles), + u.forEach(function (e) { + return s.eles.push(e); + }), + s.eles.sort(function (e, t) { + return e.poolIndex() - t.poolIndex(); + })); + } + var c = s.eles[0], + d = c.source(), + h = c.target(); + if (d.poolIndex() > h.poolIndex()) { + var p = d; + ((d = h), (h = p)); + } + var f = (s.srcPos = d.position()), + g = (s.tgtPos = h.position()), + v = (s.srcW = d.outerWidth()), + y = (s.srcH = d.outerHeight()), + m = (s.tgtW = h.outerWidth()), + b = (s.tgtH = h.outerHeight()), + w = (s.srcShape = n.nodeShapes[t.getNodeShape(d)]), + E = (s.tgtShape = n.nodeShapes[t.getNodeShape(h)]), + k = (s.srcCornerRadius = + "auto" === d.pstyle("corner-radius").value + ? "auto" + : d.pstyle("corner-radius").pfValue), + C = (s.tgtCornerRadius = + "auto" === h.pstyle("corner-radius").value + ? "auto" + : h.pstyle("corner-radius").pfValue), + S = (s.tgtRs = h._private.rscratch), + P = (s.srcRs = d._private.rscratch); + s.dirCounts = { + north: 0, + west: 0, + south: 0, + east: 0, + northwest: 0, + southwest: 0, + northeast: 0, + southeast: 0, + }; + for (var D = 0; D < s.eles.length; D++) { + var T = s.eles[D], + _ = T[0]._private.rscratch, + M = T.pstyle("curve-style").value, + B = + "unbundled-bezier" === M || + M.endsWith("segments") || + M.endsWith("taxi"), + N = !d.same(T.source()); + if ( + !s.calculatedIntersection && + d !== h && + (s.hasBezier || s.hasUnbundled) + ) { + s.calculatedIntersection = !0; + var z = w.intersectLine(f.x, f.y, v, y, g.x, g.y, 0, k, P), + I = (s.srcIntn = z), + A = E.intersectLine(g.x, g.y, m, b, f.x, f.y, 0, C, S), + L = (s.tgtIntn = A), + O = (s.intersectionPts = { + x1: z[0], + x2: A[0], + y1: z[1], + y2: A[1], + }), + R = (s.posPts = { x1: f.x, x2: g.x, y1: f.y, y2: g.y }), + V = A[1] - z[1], + F = A[0] - z[0], + j = Math.sqrt(F * F + V * V), + q = (s.vector = { x: F, y: V }), + Y = (s.vectorNorm = { x: q.x / j, y: q.y / j }), + X = { x: -Y.y, y: Y.x }; + ((s.nodesOverlap = + !x(j) || + E.checkPoint(z[0], z[1], 0, m, b, g.x, g.y, C, S) || + w.checkPoint(A[0], A[1], 0, v, y, f.x, f.y, k, P)), + (s.vectorNormInverse = X), + (l = { + nodesOverlap: s.nodesOverlap, + dirCounts: s.dirCounts, + calculatedIntersection: !0, + hasBezier: s.hasBezier, + hasUnbundled: s.hasUnbundled, + eles: s.eles, + srcPos: g, + tgtPos: f, + srcW: m, + srcH: b, + tgtW: v, + tgtH: y, + srcIntn: L, + tgtIntn: I, + srcShape: E, + tgtShape: w, + posPts: { x1: R.x2, y1: R.y2, x2: R.x1, y2: R.y1 }, + intersectionPts: { + x1: O.x2, + y1: O.y2, + x2: O.x1, + y2: O.y1, + }, + vector: { x: -q.x, y: -q.y }, + vectorNorm: { x: -Y.x, y: -Y.y }, + vectorNormInverse: { x: -X.x, y: -X.y }, + })); + } + var W = N ? l : s; + ((_.nodesOverlap = W.nodesOverlap), + (_.srcIntn = W.srcIntn), + (_.tgtIntn = W.tgtIntn), + (_.isRound = M.startsWith("round")), + r && + (d.isParent() || + d.isChild() || + h.isParent() || + h.isChild()) && + (d.parents().anySame(h) || + h.parents().anySame(d) || + (d.same(h) && d.isParent())) + ? t.findCompoundLoopPoints(T, W, D, B) + : d === h + ? t.findLoopPoints(T, W, D, B) + : M.endsWith("segments") + ? t.findSegmentsPoints(T, W) + : M.endsWith("taxi") + ? t.findTaxiPoints(T, W) + : "straight" === M || + (!B && + s.eles.length % 2 == 1 && + D === Math.floor(s.eles.length / 2)) + ? t.findStraightEdgePoints(T) + : t.findBezierPoints(T, W, D, B, N), + t.findEndpoints(T), + t.tryToCorrectInvalidPoints(T, W), + t.checkForInvalidEdgeWarning(T), + t.storeAllpts(T), + t.storeEdgeProjections(T), + t.calculateArrowAngles(T), + t.recalculateEdgeLabelProjections(T), + t.calculateLabelAngles(T)); + } + }, + m = 0; + m < a.length; + m++ + ) + y(m); + this.findHaystackPoints(o); + } + }), + (eu.getSegmentPoints = function (e) { + var t = e[0]._private.rscratch; + if ("segments" === t.edgeType) + return (this.recalculateRenderedStyle(e), tu(t.segpts)); + }), + (eu.getControlPoints = function (e) { + var t = e[0]._private.rscratch, + n = t.edgeType; + if ( + "bezier" === n || + "multibezier" === n || + "self" === n || + "compound" === n + ) + return (this.recalculateRenderedStyle(e), tu(t.ctrlpts)); + }), + (eu.getEdgeMidpoint = function (e) { + var t = e[0]._private.rscratch; + return (this.recalculateRenderedStyle(e), { x: t.midX, y: t.midY }); + })); + var nu = { + manualEndptToPx: function (e, t) { + var n = e.position(), + r = e.outerWidth(), + i = e.outerHeight(), + a = e._private.rscratch; + if (2 === t.value.length) { + var o = [t.pfValue[0], t.pfValue[1]]; + return ( + "%" === t.units[0] && (o[0] = o[0] * r), + "%" === t.units[1] && (o[1] = o[1] * i), + (o[0] += n.x), + (o[1] += n.y), + o + ); + } + var s = t.pfValue[0]; + s = -Math.PI / 2 + s; + var l = 2 * Math.max(r, i), + u = [n.x + Math.cos(s) * l, n.y + Math.sin(s) * l]; + return this.nodeShapes[this.getNodeShape(e)].intersectLine( + n.x, + n.y, + r, + i, + u[0], + u[1], + 0, + "auto" === e.pstyle("corner-radius").value + ? "auto" + : e.pstyle("corner-radius").pfValue, + a, + ); + }, + findEndpoints: function (e) { + var t, + n, + r, + i, + a, + o = this, + s = e.source()[0], + l = e.target()[0], + u = s.position(), + c = l.position(), + d = e.pstyle("target-arrow-shape").value, + h = e.pstyle("source-arrow-shape").value, + p = e.pstyle("target-distance-from-node").pfValue, + f = e.pstyle("source-distance-from-node").pfValue, + g = s._private.rscratch, + v = l._private.rscratch, + y = e.pstyle("curve-style").value, + m = e._private.rscratch, + b = m.edgeType, + w = "self" === b || "compound" === b, + E = "bezier" === b || "multibezier" === b || w, + k = "bezier" !== b, + C = "straight" === b || "segments" === b, + S = "segments" === b, + P = E || k || C, + D = w || "taxi" === y, + T = e.pstyle("source-endpoint"), + _ = D ? "outside-to-node" : T.value, + M = + "auto" === s.pstyle("corner-radius").value + ? "auto" + : s.pstyle("corner-radius").pfValue, + B = e.pstyle("target-endpoint"), + N = D ? "outside-to-node" : B.value, + z = + "auto" === l.pstyle("corner-radius").value + ? "auto" + : l.pstyle("corner-radius").pfValue; + if (((m.srcManEndpt = T), (m.tgtManEndpt = B), E)) { + var I = [m.ctrlpts[0], m.ctrlpts[1]]; + ((n = k + ? [m.ctrlpts[m.ctrlpts.length - 2], m.ctrlpts[m.ctrlpts.length - 1]] + : I), + (r = I)); + } else if (C) { + var A = S ? m.segpts.slice(0, 2) : [c.x, c.y]; + ((n = S ? m.segpts.slice(m.segpts.length - 2) : [u.x, u.y]), (r = A)); + } + if ("inside-to-node" === N) t = [c.x, c.y]; + else if (B.units) t = this.manualEndptToPx(l, B); + else if ("outside-to-line" === N) t = m.tgtIntn; + else if ( + ("outside-to-node" === N || "outside-to-node-or-label" === N + ? (i = n) + : ("outside-to-line" !== N && "outside-to-line-or-label" !== N) || + (i = [u.x, u.y]), + (t = o.nodeShapes[this.getNodeShape(l)].intersectLine( + c.x, + c.y, + l.outerWidth(), + l.outerHeight(), + i[0], + i[1], + 0, + z, + v, + )), + "outside-to-node-or-label" === N || "outside-to-line-or-label" === N) + ) { + var L = l._private.rscratch, + O = L.labelWidth, + R = L.labelHeight, + V = L.labelX, + F = L.labelY, + j = O / 2, + q = R / 2, + Y = l.pstyle("text-valign").value; + "top" === Y ? (F -= q) : "bottom" === Y && (F += q); + var X = l.pstyle("text-halign").value; + "left" === X ? (V -= j) : "right" === X && (V += j); + var W = $t( + i[0], + i[1], + [V - j, F - q, V + j, F - q, V + j, F + q, V - j, F + q], + c.x, + c.y, + ); + if (W.length > 0) { + var H = u, + K = Ct(H, bt(t)), + G = Ct(H, bt(W)), + U = K; + if ((G < K && ((t = W), (U = G)), W.length > 2)) + Ct(H, { x: W[2], y: W[3] }) < U && (t = [W[2], W[3]]); + } + } + var Z = Qt(t, n, o.arrowShapes[d].spacing(e) + p), + $ = Qt(t, n, o.arrowShapes[d].gap(e) + p); + if ( + ((m.endX = $[0]), + (m.endY = $[1]), + (m.arrowEndX = Z[0]), + (m.arrowEndY = Z[1]), + "inside-to-node" === _) + ) + t = [u.x, u.y]; + else if (T.units) t = this.manualEndptToPx(s, T); + else if ("outside-to-line" === _) t = m.srcIntn; + else if ( + ("outside-to-node" === _ || "outside-to-node-or-label" === _ + ? (a = r) + : ("outside-to-line" !== _ && "outside-to-line-or-label" !== _) || + (a = [c.x, c.y]), + (t = o.nodeShapes[this.getNodeShape(s)].intersectLine( + u.x, + u.y, + s.outerWidth(), + s.outerHeight(), + a[0], + a[1], + 0, + M, + g, + )), + "outside-to-node-or-label" === _ || "outside-to-line-or-label" === _) + ) { + var Q = s._private.rscratch, + J = Q.labelWidth, + ee = Q.labelHeight, + te = Q.labelX, + ne = Q.labelY, + re = J / 2, + ie = ee / 2, + ae = s.pstyle("text-valign").value; + "top" === ae ? (ne -= ie) : "bottom" === ae && (ne += ie); + var oe = s.pstyle("text-halign").value; + "left" === oe ? (te -= re) : "right" === oe && (te += re); + var se = $t( + a[0], + a[1], + [ + te - re, + ne - ie, + te + re, + ne - ie, + te + re, + ne + ie, + te - re, + ne + ie, + ], + u.x, + u.y, + ); + if (se.length > 0) { + var le = c, + ue = Ct(le, bt(t)), + ce = Ct(le, bt(se)), + de = ue; + if ((ce < ue && ((t = [se[0], se[1]]), (de = ce)), se.length > 2)) + Ct(le, { x: se[2], y: se[3] }) < de && (t = [se[2], se[3]]); + } + } + var he = Qt(t, r, o.arrowShapes[h].spacing(e) + f), + pe = Qt(t, r, o.arrowShapes[h].gap(e) + f); + ((m.startX = pe[0]), + (m.startY = pe[1]), + (m.arrowStartX = he[0]), + (m.arrowStartY = he[1]), + P && + (x(m.startX) && x(m.startY) && x(m.endX) && x(m.endY) + ? (m.badLine = !1) + : (m.badLine = !0))); + }, + getSourceEndpoint: function (e) { + var t = e[0]._private.rscratch; + switch ((this.recalculateRenderedStyle(e), t.edgeType)) { + case "haystack": + return { x: t.haystackPts[0], y: t.haystackPts[1] }; + default: + return { x: t.arrowStartX, y: t.arrowStartY }; + } + }, + getTargetEndpoint: function (e) { + var t = e[0]._private.rscratch; + switch ((this.recalculateRenderedStyle(e), t.edgeType)) { + case "haystack": + return { x: t.haystackPts[2], y: t.haystackPts[3] }; + default: + return { x: t.arrowEndX, y: t.arrowEndY }; + } + }, + }, + ru = {}; + function iu(e, t, n) { + for ( + var r = function (e, t, n, r) { + return Pt(e, t, n, r); + }, + i = t._private.rstyle.bezierPts, + a = 0; + a < e.bezierProjPcts.length; + a++ + ) { + var o = e.bezierProjPcts[a]; + i.push({ x: r(n[0], n[2], n[4], o), y: r(n[1], n[3], n[5], o) }); + } + } + ((ru.storeEdgeProjections = function (e) { + var t = e._private, + n = t.rscratch, + r = n.edgeType; + if ( + ((t.rstyle.bezierPts = null), + (t.rstyle.linePts = null), + (t.rstyle.haystackPts = null), + "multibezier" === r || "bezier" === r || "self" === r || "compound" === r) + ) { + t.rstyle.bezierPts = []; + for (var i = 0; i + 5 < n.allpts.length; i += 4) + iu(this, e, n.allpts.slice(i, i + 6)); + } else if ("segments" === r) { + var a = (t.rstyle.linePts = []); + for (i = 0; i + 1 < n.allpts.length; i += 2) + a.push({ x: n.allpts[i], y: n.allpts[i + 1] }); + } else if ("haystack" === r) { + var o = n.haystackPts; + t.rstyle.haystackPts = [ + { x: o[0], y: o[1] }, + { x: o[2], y: o[3] }, + ]; + } + t.rstyle.arrowWidth = + this.getArrowWidth( + e.pstyle("width").pfValue, + e.pstyle("arrow-scale").value, + ) * this.arrowShapeWidth; + }), + (ru.recalculateEdgeProjections = function (e) { + this.findEdgeControlPoints(e); + })); + var au = { + recalculateNodeLabelProjection: function (e) { + var t = e.pstyle("label").strValue; + if (!D(t)) { + var n, + r, + i = e._private, + a = e.width(), + o = e.height(), + s = e.padding(), + l = e.position(), + u = e.pstyle("text-halign").strValue, + c = e.pstyle("text-valign").strValue, + d = i.rscratch, + h = i.rstyle; + switch (u) { + case "left": + n = l.x - a / 2 - s; + break; + case "right": + n = l.x + a / 2 + s; + break; + default: + n = l.x; + } + switch (c) { + case "top": + r = l.y - o / 2 - s; + break; + case "bottom": + r = l.y + o / 2 + s; + break; + default: + r = l.y; + } + ((d.labelX = n), + (d.labelY = r), + (h.labelX = n), + (h.labelY = r), + this.calculateLabelAngles(e), + this.applyLabelDimensions(e)); + } + }, + }, + ou = function (e, t) { + var n = Math.atan(t / e); + return (0 === e && n < 0 && (n *= -1), n); + }, + su = function (e, t) { + var n = t.x - e.x, + r = t.y - e.y; + return ou(n, r); + }; + ((au.recalculateEdgeLabelProjections = function (e) { + var t, + n = e._private, + r = n.rscratch, + i = this, + a = { + mid: e.pstyle("label").strValue, + source: e.pstyle("source-label").strValue, + target: e.pstyle("target-label").strValue, + }; + if (a.mid || a.source || a.target) { + t = { x: r.midX, y: r.midY }; + var o = function (e, t, r) { + (Ze(n.rscratch, e, t, r), Ze(n.rstyle, e, t, r)); + }; + (o("labelX", null, t.x), o("labelY", null, t.y)); + var s = ou(r.midDispX, r.midDispY); + o("labelAutoAngle", null, s); + var l = function (s) { + var l, + u = "source" === s; + if (a[s]) { + var c = e.pstyle(s + "-text-offset").pfValue; + switch (r.edgeType) { + case "self": + case "compound": + case "bezier": + case "multibezier": + for ( + var d, + h = (function e() { + if (e.cache) return e.cache; + for (var t = [], a = 0; a + 5 < r.allpts.length; a += 4) { + var o = { x: r.allpts[a], y: r.allpts[a + 1] }, + s = { x: r.allpts[a + 2], y: r.allpts[a + 3] }, + l = { x: r.allpts[a + 4], y: r.allpts[a + 5] }; + t.push({ + p0: o, + p1: s, + p2: l, + startDist: 0, + length: 0, + segments: [], + }); + } + var u = n.rstyle.bezierPts, + c = i.bezierProjPcts.length; + function d(e, t, n, r, i) { + var a = kt(t, n), + o = e.segments[e.segments.length - 1], + s = { + p0: t, + p1: n, + t0: r, + t1: i, + startDist: o ? o.startDist + o.length : 0, + length: a, + }; + (e.segments.push(s), (e.length += a)); + } + for (var h = 0; h < t.length; h++) { + var p = t[h], + f = t[h - 1]; + (f && (p.startDist = f.startDist + f.length), + d(p, p.p0, u[h * c], 0, i.bezierProjPcts[0])); + for (var g = 0; g < c - 1; g++) + d( + p, + u[h * c + g], + u[h * c + g + 1], + i.bezierProjPcts[g], + i.bezierProjPcts[g + 1], + ); + d(p, u[h * c + c - 1], p.p2, i.bezierProjPcts[c - 1], 1); + } + return (e.cache = t); + })(), + p = 0, + f = 0, + g = 0; + g < h.length; + g++ + ) { + for ( + var v = h[u ? g : h.length - 1 - g], y = 0; + y < v.segments.length; + y++ + ) { + var m = v.segments[u ? y : v.segments.length - 1 - y], + b = g === h.length - 1 && y === v.segments.length - 1; + if (((p = f), (f += m.length) >= c || b)) { + d = { cp: v, segment: m }; + break; + } + } + if (d) break; + } + var x = d.cp, + w = d.segment, + E = (c - p) / w.length, + k = w.t1 - w.t0, + C = u ? w.t0 + k * E : w.t1 - k * E; + ((C = Tt(0, C, 1)), + (t = Dt(x.p0, x.p1, x.p2, C)), + (l = (function (e, t, n, r) { + var i = Tt(0, r - 0.001, 1), + a = Tt(0, r + 0.001, 1), + o = Dt(e, t, n, i), + s = Dt(e, t, n, a); + return su(o, s); + })(x.p0, x.p1, x.p2, C))); + break; + case "straight": + case "segments": + case "haystack": + for ( + var S, P, D, T, _ = 0, M = r.allpts.length, B = 0; + B + 3 < M && + (u + ? ((D = { x: r.allpts[B], y: r.allpts[B + 1] }), + (T = { x: r.allpts[B + 2], y: r.allpts[B + 3] })) + : ((D = { x: r.allpts[M - 2 - B], y: r.allpts[M - 1 - B] }), + (T = { x: r.allpts[M - 4 - B], y: r.allpts[M - 3 - B] })), + (P = _), + !((_ += S = kt(D, T)) >= c)); + B += 2 + ); + var N = (c - P) / S; + ((N = Tt(0, N, 1)), + (t = (function (e, t, n, r) { + var i = t.x - e.x, + a = t.y - e.y, + o = kt(e, t), + s = i / o, + l = a / o; + return ( + (n = null == n ? 0 : n), + (r = null != r ? r : n * o), + { x: e.x + s * r, y: e.y + l * r } + ); + })(D, T, N)), + (l = su(D, T))); + } + (o("labelX", s, t.x), o("labelY", s, t.y), o("labelAutoAngle", s, l)); + } + }; + (l("source"), l("target"), this.applyLabelDimensions(e)); + } + }), + (au.applyLabelDimensions = function (e) { + (this.applyPrefixedLabelDimensions(e), + e.isEdge() && + (this.applyPrefixedLabelDimensions(e, "source"), + this.applyPrefixedLabelDimensions(e, "target"))); + }), + (au.applyPrefixedLabelDimensions = function (e, t) { + var n = e._private, + r = this.getLabelText(e, t), + i = this.calculateLabelDimensions(e, r), + a = e.pstyle("line-height").pfValue, + o = e.pstyle("text-wrap").strValue, + s = Ue(n.rscratch, "labelWrapCachedLines", t) || [], + l = "wrap" !== o ? 1 : Math.max(s.length, 1), + u = i.height / l, + c = u * a, + d = i.width, + h = i.height + (l - 1) * (a - 1) * u; + (Ze(n.rstyle, "labelWidth", t, d), + Ze(n.rscratch, "labelWidth", t, d), + Ze(n.rstyle, "labelHeight", t, h), + Ze(n.rscratch, "labelHeight", t, h), + Ze(n.rscratch, "labelLineHeight", t, c)); + }), + (au.getLabelText = function (e, t) { + var n = e._private, + r = t ? t + "-" : "", + i = e.pstyle(r + "label").strValue, + a = e.pstyle("text-transform").value, + o = function (e, r) { + return r ? (Ze(n.rscratch, e, t, r), r) : Ue(n.rscratch, e, t); + }; + if (!i) return ""; + "none" == a || + ("uppercase" == a + ? (i = i.toUpperCase()) + : "lowercase" == a && (i = i.toLowerCase())); + var s = e.pstyle("text-wrap").value; + if ("wrap" === s) { + var u = o("labelKey"); + if (null != u && o("labelWrapKey") === u) + return o("labelWrapCachedText"); + for ( + var c = i.split("\n"), + d = e.pstyle("text-max-width").pfValue, + h = "anywhere" === e.pstyle("text-overflow-wrap").value, + p = [], + f = /[\s\u200b]+|$/g, + g = 0; + g < c.length; + g++ + ) { + var v = c[g], + y = this.calculateLabelDimensions(e, v).width; + if (h) { + var m = v.split("").join("​"); + v = m; + } + if (y > d) { + var b, + x = "", + w = 0, + E = l(v.matchAll(f)); + try { + for (E.s(); !(b = E.n()).done; ) { + var k = b.value, + C = k[0], + S = v.substring(w, k.index); + w = k.index + C.length; + var P = 0 === x.length ? S : x + S + C; + this.calculateLabelDimensions(e, P).width <= d + ? (x += S + C) + : (x && p.push(x), (x = S + C)); + } + } catch (e) { + E.e(e); + } finally { + E.f(); + } + x.match(/^[\s\u200b]+$/) || p.push(x); + } else p.push(v); + } + (o("labelWrapCachedLines", p), + (i = o("labelWrapCachedText", p.join("\n"))), + o("labelWrapKey", u)); + } else if ("ellipsis" === s) { + var D = e.pstyle("text-max-width").pfValue, + T = "", + _ = !1; + if (this.calculateLabelDimensions(e, i).width < D) return i; + for (var M = 0; M < i.length; M++) { + if (this.calculateLabelDimensions(e, T + i[M] + "…").width > D) break; + ((T += i[M]), M === i.length - 1 && (_ = !0)); + } + return (_ || (T += "…"), T); + } + return i; + }), + (au.getLabelJustification = function (e) { + var t = e.pstyle("text-justification").strValue, + n = e.pstyle("text-halign").strValue; + if ("auto" !== t) return t; + if (!e.isNode()) return "center"; + switch (n) { + case "left": + return "right"; + case "right": + return "left"; + default: + return "center"; + } + }), + (au.calculateLabelDimensions = function (e, t) { + var n = this, + r = n.cy.window().document, + i = Te(t, e._private.labelDimsKey), + a = n.labelDimCache || (n.labelDimCache = []), + o = a[i]; + if (null != o) return o; + var s = e.pstyle("font-style").strValue, + l = e.pstyle("font-size").pfValue, + u = e.pstyle("font-family").strValue, + c = e.pstyle("font-weight").strValue, + d = this.labelCalcCanvas, + h = this.labelCalcCanvasContext; + if (!d) { + ((d = this.labelCalcCanvas = r.createElement("canvas")), + (h = this.labelCalcCanvasContext = d.getContext("2d"))); + var p = d.style; + ((p.position = "absolute"), + (p.left = "-9999px"), + (p.top = "-9999px"), + (p.zIndex = "-1"), + (p.visibility = "hidden"), + (p.pointerEvents = "none")); + } + h.font = "".concat(s, " ").concat(c, " ").concat(l, "px ").concat(u); + for (var f = 0, g = 0, v = t.split("\n"), y = 0; y < v.length; y++) { + var m = v[y], + b = h.measureText(m), + x = Math.ceil(b.width), + w = l; + ((f = Math.max(x, f)), (g += w)); + } + return ((f += 0), (g += 0), (a[i] = { width: f, height: g })); + }), + (au.calculateLabelAngle = function (e, t) { + var n = e._private.rscratch, + r = e.isEdge(), + i = t ? t + "-" : "", + a = e.pstyle(i + "text-rotation"), + o = a.strValue; + return "none" === o + ? 0 + : r && "autorotate" === o + ? n.labelAutoAngle + : "autorotate" === o + ? 0 + : a.pfValue; + }), + (au.calculateLabelAngles = function (e) { + var t = this, + n = e.isEdge(), + r = e._private.rscratch; + ((r.labelAngle = t.calculateLabelAngle(e)), + n && + ((r.sourceLabelAngle = t.calculateLabelAngle(e, "source")), + (r.targetLabelAngle = t.calculateLabelAngle(e, "target")))); + })); + var lu = {}, + uu = !1; + lu.getNodeShape = function (e) { + var t = e.pstyle("shape").value; + if ("cutrectangle" === t && (e.width() < 28 || e.height() < 28)) + return ( + uu || + (je( + "The `cutrectangle` node shape can not be used at small sizes so `rectangle` is used instead", + ), + (uu = !0)), + "rectangle" + ); + if (e.isParent()) + return "rectangle" === t || + "roundrectangle" === t || + "round-rectangle" === t || + "cutrectangle" === t || + "cut-rectangle" === t || + "barrel" === t + ? t + : "rectangle"; + if ("polygon" === t) { + var n = e.pstyle("shape-polygon-points").value; + return this.nodeShapes.makePolygon(n).name; + } + return t; + }; + var cu = { + registerCalculationListeners: function () { + var e = this.cy, + t = e.collection(), + n = this, + r = function (e) { + var n = + !(arguments.length > 1 && void 0 !== arguments[1]) || + arguments[1]; + if ((t.merge(e), n)) + for (var r = 0; r < e.length; r++) { + var i = e[r], + a = i._private, + o = a.rstyle; + ((o.clean = !1), (o.cleanConnected = !1)); + } + }; + n.binder(e) + .on("bounds.* dirty.*", function (e) { + var t = e.target; + r(t); + }) + .on("style.* background.*", function (e) { + var t = e.target; + r(t, !1); + }); + var i = function (i) { + if (i) { + var a = n.onUpdateEleCalcsFns; + t.cleanStyle(); + for (var o = 0; o < t.length; o++) { + var s = t[o], + l = s._private.rstyle; + s.isNode() && + !l.cleanConnected && + (r(s.connectedEdges()), (l.cleanConnected = !0)); + } + if (a) + for (var u = 0; u < a.length; u++) { + (0, a[u])(i, t); + } + (n.recalculateRenderedStyle(t), (t = e.collection())); + } + }; + ((n.flushRenderedStyleQueue = function () { + i(!0); + }), + n.beforeRender(i, n.beforeRenderPriorities.eleCalcs)); + }, + onUpdateEleCalcs: function (e) { + (this.onUpdateEleCalcsFns = this.onUpdateEleCalcsFns || []).push(e); + }, + recalculateRenderedStyle: function (e, t) { + var n = function (e) { + return e._private.rstyle.cleanConnected; + }, + r = [], + i = []; + if (!this.destroyed) { + void 0 === t && (t = !0); + for (var a = 0; a < e.length; a++) { + var o = e[a], + s = o._private, + l = s.rstyle; + (!o.isEdge() || (n(o.source()) && n(o.target())) || (l.clean = !1), + (t && l.clean) || + o.removed() || + ("none" !== o.pstyle("display").value && + ("nodes" === s.group ? i.push(o) : r.push(o), + (l.clean = !0)))); + } + for (var u = 0; u < i.length; u++) { + var c = i[u], + d = c._private.rstyle, + h = c.position(); + (this.recalculateNodeLabelProjection(c), + (d.nodeX = h.x), + (d.nodeY = h.y), + (d.nodeW = c.pstyle("width").pfValue), + (d.nodeH = c.pstyle("height").pfValue)); + } + this.recalculateEdgeProjections(r); + for (var p = 0; p < r.length; p++) { + var f = r[p]._private, + g = f.rstyle, + v = f.rscratch; + ((g.srcX = v.arrowStartX), + (g.srcY = v.arrowStartY), + (g.tgtX = v.arrowEndX), + (g.tgtY = v.arrowEndY), + (g.midX = v.midX), + (g.midY = v.midY), + (g.labelAngle = v.labelAngle), + (g.sourceLabelAngle = v.sourceLabelAngle), + (g.targetLabelAngle = v.targetLabelAngle)); + } + } + }, + }, + du = { + updateCachedGrabbedEles: function () { + var e = this.cachedZSortedEles; + if (e) { + ((e.drag = []), (e.nondrag = [])); + for (var t = [], n = 0; n < e.length; n++) { + var r = (i = e[n])._private.rscratch; + i.grabbed() && !i.isParent() + ? t.push(i) + : r.inDragLayer + ? e.drag.push(i) + : e.nondrag.push(i); + } + for (n = 0; n < t.length; n++) { + var i = t[n]; + e.drag.push(i); + } + } + }, + invalidateCachedZSortedEles: function () { + this.cachedZSortedEles = null; + }, + getCachedZSortedEles: function (e) { + if (e || !this.cachedZSortedEles) { + var t = this.cy.mutableElements().toArray(); + (t.sort(Mo), + (t.interactive = t.filter(function (e) { + return e.interactive(); + })), + (this.cachedZSortedEles = t), + this.updateCachedGrabbedEles()); + } else t = this.cachedZSortedEles; + return t; + }, + }, + hu = {}; + [_l, Ml, eu, nu, ru, au, lu, cu, du].forEach(function (e) { + L(hu, e); + }); + var pu = { + getCachedImage: function (e, t, n) { + var r = (this.imageCache = this.imageCache || {}), + i = r[e]; + if (i) + return ( + i.image.complete || i.image.addEventListener("load", n), + i.image + ); + var a = ((i = r[e] = r[e] || {}).image = new Image()); + (a.addEventListener("load", n), + a.addEventListener("error", function () { + a.error = !0; + })); + return ( + "data:" === e.substring(0, "data:".length).toLowerCase() || + ((t = "null" === t ? null : t), (a.crossOrigin = t)), + (a.src = e), + a + ); + }, + }, + fu = { + registerBinding: function (e, t, n, r) { + var i = Array.prototype.slice.apply(arguments, [1]), + a = this.binder(e); + return a.on.apply(a, i); + }, + }; + ((fu.binder = function (e) { + var t, + n = this, + r = n.cy.window(), + i = + e === r || + e === r.document || + e === r.document.body || + ((t = e), + "undefined" != typeof HTMLElement && t instanceof HTMLElement); + if (null == n.supportsPassiveEvents) { + var a = !1; + try { + var o = Object.defineProperty({}, "passive", { + get: function () { + return ((a = !0), !0); + }, + }); + r.addEventListener("test", null, o); + } catch (e) {} + n.supportsPassiveEvents = a; + } + var s = function (t, r, a) { + var o = Array.prototype.slice.call(arguments); + return ( + i && + n.supportsPassiveEvents && + (o[2] = { capture: null != a && a, passive: !1, once: !1 }), + n.bindings.push({ target: e, args: o }), + (e.addEventListener || e.on).apply(e, o), + this + ); + }; + return { on: s, addEventListener: s, addListener: s, bind: s }; + }), + (fu.nodeIsDraggable = function (e) { + return e && e.isNode() && !e.locked() && e.grabbable(); + }), + (fu.nodeIsGrabbable = function (e) { + return this.nodeIsDraggable(e) && e.interactive(); + }), + (fu.load = function () { + var e = this, + t = e.cy.window(), + n = function (e) { + return e.selected(); + }, + r = function (t, n, r, i) { + null == t && (t = e.cy); + for (var a = 0; a < n.length; a++) { + var o = n[a]; + t.emit({ originalEvent: r, type: o, position: i }); + } + }, + i = function (e) { + return e.shiftKey || e.metaKey || e.ctrlKey; + }, + a = function (t, n) { + var r = !0; + if (e.cy.hasCompoundNodes() && t && t.pannable()) + for (var i = 0; n && i < n.length; i++) { + if ((t = n[i]).isNode() && t.isParent() && !t.pannable()) { + r = !1; + break; + } + } + else r = !0; + return r; + }, + o = function (e) { + e[0]._private.rscratch.inDragLayer = !0; + }, + s = function (e) { + e[0]._private.rscratch.isGrabTarget = !0; + }, + l = function (e, t) { + var n = t.addToList; + n.has(e) || + !e.grabbable() || + e.locked() || + (n.merge(e), + (function (e) { + e[0]._private.grabbed = !0; + })(e)); + }, + u = function (t, n) { + n = n || {}; + var r = t.cy().hasCompoundNodes(); + (n.inDragLayer && + (t.forEach(o), + t + .neighborhood() + .stdFilter(function (e) { + return !r || e.isEdge(); + }) + .forEach(o)), + n.addToList && + t.forEach(function (e) { + l(e, n); + }), + (function (e, t) { + if ( + e.cy().hasCompoundNodes() && + (null != t.inDragLayer || null != t.addToList) + ) { + var n = e.descendants(); + (t.inDragLayer && (n.forEach(o), n.connectedEdges().forEach(o)), + t.addToList && l(n, t)); + } + })(t, n), + h(t, { inDragLayer: n.inDragLayer }), + e.updateCachedGrabbedEles()); + }, + c = u, + d = function (t) { + t && + (e.getCachedZSortedEles().forEach(function (e) { + (!(function (e) { + e[0]._private.grabbed = !1; + })(e), + (function (e) { + e[0]._private.rscratch.inDragLayer = !1; + })(e), + (function (e) { + e[0]._private.rscratch.isGrabTarget = !1; + })(e)); + }), + e.updateCachedGrabbedEles()); + }, + h = function (e, t) { + if ( + (null != t.inDragLayer || null != t.addToList) && + e.cy().hasCompoundNodes() + ) { + var n = e.ancestors().orphans(); + if (!n.same(e)) { + var r = n + .descendants() + .spawnSelf() + .merge(n) + .unmerge(e) + .unmerge(e.descendants()), + i = r.connectedEdges(); + (t.inDragLayer && (i.forEach(o), r.forEach(o)), + t.addToList && + r.forEach(function (e) { + l(e, t); + })); + } + } + }, + p = function () { + null != document.activeElement && + null != document.activeElement.blur && + document.activeElement.blur(); + }, + f = "undefined" != typeof MutationObserver, + g = "undefined" != typeof ResizeObserver; + f + ? ((e.removeObserver = new MutationObserver(function (t) { + for (var n = 0; n < t.length; n++) { + var r = t[n].removedNodes; + if (r) + for (var i = 0; i < r.length; i++) { + if (r[i] === e.container) { + e.destroy(); + break; + } + } + } + })), + e.container.parentNode && + e.removeObserver.observe(e.container.parentNode, { childList: !0 })) + : e.registerBinding(e.container, "DOMNodeRemoved", function (t) { + e.destroy(); + }); + var v = ve(function () { + e.cy.resize(); + }, 100); + (f && + ((e.styleObserver = new MutationObserver(v)), + e.styleObserver.observe(e.container, { attributes: !0 })), + e.registerBinding(t, "resize", v), + g && + ((e.resizeObserver = new ResizeObserver(v)), + e.resizeObserver.observe(e.container))); + var y = function () { + e.invalidateContainerClientCoordsCache(); + }; + (!(function (e, t) { + for (; null != e; ) (t(e), (e = e.parentNode)); + })(e.container, function (t) { + (e.registerBinding(t, "transitionend", y), + e.registerBinding(t, "animationend", y), + e.registerBinding(t, "scroll", y)); + }), + e.registerBinding(e.container, "contextmenu", function (e) { + e.preventDefault(); + })); + var m, + b, + w, + E = function (t) { + for ( + var n = e.findContainerClientCoords(), + r = n[0], + i = n[1], + a = n[2], + o = n[3], + s = t.touches ? t.touches : [t], + l = !1, + u = 0; + u < s.length; + u++ + ) { + var c = s[u]; + if ( + r <= c.clientX && + c.clientX <= r + a && + i <= c.clientY && + c.clientY <= i + o + ) { + l = !0; + break; + } + } + if (!l) return !1; + for (var d = e.container, h = t.target.parentNode, p = !1; h; ) { + if (h === d) { + p = !0; + break; + } + h = h.parentNode; + } + return !!p; + }; + (e.registerBinding( + e.container, + "mousedown", + function (t) { + if (E(t) && (1 !== e.hoverData.which || 1 === t.which)) { + (t.preventDefault(), + p(), + (e.hoverData.capture = !0), + (e.hoverData.which = t.which)); + var n = e.cy, + i = [t.clientX, t.clientY], + a = e.projectIntoViewport(i[0], i[1]), + o = e.selection, + l = e.findNearestElements(a[0], a[1], !0, !1), + d = l[0], + h = e.dragData.possibleDragElements; + ((e.hoverData.mdownPos = a), (e.hoverData.mdownGPos = i)); + if (3 == t.which) { + e.hoverData.cxtStarted = !0; + var f = { + originalEvent: t, + type: "cxttapstart", + position: { x: a[0], y: a[1] }, + }; + (d + ? (d.activate(), d.emit(f), (e.hoverData.down = d)) + : n.emit(f), + (e.hoverData.downTime = new Date().getTime()), + (e.hoverData.cxtDragged = !1)); + } else if (1 == t.which) { + if ((d && d.activate(), null != d && e.nodeIsGrabbable(d))) { + var g = function (e) { + return { + originalEvent: t, + type: e, + position: { x: a[0], y: a[1] }, + }; + }; + if ((s(d), d.selected())) { + h = e.dragData.possibleDragElements = n.collection(); + var v = n.$(function (t) { + return t.isNode() && t.selected() && e.nodeIsGrabbable(t); + }); + (u(v, { addToList: h }), + d.emit(g("grabon")), + v.forEach(function (e) { + e.emit(g("grab")); + })); + } else + ((h = e.dragData.possibleDragElements = n.collection()), + c(d, { addToList: h }), + d.emit(g("grabon")).emit(g("grab"))); + (e.redrawHint("eles", !0), e.redrawHint("drag", !0)); + } + ((e.hoverData.down = d), + (e.hoverData.downs = l), + (e.hoverData.downTime = new Date().getTime()), + r(d, ["mousedown", "tapstart", "vmousedown"], t, { + x: a[0], + y: a[1], + }), + null == d + ? ((o[4] = 1), + (e.data.bgActivePosistion = { x: a[0], y: a[1] }), + e.redrawHint("select", !0), + e.redraw()) + : d.pannable() && (o[4] = 1), + (e.hoverData.tapholdCancelled = !1), + clearTimeout(e.hoverData.tapholdTimeout), + (e.hoverData.tapholdTimeout = setTimeout(function () { + if (!e.hoverData.tapholdCancelled) { + var r = e.hoverData.down; + r + ? r.emit({ + originalEvent: t, + type: "taphold", + position: { x: a[0], y: a[1] }, + }) + : n.emit({ + originalEvent: t, + type: "taphold", + position: { x: a[0], y: a[1] }, + }); + } + }, e.tapholdDuration))); + } + ((o[0] = o[2] = a[0]), (o[1] = o[3] = a[1])); + } + }, + !1, + ), + e.registerBinding( + t, + "mousemove", + function (t) { + if (e.hoverData.capture || E(t)) { + var n = !1, + o = e.cy, + s = o.zoom(), + l = [t.clientX, t.clientY], + c = e.projectIntoViewport(l[0], l[1]), + h = e.hoverData.mdownPos, + p = e.hoverData.mdownGPos, + f = e.selection, + g = null; + e.hoverData.draggingEles || + e.hoverData.dragging || + e.hoverData.selecting || + (g = e.findNearestElement(c[0], c[1], !0, !1)); + var v, + y = e.hoverData.last, + m = e.hoverData.down, + b = [c[0] - f[2], c[1] - f[3]], + w = e.dragData.possibleDragElements; + if (p) { + var k = l[0] - p[0], + C = k * k, + S = l[1] - p[1], + P = C + S * S; + e.hoverData.isOverThresholdDrag = v = + P >= e.desktopTapThreshold2; + } + var D = i(t); + v && (e.hoverData.tapholdCancelled = !0); + ((n = !0), + r(g, ["mousemove", "vmousemove", "tapdrag"], t, { + x: c[0], + y: c[1], + })); + var T = function () { + ((e.data.bgActivePosistion = void 0), + e.hoverData.selecting || + o.emit({ + originalEvent: t, + type: "boxstart", + position: { x: c[0], y: c[1] }, + }), + (f[4] = 1), + (e.hoverData.selecting = !0), + e.redrawHint("select", !0), + e.redraw()); + }; + if (3 === e.hoverData.which) { + if (v) { + var _ = { + originalEvent: t, + type: "cxtdrag", + position: { x: c[0], y: c[1] }, + }; + (m ? m.emit(_) : o.emit(_), + (e.hoverData.cxtDragged = !0), + (e.hoverData.cxtOver && g === e.hoverData.cxtOver) || + (e.hoverData.cxtOver && + e.hoverData.cxtOver.emit({ + originalEvent: t, + type: "cxtdragout", + position: { x: c[0], y: c[1] }, + }), + (e.hoverData.cxtOver = g), + g && + g.emit({ + originalEvent: t, + type: "cxtdragover", + position: { x: c[0], y: c[1] }, + }))); + } + } else if (e.hoverData.dragging) { + if (((n = !0), o.panningEnabled() && o.userPanningEnabled())) { + var M; + if (e.hoverData.justStartedPan) { + var B = e.hoverData.mdownPos; + ((M = { x: (c[0] - B[0]) * s, y: (c[1] - B[1]) * s }), + (e.hoverData.justStartedPan = !1)); + } else M = { x: b[0] * s, y: b[1] * s }; + (o.panBy(M), o.emit("dragpan"), (e.hoverData.dragged = !0)); + } + c = e.projectIntoViewport(t.clientX, t.clientY); + } else if (1 != f[4] || (null != m && !m.pannable())) { + if ( + (m && m.pannable() && m.active() && m.unactivate(), + (m && m.grabbed()) || + g == y || + (y && + r(y, ["mouseout", "tapdragout"], t, { x: c[0], y: c[1] }), + g && + r(g, ["mouseover", "tapdragover"], t, { + x: c[0], + y: c[1], + }), + (e.hoverData.last = g)), + m) + ) + if (v) { + if (o.boxSelectionEnabled() && D) + (m && + m.grabbed() && + (d(w), + m.emit("freeon"), + w.emit("free"), + e.dragData.didDrag && + (m.emit("dragfreeon"), w.emit("dragfree"))), + T()); + else if (m && m.grabbed() && e.nodeIsDraggable(m)) { + var N = !e.dragData.didDrag; + (N && e.redrawHint("eles", !0), + (e.dragData.didDrag = !0), + e.hoverData.draggingEles || u(w, { inDragLayer: !0 })); + var z = { x: 0, y: 0 }; + if ( + x(b[0]) && + x(b[1]) && + ((z.x += b[0]), (z.y += b[1]), N) + ) { + var I = e.hoverData.dragDelta; + I && + x(I[0]) && + x(I[1]) && + ((z.x += I[0]), (z.y += I[1])); + } + ((e.hoverData.draggingEles = !0), + w.silentShift(z).emit("position drag"), + e.redrawHint("drag", !0), + e.redraw()); + } + } else + !(function () { + var t = (e.hoverData.dragDelta = + e.hoverData.dragDelta || []); + 0 === t.length + ? (t.push(b[0]), t.push(b[1])) + : ((t[0] += b[0]), (t[1] += b[1])); + })(); + n = !0; + } else if (v) { + if ( + e.hoverData.dragging || + !o.boxSelectionEnabled() || + (!D && o.panningEnabled() && o.userPanningEnabled()) + ) { + if ( + !e.hoverData.selecting && + o.panningEnabled() && + o.userPanningEnabled() + ) { + a(m, e.hoverData.downs) && + ((e.hoverData.dragging = !0), + (e.hoverData.justStartedPan = !0), + (f[4] = 0), + (e.data.bgActivePosistion = bt(h)), + e.redrawHint("select", !0), + e.redraw()); + } + } else T(); + m && m.pannable() && m.active() && m.unactivate(); + } + return ( + (f[2] = c[0]), + (f[3] = c[1]), + n + ? (t.stopPropagation && t.stopPropagation(), + t.preventDefault && t.preventDefault(), + !1) + : void 0 + ); + } + }, + !1, + ), + e.registerBinding( + t, + "mouseup", + function (t) { + if ( + (1 !== e.hoverData.which || + 1 === t.which || + !e.hoverData.capture) && + e.hoverData.capture + ) { + e.hoverData.capture = !1; + var a = e.cy, + o = e.projectIntoViewport(t.clientX, t.clientY), + s = e.selection, + l = e.findNearestElement(o[0], o[1], !0, !1), + u = e.dragData.possibleDragElements, + c = e.hoverData.down, + h = i(t); + if ( + (e.data.bgActivePosistion && + (e.redrawHint("select", !0), e.redraw()), + (e.hoverData.tapholdCancelled = !0), + (e.data.bgActivePosistion = void 0), + c && c.unactivate(), + 3 === e.hoverData.which) + ) { + var p = { + originalEvent: t, + type: "cxttapend", + position: { x: o[0], y: o[1] }, + }; + if ((c ? c.emit(p) : a.emit(p), !e.hoverData.cxtDragged)) { + var f = { + originalEvent: t, + type: "cxttap", + position: { x: o[0], y: o[1] }, + }; + c ? c.emit(f) : a.emit(f); + } + ((e.hoverData.cxtDragged = !1), (e.hoverData.which = null)); + } else if (1 === e.hoverData.which) { + if ( + (r(l, ["mouseup", "tapend", "vmouseup"], t, { + x: o[0], + y: o[1], + }), + e.dragData.didDrag || + e.hoverData.dragged || + e.hoverData.selecting || + e.hoverData.isOverThresholdDrag || + (r(c, ["click", "tap", "vclick"], t, { x: o[0], y: o[1] }), + (b = !1), + t.timeStamp - w <= a.multiClickDebounceTime() + ? (m && clearTimeout(m), + (b = !0), + (w = null), + r(c, ["dblclick", "dbltap", "vdblclick"], t, { + x: o[0], + y: o[1], + })) + : ((m = setTimeout(function () { + b || + r(c, ["oneclick", "onetap", "voneclick"], t, { + x: o[0], + y: o[1], + }); + }, a.multiClickDebounceTime())), + (w = t.timeStamp))), + null != c || + e.dragData.didDrag || + e.hoverData.selecting || + e.hoverData.dragged || + i(t) || + (a.$(n).unselect(["tapunselect"]), + u.length > 0 && e.redrawHint("eles", !0), + (e.dragData.possibleDragElements = u = a.collection())), + l != c || + e.dragData.didDrag || + e.hoverData.selecting || + (null != l && + l._private.selectable && + (e.hoverData.dragging || + ("additive" === a.selectionType() || h + ? l.selected() + ? l.unselect(["tapunselect"]) + : l.select(["tapselect"]) + : h || + (a.$(n).unmerge(l).unselect(["tapunselect"]), + l.select(["tapselect"]))), + e.redrawHint("eles", !0))), + e.hoverData.selecting) + ) { + var g = a.collection(e.getAllInBox(s[0], s[1], s[2], s[3])); + (e.redrawHint("select", !0), + g.length > 0 && e.redrawHint("eles", !0), + a.emit({ + type: "boxend", + originalEvent: t, + position: { x: o[0], y: o[1] }, + })); + var v = function (e) { + return e.selectable() && !e.selected(); + }; + ("additive" === a.selectionType() || + h || + a.$(n).unmerge(g).unselect(), + g.emit("box").stdFilter(v).select().emit("boxselect"), + e.redraw()); + } + if ( + (e.hoverData.dragging && + ((e.hoverData.dragging = !1), + e.redrawHint("select", !0), + e.redrawHint("eles", !0), + e.redraw()), + !s[4]) + ) { + (e.redrawHint("drag", !0), e.redrawHint("eles", !0)); + var y = c && c.grabbed(); + (d(u), + y && + (c.emit("freeon"), + u.emit("free"), + e.dragData.didDrag && + (c.emit("dragfreeon"), u.emit("dragfree")))); + } + } + ((s[4] = 0), + (e.hoverData.down = null), + (e.hoverData.cxtStarted = !1), + (e.hoverData.draggingEles = !1), + (e.hoverData.selecting = !1), + (e.hoverData.isOverThresholdDrag = !1), + (e.dragData.didDrag = !1), + (e.hoverData.dragged = !1), + (e.hoverData.dragDelta = []), + (e.hoverData.mdownPos = null), + (e.hoverData.mdownGPos = null), + (e.hoverData.which = null)); + } + }, + !1, + )); + var k, + C, + S, + P, + D, + T, + _, + M, + B, + N, + z, + I, + A, + L = function (t) { + if (!e.scrollingPage) { + var n = e.cy, + r = n.zoom(), + i = n.pan(), + a = e.projectIntoViewport(t.clientX, t.clientY), + o = [a[0] * r + i.x, a[1] * r + i.y]; + if ( + e.hoverData.draggingEles || + e.hoverData.dragging || + e.hoverData.cxtStarted || + 0 !== e.selection[4] + ) + t.preventDefault(); + else if ( + n.panningEnabled() && + n.userPanningEnabled() && + n.zoomingEnabled() && + n.userZoomingEnabled() + ) { + var s; + (t.preventDefault(), + (e.data.wheelZooming = !0), + clearTimeout(e.data.wheelTimeout), + (e.data.wheelTimeout = setTimeout(function () { + ((e.data.wheelZooming = !1), + e.redrawHint("eles", !0), + e.redraw()); + }, 150)), + (s = + null != t.deltaY + ? t.deltaY / -250 + : null != t.wheelDeltaY + ? t.wheelDeltaY / 1e3 + : t.wheelDelta / 1e3), + (s *= e.wheelSensitivity), + 1 === t.deltaMode && (s *= 33)); + var l = n.zoom() * Math.pow(10, s); + ("gesturechange" === t.type && (l = e.gestureStartZoom * t.scale), + n.zoom({ level: l, renderedPosition: { x: o[0], y: o[1] } }), + n.emit( + "gesturechange" === t.type ? "pinchzoom" : "scrollzoom", + )); + } + } + }; + (e.registerBinding(e.container, "wheel", L, !0), + e.registerBinding( + t, + "scroll", + function (t) { + ((e.scrollingPage = !0), + clearTimeout(e.scrollingPageTimeout), + (e.scrollingPageTimeout = setTimeout(function () { + e.scrollingPage = !1; + }, 250))); + }, + !0, + ), + e.registerBinding( + e.container, + "gesturestart", + function (t) { + ((e.gestureStartZoom = e.cy.zoom()), + e.hasTouchStarted || t.preventDefault()); + }, + !0, + ), + e.registerBinding( + e.container, + "gesturechange", + function (t) { + e.hasTouchStarted || L(t); + }, + !0, + ), + e.registerBinding( + e.container, + "mouseout", + function (t) { + var n = e.projectIntoViewport(t.clientX, t.clientY); + e.cy.emit({ + originalEvent: t, + type: "mouseout", + position: { x: n[0], y: n[1] }, + }); + }, + !1, + ), + e.registerBinding( + e.container, + "mouseover", + function (t) { + var n = e.projectIntoViewport(t.clientX, t.clientY); + e.cy.emit({ + originalEvent: t, + type: "mouseover", + position: { x: n[0], y: n[1] }, + }); + }, + !1, + )); + var O, + R, + V, + F, + j, + q, + Y, + X = function (e, t, n, r) { + return Math.sqrt((n - e) * (n - e) + (r - t) * (r - t)); + }, + W = function (e, t, n, r) { + return (n - e) * (n - e) + (r - t) * (r - t); + }; + if ( + (e.registerBinding( + e.container, + "touchstart", + (O = function (t) { + if (((e.hasTouchStarted = !0), E(t))) { + (p(), + (e.touchData.capture = !0), + (e.data.bgActivePosistion = void 0)); + var n = e.cy, + i = e.touchData.now, + a = e.touchData.earlier; + if (t.touches[0]) { + var o = e.projectIntoViewport( + t.touches[0].clientX, + t.touches[0].clientY, + ); + ((i[0] = o[0]), (i[1] = o[1])); + } + if (t.touches[1]) { + o = e.projectIntoViewport( + t.touches[1].clientX, + t.touches[1].clientY, + ); + ((i[2] = o[0]), (i[3] = o[1])); + } + if (t.touches[2]) { + o = e.projectIntoViewport( + t.touches[2].clientX, + t.touches[2].clientY, + ); + ((i[4] = o[0]), (i[5] = o[1])); + } + if (t.touches[1]) { + ((e.touchData.singleTouchMoved = !0), + d(e.dragData.touchDragEles)); + var l = e.findContainerClientCoords(); + ((B = l[0]), + (N = l[1]), + (z = l[2]), + (I = l[3]), + (k = t.touches[0].clientX - B), + (C = t.touches[0].clientY - N), + (S = t.touches[1].clientX - B), + (P = t.touches[1].clientY - N), + (A = + 0 <= k && + k <= z && + 0 <= S && + S <= z && + 0 <= C && + C <= I && + 0 <= P && + P <= I)); + var h = n.pan(), + f = n.zoom(); + ((D = X(k, C, S, P)), + (T = W(k, C, S, P)), + (M = [ + ((_ = [(k + S) / 2, (C + P) / 2])[0] - h.x) / f, + (_[1] - h.y) / f, + ])); + if (T < 4e4 && !t.touches[2]) { + var g = e.findNearestElement(i[0], i[1], !0, !0), + v = e.findNearestElement(i[2], i[3], !0, !0); + return ( + g && g.isNode() + ? (g.activate().emit({ + originalEvent: t, + type: "cxttapstart", + position: { x: i[0], y: i[1] }, + }), + (e.touchData.start = g)) + : v && v.isNode() + ? (v.activate().emit({ + originalEvent: t, + type: "cxttapstart", + position: { x: i[0], y: i[1] }, + }), + (e.touchData.start = v)) + : n.emit({ + originalEvent: t, + type: "cxttapstart", + position: { x: i[0], y: i[1] }, + }), + e.touchData.start && + (e.touchData.start._private.grabbed = !1), + (e.touchData.cxt = !0), + (e.touchData.cxtDragged = !1), + (e.data.bgActivePosistion = void 0), + void e.redraw() + ); + } + } + if (t.touches[2]) n.boxSelectionEnabled() && t.preventDefault(); + else if (t.touches[1]); + else if (t.touches[0]) { + var y = e.findNearestElements(i[0], i[1], !0, !0), + m = y[0]; + if ( + null != m && + (m.activate(), + (e.touchData.start = m), + (e.touchData.starts = y), + e.nodeIsGrabbable(m)) + ) { + var b = (e.dragData.touchDragEles = n.collection()), + x = null; + (e.redrawHint("eles", !0), + e.redrawHint("drag", !0), + m.selected() + ? ((x = n.$(function (t) { + return t.selected() && e.nodeIsGrabbable(t); + })), + u(x, { addToList: b })) + : c(m, { addToList: b }), + s(m)); + var w = function (e) { + return { + originalEvent: t, + type: e, + position: { x: i[0], y: i[1] }, + }; + }; + (m.emit(w("grabon")), + x + ? x.forEach(function (e) { + e.emit(w("grab")); + }) + : m.emit(w("grab"))); + } + (r(m, ["touchstart", "tapstart", "vmousedown"], t, { + x: i[0], + y: i[1], + }), + null == m && + ((e.data.bgActivePosistion = { x: o[0], y: o[1] }), + e.redrawHint("select", !0), + e.redraw()), + (e.touchData.singleTouchMoved = !1), + (e.touchData.singleTouchStartTime = +new Date()), + clearTimeout(e.touchData.tapholdTimeout), + (e.touchData.tapholdTimeout = setTimeout(function () { + !1 !== e.touchData.singleTouchMoved || + e.pinching || + e.touchData.selecting || + r(e.touchData.start, ["taphold"], t, { + x: i[0], + y: i[1], + }); + }, e.tapholdDuration))); + } + if (t.touches.length >= 1) { + for ( + var L = (e.touchData.startPosition = [ + null, + null, + null, + null, + null, + null, + ]), + O = 0; + O < i.length; + O++ + ) + L[O] = a[O] = i[O]; + var R = t.touches[0]; + e.touchData.startGPosition = [R.clientX, R.clientY]; + } + } + }), + !1, + ), + e.registerBinding( + t, + "touchmove", + (R = function (t) { + var n = e.touchData.capture; + if (n || E(t)) { + var i = e.selection, + o = e.cy, + s = e.touchData.now, + l = e.touchData.earlier, + c = o.zoom(); + if (t.touches[0]) { + var h = e.projectIntoViewport( + t.touches[0].clientX, + t.touches[0].clientY, + ); + ((s[0] = h[0]), (s[1] = h[1])); + } + if (t.touches[1]) { + h = e.projectIntoViewport( + t.touches[1].clientX, + t.touches[1].clientY, + ); + ((s[2] = h[0]), (s[3] = h[1])); + } + if (t.touches[2]) { + h = e.projectIntoViewport( + t.touches[2].clientX, + t.touches[2].clientY, + ); + ((s[4] = h[0]), (s[5] = h[1])); + } + var p, + f = e.touchData.startGPosition; + if (n && t.touches[0] && f) { + for (var g = [], v = 0; v < s.length; v++) g[v] = s[v] - l[v]; + var y = t.touches[0].clientX - f[0], + m = y * y, + b = t.touches[0].clientY - f[1]; + p = m + b * b >= e.touchTapThreshold2; + } + if (n && e.touchData.cxt) { + t.preventDefault(); + var w = t.touches[0].clientX - B, + _ = t.touches[0].clientY - N, + z = t.touches[1].clientX - B, + I = t.touches[1].clientY - N, + L = W(w, _, z, I); + if (L / T >= 2.25 || L >= 22500) { + ((e.touchData.cxt = !1), + (e.data.bgActivePosistion = void 0), + e.redrawHint("select", !0)); + var O = { + originalEvent: t, + type: "cxttapend", + position: { x: s[0], y: s[1] }, + }; + e.touchData.start + ? (e.touchData.start.unactivate().emit(O), + (e.touchData.start = null)) + : o.emit(O); + } + } + if (n && e.touchData.cxt) { + O = { + originalEvent: t, + type: "cxtdrag", + position: { x: s[0], y: s[1] }, + }; + ((e.data.bgActivePosistion = void 0), + e.redrawHint("select", !0), + e.touchData.start ? e.touchData.start.emit(O) : o.emit(O), + e.touchData.start && + (e.touchData.start._private.grabbed = !1), + (e.touchData.cxtDragged = !0)); + var R = e.findNearestElement(s[0], s[1], !0, !0); + (e.touchData.cxtOver && R === e.touchData.cxtOver) || + (e.touchData.cxtOver && + e.touchData.cxtOver.emit({ + originalEvent: t, + type: "cxtdragout", + position: { x: s[0], y: s[1] }, + }), + (e.touchData.cxtOver = R), + R && + R.emit({ + originalEvent: t, + type: "cxtdragover", + position: { x: s[0], y: s[1] }, + })); + } else if (n && t.touches[2] && o.boxSelectionEnabled()) + (t.preventDefault(), + (e.data.bgActivePosistion = void 0), + (this.lastThreeTouch = +new Date()), + e.touchData.selecting || + o.emit({ + originalEvent: t, + type: "boxstart", + position: { x: s[0], y: s[1] }, + }), + (e.touchData.selecting = !0), + (e.touchData.didSelect = !0), + (i[4] = 1), + i && 0 !== i.length && void 0 !== i[0] + ? ((i[2] = (s[0] + s[2] + s[4]) / 3), + (i[3] = (s[1] + s[3] + s[5]) / 3)) + : ((i[0] = (s[0] + s[2] + s[4]) / 3), + (i[1] = (s[1] + s[3] + s[5]) / 3), + (i[2] = (s[0] + s[2] + s[4]) / 3 + 1), + (i[3] = (s[1] + s[3] + s[5]) / 3 + 1)), + e.redrawHint("select", !0), + e.redraw()); + else if ( + n && + t.touches[1] && + !e.touchData.didSelect && + o.zoomingEnabled() && + o.panningEnabled() && + o.userZoomingEnabled() && + o.userPanningEnabled() + ) { + if ( + (t.preventDefault(), + (e.data.bgActivePosistion = void 0), + e.redrawHint("select", !0), + (ee = e.dragData.touchDragEles)) + ) { + e.redrawHint("drag", !0); + for (var V = 0; V < ee.length; V++) { + var F = ee[V]._private; + ((F.grabbed = !1), (F.rscratch.inDragLayer = !1)); + } + } + var j = e.touchData.start, + q = + ((w = t.touches[0].clientX - B), + (_ = t.touches[0].clientY - N), + (z = t.touches[1].clientX - B), + (I = t.touches[1].clientY - N), + X(w, _, z, I)), + Y = q / D; + if (A) { + var H = (w - k + (z - S)) / 2, + K = (_ - C + (I - P)) / 2, + G = o.zoom(), + U = G * Y, + Z = o.pan(), + $ = M[0] * G + Z.x, + Q = M[1] * G + Z.y, + J = { + x: (-U / G) * ($ - Z.x - H) + $, + y: (-U / G) * (Q - Z.y - K) + Q, + }; + if (j && j.active()) { + var ee = e.dragData.touchDragEles; + (d(ee), + e.redrawHint("drag", !0), + e.redrawHint("eles", !0), + j.unactivate().emit("freeon"), + ee.emit("free"), + e.dragData.didDrag && + (j.emit("dragfreeon"), ee.emit("dragfree"))); + } + (o.viewport({ zoom: U, pan: J, cancelOnFailedZoom: !0 }), + o.emit("pinchzoom"), + (D = q), + (k = w), + (C = _), + (S = z), + (P = I), + (e.pinching = !0)); + } + if (t.touches[0]) { + h = e.projectIntoViewport( + t.touches[0].clientX, + t.touches[0].clientY, + ); + ((s[0] = h[0]), (s[1] = h[1])); + } + if (t.touches[1]) { + h = e.projectIntoViewport( + t.touches[1].clientX, + t.touches[1].clientY, + ); + ((s[2] = h[0]), (s[3] = h[1])); + } + if (t.touches[2]) { + h = e.projectIntoViewport( + t.touches[2].clientX, + t.touches[2].clientY, + ); + ((s[4] = h[0]), (s[5] = h[1])); + } + } else if (t.touches[0] && !e.touchData.didSelect) { + var te = e.touchData.start, + ne = e.touchData.last; + if ( + (e.hoverData.draggingEles || + e.swipePanning || + (R = e.findNearestElement(s[0], s[1], !0, !0)), + n && null != te && t.preventDefault(), + n && null != te && e.nodeIsDraggable(te)) + ) + if (p) { + ee = e.dragData.touchDragEles; + var re = !e.dragData.didDrag; + (re && u(ee, { inDragLayer: !0 }), + (e.dragData.didDrag = !0)); + var ie = { x: 0, y: 0 }; + if (x(g[0]) && x(g[1])) + if (((ie.x += g[0]), (ie.y += g[1]), re)) + (e.redrawHint("eles", !0), + (ae = e.touchData.dragDelta) && + x(ae[0]) && + x(ae[1]) && + ((ie.x += ae[0]), (ie.y += ae[1]))); + ((e.hoverData.draggingEles = !0), + ee.silentShift(ie).emit("position drag"), + e.redrawHint("drag", !0), + e.touchData.startPosition[0] == l[0] && + e.touchData.startPosition[1] == l[1] && + e.redrawHint("eles", !0), + e.redraw()); + } else { + var ae; + 0 === + (ae = e.touchData.dragDelta = e.touchData.dragDelta || []) + .length + ? (ae.push(g[0]), ae.push(g[1])) + : ((ae[0] += g[0]), (ae[1] += g[1])); + } + if ( + (r(te || R, ["touchmove", "tapdrag", "vmousemove"], t, { + x: s[0], + y: s[1], + }), + (te && te.grabbed()) || + R == ne || + (ne && + ne.emit({ + originalEvent: t, + type: "tapdragout", + position: { x: s[0], y: s[1] }, + }), + R && + R.emit({ + originalEvent: t, + type: "tapdragover", + position: { x: s[0], y: s[1] }, + })), + (e.touchData.last = R), + n) + ) + for (V = 0; V < s.length; V++) + s[V] && + e.touchData.startPosition[V] && + p && + (e.touchData.singleTouchMoved = !0); + if ( + n && + (null == te || te.pannable()) && + o.panningEnabled() && + o.userPanningEnabled() + ) { + a(te, e.touchData.starts) && + (t.preventDefault(), + e.data.bgActivePosistion || + (e.data.bgActivePosistion = bt( + e.touchData.startPosition, + )), + e.swipePanning + ? (o.panBy({ x: g[0] * c, y: g[1] * c }), + o.emit("dragpan")) + : p && + ((e.swipePanning = !0), + o.panBy({ x: y * c, y: b * c }), + o.emit("dragpan"), + te && + (te.unactivate(), + e.redrawHint("select", !0), + (e.touchData.start = null)))); + h = e.projectIntoViewport( + t.touches[0].clientX, + t.touches[0].clientY, + ); + ((s[0] = h[0]), (s[1] = h[1])); + } + } + for (v = 0; v < s.length; v++) l[v] = s[v]; + n && + t.touches.length > 0 && + !e.hoverData.draggingEles && + !e.swipePanning && + null != e.data.bgActivePosistion && + ((e.data.bgActivePosistion = void 0), + e.redrawHint("select", !0), + e.redraw()); + } + }), + !1, + ), + e.registerBinding( + t, + "touchcancel", + (V = function (t) { + var n = e.touchData.start; + ((e.touchData.capture = !1), n && n.unactivate()); + }), + ), + e.registerBinding( + t, + "touchend", + (F = function (t) { + var i = e.touchData.start; + if (e.touchData.capture) { + (0 === t.touches.length && (e.touchData.capture = !1), + t.preventDefault()); + var a = e.selection; + ((e.swipePanning = !1), (e.hoverData.draggingEles = !1)); + var o, + s = e.cy, + l = s.zoom(), + u = e.touchData.now, + c = e.touchData.earlier; + if (t.touches[0]) { + var h = e.projectIntoViewport( + t.touches[0].clientX, + t.touches[0].clientY, + ); + ((u[0] = h[0]), (u[1] = h[1])); + } + if (t.touches[1]) { + h = e.projectIntoViewport( + t.touches[1].clientX, + t.touches[1].clientY, + ); + ((u[2] = h[0]), (u[3] = h[1])); + } + if (t.touches[2]) { + h = e.projectIntoViewport( + t.touches[2].clientX, + t.touches[2].clientY, + ); + ((u[4] = h[0]), (u[5] = h[1])); + } + if ((i && i.unactivate(), e.touchData.cxt)) { + if ( + ((o = { + originalEvent: t, + type: "cxttapend", + position: { x: u[0], y: u[1] }, + }), + i ? i.emit(o) : s.emit(o), + !e.touchData.cxtDragged) + ) { + var p = { + originalEvent: t, + type: "cxttap", + position: { x: u[0], y: u[1] }, + }; + i ? i.emit(p) : s.emit(p); + } + return ( + e.touchData.start && + (e.touchData.start._private.grabbed = !1), + (e.touchData.cxt = !1), + (e.touchData.start = null), + void e.redraw() + ); + } + if ( + !t.touches[2] && + s.boxSelectionEnabled() && + e.touchData.selecting + ) { + e.touchData.selecting = !1; + var f = s.collection(e.getAllInBox(a[0], a[1], a[2], a[3])); + ((a[0] = void 0), + (a[1] = void 0), + (a[2] = void 0), + (a[3] = void 0), + (a[4] = 0), + e.redrawHint("select", !0), + s.emit({ + type: "boxend", + originalEvent: t, + position: { x: u[0], y: u[1] }, + })); + (f + .emit("box") + .stdFilter(function (e) { + return e.selectable() && !e.selected(); + }) + .select() + .emit("boxselect"), + f.nonempty() && e.redrawHint("eles", !0), + e.redraw()); + } + if ((null != i && i.unactivate(), t.touches[2])) + ((e.data.bgActivePosistion = void 0), + e.redrawHint("select", !0)); + else if (t.touches[1]); + else if (t.touches[0]); + else if (!t.touches[0]) { + ((e.data.bgActivePosistion = void 0), + e.redrawHint("select", !0)); + var g = e.dragData.touchDragEles; + if (null != i) { + var v = i._private.grabbed; + (d(g), + e.redrawHint("drag", !0), + e.redrawHint("eles", !0), + v && + (i.emit("freeon"), + g.emit("free"), + e.dragData.didDrag && + (i.emit("dragfreeon"), g.emit("dragfree"))), + r(i, ["touchend", "tapend", "vmouseup", "tapdragout"], t, { + x: u[0], + y: u[1], + }), + i.unactivate(), + (e.touchData.start = null)); + } else { + var y = e.findNearestElement(u[0], u[1], !0, !0); + r(y, ["touchend", "tapend", "vmouseup", "tapdragout"], t, { + x: u[0], + y: u[1], + }); + } + var m = e.touchData.startPosition[0] - u[0], + b = m * m, + x = e.touchData.startPosition[1] - u[1], + w = (b + x * x) * l * l; + (e.touchData.singleTouchMoved || + (i || s.$(":selected").unselect(["tapunselect"]), + r(i, ["tap", "vclick"], t, { x: u[0], y: u[1] }), + (j = !1), + t.timeStamp - Y <= s.multiClickDebounceTime() + ? (q && clearTimeout(q), + (j = !0), + (Y = null), + r(i, ["dbltap", "vdblclick"], t, { x: u[0], y: u[1] })) + : ((q = setTimeout(function () { + j || + r(i, ["onetap", "voneclick"], t, { + x: u[0], + y: u[1], + }); + }, s.multiClickDebounceTime())), + (Y = t.timeStamp))), + null != i && + !e.dragData.didDrag && + i._private.selectable && + w < e.touchTapThreshold2 && + !e.pinching && + ("single" === s.selectionType() + ? (s.$(n).unmerge(i).unselect(["tapunselect"]), + i.select(["tapselect"])) + : i.selected() + ? i.unselect(["tapunselect"]) + : i.select(["tapselect"]), + e.redrawHint("eles", !0)), + (e.touchData.singleTouchMoved = !0)); + } + for (var E = 0; E < u.length; E++) c[E] = u[E]; + ((e.dragData.didDrag = !1), + 0 === t.touches.length && + ((e.touchData.dragDelta = []), + (e.touchData.startPosition = [ + null, + null, + null, + null, + null, + null, + ]), + (e.touchData.startGPosition = null), + (e.touchData.didSelect = !1)), + t.touches.length < 2 && + (1 === t.touches.length && + (e.touchData.startGPosition = [ + t.touches[0].clientX, + t.touches[0].clientY, + ]), + (e.pinching = !1), + e.redrawHint("eles", !0), + e.redraw())); + } + }), + !1, + ), + "undefined" == typeof TouchEvent) + ) { + var H = [], + K = function (e) { + return { + clientX: e.clientX, + clientY: e.clientY, + force: 1, + identifier: e.pointerId, + pageX: e.pageX, + pageY: e.pageY, + radiusX: e.width / 2, + radiusY: e.height / 2, + screenX: e.screenX, + screenY: e.screenY, + target: e.target, + }; + }, + G = function (e) { + H.push( + (function (e) { + return { event: e, touch: K(e) }; + })(e), + ); + }, + U = function (e) { + for (var t = 0; t < H.length; t++) { + if (H[t].event.pointerId === e.pointerId) + return void H.splice(t, 1); + } + }, + Z = function (e) { + e.touches = H.map(function (e) { + return e.touch; + }); + }, + $ = function (e) { + return "mouse" === e.pointerType || 4 === e.pointerType; + }; + (e.registerBinding(e.container, "pointerdown", function (e) { + $(e) || (e.preventDefault(), G(e), Z(e), O(e)); + }), + e.registerBinding(e.container, "pointerup", function (e) { + $(e) || (U(e), Z(e), F(e)); + }), + e.registerBinding(e.container, "pointercancel", function (e) { + $(e) || (U(e), Z(e), V()); + }), + e.registerBinding(e.container, "pointermove", function (e) { + $(e) || + (e.preventDefault(), + (function (e) { + var t = H.filter(function (t) { + return t.event.pointerId === e.pointerId; + })[0]; + ((t.event = e), (t.touch = K(e))); + })(e), + Z(e), + R(e)); + })); + } + })); + var gu = { + generatePolygon: function (e, t) { + return (this.nodeShapes[e] = { + renderer: this, + name: e, + points: t, + draw: function (e, t, n, r, i, a) { + this.renderer.nodeShapeImpl("polygon", e, t, n, r, i, this.points); + }, + intersectLine: function (e, t, n, r, i, a, o, s) { + return $t(i, a, this.points, e, t, n / 2, r / 2, o); + }, + checkPoint: function (e, t, n, r, i, a, o, s) { + return Xt(e, t, this.points, a, o, r, i, [0, -1], n); + }, + }); + }, + }; + ((gu.generateEllipse = function () { + return (this.nodeShapes.ellipse = { + renderer: this, + name: "ellipse", + draw: function (e, t, n, r, i, a) { + this.renderer.nodeShapeImpl(this.name, e, t, n, r, i); + }, + intersectLine: function (e, t, n, r, i, a, o, s) { + return (function (e, t, n, r, i, a) { + var o = n - e, + s = r - t; + ((o /= i), (s /= a)); + var l = Math.sqrt(o * o + s * s), + u = l - 1; + if (u < 0) return []; + var c = u / l; + return [(n - e) * c + e, (r - t) * c + t]; + })(i, a, e, t, n / 2 + o, r / 2 + o); + }, + checkPoint: function (e, t, n, r, i, a, o, s) { + return Kt(e, t, r, i, a, o, n); + }, + }); + }), + (gu.generateRoundPolygon = function (e, t) { + return (this.nodeShapes[e] = { + renderer: this, + name: e, + points: t, + getOrCreateCorners: function (e, n, r, i, a, o, s) { + if (void 0 !== o[s] && o[s + "-cx"] === e && o[s + "-cy"] === n) + return o[s]; + ((o[s] = new Array(t.length / 2)), + (o[s + "-cx"] = e), + (o[s + "-cy"] = n)); + var l = r / 2, + u = i / 2; + a = "auto" === a ? rn(r, i) : a; + for (var c = new Array(t.length / 2), d = 0; d < t.length / 2; d++) + c[d] = { x: e + l * t[2 * d], y: n + u * t[2 * d + 1] }; + var h, + p, + f, + g, + v = c.length; + for (p = c[v - 1], h = 0; h < v; h++) + ((f = c[h % v]), + (g = c[(h + 1) % v]), + (o[s][h] = Jl(p, f, g, a)), + (p = f), + (f = g)); + return o[s]; + }, + draw: function (e, t, n, r, i, a, o) { + this.renderer.nodeShapeImpl( + "round-polygon", + e, + t, + n, + r, + i, + this.points, + this.getOrCreateCorners(t, n, r, i, a, o, "drawCorners"), + ); + }, + intersectLine: function (e, t, n, r, i, a, o, s, l) { + return (function (e, t, n, r, i, a, o, s, l) { + var u, + c = [], + d = new Array(2 * n.length); + l.forEach(function (n, a) { + (0 === a + ? ((d[d.length - 2] = n.startX), (d[d.length - 1] = n.startY)) + : ((d[4 * a - 2] = n.startX), (d[4 * a - 1] = n.startY)), + (d[4 * a] = n.stopX), + (d[4 * a + 1] = n.stopY), + 0 !== (u = Gt(e, t, r, i, n.cx, n.cy, n.radius)).length && + c.push(u[0], u[1])); + }); + for (var h = 0; h < d.length / 4; h++) + 0 !== + (u = Zt( + e, + t, + r, + i, + d[4 * h], + d[4 * h + 1], + d[4 * h + 2], + d[4 * h + 3], + !1, + )).length && c.push(u[0], u[1]); + if (c.length > 2) { + for ( + var p = [c[0], c[1]], + f = Math.pow(p[0] - e, 2) + Math.pow(p[1] - t, 2), + g = 1; + g < c.length / 2; + g++ + ) { + var v = + Math.pow(c[2 * g] - e, 2) + Math.pow(c[2 * g + 1] - t, 2); + v <= f && ((p[0] = c[2 * g]), (p[1] = c[2 * g + 1]), (f = v)); + } + return p; + } + return c; + })( + i, + a, + this.points, + e, + t, + 0, + 0, + 0, + this.getOrCreateCorners(e, t, n, r, s, l, "corners"), + ); + }, + checkPoint: function (e, t, n, r, i, a, o, s, l) { + return (function (e, t, n, r, i, a, o, s) { + for (var l = new Array(2 * n.length), u = 0; u < s.length; u++) { + var c = s[u]; + if ( + ((l[4 * u + 0] = c.startX), + (l[4 * u + 1] = c.startY), + (l[4 * u + 2] = c.stopX), + (l[4 * u + 3] = c.stopY), + Math.pow(c.cx - e, 2) + Math.pow(c.cy - t, 2) <= + Math.pow(c.radius, 2)) + ) + return !0; + } + return Yt(e, t, l); + })( + e, + t, + this.points, + 0, + 0, + 0, + 0, + this.getOrCreateCorners(a, o, r, i, s, l, "corners"), + ); + }, + }); + }), + (gu.generateRoundRectangle = function () { + return (this.nodeShapes["round-rectangle"] = + this.nodeShapes.roundrectangle = + { + renderer: this, + name: "round-rectangle", + points: Jt(4, 0), + draw: function (e, t, n, r, i, a) { + this.renderer.nodeShapeImpl( + this.name, + e, + t, + n, + r, + i, + this.points, + a, + ); + }, + intersectLine: function (e, t, n, r, i, a, o, s) { + return Rt(i, a, e, t, n, r, o, s); + }, + checkPoint: function (e, t, n, r, i, a, o, s) { + var l = r / 2, + u = i / 2; + s = "auto" === s ? nn(r, i) : s; + var c = 2 * (s = Math.min(l, u, s)); + return ( + !!Xt(e, t, this.points, a, o, r, i - c, [0, -1], n) || + !!Xt(e, t, this.points, a, o, r - c, i, [0, -1], n) || + !!Kt(e, t, c, c, a - l + s, o - u + s, n) || + !!Kt(e, t, c, c, a + l - s, o - u + s, n) || + !!Kt(e, t, c, c, a + l - s, o + u - s, n) || + !!Kt(e, t, c, c, a - l + s, o + u - s, n) + ); + }, + }); + }), + (gu.generateCutRectangle = function () { + return (this.nodeShapes["cut-rectangle"] = this.nodeShapes.cutrectangle = + { + renderer: this, + name: "cut-rectangle", + cornerLength: 8, + points: Jt(4, 0), + draw: function (e, t, n, r, i, a) { + this.renderer.nodeShapeImpl(this.name, e, t, n, r, i, null, a); + }, + generateCutTrianglePts: function (e, t, n, r, i) { + var a = "auto" === i ? this.cornerLength : i, + o = t / 2, + s = e / 2, + l = n - s, + u = n + s, + c = r - o, + d = r + o; + return { + topLeft: [l, c + a, l + a, c, l + a, c + a], + topRight: [u - a, c, u, c + a, u - a, c + a], + bottomRight: [u, d - a, u - a, d, u - a, d - a], + bottomLeft: [l + a, d, l, d - a, l + a, d - a], + }; + }, + intersectLine: function (e, t, n, r, i, a, o, s) { + var l = this.generateCutTrianglePts(n + 2 * o, r + 2 * o, e, t, s), + u = [].concat.apply( + [], + [ + l.topLeft.splice(0, 4), + l.topRight.splice(0, 4), + l.bottomRight.splice(0, 4), + l.bottomLeft.splice(0, 4), + ], + ); + return $t(i, a, u, e, t); + }, + checkPoint: function (e, t, n, r, i, a, o, s) { + var l = "auto" === s ? this.cornerLength : s; + if (Xt(e, t, this.points, a, o, r, i - 2 * l, [0, -1], n)) + return !0; + if (Xt(e, t, this.points, a, o, r - 2 * l, i, [0, -1], n)) + return !0; + var u = this.generateCutTrianglePts(r, i, a, o); + return ( + Yt(e, t, u.topLeft) || + Yt(e, t, u.topRight) || + Yt(e, t, u.bottomRight) || + Yt(e, t, u.bottomLeft) + ); + }, + }); + }), + (gu.generateBarrel = function () { + return (this.nodeShapes.barrel = { + renderer: this, + name: "barrel", + points: Jt(4, 0), + draw: function (e, t, n, r, i, a) { + this.renderer.nodeShapeImpl(this.name, e, t, n, r, i); + }, + intersectLine: function (e, t, n, r, i, a, o, s) { + var l = this.generateBarrelBezierPts(n + 2 * o, r + 2 * o, e, t), + u = function (e) { + var t = Dt( + { x: e[0], y: e[1] }, + { x: e[2], y: e[3] }, + { x: e[4], y: e[5] }, + 0.15, + ), + n = Dt( + { x: e[0], y: e[1] }, + { x: e[2], y: e[3] }, + { x: e[4], y: e[5] }, + 0.5, + ), + r = Dt( + { x: e[0], y: e[1] }, + { x: e[2], y: e[3] }, + { x: e[4], y: e[5] }, + 0.85, + ); + return [e[0], e[1], t.x, t.y, n.x, n.y, r.x, r.y, e[4], e[5]]; + }, + c = [].concat( + u(l.topLeft), + u(l.topRight), + u(l.bottomRight), + u(l.bottomLeft), + ); + return $t(i, a, c, e, t); + }, + generateBarrelBezierPts: function (e, t, n, r) { + var i = t / 2, + a = e / 2, + o = n - a, + s = n + a, + l = r - i, + u = r + i, + c = an(e, t), + d = c.heightOffset, + h = c.widthOffset, + p = c.ctrlPtOffsetPct * e, + f = { + topLeft: [o, l + d, o + p, l, o + h, l], + topRight: [s - h, l, s - p, l, s, l + d], + bottomRight: [s, u - d, s - p, u, s - h, u], + bottomLeft: [o + h, u, o + p, u, o, u - d], + }; + return ( + (f.topLeft.isTop = !0), + (f.topRight.isTop = !0), + (f.bottomLeft.isBottom = !0), + (f.bottomRight.isBottom = !0), + f + ); + }, + checkPoint: function (e, t, n, r, i, a, o, s) { + var l = an(r, i), + u = l.heightOffset, + c = l.widthOffset; + if (Xt(e, t, this.points, a, o, r, i - 2 * u, [0, -1], n)) return !0; + if (Xt(e, t, this.points, a, o, r - 2 * c, i, [0, -1], n)) return !0; + for ( + var d = this.generateBarrelBezierPts(r, i, a, o), + h = function (e, t, n) { + var r, + i, + a = n[4], + o = n[2], + s = n[0], + l = n[5], + u = n[1], + c = Math.min(a, s), + d = Math.max(a, s), + h = Math.min(l, u), + p = Math.max(l, u); + if (c <= e && e <= d && h <= t && t <= p) { + var f = [(r = a) - 2 * (i = o) + s, 2 * (i - r), r], + g = (function (e, t, n, r) { + var i = t * t - 4 * e * (n -= r); + if (i < 0) return []; + var a = Math.sqrt(i), + o = 2 * e; + return [(-t + a) / o, (-t - a) / o]; + })(f[0], f[1], f[2], e).filter(function (e) { + return 0 <= e && e <= 1; + }); + if (g.length > 0) return g[0]; + } + return null; + }, + p = Object.keys(d), + f = 0; + f < p.length; + f++ + ) { + var g = d[p[f]], + v = h(e, t, g); + if (null != v) { + var y = g[5], + m = g[3], + b = g[1], + x = Pt(y, m, b, v); + if (g.isTop && x <= t) return !0; + if (g.isBottom && t <= x) return !0; + } + } + return !1; + }, + }); + }), + (gu.generateBottomRoundrectangle = function () { + return (this.nodeShapes["bottom-round-rectangle"] = + this.nodeShapes.bottomroundrectangle = + { + renderer: this, + name: "bottom-round-rectangle", + points: Jt(4, 0), + draw: function (e, t, n, r, i, a) { + this.renderer.nodeShapeImpl( + this.name, + e, + t, + n, + r, + i, + this.points, + a, + ); + }, + intersectLine: function (e, t, n, r, i, a, o, s) { + var l = t - (r / 2 + o), + u = Zt(i, a, e, t, e - (n / 2 + o), l, e + (n / 2 + o), l, !1); + return u.length > 0 ? u : Rt(i, a, e, t, n, r, o, s); + }, + checkPoint: function (e, t, n, r, i, a, o, s) { + var l = 2 * (s = "auto" === s ? nn(r, i) : s); + if (Xt(e, t, this.points, a, o, r, i - l, [0, -1], n)) return !0; + if (Xt(e, t, this.points, a, o, r - l, i, [0, -1], n)) return !0; + var u = r / 2 + 2 * n, + c = i / 2 + 2 * n; + return ( + !!Yt(e, t, [a - u, o - c, a - u, o, a + u, o, a + u, o - c]) || + !!Kt(e, t, l, l, a + r / 2 - s, o + i / 2 - s, n) || + !!Kt(e, t, l, l, a - r / 2 + s, o + i / 2 - s, n) + ); + }, + }); + }), + (gu.registerNodeShapes = function () { + var e = (this.nodeShapes = {}), + t = this; + (this.generateEllipse(), + this.generatePolygon("triangle", Jt(3, 0)), + this.generateRoundPolygon("round-triangle", Jt(3, 0)), + this.generatePolygon("rectangle", Jt(4, 0)), + (e.square = e.rectangle), + this.generateRoundRectangle(), + this.generateCutRectangle(), + this.generateBarrel(), + this.generateBottomRoundrectangle()); + var n = [0, 1, 1, 0, 0, -1, -1, 0]; + (this.generatePolygon("diamond", n), + this.generateRoundPolygon("round-diamond", n), + this.generatePolygon("pentagon", Jt(5, 0)), + this.generateRoundPolygon("round-pentagon", Jt(5, 0)), + this.generatePolygon("hexagon", Jt(6, 0)), + this.generateRoundPolygon("round-hexagon", Jt(6, 0)), + this.generatePolygon("heptagon", Jt(7, 0)), + this.generateRoundPolygon("round-heptagon", Jt(7, 0)), + this.generatePolygon("octagon", Jt(8, 0)), + this.generateRoundPolygon("round-octagon", Jt(8, 0))); + var r = new Array(20), + i = tn(5, 0), + a = tn(5, Math.PI / 5), + o = 0.5 * (3 - Math.sqrt(5)); + o *= 1.57; + for (var s = 0; s < a.length / 2; s++) + ((a[2 * s] *= o), (a[2 * s + 1] *= o)); + for (s = 0; s < 5; s++) + ((r[4 * s] = i[2 * s]), + (r[4 * s + 1] = i[2 * s + 1]), + (r[4 * s + 2] = a[2 * s]), + (r[4 * s + 3] = a[2 * s + 1])); + ((r = en(r)), + this.generatePolygon("star", r), + this.generatePolygon("vee", [-1, -1, 0, -0.333, 1, -1, 0, 1]), + this.generatePolygon("rhomboid", [-1, -1, 0.333, -1, 1, 1, -0.333, 1]), + this.generatePolygon( + "right-rhomboid", + [-0.333, -1, 1, -1, 0.333, 1, -1, 1], + ), + (this.nodeShapes.concavehexagon = this.generatePolygon( + "concave-hexagon", + [-1, -0.95, -0.75, 0, -1, 0.95, 1, 0.95, 0.75, 0, 1, -0.95], + ))); + var l = [-1, -1, 0.25, -1, 1, 0, 0.25, 1, -1, 1]; + (this.generatePolygon("tag", l), + this.generateRoundPolygon("round-tag", l), + (e.makePolygon = function (e) { + var n, + r = "polygon-" + e.join("$"); + return (n = this[r]) ? n : t.generatePolygon(r, e); + })); + })); + var vu = { + timeToRender: function () { + return this.redrawTotalTime / this.redrawCount; + }, + redraw: function (e) { + e = e || We(); + var t = this; + (void 0 === t.averageRedrawTime && (t.averageRedrawTime = 0), + void 0 === t.lastRedrawTime && (t.lastRedrawTime = 0), + void 0 === t.lastDrawTime && (t.lastDrawTime = 0), + (t.requestedFrame = !0), + (t.renderOptions = e)); + }, + beforeRender: function (e, t) { + if (!this.destroyed) { + null == t && Ve("Priority is not optional for beforeRender"); + var n = this.beforeRenderCallbacks; + (n.push({ fn: e, priority: t }), + n.sort(function (e, t) { + return t.priority - e.priority; + })); + } + }, + }, + yu = function (e, t, n) { + for (var r = e.beforeRenderCallbacks, i = 0; i < r.length; i++) + r[i].fn(t, n); + }; + vu.startRenderLoop = function () { + var e = this, + t = e.cy; + if (!e.renderLoopStarted) { + e.renderLoopStarted = !0; + xe(function n(r) { + if (!e.destroyed) { + if (t.batching()); + else if (e.requestedFrame && !e.skipFrame) { + yu(e, !0, r); + var i = we(); + e.render(e.renderOptions); + var a = (e.lastDrawTime = we()); + (void 0 === e.averageRedrawTime && (e.averageRedrawTime = a - i), + void 0 === e.redrawCount && (e.redrawCount = 0), + e.redrawCount++, + void 0 === e.redrawTotalTime && (e.redrawTotalTime = 0)); + var o = a - i; + ((e.redrawTotalTime += o), + (e.lastRedrawTime = o), + (e.averageRedrawTime = e.averageRedrawTime / 2 + o / 2), + (e.requestedFrame = !1)); + } else yu(e, !1, r); + ((e.skipFrame = !1), xe(n)); + } + }); + } + }; + var mu = function (e) { + this.init(e); + }, + bu = mu.prototype; + ((bu.clientFunctions = [ + "redrawHint", + "render", + "renderTo", + "matchCanvasSize", + "nodeShapeImpl", + "arrowShapeImpl", + ]), + (bu.init = function (e) { + var t = this; + ((t.options = e), (t.cy = e.cy)); + var n = (t.container = e.cy.container()), + r = t.cy.window(); + if (r) { + var i = r.document, + a = i.head, + o = "__________cytoscape_container", + s = null != i.getElementById("__________cytoscape_stylesheet"); + if ( + (n.className.indexOf(o) < 0 && + (n.className = (n.className || "") + " " + o), + !s) + ) { + var l = i.createElement("style"); + ((l.id = "__________cytoscape_stylesheet"), + (l.textContent = "." + o + " { position: relative; }"), + a.insertBefore(l, a.children[0])); + } + "static" === r.getComputedStyle(n).getPropertyValue("position") && + je( + "A Cytoscape container has style position:static and so can not use UI extensions properly", + ); + } + ((t.selection = [void 0, void 0, void 0, void 0, 0]), + (t.bezierProjPcts = [0.05, 0.225, 0.4, 0.5, 0.6, 0.775, 0.95]), + (t.hoverData = { + down: null, + last: null, + downTime: null, + triggerMode: null, + dragging: !1, + initialPan: [null, null], + capture: !1, + }), + (t.dragData = { possibleDragElements: [] }), + (t.touchData = { + start: null, + capture: !1, + startPosition: [null, null, null, null, null, null], + singleTouchStartTime: null, + singleTouchMoved: !0, + now: [null, null, null, null, null, null], + earlier: [null, null, null, null, null, null], + }), + (t.redraws = 0), + (t.showFps = e.showFps), + (t.debug = e.debug), + (t.hideEdgesOnViewport = e.hideEdgesOnViewport), + (t.textureOnViewport = e.textureOnViewport), + (t.wheelSensitivity = e.wheelSensitivity), + (t.motionBlurEnabled = e.motionBlur), + (t.forcedPixelRatio = x(e.pixelRatio) ? e.pixelRatio : null), + (t.motionBlur = e.motionBlur), + (t.motionBlurOpacity = e.motionBlurOpacity), + (t.motionBlurTransparency = 1 - t.motionBlurOpacity), + (t.motionBlurPxRatio = 1), + (t.mbPxRBlurry = 1), + (t.minMbLowQualFrames = 4), + (t.fullQualityMb = !1), + (t.clearedForMotionBlur = []), + (t.desktopTapThreshold = e.desktopTapThreshold), + (t.desktopTapThreshold2 = + e.desktopTapThreshold * e.desktopTapThreshold), + (t.touchTapThreshold = e.touchTapThreshold), + (t.touchTapThreshold2 = e.touchTapThreshold * e.touchTapThreshold), + (t.tapholdDuration = 500), + (t.bindings = []), + (t.beforeRenderCallbacks = []), + (t.beforeRenderPriorities = { + animations: 400, + eleCalcs: 300, + eleTxrDeq: 200, + lyrTxrDeq: 150, + lyrTxrSkip: 100, + }), + t.registerNodeShapes(), + t.registerArrowShapes(), + t.registerCalculationListeners()); + }), + (bu.notify = function (e, t) { + var n = this, + r = n.cy; + this.destroyed || + ("init" !== e + ? "destroy" !== e + ? (("add" === e || + "remove" === e || + ("move" === e && r.hasCompoundNodes()) || + "load" === e || + "zorder" === e || + "mount" === e) && + n.invalidateCachedZSortedEles(), + "viewport" === e && n.redrawHint("select", !0), + ("load" !== e && "resize" !== e && "mount" !== e) || + (n.invalidateContainerClientCoordsCache(), + n.matchCanvasSize(n.container)), + n.redrawHint("eles", !0), + n.redrawHint("drag", !0), + this.startRenderLoop(), + this.redraw()) + : n.destroy() + : n.load()); + }), + (bu.destroy = function () { + var e = this; + ((e.destroyed = !0), e.cy.stopAnimationLoop()); + for (var t = 0; t < e.bindings.length; t++) { + var n = e.bindings[t], + r = n.target; + (r.off || r.removeEventListener).apply(r, n.args); + } + if ( + ((e.bindings = []), + (e.beforeRenderCallbacks = []), + (e.onUpdateEleCalcsFns = []), + e.removeObserver && e.removeObserver.disconnect(), + e.styleObserver && e.styleObserver.disconnect(), + e.resizeObserver && e.resizeObserver.disconnect(), + e.labelCalcDiv) + ) + try { + document.body.removeChild(e.labelCalcDiv); + } catch (e) {} + }), + (bu.isHeadless = function () { + return !1; + }), + [Tl, hu, pu, fu, gu, vu].forEach(function (e) { + L(bu, e); + })); + var xu = function (e) { + return function () { + var t = this, + n = this.renderer; + if (!t.dequeueingSetup) { + t.dequeueingSetup = !0; + var r = ve(function () { + (n.redrawHint("eles", !0), n.redrawHint("drag", !0), n.redraw()); + }, e.deqRedrawThreshold), + i = e.priority || Re; + n.beforeRender(function (i, a) { + var o = we(), + s = n.averageRedrawTime, + l = n.lastRedrawTime, + u = [], + c = n.cy.extent(), + d = n.getPixelRatio(); + for (i || n.flushRenderedStyleQueue(); ; ) { + var h = we(), + p = h - o, + f = h - a; + if (l < 1e3 / 60) { + var g = 1e3 / 60 - (i ? s : 0); + if (f >= e.deqFastCost * g) break; + } else if (i) { + if (p >= e.deqCost * l || p >= e.deqAvgCost * s) break; + } else if (f >= e.deqNoDrawCost * (1e3 / 60)) break; + var v = e.deq(t, d, c); + if (!(v.length > 0)) break; + for (var y = 0; y < v.length; y++) u.push(v[y]); + } + u.length > 0 && + (e.onDeqd(t, u), !i && e.shouldRedraw(t, u, d, c) && r()); + }, i(t)); + } + }; + }, + wu = (function () { + function e(n) { + var r = + arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : Le; + (t(this, e), + (this.idsByKey = new $e()), + (this.keyForId = new $e()), + (this.cachesByLvl = new $e()), + (this.lvls = []), + (this.getKey = n), + (this.doesEleInvalidateKey = r)); + } + return ( + r(e, [ + { + key: "getIdsFor", + value: function (e) { + null == e && Ve("Can not get id list for null key"); + var t = this.idsByKey, + n = this.idsByKey.get(e); + return (n || ((n = new Je()), t.set(e, n)), n); + }, + }, + { + key: "addIdForKey", + value: function (e, t) { + null != e && this.getIdsFor(e).add(t); + }, + }, + { + key: "deleteIdForKey", + value: function (e, t) { + null != e && this.getIdsFor(e).delete(t); + }, + }, + { + key: "getNumberOfIdsForKey", + value: function (e) { + return null == e ? 0 : this.getIdsFor(e).size; + }, + }, + { + key: "updateKeyMappingFor", + value: function (e) { + var t = e.id(), + n = this.keyForId.get(t), + r = this.getKey(e); + (this.deleteIdForKey(n, t), + this.addIdForKey(r, t), + this.keyForId.set(t, r)); + }, + }, + { + key: "deleteKeyMappingFor", + value: function (e) { + var t = e.id(), + n = this.keyForId.get(t); + (this.deleteIdForKey(n, t), this.keyForId.delete(t)); + }, + }, + { + key: "keyHasChangedFor", + value: function (e) { + var t = e.id(); + return this.keyForId.get(t) !== this.getKey(e); + }, + }, + { + key: "isInvalid", + value: function (e) { + return this.keyHasChangedFor(e) || this.doesEleInvalidateKey(e); + }, + }, + { + key: "getCachesAt", + value: function (e) { + var t = this.cachesByLvl, + n = this.lvls, + r = t.get(e); + return (r || ((r = new $e()), t.set(e, r), n.push(e)), r); + }, + }, + { + key: "getCache", + value: function (e, t) { + return this.getCachesAt(t).get(e); + }, + }, + { + key: "get", + value: function (e, t) { + var n = this.getKey(e), + r = this.getCache(n, t); + return (null != r && this.updateKeyMappingFor(e), r); + }, + }, + { + key: "getForCachedKey", + value: function (e, t) { + var n = this.keyForId.get(e.id()); + return this.getCache(n, t); + }, + }, + { + key: "hasCache", + value: function (e, t) { + return this.getCachesAt(t).has(e); + }, + }, + { + key: "has", + value: function (e, t) { + var n = this.getKey(e); + return this.hasCache(n, t); + }, + }, + { + key: "setCache", + value: function (e, t, n) { + ((n.key = e), this.getCachesAt(t).set(e, n)); + }, + }, + { + key: "set", + value: function (e, t, n) { + var r = this.getKey(e); + (this.setCache(r, t, n), this.updateKeyMappingFor(e)); + }, + }, + { + key: "deleteCache", + value: function (e, t) { + this.getCachesAt(t).delete(e); + }, + }, + { + key: "delete", + value: function (e, t) { + var n = this.getKey(e); + this.deleteCache(n, t); + }, + }, + { + key: "invalidateKey", + value: function (e) { + var t = this; + this.lvls.forEach(function (n) { + return t.deleteCache(e, n); + }); + }, + }, + { + key: "invalidate", + value: function (e) { + var t = e.id(), + n = this.keyForId.get(t); + this.deleteKeyMappingFor(e); + var r = this.doesEleInvalidateKey(e); + return ( + r && this.invalidateKey(n), + r || 0 === this.getNumberOfIdsForKey(n) + ); + }, + }, + ]), + e + ); + })(), + Eu = { + dequeue: "dequeue", + downscale: "downscale", + highQuality: "highQuality", + }, + ku = He({ + getKey: null, + doesEleInvalidateKey: Le, + drawElement: null, + getBoundingBox: null, + getRotationPoint: null, + getRotationOffset: null, + isVisible: Ae, + allowEdgeTxrCaching: !0, + allowParentTxrCaching: !0, + }), + Cu = function (e, t) { + ((this.renderer = e), (this.onDequeues = [])); + var n = ku(t); + (L(this, n), + (this.lookup = new wu(n.getKey, n.doesEleInvalidateKey)), + this.setupDequeueing()); + }, + Su = Cu.prototype; + ((Su.reasons = Eu), + (Su.getTextureQueue = function (e) { + return ( + (this.eleImgCaches = this.eleImgCaches || {}), + (this.eleImgCaches[e] = this.eleImgCaches[e] || []) + ); + }), + (Su.getRetiredTextureQueue = function (e) { + var t = (this.eleImgCaches.retired = this.eleImgCaches.retired || {}); + return (t[e] = t[e] || []); + }), + (Su.getElementQueue = function () { + return (this.eleCacheQueue = + this.eleCacheQueue || + new rt(function (e, t) { + return t.reqs - e.reqs; + })); + }), + (Su.getElementKeyToQueue = function () { + return (this.eleKeyToCacheQueue = this.eleKeyToCacheQueue || {}); + }), + (Su.getElement = function (e, t, n, r, i) { + var a = this, + o = this.renderer, + s = o.cy.zoom(), + l = this.lookup; + if ( + !t || + 0 === t.w || + 0 === t.h || + isNaN(t.w) || + isNaN(t.h) || + !e.visible() || + e.removed() + ) + return null; + if ( + (!a.allowEdgeTxrCaching && e.isEdge()) || + (!a.allowParentTxrCaching && e.isParent()) + ) + return null; + if ((null == r && (r = Math.ceil(wt(s * n))), r < -4)) r = -4; + else if (s >= 7.99 || r > 3) return null; + var u = Math.pow(2, r), + c = t.h * u, + d = t.w * u, + h = o.eleTextBiggerThanMin(e, u); + if (!this.isVisible(e, h)) return null; + var p, + f = l.get(e, r); + if ( + (f && + f.invalidated && + ((f.invalidated = !1), (f.texture.invalidatedWidth -= f.width)), + f) + ) + return f; + if ( + ((p = c <= 25 ? 25 : c <= 50 ? 50 : 50 * Math.ceil(c / 50)), + c > 1024 || d > 1024) + ) + return null; + var g = a.getTextureQueue(p), + v = g[g.length - 2], + y = function () { + return a.recycleTexture(p, d) || a.addTexture(p, d); + }; + (v || (v = g[g.length - 1]), + v || (v = y()), + v.width - v.usedWidth < d && (v = y())); + for ( + var m, + b = function (e) { + return e && e.scaledLabelShown === h; + }, + x = i && i === Eu.dequeue, + w = i && i === Eu.highQuality, + E = i && i === Eu.downscale, + k = r + 1; + k <= 3; + k++ + ) { + var C = l.get(e, k); + if (C) { + m = C; + break; + } + } + var S = m && m.level === r + 1 ? m : null, + P = function () { + v.context.drawImage( + S.texture.canvas, + S.x, + 0, + S.width, + S.height, + v.usedWidth, + 0, + d, + c, + ); + }; + if ( + (v.context.setTransform(1, 0, 0, 1, 0, 0), + v.context.clearRect(v.usedWidth, 0, d, p), + b(S)) + ) + P(); + else if (b(m)) { + if (!w) return (a.queueElement(e, m.level - 1), m); + for (var D = m.level; D > r; D--) + S = a.getElement(e, t, n, D, Eu.downscale); + P(); + } else { + var T; + if (!x && !w && !E) + for (var _ = r - 1; _ >= -4; _--) { + var M = l.get(e, _); + if (M) { + T = M; + break; + } + } + if (b(T)) return (a.queueElement(e, r), T); + (v.context.translate(v.usedWidth, 0), + v.context.scale(u, u), + this.drawElement(v.context, e, t, h, !1), + v.context.scale(1 / u, 1 / u), + v.context.translate(-v.usedWidth, 0)); + } + return ( + (f = { + x: v.usedWidth, + texture: v, + level: r, + scale: u, + width: d, + height: c, + scaledLabelShown: h, + }), + (v.usedWidth += Math.ceil(d + 8)), + v.eleCaches.push(f), + l.set(e, r, f), + a.checkTextureFullness(v), + f + ); + }), + (Su.invalidateElements = function (e) { + for (var t = 0; t < e.length; t++) this.invalidateElement(e[t]); + }), + (Su.invalidateElement = function (e) { + var t = this.lookup, + n = []; + if (t.isInvalid(e)) { + for (var r = -4; r <= 3; r++) { + var i = t.getForCachedKey(e, r); + i && n.push(i); + } + if (t.invalidate(e)) + for (var a = 0; a < n.length; a++) { + var o = n[a], + s = o.texture; + ((s.invalidatedWidth += o.width), + (o.invalidated = !0), + this.checkTextureUtility(s)); + } + this.removeFromQueue(e); + } + }), + (Su.checkTextureUtility = function (e) { + e.invalidatedWidth >= 0.2 * e.width && this.retireTexture(e); + }), + (Su.checkTextureFullness = function (e) { + var t = this.getTextureQueue(e.height); + e.usedWidth / e.width > 0.8 && e.fullnessChecks >= 10 + ? Ke(t, e) + : e.fullnessChecks++; + }), + (Su.retireTexture = function (e) { + var t = e.height, + n = this.getTextureQueue(t), + r = this.lookup; + (Ke(n, e), (e.retired = !0)); + for (var i = e.eleCaches, a = 0; a < i.length; a++) { + var o = i[a]; + r.deleteCache(o.key, o.level); + } + (Ge(i), this.getRetiredTextureQueue(t).push(e)); + }), + (Su.addTexture = function (e, t) { + var n = {}; + return ( + this.getTextureQueue(e).push(n), + (n.eleCaches = []), + (n.height = e), + (n.width = Math.max(1024, t)), + (n.usedWidth = 0), + (n.invalidatedWidth = 0), + (n.fullnessChecks = 0), + (n.canvas = this.renderer.makeOffscreenCanvas(n.width, n.height)), + (n.context = n.canvas.getContext("2d")), + n + ); + }), + (Su.recycleTexture = function (e, t) { + for ( + var n = this.getTextureQueue(e), + r = this.getRetiredTextureQueue(e), + i = 0; + i < r.length; + i++ + ) { + var a = r[i]; + if (a.width >= t) + return ( + (a.retired = !1), + (a.usedWidth = 0), + (a.invalidatedWidth = 0), + (a.fullnessChecks = 0), + Ge(a.eleCaches), + a.context.setTransform(1, 0, 0, 1, 0, 0), + a.context.clearRect(0, 0, a.width, a.height), + Ke(r, a), + n.push(a), + a + ); + } + }), + (Su.queueElement = function (e, t) { + var n = this.getElementQueue(), + r = this.getElementKeyToQueue(), + i = this.getKey(e), + a = r[i]; + if (a) + ((a.level = Math.max(a.level, t)), + a.eles.merge(e), + a.reqs++, + n.updateItem(a)); + else { + var o = { eles: e.spawn().merge(e), level: t, reqs: 1, key: i }; + (n.push(o), (r[i] = o)); + } + }), + (Su.dequeue = function (e) { + for ( + var t = this.getElementQueue(), + n = this.getElementKeyToQueue(), + r = [], + i = this.lookup, + a = 0; + a < 1 && t.size() > 0; + a++ + ) { + var o = t.pop(), + s = o.key, + l = o.eles[0], + u = i.hasCache(l, o.level); + if (((n[s] = null), !u)) { + r.push(o); + var c = this.getBoundingBox(l); + this.getElement(l, c, e, o.level, Eu.dequeue); + } + } + return r; + }), + (Su.removeFromQueue = function (e) { + var t = this.getElementQueue(), + n = this.getElementKeyToQueue(), + r = this.getKey(e), + i = n[r]; + null != i && + (1 === i.eles.length + ? ((i.reqs = Ie), t.updateItem(i), t.pop(), (n[r] = null)) + : i.eles.unmerge(e)); + }), + (Su.onDequeue = function (e) { + this.onDequeues.push(e); + }), + (Su.offDequeue = function (e) { + Ke(this.onDequeues, e); + }), + (Su.setupDequeueing = xu({ + deqRedrawThreshold: 100, + deqCost: 0.15, + deqAvgCost: 0.1, + deqNoDrawCost: 0.9, + deqFastCost: 0.9, + deq: function (e, t, n) { + return e.dequeue(t, n); + }, + onDeqd: function (e, t) { + for (var n = 0; n < e.onDequeues.length; n++) { + (0, e.onDequeues[n])(t); + } + }, + shouldRedraw: function (e, t, n, r) { + for (var i = 0; i < t.length; i++) + for (var a = t[i].eles, o = 0; o < a.length; o++) { + var s = a[o].boundingBox(); + if (At(s, r)) return !0; + } + return !1; + }, + priority: function (e) { + return e.renderer.beforeRenderPriorities.eleTxrDeq; + }, + }))); + var Pu = function (e) { + var t = this, + n = (t.renderer = e), + r = n.cy; + ((t.layersByLevel = {}), + (t.firstGet = !0), + (t.lastInvalidationTime = we() - 500), + (t.skipping = !1), + (t.eleTxrDeqs = r.collection()), + (t.scheduleElementRefinement = ve(function () { + (t.refineElementTextures(t.eleTxrDeqs), + t.eleTxrDeqs.unmerge(t.eleTxrDeqs)); + }, 50)), + n.beforeRender(function (e, n) { + n - t.lastInvalidationTime <= 250 + ? (t.skipping = !0) + : (t.skipping = !1); + }, n.beforeRenderPriorities.lyrTxrSkip)); + ((t.layersQueue = new rt(function (e, t) { + return t.reqs - e.reqs; + })), + t.setupDequeueing()); + }, + Du = Pu.prototype, + Tu = 0, + _u = Math.pow(2, 53) - 1; + ((Du.makeLayer = function (e, t) { + var n = Math.pow(2, t), + r = Math.ceil(e.w * n), + i = Math.ceil(e.h * n), + a = this.renderer.makeOffscreenCanvas(r, i), + o = { + id: (Tu = ++Tu % _u), + bb: e, + level: t, + width: r, + height: i, + canvas: a, + context: a.getContext("2d"), + eles: [], + elesQueue: [], + reqs: 0, + }, + s = o.context, + l = -o.bb.x1, + u = -o.bb.y1; + return (s.scale(n, n), s.translate(l, u), o); + }), + (Du.getLayers = function (e, t, n) { + var r = this, + i = r.renderer.cy.zoom(), + a = r.firstGet; + if (((r.firstGet = !1), null == n)) + if ((n = Math.ceil(wt(i * t))) < -4) n = -4; + else if (i >= 3.99 || n > 2) return null; + r.validateLayersElesOrdering(n, e); + var o, + s, + l = r.layersByLevel, + u = Math.pow(2, n), + c = (l[n] = l[n] || []); + if (r.levelIsComplete(n, e)) return c; + !(function () { + var t = function (t) { + if ((r.validateLayersElesOrdering(t, e), r.levelIsComplete(t, e))) + return ((s = l[t]), !0); + }, + i = function (e) { + if (!s) for (var r = n + e; -4 <= r && r <= 2 && !t(r); r += e); + }; + (i(1), i(-1)); + for (var a = c.length - 1; a >= 0; a--) { + var o = c[a]; + o.invalid && Ke(c, o); + } + })(); + var d = function (t) { + var i = (t = t || {}).after; + if ( + ((function () { + if (!o) { + o = _t(); + for (var t = 0; t < e.length; t++) Mt(o, e[t].boundingBox()); + } + })(), + o.w * u * (o.h * u) > 16e6) + ) + return null; + var a = r.makeLayer(o, n); + if (null != i) { + var s = c.indexOf(i) + 1; + c.splice(s, 0, a); + } else (void 0 === t.insert || t.insert) && c.unshift(a); + return a; + }; + if (r.skipping && !a) return null; + for (var h = null, p = e.length / 1, f = !a, g = 0; g < e.length; g++) { + var v = e[g], + y = v._private.rscratch, + m = (y.imgLayerCaches = y.imgLayerCaches || {}), + b = m[n]; + if (b) h = b; + else { + if ( + (!h || h.eles.length >= p || !Ot(h.bb, v.boundingBox())) && + !(h = d({ insert: !0, after: h })) + ) + return null; + (s || f ? r.queueLayer(h, v) : r.drawEleInLayer(h, v, n, t), + h.eles.push(v), + (m[n] = h)); + } + } + return s || (f ? null : c); + }), + (Du.getEleLevelForLayerLevel = function (e, t) { + return e; + }), + (Du.drawEleInLayer = function (e, t, n, r) { + var i = this.renderer, + a = e.context, + o = t.boundingBox(); + 0 !== o.w && + 0 !== o.h && + t.visible() && + ((n = this.getEleLevelForLayerLevel(n, r)), + i.setImgSmoothing(a, !1), + i.drawCachedElement(a, t, null, null, n, !0), + i.setImgSmoothing(a, !0)); + }), + (Du.levelIsComplete = function (e, t) { + var n = this.layersByLevel[e]; + if (!n || 0 === n.length) return !1; + for (var r = 0, i = 0; i < n.length; i++) { + var a = n[i]; + if (a.reqs > 0) return !1; + if (a.invalid) return !1; + r += a.eles.length; + } + return r === t.length; + }), + (Du.validateLayersElesOrdering = function (e, t) { + var n = this.layersByLevel[e]; + if (n) + for (var r = 0; r < n.length; r++) { + for (var i = n[r], a = -1, o = 0; o < t.length; o++) + if (i.eles[0] === t[o]) { + a = o; + break; + } + if (a < 0) this.invalidateLayer(i); + else { + var s = a; + for (o = 0; o < i.eles.length; o++) + if (i.eles[o] !== t[s + o]) { + this.invalidateLayer(i); + break; + } + } + } + }), + (Du.updateElementsInLayers = function (e, t) { + for (var n = k(e[0]), r = 0; r < e.length; r++) + for ( + var i = n ? null : e[r], + a = n ? e[r] : e[r].ele, + o = a._private.rscratch, + s = (o.imgLayerCaches = o.imgLayerCaches || {}), + l = -4; + l <= 2; + l++ + ) { + var u = s[l]; + u && + ((i && this.getEleLevelForLayerLevel(u.level) !== i.level) || + t(u, a, i)); + } + }), + (Du.haveLayers = function () { + for (var e = !1, t = -4; t <= 2; t++) { + var n = this.layersByLevel[t]; + if (n && n.length > 0) { + e = !0; + break; + } + } + return e; + }), + (Du.invalidateElements = function (e) { + var t = this; + 0 !== e.length && + ((t.lastInvalidationTime = we()), + 0 !== e.length && + t.haveLayers() && + t.updateElementsInLayers(e, function (e, n, r) { + t.invalidateLayer(e); + })); + }), + (Du.invalidateLayer = function (e) { + if (((this.lastInvalidationTime = we()), !e.invalid)) { + var t = e.level, + n = e.eles, + r = this.layersByLevel[t]; + (Ke(r, e), + (e.elesQueue = []), + (e.invalid = !0), + e.replacement && (e.replacement.invalid = !0)); + for (var i = 0; i < n.length; i++) { + var a = n[i]._private.rscratch.imgLayerCaches; + a && (a[t] = null); + } + } + }), + (Du.refineElementTextures = function (e) { + var t = this; + t.updateElementsInLayers(e, function (e, n, r) { + var i = e.replacement; + if ( + (i || + (((i = e.replacement = t.makeLayer(e.bb, e.level)).replaces = e), + (i.eles = e.eles)), + !i.reqs) + ) + for (var a = 0; a < i.eles.length; a++) t.queueLayer(i, i.eles[a]); + }); + }), + (Du.enqueueElementRefinement = function (e) { + (this.eleTxrDeqs.merge(e), this.scheduleElementRefinement()); + }), + (Du.queueLayer = function (e, t) { + var n = this.layersQueue, + r = e.elesQueue, + i = (r.hasId = r.hasId || {}); + if (!e.replacement) { + if (t) { + if (i[t.id()]) return; + (r.push(t), (i[t.id()] = !0)); + } + e.reqs ? (e.reqs++, n.updateItem(e)) : ((e.reqs = 1), n.push(e)); + } + }), + (Du.dequeue = function (e) { + for (var t = this.layersQueue, n = [], r = 0; r < 1 && 0 !== t.size(); ) { + var i = t.peek(); + if (i.replacement) t.pop(); + else if (i.replaces && i !== i.replaces.replacement) t.pop(); + else if (i.invalid) t.pop(); + else { + var a = i.elesQueue.shift(); + (a && (this.drawEleInLayer(i, a, i.level, e), r++), + 0 === n.length && n.push(!0), + 0 === i.elesQueue.length && + (t.pop(), + (i.reqs = 0), + i.replaces && this.applyLayerReplacement(i), + this.requestRedraw())); + } + } + return n; + }), + (Du.applyLayerReplacement = function (e) { + var t = this.layersByLevel[e.level], + n = e.replaces, + r = t.indexOf(n); + if (!(r < 0 || n.invalid)) { + t[r] = e; + for (var i = 0; i < e.eles.length; i++) { + var a = e.eles[i]._private, + o = (a.imgLayerCaches = a.imgLayerCaches || {}); + o && (o[e.level] = e); + } + this.requestRedraw(); + } + }), + (Du.requestRedraw = ve(function () { + var e = this.renderer; + (e.redrawHint("eles", !0), e.redrawHint("drag", !0), e.redraw()); + }, 100)), + (Du.setupDequeueing = xu({ + deqRedrawThreshold: 50, + deqCost: 0.15, + deqAvgCost: 0.1, + deqNoDrawCost: 0.9, + deqFastCost: 0.9, + deq: function (e, t) { + return e.dequeue(t); + }, + onDeqd: Re, + shouldRedraw: Ae, + priority: function (e) { + return e.renderer.beforeRenderPriorities.lyrTxrDeq; + }, + }))); + var Mu, + Bu = {}; + function Nu(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + e.lineTo(r.x, r.y); + } + } + function zu(e, t, n) { + for (var r, i = 0; i < t.length; i++) { + var a = t[i]; + (0 === i && (r = a), e.lineTo(a.x, a.y)); + } + e.quadraticCurveTo(n.x, n.y, r.x, r.y); + } + function Iu(e, t, n) { + e.beginPath && e.beginPath(); + for (var r = t, i = 0; i < r.length; i++) { + var a = r[i]; + e.lineTo(a.x, a.y); + } + var o = n, + s = n[0]; + e.moveTo(s.x, s.y); + for (i = 1; i < o.length; i++) { + a = o[i]; + e.lineTo(a.x, a.y); + } + e.closePath && e.closePath(); + } + function Au(e, t, n, r, i) { + (e.beginPath && e.beginPath(), e.arc(n, r, i, 0, 2 * Math.PI, !1)); + var a = t, + o = a[0]; + e.moveTo(o.x, o.y); + for (var s = 0; s < a.length; s++) { + var l = a[s]; + e.lineTo(l.x, l.y); + } + e.closePath && e.closePath(); + } + function Lu(e, t, n, r) { + e.arc(t, n, r, 0, 2 * Math.PI, !1); + } + Bu.arrowShapeImpl = function (e) { + return (Mu || + (Mu = { + polygon: Nu, + "triangle-backcurve": zu, + "triangle-tee": Iu, + "circle-triangle": Au, + "triangle-cross": Iu, + circle: Lu, + }))[e]; + }; + var Ou = { + drawElement: function (e, t, n, r, i, a) { + t.isNode() + ? this.drawNode(e, t, n, r, i, a) + : this.drawEdge(e, t, n, r, i, a); + }, + drawElementOverlay: function (e, t) { + t.isNode() ? this.drawNodeOverlay(e, t) : this.drawEdgeOverlay(e, t); + }, + drawElementUnderlay: function (e, t) { + t.isNode() ? this.drawNodeUnderlay(e, t) : this.drawEdgeUnderlay(e, t); + }, + drawCachedElementPortion: function (e, t, n, r, i, a, o, s) { + var l = this, + u = n.getBoundingBox(t); + if (0 !== u.w && 0 !== u.h) { + var c = n.getElement(t, u, r, i, a); + if (null != c) { + var d = s(l, t); + if (0 === d) return; + var h, + p, + f, + g, + v, + y, + m = o(l, t), + b = u.x1, + x = u.y1, + w = u.w, + E = u.h; + if (0 !== m) { + var k = n.getRotationPoint(t); + ((f = k.x), + (g = k.y), + e.translate(f, g), + e.rotate(m), + (v = l.getImgSmoothing(e)) || l.setImgSmoothing(e, !0)); + var C = n.getRotationOffset(t); + ((h = C.x), (p = C.y)); + } else ((h = b), (p = x)); + (1 !== d && ((y = e.globalAlpha), (e.globalAlpha = y * d)), + e.drawImage( + c.texture.canvas, + c.x, + 0, + c.width, + c.height, + h, + p, + w, + E, + ), + 1 !== d && (e.globalAlpha = y), + 0 !== m && + (e.rotate(-m), + e.translate(-f, -g), + v || l.setImgSmoothing(e, !1))); + } else n.drawElement(e, t); + } + }, + }, + Ru = function () { + return 0; + }, + Vu = function (e, t) { + return e.getTextAngle(t, null); + }, + Fu = function (e, t) { + return e.getTextAngle(t, "source"); + }, + ju = function (e, t) { + return e.getTextAngle(t, "target"); + }, + qu = function (e, t) { + return t.effectiveOpacity(); + }, + Yu = function (e, t) { + return t.pstyle("text-opacity").pfValue * t.effectiveOpacity(); + }; + ((Ou.drawCachedElement = function (e, t, n, r, i, a) { + var o = this, + s = o.data, + l = s.eleTxrCache, + u = s.lblTxrCache, + c = s.slbTxrCache, + d = s.tlbTxrCache, + h = t.boundingBox(), + p = !0 === a ? l.reasons.highQuality : null; + if (0 !== h.w && 0 !== h.h && t.visible() && (!r || At(h, r))) { + var f = t.isEdge(), + g = t.element()._private.rscratch.badLine; + (o.drawElementUnderlay(e, t), + o.drawCachedElementPortion(e, t, l, n, i, p, Ru, qu), + (f && g) || o.drawCachedElementPortion(e, t, u, n, i, p, Vu, Yu), + f && + !g && + (o.drawCachedElementPortion(e, t, c, n, i, p, Fu, Yu), + o.drawCachedElementPortion(e, t, d, n, i, p, ju, Yu)), + o.drawElementOverlay(e, t)); + } + }), + (Ou.drawElements = function (e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + this.drawElement(e, r); + } + }), + (Ou.drawCachedElements = function (e, t, n, r) { + for (var i = 0; i < t.length; i++) { + var a = t[i]; + this.drawCachedElement(e, a, n, r); + } + }), + (Ou.drawCachedNodes = function (e, t, n, r) { + for (var i = 0; i < t.length; i++) { + var a = t[i]; + a.isNode() && this.drawCachedElement(e, a, n, r); + } + }), + (Ou.drawLayeredElements = function (e, t, n, r) { + var i = this.data.lyrTxrCache.getLayers(t, n); + if (i) + for (var a = 0; a < i.length; a++) { + var o = i[a], + s = o.bb; + 0 !== s.w && 0 !== s.h && e.drawImage(o.canvas, s.x1, s.y1, s.w, s.h); + } + else this.drawCachedElements(e, t, n, r); + })); + var Xu = { + drawEdge: function (e, t, n) { + var r = + !(arguments.length > 3 && void 0 !== arguments[3]) || arguments[3], + i = + !(arguments.length > 4 && void 0 !== arguments[4]) || arguments[4], + a = + !(arguments.length > 5 && void 0 !== arguments[5]) || arguments[5], + o = this, + s = t._private.rscratch; + if ( + (!a || t.visible()) && + !s.badLine && + null != s.allpts && + !isNaN(s.allpts[0]) + ) { + var l; + n && ((l = n), e.translate(-l.x1, -l.y1)); + var u = a ? t.pstyle("opacity").value : 1, + c = a ? t.pstyle("line-opacity").value : 1, + d = t.pstyle("curve-style").value, + h = t.pstyle("line-style").value, + p = t.pstyle("width").pfValue, + f = t.pstyle("line-cap").value, + g = t.pstyle("line-outline-width").value, + v = t.pstyle("line-outline-color").value, + y = u * c, + m = u * c, + b = function () { + var n = + arguments.length > 0 && void 0 !== arguments[0] + ? arguments[0] + : y; + "straight-triangle" === d + ? (o.eleStrokeStyle(e, t, n), + o.drawEdgeTrianglePath(t, e, s.allpts)) + : ((e.lineWidth = p), + (e.lineCap = f), + o.eleStrokeStyle(e, t, n), + o.drawEdgePath(t, e, s.allpts, h), + (e.lineCap = "butt")); + }, + x = function () { + var n = + arguments.length > 0 && void 0 !== arguments[0] + ? arguments[0] + : y; + ((e.lineWidth = p + g), + (e.lineCap = f), + g > 0 + ? (o.colorStrokeStyle(e, v[0], v[1], v[2], n), + "straight-triangle" === d + ? o.drawEdgeTrianglePath(t, e, s.allpts) + : (o.drawEdgePath(t, e, s.allpts, h), + (e.lineCap = "butt"))) + : (e.lineCap = "butt")); + }, + w = function () { + i && o.drawEdgeOverlay(e, t); + }, + E = function () { + i && o.drawEdgeUnderlay(e, t); + }, + k = function () { + var n = + arguments.length > 0 && void 0 !== arguments[0] + ? arguments[0] + : m; + o.drawArrowheads(e, t, n); + }, + C = function () { + o.drawElementText(e, t, null, r); + }; + e.lineJoin = "round"; + var S = "yes" === t.pstyle("ghost").value; + if (S) { + var P = t.pstyle("ghost-offset-x").pfValue, + D = t.pstyle("ghost-offset-y").pfValue, + T = t.pstyle("ghost-opacity").value, + _ = y * T; + (e.translate(P, D), b(_), k(_), e.translate(-P, -D)); + } else x(); + (E(), b(), k(), w(), C(), n && e.translate(l.x1, l.y1)); + } + }, + }, + Wu = function (e) { + if (!["overlay", "underlay"].includes(e)) + throw new Error("Invalid state"); + return function (t, n) { + if (n.visible()) { + var r = n.pstyle("".concat(e, "-opacity")).value; + if (0 !== r) { + var i = this, + a = i.usePaths(), + o = n._private.rscratch, + s = 2 * n.pstyle("".concat(e, "-padding")).pfValue, + l = n.pstyle("".concat(e, "-color")).value; + ((t.lineWidth = s), + "self" !== o.edgeType || a + ? (t.lineCap = "round") + : (t.lineCap = "butt"), + i.colorStrokeStyle(t, l[0], l[1], l[2], r), + i.drawEdgePath(n, t, o.allpts, "solid")); + } + } + }; + }; + ((Xu.drawEdgeOverlay = Wu("overlay")), + (Xu.drawEdgeUnderlay = Wu("underlay")), + (Xu.drawEdgePath = function (e, t, n, r) { + var i, + a = e._private.rscratch, + o = t, + s = !1, + u = this.usePaths(), + c = e.pstyle("line-dash-pattern").pfValue, + d = e.pstyle("line-dash-offset").pfValue; + if (u) { + var h = n.join("$"); + a.pathCacheKey && a.pathCacheKey === h + ? ((i = t = a.pathCache), (s = !0)) + : ((i = t = new Path2D()), (a.pathCacheKey = h), (a.pathCache = i)); + } + if (o.setLineDash) + switch (r) { + case "dotted": + o.setLineDash([1, 1]); + break; + case "dashed": + (o.setLineDash(c), (o.lineDashOffset = d)); + break; + case "solid": + o.setLineDash([]); + } + if (!s && !a.badLine) + switch ( + (t.beginPath && t.beginPath(), t.moveTo(n[0], n[1]), a.edgeType) + ) { + case "bezier": + case "self": + case "compound": + case "multibezier": + for (var p = 2; p + 3 < n.length; p += 4) + t.quadraticCurveTo(n[p], n[p + 1], n[p + 2], n[p + 3]); + break; + case "straight": + case "haystack": + for (var f = 2; f + 1 < n.length; f += 2) t.lineTo(n[f], n[f + 1]); + break; + case "segments": + if (a.isRound) { + var g, + v = l(a.roundCorners); + try { + for (v.s(); !(g = v.n()).done; ) { + Ql(t, g.value); + } + } catch (e) { + v.e(e); + } finally { + v.f(); + } + t.lineTo(n[n.length - 2], n[n.length - 1]); + } else + for (var y = 2; y + 1 < n.length; y += 2) + t.lineTo(n[y], n[y + 1]); + } + ((t = o), + u ? t.stroke(i) : t.stroke(), + t.setLineDash && t.setLineDash([])); + }), + (Xu.drawEdgeTrianglePath = function (e, t, n) { + t.fillStyle = t.strokeStyle; + for (var r = e.pstyle("width").pfValue, i = 0; i + 1 < n.length; i += 2) { + var a = [n[i + 2] - n[i], n[i + 3] - n[i + 1]], + o = Math.sqrt(a[0] * a[0] + a[1] * a[1]), + s = [a[1] / o, -a[0] / o], + l = [(s[0] * r) / 2, (s[1] * r) / 2]; + (t.beginPath(), + t.moveTo(n[i] - l[0], n[i + 1] - l[1]), + t.lineTo(n[i] + l[0], n[i + 1] + l[1]), + t.lineTo(n[i + 2], n[i + 3]), + t.closePath(), + t.fill()); + } + }), + (Xu.drawArrowheads = function (e, t, n) { + var r = t._private.rscratch, + i = "haystack" === r.edgeType; + (i || + this.drawArrowhead( + e, + t, + "source", + r.arrowStartX, + r.arrowStartY, + r.srcArrowAngle, + n, + ), + this.drawArrowhead( + e, + t, + "mid-target", + r.midX, + r.midY, + r.midtgtArrowAngle, + n, + ), + this.drawArrowhead( + e, + t, + "mid-source", + r.midX, + r.midY, + r.midsrcArrowAngle, + n, + ), + i || + this.drawArrowhead( + e, + t, + "target", + r.arrowEndX, + r.arrowEndY, + r.tgtArrowAngle, + n, + )); + }), + (Xu.drawArrowhead = function (e, t, n, r, i, a, o) { + if ( + !( + isNaN(r) || + null == r || + isNaN(i) || + null == i || + isNaN(a) || + null == a + ) + ) { + var s = t.pstyle(n + "-arrow-shape").value; + if ("none" !== s) { + var l = + "hollow" === t.pstyle(n + "-arrow-fill").value + ? "both" + : "filled", + u = t.pstyle(n + "-arrow-fill").value, + c = t.pstyle("width").pfValue, + d = t.pstyle(n + "-arrow-width"), + h = "match-line" === d.value ? c : d.pfValue; + "%" === d.units && (h *= c); + var p = t.pstyle("opacity").value; + void 0 === o && (o = p); + var f = e.globalCompositeOperation; + (1 === o && "hollow" !== u) || + ((e.globalCompositeOperation = "destination-out"), + this.colorFillStyle(e, 255, 255, 255, 1), + this.colorStrokeStyle(e, 255, 255, 255, 1), + this.drawArrowShape(t, e, l, c, s, h, r, i, a), + (e.globalCompositeOperation = f)); + var g = t.pstyle(n + "-arrow-color").value; + (this.colorFillStyle(e, g[0], g[1], g[2], o), + this.colorStrokeStyle(e, g[0], g[1], g[2], o), + this.drawArrowShape(t, e, u, c, s, h, r, i, a)); + } + } + }), + (Xu.drawArrowShape = function (e, t, n, r, i, a, o, s, l) { + var u, + c = this, + d = this.usePaths() && "triangle-cross" !== i, + h = !1, + p = t, + f = { x: o, y: s }, + g = e.pstyle("arrow-scale").value, + v = this.getArrowWidth(r, g), + y = c.arrowShapes[i]; + if (d) { + var m = (c.arrowPathCache = c.arrowPathCache || []), + b = Te(i), + x = m[b]; + null != x + ? ((u = t = x), (h = !0)) + : ((u = t = new Path2D()), (m[b] = u)); + } + (h || + (t.beginPath && t.beginPath(), + d ? y.draw(t, 1, 0, { x: 0, y: 0 }, 1) : y.draw(t, v, l, f, r), + t.closePath && t.closePath()), + (t = p), + d && (t.translate(o, s), t.rotate(l), t.scale(v, v)), + ("filled" !== n && "both" !== n) || (d ? t.fill(u) : t.fill()), + ("hollow" !== n && "both" !== n) || + ((t.lineWidth = a / (d ? v : 1)), + (t.lineJoin = "miter"), + d ? t.stroke(u) : t.stroke()), + d && (t.scale(1 / v, 1 / v), t.rotate(-l), t.translate(-o, -s))); + })); + var Hu = { + safeDrawImage: function (e, t, n, r, i, a, o, s, l, u) { + if (!(i <= 0 || a <= 0 || l <= 0 || u <= 0)) + try { + e.drawImage(t, n, r, i, a, o, s, l, u); + } catch (e) { + je(e); + } + }, + drawInscribedImage: function (e, t, n, r, i) { + var a = this, + o = n.position(), + s = o.x, + l = o.y, + u = n.cy().style(), + c = u.getIndexedStyle.bind(u), + d = c(n, "background-fit", "value", r), + h = c(n, "background-repeat", "value", r), + p = n.width(), + f = n.height(), + g = 2 * n.padding(), + v = + p + + ("inner" === c(n, "background-width-relative-to", "value", r) + ? 0 + : g), + y = + f + + ("inner" === c(n, "background-height-relative-to", "value", r) + ? 0 + : g), + m = n._private.rscratch, + b = "node" === c(n, "background-clip", "value", r), + x = c(n, "background-image-opacity", "value", r) * i, + w = c(n, "background-image-smoothing", "value", r), + E = n.pstyle("corner-radius").value; + "auto" !== E && (E = n.pstyle("corner-radius").pfValue); + var k = t.width || t.cachedW, + C = t.height || t.cachedH; + (null != k && null != C) || + (document.body.appendChild(t), + (k = t.cachedW = t.width || t.offsetWidth), + (C = t.cachedH = t.height || t.offsetHeight), + document.body.removeChild(t)); + var S = k, + P = C; + if ( + ("auto" !== c(n, "background-width", "value", r) && + (S = + "%" === c(n, "background-width", "units", r) + ? c(n, "background-width", "pfValue", r) * v + : c(n, "background-width", "pfValue", r)), + "auto" !== c(n, "background-height", "value", r) && + (P = + "%" === c(n, "background-height", "units", r) + ? c(n, "background-height", "pfValue", r) * y + : c(n, "background-height", "pfValue", r)), + 0 !== S && 0 !== P) + ) { + if ("contain" === d) ((S *= D = Math.min(v / S, y / P)), (P *= D)); + else if ("cover" === d) { + var D; + ((S *= D = Math.max(v / S, y / P)), (P *= D)); + } + var T = s - v / 2, + _ = c(n, "background-position-x", "units", r), + M = c(n, "background-position-x", "pfValue", r); + T += "%" === _ ? (v - S) * M : M; + var B = c(n, "background-offset-x", "units", r), + N = c(n, "background-offset-x", "pfValue", r); + T += "%" === B ? (v - S) * N : N; + var z = l - y / 2, + I = c(n, "background-position-y", "units", r), + A = c(n, "background-position-y", "pfValue", r); + z += "%" === I ? (y - P) * A : A; + var L = c(n, "background-offset-y", "units", r), + O = c(n, "background-offset-y", "pfValue", r); + ((z += "%" === L ? (y - P) * O : O), + m.pathCache && ((T -= s), (z -= l), (s = 0), (l = 0))); + var R = e.globalAlpha; + e.globalAlpha = x; + var V = a.getImgSmoothing(e), + F = !1; + if ( + ("no" === w && V + ? (a.setImgSmoothing(e, !1), (F = !0)) + : "yes" !== w || V || (a.setImgSmoothing(e, !0), (F = !0)), + "no-repeat" === h) + ) + (b && + (e.save(), + m.pathCache + ? e.clip(m.pathCache) + : (a.nodeShapes[a.getNodeShape(n)].draw(e, s, l, v, y, E, m), + e.clip())), + a.safeDrawImage(e, t, 0, 0, k, C, T, z, S, P), + b && e.restore()); + else { + var j = e.createPattern(t, h); + ((e.fillStyle = j), + a.nodeShapes[a.getNodeShape(n)].draw(e, s, l, v, y, E, m), + e.translate(T, z), + e.fill(), + e.translate(-T, -z)); + } + ((e.globalAlpha = R), F && a.setImgSmoothing(e, V)); + } + }, + }, + Ku = {}; + function Gu(e, t, n, r, i) { + var a = arguments.length > 5 && void 0 !== arguments[5] ? arguments[5] : 5, + o = arguments.length > 6 ? arguments[6] : void 0; + (e.beginPath(), + e.moveTo(t + a, n), + e.lineTo(t + r - a, n), + e.quadraticCurveTo(t + r, n, t + r, n + a), + e.lineTo(t + r, n + i - a), + e.quadraticCurveTo(t + r, n + i, t + r - a, n + i), + e.lineTo(t + a, n + i), + e.quadraticCurveTo(t, n + i, t, n + i - a), + e.lineTo(t, n + a), + e.quadraticCurveTo(t, n, t + a, n), + e.closePath(), + o ? e.stroke() : e.fill()); + } + ((Ku.eleTextBiggerThanMin = function (e, t) { + if (!t) { + var n = e.cy().zoom(), + r = this.getPixelRatio(), + i = Math.ceil(wt(n * r)); + t = Math.pow(2, i); + } + return !( + e.pstyle("font-size").pfValue * t < + e.pstyle("min-zoomed-font-size").pfValue + ); + }), + (Ku.drawElementText = function (e, t, n, r, i) { + var a = + !(arguments.length > 5 && void 0 !== arguments[5]) || arguments[5], + o = this; + if (null == r) { + if (a && !o.eleTextBiggerThanMin(t)) return; + } else if (!1 === r) return; + if (t.isNode()) { + var s = t.pstyle("label"); + if (!s || !s.value) return; + var l = o.getLabelJustification(t); + ((e.textAlign = l), (e.textBaseline = "bottom")); + } else { + var u = t.element()._private.rscratch.badLine, + c = t.pstyle("label"), + d = t.pstyle("source-label"), + h = t.pstyle("target-label"); + if (u || ((!c || !c.value) && (!d || !d.value) && (!h || !h.value))) + return; + ((e.textAlign = "center"), (e.textBaseline = "bottom")); + } + var p, + f = !n; + (n && ((p = n), e.translate(-p.x1, -p.y1)), + null == i + ? (o.drawText(e, t, null, f, a), + t.isEdge() && + (o.drawText(e, t, "source", f, a), + o.drawText(e, t, "target", f, a))) + : o.drawText(e, t, i, f, a), + n && e.translate(p.x1, p.y1)); + }), + (Ku.getFontCache = function (e) { + var t; + this.fontCaches = this.fontCaches || []; + for (var n = 0; n < this.fontCaches.length; n++) + if ((t = this.fontCaches[n]).context === e) return t; + return ((t = { context: e }), this.fontCaches.push(t), t); + }), + (Ku.setupTextStyle = function (e, t) { + var n = + !(arguments.length > 2 && void 0 !== arguments[2]) || arguments[2], + r = t.pstyle("font-style").strValue, + i = t.pstyle("font-size").pfValue + "px", + a = t.pstyle("font-family").strValue, + o = t.pstyle("font-weight").strValue, + s = n ? t.effectiveOpacity() * t.pstyle("text-opacity").value : 1, + l = t.pstyle("text-outline-opacity").value * s, + u = t.pstyle("color").value, + c = t.pstyle("text-outline-color").value; + ((e.font = r + " " + o + " " + i + " " + a), + (e.lineJoin = "round"), + this.colorFillStyle(e, u[0], u[1], u[2], s), + this.colorStrokeStyle(e, c[0], c[1], c[2], l)); + }), + (Ku.getTextAngle = function (e, t) { + var n = e._private.rscratch, + r = t ? t + "-" : "", + i = e.pstyle(r + "text-rotation"), + a = Ue(n, "labelAngle", t); + return "autorotate" === i.strValue + ? e.isEdge() + ? a + : 0 + : "none" === i.strValue + ? 0 + : i.pfValue; + }), + (Ku.drawText = function (e, t, n) { + var r = + !(arguments.length > 3 && void 0 !== arguments[3]) || arguments[3], + i = !(arguments.length > 4 && void 0 !== arguments[4]) || arguments[4], + a = t._private, + o = a.rscratch, + s = i ? t.effectiveOpacity() : 1; + if (!i || (0 !== s && 0 !== t.pstyle("text-opacity").value)) { + "main" === n && (n = null); + var l, + u, + c = Ue(o, "labelX", n), + d = Ue(o, "labelY", n), + h = this.getLabelText(t, n); + if (null != h && "" !== h && !isNaN(c) && !isNaN(d)) { + this.setupTextStyle(e, t, i); + var p, + f = n ? n + "-" : "", + g = Ue(o, "labelWidth", n), + v = Ue(o, "labelHeight", n), + y = t.pstyle(f + "text-margin-x").pfValue, + m = t.pstyle(f + "text-margin-y").pfValue, + b = t.isEdge(), + x = t.pstyle("text-halign").value, + w = t.pstyle("text-valign").value; + switch ( + (b && ((x = "center"), (w = "center")), + (c += y), + (d += m), + 0 !== (p = r ? this.getTextAngle(t, n) : 0) && + ((l = c), + (u = d), + e.translate(l, u), + e.rotate(p), + (c = 0), + (d = 0)), + w) + ) { + case "top": + break; + case "center": + d += v / 2; + break; + case "bottom": + d += v; + } + var E = t.pstyle("text-background-opacity").value, + k = t.pstyle("text-border-opacity").value, + C = t.pstyle("text-border-width").pfValue, + S = t.pstyle("text-background-padding").pfValue, + P = t.pstyle("text-background-shape").strValue, + D = 0 === P.indexOf("round"), + T = 2; + if (E > 0 || (C > 0 && k > 0)) { + var _ = c - S; + switch (x) { + case "left": + _ -= g; + break; + case "center": + _ -= g / 2; + } + var M = d - v - S, + B = g + 2 * S, + N = v + 2 * S; + if (E > 0) { + var z = e.fillStyle, + I = t.pstyle("text-background-color").value; + ((e.fillStyle = + "rgba(" + I[0] + "," + I[1] + "," + I[2] + "," + E * s + ")"), + D ? Gu(e, _, M, B, N, T) : e.fillRect(_, M, B, N), + (e.fillStyle = z)); + } + if (C > 0 && k > 0) { + var A = e.strokeStyle, + L = e.lineWidth, + O = t.pstyle("text-border-color").value, + R = t.pstyle("text-border-style").value; + if ( + ((e.strokeStyle = + "rgba(" + O[0] + "," + O[1] + "," + O[2] + "," + k * s + ")"), + (e.lineWidth = C), + e.setLineDash) + ) + switch (R) { + case "dotted": + e.setLineDash([1, 1]); + break; + case "dashed": + e.setLineDash([4, 2]); + break; + case "double": + ((e.lineWidth = C / 4), e.setLineDash([])); + break; + case "solid": + e.setLineDash([]); + } + if ( + (D ? Gu(e, _, M, B, N, T, "stroke") : e.strokeRect(_, M, B, N), + "double" === R) + ) { + var V = C / 2; + D + ? Gu(e, _ + V, M + V, B - 2 * V, N - 2 * V, T, "stroke") + : e.strokeRect(_ + V, M + V, B - 2 * V, N - 2 * V); + } + (e.setLineDash && e.setLineDash([]), + (e.lineWidth = L), + (e.strokeStyle = A)); + } + } + var F = 2 * t.pstyle("text-outline-width").pfValue; + if ( + (F > 0 && (e.lineWidth = F), "wrap" === t.pstyle("text-wrap").value) + ) { + var j = Ue(o, "labelWrapCachedLines", n), + q = Ue(o, "labelLineHeight", n), + Y = g / 2, + X = this.getLabelJustification(t); + switch ( + ("auto" === X || + ("left" === x + ? "left" === X + ? (c += -g) + : "center" === X && (c += -Y) + : "center" === x + ? "left" === X + ? (c += -Y) + : "right" === X && (c += Y) + : "right" === x && + ("center" === X ? (c += Y) : "right" === X && (c += g))), + w) + ) { + case "top": + d -= (j.length - 1) * q; + break; + case "center": + case "bottom": + d -= (j.length - 1) * q; + } + for (var W = 0; W < j.length; W++) + (F > 0 && e.strokeText(j[W], c, d), + e.fillText(j[W], c, d), + (d += q)); + } else (F > 0 && e.strokeText(h, c, d), e.fillText(h, c, d)); + 0 !== p && (e.rotate(-p), e.translate(-l, -u)); + } + } + })); + var Uu = { + drawNode: function (e, t, n) { + var r, + i, + a = + !(arguments.length > 3 && void 0 !== arguments[3]) || arguments[3], + o = + !(arguments.length > 4 && void 0 !== arguments[4]) || arguments[4], + s = + !(arguments.length > 5 && void 0 !== arguments[5]) || arguments[5], + l = this, + u = t._private, + c = u.rscratch, + d = t.position(); + if (x(d.x) && x(d.y) && (!s || t.visible())) { + var h, + p, + f = s ? t.effectiveOpacity() : 1, + g = l.usePaths(), + v = !1, + y = t.padding(); + ((r = t.width() + 2 * y), + (i = t.height() + 2 * y), + n && ((p = n), e.translate(-p.x1, -p.y1))); + for ( + var m = t.pstyle("background-image"), + b = m.value, + w = new Array(b.length), + E = new Array(b.length), + k = 0, + C = 0; + C < b.length; + C++ + ) { + var S = b[C], + P = (w[C] = null != S && "none" !== S); + if (P) { + var D = t + .cy() + .style() + .getIndexedStyle(t, "background-image-crossorigin", "value", C); + (k++, + (E[C] = l.getCachedImage(S, D, function () { + ((u.backgroundTimestamp = Date.now()), + t.emitAndNotify("background")); + }))); + } + } + var T = t.pstyle("background-blacken").value, + _ = t.pstyle("border-width").pfValue, + M = t.pstyle("background-opacity").value * f, + B = t.pstyle("border-color").value, + N = t.pstyle("border-style").value, + z = t.pstyle("border-join").value, + I = t.pstyle("border-cap").value, + A = t.pstyle("border-position").value, + L = t.pstyle("border-dash-pattern").pfValue, + O = t.pstyle("border-dash-offset").pfValue, + R = t.pstyle("border-opacity").value * f, + V = t.pstyle("outline-width").pfValue, + F = t.pstyle("outline-color").value, + j = t.pstyle("outline-style").value, + q = t.pstyle("outline-opacity").value * f, + Y = t.pstyle("outline-offset").value, + X = t.pstyle("corner-radius").value; + "auto" !== X && (X = t.pstyle("corner-radius").pfValue); + var W = function () { + var n = + arguments.length > 0 && void 0 !== arguments[0] + ? arguments[0] + : M; + l.eleFillStyle(e, t, n); + }, + H = function () { + var t = + arguments.length > 0 && void 0 !== arguments[0] + ? arguments[0] + : R; + l.colorStrokeStyle(e, B[0], B[1], B[2], t); + }, + K = function () { + var t = + arguments.length > 0 && void 0 !== arguments[0] + ? arguments[0] + : q; + l.colorStrokeStyle(e, F[0], F[1], F[2], t); + }, + G = function (e, t, n, r) { + var i, + a = (l.nodePathCache = l.nodePathCache || []), + o = _e( + "polygon" === n ? n + "," + r.join(",") : n, + "" + t, + "" + e, + "" + X, + ), + s = a[o], + u = !1; + return ( + null != s + ? ((i = s), (u = !0), (c.pathCache = i)) + : ((i = new Path2D()), (a[o] = c.pathCache = i)), + { path: i, cacheHit: u } + ); + }, + U = t.pstyle("shape").strValue, + Z = t.pstyle("shape-polygon-points").pfValue; + if (g) { + e.translate(d.x, d.y); + var $ = G(r, i, U, Z); + ((h = $.path), (v = $.cacheHit)); + } + var Q = function () { + if (!v) { + var n = d; + (g && (n = { x: 0, y: 0 }), + l.nodeShapes[l.getNodeShape(t)].draw( + h || e, + n.x, + n.y, + r, + i, + X, + c, + )); + } + g ? e.fill(h) : e.fill(); + }, + J = function () { + for ( + var n = + arguments.length > 0 && void 0 !== arguments[0] + ? arguments[0] + : f, + r = + !(arguments.length > 1 && void 0 !== arguments[1]) || + arguments[1], + i = u.backgrounding, + a = 0, + o = 0; + o < E.length; + o++ + ) { + var s = t + .cy() + .style() + .getIndexedStyle( + t, + "background-image-containment", + "value", + o, + ); + (r && "over" === s) || (!r && "inside" === s) + ? a++ + : w[o] && + E[o].complete && + !E[o].error && + (a++, l.drawInscribedImage(e, E[o], t, o, n)); + } + ((u.backgrounding = !(a === k)), + i !== u.backgrounding && t.updateStyle(!1)); + }, + ee = function () { + var n = + arguments.length > 0 && + void 0 !== arguments[0] && + arguments[0], + a = + arguments.length > 1 && void 0 !== arguments[1] + ? arguments[1] + : f; + l.hasPie(t) && + (l.drawPie(e, t, a), + n && + (g || + l.nodeShapes[l.getNodeShape(t)].draw( + e, + d.x, + d.y, + r, + i, + X, + c, + ))); + }, + te = function () { + var t = + arguments.length > 0 && void 0 !== arguments[0] + ? arguments[0] + : f, + n = (T > 0 ? T : -T) * t, + r = T > 0 ? 0 : 255; + 0 !== T && + (l.colorFillStyle(e, r, r, r, n), g ? e.fill(h) : e.fill()); + }, + ne = function () { + if (_ > 0) { + if ( + ((e.lineWidth = _), + (e.lineCap = I), + (e.lineJoin = z), + e.setLineDash) + ) + switch (N) { + case "dotted": + e.setLineDash([1, 1]); + break; + case "dashed": + (e.setLineDash(L), (e.lineDashOffset = O)); + break; + case "solid": + case "double": + e.setLineDash([]); + } + if ("center" !== A) { + if ((e.save(), (e.lineWidth *= 2), "inside" === A)) + g ? e.clip(h) : e.clip(); + else { + var t = new Path2D(); + (t.rect(-r / 2 - _, -i / 2 - _, r + 2 * _, i + 2 * _), + t.addPath(h), + e.clip(t, "evenodd")); + } + (g ? e.stroke(h) : e.stroke(), e.restore()); + } else g ? e.stroke(h) : e.stroke(); + if ("double" === N) { + e.lineWidth = _ / 3; + var n = e.globalCompositeOperation; + ((e.globalCompositeOperation = "destination-out"), + g ? e.stroke(h) : e.stroke(), + (e.globalCompositeOperation = n)); + } + e.setLineDash && e.setLineDash([]); + } + }, + re = function () { + if (V > 0) { + if (((e.lineWidth = V), (e.lineCap = "butt"), e.setLineDash)) + switch (j) { + case "dotted": + e.setLineDash([1, 1]); + break; + case "dashed": + e.setLineDash([4, 2]); + break; + case "solid": + case "double": + e.setLineDash([]); + } + var n = d; + g && (n = { x: 0, y: 0 }); + var a = l.getNodeShape(t), + o = _; + ("inside" === A && (o = 0), "outside" === A && (o *= 2)); + var s, + u = (r + o + (V + Y)) / r, + c = (i + o + (V + Y)) / i, + h = r * u, + p = i * c, + f = l.nodeShapes[a].points; + if (g) s = G(h, p, a, f).path; + if ("ellipse" === a) l.drawEllipsePath(s || e, n.x, n.y, h, p); + else if ( + [ + "round-diamond", + "round-heptagon", + "round-hexagon", + "round-octagon", + "round-pentagon", + "round-polygon", + "round-triangle", + "round-tag", + ].includes(a) + ) { + var v = 0, + y = 0, + m = 0; + ("round-diamond" === a + ? (v = 1.4 * (o + Y + V)) + : "round-heptagon" === a + ? ((v = 1.075 * (o + Y + V)), (m = -(o / 2 + Y + V) / 35)) + : "round-hexagon" === a + ? (v = 1.12 * (o + Y + V)) + : "round-pentagon" === a + ? ((v = 1.13 * (o + Y + V)), + (m = -(o / 2 + Y + V) / 15)) + : "round-tag" === a + ? ((v = 1.12 * (o + Y + V)), + (y = 0.07 * (o / 2 + V + Y))) + : "round-triangle" === a && + ((v = (o + Y + V) * (Math.PI / 2)), + (m = -(o + Y / 2 + V) / Math.PI)), + 0 !== v && + ((h = r * (u = (r + v) / r)), + ["round-hexagon", "round-tag"].includes(a) || + (p = i * (c = (i + v) / i)))); + for ( + var b = h / 2, + x = p / 2, + w = (X = "auto" === X ? rn(h, p) : X) + (o + V + Y) / 2, + E = new Array(f.length / 2), + k = new Array(f.length / 2), + C = 0; + C < f.length / 2; + C++ + ) + E[C] = { + x: n.x + y + b * f[2 * C], + y: n.y + m + x * f[2 * C + 1], + }; + var S, + P, + D, + T, + M = E.length; + for (P = E[M - 1], S = 0; S < M; S++) + ((D = E[S % M]), + (T = E[(S + 1) % M]), + (k[S] = Jl(P, D, T, w)), + (P = D), + (D = T)); + l.drawRoundPolygonPath( + s || e, + n.x + y, + n.y + m, + r * u, + i * c, + f, + k, + ); + } else if (["roundrectangle", "round-rectangle"].includes(a)) + ((X = "auto" === X ? nn(h, p) : X), + l.drawRoundRectanglePath( + s || e, + n.x, + n.y, + h, + p, + X + (o + V + Y) / 2, + )); + else if (["cutrectangle", "cut-rectangle"].includes(a)) + ((X = "auto" === X ? 8 : X), + l.drawCutRectanglePath( + s || e, + n.x, + n.y, + h, + p, + null, + X + (o + V + Y) / 4, + )); + else if ( + ["bottomroundrectangle", "bottom-round-rectangle"].includes(a) + ) + ((X = "auto" === X ? nn(h, p) : X), + l.drawBottomRoundRectanglePath( + s || e, + n.x, + n.y, + h, + p, + X + (o + V + Y) / 2, + )); + else if ("barrel" === a) + l.drawBarrelPath(s || e, n.x, n.y, h, p); + else if ( + a.startsWith("polygon") || + [ + "rhomboid", + "right-rhomboid", + "round-tag", + "tag", + "vee", + ].includes(a) + ) { + ((f = Wt(Ht(f, (o + V + Y) / r))), + l.drawPolygonPath(s || e, n.x, n.y, r, i, f)); + } else { + ((f = Wt(Ht(f, -((o + V + Y) / r)))), + l.drawPolygonPath(s || e, n.x, n.y, r, i, f)); + } + if ((g ? e.stroke(s) : e.stroke(), "double" === j)) { + e.lineWidth = o / 3; + var B = e.globalCompositeOperation; + ((e.globalCompositeOperation = "destination-out"), + g ? e.stroke(s) : e.stroke(), + (e.globalCompositeOperation = B)); + } + e.setLineDash && e.setLineDash([]); + } + }, + ie = function () { + o && l.drawNodeOverlay(e, t, d, r, i); + }, + ae = function () { + o && l.drawNodeUnderlay(e, t, d, r, i); + }, + oe = function () { + l.drawElementText(e, t, null, a); + }, + se = "yes" === t.pstyle("ghost").value; + if (se) { + var le = t.pstyle("ghost-offset-x").pfValue, + ue = t.pstyle("ghost-offset-y").pfValue, + ce = t.pstyle("ghost-opacity").value, + de = ce * f; + (e.translate(le, ue), + K(), + re(), + W(ce * M), + Q(), + J(de, !0), + H(ce * R), + ne(), + ee(0 !== T || 0 !== _), + J(de, !1), + te(de), + e.translate(-le, -ue)); + } + (g && e.translate(-d.x, -d.y), + ae(), + g && e.translate(d.x, d.y), + K(), + re(), + W(), + Q(), + J(f, !0), + H(), + ne(), + ee(0 !== T || 0 !== _), + J(f, !1), + te(), + g && e.translate(-d.x, -d.y), + oe(), + ie(), + n && e.translate(p.x1, p.y1)); + } + }, + }, + Zu = function (e) { + if (!["overlay", "underlay"].includes(e)) + throw new Error("Invalid state"); + return function (t, n, r, i, a) { + if (n.visible()) { + var o = n.pstyle("".concat(e, "-padding")).pfValue, + s = n.pstyle("".concat(e, "-opacity")).value, + l = n.pstyle("".concat(e, "-color")).value, + u = n.pstyle("".concat(e, "-shape")).value, + c = n.pstyle("".concat(e, "-corner-radius")).value; + if (s > 0) { + if (((r = r || n.position()), null == i || null == a)) { + var d = n.padding(); + ((i = n.width() + 2 * d), (a = n.height() + 2 * d)); + } + (this.colorFillStyle(t, l[0], l[1], l[2], s), + this.nodeShapes[u].draw(t, r.x, r.y, i + 2 * o, a + 2 * o, c), + t.fill()); + } + } + }; + }; + ((Uu.drawNodeOverlay = Zu("overlay")), + (Uu.drawNodeUnderlay = Zu("underlay")), + (Uu.hasPie = function (e) { + return (e = e[0])._private.hasPie; + }), + (Uu.drawPie = function (e, t, n, r) { + ((t = t[0]), (r = r || t.position())); + var i = t.cy().style(), + a = t.pstyle("pie-size"), + o = r.x, + s = r.y, + l = t.width(), + u = t.height(), + c = Math.min(l, u) / 2, + d = 0; + (this.usePaths() && ((o = 0), (s = 0)), + "%" === a.units + ? (c *= a.pfValue) + : void 0 !== a.pfValue && (c = a.pfValue / 2)); + for (var h = 1; h <= i.pieBackgroundN; h++) { + var p = t.pstyle("pie-" + h + "-background-size").value, + f = t.pstyle("pie-" + h + "-background-color").value, + g = t.pstyle("pie-" + h + "-background-opacity").value * n, + v = p / 100; + v + d > 1 && (v = 1 - d); + var y = 1.5 * Math.PI + 2 * Math.PI * d, + m = y + 2 * Math.PI * v; + 0 === p || + d >= 1 || + d + v > 1 || + (e.beginPath(), + e.moveTo(o, s), + e.arc(o, s, c, y, m), + e.closePath(), + this.colorFillStyle(e, f[0], f[1], f[2], g), + e.fill(), + (d += v)); + } + })); + var $u = {}; + (($u.getPixelRatio = function () { + var e = this.data.contexts[0]; + if (null != this.forcedPixelRatio) return this.forcedPixelRatio; + var t = this.cy.window(), + n = + e.backingStorePixelRatio || + e.webkitBackingStorePixelRatio || + e.mozBackingStorePixelRatio || + e.msBackingStorePixelRatio || + e.oBackingStorePixelRatio || + e.backingStorePixelRatio || + 1; + return (t.devicePixelRatio || 1) / n; + }), + ($u.paintCache = function (e) { + for ( + var t, n = (this.paintCaches = this.paintCaches || []), r = !0, i = 0; + i < n.length; + i++ + ) + if ((t = n[i]).context === e) { + r = !1; + break; + } + return (r && ((t = { context: e }), n.push(t)), t); + }), + ($u.createGradientStyleFor = function (e, t, n, r, i) { + var a, + o = this.usePaths(), + s = n.pstyle(t + "-gradient-stop-colors").value, + l = n.pstyle(t + "-gradient-stop-positions").pfValue; + if ("radial-gradient" === r) + if (n.isEdge()) { + var u = n.sourceEndpoint(), + c = n.targetEndpoint(), + d = n.midpoint(), + h = kt(u, d), + p = kt(c, d); + a = e.createRadialGradient(d.x, d.y, 0, d.x, d.y, Math.max(h, p)); + } else { + var f = o ? { x: 0, y: 0 } : n.position(), + g = n.paddedWidth(), + v = n.paddedHeight(); + a = e.createRadialGradient(f.x, f.y, 0, f.x, f.y, Math.max(g, v)); + } + else if (n.isEdge()) { + var y = n.sourceEndpoint(), + m = n.targetEndpoint(); + a = e.createLinearGradient(y.x, y.y, m.x, m.y); + } else { + var b = o ? { x: 0, y: 0 } : n.position(), + x = n.paddedWidth() / 2, + w = n.paddedHeight() / 2; + switch (n.pstyle("background-gradient-direction").value) { + case "to-bottom": + a = e.createLinearGradient(b.x, b.y - w, b.x, b.y + w); + break; + case "to-top": + a = e.createLinearGradient(b.x, b.y + w, b.x, b.y - w); + break; + case "to-left": + a = e.createLinearGradient(b.x + x, b.y, b.x - x, b.y); + break; + case "to-right": + a = e.createLinearGradient(b.x - x, b.y, b.x + x, b.y); + break; + case "to-bottom-right": + case "to-right-bottom": + a = e.createLinearGradient(b.x - x, b.y - w, b.x + x, b.y + w); + break; + case "to-top-right": + case "to-right-top": + a = e.createLinearGradient(b.x - x, b.y + w, b.x + x, b.y - w); + break; + case "to-bottom-left": + case "to-left-bottom": + a = e.createLinearGradient(b.x + x, b.y - w, b.x - x, b.y + w); + break; + case "to-top-left": + case "to-left-top": + a = e.createLinearGradient(b.x + x, b.y + w, b.x - x, b.y - w); + } + } + if (!a) return null; + for (var E = l.length === s.length, k = s.length, C = 0; C < k; C++) + a.addColorStop( + E ? l[C] : C / (k - 1), + "rgba(" + s[C][0] + "," + s[C][1] + "," + s[C][2] + "," + i + ")", + ); + return a; + }), + ($u.gradientFillStyle = function (e, t, n, r) { + var i = this.createGradientStyleFor(e, "background", t, n, r); + if (!i) return null; + e.fillStyle = i; + }), + ($u.colorFillStyle = function (e, t, n, r, i) { + e.fillStyle = "rgba(" + t + "," + n + "," + r + "," + i + ")"; + }), + ($u.eleFillStyle = function (e, t, n) { + var r = t.pstyle("background-fill").value; + if ("linear-gradient" === r || "radial-gradient" === r) + this.gradientFillStyle(e, t, r, n); + else { + var i = t.pstyle("background-color").value; + this.colorFillStyle(e, i[0], i[1], i[2], n); + } + }), + ($u.gradientStrokeStyle = function (e, t, n, r) { + var i = this.createGradientStyleFor(e, "line", t, n, r); + if (!i) return null; + e.strokeStyle = i; + }), + ($u.colorStrokeStyle = function (e, t, n, r, i) { + e.strokeStyle = "rgba(" + t + "," + n + "," + r + "," + i + ")"; + }), + ($u.eleStrokeStyle = function (e, t, n) { + var r = t.pstyle("line-fill").value; + if ("linear-gradient" === r || "radial-gradient" === r) + this.gradientStrokeStyle(e, t, r, n); + else { + var i = t.pstyle("line-color").value; + this.colorStrokeStyle(e, i[0], i[1], i[2], n); + } + }), + ($u.matchCanvasSize = function (e) { + var t = this, + n = t.data, + r = t.findContainerClientCoords(), + i = r[2], + a = r[3], + o = t.getPixelRatio(), + s = t.motionBlurPxRatio; + (e !== t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_NODE] && + e !== t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_DRAG]) || + (o = s); + var l, + u = i * o, + c = a * o; + if (u !== t.canvasWidth || c !== t.canvasHeight) { + t.fontCaches = null; + var d = n.canvasContainer; + ((d.style.width = i + "px"), (d.style.height = a + "px")); + for (var h = 0; h < t.CANVAS_LAYERS; h++) + (((l = n.canvases[h]).width = u), + (l.height = c), + (l.style.width = i + "px"), + (l.style.height = a + "px")); + for (h = 0; h < t.BUFFER_COUNT; h++) + (((l = n.bufferCanvases[h]).width = u), + (l.height = c), + (l.style.width = i + "px"), + (l.style.height = a + "px")); + ((t.textureMult = 1), + o <= 1 && + ((l = n.bufferCanvases[t.TEXTURE_BUFFER]), + (t.textureMult = 2), + (l.width = u * t.textureMult), + (l.height = c * t.textureMult)), + (t.canvasWidth = u), + (t.canvasHeight = c)); + } + }), + ($u.renderTo = function (e, t, n, r) { + this.render({ + forcedContext: e, + forcedZoom: t, + forcedPan: n, + drawAllLayers: !0, + forcedPxRatio: r, + }); + }), + ($u.render = function (e) { + var t = (e = e || We()).forcedContext, + n = e.drawAllLayers, + r = e.drawOnlyNodeLayer, + i = e.forcedZoom, + a = e.forcedPan, + o = this, + s = void 0 === e.forcedPxRatio ? this.getPixelRatio() : e.forcedPxRatio, + l = o.cy, + u = o.data, + c = u.canvasNeedsRedraw, + d = + o.textureOnViewport && + !t && + (o.pinching || + o.hoverData.dragging || + o.swipePanning || + o.data.wheelZooming), + h = void 0 !== e.motionBlur ? e.motionBlur : o.motionBlur, + p = o.motionBlurPxRatio, + f = l.hasCompoundNodes(), + g = o.hoverData.draggingEles, + v = !(!o.hoverData.selecting && !o.touchData.selecting), + y = (h = h && !t && o.motionBlurEnabled && !v); + (t || + (o.prevPxRatio !== s && + (o.invalidateContainerClientCoordsCache(), + o.matchCanvasSize(o.container), + o.redrawHint("eles", !0), + o.redrawHint("drag", !0)), + (o.prevPxRatio = s)), + !t && o.motionBlurTimeout && clearTimeout(o.motionBlurTimeout), + h && + (null == o.mbFrames && (o.mbFrames = 0), + o.mbFrames++, + o.mbFrames < 3 && (y = !1), + o.mbFrames > o.minMbLowQualFrames && + (o.motionBlurPxRatio = o.mbPxRBlurry)), + o.clearingMotionBlur && (o.motionBlurPxRatio = 1), + o.textureDrawLastFrame && + !d && + ((c[o.NODE] = !0), (c[o.SELECT_BOX] = !0))); + var m = l.style(), + b = l.zoom(), + x = void 0 !== i ? i : b, + w = l.pan(), + E = { x: w.x, y: w.y }, + k = { zoom: b, pan: { x: w.x, y: w.y } }, + C = o.prevViewport; + (void 0 === C || + k.zoom !== C.zoom || + k.pan.x !== C.pan.x || + k.pan.y !== C.pan.y || + (g && !f) || + (o.motionBlurPxRatio = 1), + a && (E = a), + (x *= s), + (E.x *= s), + (E.y *= s)); + var S = o.getCachedZSortedEles(); + function P(e, t, n, r, i) { + var a = e.globalCompositeOperation; + ((e.globalCompositeOperation = "destination-out"), + o.colorFillStyle(e, 255, 255, 255, o.motionBlurTransparency), + e.fillRect(t, n, r, i), + (e.globalCompositeOperation = a)); + } + function D(e, r) { + var s, l, c, d; + (o.clearingMotionBlur || + (e !== u.bufferContexts[o.MOTIONBLUR_BUFFER_NODE] && + e !== u.bufferContexts[o.MOTIONBLUR_BUFFER_DRAG]) + ? ((s = E), (l = x), (c = o.canvasWidth), (d = o.canvasHeight)) + : ((s = { x: w.x * p, y: w.y * p }), + (l = b * p), + (c = o.canvasWidth * p), + (d = o.canvasHeight * p)), + e.setTransform(1, 0, 0, 1, 0, 0), + "motionBlur" === r + ? P(e, 0, 0, c, d) + : t || (void 0 !== r && !r) || e.clearRect(0, 0, c, d), + n || (e.translate(s.x, s.y), e.scale(l, l)), + a && e.translate(a.x, a.y), + i && e.scale(i, i)); + } + if ((d || (o.textureDrawLastFrame = !1), d)) { + if (((o.textureDrawLastFrame = !0), !o.textureCache)) { + ((o.textureCache = {}), + (o.textureCache.bb = l.mutableElements().boundingBox()), + (o.textureCache.texture = o.data.bufferCanvases[o.TEXTURE_BUFFER])); + var T = o.data.bufferContexts[o.TEXTURE_BUFFER]; + (T.setTransform(1, 0, 0, 1, 0, 0), + T.clearRect( + 0, + 0, + o.canvasWidth * o.textureMult, + o.canvasHeight * o.textureMult, + ), + o.render({ + forcedContext: T, + drawOnlyNodeLayer: !0, + forcedPxRatio: s * o.textureMult, + }), + ((k = o.textureCache.viewport = + { + zoom: l.zoom(), + pan: l.pan(), + width: o.canvasWidth, + height: o.canvasHeight, + }).mpan = { + x: (0 - k.pan.x) / k.zoom, + y: (0 - k.pan.y) / k.zoom, + })); + } + ((c[o.DRAG] = !1), (c[o.NODE] = !1)); + var _ = u.contexts[o.NODE], + M = o.textureCache.texture; + k = o.textureCache.viewport; + (_.setTransform(1, 0, 0, 1, 0, 0), + h + ? P(_, 0, 0, k.width, k.height) + : _.clearRect(0, 0, k.width, k.height)); + var B = m.core("outside-texture-bg-color").value, + N = m.core("outside-texture-bg-opacity").value; + (o.colorFillStyle(_, B[0], B[1], B[2], N), + _.fillRect(0, 0, k.width, k.height)); + b = l.zoom(); + (D(_, !1), + _.clearRect( + k.mpan.x, + k.mpan.y, + k.width / k.zoom / s, + k.height / k.zoom / s, + ), + _.drawImage( + M, + k.mpan.x, + k.mpan.y, + k.width / k.zoom / s, + k.height / k.zoom / s, + )); + } else o.textureOnViewport && !t && (o.textureCache = null); + var z = l.extent(), + I = + o.pinching || + o.hoverData.dragging || + o.swipePanning || + o.data.wheelZooming || + o.hoverData.draggingEles || + o.cy.animated(), + A = o.hideEdgesOnViewport && I, + L = []; + if ( + ((L[o.NODE] = + (!c[o.NODE] && h && !o.clearedForMotionBlur[o.NODE]) || + o.clearingMotionBlur), + L[o.NODE] && (o.clearedForMotionBlur[o.NODE] = !0), + (L[o.DRAG] = + (!c[o.DRAG] && h && !o.clearedForMotionBlur[o.DRAG]) || + o.clearingMotionBlur), + L[o.DRAG] && (o.clearedForMotionBlur[o.DRAG] = !0), + c[o.NODE] || n || r || L[o.NODE]) + ) { + var O = h && !L[o.NODE] && 1 !== p; + (D( + (_ = + t || + (O + ? o.data.bufferContexts[o.MOTIONBLUR_BUFFER_NODE] + : u.contexts[o.NODE])), + h && !O ? "motionBlur" : void 0, + ), + A + ? o.drawCachedNodes(_, S.nondrag, s, z) + : o.drawLayeredElements(_, S.nondrag, s, z), + o.debug && o.drawDebugPoints(_, S.nondrag), + n || h || (c[o.NODE] = !1)); + } + if (!r && (c[o.DRAG] || n || L[o.DRAG])) { + O = h && !L[o.DRAG] && 1 !== p; + (D( + (_ = + t || + (O + ? o.data.bufferContexts[o.MOTIONBLUR_BUFFER_DRAG] + : u.contexts[o.DRAG])), + h && !O ? "motionBlur" : void 0, + ), + A + ? o.drawCachedNodes(_, S.drag, s, z) + : o.drawCachedElements(_, S.drag, s, z), + o.debug && o.drawDebugPoints(_, S.drag), + n || h || (c[o.DRAG] = !1)); + } + if (o.showFps || (!r && c[o.SELECT_BOX] && !n)) { + if ( + (D((_ = t || u.contexts[o.SELECT_BOX])), + 1 == o.selection[4] && + (o.hoverData.selecting || o.touchData.selecting)) + ) { + b = o.cy.zoom(); + var R = m.core("selection-box-border-width").value / b; + ((_.lineWidth = R), + (_.fillStyle = + "rgba(" + + m.core("selection-box-color").value[0] + + "," + + m.core("selection-box-color").value[1] + + "," + + m.core("selection-box-color").value[2] + + "," + + m.core("selection-box-opacity").value + + ")"), + _.fillRect( + o.selection[0], + o.selection[1], + o.selection[2] - o.selection[0], + o.selection[3] - o.selection[1], + ), + R > 0 && + ((_.strokeStyle = + "rgba(" + + m.core("selection-box-border-color").value[0] + + "," + + m.core("selection-box-border-color").value[1] + + "," + + m.core("selection-box-border-color").value[2] + + "," + + m.core("selection-box-opacity").value + + ")"), + _.strokeRect( + o.selection[0], + o.selection[1], + o.selection[2] - o.selection[0], + o.selection[3] - o.selection[1], + ))); + } + if (u.bgActivePosistion && !o.hoverData.selecting) { + b = o.cy.zoom(); + var V = u.bgActivePosistion; + ((_.fillStyle = + "rgba(" + + m.core("active-bg-color").value[0] + + "," + + m.core("active-bg-color").value[1] + + "," + + m.core("active-bg-color").value[2] + + "," + + m.core("active-bg-opacity").value + + ")"), + _.beginPath(), + _.arc( + V.x, + V.y, + m.core("active-bg-size").pfValue / b, + 0, + 2 * Math.PI, + ), + _.fill()); + } + var F = o.lastRedrawTime; + if (o.showFps && F) { + F = Math.round(F); + var j = Math.round(1e3 / F); + (_.setTransform(1, 0, 0, 1, 0, 0), + (_.fillStyle = "rgba(255, 0, 0, 0.75)"), + (_.strokeStyle = "rgba(255, 0, 0, 0.75)"), + (_.lineWidth = 1), + _.fillText("1 frame = " + F + " ms = " + j + " fps", 0, 20)); + (_.strokeRect(0, 30, 250, 20), + _.fillRect(0, 30, 250 * Math.min(j / 60, 1), 20)); + } + n || (c[o.SELECT_BOX] = !1); + } + if (h && 1 !== p) { + var q = u.contexts[o.NODE], + Y = o.data.bufferCanvases[o.MOTIONBLUR_BUFFER_NODE], + X = u.contexts[o.DRAG], + W = o.data.bufferCanvases[o.MOTIONBLUR_BUFFER_DRAG], + H = function (e, t, n) { + (e.setTransform(1, 0, 0, 1, 0, 0), + n || !y + ? e.clearRect(0, 0, o.canvasWidth, o.canvasHeight) + : P(e, 0, 0, o.canvasWidth, o.canvasHeight)); + var r = p; + e.drawImage( + t, + 0, + 0, + o.canvasWidth * r, + o.canvasHeight * r, + 0, + 0, + o.canvasWidth, + o.canvasHeight, + ); + }; + ((c[o.NODE] || L[o.NODE]) && (H(q, Y, L[o.NODE]), (c[o.NODE] = !1)), + (c[o.DRAG] || L[o.DRAG]) && (H(X, W, L[o.DRAG]), (c[o.DRAG] = !1))); + } + ((o.prevViewport = k), + o.clearingMotionBlur && + ((o.clearingMotionBlur = !1), + (o.motionBlurCleared = !0), + (o.motionBlur = !0)), + h && + (o.motionBlurTimeout = setTimeout(function () { + ((o.motionBlurTimeout = null), + (o.clearedForMotionBlur[o.NODE] = !1), + (o.clearedForMotionBlur[o.DRAG] = !1), + (o.motionBlur = !1), + (o.clearingMotionBlur = !d), + (o.mbFrames = 0), + (c[o.NODE] = !0), + (c[o.DRAG] = !0), + o.redraw()); + }, 100)), + t || l.emit("render")); + })); + for ( + var Qu = { + drawPolygonPath: function (e, t, n, r, i, a) { + var o = r / 2, + s = i / 2; + (e.beginPath && e.beginPath(), e.moveTo(t + o * a[0], n + s * a[1])); + for (var l = 1; l < a.length / 2; l++) + e.lineTo(t + o * a[2 * l], n + s * a[2 * l + 1]); + e.closePath(); + }, + drawRoundPolygonPath: function (e, t, n, r, i, a, o) { + (o.forEach(function (t) { + return Ql(e, t); + }), + e.closePath()); + }, + drawRoundRectanglePath: function (e, t, n, r, i, a) { + var o = r / 2, + s = i / 2, + l = "auto" === a ? nn(r, i) : Math.min(a, s, o); + (e.beginPath && e.beginPath(), + e.moveTo(t, n - s), + e.arcTo(t + o, n - s, t + o, n, l), + e.arcTo(t + o, n + s, t, n + s, l), + e.arcTo(t - o, n + s, t - o, n, l), + e.arcTo(t - o, n - s, t, n - s, l), + e.lineTo(t, n - s), + e.closePath()); + }, + drawBottomRoundRectanglePath: function (e, t, n, r, i, a) { + var o = r / 2, + s = i / 2, + l = "auto" === a ? nn(r, i) : a; + (e.beginPath && e.beginPath(), + e.moveTo(t, n - s), + e.lineTo(t + o, n - s), + e.lineTo(t + o, n), + e.arcTo(t + o, n + s, t, n + s, l), + e.arcTo(t - o, n + s, t - o, n, l), + e.lineTo(t - o, n - s), + e.lineTo(t, n - s), + e.closePath()); + }, + drawCutRectanglePath: function (e, t, n, r, i, a, o) { + var s = r / 2, + l = i / 2, + u = "auto" === o ? 8 : o; + (e.beginPath && e.beginPath(), + e.moveTo(t - s + u, n - l), + e.lineTo(t + s - u, n - l), + e.lineTo(t + s, n - l + u), + e.lineTo(t + s, n + l - u), + e.lineTo(t + s - u, n + l), + e.lineTo(t - s + u, n + l), + e.lineTo(t - s, n + l - u), + e.lineTo(t - s, n - l + u), + e.closePath()); + }, + drawBarrelPath: function (e, t, n, r, i) { + var a = r / 2, + o = i / 2, + s = t - a, + l = t + a, + u = n - o, + c = n + o, + d = an(r, i), + h = d.widthOffset, + p = d.heightOffset, + f = d.ctrlPtOffsetPct * h; + (e.beginPath && e.beginPath(), + e.moveTo(s, u + p), + e.lineTo(s, c - p), + e.quadraticCurveTo(s + f, c, s + h, c), + e.lineTo(l - h, c), + e.quadraticCurveTo(l - f, c, l, c - p), + e.lineTo(l, u + p), + e.quadraticCurveTo(l - f, u, l - h, u), + e.lineTo(s + h, u), + e.quadraticCurveTo(s + f, u, s, u + p), + e.closePath()); + }, + }, + Ju = Math.sin(0), + ec = Math.cos(0), + tc = {}, + nc = {}, + rc = Math.PI / 40, + ic = 0 * Math.PI; + ic < 2 * Math.PI; + ic += rc + ) + ((tc[ic] = Math.sin(ic)), (nc[ic] = Math.cos(ic))); + Qu.drawEllipsePath = function (e, t, n, r, i) { + if ((e.beginPath && e.beginPath(), e.ellipse)) + e.ellipse(t, n, r / 2, i / 2, 0, 0, 2 * Math.PI); + else + for ( + var a, o, s = r / 2, l = i / 2, u = 0 * Math.PI; + u < 2 * Math.PI; + u += rc + ) + ((a = t - s * tc[u] * Ju + s * nc[u] * ec), + (o = n + l * nc[u] * Ju + l * tc[u] * ec), + 0 === u ? e.moveTo(a, o) : e.lineTo(a, o)); + e.closePath(); + }; + var ac = {}; + function oc(e) { + var t = e.indexOf(","); + return e.substr(t + 1); + } + function sc(e, t, n) { + var r = function () { + return t.toDataURL(n, e.quality); + }; + switch (e.output) { + case "blob-promise": + return new vr(function (r, i) { + try { + t.toBlob( + function (e) { + null != e + ? r(e) + : i( + new Error( + "`canvas.toBlob()` sent a null value in its callback", + ), + ); + }, + n, + e.quality, + ); + } catch (e) { + i(e); + } + }); + case "blob": + return (function (e, t) { + for ( + var n = atob(e), + r = new ArrayBuffer(n.length), + i = new Uint8Array(r), + a = 0; + a < n.length; + a++ + ) + i[a] = n.charCodeAt(a); + return new Blob([r], { type: t }); + })(oc(r()), n); + case "base64": + return oc(r()); + case "base64uri": + default: + return r(); + } + } + ((ac.createBuffer = function (e, t) { + var n = document.createElement("canvas"); + return ((n.width = e), (n.height = t), [n, n.getContext("2d")]); + }), + (ac.bufferCanvasImage = function (e) { + var t = this.cy, + n = t.mutableElements().boundingBox(), + r = this.findContainerClientCoords(), + i = e.full ? Math.ceil(n.w) : r[2], + a = e.full ? Math.ceil(n.h) : r[3], + o = x(e.maxWidth) || x(e.maxHeight), + s = this.getPixelRatio(), + l = 1; + if (void 0 !== e.scale) ((i *= e.scale), (a *= e.scale), (l = e.scale)); + else if (o) { + var u = 1 / 0, + c = 1 / 0; + (x(e.maxWidth) && (u = (l * e.maxWidth) / i), + x(e.maxHeight) && (c = (l * e.maxHeight) / a), + (i *= l = Math.min(u, c)), + (a *= l)); + } + o || ((i *= s), (a *= s), (l *= s)); + var d = document.createElement("canvas"); + ((d.width = i), + (d.height = a), + (d.style.width = i + "px"), + (d.style.height = a + "px")); + var h = d.getContext("2d"); + if (i > 0 && a > 0) { + (h.clearRect(0, 0, i, a), (h.globalCompositeOperation = "source-over")); + var p = this.getCachedZSortedEles(); + if (e.full) + (h.translate(-n.x1 * l, -n.y1 * l), + h.scale(l, l), + this.drawElements(h, p), + h.scale(1 / l, 1 / l), + h.translate(n.x1 * l, n.y1 * l)); + else { + var f = t.pan(), + g = { x: f.x * l, y: f.y * l }; + ((l *= t.zoom()), + h.translate(g.x, g.y), + h.scale(l, l), + this.drawElements(h, p), + h.scale(1 / l, 1 / l), + h.translate(-g.x, -g.y)); + } + e.bg && + ((h.globalCompositeOperation = "destination-over"), + (h.fillStyle = e.bg), + h.rect(0, 0, i, a), + h.fill()); + } + return d; + }), + (ac.png = function (e) { + return sc(e, this.bufferCanvasImage(e), "image/png"); + }), + (ac.jpg = function (e) { + return sc(e, this.bufferCanvasImage(e), "image/jpeg"); + })); + var lc = { + nodeShapeImpl: function (e, t, n, r, i, a, o, s) { + switch (e) { + case "ellipse": + return this.drawEllipsePath(t, n, r, i, a); + case "polygon": + return this.drawPolygonPath(t, n, r, i, a, o); + case "round-polygon": + return this.drawRoundPolygonPath(t, n, r, i, a, o, s); + case "roundrectangle": + case "round-rectangle": + return this.drawRoundRectanglePath(t, n, r, i, a, s); + case "cutrectangle": + case "cut-rectangle": + return this.drawCutRectanglePath(t, n, r, i, a, o, s); + case "bottomroundrectangle": + case "bottom-round-rectangle": + return this.drawBottomRoundRectanglePath(t, n, r, i, a, s); + case "barrel": + return this.drawBarrelPath(t, n, r, i, a); + } + }, + }, + uc = dc, + cc = dc.prototype; + function dc(e) { + var t = this, + n = t.cy.window().document; + t.data = { + canvases: new Array(cc.CANVAS_LAYERS), + contexts: new Array(cc.CANVAS_LAYERS), + canvasNeedsRedraw: new Array(cc.CANVAS_LAYERS), + bufferCanvases: new Array(cc.BUFFER_COUNT), + bufferContexts: new Array(cc.CANVAS_LAYERS), + }; + t.data.canvasContainer = n.createElement("div"); + var r = t.data.canvasContainer.style; + ((t.data.canvasContainer.style["-webkit-tap-highlight-color"] = + "rgba(0,0,0,0)"), + (r.position = "relative"), + (r.zIndex = "0"), + (r.overflow = "hidden")); + var i = e.cy.container(); + (i.appendChild(t.data.canvasContainer), + (i.style["-webkit-tap-highlight-color"] = "rgba(0,0,0,0)")); + var a = { + "-webkit-user-select": "none", + "-moz-user-select": "-moz-none", + "user-select": "none", + "-webkit-tap-highlight-color": "rgba(0,0,0,0)", + "outline-style": "none", + }; + c && + c.userAgent.match(/msie|trident|edge/i) && + ((a["-ms-touch-action"] = "none"), (a["touch-action"] = "none")); + for (var o = 0; o < cc.CANVAS_LAYERS; o++) { + var s = (t.data.canvases[o] = n.createElement("canvas")); + ((t.data.contexts[o] = s.getContext("2d")), + Object.keys(a).forEach(function (e) { + s.style[e] = a[e]; + }), + (s.style.position = "absolute"), + s.setAttribute("data-id", "layer" + o), + (s.style.zIndex = String(cc.CANVAS_LAYERS - o)), + t.data.canvasContainer.appendChild(s), + (t.data.canvasNeedsRedraw[o] = !1)); + } + ((t.data.topCanvas = t.data.canvases[0]), + t.data.canvases[cc.NODE].setAttribute( + "data-id", + "layer" + cc.NODE + "-node", + ), + t.data.canvases[cc.SELECT_BOX].setAttribute( + "data-id", + "layer" + cc.SELECT_BOX + "-selectbox", + ), + t.data.canvases[cc.DRAG].setAttribute( + "data-id", + "layer" + cc.DRAG + "-drag", + )); + for (o = 0; o < cc.BUFFER_COUNT; o++) + ((t.data.bufferCanvases[o] = n.createElement("canvas")), + (t.data.bufferContexts[o] = t.data.bufferCanvases[o].getContext("2d")), + (t.data.bufferCanvases[o].style.position = "absolute"), + t.data.bufferCanvases[o].setAttribute("data-id", "buffer" + o), + (t.data.bufferCanvases[o].style.zIndex = String(-o - 1)), + (t.data.bufferCanvases[o].style.visibility = "hidden")); + t.pathsEnabled = !0; + var l = _t(), + u = function (e) { + return { x: -e.w / 2, y: -e.h / 2 }; + }, + d = function (e) { + return (e.boundingBox(), e[0]._private.bodyBounds); + }, + h = function (e) { + return (e.boundingBox(), e[0]._private.labelBounds.main || l); + }, + p = function (e) { + return (e.boundingBox(), e[0]._private.labelBounds.source || l); + }, + f = function (e) { + return (e.boundingBox(), e[0]._private.labelBounds.target || l); + }, + g = function (e, t) { + return t; + }, + v = function (e, t, n) { + var r = e ? e + "-" : ""; + return { + x: t.x + n.pstyle(r + "text-margin-x").pfValue, + y: t.y + n.pstyle(r + "text-margin-y").pfValue, + }; + }, + y = function (e, t, n) { + var r = e[0]._private.rscratch; + return { x: r[t], y: r[n] }; + }, + m = (t.data.eleTxrCache = new Cu(t, { + getKey: function (e) { + return e[0]._private.nodeKey; + }, + doesEleInvalidateKey: function (e) { + var t = e[0]._private; + return !(t.oldBackgroundTimestamp === t.backgroundTimestamp); + }, + drawElement: function (e, n, r, i, a) { + return t.drawElement(e, n, r, !1, !1, a); + }, + getBoundingBox: d, + getRotationPoint: function (e) { + return { x: ((t = d(e)).x1 + t.x2) / 2, y: (t.y1 + t.y2) / 2 }; + var t; + }, + getRotationOffset: function (e) { + return u(d(e)); + }, + allowEdgeTxrCaching: !1, + allowParentTxrCaching: !1, + })), + b = (t.data.lblTxrCache = new Cu(t, { + getKey: function (e) { + return e[0]._private.labelStyleKey; + }, + drawElement: function (e, n, r, i, a) { + return t.drawElementText(e, n, r, i, "main", a); + }, + getBoundingBox: h, + getRotationPoint: function (e) { + return v("", y(e, "labelX", "labelY"), e); + }, + getRotationOffset: function (e) { + var t = h(e), + n = u(h(e)); + if (e.isNode()) { + switch (e.pstyle("text-halign").value) { + case "left": + n.x = -t.w; + break; + case "right": + n.x = 0; + } + switch (e.pstyle("text-valign").value) { + case "top": + n.y = -t.h; + break; + case "bottom": + n.y = 0; + } + } + return n; + }, + isVisible: g, + })), + x = (t.data.slbTxrCache = new Cu(t, { + getKey: function (e) { + return e[0]._private.sourceLabelStyleKey; + }, + drawElement: function (e, n, r, i, a) { + return t.drawElementText(e, n, r, i, "source", a); + }, + getBoundingBox: p, + getRotationPoint: function (e) { + return v("source", y(e, "sourceLabelX", "sourceLabelY"), e); + }, + getRotationOffset: function (e) { + return u(p(e)); + }, + isVisible: g, + })), + w = (t.data.tlbTxrCache = new Cu(t, { + getKey: function (e) { + return e[0]._private.targetLabelStyleKey; + }, + drawElement: function (e, n, r, i, a) { + return t.drawElementText(e, n, r, i, "target", a); + }, + getBoundingBox: f, + getRotationPoint: function (e) { + return v("target", y(e, "targetLabelX", "targetLabelY"), e); + }, + getRotationOffset: function (e) { + return u(f(e)); + }, + isVisible: g, + })), + E = (t.data.lyrTxrCache = new Pu(t)); + t.onUpdateEleCalcs(function (e, t) { + (m.invalidateElements(t), + b.invalidateElements(t), + x.invalidateElements(t), + w.invalidateElements(t), + E.invalidateElements(t)); + for (var n = 0; n < t.length; n++) { + var r = t[n]._private; + r.oldBackgroundTimestamp = r.backgroundTimestamp; + } + }); + var k = function (e) { + for (var t = 0; t < e.length; t++) E.enqueueElementRefinement(e[t].ele); + }; + (m.onDequeue(k), b.onDequeue(k), x.onDequeue(k), w.onDequeue(k)); + } + ((cc.CANVAS_LAYERS = 3), + (cc.SELECT_BOX = 0), + (cc.DRAG = 1), + (cc.NODE = 2), + (cc.BUFFER_COUNT = 3), + (cc.TEXTURE_BUFFER = 0), + (cc.MOTIONBLUR_BUFFER_NODE = 1), + (cc.MOTIONBLUR_BUFFER_DRAG = 2), + (cc.redrawHint = function (e, t) { + var n = this; + switch (e) { + case "eles": + n.data.canvasNeedsRedraw[cc.NODE] = t; + break; + case "drag": + n.data.canvasNeedsRedraw[cc.DRAG] = t; + break; + case "select": + n.data.canvasNeedsRedraw[cc.SELECT_BOX] = t; + } + })); + var hc = "undefined" != typeof Path2D; + ((cc.path2dEnabled = function (e) { + if (void 0 === e) return this.pathsEnabled; + this.pathsEnabled = !!e; + }), + (cc.usePaths = function () { + return hc && this.pathsEnabled; + }), + (cc.setImgSmoothing = function (e, t) { + null != e.imageSmoothingEnabled + ? (e.imageSmoothingEnabled = t) + : ((e.webkitImageSmoothingEnabled = t), + (e.mozImageSmoothingEnabled = t), + (e.msImageSmoothingEnabled = t)); + }), + (cc.getImgSmoothing = function (e) { + return null != e.imageSmoothingEnabled + ? e.imageSmoothingEnabled + : e.webkitImageSmoothingEnabled || + e.mozImageSmoothingEnabled || + e.msImageSmoothingEnabled; + }), + (cc.makeOffscreenCanvas = function (t, n) { + var r; + "undefined" !== + ("undefined" == typeof OffscreenCanvas ? "undefined" : e(OffscreenCanvas)) + ? (r = new OffscreenCanvas(t, n)) + : (((r = this.cy.window().document.createElement("canvas")).width = t), + (r.height = n)); + return r; + }), + [Bu, Ou, Xu, Hu, Ku, Uu, $u, Qu, ac, lc].forEach(function (e) { + L(cc, e); + })); + var pc = [ + { type: "layout", extensions: Cl }, + { + type: "renderer", + extensions: [ + { name: "null", impl: Sl }, + { name: "base", impl: mu }, + { name: "canvas", impl: uc }, + ], + }, + ], + fc = {}, + gc = {}; + function vc(e, t, n) { + var r = n, + i = function (n) { + je( + "Can not register `" + + t + + "` for `" + + e + + "` since `" + + n + + "` already exists in the prototype and can not be overridden", + ); + }; + if ("core" === e) { + if (Os.prototype[t]) return i(t); + Os.prototype[t] = n; + } else if ("collection" === e) { + if (ts.prototype[t]) return i(t); + ts.prototype[t] = n; + } else if ("layout" === e) { + for ( + var a = function (e) { + ((this.options = e), + n.call(this, e), + b(this._private) || (this._private = {}), + (this._private.cy = e.cy), + (this._private.listeners = []), + this.createEmitter()); + }, + o = (a.prototype = Object.create(n.prototype)), + s = [], + l = 0; + l < s.length; + l++ + ) { + var u = s[l]; + o[u] = + o[u] || + function () { + return this; + }; + } + o.start && !o.run + ? (o.run = function () { + return (this.start(), this); + }) + : !o.start && + o.run && + (o.start = function () { + return (this.run(), this); + }); + var c = n.prototype.stop; + ((o.stop = function () { + var e = this.options; + if (e && e.animate) { + var t = this.animations; + if (t) for (var n = 0; n < t.length; n++) t[n].stop(); + } + return (c ? c.call(this) : this.emit("layoutstop"), this); + }), + o.destroy || + (o.destroy = function () { + return this; + }), + (o.cy = function () { + return this._private.cy; + })); + var d = function (e) { + return e._private.cy; + }, + h = { + addEventFields: function (e, t) { + ((t.layout = e), (t.cy = d(e)), (t.target = e)); + }, + bubble: function () { + return !0; + }, + parent: function (e) { + return d(e); + }, + }; + (L(o, { + createEmitter: function () { + return ((this._private.emitter = new xo(h, this)), this); + }, + emitter: function () { + return this._private.emitter; + }, + on: function (e, t) { + return (this.emitter().on(e, t), this); + }, + one: function (e, t) { + return (this.emitter().one(e, t), this); + }, + once: function (e, t) { + return (this.emitter().one(e, t), this); + }, + removeListener: function (e, t) { + return (this.emitter().removeListener(e, t), this); + }, + removeAllListeners: function () { + return (this.emitter().removeAllListeners(), this); + }, + emit: function (e, t) { + return (this.emitter().emit(e, t), this); + }, + }), + Fi.eventAliasesOn(o), + (r = a)); + } else if ("renderer" === e && "null" !== t && "base" !== t) { + var p = yc("renderer", "base"), + f = p.prototype, + g = n, + v = n.prototype, + y = function () { + (p.apply(this, arguments), g.apply(this, arguments)); + }, + m = y.prototype; + for (var x in f) { + var w = f[x]; + if (null != v[x]) return i(x); + m[x] = w; + } + for (var E in v) m[E] = v[E]; + (f.clientFunctions.forEach(function (e) { + m[e] = + m[e] || + function () { + Ve( + "Renderer does not implement `renderer." + + e + + "()` on its prototype", + ); + }; + }), + (r = y)); + } else if ("__proto__" === e || "constructor" === e || "prototype" === e) + return Ve( + e + + " is an illegal type to be registered, possibly lead to prototype pollutions", + ); + return V({ map: fc, keys: [e, t], value: r }); + } + function yc(e, t) { + return F({ map: fc, keys: [e, t] }); + } + function mc(e, t, n, r, i) { + return V({ map: gc, keys: [e, t, n, r], value: i }); + } + function bc(e, t, n, r) { + return F({ map: gc, keys: [e, t, n, r] }); + } + var xc = function () { + return 2 === arguments.length + ? yc.apply(null, arguments) + : 3 === arguments.length + ? vc.apply(null, arguments) + : 4 === arguments.length + ? bc.apply(null, arguments) + : 5 === arguments.length + ? mc.apply(null, arguments) + : void Ve("Invalid extension access syntax"); + }; + ((Os.prototype.extension = xc), + pc.forEach(function (e) { + e.extensions.forEach(function (t) { + vc(e.type, t.name, t.impl); + }); + })); + var wc = function e() { + if (!(this instanceof e)) return new e(); + this.length = 0; + }, + Ec = wc.prototype; + ((Ec.instanceString = function () { + return "stylesheet"; + }), + (Ec.selector = function (e) { + return ((this[this.length++] = { selector: e, properties: [] }), this); + }), + (Ec.css = function (e, t) { + var n = this.length - 1; + if (v(e)) this[n].properties.push({ name: e, value: t }); + else if (b(e)) + for (var r = e, i = Object.keys(r), a = 0; a < i.length; a++) { + var o = i[a], + s = r[o]; + if (null != s) { + var l = Ns.properties[o] || Ns.properties[B(o)]; + if (null != l) { + var u = l.name, + c = s; + this[n].properties.push({ name: u, value: c }); + } + } + } + return this; + }), + (Ec.style = Ec.css), + (Ec.generateStyle = function (e) { + var t = new Ns(e); + return this.appendToStyle(t); + }), + (Ec.appendToStyle = function (e) { + for (var t = 0; t < this.length; t++) { + var n = this[t], + r = n.selector, + i = n.properties; + e.selector(r); + for (var a = 0; a < i.length; a++) { + var o = i[a]; + e.css(o.name, o.value); + } + } + return e; + })); + var kc = function (e) { + return ( + void 0 === e && (e = {}), + b(e) ? new Os(e) : v(e) ? xc.apply(xc, arguments) : void 0 + ); + }; + return ( + (kc.use = function (e) { + var t = Array.prototype.slice.call(arguments, 1); + return (t.unshift(kc), e.apply(null, t), this); + }), + (kc.warnings = function (e) { + return Fe(e); + }), + (kc.version = "3.30.2"), + (kc.stylesheet = kc.Stylesheet = wc), + kc + ); +}); diff --git a/Web/editor.css b/Web/editor.css index 50b2840cb..772ab29ad 100644 --- a/Web/editor.css +++ b/Web/editor.css @@ -43,6 +43,18 @@ color: #e9d5ff; } +.sidebar-btn-graph { + background: rgba(14, 165, 233, 0.1); + border-color: #0ea5e9; + color: #7dd3fc; +} + +.sidebar-btn-graph:hover { + background: rgba(14, 165, 233, 0.22); + border-color: #38bdf8; + color: #bae6fd; +} + /* ==================== Editor Icon Buttons ==================== */ .editor-icons { @@ -299,6 +311,9 @@ .editor-modal { width: min(680px, 92vw); +} + +.editor-modal { max-height: 88vh; display: flex; flex-direction: column; diff --git a/Web/editor.js b/Web/editor.js index 9255e969e..126e73153 100644 --- a/Web/editor.js +++ b/Web/editor.js @@ -300,6 +300,10 @@ return !!findMessageDefRange(msgName) || !!findCustomCanIdRange(msgName); } + function isCustomCanIdMessage(msgName) { + return !!findCustomCanIdRange(msgName); + } + function renameRoutingMessageRefs(oldName, newName) { if (!oldName || !newName || oldName === newName) return false; const lines = getLines(); @@ -394,14 +398,20 @@ const btn = document.createElement("button"); btn.className = "editor-add-btn"; btn.innerHTML = window.FormUtils.PLUS_SVG + " " + label; - btn.addEventListener("click", onClick); + btn.addEventListener("click", (e) => { + e.stopPropagation(); + onClick(); + }); return btn; } // ==================== Download ==================== function downloadCando() { - const blob = new Blob([rawCandoText], { type: "text/plain" }); + const serialized = window.GrcanDocument + ? window.GrcanDocument.getSerializedText() + : null; + const blob = new Blob([serialized ?? rawCandoText], { type: "text/plain" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; @@ -433,6 +443,12 @@ editedKeys.clear(); newKeys.clear(); }, + // Update working text without resetting original or edit state. + // Used by GrcanDocument after semantic mutations. + updateRawText(text) { + rawCandoText = text; + hasEdits = true; + }, getRawText() { return rawCandoText; }, @@ -477,6 +493,7 @@ grIdNameExists, renameGrIdNode, messageNameExists, + isCustomCanIdMessage, renameRoutingMessageRefs, generateMessageIdYaml, generateRoutingMsgYaml, diff --git a/Web/formBusAdd.js b/Web/formBusAdd.js new file mode 100644 index 000000000..85cc4cfaf --- /dev/null +++ b/Web/formBusAdd.js @@ -0,0 +1,52 @@ +// Purpose: "Add Bus" modal form. +// Allows creating a new bus block (CAN1/CAN2/CAN3) for an existing routing node +// without requiring receiver/message route details. +// Depends on: formUtils.js (FormUtils), editor.js (GrcanEditor). +// Registers: window.GrcanEditor.showRoutingBusAddForm + +(function () { + "use strict"; + + function showRoutingBusAddForm(deviceName) { + const editor = window.GrcanEditor; + const fu = window.FormUtils; + const { overlay, body, footer } = fu.createModal("Add Bus"); + + const nodeF = fu.makeFormRow( + "Node", + fu.makeInput("text", deviceName || "", "Node Name"), + true, + ); + nodeF.input.disabled = true; + body.appendChild(nodeF.row); + + const busF = fu.makeFormRow( + "Bus", + fu.makeSelect(["CAN1", "CAN2", "CAN3"], "CAN1"), + true, + ); + body.appendChild(busF.row); + + const cancelBtn = fu.makeBtn("Cancel"); + cancelBtn.addEventListener("click", () => fu.closeOverlay(overlay)); + const saveBtn = fu.makeBtn("Add", "editor-btn-primary"); + footer.appendChild(cancelBtn); + footer.appendChild(saveBtn); + + saveBtn.addEventListener("click", () => { + const bus = busF.input.value; + const result = window.GrcanDocument.addBus(deviceName, bus); + if (!result.ok) { + busF.error.textContent = result.error; + return; + } + busF.error.textContent = ""; + editor.markEdited("routeNode:" + deviceName); + editor.markNew("routeBus:" + deviceName + "|" + bus); + fu.closeOverlay(overlay, { force: true }); + editor.triggerReRender(); + }); + } + + window.GrcanEditor.showRoutingBusAddForm = showRoutingBusAddForm; +})(); diff --git a/Web/formCustomCanId.js b/Web/formCustomCanId.js new file mode 100644 index 000000000..c26364245 --- /dev/null +++ b/Web/formCustomCanId.js @@ -0,0 +1,204 @@ +// Purpose: "Add / Edit Custom CAN ID" modal form. +// Handles Custom CAN ID section entries: CAN ID (hex), Length, and signals +// (name, bit_start, optional comment). Uses GrcanDocument for mutations. +// Depends on: formUtils.js (FormUtils), editor.js (GrcanEditor), candoDocument.js. +// Registers: window.GrcanEditor.showCustomCanIdEditForm + +(function () { + "use strict"; + + function showCustomCanIdEditForm(msgName, isNew) { + const editor = window.GrcanEditor; + const doc = window.GrcanDocument; + const fu = window.FormUtils; + + const existing = isNew ? null : doc.getCustomCanIdDef(msgName); + const { overlay, body, footer } = fu.createModal( + isNew ? "Add Custom CAN ID" : "Edit: " + msgName, + ); + + const nameF = fu.makeFormRow( + "Message Name", + fu.makeInput("text", isNew ? "" : msgName), + true, + ); + const idF = fu.makeFormRow( + "CAN ID", + fu.makeInput("text", existing?.canId || "", "e.g. 116 or 18FF50E5"), + true, + ); + const lenF = fu.makeFormRow( + "Length (bytes)", + fu.makeInput("number", existing?.length || "", "8"), + true, + ); + body.appendChild(nameF.row); + body.appendChild(idF.row); + body.appendChild(lenF.row); + + // Signals section + const sigHdr = document.createElement("div"); + sigHdr.className = "editor-section-header"; + const sigTitle = document.createElement("span"); + sigTitle.textContent = "Signals"; + sigHdr.appendChild(sigTitle); + const addSigBtn = document.createElement("button"); + addSigBtn.className = "editor-btn editor-btn-sm"; + addSigBtn.innerHTML = fu.PLUS_SVG + " Add Signal"; + sigHdr.appendChild(addSigBtn); + body.appendChild(sigHdr); + + const sigBox = document.createElement("div"); + sigBox.className = "editor-fields-box"; + body.appendChild(sigBox); + + function addSignalRow(sig) { + const card = document.createElement("div"); + card.className = "editor-field-card"; + + const topRow = document.createElement("div"); + topRow.className = "editor-field-grid"; + + const fName = fu.makeFormRow( + "Name", + fu.makeInput("text", sig?.name || "", "Signal Name"), + true, + ); + const fBit = fu.makeFormRow( + "bit_start", + fu.makeInput("text", sig?.bitStart || "", "0 or 0-7"), + true, + ); + topRow.appendChild(fName.row); + topRow.appendChild(fBit.row); + card.appendChild(topRow); + + const commentRow = document.createElement("div"); + commentRow.className = "editor-field-grid"; + const fComment = fu.makeFormRow( + "Comment", + fu.makeInput("textarea", sig?.comment || "", "Description"), + ); + commentRow.appendChild(fComment.row); + card.appendChild(commentRow); + + const controlsRow = document.createElement("div"); + controlsRow.className = "editor-field-controls"; + const upBtn = fu.makeBtn("Move Up", "editor-btn-sm"); + const downBtn = fu.makeBtn("Move Down", "editor-btn-sm"); + const removeBtn = document.createElement("button"); + removeBtn.className = "editor-btn editor-btn-danger editor-btn-sm"; + removeBtn.innerHTML = fu.TRASH_SVG + " Remove"; + removeBtn.addEventListener("click", () => card.remove()); + upBtn.addEventListener("click", (e) => { + e.preventDefault(); + const prev = card.previousElementSibling; + if (prev) card.parentNode.insertBefore(card, prev); + }); + downBtn.addEventListener("click", (e) => { + e.preventDefault(); + const next = card.nextElementSibling; + if (next) card.parentNode.insertBefore(next, card); + }); + controlsRow.appendChild(upBtn); + controlsRow.appendChild(downBtn); + controlsRow.appendChild(removeBtn); + card.appendChild(controlsRow); + + card._getValues = () => ({ + name: fName.input.value.trim(), + bitStart: fBit.input.value.trim(), + comment: fComment.input.value.trim() || null, + }); + + card._validate = () => { + let ok = true; + if (!fName.input.value.trim()) { + fName.error.textContent = "Required"; + ok = false; + } else fName.error.textContent = ""; + + const bs = fBit.input.value.trim(); + if (!bs) { + fBit.error.textContent = "Required"; + ok = false; + } else if (!/^\d+(\s*-\s*\d+)?$/.test(bs)) { + fBit.error.textContent = "Integer or range (e.g. 0-7)"; + ok = false; + } else fBit.error.textContent = ""; + + return ok; + }; + + sigBox.appendChild(card); + } + + if (existing && existing.signals.length > 0) { + existing.signals.forEach((s) => addSignalRow(s)); + } + addSigBtn.addEventListener("click", () => addSignalRow(null)); + + const cancelBtn = fu.makeBtn("Cancel"); + cancelBtn.addEventListener("click", () => fu.closeOverlay(overlay)); + const saveBtn = fu.makeBtn("Save", "editor-btn-primary"); + footer.appendChild(cancelBtn); + footer.appendChild(saveBtn); + + saveBtn.addEventListener("click", () => { + let ok = true; + + const name = nameF.input.value.trim(); + if (!name) { + nameF.error.textContent = "Required"; + ok = false; + } else nameF.error.textContent = ""; + + const canId = idF.input.value.trim(); + if (!canId) { + idF.error.textContent = "Required"; + ok = false; + } else if (!/^[0-9a-fA-F]+$/.test(canId)) { + idF.error.textContent = "Must be hex (e.g. 116 or 18FF50E5)"; + ok = false; + } else idF.error.textContent = ""; + + const length = lenF.input.value.trim(); + if (!length || parseInt(length, 10) < 0 || isNaN(parseInt(length, 10))) { + lenF.error.textContent = "Non-negative integer"; + ok = false; + } else lenF.error.textContent = ""; + + const cards = sigBox.querySelectorAll(".editor-field-card"); + cards.forEach((c) => { + if (!c._validate()) ok = false; + }); + if (!ok) return; + + const signals = []; + cards.forEach((c) => signals.push(c._getValues())); + + const def = { name, canId, length, signals }; + + if (!isNew && msgName) { + const result = doc.updateCustomCanIdDef(msgName, def); + if (!result.ok) { + nameF.error.textContent = result.error; + return; + } + editor.markEdited("customCan:" + msgName); + if (name !== msgName) editor.markEdited("customCan:" + name); + } else { + const result = doc.addCustomCanIdDef(def); + if (!result.ok) { + nameF.error.textContent = result.error; + return; + } + editor.markNew("customCan:" + name); + } + fu.closeOverlay(overlay, { force: true }); + editor.triggerReRender(); + }); + } + + window.GrcanEditor.showCustomCanIdEditForm = showCustomCanIdEditForm; +})(); diff --git a/Web/formMessageDef.js b/Web/formMessageDef.js index 0e961cd40..10967f1de 100644 --- a/Web/formMessageDef.js +++ b/Web/formMessageDef.js @@ -33,6 +33,7 @@ const lines = editor.getLines().slice(range.startLine, range.endLine); const result = { name: msgName, msgId: "", msgLength: "", fields: [] }; let cur = null; + let _inComment = false; for (const line of lines) { const indent = line.search(/\S/); @@ -40,6 +41,7 @@ const c = line.trim(); if (indent === 4) { + _inComment = false; if (c.startsWith("MSG ID:")) { result.msgId = c.slice(7).trim(); } else if (c.startsWith("MSG LENGTH:")) { @@ -60,6 +62,7 @@ } } else if (indent >= 6 && cur) { if (c.startsWith("bit_start:")) { + _inComment = false; const v = c.slice(10).trim(); const rm = v.match(/^(\d+)\s*-\s*(\d+)$/); if (rm) { @@ -72,27 +75,37 @@ cur.bitEnd = n; } } + } else if (c.startsWith("comment:")) { + const raw = c.slice("comment:".length).trim(); + const inline = raw === "|" || raw === ">" ? "" : raw; + cur.comment = inline || ""; + _inComment = true; } else if (c.startsWith("#")) { + // backward compat: old # format + _inComment = false; const t = c.replace(/^#\s*/, "").trim(); if (t) cur.comment = cur.comment ? cur.comment + "\n" + t : t; - } else if (c.startsWith("data type:")) { + } else if (!_inComment && c.startsWith("data type:")) { const rawType = c.slice(10).trim(); // Backward compatibility for older aliases while keeping // canonical signed type labels in the editor UI. if (rawType === "i16") cur.rawDataType = "s16"; else if (rawType === "i32") cur.rawDataType = "s32"; else cur.rawDataType = rawType; - } else if (c.startsWith("units:")) { + } else if (!_inComment && c.startsWith("units:")) { cur.units = c.slice(6).trim(); - } else if (c.startsWith("scaled min:")) { + } else if (!_inComment && c.startsWith("scaled min:")) { cur.scaledMin = c.slice(11).trim(); - } else if (c.startsWith("scaled max:")) { + } else if (!_inComment && c.startsWith("scaled max:")) { cur.scaledMax = c.slice(11).trim(); - } else if (c.startsWith("map equation:")) { + } else if (!_inComment && c.startsWith("map equation:")) { cur.mapEquation = c .slice(13) .trim() .replace(/^["']|["']$/g, ""); + } else if (_inComment) { + // continuation lines of the comment: block + cur.comment = cur.comment ? cur.comment + "\n" + c : c; } } } @@ -183,7 +196,7 @@ botRow.className = "editor-field-grid editor-field-grid-5"; const fComment = fu.makeFormRow( "Comment", - fu.makeInput("text", field?.comment || "", "Description"), + fu.makeInput("textarea", field?.comment || "", "Description"), ); const fUnits = fu.makeFormRow( "Units", @@ -441,38 +454,24 @@ } if (!ok) return; - const yaml = editor.generateMessageIdYaml({ - name, - msgId, - msgLength: parseInt(msgLen, 10), - fields, - }); + const def = { name, msgId, msgLength: msgLen, fields }; if (!isNewMsg && msgName) { - const defRange = editor.findMessageDefRange(msgName); - const changed = - defRange && - editor.getLineRangeText(defRange.startLine, defRange.endLine) !== - yaml; - if (changed) { - editor.replaceLineRange(defRange.startLine, defRange.endLine, yaml); - if (name !== msgName) { - editor.renameRoutingMessageRefs(msgName, name); - } - } - if (changed) { - editor.markEdited("msgDef:" + msgName); - if (name !== msgName) editor.markEdited("msgDef:" + name); + const result = window.GrcanDocument.updateMessageDef(msgName, def); + if (!result.ok) { + nameF.error.textContent = result.error; + return; } + editor.markEdited("msgDef:" + msgName); + if (name !== msgName) editor.markEdited("msgDef:" + name); fu.closeOverlay(overlay, { force: true }); - if (changed) editor.triggerReRender(); + editor.triggerReRender(); return; } else { - const lines = editor.getLines(); - const secStart = editor.findSectionStart(lines, "Message ID"); - if (secStart !== -1) { - const secEnd = editor.findSectionEnd(lines, secStart); - editor.insertAtLine(secEnd, yaml); + const result = window.GrcanDocument.addMessageDef(def); + if (!result.ok) { + nameF.error.textContent = result.error; + return; } editor.markNew("msgDef:" + name); } diff --git a/Web/formNodeEdit.js b/Web/formNodeEdit.js index 839e82ea2..03a0c7edd 100644 --- a/Web/formNodeEdit.js +++ b/Web/formNodeEdit.js @@ -35,8 +35,7 @@ ok = false; } else if ( newName !== oldDeviceName && - (editor.findRoutingDeviceRange(newName) || - (!!editor.grIdNameExists && editor.grIdNameExists(newName))) + window.GrcanDocument.deviceExists(newName) ) { nameF.error.textContent = "Node already exists"; ok = false; @@ -50,14 +49,11 @@ return; } - const range = editor.findRoutingDeviceRange(oldDeviceName); - if (!range) return; - editor.replaceLineRange( - range.startLine, - range.startLine + 1, - " " + newName + ":\n", - ); - if (editor.renameGrIdNode) editor.renameGrIdNode(oldDeviceName, newName); + const result = window.GrcanDocument.renameDevice(oldDeviceName, newName); + if (!result.ok) { + nameF.error.textContent = result.error; + return; + } editor.markEdited("routeNode:" + newName); fu.closeOverlay(overlay, { force: true }); editor.triggerReRender(); diff --git a/Web/formRoutingAdd.js b/Web/formRoutingAdd.js index 232e03772..ea76aa91d 100644 --- a/Web/formRoutingAdd.js +++ b/Web/formRoutingAdd.js @@ -88,58 +88,30 @@ // name lists). Usage ranking is bus-local: currentBusPort narrows which // routing entries count as "already used" so unused-first sorting is // meaningful in context. - async function loadCatalogSuggestions() { + function loadCatalogSuggestions() { const rawText = editor.getRawText ? editor.getRawText() : ""; // Read the live bus value so filtering updates when the user changes it. const currentBusPort = busF.input.value || null; buildRouteUsageMap(rawText, currentBusPort); const routingNames = buildRoutingReceiverSet(rawText, currentBusPort); - const fallbackMessages = + const messages = window.GrcanApi && window.GrcanApi.parseMessageCatalogFromText ? window.GrcanApi.parseMessageCatalogFromText(rawText) : []; - const fallbackNodes = + const nodes = window.GrcanApi && window.GrcanApi.parseNodeCatalogFromText ? window.GrcanApi.parseNodeCatalogFromText(rawText) : []; - const refEl = document.getElementById("ref-select"); - const ref = refEl ? refEl.value : ""; - if (!window.GrcanApi || !ref) { - allMessageNames = [...new Set(fallbackMessages)]; - receiverList = [...new Set([...fallbackNodes, ...routingNames])].sort( - (a, b) => a.localeCompare(b), - ); - return; - } - const [messageCatalog, nodeCatalog] = await Promise.all([ - window.GrcanApi.fetchMessageCatalog(ref), - window.GrcanApi.fetchNodeCatalog(ref), - ]); - const headerNames = - !messageCatalog.error && messageCatalog.messages - ? messageCatalog.messages - : []; - // Merge header-derived and current-text-derived names so that new - // message definitions created in this edit session are immediately - // available in autocomplete. Header names remain the long-term - // source of truth; text names add local, in-session additions. - const messageCandidates = [ - ...new Set([...headerNames, ...fallbackMessages]), - ]; - // For receivers: use catalog node names ONLY when no bus is selected, - // so we don't suggest nodes from other buses. When a bus is locked, - // routingNames already contains the bus-local receivers. - const nodeCandidates = - !nodeCatalog.error && nodeCatalog.nodes - ? nodeCatalog.nodes - : fallbackNodes; + allMessageNames = [...new Set(messages)]; + // For receivers: when a bus is locked, routingNames already contains + // the bus-local receivers; don't mix in nodes from other buses. const baseReceivers = currentBusPort ? [...routingNames] - : [...new Set([...nodeCandidates, ...routingNames])]; - allMessageNames = [...new Set(messageCandidates)]; + : [...new Set([...nodes, ...routingNames])]; receiverList = [...new Set(baseReceivers)].sort((a, b) => a.localeCompare(b), ); + if (!receiverList.includes("ALL")) receiverList.unshift("ALL"); } const devF = fu.makeFormRow( @@ -150,6 +122,25 @@ if (deviceName) devF.input.disabled = true; body.appendChild(devF.row); + // GR ID field: only shown (and required) when the typed device name is new. + const grIdF = fu.makeFormRow( + "GR ID (new device)", + fu.makeInput("text", "", "e.g. 0x2B"), + false, + ); + grIdF.row.style.display = "none"; + body.appendChild(grIdF.row); + + function updateGrIdVisibility() { + const isNew = + !devF.input.disabled && + !window.GrcanDocument.deviceExists(devF.input.value.trim()); + grIdF.row.style.display = isNew && devF.input.value.trim() ? "" : "none"; + } + devF.input.addEventListener("input", updateGrIdVisibility); + // Run once on open in case a device name was pre-filled. + if (!devF.input.disabled) updateGrIdVisibility(); + const busF = fu.makeFormRow( "Bus", fu.makeSelect(["CAN1", "CAN2", "CAN3"], busPort || "CAN1"), @@ -167,6 +158,10 @@ } body.appendChild(busF.row); + // Eagerly populate suggestions so "ALL" and other candidates are ready + // before the user focuses the receiver field. + loadCatalogSuggestions(); + const recF = fu.makeFormRow( "Receiver", fu.makeInput("text", "", "Receiver Name"), @@ -224,7 +219,6 @@ renderReceiverSuggestions(recF.input.value); }); recF.input.addEventListener("focus", () => { - if (!receiverList.length) loadCatalogSuggestions(); renderReceiverSuggestions(recF.input.value); }); recF.input.addEventListener("blur", () => { @@ -312,6 +306,7 @@ e.preventDefault(); msgF.input.value = name; suggestBox.classList.add("hidden"); + syncOverrideForMessage(name); }); suggestBox.appendChild(item); }); @@ -345,6 +340,7 @@ if (suggestIndex >= 0 && suggestIndex < items.length) { const name = items[suggestIndex].textContent || ""; msgF.input.value = name; + syncOverrideForMessage(name); } suggestBox.classList.add("hidden"); return; @@ -362,6 +358,36 @@ ); body.appendChild(ovrF.row); + // Auto-fill the override field when the selected message is a Custom CAN ID + // message (whose canId is stored as bare hex, e.g. "2416"). The routing + // section requires 0x-prefixed format, so we prefix it here. + // _autoFilled tracks whether the current value was set programmatically so + // we can clear it when the user switches to a non-custom message, without + // ever clearing a value the user typed themselves. + ovrF.input._autoFilled = false; + ovrF.input.addEventListener("input", () => { + ovrF.input._autoFilled = false; + }); + + function syncOverrideForMessage(name) { + if (!name) return; + if (window.GrcanEditor.isCustomCanIdMessage(name)) { + const def = + window.GrcanDocument && window.GrcanDocument.getCustomCanIdDef(name); + if (def && def.canId && !ovrF.input.value.trim()) { + ovrF.input.value = "0x" + def.canId.toUpperCase(); + ovrF.input._autoFilled = true; + } + } else if (ovrF.input._autoFilled) { + ovrF.input.value = ""; + ovrF.input._autoFilled = false; + } + } + + msgF.input.addEventListener("blur", () => + syncOverrideForMessage(msgF.input.value.trim()), + ); + const cancelBtn = fu.makeBtn("Cancel"); cancelBtn.addEventListener("click", () => fu.closeOverlay(overlay)); const saveBtn = fu.makeBtn("Add", "editor-btn-primary"); @@ -403,86 +429,37 @@ } else ovrF.error.textContent = ""; if (!ok) return; - if (editor.routeEntryExists(dev, bus, rec, msg, ovr || null)) { - fu.closeOverlay(overlay, { force: true }); - return; - } - const lines = editor.getLines(); - const devRange = editor.findRoutingDeviceRange(dev); - let createdNode = false; - let createdBus = false; - - if (!devRange) { - createdNode = true; - createdBus = true; - const rStart = editor.findSectionStart(lines, "routing"); - if (rStart === -1) return; - const rEnd = editor.findSectionEnd(lines, rStart); - editor.insertAtLine( - rEnd, - " " + - dev + - ":\n " + - bus + - ":\n " + - rec + - ":\n" + - editor.generateRoutingMsgYaml(msg, ovr || null), - ); - } else { - const busRange = editor.findRoutingBusRange(dev, bus); - if (!busRange) { - createdBus = true; - editor.insertAtLine( - devRange.endLine, - " " + - bus + - ":\n " + - rec + - ":\n" + - editor.generateRoutingMsgYaml(msg, ovr || null), - ); - } else { - let recFound = false; - const freshLines = editor.getLines(); - for (let i = busRange.startLine + 1; i < busRange.endLine; i++) { - if ( - freshLines[i].search(/\S/) === 8 && - freshLines[i].trim() === rec + ":" - ) { - // findBlockEnd locates the end of this receiver block - // (indent ≤ 8), bounded by the parent bus block end. - const recEnd = editor.findBlockEnd( - freshLines, - i, - busRange.endLine, - 8, - ); - editor.insertAtLine( - recEnd, - editor.generateRoutingMsgYaml(msg, ovr || null), - ); - recFound = true; - break; - } - } - if (!recFound) { - editor.insertAtLine( - busRange.endLine, - " " + - rec + - ":\n" + - editor.generateRoutingMsgYaml(msg, ovr || null), - ); - } + // If device is new, validate and create it with a GR ID first. + const isNewDevice = !window.GrcanDocument.deviceExists(dev); + if (isNewDevice) { + const grId = grIdF.input.value.trim(); + if (!grId || !/^0x[0-9a-fA-F]+$/i.test(grId)) { + grIdF.error.textContent = "Required for new device (hex, e.g. 0x2B)"; + return; + } + const addResult = window.GrcanDocument.addDevice(dev, grId); + if (!addResult.ok) { + devF.error.textContent = addResult.error; + return; } } - if (createdNode) editor.markNew("routeNode:" + dev); + const routeResult = window.GrcanDocument.addRoute( + dev, + bus, + rec, + msg, + ovr || null, + ); + if (!routeResult.ok) { + msgF.error.textContent = routeResult.error; + return; + } + + if (isNewDevice) editor.markNew("routeNode:" + dev); else editor.markEdited("routeNode:" + dev); - if (createdBus) editor.markNew("routeBus:" + dev + "|" + bus); - else editor.markEdited("routeBus:" + dev + "|" + bus); + editor.markNew("routeBus:" + dev + "|" + bus); editor.markNew("routeMsg:" + dev + "|" + bus + "|" + msg); fu.closeOverlay(overlay, { force: true }); diff --git a/Web/formRoutingEdit.js b/Web/formRoutingEdit.js new file mode 100644 index 000000000..321e9ebeb --- /dev/null +++ b/Web/formRoutingEdit.js @@ -0,0 +1,362 @@ +// Purpose: "Edit Route" modal form. +// Lets users modify receiver assignments and CAN ID overrides for an existing +// routing entry without having to delete and re-add it manually. +// Device, Bus, and Message are locked (read-only). Only receivers and their +// optional CAN ID overrides are editable. +// Depends on: formUtils.js (FormUtils), editor.js (GrcanEditor), candoDocument.js. +// Registers: window.GrcanEditor.showRoutingEditForm + +(function () { + "use strict"; + + function showRoutingEditForm(deviceName, busPort, msgName, currentReceivers) { + const editor = window.GrcanEditor; + const fu = window.FormUtils; + const { overlay, body, footer } = fu.createModal( + "Edit Route \u2014 " + msgName, + ); + overlay.querySelector(".editor-modal").classList.add("editor-modal-wide"); + + // Compact context subtitle (device · bus) instead of locked row fields. + const subtitle = document.createElement("p"); + subtitle.className = "route-edit-subtitle"; + subtitle.textContent = deviceName + " \u00b7 " + busPort; + body.appendChild(subtitle); + + // Working copy of receiver rows. Mutated by add/remove actions before Save. + let rows = currentReceivers.map((r) => ({ + receiverName: r.receiverName, + canIdOverride: r.canIdOverride || "", + })); + + // Receiver name candidates for autocomplete (shared across all rows). + let receiverList = []; + + function routingSectionBounds(lines) { + const routingStart = lines.findIndex((l) => l.startsWith("routing:")); + if (routingStart === -1) return null; + const routingEnd = lines.findIndex( + (l, i) => i > routingStart + 1 && /^\S/.test(l), + ); + return { + start: routingStart, + end: routingEnd === -1 ? lines.length : routingEnd, + }; + } + + function buildRoutingReceiverSet(rawText) { + const names = new Set(); + const lines = String(rawText || "").split("\n"); + const bounds = routingSectionBounds(lines); + if (!bounds) return names; + let activeBus = false; + for (let i = bounds.start + 1; i < bounds.end; i++) { + const line = lines[i]; + if (!line.trim()) continue; + const indent = line.search(/\S/); + const content = line.trim(); + if (indent === 6) { + activeBus = content === busPort + ":"; + } else if (indent === 4) { + activeBus = false; + } else if (activeBus && indent === 8 && content.endsWith(":")) { + names.add(content.slice(0, -1).trim()); + } + } + return names; + } + + function loadReceiverList() { + const rawText = editor.getRawText ? editor.getRawText() : ""; + const routingNames = buildRoutingReceiverSet(rawText); + const nodes = + window.GrcanApi && window.GrcanApi.parseNodeCatalogFromText + ? window.GrcanApi.parseNodeCatalogFromText(rawText) + : []; + const base = [...new Set([...nodes, ...routingNames])]; + receiverList = [...new Set(base)].sort((a, b) => a.localeCompare(b)); + if (!receiverList.includes("ALL")) receiverList.unshift("ALL"); + } + + // ── Locked header fields ────────────────────────────────────────────────── + + // ── Receiver assignments section ────────────────────────────────────────── + + // Column headers aligned with the receiver rows below. + const colHeaders = document.createElement("div"); + colHeaders.className = "route-edit-col-headers"; + colHeaders.innerHTML = "ReceiverCAN ID Override"; + body.appendChild(colHeaders); + + const rowsContainer = document.createElement("div"); + rowsContainer.className = "route-edit-rows"; + body.appendChild(rowsContainer); + + // Inline error shown below the rows container. + const rowsError = document.createElement("div"); + rowsError.className = "editor-error"; + body.appendChild(rowsError); + + function makeReceiverSuggestBox(inputEl) { + let suggestIndex = -1; + const suggestBox = document.createElement("div"); + suggestBox.className = "editor-suggest hidden"; + + function renderSuggestions(term) { + if (document.activeElement !== inputEl) { + suggestBox.classList.add("hidden"); + return; + } + const q = String(term || "").toLowerCase(); + const matches = receiverList.filter( + (name) => !q || name.toLowerCase().includes(q), + ); + if (!matches.length) { + suggestBox.classList.add("hidden"); + suggestBox.innerHTML = ""; + return; + } + suggestBox.innerHTML = ""; + suggestIndex = 0; + matches.slice(0, 20).forEach((name, idx) => { + const item = document.createElement("div"); + item.className = + "editor-suggest-item" + + (idx === 0 ? " editor-suggest-item-active" : ""); + item.textContent = name; + item.addEventListener("mousedown", (e) => { + e.preventDefault(); + inputEl.value = name; + suggestBox.classList.add("hidden"); + }); + suggestBox.appendChild(item); + }); + suggestBox.classList.remove("hidden"); + } + + inputEl.addEventListener("input", () => renderSuggestions(inputEl.value)); + inputEl.addEventListener("focus", () => renderSuggestions(inputEl.value)); + inputEl.addEventListener("blur", () => { + setTimeout(() => suggestBox.classList.add("hidden"), 150); + }); + inputEl.addEventListener("keydown", (e) => { + const items = suggestBox.querySelectorAll(".editor-suggest-item"); + if (!items.length || suggestBox.classList.contains("hidden")) return; + if (e.key === "ArrowDown") { + e.preventDefault(); + suggestIndex = (suggestIndex + 1) % items.length; + } else if (e.key === "ArrowUp") { + e.preventDefault(); + suggestIndex = (suggestIndex - 1 + items.length) % items.length; + } else if (e.key === "Enter") { + e.preventDefault(); + if (suggestIndex >= 0 && suggestIndex < items.length) { + inputEl.value = items[suggestIndex].textContent || ""; + } + suggestBox.classList.add("hidden"); + return; + } else { + return; + } + items.forEach((el, idx) => + el.classList.toggle( + "editor-suggest-item-active", + idx === suggestIndex, + ), + ); + }); + + return suggestBox; + } + + function renderRows() { + rowsContainer.innerHTML = ""; + rows.forEach((row, idx) => { + const rowEl = document.createElement("div"); + rowEl.className = "route-edit-row"; + + // Receiver input + const recInput = document.createElement("input"); + recInput.type = "text"; + recInput.className = "editor-input route-edit-rec-input"; + recInput.placeholder = "Receiver Name"; + recInput.value = row.receiverName; + recInput.addEventListener("input", () => { + rows[idx].receiverName = recInput.value; + }); + + const recWrap = document.createElement("div"); + recWrap.className = "route-edit-rec-wrap"; + recWrap.appendChild(recInput); + recWrap.appendChild(makeReceiverSuggestBox(recInput)); + + // CAN ID Override input + const ovrInput = document.createElement("input"); + ovrInput.type = "text"; + ovrInput.className = "editor-input route-edit-ovr-input"; + ovrInput.placeholder = "0x... (optional)"; + ovrInput.value = row.canIdOverride; + ovrInput.addEventListener("input", () => { + rows[idx].canIdOverride = ovrInput.value; + }); + + // Per-row error span + const rowErr = document.createElement("span"); + rowErr.className = "route-edit-row-error editor-error"; + + // Remove button + const removeBtn = document.createElement("button"); + removeBtn.type = "button"; + removeBtn.className = "editor-icon-btn route-edit-remove-btn"; + removeBtn.title = "Remove"; + removeBtn.textContent = "\u00d7"; + removeBtn.addEventListener("click", () => { + rows.splice(idx, 1); + renderRows(); + }); + + rowEl.appendChild(recWrap); + rowEl.appendChild(ovrInput); + rowEl.appendChild(rowErr); + rowEl.appendChild(removeBtn); + rowsContainer.appendChild(rowEl); + }); + } + + // Populate suggestions and render initial rows. + loadReceiverList(); + renderRows(); + + // [+ Add Receiver] button + const addRecBtn = fu.makeBtn("+ Add Receiver"); + addRecBtn.className = "editor-btn route-edit-add-btn"; + addRecBtn.addEventListener("click", () => { + rows.push({ receiverName: "", canIdOverride: "" }); + renderRows(); + // Focus the new receiver input + const inputs = rowsContainer.querySelectorAll(".route-edit-rec-input"); + if (inputs.length) inputs[inputs.length - 1].focus(); + }); + body.appendChild(addRecBtn); + + // ── Footer ──────────────────────────────────────────────────────────────── + + const cancelBtn = fu.makeBtn("Cancel"); + cancelBtn.addEventListener("click", () => fu.closeOverlay(overlay)); + const saveBtn = fu.makeBtn("Save", "editor-btn-primary"); + footer.appendChild(cancelBtn); + footer.appendChild(saveBtn); + + saveBtn.addEventListener("click", () => { + rowsError.textContent = ""; + // Clear per-row errors + rowsContainer + .querySelectorAll(".route-edit-row-error") + .forEach((el) => (el.textContent = "")); + + // Validate: at least one non-empty receiver + const filledRows = rows.filter((r) => r.receiverName.trim()); + if (!filledRows.length) { + rowsError.textContent = "At least one receiver is required"; + return; + } + + // Validate: no duplicate receivers + const names = filledRows.map((r) => r.receiverName.trim()); + const dupeSet = new Set(); + let hasDupe = false; + names.forEach((n) => { + if (dupeSet.has(n)) hasDupe = true; + dupeSet.add(n); + }); + if (hasDupe) { + rowsError.textContent = "Duplicate receiver names"; + return; + } + + // Validate: CAN ID overrides are hex if filled + let ovrValid = true; + filledRows.forEach((r, idx) => { + const ovr = r.canIdOverride.trim(); + if (ovr && !/^0x[0-9a-fA-F]+$/.test(ovr)) { + const rowEls = rowsContainer.querySelectorAll(".route-edit-row"); + const errEl = + rowEls[idx] && rowEls[idx].querySelector(".route-edit-row-error"); + if (errEl) + errEl.textContent = "Hex format required (e.g. 0x1806E5F4)"; + ovrValid = false; + } + }); + if (!ovrValid) return; + + // Build diff maps + const originalMap = new Map( + currentReceivers.map((r) => [r.receiverName, r.canIdOverride || null]), + ); + const newMap = new Map( + filledRows.map((r) => [ + r.receiverName.trim(), + r.canIdOverride.trim() || null, + ]), + ); + + let anyChange = false; + + // Removed: in original but not in new + for (const [recName] of originalMap) { + if (!newMap.has(recName)) { + window.GrcanDocument.deleteRouteFromReceiver( + deviceName, + busPort, + recName, + msgName, + ); + anyChange = true; + } + } + + // Added or changed + for (const [recName, ovr] of newMap) { + const origOvr = originalMap.get(recName); + if (origOvr === undefined) { + // New receiver + window.GrcanDocument.addRoute( + deviceName, + busPort, + recName, + msgName, + ovr, + ); + anyChange = true; + } else if (origOvr !== ovr) { + // Same receiver, updated CAN ID override + window.GrcanDocument.deleteRouteFromReceiver( + deviceName, + busPort, + recName, + msgName, + ); + window.GrcanDocument.addRoute( + deviceName, + busPort, + recName, + msgName, + ovr, + ); + anyChange = true; + } + } + + if (anyChange) { + editor.markEdited( + "routeMsg:" + deviceName + "|" + busPort + "|" + msgName, + ); + } + + fu.closeOverlay(overlay, { force: true }); + editor.triggerReRender(); + }); + } + + window.GrcanEditor.showRoutingEditForm = showRoutingEditForm; +})(); diff --git a/Web/formSuperAdd.js b/Web/formSuperAdd.js index b02b73c52..9b9160cdc 100644 --- a/Web/formSuperAdd.js +++ b/Web/formSuperAdd.js @@ -429,25 +429,36 @@ if (!ok) return; let changed = false; + const doc = window.GrcanDocument; - if (createSender && insertGrIdEntry(editor, sender, senderId)) { + if (createSender && !doc.deviceExists(sender)) { + const r = doc.addDevice(sender, senderId); + if (!r.ok) { + senderF.error.textContent = r.error; + return; + } editor.markNew("routeNode:" + sender); changed = true; } if ( createReceiver && receiver !== sender && - insertGrIdEntry(editor, receiver, receiverId) + !doc.deviceExists(receiver) ) { + const r = doc.addDevice(receiver, receiverId); + if (!r.ok) { + receiverF.error.textContent = r.error; + return; + } editor.markNew("routeNode:" + receiver); changed = true; } if (creatingMsg) { - const msgYaml = editor.generateMessageIdYaml({ + const msgDef = { name: msgName, msgId: msgIdF.input.value.trim(), - msgLength: parseInt(msgLenF.input.value.trim(), 10), + msgLength: msgLenF.input.value.trim(), fields: [ { name: fieldNameF.input.value.trim(), @@ -460,35 +471,33 @@ mapEquation: "", }, ], - }); - const lines = editor.getLines(); - const msgStart = editor.findSectionStart(lines, "Message ID"); - if (msgStart !== -1) { - const msgEnd = editor.findSectionEnd(lines, msgStart); - editor.insertAtLine(msgEnd, msgYaml); - editor.markNew("msgDef:" + msgName); - changed = true; + }; + const r = doc.addMessageDef(msgDef); + if (!r.ok) { + msgNameF.error.textContent = r.error; + return; } + editor.markNew("msgDef:" + msgName); + changed = true; } if (routeOn) { - const routeResult = appendRoute( - editor, + const r = doc.addRoute( sender, bus, receiver, msgName, overrideId || null, ); - if (routeResult.changed) { - if (routeResult.createdNode) editor.markNew("routeNode:" + sender); - else editor.markEdited("routeNode:" + sender); - if (routeResult.createdBus) - editor.markNew("routeBus:" + sender + "|" + bus); - else editor.markEdited("routeBus:" + sender + "|" + bus); - editor.markNew("routeMsg:" + sender + "|" + bus + "|" + msgName); - changed = true; + if (!r.ok) { + msgNameF.error.textContent = r.error; + return; } + if (!doc.deviceExists(sender)) editor.markNew("routeNode:" + sender); + else editor.markEdited("routeNode:" + sender); + editor.markNew("routeBus:" + sender + "|" + bus); + editor.markNew("routeMsg:" + sender + "|" + bus + "|" + msgName); + changed = true; } fu.closeOverlay(overlay, { force: true }); diff --git a/Web/graphView.css b/Web/graphView.css new file mode 100644 index 000000000..e7d799413 --- /dev/null +++ b/Web/graphView.css @@ -0,0 +1,256 @@ +/* ==================== Graph View Overlay ==================== */ + +.graph-overlay { + position: fixed; + inset: 0; + z-index: 3000; + background: #07090f; + display: flex; + flex-direction: column; +} + +/* ==================== Toolbar ==================== */ + +.graph-toolbar { + height: 52px; + flex-shrink: 0; + display: flex; + align-items: center; + gap: 12px; + padding: 0 20px; + background: rgba(14, 16, 23, 0.96); + border-bottom: 1px solid #1f2439; +} + +.graph-back-btn { + background: transparent; + border: 1px solid #2c3350; + border-radius: 7px; + color: #94a3b8; + font-size: 0.82rem; + font-family: inherit; + padding: 6px 12px; + cursor: pointer; + transition: + background 0.12s, + border-color 0.12s, + color 0.12s; + white-space: nowrap; +} + +.graph-back-btn:hover { + background: #131729; + border-color: #3d4872; + color: #f1f5f9; +} + +.graph-title { + font-size: 0.9rem; + font-weight: 600; + color: #e2e8f0; + white-space: nowrap; +} + +/* ==================== Bus Tabs ==================== */ + +.graph-bus-tabs { + display: flex; + gap: 4px; + margin: 0 auto; +} + +.graph-bus-tab { + background: transparent; + border: 1px solid #2c3350; + border-radius: 7px; + color: #67728b; + font-size: 0.8rem; + font-family: inherit; + font-weight: 500; + padding: 5px 14px; + cursor: pointer; + transition: + background 0.12s, + border-color 0.12s, + color 0.12s; +} + +.graph-bus-tab:hover { + background: #131729; + border-color: #3d4872; + color: #b8c3d8; +} + +.graph-bus-tab.active { + background: rgba(14, 165, 233, 0.14); + border-color: #0ea5e9; + color: #7dd3fc; +} + +/* ==================== Focus Pill ==================== */ + +.graph-focus-pill { + display: flex; + align-items: center; + gap: 6px; + background: rgba(14, 165, 233, 0.15); + border: 1px solid #0ea5e9; + border-radius: 20px; + padding: 4px 10px 4px 14px; + font-size: 0.78rem; + color: #7dd3fc; + white-space: nowrap; +} + +.graph-pill-label { + font-weight: 600; +} + +.graph-pill-close { + background: transparent; + border: none; + color: #7dd3fc; + font-size: 1rem; + line-height: 1; + cursor: pointer; + padding: 0 2px; + opacity: 0.7; + font-family: inherit; + transition: opacity 0.1s; +} + +.graph-pill-close:hover { + opacity: 1; +} + +/* ==================== Fit Button ==================== */ + +.graph-fit-btn { + background: transparent; + border: 1px solid #2c3350; + border-radius: 7px; + color: #67728b; + font-size: 0.8rem; + font-family: inherit; + padding: 5px 12px; + cursor: pointer; + transition: + background 0.12s, + border-color 0.12s, + color 0.12s; +} + +.graph-fit-btn:hover { + background: #131729; + border-color: #3d4872; + color: #b8c3d8; +} + +/* ==================== Canvas Area ==================== */ + +.graph-canvas-area { + flex: 1; + position: relative; + overflow: hidden; +} + +#graph-cy-container { + width: 100%; + height: 100%; +} + +/* ==================== Node Detail Panel ==================== */ + +.graph-node-panel { + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 280px; + background: rgba(11, 13, 20, 0.97); + border-left: 1px solid #1f2439; + overflow-y: auto; + padding: 20px 18px; + transform: translateX(100%); + transition: transform 0.18s ease-out; + display: flex; + flex-direction: column; + gap: 0; +} + +.graph-node-panel.open { + transform: translateX(0); +} + +.graph-panel-title { + font-size: 1rem; + font-weight: 700; + color: #e2e8f0; + margin: 0 0 4px 0; +} + +.graph-panel-grid { + font-size: 0.78rem; + color: #67728b; + margin-bottom: 16px; +} + +.graph-panel-divider { + height: 1px; + background: #1f2439; + margin: 12px 0; +} + +.graph-panel-section-label { + font-size: 0.7rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + color: #4b5568; + margin-bottom: 8px; +} + +.graph-panel-peer { + display: flex; + align-items: center; + gap: 6px; + font-size: 0.82rem; + font-weight: 600; + color: #7dd3fc; + cursor: pointer; + padding: 4px 0; + border-radius: 4px; + transition: color 0.1s; + background: transparent; + border: none; + font-family: inherit; + text-align: left; + width: 100%; +} + +.graph-panel-peer:hover { + color: #bae6fd; +} + +.graph-panel-peer-arrow { + font-size: 0.75rem; + color: #4b5568; + flex-shrink: 0; +} + +.graph-panel-msgs { + padding-left: 18px; + margin: 2px 0 8px; +} + +.graph-panel-msg { + font-size: 0.75rem; + color: #94a3b8; + padding: 1px 0; +} + +.graph-panel-empty { + font-size: 0.8rem; + color: #4b5568; + font-style: italic; +} diff --git a/Web/graphView.js b/Web/graphView.js new file mode 100644 index 000000000..385a78111 --- /dev/null +++ b/Web/graphView.js @@ -0,0 +1,624 @@ +window.GrcanGraphView = (() => { + // ==================== Constants ==================== + + const COLOR_PALETTE = [ + "#7c3aed", + "#0ea5e9", + "#10b981", + "#f59e0b", + "#ef4444", + "#ec4899", + "#14b8a6", + "#f97316", + ]; + + const BUS_LABELS = { CAN1: "Primary", CAN2: "Data", CAN3: "Charger" }; + + // ==================== State ==================== + + let cy = null; + let currentBus = "CAN1"; + let overlayEl = null; + let nodePanelEl = null; + let focusPillEl = null; + let _escHandler = null; + let _focusedNodeId = null; // null = full graph view + let _savedPositions = null; // node positions before entering focus + let _currentGraphData = null; + + // ==================== Color Assignment ==================== + + function _assignColors(nodes) { + const sorted = nodes.map((n) => n.id).sort(); + const map = new Map(); + sorted.forEach((id, i) => + map.set(id, COLOR_PALETTE[i % COLOR_PALETTE.length]), + ); + return map; + } + + // ==================== Layout ==================== + + function _overviewLayout(nodeCount) { + if (nodeCount <= 6) { + return { + name: "cose", + animate: true, + animationDuration: 300, + nodeRepulsion: 8000, + edgeElasticity: 80, + gravity: 0.4, + numIter: 800, + fit: true, + padding: 48, + }; + } + return { + name: "concentric", + concentric: (node) => node.degree(), + levelWidth: () => 2, + minNodeSpacing: 80, + fit: true, + padding: 64, + animate: true, + animationDuration: 400, + }; + } + + function _spokeLayout(centerId) { + return { + name: "concentric", + concentric: (node) => (node.id() === centerId ? 100 : 1), + levelWidth: () => 1, + minNodeSpacing: 48, + fit: true, + padding: 80, + animate: true, + animationDuration: 280, + }; + } + + // ==================== Ghosting (sends/receives distinction) ==================== + + function _applyGhosting(nodeId) { + cy.elements().removeClass("highlighted faded sends-edge receives-edge"); + const node = cy.getElementById(nodeId); + node.addClass("highlighted"); + node.outgoers("edge").addClass("sends-edge"); + node.outgoers("edge").targets().addClass("highlighted"); + node.incomers("edge").addClass("receives-edge"); + node.incomers("edge").sources().addClass("highlighted"); + cy.elements(":visible") + .not(".highlighted, .sends-edge, .receives-edge") + .addClass("faded"); + } + + function _clearGhosting() { + cy.elements().removeClass("highlighted faded sends-edge receives-edge"); + } + + // ==================== Focus Mode ==================== + + function _enterFocus(nodeId) { + _focusedNodeId = nodeId; + + // Save every node's current position for restore + _savedPositions = {}; + cy.nodes().forEach((n) => { + _savedPositions[n.id()] = { x: n.position("x"), y: n.position("y") }; + }); + + const focusNode = cy.getElementById(nodeId); + const neighborhood = focusNode.closedNeighborhood(); // node + neighbours + edges + + // Hide everything outside the neighbourhood + cy.elements().not(neighborhood).style("display", "none"); + + // Layout just the visible neighbourhood as a spoke + cy.layout(_spokeLayout(nodeId)).run(); + + // Apply sends/receives ghosting within the spoke + _applyGhosting(nodeId); + + // Show focus pill + _showFocusPill(nodeId); + } + + function _exitFocus() { + _focusedNodeId = null; + + // Restore all elements + cy.elements().style("display", "element"); + _clearGhosting(); + + // Restore saved positions then fit + if (_savedPositions) { + cy.batch(() => { + cy.nodes().forEach((n) => { + const pos = _savedPositions[n.id()]; + if (pos) n.position(pos); + }); + }); + _savedPositions = null; + } + cy.fit(64); + + _hideFocusPill(); + _hideNodePanel(); + } + + // ==================== Focus Pill ==================== + + function _showFocusPill(nodeId) { + focusPillEl.querySelector(".graph-pill-label").textContent = + `Focus: ${nodeId}`; + focusPillEl.style.display = "flex"; + } + + function _hideFocusPill() { + focusPillEl.style.display = "none"; + } + + // ==================== DOM Construction ==================== + + function _buildOverlay() { + const overlay = document.createElement("div"); + overlay.className = "graph-overlay"; + + // Toolbar + const toolbar = document.createElement("div"); + toolbar.className = "graph-toolbar"; + + const backBtn = document.createElement("button"); + backBtn.className = "graph-back-btn"; + backBtn.textContent = "← Back"; + + const title = document.createElement("span"); + title.className = "graph-title"; + title.textContent = "CAN Graph"; + + const tabs = document.createElement("div"); + tabs.className = "graph-bus-tabs"; + ["CAN1", "CAN2", "CAN3"].forEach((bus) => { + const btn = document.createElement("button"); + btn.className = "graph-bus-tab"; + btn.dataset.bus = bus; + btn.textContent = BUS_LABELS[bus]; + tabs.appendChild(btn); + }); + + // Focus pill (hidden until a node is selected) + const pill = document.createElement("div"); + pill.className = "graph-focus-pill"; + pill.style.display = "none"; + + const pillLabel = document.createElement("span"); + pillLabel.className = "graph-pill-label"; + + const pillClose = document.createElement("button"); + pillClose.className = "graph-pill-close"; + pillClose.textContent = "×"; + pillClose.setAttribute("aria-label", "Exit focus"); + + pill.appendChild(pillLabel); + pill.appendChild(pillClose); + + const fitBtn = document.createElement("button"); + fitBtn.className = "graph-fit-btn"; + fitBtn.textContent = "Fit"; + + toolbar.appendChild(backBtn); + toolbar.appendChild(title); + toolbar.appendChild(tabs); + toolbar.appendChild(pill); + toolbar.appendChild(fitBtn); + + // Canvas area + const canvasArea = document.createElement("div"); + canvasArea.className = "graph-canvas-area"; + + const cyContainer = document.createElement("div"); + cyContainer.id = "graph-cy-container"; + + // Node detail panel + const nodePanel = document.createElement("div"); + nodePanel.className = "graph-node-panel"; + + canvasArea.appendChild(cyContainer); + canvasArea.appendChild(nodePanel); + + overlay.appendChild(toolbar); + overlay.appendChild(canvasArea); + + return overlay; + } + + // ==================== Cytoscape Init ==================== + + function _initCytoscape(containerEl) { + cy = cytoscape({ + container: containerEl, + elements: [], + style: [ + // ── Default node ────────────────────────────────────────────── + { + selector: "node", + style: { + "background-color": "#13172a", + "border-width": 1.5, + "border-color": "#2c3350", + label: "data(labelFull)", + color: "#e2e8f0", + "font-size": "12px", + "font-family": "monospace", + "text-valign": "center", + "text-halign": "center", + "text-wrap": "wrap", + "text-max-width": "120px", + width: "label", + height: "label", + padding: "14px", + shape: "round-rectangle", + "min-zoomed-font-size": 7, + }, + }, + // Hub nodes — slightly larger + { + selector: "node[degree > 4]", + style: { + padding: "20px", + "border-width": 2, + "background-color": "#181d30", + }, + }, + // Highlighted node (selected or neighbour) + { + selector: "node.highlighted", + style: { + "border-color": "#0ea5e9", + "border-width": 3, + opacity: 1, + }, + }, + // Faded node + { selector: "node.faded", style: { opacity: 0.2 } }, + + // ── Default edge — very transparent overview hint ───────────── + // NOTE: Cytoscape ignores alpha in line-color strings. + // Transparency must be set via the `opacity` property. + { + selector: "edge", + style: { + "curve-style": "bezier", + "target-arrow-shape": "triangle", + "arrow-scale": 1.0, + "line-color": "#7090b0", + "target-arrow-color": "#7090b0", + opacity: 0.06, // ← actual transparency control + width: "data(width)", + "min-zoomed-font-size": 7, + }, + }, + // SENDS edge: selected → receiver (sender color, solid, labeled) + { + selector: "edge.sends-edge", + style: { + "line-color": "data(color)", + "target-arrow-color": "data(color)", + "line-style": "solid", + width: "data(highlightWidth)", + label: "data(countLabel)", + "font-size": "10px", + color: "#e2e8f0", + "text-background-color": "#07090f", + "text-background-opacity": 0.92, + "text-background-padding": "3px", + "text-background-shape": "round-rectangle", + "text-rotation": "autorotate", + opacity: 1, + }, + }, + // RECEIVES edge: sender → selected (gray dashed, labeled) + { + selector: "edge.receives-edge", + style: { + "line-color": "#475569", + "target-arrow-color": "#475569", + "line-style": "dashed", + "line-dash-pattern": [6, 3], + width: "data(highlightWidth)", + label: "data(countLabel)", + "font-size": "10px", + color: "#94a3b8", + "text-background-color": "#07090f", + "text-background-opacity": 0.92, + "text-background-padding": "3px", + "text-background-shape": "round-rectangle", + "text-rotation": "autorotate", + opacity: 0.85, + }, + }, + // Faded edge — nearly invisible + { + selector: "edge.faded", + style: { opacity: 0.02 }, + }, + ], + userZoomingEnabled: true, + userPanningEnabled: true, + boxSelectionEnabled: false, + minZoom: 0.1, + maxZoom: 4, + }); + } + + // ==================== Bus Loading ==================== + + function _loadBus(busPort) { + currentBus = busPort; + _focusedNodeId = null; + _savedPositions = null; + + overlayEl.querySelectorAll(".graph-bus-tab").forEach((btn) => { + btn.classList.toggle("active", btn.dataset.bus === busPort); + }); + overlayEl.querySelector(".graph-title").textContent = + `CAN Graph — ${BUS_LABELS[busPort]}`; + + _hideFocusPill(); + _hideNodePanel(); + + const doc = window.GrcanDocument; + if (!doc) return; + + const { nodes, edges } = doc.getGraphDataForBus(busPort); + _currentGraphData = { nodes, edges }; + + const colorMap = _assignColors(nodes); + + // Degree map for node sizing + const degreeMap = new Map(); + edges.forEach((e) => { + degreeMap.set(e.source, (degreeMap.get(e.source) || 0) + 1); + degreeMap.set(e.target, (degreeMap.get(e.target) || 0) + 1); + }); + + const cyNodes = nodes.map((n) => ({ + data: { + id: n.id, + label: n.id, + labelFull: n.grId ? `${n.id}\n${n.grId}` : n.id, + grId: n.grId, + degree: degreeMap.get(n.id) || 0, + }, + })); + + const cyEdges = edges.map((e) => { + const w = Math.min(1.2 + e.count * 0.4, 4); + return { + data: { + id: e.id, + source: e.source, + target: e.target, + messages: e.messages, + count: e.count, + countLabel: e.count === 1 ? e.messages[0] : `${e.count} msgs`, + color: colorMap.get(e.source) || "#94a3b8", + width: w, + highlightWidth: Math.min(w + 1.2, 5), + }, + }; + }); + + cy.elements().remove(); + if (cyNodes.length === 0) return; + + cy.add([...cyNodes, ...cyEdges]); + cy.layout(_overviewLayout(cyNodes.length)).run(); + + _wireEvents(); + } + + function _wireEvents() { + cy.removeAllListeners(); + + cy.on("tap", "node", (evt) => { + const nodeId = evt.target.data("id"); + if (_focusedNodeId === nodeId) { + _exitFocus(); + } else { + _exitFocus(); // clean up any prior focus first + _enterFocus(nodeId); + _showNodePanel(nodeId); + } + }); + + cy.on("tap", "edge", (evt) => { + // Tapping an edge focuses the source node + const sourceId = evt.target.data("source"); + if (_focusedNodeId === sourceId) { + _exitFocus(); + } else { + _exitFocus(); + _enterFocus(sourceId); + _showNodePanel(sourceId); + } + }); + + cy.on("tap", (evt) => { + if (evt.target === cy) { + _exitFocus(); + } + }); + } + + // ==================== Node Panel ==================== + + function _showNodePanel(nodeId) { + if (!_currentGraphData) return; + const { nodes, edges } = _currentGraphData; + const nodeData = nodes.find((n) => n.id === nodeId); + if (!nodeData) return; + + nodePanelEl.innerHTML = ""; + + const title = document.createElement("div"); + title.className = "graph-panel-title"; + title.textContent = nodeData.id; + nodePanelEl.appendChild(title); + + if (nodeData.grId) { + const grIdEl = document.createElement("div"); + grIdEl.className = "graph-panel-grid"; + grIdEl.textContent = `GR ID: ${nodeData.grId}`; + nodePanelEl.appendChild(grIdEl); + } + + _appendPeerSection( + nodePanelEl, + "Sends", + edges.filter((e) => e.source === nodeId), + (e) => e.target, + "→", + ); + _appendPeerSection( + nodePanelEl, + "Receives", + edges.filter((e) => e.target === nodeId), + (e) => e.source, + "←", + ); + + nodePanelEl.classList.add("open"); + } + + function _appendPeerSection( + container, + label, + peerEdges, + getPeerId, + arrowChar, + ) { + const divider = document.createElement("div"); + divider.className = "graph-panel-divider"; + container.appendChild(divider); + + const sectionLabel = document.createElement("div"); + sectionLabel.className = "graph-panel-section-label"; + sectionLabel.textContent = label; + container.appendChild(sectionLabel); + + if (peerEdges.length === 0) { + const empty = document.createElement("div"); + empty.className = "graph-panel-empty"; + empty.textContent = + label === "Sends" ? "No outgoing messages" : "No incoming messages"; + container.appendChild(empty); + return; + } + + peerEdges.forEach((edge) => { + const peerId = getPeerId(edge); + + const peer = document.createElement("button"); + peer.className = "graph-panel-peer"; + + const arrow = document.createElement("span"); + arrow.className = "graph-panel-peer-arrow"; + arrow.textContent = arrowChar; + + const peerLabel = document.createElement("span"); + peerLabel.textContent = peerId; + + peer.appendChild(arrow); + peer.appendChild(peerLabel); + peer.addEventListener("click", () => { + _exitFocus(); + _enterFocus(peerId); + _showNodePanel(peerId); + }); + container.appendChild(peer); + + const msgList = document.createElement("div"); + msgList.className = "graph-panel-msgs"; + edge.messages.forEach((m) => { + const item = document.createElement("div"); + item.className = "graph-panel-msg"; + item.textContent = `• ${m}`; + msgList.appendChild(item); + }); + container.appendChild(msgList); + }); + } + + function _hideNodePanel() { + nodePanelEl.classList.remove("open"); + } + + // ==================== Open / Close ==================== + + function open() { + if (overlayEl) return; + + overlayEl = _buildOverlay(); + document.body.appendChild(overlayEl); + + nodePanelEl = overlayEl.querySelector(".graph-node-panel"); + focusPillEl = overlayEl.querySelector(".graph-focus-pill"); + const cyContainer = overlayEl.querySelector("#graph-cy-container"); + + _initCytoscape(cyContainer); + + overlayEl.querySelectorAll(".graph-bus-tab").forEach((btn) => { + btn.addEventListener("click", () => _loadBus(btn.dataset.bus)); + }); + + overlayEl + .querySelector(".graph-fit-btn") + .addEventListener("click", () => cy.fit(64)); + overlayEl + .querySelector(".graph-back-btn") + .addEventListener("click", _close); + overlayEl + .querySelector(".graph-pill-close") + .addEventListener("click", () => { + _exitFocus(); + }); + + _escHandler = (e) => { + if (e.key === "Escape") { + if (_focusedNodeId) _exitFocus(); + else _close(); + } + }; + document.addEventListener("keydown", _escHandler); + + _loadBus("CAN1"); + } + + function _close() { + if (!overlayEl) return; + if (cy) { + cy.destroy(); + cy = null; + } + overlayEl.remove(); + overlayEl = null; + nodePanelEl = null; + focusPillEl = null; + _focusedNodeId = null; + _savedPositions = null; + _currentGraphData = null; + if (_escHandler) { + document.removeEventListener("keydown", _escHandler); + _escHandler = null; + } + } + + // ==================== Init ==================== + + const graphBtn = document.getElementById("graph-view-btn"); + if (graphBtn) graphBtn.addEventListener("click", open); + + return { open }; +})(); diff --git a/Web/index.css b/Web/index.css index c71d51b40..73c3665dd 100644 --- a/Web/index.css +++ b/Web/index.css @@ -8,7 +8,7 @@ body { margin: 0; - padding-top: 44px; + padding-top: 36px; min-height: 100vh; font-family: "Inter", Arial, sans-serif; background: #050608; @@ -42,9 +42,9 @@ body { .app-shell { position: relative; z-index: 1; - width: min(1200px, 94vw); - min-height: min(84vh, 760px); - margin: 28px auto 36px; + width: min(1600px, 96vw); + min-height: 84vh; + margin: 12px auto 16px; display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 16px; diff --git a/Web/index.html b/Web/index.html index 4d1457491..d06054f8b 100644 --- a/Web/index.html +++ b/Web/index.html @@ -5,8 +5,9 @@ GRCAN Viewer - - + + +
Not an official GR tool.
@@ -31,6 +32,28 @@

GRCAN Viewer

+
+ + +
+ @@ -38,9 +61,20 @@

GRCAN Viewer

+ +
+
+ +
Bus
@@ -72,17 +106,22 @@

GRCAN Viewer

diffViewer.js → DiffViewer (standalone diff modal) viewer.js → main controller (rendering + edit-mode wiring) background.js → decorative canvas (no dependencies) --> - + - + + - + + + - + + + diff --git a/Web/logic.js b/Web/logic.js index 55effa4b5..44dfbab63 100644 --- a/Web/logic.js +++ b/Web/logic.js @@ -11,6 +11,18 @@ const GR_NAVY = "#195297"; const GR_GRAY = "#9AA3B0"; const GITHUB_API = "https://api.github.com/repos/Gaucho-Racing/Firmware"; + +// Local-file mode: when set, fetchCando returns this content instead of hitting the API. +let _localCandoText = null; +function setLocalCandoText(text) { + _localCandoText = text; +} +function getLocalCandoText() { + return _localCandoText; +} +function isLocalMode() { + return _localCandoText !== null; +} const CANDO_PATH = "Autogen/CAN/Doc/GRCAN.CANdo"; const BUS_ID_PATH = "Autogen/CAN/Inc/GRCAN_BUS_ID.h"; const NODE_ID_PATH = "Autogen/CAN/Inc/GRCAN_NODE_ID.h"; @@ -278,6 +290,11 @@ function reconcileCatalogNames(preferredNames, canonicalNames) { return resolved; } +function decodeBase64Utf8(b64) { + const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0)); + return new TextDecoder().decode(bytes); +} + async function fetchRepoText(path, ref) { const res = await fetch( `${GITHUB_API}/contents/${path}?ref=${encodeURIComponent(ref)}`, @@ -287,7 +304,10 @@ async function fetchRepoText(path, ref) { if (!res.ok) return { text: null, error: "fetch_failed" }; const data = await res.json(); if (data.encoding !== "base64") return { text: null, error: "encoding" }; - return { text: atob(data.content.replace(/\n/g, "")), error: null }; + return { + text: decodeBase64Utf8(data.content.replace(/\n/g, "")), + error: null, + }; } async function fetchBranches() { @@ -317,6 +337,9 @@ async function fetchTags() { } async function fetchCando(ref) { + if (_localCandoText !== null) { + return { content: _localCandoText, notFound: false }; + } try { const res = await fetch( `${GITHUB_API}/contents/${CANDO_PATH}?ref=${encodeURIComponent(ref)}`, @@ -333,7 +356,7 @@ async function fetchCando(ref) { if (!res.ok) throw new Error("File not found"); const data = await res.json(); if (data.encoding === "base64") { - const decoded = atob(data.content.replace(/\n/g, "")); + const decoded = decodeBase64Utf8(data.content.replace(/\n/g, "")); return { content: decoded, notFound: false }; } else { return { content: "[Unsupported file encoding]", notFound: true }; @@ -356,7 +379,7 @@ async function fetchBus(ref) { if (!res.ok) throw new Error("Unexpected response"); const data = await res.json(); if (data.encoding !== "base64") return { buses: null, error: "encoding" }; - const text = atob(data.content.replace(/\n/g, "")); + const text = decodeBase64Utf8(data.content.replace(/\n/g, "")); const buses = []; const enumBody = text.match(/typedef\s+enum\s*\{([^}]*)\}/s); if (enumBody) { @@ -401,7 +424,7 @@ async function fetchNodeIds(ref) { if (!res.ok) throw new Error("Unexpected response"); const data = await res.json(); if (data.encoding !== "base64") return { nodeIds: null, error: "encoding" }; - const text = atob(data.content.replace(/\n/g, "")); + const text = decodeBase64Utf8(data.content.replace(/\n/g, "")); const nodeIds = []; const enumBody = text.match(/typedef\s+enum\s*\{([^}]*)\}/s); @@ -520,13 +543,18 @@ function parseMessageByBusFromText(text, busName) { if (indent === 4) { const senderName = content.replace(/:$/, ""); if (!nodeMap.has(senderName)) - nodeMap.set(senderName, { name: senderName, messages: [] }); + nodeMap.set(senderName, { + name: senderName, + messages: [], + hasBus: false, + }); currentNode = nodeMap.get(senderName); onTargetPort = false; receiver = null; pendingMsg = null; } else if (indent === 6) { onTargetPort = content.replace(/:$/, "") === targetPort; + if (onTargetPort && currentNode) currentNode.hasBus = true; receiver = null; pendingMsg = null; } else if (onTargetPort && indent === 8) { @@ -566,6 +594,9 @@ function parseMessageByBusFromText(text, busName) { } async function fetchMessageByBus(ref, busName) { + if (_localCandoText !== null) { + return parseMessageByBusFromText(_localCandoText, busName); + } try { const res = await fetch( `${GITHUB_API}/contents/${CANDO_PATH}?ref=${encodeURIComponent(ref)}`, @@ -575,7 +606,7 @@ async function fetchMessageByBus(ref, busName) { if (!res.ok) throw new Error("Unexpected response"); const data = await res.json(); if (data.encoding !== "base64") return { nodes: null, error: "encoding" }; - const text = atob(data.content.replace(/\n/g, "")); + const text = decodeBase64Utf8(data.content.replace(/\n/g, "")); return parseMessageByBusFromText(text, busName); } catch (e) { return { nodes: null, error: "fetch_failed" }; @@ -630,9 +661,13 @@ function busToPort(canonicalBus) { window.GrcanApi = { CAN_PORT_TO_BUS, isValidSha, + decodeBase64Utf8, fetchBranches, fetchTags, fetchCando, + setLocalCandoText, + getLocalCandoText, + isLocalMode, fetchBus, fetchNodeIds, fetchMessageCatalog, diff --git a/Web/viewer.css b/Web/viewer.css index 0278c7394..fe8db5284 100644 --- a/Web/viewer.css +++ b/Web/viewer.css @@ -3,7 +3,7 @@ flex-direction: row; align-items: stretch; width: 100%; - height: min(72vh, 660px); + height: calc(100vh - 160px); min-height: 420px; background: #0a0c12; border: 1px solid #1f2439; @@ -108,9 +108,7 @@ .item-label { flex: 1 1 auto; min-width: 0; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; + word-break: break-word; } .item-chevron { @@ -216,3 +214,122 @@ color: #7f8ca6; font-style: italic; } + +#viewer-search-row { + padding: 0 0 8px; + position: relative; +} + +#viewer-search { + width: 100%; + font-family: inherit; + font-size: 0.82rem; + padding: 8px 12px; + border-radius: 8px; + border: 1px solid #2c3350; + background: #0a0c13; + color: #ecf2ff; + outline: none; + transition: + border-color 0.16s, + box-shadow 0.16s; +} + +#viewer-search:focus { + border-color: #7c3aed; + box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.2); +} + +#viewer-search::placeholder { + color: #667189; +} + +#search-dropdown { + display: none; + position: absolute; + top: calc(100% - 8px); + left: 0; + right: 0; + z-index: 50; + background: #0d1020; + border: 1px solid #2c3350; + border-top: none; + border-radius: 0 0 8px 8px; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); + max-height: 280px; + overflow-y: auto; +} + +.search-result-row { + display: flex; + flex-direction: column; + gap: 2px; + padding: 8px 12px; + cursor: pointer; + border-bottom: 1px solid #1a1f35; + transition: background 0.1s; +} + +.search-result-row:last-child { + border-bottom: none; +} + +.search-result-row:hover { + background: #151d33; +} + +.sr-name { + font-size: 0.84rem; + font-weight: 500; + color: #f0f4ff; +} + +.sr-path { + font-size: 0.72rem; + color: #667189; +} + +@keyframes highlight-fade { + 0% { + background: rgba(139, 92, 246, 0.35); + } + 100% { + background: transparent; + } +} + +.msg-highlight { + animation: highlight-fade 1.8s ease-out forwards; + border-radius: 4px; +} + +/* ── Message expand/collapse toggle ── */ +.msg-expand-btn { + flex-shrink: 0; + color: #8b5cf6; + cursor: pointer; + font-size: 0.82rem; + line-height: 1; + padding: 0 2px; + transform: rotate(90deg); + transition: + transform 0.12s, + color 0.12s; + user-select: none; +} + +.msg-expand-btn.collapsed { + transform: rotate(0deg); + color: #67728b; +} + +.msg-details { + width: 100%; + overflow: hidden; + max-height: 600px; + transition: max-height 0.15s ease-out; +} + +.msg-details.collapsed { + max-height: 0; +} diff --git a/Web/viewer.js b/Web/viewer.js index d9b1f00bc..a093ecdc3 100644 --- a/Web/viewer.js +++ b/Web/viewer.js @@ -17,8 +17,11 @@ window.addEventListener("DOMContentLoaded", function () { const refInputRow = document.getElementById("ref-input-row"); const firstHeader = document.querySelector("#bus-panel .panel-header"); const secondHeader = document.querySelector("#node-panel .panel-header"); + const searchInput = document.getElementById("viewer-search"); let nodeIdMap = new Map(); let currentRef = ""; + let _allNodes = []; // persisted node→bus→messages index for search + let _searchDropdown = null; let currentDeviceName = null; let currentBusCanonical = null; @@ -157,6 +160,144 @@ window.addEventListener("DOMContentLoaded", function () { else item.appendChild(icons); } + function applySearchFilter() { + const term = (searchInput ? searchInput.value : "").trim().toLowerCase(); + [firstList, secondList, msgList].forEach((list) => { + list.querySelectorAll(".panel-item").forEach((item) => { + const text = item.textContent.toLowerCase(); + item.style.display = term && !text.includes(term) ? "none" : ""; + }); + }); + } + + function buildMessageIndex() { + const results = []; + for (const node of _allNodes) { + for (const bus of node.buses) { + for (const msg of bus.messages) { + results.push({ + msgName: msg.msgName, + deviceName: node.name, + canonicalBus: bus.canonicalBus, + busDisplayName: bus.busName, + }); + } + } + } + return results; + } + + function getSearchDropdown() { + if (_searchDropdown) return _searchDropdown; + _searchDropdown = document.createElement("div"); + _searchDropdown.id = "search-dropdown"; + const row = document.getElementById("viewer-search-row"); + if (row) row.appendChild(_searchDropdown); + return _searchDropdown; + } + + function highlightMessage(msgName) { + const items = msgList.querySelectorAll(".msg-item"); + for (const item of items) { + const nameEl = item.querySelector(".msg-name"); + if (nameEl && nameEl.textContent === msgName) { + item.scrollIntoView({ block: "nearest" }); + item.classList.add("msg-highlight"); + setTimeout(() => item.classList.remove("msg-highlight"), 1800); + break; + } + } + } + + function navigateToMessage(result) { + if (_searchDropdown) _searchDropdown.style.display = "none"; + if (searchInput) searchInput.value = ""; + applySearchFilter(); + const nodeEl = firstList.querySelector( + '[data-node-name="' + CSS.escape(result.deviceName) + '"]', + ); + if (!nodeEl) return; + nodeEl.scrollIntoView({ block: "nearest" }); + nodeEl.click(); + requestAnimationFrame(() => { + const busEl = secondList.querySelector( + '[data-bus-canonical="' + CSS.escape(result.canonicalBus) + '"]', + ); + if (!busEl) return; + busEl.scrollIntoView({ block: "nearest" }); + busEl.click(); + requestAnimationFrame(() => highlightMessage(result.msgName)); + }); + } + + function applySearch() { + applySearchFilter(); + const dropdown = getSearchDropdown(); + const term = searchInput ? searchInput.value.trim().toLowerCase() : ""; + if (!term || _allNodes.length === 0) { + dropdown.style.display = "none"; + return; + } + const index = buildMessageIndex(); + const seen = new Set(); + const matches = index.filter((r) => { + if (!r.msgName.toLowerCase().includes(term)) return false; + const key = r.msgName + "|" + r.deviceName + "|" + r.canonicalBus; + if (seen.has(key)) return false; + seen.add(key); + return true; + }); + if (matches.length === 0) { + dropdown.style.display = "none"; + return; + } + dropdown.innerHTML = ""; + matches.slice(0, 12).forEach((result) => { + const row = document.createElement("div"); + row.className = "search-result-row"; + const nameEl = document.createElement("span"); + nameEl.className = "sr-name"; + nameEl.textContent = result.msgName; + const pathEl = document.createElement("span"); + pathEl.className = "sr-path"; + pathEl.textContent = + result.deviceName + " \u203a " + result.busDisplayName; + row.appendChild(nameEl); + row.appendChild(pathEl); + row.addEventListener("mousedown", (e) => { + e.preventDefault(); + navigateToMessage(result); + }); + dropdown.appendChild(row); + }); + dropdown.style.display = "block"; + } + + if (searchInput) { + searchInput.addEventListener("input", applySearch); + searchInput.addEventListener("keydown", (e) => { + if (e.key === "Escape") { + searchInput.value = ""; + applySearch(); + searchInput.blur(); + } else if (e.key === "Enter") { + const dd = _searchDropdown; + if (dd && dd.firstElementChild) { + dd.firstElementChild.dispatchEvent(new MouseEvent("mousedown")); + } + } + }); + document.addEventListener("click", (e) => { + if ( + _searchDropdown && + !_searchDropdown.contains(e.target) && + e.target !== searchInput + ) { + _searchDropdown.style.display = "none"; + } + }); + } + async function loadNodeIds(ref) { const result = await window.GrcanApi.fetchNodeIds(ref); nodeIdMap = new Map(); @@ -269,6 +410,12 @@ window.addEventListener("DOMContentLoaded", function () { editor.showMessageEditForm(null, true); }), ); + msgList.appendChild( + editor.createAddBtn("Add Custom CAN ID", () => { + editor.setNavSnapshot(navSnapshot()); + editor.showCustomCanIdEditForm(null, true); + }), + ); } return; } @@ -291,13 +438,42 @@ window.addEventListener("DOMContentLoaded", function () { name.textContent = msg.msgName; nameRow.appendChild(name); + // Determine preview content: standard byte mappings or Custom CAN ID signals + const hasByteMappings = msg.byteMappings && msg.byteMappings.length > 0; + let customCanIdDef = null; + if ( + !hasByteMappings && + editor && + editor.isCustomCanIdMessage(msg.msgName) + ) { + customCanIdDef = + window.GrcanDocument && + window.GrcanDocument.getCustomCanIdDef(msg.msgName); + } + const hasPreview = + hasByteMappings || + (customCanIdDef && + customCanIdDef.signals && + customCanIdDef.signals.length > 0); + + if (hasPreview) { + const expandBtn = document.createElement("span"); + expandBtn.className = "msg-expand-btn"; + expandBtn.textContent = "›"; + nameRow.appendChild(expandBtn); + } + if (editing) { const icons = document.createElement("span"); icons.className = "editor-icons"; icons.appendChild( editor.createEditBtn(() => { editor.setNavSnapshot(navSnapshot()); - editor.showMessageEditForm(msg.msgName, false); + if (editor.isCustomCanIdMessage(msg.msgName)) { + editor.showCustomCanIdEditForm(msg.msgName, false); + } else { + editor.showMessageEditForm(msg.msgName, false); + } }), ); if (busPort && currentDeviceName) { @@ -305,17 +481,11 @@ window.addEventListener("DOMContentLoaded", function () { editor.createDeleteBtn(() => { editor.setNavSnapshot(navSnapshot()); editor.confirmAndDelete(msg.msgName, () => { - const entries = editor.findRoutingMsgEntries( + window.GrcanDocument.deleteRouteEntry( currentDeviceName, busPort, msg.msgName, ); - for (let i = entries.length - 1; i >= 0; i--) { - editor.deleteLineRange( - entries[i].startLine, - entries[i].endLine, - ); - } editor.markEdited( "routeMsg:" + (currentDeviceName || "") + @@ -357,42 +527,86 @@ window.addEventListener("DOMContentLoaded", function () { item.appendChild(meta); } - if (msg.byteMappings && msg.byteMappings.length > 0) { + if (hasPreview) { + const details = document.createElement("div"); + details.className = "msg-details"; + const bytesWrap = document.createElement("div"); bytesWrap.className = "msg-bytes"; - msg.byteMappings.forEach((mapping) => { - const row = document.createElement("div"); - row.className = "msg-byte-row"; - - const main = document.createElement("span"); - main.className = "msg-byte-main"; - main.textContent = `Byte ${mapping.byteLabel} -> ${mapping.fieldName}`; - row.appendChild(main); - - if (mapping.dataType) { - const typeChip = document.createElement("span"); - typeChip.className = "msg-type-chip"; - typeChip.textContent = mapping.dataType; - row.appendChild(typeChip); - } - - if (mapping.bitLabel) { - const bit = document.createElement("span"); - bit.className = "msg-byte-bits"; - bit.textContent = ` (bits ${mapping.bitLabel})`; - row.appendChild(bit); - } - - if (mapping.comment) { - const c = document.createElement("div"); - c.className = "msg-byte-comment"; - c.textContent = mapping.comment; - row.appendChild(c); - } - - bytesWrap.appendChild(row); - }); - item.appendChild(bytesWrap); + + if (hasByteMappings) { + msg.byteMappings.forEach((mapping) => { + const row = document.createElement("div"); + row.className = "msg-byte-row"; + + const main = document.createElement("span"); + main.className = "msg-byte-main"; + main.textContent = `Byte ${mapping.byteLabel} -> ${mapping.fieldName}`; + row.appendChild(main); + + if (mapping.dataType) { + const typeChip = document.createElement("span"); + typeChip.className = "msg-type-chip"; + typeChip.textContent = mapping.dataType; + row.appendChild(typeChip); + } + + if (mapping.bitLabel) { + const bit = document.createElement("span"); + bit.className = "msg-byte-bits"; + bit.textContent = ` (bits ${mapping.bitLabel})`; + row.appendChild(bit); + } + + if (mapping.comment) { + const c = document.createElement("div"); + c.className = "msg-byte-comment"; + c.textContent = mapping.comment; + row.appendChild(c); + } + + bytesWrap.appendChild(row); + }); + } else if (customCanIdDef) { + customCanIdDef.signals.forEach((signal) => { + const row = document.createElement("div"); + row.className = "msg-byte-row"; + + const main = document.createElement("span"); + main.className = "msg-byte-main"; + main.textContent = `Signal: ${signal.name || "(unnamed)"}`; + row.appendChild(main); + + if (signal.bitStart !== undefined && signal.bitStart !== null) { + const bit = document.createElement("span"); + bit.className = "msg-byte-bits"; + bit.textContent = ` (bits ${signal.bitStart})`; + row.appendChild(bit); + } + + if (signal.comment) { + const c = document.createElement("div"); + c.className = "msg-byte-comment"; + c.textContent = signal.comment; + row.appendChild(c); + } + + bytesWrap.appendChild(row); + }); + } + + details.appendChild(bytesWrap); + item.appendChild(details); + + // Wire expand/collapse toggle + const expandBtn = nameRow.querySelector(".msg-expand-btn"); + if (expandBtn) { + expandBtn.addEventListener("click", (e) => { + e.stopPropagation(); + const collapsed = details.classList.toggle("collapsed"); + expandBtn.classList.toggle("collapsed", collapsed); + }); + } } msgList.appendChild(item); }); @@ -410,7 +624,14 @@ window.addEventListener("DOMContentLoaded", function () { editor.showMessageEditForm(null, true); }), ); + msgList.appendChild( + editor.createAddBtn("Add Custom CAN ID", () => { + editor.setNavSnapshot(navSnapshot()); + editor.showCustomCanIdEditForm(null, true); + }), + ); } + applySearchFilter(); } // ==================== BUS_NODE mode ==================== @@ -460,9 +681,7 @@ window.addEventListener("DOMContentLoaded", function () { editor.confirmAndDelete( node.name + " on " + currentBusCanonical, () => { - const range = editor.findRoutingBusRange(node.name, busPort); - if (range) - editor.deleteLineRange(range.startLine, range.endLine); + window.GrcanDocument.deleteBusBlock(node.name, busPort); editor.markEdited("routeBus:" + node.name + "|" + busPort); }, ); @@ -563,7 +782,7 @@ window.addEventListener("DOMContentLoaded", function () { return; } const nodesOnBus = (nodesResult.nodes || []).filter( - (node) => (node.messages || []).length > 0, + (node) => node.hasBus || (node.messages || []).length > 0, ); renderBusNodeSecondary(nodesOnBus); }); @@ -582,14 +801,14 @@ window.addEventListener("DOMContentLoaded", function () { if (editing) { const hint = document.createElement("div"); hint.className = "placeholder"; - hint.textContent = "Use Add Bus to create this node's first route."; + hint.textContent = "Use Add Bus to create this node's first bus."; secondList.appendChild(hint); } if (editing && deviceName) { secondList.appendChild( editor.createAddBtn("Add Bus", () => { editor.setNavSnapshot(navSnapshot()); - editor.showRoutingAddForm(deviceName, null); + editor.showRoutingBusAddForm(deviceName); }), ); } @@ -629,9 +848,7 @@ window.addEventListener("DOMContentLoaded", function () { editor.confirmAndDelete( deviceName + " > " + entry.busName, () => { - const range = editor.findRoutingBusRange(deviceName, busPort); - if (range) - editor.deleteLineRange(range.startLine, range.endLine); + window.GrcanDocument.deleteBusBlock(deviceName, busPort); editor.markEdited("routeBus:" + deviceName + "|" + busPort); }, ); @@ -656,13 +873,15 @@ window.addEventListener("DOMContentLoaded", function () { secondList.appendChild( editor.createAddBtn("Add Bus", () => { editor.setNavSnapshot(navSnapshot()); - editor.showRoutingAddForm(deviceName, null); + editor.showRoutingBusAddForm(deviceName); }), ); } + applySearchFilter(); } async function renderNodeBus(ref, localText) { + _allNodes = []; const isLocal = !!localText; setPlaceholder(firstList, "Loading nodes..."); setPlaceholder(secondList, "Select a node"); @@ -722,7 +941,8 @@ window.addEventListener("DOMContentLoaded", function () { } if (nodesResult.error || !nodesResult.nodes) continue; for (const node of nodesResult.nodes) { - if (!node.messages || node.messages.length === 0) continue; + if (!node.hasBus && (!node.messages || node.messages.length === 0)) + continue; if (!nodeMap.has(node.name)) nodeMap.set(node.name, []); nodeMap.get(node.name).push({ busName: bus.display, @@ -734,7 +954,15 @@ window.addEventListener("DOMContentLoaded", function () { const nodes = [...nodeMap.entries()] .map(([name, buses]) => ({ name, buses })) - .sort((a, b) => a.name.localeCompare(b.name)); + .sort((a, b) => { + const idA = nodeIdForName(a.name); + const idB = nodeIdForName(b.name); + const numA = idA ? parseInt(idA, 16) : Infinity; + const numB = idB ? parseInt(idB, 16) : Infinity; + if (numA !== numB) return numA - numB; + return a.name.localeCompare(b.name); + }); + _allNodes = nodes; firstList.innerHTML = ""; if (nodes.length === 0) { @@ -771,8 +999,11 @@ window.addEventListener("DOMContentLoaded", function () { editor.createDeleteBtn(() => { editor.setNavSnapshot(navSnapshot()); editor.confirmAndDelete(nodeEntry.name + " (all routes)", () => { - const range = editor.findRoutingDeviceRange(nodeEntry.name); - if (range) editor.deleteLineRange(range.startLine, range.endLine); + const result = window.GrcanDocument.deleteDevice(nodeEntry.name); + if (!result.ok) { + console.error("deleteDevice failed:", result.error); + return; + } editor.markEdited("routeNode:" + nodeEntry.name); }); }), @@ -805,22 +1036,38 @@ window.addEventListener("DOMContentLoaded", function () { }), ); } + applySearchFilter(); } // ==================== Hierarchy entry points ==================== async function renderHierarchy(ref) { - await loadNodeIds(ref); - const candoResult = await window.GrcanApi.fetchCando(ref); + const localText = candoResult.notFound ? null : candoResult.content; + + if (localText) { + loadNodeIdsFromText(localText); + } else { + await loadNodeIds(ref); + } + if (!candoResult.notFound && editor) { editor.setRawText(candoResult.content); + if (window.GrcanDocument) { + const violations = window.GrcanDocument.validate(); + if (violations.length > 0) { + console.warn( + "[GrcanDocument] CANdo validation issues on load:", + violations, + ); + } + } } if (HIERARCHY_MODE === "NODE_BUS") { - await renderNodeBus(ref); + await renderNodeBus(ref, localText); } else { - await renderBusNode(ref); + await renderBusNode(ref, localText); } } @@ -974,5 +1221,47 @@ window.addEventListener("DOMContentLoaded", function () { refSelect.addEventListener("change", onRefInputChange); + // ==================== Local-file toggle ==================== + const localToggle = document.getElementById("local-toggle"); + const localFileInput = document.getElementById("local-file-input"); + + if (localToggle && localFileInput) { + localToggle.addEventListener("change", function () { + if (localToggle.checked) { + localFileInput.style.display = "block"; + localFileInput.click(); + } else { + localFileInput.style.display = "none"; + localFileInput.value = ""; + window.GrcanApi.setLocalCandoText(null); + refSelect.disabled = false; + if (currentRef) renderHierarchy(currentRef); + } + }); + + localFileInput.addEventListener("change", function () { + const file = localFileInput.files[0]; + if (!file) { + localToggle.checked = false; + localFileInput.style.display = "none"; + window.GrcanApi.setLocalCandoText(null); + refSelect.disabled = false; + return; + } + const reader = new FileReader(); + reader.onload = function (e) { + window.GrcanApi.setLocalCandoText(e.target.result); + refSelect.disabled = true; + renderHierarchy(currentRef || "local"); + }; + reader.readAsText(file); + }); + + localFileInput.addEventListener("cancel", function () { + localToggle.checked = false; + localFileInput.style.display = "none"; + }); + } + init(); }); diff --git a/leftovers.txt b/leftovers.txt new file mode 100644 index 000000000..c35d18060 --- /dev/null +++ b/leftovers.txt @@ -0,0 +1,225 @@ +================================================================================ +GRCANDO_editor_refinement — Work Summary & Leftovers +Branch: GRCANDO_editor_refinement +Date: 2026-03-30 +================================================================================ + +-------------------------------------------------------------------------------- +COMPLETED WORK +-------------------------------------------------------------------------------- + +1. GRAPH VIEW FIX (cytoscape CDN → vendored) + File: Web/index.html, Web/cytoscape.min.js (new, 373 KB) + Problem: htmlpreview.github.io rewrites all