diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 65a8f2d78d..716a908f42 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -1282,14 +1282,6 @@ icon_state = "dark" }, /area/holodeck/rec_center/chapelcourt) -"dy" = ( -/obj/structure/table/wood/fancy, -/obj/item/book/manual/splurt_space_law, -/turf/open/floor/holofloor{ - dir = 8; - icon_state = "dark" - }, -/area/holodeck/rec_center/chapelcourt) "dz" = ( /obj/structure/closet{ name = "Evidence Closet" @@ -3979,22 +3971,6 @@ }, /turf/open/floor/plasteel/dark, /area/centcom/control) -"kc" = ( -/obj/item/book/manual/splurt_space_law, -/obj/item/taperecorder, -/obj/structure/table/wood, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/centcom/control) "kd" = ( /obj/item/wrench, /obj/item/restraints/handcuffs, @@ -5312,21 +5288,6 @@ }, /turf/open/floor/plasteel, /area/centcom/control) -"mU" = ( -/obj/item/book/manual/splurt_space_law, -/obj/structure/table/wood, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/centcom/control) "mV" = ( /obj/machinery/vending/cola, /obj/effect/turf_decal/tile/neutral{ @@ -7079,28 +7040,6 @@ /obj/effect/light_emitter, /turf/open/floor/plating/asteroid/snow/airless, /area/syndicate_mothership) -"qb" = ( -/obj/structure/table/wood, -/obj/item/folder/red, -/obj/item/book/manual/splurt_space_law, -/obj/item/restraints/handcuffs, -/obj/item/assembly/flash/handheld, -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/centcom/ferry) "qc" = ( /obj/structure/table/wood, /obj/item/folder/red, @@ -7453,6 +7392,13 @@ }, /turf/open/floor/plasteel, /area/slavers) +"qM" = ( +/obj/effect/turf_decal/stripes/corner, +/obj/machinery/computer/cryopod{ + pixel_x = 32 + }, +/turf/open/floor/plasteel, +/area/slavers) "qP" = ( /obj/structure/bed/matress, /turf/open/floor/plating, @@ -7567,22 +7513,6 @@ /obj/item/pen/fountain, /turf/open/indestructible/hotelwood, /area/centcom/holding) -"rk" = ( -/obj/structure/table/reinforced, -/obj/item/book/manual/splurt_space_law, -/obj/item/taperecorder, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/centcom/ferry) "rl" = ( /obj/machinery/computer/auxillary_base{ pixel_y = 32 @@ -10812,6 +10742,12 @@ }, /turf/open/floor/plasteel, /area/centcom/control) +"yk" = ( +/obj/structure/table/reinforced, +/obj/item/book/manual/splurt_space_law, +/obj/item/taperecorder, +/turf/open/floor/plasteel/grimy, +/area/centcom/ferry) "yn" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/sign/warning/vacuum, @@ -11818,6 +11754,24 @@ }, /turf/open/floor/plasteel, /area/syndicate_mothership) +"AE" = ( +/obj/structure/table/wood, +/obj/item/folder/red, +/obj/item/book/manual/splurt_space_law, +/obj/item/restraints/handcuffs, +/obj/item/assembly/flash/handheld, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/centcom/ferry) "AF" = ( /obj/structure/toilet{ dir = 4 @@ -12091,6 +12045,24 @@ /obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel/dark, /area/slavers) +"Br" = ( +/obj/structure/table/wood, +/obj/item/folder/red, +/obj/item/book/manual/splurt_space_law, +/obj/item/restraints/handcuffs, +/obj/item/assembly/flash/handheld, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/tdome/tdomeadmin) "Bu" = ( /obj/structure/table/wood, /obj/item/paper_bin, @@ -12113,12 +12085,6 @@ }, /turf/open/floor/plasteel/grimy, /area/centcom/ferry) -"Bw" = ( -/obj/structure/table/reinforced, -/obj/item/book/manual/splurt_space_law, -/obj/item/taperecorder, -/turf/open/floor/plasteel/grimy, -/area/centcom/ferry) "Bx" = ( /obj/structure/table/reinforced, /obj/item/storage/fancy/donut_box, @@ -12564,24 +12530,6 @@ /obj/structure/statue/uranium/nuke, /turf/open/floor/plating/asteroid/snow/airless, /area/syndicate_mothership) -"Cq" = ( -/obj/structure/table/wood, -/obj/item/folder/red, -/obj/item/book/manual/splurt_space_law, -/obj/item/restraints/handcuffs, -/obj/item/assembly/flash/handheld, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/centcom/ferry) "Cr" = ( /obj/structure/table/wood, /obj/item/folder/red, @@ -12823,26 +12771,6 @@ }, /turf/open/floor/plasteel, /area/centcom/ferry) -"CH" = ( -/obj/structure/table/reinforced, -/obj/item/book/manual/splurt_space_law, -/obj/item/taperecorder, -/obj/machinery/firealarm{ - dir = 8; - pixel_x = 24 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/centcom/control) "CI" = ( /obj/structure/table, /obj/item/paper_bin, @@ -13327,22 +13255,6 @@ }, /turf/open/floor/plasteel/dark, /area/centcom/evac) -"DA" = ( -/obj/structure/table/reinforced, -/obj/item/book/manual/splurt_space_law, -/obj/item/taperecorder, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/centcom/evac) "DB" = ( /obj/item/storage/box/ids{ pixel_x = 3; @@ -16589,24 +16501,6 @@ }, /turf/open/floor/plasteel/dark, /area/tdome/tdomeadmin) -"Kp" = ( -/obj/structure/table/wood, -/obj/item/folder/red, -/obj/item/book/manual/splurt_space_law, -/obj/item/restraints/handcuffs, -/obj/item/assembly/flash/handheld, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/tdome/tdomeadmin) "Kq" = ( /obj/structure/table/wood, /obj/item/clipboard, @@ -17062,6 +16956,21 @@ }, /turf/open/floor/wood, /area/centcom/holding) +"Lr" = ( +/obj/item/book/manual/splurt_space_law, +/obj/structure/table/wood, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/centcom/control) "Ls" = ( /obj/docking_port/stationary{ dir = 4; @@ -19097,6 +19006,28 @@ }, /turf/open/floor/plasteel/dark, /area/slavers) +"Tb" = ( +/obj/structure/table/wood, +/obj/item/folder/red, +/obj/item/book/manual/splurt_space_law, +/obj/item/restraints/handcuffs, +/obj/item/assembly/flash/handheld, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/centcom/ferry) "Td" = ( /obj/structure/fireplace, /turf/open/floor/carpet/red, @@ -19353,10 +19284,6 @@ }, /turf/open/indestructible/hotelwood, /area/centcom/holding) -"Ud" = ( -/obj/effect/turf_decal/stripes/corner, -/turf/open/floor/plasteel, -/area/slavers) "Ug" = ( /obj/machinery/door/poddoor/shuttledock{ checkdir = 1; @@ -19481,6 +19408,14 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel, /area/slavers) +"UB" = ( +/obj/structure/table/wood/fancy, +/obj/item/book/manual/splurt_space_law, +/turf/open/floor/holofloor{ + dir = 8; + icon_state = "dark" + }, +/area/holodeck/rec_center/chapelcourt) "UC" = ( /obj/machinery/vending/cola, /turf/open/floor/plasteel, @@ -20084,6 +20019,22 @@ }, /turf/open/floor/plasteel, /area/centcom/supplypod) +"WP" = ( +/obj/structure/table/reinforced, +/obj/item/book/manual/splurt_space_law, +/obj/item/taperecorder, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/centcom/ferry) "WQ" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/centcom{ @@ -20108,6 +20059,22 @@ /obj/structure/closet/syndicate/personal, /turf/open/floor/wood, /area/syndicate_mothership) +"WT" = ( +/obj/structure/table/reinforced, +/obj/item/book/manual/splurt_space_law, +/obj/item/taperecorder, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/centcom/evac) "WU" = ( /obj/structure/flora/bush, /obj/structure/sign/warning/securearea{ @@ -20498,6 +20465,26 @@ /obj/item/kitchen/rollingpin, /turf/open/floor/plasteel/cafeteria, /area/slavers) +"YD" = ( +/obj/structure/table/reinforced, +/obj/item/book/manual/splurt_space_law, +/obj/item/taperecorder, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = 24 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/centcom/control) "YF" = ( /obj/machinery/vending/clothing{ extended_inventory = 1 @@ -20543,6 +20530,22 @@ /obj/item/book/manual/hydroponics_pod_people, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"YQ" = ( +/obj/item/book/manual/splurt_space_law, +/obj/item/taperecorder, +/obj/structure/table/wood, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/centcom/control) "YU" = ( /obj/structure/window/reinforced{ dir = 1 @@ -55187,7 +55190,7 @@ aa aa aa oe -rk +WP sq to uj @@ -57259,7 +57262,7 @@ oA uV Bu BZ -Cq +AE mD aa aa @@ -57498,7 +57501,7 @@ of oA oX pH -qb +Tb mD rs sw @@ -58028,7 +58031,7 @@ zb pg Ac AK -Bw +yk pg Ct nT @@ -62945,7 +62948,7 @@ JI JQ Ka JG -Kp +Br IR KG Iv @@ -63170,7 +63173,7 @@ tL io iu io -CH +YD vM Ds DG @@ -68541,7 +68544,7 @@ iH iq iA il -mU +Lr nt nO iC @@ -71104,7 +71107,7 @@ aa aa aa in -kc +YQ kl kE lb @@ -71396,7 +71399,7 @@ BP Cf Cc Dg -DA +WT VO WK WK @@ -81205,7 +81208,7 @@ XS ZD Co Pi -Ud +qM Xn Xn Wg @@ -82543,7 +82546,7 @@ cS cY dh bj -dy +UB dV ep eB diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 3386229fc8..b11d17c49c 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -10,7 +10,6 @@ GLOBAL_LIST_EMPTY(cryopod_computers) //Main cryopod console. - /obj/machinery/computer/cryopod name = "general oversight console" desc = "An interface between crew and the cryogenic storage/teleporter storage oversight systems." @@ -143,7 +142,6 @@ GLOBAL_LIST_EMPTY(cryopod_computers) ///Weakref to our controller var/datum/weakref/control_computer_weakref - COOLDOWN_DECLARE(last_no_computer_message) /obj/machinery/cryopod/Initialize() ..() @@ -151,32 +149,16 @@ GLOBAL_LIST_EMPTY(cryopod_computers) /obj/machinery/cryopod/LateInitialize() update_icon() - find_control_computer() + control_computer_weakref = cryo_find_control_computer(src) // This is not a good situation /obj/machinery/cryopod/Destroy() control_computer_weakref = null return ..() -/obj/machinery/cryopod/proc/find_control_computer(urgent = FALSE) - for(var/cryo_console as anything in GLOB.cryopod_computers) - var/obj/machinery/computer/cryopod/console = cryo_console - if(get_area(console) == get_area(src)) - control_computer_weakref = WEAKREF(console) - break - - // Don't send messages unless we *need* the computer, and less than five minutes have passed since last time we messaged - if(!control_computer_weakref && urgent && COOLDOWN_FINISHED(src, last_no_computer_message)) - COOLDOWN_START(src, last_no_computer_message, 5 MINUTES) - log_admin("\The [src] in [get_area(src)] could not find control computer!") - message_admins("\The [src] in [get_area(src)] could not find control computer!") - last_no_computer_message = world.time - - return control_computer_weakref != null - /obj/machinery/cryopod/close_machine(atom/movable/target) if(!control_computer_weakref) - find_control_computer(TRUE) + control_computer_weakref = cryo_find_control_computer(src, TRUE) if((isnull(target) || isliving(target)) && state_open && !panel_open) ..(target) var/mob/living/mob_occupant = occupant @@ -214,12 +196,11 @@ GLOBAL_LIST_EMPTY(cryopod_computers) if(!mob_occupant.client && COOLDOWN_FINISHED(src, despawn_world_time)) if(!control_computer_weakref) - find_control_computer(urgent = TRUE) + control_computer_weakref = cryo_find_control_computer(src, urgent = TRUE) despawn_occupant() -/obj/machinery/cryopod/proc/handle_objectives() - var/mob/living/mob_occupant = occupant +/proc/cryo_handle_objectives(mob/living/mob_occupant) // Update any existing objectives involving this mob. for(var/datum/objective/objective in GLOB.objectives) // We don't want revs to get objectives that aren't for heads of staff. Letting @@ -276,147 +257,6 @@ GLOBAL_LIST_EMPTY(cryopod_computers) return TRUE return FALSE -// This function can not be undone; do not call this unless you are sure -/obj/machinery/cryopod/proc/despawn_occupant() - var/mob/living/mob_occupant = occupant - var/list/crew_member = list() - - crew_member["name"] = mob_occupant.real_name - - if(mob_occupant.mind) - // Handle job slot/tater cleanup. - var/job = mob_occupant.mind.assigned_role - crew_member["job"] = job - SSjob.FreeRole(job) - // if(LAZYLEN(mob_occupant.mind.objectives)) - // mob_occupant.mind.objectives.Cut() - mob_occupant.mind.special_role = null - else - crew_member["job"] = "N/A" - - // Delete them from datacore. - var/announce_rank = null - for(var/datum/data/record/medical_record as anything in GLOB.data_core.medical) - if(medical_record.fields["name"] == mob_occupant.real_name) - qdel(medical_record) - for(var/datum/data/record/security_record as anything in GLOB.data_core.security) - if(security_record.fields["name"] == mob_occupant.real_name) - qdel(security_record) - for(var/datum/data/record/general_record as anything in GLOB.data_core.general) - if(general_record.fields["name"] == mob_occupant.real_name) - announce_rank = general_record.fields["rank"] - qdel(general_record) - - var/obj/machinery/computer/cryopod/control_computer = control_computer_weakref?.resolve() - if(!control_computer) - control_computer_weakref = null - else - control_computer.frozen_crew += list(crew_member) - - // Make an announcement and log the person entering storage. - if(GLOB.announcement_systems.len) - var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems) - announcer.announce(tele ? "CRYOSTORAGE_TELE" : "CRYOSTORAGE", mob_occupant.real_name, announce_rank, list()) - - visible_message(span_notice("\The [src] hums and hisses as it [tele ? "teleports" : "moves"] [mob_occupant.real_name] [tele ? "to centcom" : "into storage"].")) - if(tele) - do_fake_sparks(2, TRUE, src) // Oh yeah plasmafire time. - playsound(src, 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff_exponent = 5) - - /* ============================= */ - var/list/obj/item/storing = list() - var/list/obj/item/destroying = list() - var/list/obj/item/destroy_later = list() - var/drop_to_ground = !istype(control_computer, /obj/machinery/computer/cryopod) || !control_computer.allow_items - var/mind_identity = mob_occupant.mind?.name - var/occupant_identity = mob_occupant.real_name - - if(iscyborg(mob_occupant)) - var/mob/living/silicon/robot/R = mob_occupant - if(R.mmi?.brain) - destroy_later += R.mmi - destroy_later += R.mmi.brain - for(var/i in R.module) - if(!isitem(i)) - destroying += i - continue - var/obj/item/I = i - // let's be honest we only care about the trash bag don't beat around the bush - if(SEND_SIGNAL(I, COMSIG_CONTAINS_STORAGE)) - storing += I.contents - for(var/atom/movable/AM in I.contents) - AM.forceMove(src) - R.module.remove_module(I, TRUE) - else - if(ishuman(mob_occupant)) - var/mob/living/carbon/human/H = mob_occupant - if(H.mind && H.client && H.client.prefs && H == H.mind.original_character) - H.SaveTCGCards() - - var/list/gear = list() - if(iscarbon(mob_occupant)) // sorry simp-le-mobs deserve no mercy - var/mob/living/carbon/C = mob_occupant - gear = C.get_all_gear() - - for(var/obj/item/item_content as anything in gear) - if(!istype(item_content) || HAS_TRAIT(item_content, TRAIT_NODROP)) - destroying += item_content - continue - if(item_content.item_flags & (DROPDEL | ABSTRACT)) - destroying += item_content - continue - - // destroying stays in mob for a bit - item_content.forceMove(src) - - // WEE WOO SNOWFLAKE TIME - if(istype(item_content, /obj/item/pda)) - var/obj/item/pda/P = item_content - if((P.owner == mind_identity) || (P.owner == occupant_identity)) - destroying += P - else - storing += P - else if(istype(item_content, /obj/item/card/id)) - var/obj/item/card/id/idcard = item_content - if((idcard.registered_name == mind_identity) || (idcard.registered_name == occupant_identity)) - destroying += idcard - else - storing += idcard - else - storing += item_content - - // get rid of mobs - for(var/mob/living/L in mob_occupant.GetAllContents() - mob_occupant) - L.forceMove(drop_location()) - - if(storing.len) - var/obj/item/storage/box/blue/cryostorage_items/O = new /obj/item/storage/box/blue/cryostorage_items - O.name = "[tele ? "early leave" : "cryogenic"] retrieval package: [mob_occupant.real_name]" - O.real_name = mob_occupant.real_name - for(var/i in storing) - var/obj/item/I = i - I.forceMove(O) - O.forceMove(drop_to_ground ? control_computer.drop_location() : control_computer) - if((control_computer == control_computer) && !drop_to_ground) - control_computer.stored_packages += O - /* ============================= */ - - // Ghost and delete the mob. - // they already did ghost verb - var/mob/dead/observer/G = mob_occupant.get_ghost(TRUE) - if(G) - G.voluntary_ghosted = TRUE - // they did not ghost verb - else - mob_occupant.ghostize(FALSE, penalize = TRUE, voluntary = TRUE, cryo = TRUE) - - QDEL_LIST(destroying) - handle_objectives() - QDEL_NULL(occupant) - QDEL_LIST(destroy_later) - open_machine() - name = initial(name) - /obj/machinery/cryopod/MouseDrop_T(mob/living/target, mob/user) if(!istype(target) || !can_interact(user) || !target.Adjacent(user) || !ismob(target) || isanimal(target) || !istype(user.loc, /turf) || target.buckled) return @@ -502,3 +342,165 @@ GLOBAL_LIST_EMPTY(cryopod_computers) /obj/item/storage/box/blue/cryostorage_items w_class = WEIGHT_CLASS_HUGE var/real_name = "fire coderbus" + occupant + +// This function can not be undone; do not call this unless you are sure +/obj/machinery/cryopod/proc/despawn_occupant() + cryoMob(occupant, control_computer_weakref, src, tele, initial(name)) + +/proc/cryoMob(mob/living/mob_occupant, datum/weakref/control_computer_weakref, obj/machinery/cryopod/pod, is_teleporter, initial_name, effects = FALSE) + var/list/crew_member = list() + + // No computer passed in, use admin-cryo instead + if (!control_computer_weakref) + control_computer_weakref = cryo_find_control_computer(urgent = TRUE) + + if (effects) + // Fancy effect for admin-cryo + playsound(get_turf(mob_occupant.loc), 'sound/magic/Repulse.ogg', 100, 1) + var/datum/effect_system/spark_spread/quantum/sparks = new + sparks.set_up(10, 1, mob_occupant) + sparks.attach(mob_occupant.loc) + sparks.start() + + crew_member["name"] = mob_occupant.real_name + + if(mob_occupant.mind) + // Handle job slot/tater cleanup. + var/job = mob_occupant.mind.assigned_role + crew_member["job"] = job + SSjob.FreeRole(job) + // if(LAZYLEN(mob_occupant.mind.objectives)) + // mob_occupant.mind.objectives.Cut() + mob_occupant.mind.special_role = null + else + crew_member["job"] = "N/A" + + // Delete them from datacore. + var/announce_rank = null + for(var/datum/data/record/medical_record as anything in GLOB.data_core.medical) + if(medical_record.fields["name"] == mob_occupant.real_name) + qdel(medical_record) + for(var/datum/data/record/security_record as anything in GLOB.data_core.security) + if(security_record.fields["name"] == mob_occupant.real_name) + qdel(security_record) + for(var/datum/data/record/general_record as anything in GLOB.data_core.general) + if(general_record.fields["name"] == mob_occupant.real_name) + announce_rank = general_record.fields["rank"] + qdel(general_record) + + var/obj/machinery/computer/cryopod/control_computer = control_computer_weakref?.resolve() + if(!control_computer) + control_computer_weakref = null + else + control_computer.frozen_crew += list(crew_member) + + // Make an announcement and log the person entering storage. + if(GLOB.announcement_systems.len) + var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems) + announcer.announce(is_teleporter ? "CRYOSTORAGE_TELE" : "CRYOSTORAGE", mob_occupant.real_name, announce_rank, list()) + + if (pod) + pod.visible_message(span_notice("\The [pod] hums and hisses as it [is_teleporter ? "teleports" : "moves"] [mob_occupant.real_name] [is_teleporter ? "to centcom" : "into storage"].")) + if(is_teleporter) + do_fake_sparks(2, TRUE, pod) // Oh yeah plasmafire time. + playsound(pod, 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff_exponent = 5) + + /* ============================= */ + var/list/obj/item/storing = list() + var/list/obj/item/destroying = list() + var/list/obj/item/destroy_later = list() + var/drop_to_ground = !istype(control_computer, /obj/machinery/computer/cryopod) || !control_computer.allow_items + var/mind_identity = mob_occupant.mind?.name + var/occupant_identity = mob_occupant.real_name + + if(iscyborg(mob_occupant)) + var/mob/living/silicon/robot/R = mob_occupant + if(R.mmi?.brain) + destroy_later += R.mmi + destroy_later += R.mmi.brain + for(var/i in R.module) + if(!isitem(i)) + destroying += i + continue + var/obj/item/I = i + // let's be honest we only care about the trash bag don't beat around the bush + if(SEND_SIGNAL(I, COMSIG_CONTAINS_STORAGE)) + storing += I.contents + for(var/atom/movable/AM in I.contents) + if(pod) + AM.forceMove(pod) + R.module.remove_module(I, TRUE) + else + if(ishuman(mob_occupant)) + var/mob/living/carbon/human/H = mob_occupant + if(H.mind && H.client && H.client.prefs && H == H.mind.original_character) + H.SaveTCGCards() + + var/list/gear = list() + if(iscarbon(mob_occupant)) // sorry simp-le-mobs deserve no mercy + var/mob/living/carbon/C = mob_occupant + gear = C.get_all_gear() + + for(var/obj/item/item_content as anything in gear) + if(!istype(item_content) || HAS_TRAIT(item_content, TRAIT_NODROP)) + destroying += item_content + continue + if(item_content.item_flags & (DROPDEL | ABSTRACT)) + destroying += item_content + continue + + // destroying stays in mob for a bit + if(pod) + item_content.forceMove(pod) + + // WEE WOO SNOWFLAKE TIME + if(istype(item_content, /obj/item/pda)) + var/obj/item/pda/P = item_content + if((P.owner == mind_identity) || (P.owner == occupant_identity)) + destroying += P + else + storing += P + else if(istype(item_content, /obj/item/card/id)) + var/obj/item/card/id/idcard = item_content + if((idcard.registered_name == mind_identity) || (idcard.registered_name == occupant_identity)) + destroying += idcard + else + storing += idcard + else + storing += item_content + + // get rid of mobs + if (pod) + for(var/mob/living/L in mob_occupant.GetAllContents() - mob_occupant) + L.forceMove(pod.drop_location()) + + if(storing.len) + var/obj/item/storage/box/blue/cryostorage_items/O = new /obj/item/storage/box/blue/cryostorage_items + O.name = "[is_teleporter ? "early leave" : "cryogenic"] retrieval package: [mob_occupant.real_name]" + O.real_name = mob_occupant.real_name + for(var/i in storing) + var/obj/item/I = i + I.forceMove(O) + O.forceMove(drop_to_ground ? control_computer.drop_location() : control_computer) + if((control_computer == control_computer) && !drop_to_ground) + control_computer.stored_packages += O + /* ============================= */ + + // Ghost and delete the mob. + // they already did ghost verb + var/mob/dead/observer/G = mob_occupant.get_ghost(TRUE) + if(G) + G.voluntary_ghosted = TRUE + // they did not ghost verb + else + mob_occupant.ghostize(FALSE, penalize = TRUE, voluntary = TRUE, cryo = TRUE) + + QDEL_LIST(destroying) + cryo_handle_objectives() + QDEL_NULL(mob_occupant) + QDEL_LIST(destroy_later) + + if (pod) + pod.open_machine() + pod.name = initial_name diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 30db44338d..8b28141958 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -16,6 +16,11 @@ set name = "Show Player Panel" set desc="Edit player (respawn, ban, heal, etc)" + // Based on client setting, use modern TGUI player panel instead + if(usr.client.prefs.use_new_playerpanel) + usr.client.holder.show_player_panel2(M) + return + if(!check_rights()) return @@ -74,8 +79,6 @@ body += "BP - " body += "PM - " body += "SM - " - if (ishuman(M) && M.mind) - body += "HM - " body += "FLW - " //Default to client logs if available var/source = LOGSRC_MOB diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index b6948eadab..69201d0317 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -46,7 +46,6 @@ GLOBAL_PROTECT(admin_verbs_admin) /client/proc/getserverlogs, /*for accessing server logs*/ /client/proc/getcurrentlogs, /*for accessing server logs for the current round*/ /client/proc/cmd_admin_subtle_message, /*send a message to somebody as a 'voice in their head'*/ - /client/proc/cmd_admin_headset_message, /*send a message to somebody through their headset as CentCom*/ /client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/ /client/proc/cmd_admin_check_contents, /*displays the contents of an instance*/ /client/proc/centcom_podlauncher,/*Open a window to launch a Supplypod and configure it or it's contents*/ @@ -229,8 +228,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( /datum/admins/proc/set_admin_notice, /client/proc/admin_ghost, /client/proc/toggle_view_range, - /client/proc/cmd_admin_subtle_message, - /client/proc/cmd_admin_headset_message, /client/proc/cmd_admin_check_contents, /datum/admins/proc/access_news_network, /client/proc/admin_end_shift, @@ -713,7 +710,8 @@ GLOBAL_PROTECT(admin_verbs_hideable) var/type_length = length_char("/obj/effect/proc_holder/spell") + 2 for(var/A in GLOB.spells) spell_list[copytext_char("[A]", type_length)] = A - var/obj/effect/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in sortList(spell_list) + var/obj/effect/proc_holder/spell/S = tgui_input_list(usr, "Choose a spell to give", "ABRAKADABRA", sortList(spell_list)) //input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in sortList(spell_list) + if(!S) return @@ -734,7 +732,7 @@ GLOBAL_PROTECT(admin_verbs_hideable) set desc = "Remove a spell from the selected mob." if(T?.mind) - var/obj/effect/proc_holder/spell/S = input("Choose the spell to remove", "NO ABRAKADABRA") as null|anything in sortList(T.mind.spell_list) + var/obj/effect/proc_holder/spell/S = tgui_input_list(usr, "Choose the spell to remove", "NO ABRAKADABRA", sortList(T.mind.spell_list)) // input("Choose the spell to remove", "NO ABRAKADABRA") as null|anything in sortList(T.mind.spell_list) if(S) T.mind.RemoveSpell(S) log_admin("[key_name(usr)] removed the spell [S] from [key_name(T)].") diff --git a/code/modules/admin/player_panel2.dm b/code/modules/admin/player_panel2.dm new file mode 100644 index 0000000000..72139127d7 --- /dev/null +++ b/code/modules/admin/player_panel2.dm @@ -0,0 +1,508 @@ +GLOBAL_LIST_INIT(mute_bits, list( + list(name = "IC", bitflag = MUTE_IC), + list(name = "OOC", bitflag = MUTE_OOC), + list(name = "Pray", bitflag = MUTE_PRAY), + list(name = "Ahelp", bitflag = MUTE_ADMINHELP), + list(name = "Deadchat", bitflag = MUTE_DEADCHAT) +)) + +GLOBAL_LIST_INIT(pp_limbs, list( + "Head" = BODY_ZONE_HEAD, + "Left leg" = BODY_ZONE_L_LEG, + "Right leg" = BODY_ZONE_R_LEG, + "Left arm" = BODY_ZONE_L_ARM, + "Right arm" = BODY_ZONE_R_ARM +)) + +/datum/admins/proc/show_player_panel2(mob/M) + if(!M) + to_chat(owner, "You seem to be selecting a mob that doesn't exist anymore.") + return + + // this is stupid, thanks byond + if(istype(src, /client)) + var/client/C = src + src = C.holder + + if(!check_rights()) + to_chat(owner, "Error: you are not an admin!") + return + + if(!M.mob_panel) + M.create_player_panel() + + M.mob_panel.ui_interact(owner.mob) + +/datum/player_panel + var/mob/targetMob + var/client/targetClient + var/list/roleStatus // A list of each role and whether they are banned or not for this player. + var/antagBanReason + var/activeRoleBans + var/mobSize // Because aparently there is no variable that tracks this on the mob?? + +/datum/player_panel/New(mob/target) + . = ..() + targetMob = target + + var/mob/living/L = targetMob + if (istype(L)) + mobSize = L.mob_size + +/datum/player_panel/Destroy(force, ...) + targetMob = null + targetClient = null + roleStatus = null + antagBanReason = null + activeRoleBans = null + mobSize = null + + SStgui.close_uis(src) + return ..() + +/datum/player_panel/ui_interact(mob/user, datum/tgui/ui) + if(!targetMob) + return + + ui = SStgui.try_update_ui(user, src, ui) + if (!ui) + ui = new(user, src, "PlayerPanel2", "[targetMob.name] Player Panel") + ui.open() + +/datum/player_panel/ui_state(mob/user) + return GLOB.admin_state + +/datum/player_panel/ui_data(mob/user) + . = list() + .["mob_name"] = targetMob.real_name + // .["current_permissions"] = user.client?.holder?.rank.rights + .["mob_type"] = targetMob.type + .["admin_mob_type"] = user.client?.mob.type + .["godmode"] = targetMob.status_flags & GODMODE + + var/mob/living/L = targetMob + if (istype(L)) + .["is_frozen"] = L.admin_frozen + .["is_slept"] = L.admin_sleeping + .["mob_scale"] = mobSize + + if(targetMob.client) + targetClient = targetMob.client + .["client_ckey"] = targetClient.ckey + .["client_muted"] = targetClient.prefs.muted + .["client_rank"] = targetClient.holder ? targetClient.holder.rank : "Player" + + if (!roleStatus) + updateJobbanStatus() + .["roles"] = roleStatus + .["antag_ban_reason"] = antagBanReason + .["active_role_ban_count"] = activeRoleBans + + else + targetClient = null + roleStatus = null + antagBanReason = null + .["client_ckey"] = null + +/datum/player_panel/ui_static_data() + . = list() + + .["transformables"] = GLOB.pp_transformables + .["glob_limbs"] = GLOB.pp_limbs + .["glob_mute_bits"] = GLOB.mute_bits + .["current_time"] = time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss") + + .["initial_scale"] = 1 + + if(targetClient) + var/byond_version = "Unknown" + if(targetClient.byond_version) + byond_version = "[targetClient.byond_version].[targetClient.byond_build ? targetClient.byond_build : "xxx"]" + .["data_byond_version"] = byond_version + .["data_player_join_date"] = targetClient.player_join_date + .["data_account_join_date"] = targetClient.account_join_date + .["data_related_cid"] = targetClient.related_accounts_cid + .["data_related_ip"] = targetClient.related_accounts_ip + + .["initial_scale"] = targetClient.prefs.features["body_size"] + + if(CONFIG_GET(flag/use_exp_tracking)) + .["playtimes_enabled"] = TRUE + .["playtime"] = targetMob.client.get_exp_living() + +/datum/player_panel/ui_act(action, params, datum/tgui/ui) + if(..()) + return + + var/client/admin = usr.client + + if (!check_rights(R_ADMIN)) + message_admins("WARNING: NON-ADMIN [ADMIN_LOOKUPFLW(admin)] ACCESSING ADMIN PANEL. WARN Casper#3044.") + to_chat(admin, "Error: you are not an admin!") + return + + switch(action) + if ("edit_rank") + if (!targetMob.client?.ckey) + return + + var/list/context = list() + + context["key"] = targetMob.client.ckey + + if (GLOB.admin_datums[targetMob.client.ckey] || GLOB.deadmins[targetMob.client.ckey]) + context["editrights"] = "rank" + else + context["editrights"] = "add" + + admin.holder.edit_rights_topic(context) + + if ("access_variables") + admin.debug_variables(targetMob) + + if ("access_playtimes") + if (targetMob.client) + admin.holder.cmd_show_exp_panel(targetMob.client) + + if ("private_message") + admin.cmd_admin_pm_context(targetMob) + + if ("subtle_message") + admin.cmd_admin_subtle_headset_message(targetMob) + + if ("set_name") + targetMob.vv_auto_rename(params["name"]) + + if ("heal") + admin.cmd_admin_rejuvenate(targetMob) + + if ("ghost") + if(targetMob.client) + log_admin("[key_name(admin)] ejected [key_name(targetMob)] from their body.") + message_admins("[key_name_admin(admin)] ejected [key_name_admin(targetMob)] from their body.") + to_chat(targetMob, "An admin has ejected you from your body.") + targetMob.ghostize(FALSE) + + if ("offer_control") + offer_control(targetMob) + + if ("take_control") + var/mob/adminMob = admin.mob + + // Disassociates observer mind from the body mind + if(targetMob.client) + targetMob.ghostize(FALSE) + else + for(var/mob/dead/observer/ghost in GLOB.dead_mob_list) + if(targetMob.mind == ghost.mind) + ghost.mind = null + + targetMob.ckey = adminMob.ckey + qdel(adminMob) + + message_admins("[key_name_admin(usr)] took control of [targetMob].") + log_admin("[key_name(usr)] took control of [targetMob].") + addtimer(CALLBACK(targetMob.mob_panel, /datum.proc/ui_interact, targetMob), 0.1 SECONDS) + + if ("smite") + admin.smite(targetMob) + + if ("bring") + admin.Getmob(targetMob) + + if ("orbit") + if(!isobserver(admin.mob)) + admin.admin_ghost() + var/mob/dead/observer/O = admin.mob + O.ManualFollow(targetMob) + + if ("jump_to") + admin.jumptomob(targetMob) + + if ("freeze") + var/mob/living/L = targetMob + if (istype(L)) + L.toggle_admin_freeze(admin) + + if ("sleep") + var/mob/living/L = targetMob + if (istype(L)) + L.toggle_admin_sleep(admin) + + if ("lobby") + if(!isobserver(targetMob)) + to_chat(usr, "You can only send ghost players back to the Lobby.") + return + + if(!targetMob.client) + to_chat(usr, "[targetMob] doesn't seem to have an active client.") + return + + log_admin("[key_name(usr)] has sent [key_name(targetMob)] back to the Lobby.") + message_admins("[key_name(usr)] has sent [key_name(targetMob)] back to the Lobby.") + + var/mob/dead/new_player/NP = new() + NP.ckey = targetMob.ckey + qdel(targetMob) + if(GLOB.preferences_datums[NP.ckey]) + var/datum/preferences/P = GLOB.preferences_datums[NP.ckey] + P.respawn_restrictions_active = FALSE + + if ("select_equipment") + admin.cmd_select_equipment(targetMob) + + if ("strip") + for(var/obj/item/I in targetMob) + targetMob.dropItemToGround(I, TRUE) //The TRUE forces all items to drop, since this is an admin undress. + + if ("cryo") + cryoMob(targetMob, effects = TRUE) + + if ("force_say") + targetMob.say(params["to_say"], forced="admin") + + if ("force_emote") + targetMob.emote("me", EMOTE_VISIBLE, params["to_emote"]) + + if ("prison") + if(isAI(targetMob)) + to_chat(usr, "This cannot be used on instances of type /mob/living/silicon/ai.") + return + + targetMob.forceMove(pick(GLOB.prisonwarp)) + to_chat(targetMob, "You have been sent to Prison!") + + log_admin("[key_name(admin)] has sent [key_name(targetMob)] to Prison!") + message_admins("[key_name_admin(admin)] has sent [key_name_admin(targetMob)] to Prison!") + + if ("kick") + admin.holder.kick(targetMob) + + if ("ban") + admin.holder.newBan(targetMob) + + if ("sticky_ban") + var/list/ban_settings = list() + if(targetMob.client) + ban_settings["ckey"] = targetMob.ckey + admin.holder.stickyban("add", ban_settings) + + if ("notes") + if (targetMob.client) + browse_messages(target_ckey = targetMob.ckey) + + if ("logs") + var/source = LOGSRC_MOB + if (targetMob.client) + source = LOGSRC_CLIENT + + show_individual_logging_panel(targetMob, source) + + if ("job_ban") + if(targetMob.client) + process_banlist(params["selected_role"], params["is_category"], params["want_to_ban"]) + + if ("mute") + if(!targetMob.client) + return + + targetMob.client.prefs.muted = text2num(params["mute_flag"]) + log_admin("[key_name(admin)] set the mute flags for [key_name(targetMob)] to [targetMob.client.prefs.muted].") + + if ("mute_all") + if(!targetMob.client) + return + + for(var/bit in GLOB.mute_bits) + targetMob.client.prefs.muted |= bit["bitflag"] + + log_admin("[key_name(admin)] mass-muted [key_name(targetMob)].") + + if ("unmute_all") + if(!targetMob.client) + return + + for(var/bit in GLOB.mute_bits) + targetMob.client.prefs.muted &= ~bit["bitflag"] + + log_admin("[key_name(admin)] mass-unmuted [key_name(targetMob)].") + + if ("related_accounts") + if(targetMob.client) + var/related_accounts + if (params["related_thing"] == "CID") + related_accounts = targetMob.client.related_accounts_cid + else + related_accounts = targetMob.client.related_accounts_ip + + related_accounts = splittext(related_accounts, ", ") + + var/list/dat = list("Related accounts by [params["related_thing"]]:") + dat += related_accounts + usr << browse(dat.Join("
"), "window=related_[targetMob.client];size=420x300") + + if ("transform") + var/choice = params["newType"] + if (choice == "/mob/living") + choice = tgui_input_list(usr, "What should this mob transform into", "Mob Transform", subtypesof(choice)) + if (!choice) + return + + admin.holder.transformMob(targetMob, admin.mob, choice, params["newTypeName"]) + + if ("toggle_godmode") + admin.cmd_admin_godmode(targetMob) + + if ("spell") + admin.toggle_spell(targetMob) + + if ("martial_art") + admin.teach_martial_art(targetMob) + + if ("quirk") + admin.toggle_quirk(targetMob) + + if ("species") + admin.set_species(targetMob) + + if ("limb") + if(!params["limbs"] || !ishuman(targetMob)) + return + + var/mob/living/carbon/human/H = targetMob + + for(var/limb in params["limbs"]) + if (!limb) + continue + + if (params["delimb_mode"]) + var/obj/item/bodypart/L = H.get_bodypart(limb) + if (!L) + continue + L.dismember(harmless = TRUE) + playsound(H, 'modular_splurt/sound/effects/cartoon_pop.ogg', 70) + else + H.regenerate_limb(limb) + + if ("scale") + var/mob/living/L = targetMob + if(!isnull(params["new_scale"]) && istype(L)) + L.vv_edit_var("resize", params["new_scale"]) + mobSize = params["new_scale"] + + if ("explode") + var/power = text2num(params["power"]) + var/empMode = text2num(params["emp_mode"]) + + + var/turf/T = get_turf(usr) + message_admins("[ADMIN_LOOKUPFLW(usr)] created an admin [empMode ? "EMP" : "explosion"] at [ADMIN_VERBOSEJMP(T)].") + log_admin("[key_name(usr)] created an admin [empMode ? "EMP" : "explosion"] at [usr.loc].") + + if (empMode) + empulse_using_range(usr, power, TRUE) + else + explosion(usr, power / 3, power / 2, power, power, ignorecap = TRUE) + + if ("narrate") + var/list/stylesRaw = params["classes"] + + var/styles = "" + for(var/style in stylesRaw) + styles += "[style]:[stylesRaw[style]];" + + if (params["mode_global"]) + to_chat(world, "[params["message"]]") + log_admin("GlobalNarrate: [key_name(usr)] : [params["message"]]") + message_admins("[key_name_admin(usr)] Sent a global narrate") + else + for(var/mob/M in view(params["range"], usr)) + to_chat(M, "[params["message"]]") + + log_admin("LocalNarrate: [key_name(usr)] at [AREACOORD(usr)]: [params["message"]]") + message_admins(" LocalNarrate: [key_name_admin(usr)] at [ADMIN_VERBOSEJMP(usr)]: [params["message"]]
") + + if ("languages") + var/datum/language_holder/H = targetMob.get_language_holder() + H.open_language_menu(usr) + + if ("ambitions") + var/datum/mind/requesting_mind = targetMob.mind + if(!istype(requesting_mind) || QDELETED(requesting_mind)) + to_chat(usr, "This mind reference is no longer valid. It has probably since been destroyed.") + return + requesting_mind.do_edit_objectives_ambitions() + + if ("traitor_panel") + admin.holder.show_traitor_panel(targetMob) + +// process_banlist: Gets all jobs in a job category +// Input: +// query (string): The name of the role / department you want to jobban. +// is_category (boolean): Is the query a department / role category? e.g. query "Engineering" needs TRUE +// want_to_ban (boolean): Should we ban or should we unban the job we just supplied. +// +// Output:A list of strings with the names of each role the INPUT covers. +/datum/player_panel/proc/process_banlist(query, is_category, want_to_ban) + if(!SSjob) + to_chat(usr, "Jobs subsystem not initialized yet!") + return + + var/mob/M = targetClient.mob + var/list/jobs_to_set = list() // All the roles relating to the clicked button + + if (is_category) + for(var/list/role_category in roleStatus) // For every department / antag category + if (role_category["category_name"] == query) // If this is the selected category + + for(var/list/role in role_category["category_roles"]) + jobs_to_set += role["name"] + break + + else + jobs_to_set += query + + var/list/jobs_to_set_trimmed = list() // The roles from jobs_to_set that aren't already banned / unbanned + for(var/role in jobs_to_set) + + // If we are in ban mode and this role is unbanned OR if we are in unban mode and this role is banned + // (We don't want to ban / unban roles that are already banned / unbanned) + if ((want_to_ban && !jobban_isbanned(M, role)) || (!want_to_ban && jobban_isbanned(M, role))) + jobs_to_set_trimmed += role + + for(var/role in jobs_to_set_trimmed) + + if (jobs_to_set_trimmed.len) // At least one role to get banned / unbanned + if (want_to_ban) + usr.client.holder.Jobban(targetClient.mob, jobs_to_set_trimmed) + else + usr.client.holder.UnJobban(targetClient.mob, jobs_to_set_trimmed) + + updateJobbanStatus() // Update TGUI data to reflect new ban statuses + +// Updates the jobban status of this client's jobban panel. +/datum/player_panel/proc/updateJobbanStatus() + var/list/roles = list() + var/active_role_bans = 0 + + for(var/list/role_category in GLOB.jobban_panel_data) // For every department / antag category + var/list/category_roles = list() + category_roles["category_name"] = role_category["name"] + category_roles["category_color"] = role_category["color"] + category_roles["category_roles"] = list() + + for(var/role in role_category["roles"]) // For every job / antag + var/list/roles_instance = list() + roles_instance["name"] = role + var/reason = jobban_isbanned(targetMob, role) + if(reason) + roles_instance["ban_reason"] = reason + active_role_bans++ + + category_roles["category_roles"] += list(roles_instance) + + roles += list(category_roles) + + roleStatus = roles + antagBanReason = jobban_isbanned(targetMob, ROLE_SYNDICATE) + activeRoleBans = active_role_bans diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 6b7d1bb8cb..6a0778a518 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -933,13 +933,15 @@ dat += "Bloodsucker" else dat += "Bloodsucker" + + dat += "" //So things dont get squished. + //Slave Trader if(jobban_isbanned(M, ROLE_SLAVER) || isbanned_dept) dat += "Slaver" else dat += "Slaver" - //Other Roles (black) dat += "" dat += "" @@ -2025,21 +2027,15 @@ return var/mob/M = locate(href_list["CentComReply"]) - usr.client.admin_headset_message(M, RADIO_CHANNEL_CENTCOM) + usr.client.cmd_admin_subtle_headset_message(M, RADIO_CHANNEL_CENTCOM) else if(href_list["SyndicateReply"]) if(!check_rights(R_ADMIN)) return var/mob/M = locate(href_list["SyndicateReply"]) - usr.client.admin_headset_message(M, RADIO_CHANNEL_SYNDICATE) + usr.client.cmd_admin_subtle_headset_message(M, RADIO_CHANNEL_SYNDICATE) - else if(href_list["HeadsetMessage"]) - if(!check_rights(R_ADMIN)) - return - - var/mob/M = locate(href_list["HeadsetMessage"]) - usr.client.admin_headset_message(M) //ambition start else if(href_list["ObjectiveRequest"]) if(!check_rights(R_ADMIN)) @@ -2100,7 +2096,7 @@ return var/mob/M = locate(href_list["subtlemessage"]) - usr.client.cmd_admin_subtle_message(M) + usr.client.cmd_admin_subtle_headset_message(M) else if(href_list["individuallog"]) if(!check_rights(R_ADMIN)) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index c01c376b87..ec0bcd5bab 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -19,67 +19,12 @@ admin_ticket_log(M, msg) SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Everything") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +// Unless I am dent-skulled, there is no way to do (mob/M in GLOB.mob_list, someothervar) with context-menu buttons, hence the instant proc call. /client/proc/cmd_admin_subtle_message(mob/M in GLOB.mob_list) set category = "Admin.Events" set name = "Subtle Message" - if(!ismob(M)) - return - if(!check_rights(R_ADMIN)) - return - - message_admins("[key_name_admin(src)] has started answering [ADMIN_LOOKUPFLW(M)]'s prayer.") - var/msg = input("Message:", text("Subtle PM to [M.key]")) as text|null - - if (!msg) - message_admins("[key_name_admin(src)] decided not to answer [ADMIN_LOOKUPFLW(M)]'s prayer") - return - if(usr) - if (usr.client) - if(usr.client.holder) - to_chat(M, "You hear a voice in your head... [msg]") - - log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]") - msg = " SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]" - message_admins(msg) - admin_ticket_log(M, msg) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_headset_message(mob/M in GLOB.mob_list) - set category = "Admin.Events" - set name = "Headset Message" - - admin_headset_message(M) - -/client/proc/admin_headset_message(mob/M in GLOB.mob_list, sender = null) - var/mob/living/carbon/human/H = M - - if(!check_rights(R_ADMIN)) - return - - if(!istype(H)) - to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human") - return - if(!istype(H.ears, /obj/item/radio/headset)) - to_chat(usr, "The person you are trying to contact is not wearing a headset.") - return - - if (!sender) - sender = input("Who is the message from?", "Sender") as null|anything in list(RADIO_CHANNEL_CENTCOM,RADIO_CHANNEL_SYNDICATE) - if(!sender) - return - - message_admins("[key_name_admin(src)] has started answering [key_name_admin(H)]'s [sender] request.") - var/input = input("Please enter a message to reply to [key_name(H)] via their headset.","Outgoing message from [sender]", "") as text|null - if(!input) - message_admins("[key_name_admin(src)] decided not to answer [key_name_admin(H)]'s [sender] request.") - return - - log_directed_talk(mob, H, input, LOG_ADMIN, "reply") - message_admins("[key_name_admin(src)] replied to [key_name_admin(H)]'s [sender] message with: \"[input]\"") - to_chat(H, "You hear something crackle in your ears for a moment before a voice speaks. \"Please stand by for a message from [sender == "Syndicate" ? "your benefactor" : "Central Command"]. Message as follows[sender == "Syndicate" ? ", agent." : ":"] [input]. Message ends.\"") - - SSblackbox.record_feedback("tally", "admin_verb", 1, "Headset Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + cmd_admin_subtle_headset_message(M) /client/proc/cmd_admin_mod_antag_rep(client/C in GLOB.clients, var/operation) set category = "Special Verbs" @@ -1336,7 +1281,8 @@ Traitors and the like can also be revived with the previous role mostly intact. if(!check_rights(R_ADMIN) || !check_rights(R_FUN)) return - var/list/punishment_list = list(ADMIN_PUNISHMENT_PIE, + var/list/punishment_list = list( + ADMIN_PUNISHMENT_PIE, ADMIN_PUNISHMENT_CUSTOM_PIE, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_LIGHTNING, @@ -1362,7 +1308,7 @@ Traitors and the like can also be revived with the previous role mostly intact. ADMIN_PUNISHMENT_BOOKIFY, ADMIN_PUNISHMENT_BONK) - var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list + var/punishment = tgui_input_list(usr, "Choose a punishment", "Divine Smiting", punishment_list) if(QDELETED(target) || !punishment) return diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 7b58e31b5a..006ecb6bd4 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -97,6 +97,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/preferred_map = null var/preferred_chaos = null var/be_victim = null + var/use_new_playerpanel = FALSE var/disable_combat_cursor = FALSE var/pda_style = MONO var/pda_color = "#808000" @@ -1037,7 +1038,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Adminhelp Sounds:[(toggles & SOUND_ADMINHELP)?"Enabled":"Disabled"]
" dat += "Announce Login:[(toggles & ANNOUNCE_LOGIN)?"Enabled":"Disabled"]
" dat += "
" - dat += "Combo HUD Lighting:[(toggles & COMBOHUD_LIGHTING)?"Full-bright":"No Change"]
" // sandstorm end - moves admins prefs to the right + dat += "Combo HUD Lighting:[(toggles & COMBOHUD_LIGHTING)?"Full-bright":"No Change"]
" + dat += "Use Modern Player Panel:[use_new_playerpanel ? "Yes" : "No"]
" // sandstorm end - moves admins prefs to the right dat += "

Citadel Preferences

" //Because fuck me if preferences can't be fucking modularized and expected to update in a reasonable timeframe. dat += "Widescreen:[widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]
" @@ -3181,6 +3183,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) toggles ^= ANNOUNCE_LOGIN if("combohud_lighting") toggles ^= COMBOHUD_LIGHTING + if("use_new_playerpanel") + use_new_playerpanel = !use_new_playerpanel if("be_special") var/be_special_type = href_list["be_special_type"] diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index eb644f3150..689bcf09d1 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -445,10 +445,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["no_tetris_storage"] >> no_tetris_storage // Splurt - S["be_victim"] >> be_victim - S["disable_combat_cursor"] >> disable_combat_cursor + S["be_victim"] >> be_victim + S["disable_combat_cursor"] >> disable_combat_cursor + S["use_new_playerpanel"] >> use_new_playerpanel //favorite outfits - S["favorite_outfits"] >> favorite_outfits + S["favorite_outfits"] >> favorite_outfits var/list/parsed_favs = list() for(var/typetext in favorite_outfits) @@ -633,6 +634,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car // Splurt WRITE_FILE(S["be_victim"], be_victim) WRITE_FILE(S["disable_combat_cursor"], disable_combat_cursor) + WRITE_FILE(S["use_new_playerpanel"], use_new_playerpanel) var/mob/living/carbon/human/H = parent.mob if(istype(H)) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index f4b172fce9..cec589dddd 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1037,23 +1037,7 @@ if(href_list[VV_HK_MARTIAL_ART]) if(!check_rights(NONE)) return - var/list/artpaths = subtypesof(/datum/martial_art) - var/list/artnames = list() - for(var/i in artpaths) - var/datum/martial_art/M = i - artnames[initial(M.name)] = M - var/result = input(usr, "Choose the martial art to teach","JUDO CHOP") as null|anything in artnames - if(!usr) - return - if(QDELETED(src)) - to_chat(usr, "Mob doesn't exist anymore") - return - if(result) - var/chosenart = artnames[result] - var/datum/martial_art/MA = new chosenart - MA.teach(src) - log_admin("[key_name(usr)] has taught [MA] to [key_name(src)].") - message_admins("[key_name_admin(usr)] has taught [MA] to [key_name_admin(src)].") + usr.client.teach_martial_art(src) if(href_list[VV_HK_GIVE_TRAUMA]) if(!check_rights(NONE)) return diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index f588967f30..933cee55b2 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -721,26 +721,7 @@ return copy_outfit() if(href_list[VV_HK_MOD_QUIRKS]) - if(!check_rights(R_SPAWN)) - return - - var/list/options = list("Clear"="Clear") - for(var/x in subtypesof(/datum/quirk)) - var/datum/quirk/T = x - var/qname = initial(T.name) - options[has_quirk(T) ? "[qname] (Remove)" : "[qname] (Add)"] = T - - var/result = input(usr, "Choose quirk to add/remove","Quirk Mod") as null|anything in options - if(result) - if(result == "Clear") - for(var/datum/quirk/q in roundstart_quirks) - remove_quirk(q.type) - else - var/T = options[result] - if(has_quirk(T)) - remove_quirk(T) - else - add_quirk(T,TRUE) + usr.client.toggle_quirk(src) if(href_list[VV_HK_MAKE_MONKEY]) if(!check_rights(R_SPAWN)) return diff --git a/html/changelogs/AutoChangeLog-pr-214.yml b/html/changelogs/AutoChangeLog-pr-214.yml new file mode 100644 index 0000000000..85ab2c6c67 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-214.yml @@ -0,0 +1,5 @@ +author: Crowbar764 +delete-after: true +changes: + - rscadd: Shiny new admin panel + - tweak: Switches some admin panels to TGUI diff --git a/html/changelogs/AutoChangeLog-pr-216.yml b/html/changelogs/AutoChangeLog-pr-216.yml new file mode 100644 index 0000000000..4119bc3d0f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-216.yml @@ -0,0 +1,4 @@ +author: Crowbar764 +delete-after: true +changes: + - tweak: Slaver improvements diff --git a/html/font-awesome/css/all.min.css b/html/font-awesome/css/all.min.css index e7cdfffe75..a3fb0572e8 100644 --- a/html/font-awesome/css/all.min.css +++ b/html/font-awesome/css/all.min.css @@ -2,4 +2,4 @@ * Font Awesome Free 5.9.0 by @fontawesome - https://fontawesome.com * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) */ -.fa,.fab,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{animation:fa-spin 2s infinite linear}.fa-pulse{animation:fa-spin 1s infinite steps(8)}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adobe:before{content:"\f778"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-handshake:before{content:"\f2b5"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-wizard:before{content:"\f6e8"}.fa-haykal:before{content:"\f666"}.fa-hdd:before{content:"\f0a0"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:auto;src:url(fa-regular-400.eot);src:url(fa-regular-400.eot?#iefix) format("embedded-opentype"),url(fa-regular-400.woff) format("woff")}.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:auto;src:url(fa-solid-900.eot);src:url(fa-solid-900.eot?#iefix) format("embedded-opentype"),url(fa-solid-900.woff) format("woff")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} \ No newline at end of file +.fa,.fab,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{animation:fa-spin 2s infinite linear}.fa-pulse{animation:fa-spin 1s infinite steps(8)}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adobe:before{content:"\f778"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-handshake:before{content:"\f2b5"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-wizard:before{content:"\f6e8"}.fa-haykal:before{content:"\f666"}.fa-hdd:before{content:"\f0a0"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:auto;src:url(fa-regular-400.eot);src:url(fa-regular-400.eot?#iefix) format("embedded-opentype"),url(fa-regular-400.woff) format("woff")}.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:auto;src:url(fa-solid-900.eot);src:url(fa-solid-900.eot?#iefix) format("embedded-opentype"),url(fa-solid-900.woff) format("woff")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} diff --git a/modular_splurt/code/game/machinery/computer/slavery.dm b/modular_splurt/code/game/machinery/computer/slavery.dm index 28c800beba..2466ef3b67 100644 --- a/modular_splurt/code/game/machinery/computer/slavery.dm +++ b/modular_splurt/code/game/machinery/computer/slavery.dm @@ -1,4 +1,5 @@ #define ANNOUNCEMENT_COOLDOWN 6 MINUTES +#define SLAVER_RANSOM_SCALE_VALUE 1000000 /obj/machinery/computer/slavery name = "\improper slave management console" @@ -49,6 +50,7 @@ var/turf/curr = get_turf(src) data["currentCoords"] = "[curr.x], [curr.y], [curr.z]" data["value_table"] = GLOB.slavers_ransom_values + data["ransom_scale_value"] = SLAVER_RANSOM_SCALE_VALUE data["categories"] = list() for(var/category in possible_gear) var/list/cat = list( diff --git a/modular_splurt/code/game/machinery/cryopod.dm b/modular_splurt/code/game/machinery/cryopod.dm new file mode 100644 index 0000000000..0e9bd8497f --- /dev/null +++ b/modular_splurt/code/game/machinery/cryopod.dm @@ -0,0 +1,20 @@ +GLOBAL_VAR_INIT(cryo_next_admin_warning, 0) // The last time we told admins about a mapping / coding error because no cryo computer was found + +/proc/cryo_find_control_computer(obj/machinery/cryopod/pod = null, urgent = FALSE) + + for(var/cryo_console as anything in GLOB.cryopod_computers) + var/obj/machinery/computer/cryopod/console = cryo_console + + if(!pod) // No cryopod passed in, we will try to find the standard crew cryo computer instead. + var/turf/console_turf = get_turf(console) + if((console_turf.z == 2) && (!istype(get_area(console), /area/security/prison))) // If station Z-level and NOT the prison cryo computer. Should get the standard crew cryo computer. + return WEAKREF(console) + else + if(get_area(console) == get_area(pod)) + return WEAKREF(console) + + // Don't send messages unless we *need* the computer, and less than five minutes have passed since last time we messaged + if(urgent && (world.time > GLOB.cryo_next_admin_warning)) + log_admin("\The [pod] in [get_area(pod)] could not find control computer!") + message_admins("\The [pod] in [get_area(pod)] could not find control computer!") + GLOB.cryo_next_admin_warning = world.time + 5 MINUTES diff --git a/modular_splurt/code/game/object/items/devices/radio/electropack.dm b/modular_splurt/code/game/object/items/devices/radio/electropack.dm index 95b0a4e7b8..ef7a39f609 100644 --- a/modular_splurt/code/game/object/items/devices/radio/electropack.dm +++ b/modular_splurt/code/game/object/items/devices/radio/electropack.dm @@ -43,8 +43,11 @@ var/automatic_ransom_value = GLOB.slavers_ransom_values[M.job] if (automatic_ransom_value) station_rank = M.job - setPrice(automatic_ransom_value) + var/datum/bank_account/bank = SSeconomy.get_dep_account(ACCOUNT_CAR) + automatic_ransom_value += automatic_ransom_value * (bank.account_balance / SLAVER_RANSOM_SCALE_VALUE) // Slave price scales with station credit balance (+100% per 1,000,000 credits in the cargo budget) + + setPrice(automatic_ransom_value) /obj/item/electropack/shockcollar/slave/proc/setPrice(newPrice) var/mob/living/M = loc diff --git a/modular_splurt/code/game/object/items/devices/radio/headset.dm b/modular_splurt/code/game/object/items/devices/radio/headset.dm new file mode 100644 index 0000000000..f3dbd8c603 --- /dev/null +++ b/modular_splurt/code/game/object/items/devices/radio/headset.dm @@ -0,0 +1,5 @@ +/obj/item/radio/headset/syndicate/slaver/Initialize() + . = ..() + + set_frequency(FREQ_SYNDICATE) + freqlock = TRUE diff --git a/modular_splurt/code/game/object/structures/crates_lockers/closets/slaver.dm b/modular_splurt/code/game/object/structures/crates_lockers/closets/slaver.dm index b47aa92475..a1414adfef 100644 --- a/modular_splurt/code/game/object/structures/crates_lockers/closets/slaver.dm +++ b/modular_splurt/code/game/object/structures/crates_lockers/closets/slaver.dm @@ -10,7 +10,7 @@ new /obj/item/clothing/under/syndicate(src) new /obj/item/clothing/shoes/workboots(src) new /obj/item/storage/belt/military(src) - new /obj/item/radio/headset/syndicate(src) + new /obj/item/radio/headset/syndicate/slaver(src) new /obj/item/crowbar/red(src) new /obj/item/restraints/handcuffs(src) new /obj/item/restraints/handcuffs(src) @@ -31,7 +31,7 @@ new /obj/item/clothing/under/syndicate(src) new /obj/item/clothing/shoes/workboots(src) new /obj/item/storage/belt/military(src) - new /obj/item/radio/headset/syndicate(src) + new /obj/item/radio/headset/syndicate/slaver(src) new /obj/item/crowbar/red(src) new /obj/item/restraints/handcuffs(src) new /obj/item/restraints/handcuffs(src) diff --git a/modular_splurt/code/modules/admin/JobBan.dm b/modular_splurt/code/modules/admin/JobBan.dm new file mode 100644 index 0000000000..98b2fe27d2 --- /dev/null +++ b/modular_splurt/code/modules/admin/JobBan.dm @@ -0,0 +1,179 @@ +// Stuff that helps the TGUI player panel jobban section to work + +GLOBAL_LIST_INIT(jobban_panel_data, list( + list( + "name" = "Command", + "color" = "yellow", + "roles" = GLOB.command_positions + ), + list( + "name" = "Security", + "color" = "red", + "roles" = GLOB.security_positions + ), + list( + "name" = "Engineering", + "color" = "orange", + "roles" = GLOB.engineering_positions + ), + list( + "name" = "Medical", + "color" = "blue", + "roles" = GLOB.medical_positions + ), + list( + "name" = "Science", + "color" = "violet", + "roles" = GLOB.science_positions + ), + list( + "name" = "Supply", + "color" = "brown", + "roles" = GLOB.supply_positions + ), + list( + "name" = "Service", + "color" = "green", + "roles" = GLOB.civilian_positions + ), + list( + "name" = "Silicon", + "color" = "purple", + "roles" = GLOB.nonhuman_positions + ), + list( + "name" = "Ghost Roles", + "color" = "teal", + "roles" = list( + ROLE_PAI, + ROLE_POSIBRAIN, + ROLE_DRONE, + ROLE_DEATHSQUAD, + ROLE_LAVALAND, + ROLE_GHOSTCAFE, + ROLE_SENTIENCE, + ROLE_MIND_TRANSFER + ) + ), + list( + "name" = "Antagonists", + "color" = "red", + "roles" = list( + ROLE_TRAITOR, + ROLE_CHANGELING, + ROLE_HERETIC, + ROLE_OPERATIVE, + ROLE_REV, + ROLE_CULTIST, + ROLE_SERVANT_OF_RATVAR, + ROLE_WIZARD, + ROLE_ABDUCTOR, + ROLE_ALIEN, + ROLE_FAMILIES, + ROLE_BLOODSUCKER, + ROLE_SLAVER + ) + ), + list( + "name" = "Other", + "color" = "red", + "roles" = list( + "pacifist", + "appearance", + "emote", + "OOC", + ROLE_RESPAWN + ) + ) +)) + +// notbannedlist is just a list of strings of the job titles you want to ban. +/datum/admins/proc/Jobban(mob/M, list/notbannedlist) + if (!check_rights(R_BAN)) + to_chat(usr, "Error: You do not have sufficient admin rights to ban players.") + return + + var/severity = null + var/reason = null + + switch(tgui_alert(usr, "Job ban type", buttons = list("Temporary", "Permanent", "Cancel"))) + if("Temporary") + var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null + if(mins <= 0) + to_chat(usr, "[mins] is not a valid duration.") + return + reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null + if(!reason) + return + severity = tgui_alert(usr, "Set the severity of the note/ban", buttons = list("High", "Medium", "Minor", "None")) + if(!severity) + return + var/msg + for(var/job in notbannedlist) + if(!DB_ban_record(BANTYPE_JOB_TEMP, M, mins, reason, job)) + to_chat(usr, "Failed to apply ban.") + return + if(M.client) + jobban_buildcache(M.client) + ban_unban_log_save("[key_name(usr)] temp-jobbanned [key_name(M)] from [job] for [mins] minutes. reason: [reason]") + log_admin_private("[key_name(usr)] temp-jobbanned [key_name(M)] from [job] for [mins] minutes.") + if(!msg) + msg = job + else + msg += ", [job]" + create_message("note", M.key, null, "Banned from [msg] - [reason]", null, null, 0, 0, null, 0, severity) + message_admins("[key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes.") + to_chat(M, "You have been [((msg == "ooc") || (msg == "appearance") || (msg == "pacifist")) ? "banned" : "jobbanned"] by [usr.client.key] from: [msg == "pacifist" ? "using violence" : msg].") + to_chat(M, "The reason is: [reason]") + to_chat(M, "This jobban will be lifted in [mins] minutes.") + + if("Permanent") + reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null + if (!reason) + return + severity = tgui_alert(usr, "Please State Reason For Banning", buttons = list("High", "Medium", "Minor", "None")) + if (!severity) + return + + var/msg + for(var/job in notbannedlist) + if(!DB_ban_record(BANTYPE_JOB_PERMA, M, -1, reason, job)) + to_chat(usr, "Failed to apply ban.") + return + if(M.client) + jobban_buildcache(M.client) + ban_unban_log_save("[key_name(usr)] perma-jobbanned [key_name(M)] from [job]. reason: [reason]") + log_admin_private("[key_name(usr)] perma-banned [key_name(M)] from [job]") + if(!msg) + msg = job + else + msg += ", [job]" + create_message("note", M.key, null, "Banned from [msg] - [reason]", null, null, 0, 0, null, 0, severity) + message_admins("[key_name_admin(usr)] banned [key_name_admin(M)] from [msg].") + to_chat(M, "You have been [((msg == "ooc") || (msg == "appearance") || (msg == "pacifist")) ? "banned" : "jobbanned"] by [usr.client.key] from: [msg == "pacifist" ? "using violence" : msg].") + to_chat(M, "The reason is: [reason]") + to_chat(M, "This jobban can be lifted only upon request.") + +// notbannedlist is just a list of strings of the job titles you want to unban. +/datum/admins/proc/UnJobban(mob/M, list/bannedlist) + + if (!check_rights(R_BAN)) + to_chat(usr, "Error: You do not have sufficient admin rights to unban players.") + return + + var/msg + for(var/job in bannedlist) + var/reason = jobban_isbanned(M, job) + if (tgui_alert(usr, "Job: '[job]' Ban reason: '[reason]'", "Un-Jobban This Player?", list("Yes", "No")) == "Yes") + ban_unban_log_save("[key_name(usr)] unjobbanned [key_name(M)] from [job]") + log_admin_private("[key_name(usr)] unbanned [key_name(M)] from [job]") + DB_ban_unban(M.ckey, BANTYPE_ANY_JOB, job) + if(M.client) + jobban_buildcache(M.client) + if(!msg) + msg = job + else + msg += ", [job]" + if(msg) + message_admins("[key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg].") + to_chat(M, "You have been un-jobbanned by [usr.client.key] from [msg].") diff --git a/modular_splurt/code/modules/admin/Kick.dm b/modular_splurt/code/modules/admin/Kick.dm new file mode 100644 index 0000000000..19c0f77de2 --- /dev/null +++ b/modular_splurt/code/modules/admin/Kick.dm @@ -0,0 +1,13 @@ +/datum/admins/proc/kick(mob/M) + if (!ismob(M) || !M.client) + to_chat(usr, "Error: [M] has no client!") + return + + if(!check_if_greater_rights_than(M.client)) + to_chat(usr, "Error: They have more rights than you do.") + return + + to_chat(M, "You have been kicked from the server by [usr.client.holder.fakekey ? "an Administrator" : "[usr.client.key]"].") + log_admin("[key_name(usr)] kicked [key_name(M)].") + message_admins("[key_name_admin(usr)] kicked [key_name_admin(M)].") + qdel(M.client) diff --git a/modular_splurt/code/modules/admin/NewBan.dm b/modular_splurt/code/modules/admin/NewBan.dm new file mode 100644 index 0000000000..9a42461c34 --- /dev/null +++ b/modular_splurt/code/modules/admin/NewBan.dm @@ -0,0 +1,70 @@ +/datum/admins/proc/newBan(mob/M) + if(!check_rights(R_BAN)) + return + + // var/mob/M = mob_to_ban + if(!ismob(M) || !M.client) + to_chat(usr, "Error: [M] has no client!") + return + + if(M.client && M.client.holder) + to_chat(usr, "Error: You cannot ban admins!") + return //admins cannot be banned. Even if they could, the ban doesn't affect them anyway + + switch(tgui_alert(usr, "Ban type", buttons = list("Temporary", "Permanent", "Cancel"))) + if("Temporary") + var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null + if(mins <= 0) + to_chat(usr, "[mins] is not a valid duration.") + return + var/reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null + if(!reason) + return + if(!DB_ban_record(BANTYPE_TEMP, M, mins, reason)) + to_chat(usr, "Failed to apply ban.") + return + AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins) + ban_unban_log_save("[key_name(usr)] has banned [key_name(M)]. - Reason: [reason] - This will be removed in [mins] minutes.") + to_chat(M, "You have been banned by [usr.client.key].\nReason: [reason]") + to_chat(M, "This is a temporary ban, it will be removed in [mins] minutes. The round ID is [GLOB.round_id].") + var/bran = CONFIG_GET(string/banappeals) + if(bran) + to_chat(M, "To try to resolve this matter head to [bran]") + else + to_chat(M, "No ban appeals URL has been set.") + log_admin_private("[key_name(usr)] has banned [key_name(M)].\nReason: [key_name(M)]\nThis will be removed in [mins] minutes.") + var/msg = "[key_name_admin(usr)] has banned [key_name_admin(M)].\nReason: [reason]\nThis will be removed in [mins] minutes." + message_admins(msg) + var/datum/admin_help/AH = M.client ? M.client.current_ticket : null + if(AH) + AH.Resolve() + qdel(M.client) + if("Permanent") + var/reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null + if(!reason) + return + switch(alert(usr,"IP ban?",,"Yes","No","Cancel")) + if("Cancel") + return + if("Yes") + AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0, M.lastKnownIP) + if("No") + AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0) + to_chat(M, "You have been banned by [usr.client.key].\nReason: [reason]") + to_chat(M, "This is a permanent ban. The round ID is [GLOB.round_id].") + var/bran = CONFIG_GET(string/banappeals) + if(bran) + to_chat(M, "To try to resolve this matter head to [bran]") + else + to_chat(M, "No ban appeals URL has been set.") + if(!DB_ban_record(BANTYPE_PERMA, M, -1, reason)) + to_chat(usr, "Failed to apply ban.") + return + ban_unban_log_save("[key_name(usr)] has permabanned [key_name(M)]. - Reason: [reason] - This is a permanent ban.") + log_admin_private("[key_name(usr)] has banned [key_name(M)].\nReason: [reason]\nThis is a permanent ban.") + var/msg = "[key_name_admin(usr)] has banned [key_name_admin(M)].\nReason: [reason]\nThis is a permanent ban." + message_admins(msg) + var/datum/admin_help/AH = M.client ? M.client.current_ticket : null + if(AH) + AH.Resolve() + qdel(M.client) diff --git a/modular_splurt/code/modules/admin/Transform.dm b/modular_splurt/code/modules/admin/Transform.dm new file mode 100644 index 0000000000..5fbc48be22 --- /dev/null +++ b/modular_splurt/code/modules/admin/Transform.dm @@ -0,0 +1,127 @@ +// Stuff that helps the TGUI player panel transform section to work + +GLOBAL_LIST_INIT(pp_transformables, list( + list( + name = "Common", + color = "", + types = list( + list( + name = "Human", + key = /mob/living/carbon/human + ), + list( + name = "Monkey", + key = /mob/living/carbon/monkey + ), + list( + name = "Cyborg", + key = /mob/living/silicon/robot + ) + ) + ), + list( + name = "Xenomorph", + color = "purple", + types = list( + list( + name = "Larva", + key = /mob/living/carbon/alien/larva + ), + list( + name = "Drone", + key = /mob/living/carbon/alien/humanoid/drone + ), + list( + name = "Hunter", + key = /mob/living/carbon/alien/humanoid/hunter + ), + list( + name = "Sentinel", + key = /mob/living/carbon/alien/humanoid/sentinel + ), + list( + name = "Praetorian", + key = /mob/living/carbon/alien/humanoid/royal/praetorian + ), + list( + name = "Queen", + key = /mob/living/carbon/alien/humanoid/royal/queen + ) + ) + ), + list( + name = "Lavaland", + color = "orange", + types = list( + list( + name = "Goliath", + key = /mob/living/simple_animal/hostile/asteroid/goliath/beast + ), + list( + name = "Legion", + key = /mob/living/simple_animal/hostile/asteroid/hivelord/legion + ), + list( + name = "Blood-Drunk Miner", + key = /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner + ), + list( + name = "Gladiator", + key = /mob/living/simple_animal/hostile/megafauna/gladiator + ), + list( + name = "Dragon", + key = /mob/living/simple_animal/hostile/megafauna/dragon + ), + list( + name = "Legion Hivelord", + key = /mob/living/simple_animal/hostile/asteroid/elite/legionnaire + ) + ) + ), + list( + name = "Cultist", + color = "violet", + types = list( + list( + name = "Shade", + key = /mob/living/simple_animal/hostile/construct/shade + ), + list( + name = "Artificer", + key = /mob/living/simple_animal/hostile/construct/builder + ), + list( + name = "Wraith", + key = /mob/living/simple_animal/hostile/construct/wraith + ), + list( + name = "Juggernaut", + key = /mob/living/simple_animal/hostile/construct/armored + ) + ) + ) +)) + +// M: Mob to change +// newType: Path of new type e.g: /mob/living/carbon/alien/humanoid/drone +// newTypeName (optional): Name of the new type (used in logging): e.g: "Drone" +/datum/admins/proc/transformMob(mob/M, mob/adminMob, newType, newTypeName) + if(!check_rights(R_SPAWN)) + return + + if(!ismob(M)) + to_chat(usr, "This can only be used on instances of type /mob.") + return + + if (!newTypeName) + newTypeName = newType + + log_admin("[key_name(usr)] transformed [key_name(M)] into a [newTypeName].") + message_admins("[key_name_admin(usr)] transformed [key_name_admin(M)] into a [newTypeName].") + + var/mob/newMob = M.change_mob_type(newType, delete_old_mob = TRUE) + + if (M == adminMob) + adminMob = newMob + addtimer(CALLBACK(newMob.mob_panel, /datum.proc/ui_interact, adminMob), 0.1 SECONDS) diff --git a/modular_splurt/code/modules/admin/verbs/randomverbs.dm b/modular_splurt/code/modules/admin/verbs/randomverbs.dm index ba7c712761..00c97dddcf 100644 --- a/modular_splurt/code/modules/admin/verbs/randomverbs.dm +++ b/modular_splurt/code/modules/admin/verbs/randomverbs.dm @@ -6,3 +6,43 @@ var/obj/item/reagent_containers/food/snacks/store/book/funnyBook = new(get_turf(target)) target.forceMove(funnyBook) funnyBook.name = "Book of " + target.name + +/client/proc/cmd_admin_subtle_headset_message(mob/M, sender = null) + if(!ismob(M)) + return + if(!check_rights(R_ADMIN)) + return + + if (!sender) + var/list/subtle_message_options = list("Voice in head", RADIO_CHANNEL_CENTCOM, RADIO_CHANNEL_SYNDICATE) + sender = tgui_input_list(usr, "Choose the method of subtle messaging", "Subtle Message", subtle_message_options) + if (!sender) + return + + message_admins("[key_name_admin(src)] has started answering [ADMIN_LOOKUPFLW(M)]'s prayer / faction PM.") + var/msg = input("Contents of the message", text("Subtle PM to [M.key]")) as text + if (!msg) + message_admins("[key_name_admin(src)] decided not to answer [ADMIN_LOOKUPFLW(M)]'s prayer / faction PM.") + return + + if (sender == "Voice in head") + to_chat(M, "You hear a voice in your head... [msg]") + else + var/mob/living/carbon/human/H = M + + if(!istype(H)) + to_chat(usr, "The person you are trying to contact is not human. Unsent message: [msg]") + return + + if(!istype(H.ears, /obj/item/radio/headset)) + to_chat(usr, "The person you are trying to contact is not wearing a headset. Unsent message: [msg]") + return + + to_chat(H, "You hear something crackle in your ears for a moment before a voice speaks. \"Please stand by for a message from [sender == RADIO_CHANNEL_SYNDICATE ? "your benefactor" : "Central Command"]. Message as follows[sender == RADIO_CHANNEL_SYNDICATE ? ", agent." : ":"] [msg]. Message ends.\"") + + + log_admin("SubtlePM ([sender]): [key_name(usr)] -> [key_name(M)] : [msg]") + msg = " SubtleMessage ([sender]): [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]" + message_admins(msg) + admin_ticket_log(M, msg) + SSblackbox.record_feedback("tally", "admin_verb", 1, "Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/modular_splurt/code/modules/antagonists/_common/antag_spawner.dm b/modular_splurt/code/modules/antagonists/_common/antag_spawner.dm index f5c2ba304f..ebb077ff11 100644 --- a/modular_splurt/code/modules/antagonists/_common/antag_spawner.dm +++ b/modular_splurt/code/modules/antagonists/_common/antag_spawner.dm @@ -59,6 +59,8 @@ else R = new /mob/living/silicon/robot/modules/slaver(T) + R.radio = new /obj/item/radio/borg/syndicate(R) + var/brainopsname = C.prefs.real_name R.mmi.name = "Man-Machine Interface: [brainopsname]" @@ -73,3 +75,9 @@ new_borg.send_to_spawnpoint = FALSE R.mind.add_antag_datum(new_borg,creator_slaver.slaver_team) R.mind.special_role = "Slaver Cyborg" + R.grant_language(/datum/language/codespeak, TRUE, TRUE) + + var/newName = sanitize_name(stripped_input(R, "Enter new robot name", "Cyborg Reclassification", "Cyborg", MAX_NAME_LEN)) + if (newName) + R.custom_name = newName + R.updatename() diff --git a/modular_splurt/code/modules/antagonists/slaver/equipment/orderable_gear.dm b/modular_splurt/code/modules/antagonists/slaver/equipment/orderable_gear.dm index c460c46503..6e9033a0b4 100644 --- a/modular_splurt/code/modules/antagonists/slaver/equipment/orderable_gear.dm +++ b/modular_splurt/code/modules/antagonists/slaver/equipment/orderable_gear.dm @@ -90,6 +90,13 @@ GLOBAL_LIST_INIT(slaver_gear, subtypesof(/datum/slaver_gear)) category = "Advanced" cost = 10000 +/datum/slaver_gear/jetpack + name = "Jetpack" + description = "Back-mounted jetpack for use in zero-gravity environments." + build_path = /obj/item/tank/jetpack/oxygen/harness + category = "Advanced" + cost = 3000 + /datum/slaver_gear/riot name = "Riot Kit" description = "Toy L6 SAW with riot darts." @@ -153,7 +160,7 @@ GLOBAL_LIST_INIT(slaver_gear, subtypesof(/datum/slaver_gear)) description = ".50 cal sniper rifle with sleep-inducing rounds." build_path = /obj/item/storage/backpack/duffelbag/syndie/slaver_marksman category = "Firearms" - cost = 40000 + cost = 50000 /datum/slaver_gear/freedom name = "Freedom Implant" @@ -171,7 +178,7 @@ GLOBAL_LIST_INIT(slaver_gear, subtypesof(/datum/slaver_gear)) /datum/slaver_gear/implant_teleport name = "Emergency Teleport Implants" - description = "Emergency teleport implant x 2." + description = "Emergency teleport implant x 2. Once activated, user needs to stand still for 5 seconds, after which they will be teleported from any location back to the slaver hideout. Has only one use." build_path = /obj/item/storage/box/slaver_teleport category = "Implants" cost = 15000 diff --git a/modular_splurt/code/modules/antagonists/slaver/equipment/slaver_outfits.dm b/modular_splurt/code/modules/antagonists/slaver/equipment/slaver_outfits.dm index c123e2ca5e..c97a6f18c8 100644 --- a/modular_splurt/code/modules/antagonists/slaver/equipment/slaver_outfits.dm +++ b/modular_splurt/code/modules/antagonists/slaver/equipment/slaver_outfits.dm @@ -5,7 +5,7 @@ shoes = /obj/item/clothing/shoes/workboots gloves = /obj/item/clothing/gloves/color/black back = /obj/item/storage/backpack - ears = /obj/item/radio/headset/syndicate + ears = /obj/item/radio/headset/syndicate/slaver id = /obj/item/card/id/syndicate/slaver backpack_contents = list(/obj/item/storage/box/survival,\ /obj/item/kitchen/knife/combat/survival) @@ -17,9 +17,5 @@ gloves = /obj/item/clothing/gloves/krav_maga/combatglovesplus /datum/outfit/slaver/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) - var/obj/item/radio/R = H.ears - R.set_frequency(FREQ_SYNDICATE) - R.freqlock = TRUE - H.faction |= ROLE_SLAVER H.update_icons() diff --git a/modular_splurt/code/modules/client/client_procs.dm b/modular_splurt/code/modules/client/client_procs.dm index d62111d09d..0da99d96de 100644 --- a/modular_splurt/code/modules/client/client_procs.dm +++ b/modular_splurt/code/modules/client/client_procs.dm @@ -2,3 +2,93 @@ . = ..() if(ip_intel != initial(ip_intel) && ip_intel >= CONFIG_GET(number/ipintel_rating_bad)) uses_vpn = TRUE + +/client/proc/toggle_quirk(mob/living/carbon/human/H) + if (!istype(H)) + to_chat(usr, "This can only be used on /mob/living/carbon/human.") + return + + var/list/options = list("Clear"="Clear") + for(var/x in subtypesof(/datum/quirk)) + var/datum/quirk/T = x + var/qname = initial(T.name) + options[H.has_quirk(T) ? "[qname] (Remove)" : "[qname] (Add)"] = T + + var/result = tgui_input_list(usr, "Choose quirk to add/remove", "Mob Quirks", options) // input(usr, "Choose quirk to add/remove","Quirk Mod") as null|anything in options + + if(QDELETED(H)) + to_chat(usr, "Mob doesn't exist anymore") + return + + if(result) + if(result == "Clear") + for(var/datum/quirk/q in H.roundstart_quirks) + H.remove_quirk(q.type) + else + var/T = options[result] + if(H.has_quirk(T)) + H.remove_quirk(T) + else + H.add_quirk(T,TRUE) + +/client/proc/toggle_spell(mob/M) + var/list/options = list("Clear"="Clear") + for(var/x in GLOB.spells) + var/obj/effect/proc_holder/spell/spell = x + var/spell_name = initial(spell.name) + options[M.has_spell(spell) ? "[spell_name] (Remove)" : "[spell_name] (Add)"] = spell + + var/spell_to_modify = tgui_input_list(usr, "Choose spell to add/remove", "Mob Spells", options) // input(usr, "Choose quirk to add/remove","Quirk Mod") as null|anything in options + + if(QDELETED(M)) + to_chat(usr, "Mob doesn't exist anymore") + return + + if(spell_to_modify) + if(spell_to_modify == "Clear") + if (!M.mind) + return + for(var/obj/effect/proc_holder/spell/S in M.mind.spell_list) + M.mind.RemoveSpell(S.type) + else + var/T = options[spell_to_modify] + if(M.has_spell(T)) + M.mind.RemoveSpell(T) + else + if (M.mind) + M.mind.AddSpell(new T) + else + M.AddSpell(new T) + message_admins("Spells given to mindless mobs will not be transferred in mindswap or cloning!") + +/client/proc/teach_martial_art(mob/living/carbon/C) + if (!istype(C)) + to_chat(usr, "This can only be used on /mob/living/carbon.") + return + + var/list/artpaths = subtypesof(/datum/martial_art) + var/list/artnames = list() + for(var/i in artpaths) + var/datum/martial_art/M = i + artnames[initial(M.name)] = M + var/result = tgui_input_list(usr, "Choose the martial art to teach", "JUDO CHOP", artnames) // input(usr, "Choose the martial art to teach","JUDO CHOP") as null|anything in artnames + + if(QDELETED(C)) + to_chat(usr, "Mob doesn't exist anymore") + return + if(result) + var/chosenart = artnames[result] + var/datum/martial_art/MA = new chosenart + MA.teach(C) + log_admin("[key_name(usr)] has taught [MA] to [key_name(C)].") + message_admins("[key_name_admin(usr)] has taught [MA] to [key_name_admin(C)].") + +/client/proc/set_species(mob/living/carbon/human/H) + if (istype(H)) + var/result = tgui_input_list(usr, "Choose a new species","Species", GLOB.species_list) + if(QDELETED(H)) + to_chat(usr, "Mob doesn't exist anymore") + return + if(result) + admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [H] to [result]") + H.set_species(GLOB.species_list[result]) diff --git a/modular_splurt/code/modules/mob/living/living.dm b/modular_splurt/code/modules/mob/living/living.dm new file mode 100644 index 0000000000..e83dd0fa35 --- /dev/null +++ b/modular_splurt/code/modules/mob/living/living.dm @@ -0,0 +1,27 @@ +/// Toggle admin frozen +/mob/living/proc/toggle_admin_freeze(client/admin) + admin_frozen = !admin_frozen + + if(admin_frozen) + SetStun(INFINITY, ignore_canstun = TRUE) + else + SetStun(0, ignore_canstun = TRUE) + + if(client && admin) + to_chat(src, "An admin has [!admin_frozen ? "un" : ""]frozen you.") + log_admin("[key_name(admin)] toggled admin-freeze on [key_name(src)].") + message_admins("[key_name_admin(admin)] toggled admin-freeze on [key_name_admin(src)].") + +/// Toggle admin sleeping +/mob/living/proc/toggle_admin_sleep(client/admin) + admin_sleeping = !admin_sleeping + + if(admin_sleeping) + SetSleeping(INFINITY, ignore_canstun = TRUE) + else + SetSleeping(0, ignore_canstun = TRUE) + + if(client && admin) + to_chat(src, "An admin has [!admin_sleeping ? "un": ""]slept you.") + log_admin("[key_name(admin)] toggled admin-sleep on [key_name(src)].") + message_admins("[key_name_admin(admin)] toggled admin-sleep on [key_name_admin(src)].") diff --git a/modular_splurt/code/modules/mob/living/living_defines.dm b/modular_splurt/code/modules/mob/living/living_defines.dm new file mode 100644 index 0000000000..bfc7719041 --- /dev/null +++ b/modular_splurt/code/modules/mob/living/living_defines.dm @@ -0,0 +1,4 @@ +/mob/living + // Admin CC + var/admin_frozen = FALSE + var/admin_sleeping = FALSE diff --git a/modular_splurt/code/modules/mob/mob.dm b/modular_splurt/code/modules/mob/mob.dm index 8831d46d22..5413b496fb 100644 --- a/modular_splurt/code/modules/mob/mob.dm +++ b/modular_splurt/code/modules/mob/mob.dm @@ -1,3 +1,11 @@ +/mob/Initialize() + . = ..() + create_player_panel() + +/mob/Destroy() + QDEL_NULL(mob_panel) + . = ..() + /mob/verb/tilt_left() set hidden = TRUE if(!canface() || is_tilted < -45) @@ -11,3 +19,16 @@ return FALSE transform = transform.Turn(1) is_tilted++ + +/mob/proc/has_spell(spelltype) + if (!mind) + return FALSE + + for(var/obj/effect/proc_holder/spell/S in mind.spell_list) + if(S.type == spelltype) + return TRUE + return FALSE + +/mob/proc/create_player_panel() + QDEL_NULL(mob_panel) + mob_panel = new(src) diff --git a/modular_splurt/code/modules/mob/mob_defines.dm b/modular_splurt/code/modules/mob/mob_defines.dm index ca952d2e09..b8f14819a2 100644 --- a/modular_splurt/code/modules/mob/mob_defines.dm +++ b/modular_splurt/code/modules/mob/mob_defines.dm @@ -1,2 +1,5 @@ /mob var/is_tilted + + // Admin player panel for this mob + var/datum/player_panel/mob_panel diff --git a/tgstation.dme b/tgstation.dme index cf4c679f75..c43f345566 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1500,6 +1500,7 @@ #include "code\modules\admin\outfits.dm" #include "code\modules\admin\permissionedit.dm" #include "code\modules\admin\player_panel.dm" +#include "code\modules\admin\player_panel2.dm" #include "code\modules\admin\playtimes.dm" #include "code\modules\admin\sound_emitter.dm" #include "code\modules\admin\sql_message_system.dm" @@ -4240,6 +4241,7 @@ #include "modular_splurt\code\game\gamemodes\objectives.dm" #include "modular_splurt\code\game\machinery\brigdoors.dm" #include "modular_splurt\code\game\machinery\chem_alert.dm" +#include "modular_splurt\code\game\machinery\cryopod.dm" #include "modular_splurt\code\game\machinery\research_table.dm" #include "modular_splurt\code\game\machinery\computer\slavery.dm" #include "modular_splurt\code\game\machinery\porta_turret\portable_turret.dm" @@ -4256,6 +4258,7 @@ #include "modular_splurt\code\game\object\items\circuitboards\machine_circuitboards.dm" #include "modular_splurt\code\game\object\items\circuitboards\miner_circuitboards.dm" #include "modular_splurt\code\game\object\items\devices\radio\electropack.dm" +#include "modular_splurt\code\game\object\items\devices\radio\headset.dm" #include "modular_splurt\code\game\object\items\devices\radio\radio.dm" #include "modular_splurt\code\game\object\items\implants\implant_slave.dm" #include "modular_splurt\code\game\object\items\implants\implant_slaver.dm" @@ -4295,7 +4298,11 @@ #include "modular_splurt\code\game\turfs\simulated\floor\plating\asteroid.dm" #include "modular_splurt\code\game\turfs\simulated\wall\mineral_walls.dm" #include "modular_splurt\code\modules\admin\chat_commands.dm" +#include "modular_splurt\code\modules\admin\JobBan.dm" +#include "modular_splurt\code\modules\admin\Kick.dm" +#include "modular_splurt\code\modules\admin\NewBan.dm" #include "modular_splurt\code\modules\admin\playtimes.dm" +#include "modular_splurt\code\modules\admin\Transform.dm" #include "modular_splurt\code\modules\admin\verbs\discord_subsystem.dm" #include "modular_splurt\code\modules\admin\verbs\discordbunker.dm" #include "modular_splurt\code\modules\admin\verbs\one_click_antag.dm" @@ -4429,6 +4436,8 @@ #include "modular_splurt\code\modules\mob\dead\new_player\sprite_accesories\synthliz.dm" #include "modular_splurt\code\modules\mob\dead\new_player\sprite_accesories\tails.dm" #include "modular_splurt\code\modules\mob\dead\new_player\sprite_accesories\wings.dm" +#include "modular_splurt\code\modules\mob\living\living.dm" +#include "modular_splurt\code\modules\mob\living\living_defines.dm" #include "modular_splurt\code\modules\mob\living\carbon\human\human.dm" #include "modular_splurt\code\modules\mob\living\carbon\human\human_defines.dm" #include "modular_splurt\code\modules\mob\living\carbon\human\simple_animal\hostile\deathclaw\deathclaw.dm" diff --git a/tgui/packages/tgui/interfaces/PlayerPanel2.js b/tgui/packages/tgui/interfaces/PlayerPanel2.js new file mode 100644 index 0000000000..b3178d959a --- /dev/null +++ b/tgui/packages/tgui/interfaces/PlayerPanel2.js @@ -0,0 +1,1020 @@ +import { Fragment } from "inferno"; +import { useBackend, useLocalState } from '../backend'; +import { Input, Button, Flex, Section, Tabs, Box, NoticeBox, NumberInput, Collapsible, LabeledList, Dropdown, Slider, Tooltip } from '../components'; +import { Window } from '../layouts'; + +const PAGES = [ + { + title: 'General', + component: () => GeneralActions, + color: "green", + icon: "tools", + }, + { + title: 'Mob', + component: () => PhysicalActions, + color: "yellow", + icon: "bolt", + canAccess: data => { + return !!data.mob_type.includes("/mob/living"); + }, + }, + { + title: 'Transform', + component: () => TransformActions, + color: "orange", + icon: "exchange-alt", + }, + { + title: 'Punish', + component: () => PunishmentActions, + color: "red", + icon: "gavel", + }, + { + title: 'Feature Bans', + component: () => FeatureBanTabs, + color: "red", + icon: "gavel", + canAccess: data => { + return data.client_ckey; + }, + }, + { + title: 'Fun', + component: () => FunActions, + color: "blue", + icon: "laugh", + }, + { + title: 'Other', + component: () => OtherActions, + color: "blue", + icon: "crosshairs", + }, +]; + +export const PlayerPanel2 = (props, context) => { + const { act, data } = useBackend(context); + const [pageIndex, setPageIndex] = useLocalState(context, 'pageIndex', 0); + const PageComponent = PAGES[pageIndex].component(); + + const { mob_name, mob_type, client_ckey, client_rank, playtimes_enabled, + playtime } = data; + + return ( + + +
+ + Name: + + act("set_name", { name: value })} /> + + {!!client_ckey && ( + + Rank: + +
+ + +
+ + {PAGES.map((page, i) => { + if (page.canAccess && !page.canAccess(data)) { + return; + } + + return ( + setPageIndex(i)}> + {page.title} + + ); + })} + + +
+
+ + + +
+
+
+ ); +}; + +const PhysicalActions = (props, context) => { + const { act, data } = useBackend(context); + const { glob_limbs, godmode, mob_type, initial_scale } = data; + const [mobScale, setMobScale] = useLocalState(context, 'mobScale', initial_scale); + const limbs = Object.keys(glob_limbs); + const limb_flags = limbs.map((_, i) => (1< +
act("toggle_godmode")} + /> + }> + +
+
+ {limbs.map((val, index) => ( + setDelimbOption( + (delimbOption & limb_flags[index]) + ? delimbOption & ~limb_flags[index] + : delimbOption|limb_flags[index] + )} + /> + ))} + + )}> + + act("limb", { + limbs: limb_flags.map((val, index) => + !!(delimbOption & val) && glob_limbs[limbs[index]] + ), + delimb_mode: true, + })} + /> + act("limb", { + limbs: limb_flags.map((val, index) => + !!(delimbOption & val) && glob_limbs[limbs[index]] + ), + })} + /> + +
+
{ + setMobScale(initial_scale); + act("scale", { new_scale: initial_scale }); + }} + /> + }> + + { + setMobScale(value); // Update slider value + act("scale", { new_scale: value }); // Update mob's value + }} + unit="x" + /> + +
+
+ + Force Say: + + act("force_say", { to_say: value })} + /> + + + + Force Emote: + + act("force_emote", { to_emote: value })} + /> + + +
+ + ); +}; + + +const FeatureBanTabs = (props, context) => { + const { data } = useBackend(context); + const [jobbanTab, setJobbanTab] = useLocalState(context, 'jobbanTab', 0); + const { roles } = data; + return ( + + +
+ + {roles.map((role_category, i) => { return ( + setJobbanTab(i)}> + {role_category.category_name} + + ); })} + +
+
+ + + + +
+ ); +}; + +const FeatureBans = (props, context) => { + const { act, data } = useBackend(context); + const [jobbanTab] = useLocalState(context, 'jobbanTab', 0); + const { roles, antag_ban_reason } = data; + return ( +
+
+
+
+ ); +}; + +const GeneralActions = (props, context) => { + const { act, data } = useBackend(context); + const { client_ckey, mob_type, admin_mob_type } = data; + return ( +
+
+ +
+ +
+ + act("bring")} + /> +
+ +
+ +
+
+ + act("ghost")} + /> + act("take_control")} + /> + act("offer_control")} + /> + +
+
+ ); +}; + +const PunishmentActions = (props, context) => { + const { act, data } = useBackend(context); + const { client_ckey, mob_type, is_frozen, is_slept, glob_mute_bits, + client_muted, data_related_cid, data_related_ip, data_byond_version, + data_player_join_date, data_account_join_date, active_role_ban_count, + current_time } = data; + return ( +
+ +
+ +
+ + act("kick")} + /> +
+ +
+
+
+ + Related accounts by: + +
+ + ); +}; + +const TransformActions = (props, context) => { + const { act, data } = useBackend(context); + const { transformables, mob_type } = data; + return ( +
+ +
+ ); +}; + +const FunActions = (props, context) => { + const { act } = useBackend(context); + + const colours = { + 'White': '#a4bad6', + 'Dark': '#42474D', + 'Red': '#c51e1e', + 'Red Bright': '#FF0000', + 'Velvet': '#660015', + 'Green': '#059223', + 'Blue': '#6685f5', + 'Purple': '#800080', + 'Purple Dark': '#5000A0', + 'Narsie': '#973e3b', + 'Ratvar': '#BE8700', + }; + + const [lockExplode, setLockExplode] = useLocalState(context, "explode_lock_toggle", true); + const [empMode, setEmpMode] = useLocalState(context, "empMode", false); + const [expPower, setExpPower] = useLocalState(context, "exp_power", 8); + const [narrateSize, setNarrateSize] = useLocalState(context, "narrateSize", 1); + const [narrateMessage, setNarrateMessage] = useLocalState(context, "narrateMessage", ""); + const [narrateColour, setNarrateColour] = useLocalState(context, "narrateColour", Object.keys(colours)[0]); + const [narrateFont, setNarrateFont] = useLocalState(context, "narrateFont", "Verdana"); + const [narrateBold, setNarrateBold] = useLocalState(context, "narrateBold", false); + const [narrateItalic, setNarrateItalic] = useLocalState(context, "narrateItalic", false); + const [narrateGlobal, setNarrateGlobal] = useLocalState(context, "narrateGlobal", false); + const [narrateRange, setNarrateRange] = useLocalState(context, "narrateRange", 7); + + + + const narrateStyles = { + 'color': colours[narrateColour], + 'font-size': narrateSize + 'rem', + 'font-weight': (narrateBold ? 'bold' : ''), + 'font-family': narrateFont, + 'font-style': (narrateItalic ? 'italic' : ''), + }; + + return ( +
+ + These features are centred on YOUR viewport + + +
+ setEmpMode(!empMode)} + /> + + + + setExpPower(value)} + ranges={{ + green: [0, 8], + orange: [8, 15], + red: [15, 30], + }} + minValue={1} + maxValue={30} + height="100%" + /> + + +
+
setNarrateGlobal(!narrateGlobal)} + /> + }> + + + + + + setNarrateColour(value)} + /> + + + setNarrateFont(value)} /> + + + + + + + setNarrateBold(!narrateBold)} + /> + + + setNarrateItalic(!narrateItalic)} + /> + + + + + + + setNarrateSize(value)} /> + + {!narrateGlobal && ( + + setNarrateRange(value)} /> + + )} + + + + + + + + setNarrateMessage(value)} + /> + + +
+
+ ); +}; + +const OtherActions = (props, context) => { + const { act, data } = useBackend(context); + const { mob_type, client_ckey } = data; + + return ( +
+
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/SlaveConsole.js b/tgui/packages/tgui/interfaces/SlaveConsole.js index 2cb5545ec5..d133b4363b 100644 --- a/tgui/packages/tgui/interfaces/SlaveConsole.js +++ b/tgui/packages/tgui/interfaces/SlaveConsole.js @@ -108,7 +108,7 @@ export const SlaveConsole = (props, context) => { const SlavePanel = (props, context) => { const { slaves } = props; - const { act, data } = useBackend(context); + const { act } = useBackend(context); if (!slaves.length) { return ( @@ -239,7 +239,9 @@ const SupplyPanel = (props, context) => { }; const RansomPanel = (props, context) => { + const { data } = useBackend(context); const value_table = props.value_table; + const { cargo_credits, ransom_scale_value } = data; let value_table_converted = []; @@ -271,7 +273,10 @@ const RansomPanel = (props, context) => { {rank_value.rank} - {formatMoney(rank_value.value, null, true)}cr + {formatMoney( + rank_value.value + (rank_value.value + * (cargo_credits / ransom_scale_value)) + , null, true)}cr );
Other Roles