diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 859884a8b7c..76b18f7222e 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -141,8 +141,9 @@ return 1 /obj/machinery/turretid/AICtrlClick() //turns off/on Turrets - Topic(src, list("command"="enable", "value"="[!enabled]")) - return 1 + enabled = !enabled + updateTurrets() + return TRUE /atom/proc/AIAltClick(var/atom/A) return AltClick(A) @@ -156,8 +157,10 @@ return 1 /obj/machinery/turretid/AIAltClick() //toggles lethal on turrets - Topic(src, list("command"="lethal", "value"="[!lethal]")) - return 1 + if(lethal_is_configurable) + lethal = !lethal + updateTurrets() + return TRUE /atom/proc/AIMiddleClick(var/mob/living/silicon/user) return 0 diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 66cf3d1c128..5e5f044ac24 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -515,7 +515,7 @@ if("Show Crew Manifest") if(isAI(usr)) var/mob/living/silicon/ai/AI = usr - AI.ai_roster() + AI.subsystem_crew_manifest() if("Show Alerts") if(isAI(usr)) @@ -540,12 +540,14 @@ if("PDA - Send Message") if(isAI(usr)) var/mob/living/silicon/ai/AI = usr - AI.aiPDA.cmd_send_pdamesg(usr) + AI.aiPDA.start_program(AI.aiPDA.find_program(/datum/data/pda/app/messenger)) + AI.aiPDA.cmd_pda_open_ui(usr) if("PDA - Show Message Log") if(isAI(usr)) var/mob/living/silicon/ai/AI = usr - AI.aiPDA.cmd_show_message_log(usr) + AI.aiPDA.start_program(AI.aiPDA.find_program(/datum/data/pda/app/messenger)) + AI.aiPDA.cmd_pda_open_ui(usr) if("Take Image") if(isAI(usr)) diff --git a/code/controllers/subsystems/nanoui.dm b/code/controllers/subsystems/nanoui.dm deleted file mode 100644 index c916eb2739d..00000000000 --- a/code/controllers/subsystems/nanoui.dm +++ /dev/null @@ -1,22 +0,0 @@ -SUBSYSTEM_DEF(nanoui) - name = "NanoUI" - wait = 5 - flags = SS_NO_INIT - // a list of current open /nanoui UIs, grouped by src_object and ui_key - var/list/open_uis = list() - // a list of current open /nanoui UIs, not grouped, for use in processing - var/list/processing_uis = list() - -/datum/controller/subsystem/nanoui/Recover() - if(SSnanoui.open_uis) - open_uis |= SSnanoui.open_uis - if(SSnanoui.processing_uis) - processing_uis |= SSnanoui.processing_uis - -/datum/controller/subsystem/nanoui/stat_entry() - return ..("[processing_uis.len] UIs") - -/datum/controller/subsystem/nanoui/fire(resumed) - for(var/thing in processing_uis) - var/datum/nanoui/UI = thing - UI.process() diff --git a/code/controllers/subsystems/persistence.dm b/code/controllers/subsystems/persistence.dm index c2724c2d609..00c08363de3 100644 --- a/code/controllers/subsystems/persistence.dm +++ b/code/controllers/subsystems/persistence.dm @@ -31,7 +31,7 @@ SUBSYSTEM_DEF(persistence) return // if((!T.z in GLOB.using_map.station_levels) || !initialized) - if(!T.z in using_map.station_levels) + if(!(T.z in using_map.station_levels)) return if(!tracking_values[track_type]) diff --git a/code/datums/datum.dm b/code/datums/datum.dm index 61eb4c69538..d806728f5df 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -31,5 +31,5 @@ weakref = null // Clear this reference to ensure it's kept for as brief duration as possible. tag = null - SSnanoui.close_uis(src) + SStgui.close_uis(src) return QDEL_HINT_QUEUE diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 10a7b4b7b95..bca9df5ae1e 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -85,7 +85,6 @@ current.verbs -= /datum/changeling/proc/EvolutionMenu current.mind = null - SSnanoui.user_transferred(current, new_character) // transfer active NanoUI instances to new user if(new_character.mind) //remove any mind currently in our new body's mind variable new_character.mind.current = null diff --git a/code/datums/uplink/uplink_items.dm b/code/datums/uplink/uplink_items.dm index cca1933c9c5..8d9de8f7321 100644 --- a/code/datums/uplink/uplink_items.dm +++ b/code/datums/uplink/uplink_items.dm @@ -51,7 +51,7 @@ var/datum/uplink/uplink = new() if(!can_buy(U)) return - if(U.CanUseTopic(user, inventory_state) != STATUS_INTERACTIVE) + if(U.CanUseTopic(user, GLOB.tgui_inventory_state) != STATUS_INTERACTIVE) return var/cost = cost(U.uses, U) diff --git a/code/game/gamemodes/changeling/powers/fabricate_clothing.dm b/code/game/gamemodes/changeling/powers/fabricate_clothing.dm index b90b402e78b..6ec87a64d44 100644 --- a/code/game/gamemodes/changeling/powers/fabricate_clothing.dm +++ b/code/game/gamemodes/changeling/powers/fabricate_clothing.dm @@ -286,5 +286,5 @@ var/global/list/changeling_fabricated_clothing = list( if(!registered_user) registered_user = usr usr.set_id_info(src) - ui_interact(registered_user) + tgui_interact(registered_user) ..() \ No newline at end of file diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 6fe30aeaab3..2d5e39b1b71 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -260,7 +260,7 @@ update_flag ..() - SSnanoui.update_uis(src) // Update all NanoUIs attached to src + SStgui.update_uis(src) // Update all NanoUIs attached to src /obj/machinery/portable_atmospherics/canister/attack_ai(var/mob/user as mob) return src.attack_hand(user) diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 8ef01c9b645..6921cf989c8 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -92,8 +92,11 @@ var/blocked = 0 //Player cannot attack/heal while set var/turtle = 0 -/obj/machinery/computer/arcade/battle/New() - ..() +/obj/machinery/computer/arcade/battle/Initialize() + . = ..() + randomize_characters() + +/obj/machinery/computer/arcade/battle/proc/randomize_characters() var/name_action var/name_part1 var/name_part2 @@ -111,17 +114,17 @@ if(..()) return user.set_machine(src) - ui_interact(user) + tgui_interact(user) -/** - * Display the NanoUI window for the arcade machine. - * - * See NanoUI documentation for details. - */ -/obj/machinery/computer/arcade/battle/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) +/obj/machinery/computer/arcade/battle/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ArcadeBattle", name) + ui.open() - var/list/data = list() +/obj/machinery/computer/arcade/battle/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + data["name"] = name data["temp"] = temp data["enemyAction"] = enemy_action data["enemyName"] = enemy_name @@ -129,59 +132,54 @@ data["playerMP"] = player_mp data["enemyHP"] = enemy_hp data["gameOver"] = gameover + return data - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "arcade_battle.tmpl", src.name, 400, 300) - ui.set_initial_data(data) - ui.open() - //ui.set_auto_update(2) - -/obj/machinery/computer/arcade/battle/Topic(href, href_list) +/obj/machinery/computer/arcade/battle/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return 1 + return TRUE - if (!blocked && !gameover) - if (href_list["attack"]) - blocked = 1 - var/attackamt = rand(2,6) - temp = "You attack for [attackamt] damage!" - playsound(src, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) - if(turtle > 0) - turtle-- + if(!blocked && !gameover) + switch(action) + if("attack") + blocked = 1 + var/attackamt = rand(2,6) + temp = "You attack for [attackamt] damage!" + playsound(src, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) + if(turtle > 0) + turtle-- - sleep(10) - enemy_hp -= attackamt - arcade_action() + sleep(10) + enemy_hp -= attackamt + arcade_action() - else if (href_list["heal"]) - blocked = 1 - var/pointamt = rand(1,3) - var/healamt = rand(6,8) - temp = "You use [pointamt] magic to heal for [healamt] damage!" - playsound(src, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) - turtle++ + if("heal") + blocked = 1 + var/pointamt = rand(1,3) + var/healamt = rand(6,8) + temp = "You use [pointamt] magic to heal for [healamt] damage!" + playsound(src, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) + turtle++ - sleep(10) - player_mp -= pointamt - player_hp += healamt - blocked = 1 - arcade_action() + sleep(10) + player_mp -= pointamt + player_hp += healamt + blocked = 1 + arcade_action() - else if (href_list["charge"]) - blocked = 1 - var/chargeamt = rand(4,7) - temp = "You regain [chargeamt] points" - playsound(src, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) - player_mp += chargeamt - if(turtle > 0) - turtle-- + if("charge") + blocked = 1 + var/chargeamt = rand(4,7) + temp = "You regain [chargeamt] points" + playsound(src, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) + player_mp += chargeamt + if(turtle > 0) + turtle-- - sleep(10) - arcade_action() + sleep(10) + arcade_action() - else if (href_list["newgame"]) //Reset everything + if(action == "newgame") //Reset everything temp = "New Round" player_hp = 30 player_mp = 10 @@ -191,12 +189,11 @@ turtle = 0 if(emagged) - src.New() + randomize_characters() emagged = 0 - src.add_fingerprint(usr) - SSnanoui.update_uis(src) - return + add_fingerprint(usr) + return TRUE /obj/machinery/computer/arcade/battle/proc/arcade_action() if ((enemy_mp <= 0) || (enemy_hp <= 0)) @@ -211,7 +208,7 @@ new /obj/item/clothing/head/collectable/petehat(src.loc) message_admins("[key_name_admin(usr)] has outbombed Cuban Pete and been awarded a bomb.") log_game("[key_name_admin(usr)] has outbombed Cuban Pete and been awarded a bomb.") - src.New() + randomize_characters() emagged = 0 else if(!contents.len) feedback_inc("arcade_win_normal") diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index eb634c249f4..1a4ec083df8 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -13,14 +13,14 @@ var/reason = "NOT SPECIFIED" /obj/item/weapon/card/id/guest/GetAccess() - if (world.time > expiration_time) + if(world.time > expiration_time) return access else return temp_access /obj/item/weapon/card/id/guest/examine(mob/user) . = ..() - if (world.time < expiration_time) + if(world.time < expiration_time) . += "This pass expires at [worldtime2stationtime(expiration_time)]." else . += "It expired at [worldtime2stationtime(expiration_time)]." @@ -28,7 +28,7 @@ /obj/item/weapon/card/id/guest/read() if(!Adjacent(usr)) return //Too far to read - if (world.time > expiration_time) + if(world.time > expiration_time) to_chat(usr, "This pass expired at [worldtime2stationtime(expiration_time)].") else to_chat(usr, "This pass expires at [worldtime2stationtime(expiration_time)].") @@ -105,7 +105,7 @@ if(!giver && user.unEquip(I)) I.forceMove(src) giver = I - SSnanoui.update_uis(src) + SStgui.update_uis(src) else if(giver) to_chat(user, "There is already ID card inside.") return @@ -119,128 +119,119 @@ return user.set_machine(src) + tgui_interact(user) - ui_interact(user) +/obj/machinery/computer/guestpass/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "GuestPass", name) + ui.open() -/** - * Display the NanoUI window for the guest pass console. - * - * See NanoUI documentation for details. - */ -/obj/machinery/computer/guestpass/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) +/obj/machinery/computer/guestpass/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() - var/list/data = list() + var/list/area_list = list() - var/area_list[0] - - if (giver && giver.access) + data["access"] = null + if(giver && giver.access) data["access"] = giver.access for (var/A in giver.access) if(A in accesses) - area_list[++area_list.len] = list("area" = A, "area_name" = get_access_desc(A), "on" = 1) + area_list.Add(list(list("area" = A, "area_name" = get_access_desc(A), "on" = 1))) else - area_list[++area_list.len] = list("area" = A, "area_name" = get_access_desc(A), "on" = null) + area_list.Add(list(list("area" = A, "area_name" = get_access_desc(A), "on" = null))) + data["area"] = area_list data["giver"] = giver data["giveName"] = giv_name data["reason"] = reason data["duration"] = duration - data["area"] = area_list data["mode"] = mode data["log"] = internal_log data["uid"] = uid - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "guest_pass.tmpl", src.name, 400, 520) - ui.set_initial_data(data) - ui.open() - //ui.set_auto_update(5) + return data -/obj/machinery/computer/guestpass/Topic(href, href_list) +/obj/machinery/computer/guestpass/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return 1 - usr.set_machine(src) - if (href_list["mode"]) - mode = href_list["mode"] + return TRUE - if (href_list["choice"]) - switch(href_list["choice"]) - if ("giv_name") - var/nam = sanitizeName(input("Person pass is issued to", "Name", giv_name) as text|null) - if (nam) - giv_name = nam - if ("reason") - var/reas = sanitize(input("Reason why pass is issued", "Reason", reason) as text|null) - if(reas) - reason = reas - if ("duration") - var/dur = input("Duration (in minutes) during which pass is valid (up to 120 minutes).", "Duration") as num|null - if (dur) - if (dur > 0 && dur <= 120) - duration = dur - else - to_chat(usr, "Invalid duration.") - if ("access") - var/A = text2num(href_list["access"]) - if (A in accesses) - accesses.Remove(A) + switch(action) + if("mode") + mode = params["mode"] + + if("giv_name") + var/nam = sanitizeName(input("Person pass is issued to", "Name", giv_name) as text|null) + if(nam) + giv_name = nam + if("reason") + var/reas = sanitize(input("Reason why pass is issued", "Reason", reason) as text|null) + if(reas) + reason = reas + if("duration") + var/dur = input("Duration (in minutes) during which pass is valid (up to 120 minutes).", "Duration") as num|null + if(dur) + if(dur > 0 && dur <= 120) + duration = dur else - if(A in giver.access) //Let's make sure the ID card actually has the access. - accesses.Add(A) - else - to_chat(usr, "Invalid selection, please consult technical support if there are any issues.") - log_debug("[key_name_admin(usr)] tried selecting an invalid guest pass terminal option.") - if (href_list["action"]) - switch(href_list["action"]) - if ("id") - if (giver) - if(ishuman(usr)) - giver.loc = usr.loc - if(!usr.get_active_hand()) - usr.put_in_hands(giver) - giver = null - else - giver.loc = src.loc - giver = null - accesses.Cut() + to_chat(usr, "Invalid duration.") + if("access") + var/A = text2num(params["access"]) + if(A in accesses) + accesses.Remove(A) + else + if(A in giver.access) //Let's make sure the ID card actually has the access. + accesses.Add(A) else - var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) - I.loc = src - giver = I - - if ("print") - var/dat = "

Activity log of guest pass terminal #[uid]


" - for (var/entry in internal_log) - dat += "[entry]

" - //to_chat(usr, "Printing the log, standby...") - //sleep(50) - var/obj/item/weapon/paper/P = new/obj/item/weapon/paper( loc ) - P.name = "activity log" - P.info = dat - - if ("issue") - if (giver) - var/number = add_zero("[rand(0,9999)]", 4) - var/entry = "\[[stationtime2text()]\] Pass #[number] issued by [giver.registered_name] ([giver.assignment]) to [giv_name]. Reason: [reason]. Grants access to following areas: " - for (var/i=1 to accesses.len) - var/A = accesses[i] - if (A) - var/area = get_access_desc(A) - entry += "[i > 1 ? ", [area]" : "[area]"]" - entry += ". Expires at [worldtime2stationtime(world.time + duration*10*60)]." - internal_log.Add(entry) - - var/obj/item/weapon/card/id/guest/pass = new(src.loc) - pass.temp_access = accesses.Copy() - pass.registered_name = giv_name - pass.expiration_time = world.time + duration*10*60 - pass.reason = reason - pass.name = "guest pass #[number]" + to_chat(usr, "Invalid selection, please consult technical support if there are any issues.") + log_debug("[key_name_admin(usr)] tried selecting an invalid guest pass terminal option.") + if("id") + if(giver) + if(ishuman(usr)) + giver.loc = usr.loc + if(!usr.get_active_hand()) + usr.put_in_hands(giver) + giver = null else - to_chat(usr, "Cannot issue pass without issuing ID.") + giver.loc = src.loc + giver = null + accesses.Cut() + else + var/obj/item/I = usr.get_active_hand() + if(istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) + I.loc = src + giver = I - src.add_fingerprint(usr) - SSnanoui.update_uis(src) \ No newline at end of file + if("print") + var/dat = "

Activity log of guest pass terminal #[uid]


" + for (var/entry in internal_log) + dat += "[entry]

" + //to_chat(usr, "Printing the log, standby...") + //sleep(50) + var/obj/item/weapon/paper/P = new/obj/item/weapon/paper( loc ) + P.name = "activity log" + P.info = dat + + if("issue") + if(giver) + var/number = add_zero("[rand(0,9999)]", 4) + var/entry = "\[[stationtime2text()]\] Pass #[number] issued by [giver.registered_name] ([giver.assignment]) to [giv_name]. Reason: [reason]. Grants access to following areas: " + for (var/i=1 to accesses.len) + var/A = accesses[i] + if(A) + var/area = get_access_desc(A) + entry += "[i > 1 ? ", [area]" : "[area]"]" + entry += ". Expires at [worldtime2stationtime(world.time + duration*10*60)]." + internal_log.Add(entry) + + var/obj/item/weapon/card/id/guest/pass = new(src.loc) + pass.temp_access = accesses.Copy() + pass.registered_name = giv_name + pass.expiration_time = world.time + duration*10*60 + pass.reason = reason + pass.name = "guest pass #[number]" + else + to_chat(usr, "Cannot issue pass without issuing ID.") + + add_fingerprint(usr) + return TRUE \ No newline at end of file diff --git a/code/game/machinery/computer/timeclock_vr.dm b/code/game/machinery/computer/timeclock_vr.dm index a94b3383208..8cfc711c188 100644 --- a/code/game/machinery/computer/timeclock_vr.dm +++ b/code/game/machinery/computer/timeclock_vr.dm @@ -55,7 +55,7 @@ if(!card && user.unEquip(I)) I.forceMove(src) card = I - SSnanoui.update_uis(src) + SStgui.update_uis(src) update_icon() else if(card) to_chat(user, "There is already ID card inside.") diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 7eb9e4a3421..014efcb5813 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -851,11 +851,13 @@ About the new airlock wires panel: /obj/machinery/door/airlock/attack_ghost(mob/user) tgui_interact(user) -/obj/machinery/door/airlock/tgui_interact(mob/user, datum/tgui/ui) +/obj/machinery/door/airlock/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/custom_state) ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "AiAirlock", name) ui.open() + if(custom_state) + ui.set_state(custom_state) return TRUE /obj/machinery/door/airlock/tgui_data(mob/user) diff --git a/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm b/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm index ef6367758f0..9e65c06bcd0 100644 --- a/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm +++ b/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm @@ -7,7 +7,6 @@ layer = ABOVE_OBJ_LAYER var/id_tag - var/datum/topic_state/remote/remote_state var/obj/machinery/embedded_controller/radio/airlock/master_controller /obj/machinery/dummy_airlock_controller/process() @@ -25,15 +24,10 @@ break if(!master_controller) qdel(src) - else - remote_state = new /datum/topic_state/remote(src, master_controller) /obj/machinery/dummy_airlock_controller/Destroy() if(master_controller) master_controller.dummy_terminals -= src - if(remote_state) - qdel(remote_state) - remote_state = null return ..() /obj/machinery/dummy_airlock_controller/interface_interact(var/mob/user) diff --git a/code/game/machinery/jukebox.dm b/code/game/machinery/jukebox.dm index 00a8e687601..e8e741b578e 100644 --- a/code/game/machinery/jukebox.dm +++ b/code/game/machinery/jukebox.dm @@ -192,7 +192,6 @@ if(inoperable()) to_chat(usr, "\The [src] doesn't appear to function.") return - ui_interact(user) tgui_interact(user) /obj/machinery/media/jukebox/tgui_status(mob/user) diff --git a/code/game/machinery/oxygen_pump.dm b/code/game/machinery/oxygen_pump.dm index 37c75957be3..f7821a4e841 100644 --- a/code/game/machinery/oxygen_pump.dm +++ b/code/game/machinery/oxygen_pump.dm @@ -79,7 +79,7 @@ update_use_power(USE_POWER_IDLE) /obj/machinery/oxygen_pump/attack_ai(mob/user as mob) - ui_interact(user) + tgui_interact(user) /obj/machinery/oxygen_pump/proc/attach_mask(var/mob/living/carbon/C) if(C && istype(C)) @@ -176,61 +176,60 @@ set src in oview(1) set category = "Object" set name = "Show Tank Settings" - ui_interact(usr) + tgui_interact(usr) -//GUI Tank Setup -/obj/machinery/oxygen_pump/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/oxygen_pump/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) if(!tank) - to_chat(usr, "It is missing a tank!") - data["tankPressure"] = 0 - data["releasePressure"] = 0 - data["defaultReleasePressure"] = 0 - data["maxReleasePressure"] = 0 - data["maskConnected"] = 0 - data["tankInstalled"] = 0 - // this is the data which will be sent to the ui + to_chat(user, "[src] is missing a tank.") + if(ui) + ui.close() + return + + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Tank", name) + ui.open() + +/obj/machinery/oxygen_pump/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + data["showToggle"] = FALSE + data["maskConnected"] = !!breather + + data["tankPressure"] = 0 + data["releasePressure"] = 0 + data["defaultReleasePressure"] = 0 + data["minReleasePressure"] = 0 + data["releasePressure"] = round(tank.distribute_pressure ? tank.distribute_pressure : 0) + data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE) + if(tank) data["tankPressure"] = round(tank.air_contents.return_pressure() ? tank.air_contents.return_pressure() : 0) - data["releasePressure"] = round(tank.distribute_pressure ? tank.distribute_pressure : 0) data["defaultReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE) - data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE) - data["maskConnected"] = 0 - data["tankInstalled"] = 1 - if(!breather) - data["maskConnected"] = 0 - if(breather) - data["maskConnected"] = 1 + return data - - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "Oxygen_pump.tmpl", "Tank", 500, 300) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) - -/obj/machinery/oxygen_pump/Topic(href, href_list) +/obj/machinery/oxygen_pump/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return 1 + return TRUE - if (href_list["dist_p"]) - if (href_list["dist_p"] == "reset") - tank.distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE - else if (href_list["dist_p"] == "max") - tank.distribute_pressure = TANK_MAX_RELEASE_PRESSURE - else - var/cp = text2num(href_list["dist_p"]) - tank.distribute_pressure += cp - tank.distribute_pressure = min(max(round(tank.distribute_pressure), 0), TANK_MAX_RELEASE_PRESSURE) - return 1 + switch(action) + if("pressure") + var/pressure = params["pressure"] + if(pressure == "reset") + pressure = TANK_DEFAULT_RELEASE_PRESSURE + . = TRUE + else if(pressure == "min") + pressure = 0 + . = TRUE + else if(pressure == "max") + pressure = TANK_MAX_RELEASE_PRESSURE + . = TRUE + else if(text2num(pressure) != null) + pressure = text2num(pressure) + . = TRUE + if(.) + tank.distribute_pressure = clamp(round(pressure), 0, TANK_MAX_RELEASE_PRESSURE) /obj/machinery/oxygen_pump/anesthetic name = "anesthetic pump" diff --git a/code/game/machinery/partslathe_vr.dm b/code/game/machinery/partslathe_vr.dm index aab15f40f9b..c5ddcff900a 100644 --- a/code/game/machinery/partslathe_vr.dm +++ b/code/game/machinery/partslathe_vr.dm @@ -233,7 +233,6 @@ /obj/machinery/partslathe/attack_hand(mob/user) if(..()) return - ui_interact(user) tgui_interact(user) /obj/machinery/partslathe/ui_assets(mob/user) diff --git a/code/game/machinery/pointdefense.dm b/code/game/machinery/pointdefense.dm index 8eeb73fbc5e..5b10e398a3b 100644 --- a/code/game/machinery/pointdefense.dm +++ b/code/game/machinery/pointdefense.dm @@ -95,7 +95,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) /obj/machinery/pointdefense_control/attackby(var/obj/item/W, var/mob/user) if(W?.is_multitool()) var/new_ident = input(user, "Enter a new ident tag.", "[src]", id_tag) as null|text - if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, physical_state)) + if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state)) // Check for duplicate controllers with this ID for(var/thing in pointdefense_controllers) var/obj/machinery/pointdefense_control/PC = thing @@ -211,7 +211,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) /obj/machinery/power/pointdefense/attackby(var/obj/item/W, var/mob/user) if(W?.is_multitool()) var/new_ident = input(user, "Enter a new ident tag.", "[src]", id_tag) as null|text - if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, physical_state)) + if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state)) to_chat(user, "You register [src] with the [new_ident] network.") id_tag = new_ident return diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 1ed44c61bcc..01a890bd79d 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -66,6 +66,7 @@ var/last_fired = FALSE //TRUE: if the turret is cooling down from a shot, FALSE: turret is ready to fire var/shot_delay = 1.5 SECONDS //1.5 seconds between each shot + var/targetting_is_configurable = TRUE // if false, you cannot change who this turret attacks via its UI var/check_arrest = TRUE //checks if the perp is set to arrest var/check_records = TRUE //checks if a security record exists at all var/check_weapons = FALSE //checks if it can shoot people that have a weapon they aren't authorized to have @@ -81,6 +82,7 @@ var/enabled = TRUE //determines if the turret is on var/lethal = FALSE //whether in lethal or stun mode + var/lethal_is_configurable = TRUE // if false, its lethal setting cannot be changed var/disabled = FALSE var/shot_sound //what sound should play when the turret fires @@ -214,6 +216,9 @@ req_one_access = list() installation = /obj/item/weapon/gun/energy/lasertag/omni + targetting_is_configurable = FALSE + lethal_is_configurable = FALSE + locked = FALSE enabled = FALSE anchored = FALSE @@ -262,43 +267,14 @@ if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag) && check_weapons) // Checks if they are a blue player return TURRET_PRIORITY_TARGET -/obj/machinery/porta_turret/lasertag/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - data["access"] = !isLocked(user) - data["locked"] = locked - data["enabled"] = enabled - //data["is_lethal"] = 1 // VOREStation Removal of "Lethal" setting - it does nothing. Rykka did dis. - //data["lethal"] = lethal // VOREStation Removal of "Lethal" setting - it does nothing. Rykka did dis. - - if(data["access"]) - var/settings[0] - settings[++settings.len] = list("category" = "Target Red", "setting" = "check_synth", "value" = check_synth) // Could not get the UI to work with new vars specifically for lasertag turrets -Nalarac - settings[++settings.len] = list("category" = "Target Blue", "setting" = "check_weapons", "value" = check_weapons) // So I'm using these variables since they don't do anything else in this case - data["settings"] = settings - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/porta_turret/lasertag/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["command"] && href_list["value"]) - var/value = text2num(href_list["value"]) - if(href_list["command"] == "enable") - enabled = value - //else if(href_list["command"] == "lethal") // VOREStation Removal of "Lethal" setting - it does nothing. Rykka did dis. - //lethal = value // VOREStation Removal of "Lethal" setting - it does nothing. Rykka did dis. - else if(href_list["command"] == "check_synth") - check_synth = value - else if(href_list["command"] == "check_weapons") - check_weapons = value - - return 1 +/obj/machinery/porta_turret/lasertag/tgui_data(mob/user) + var/list/data = list( + "locked" = isLocked(user), // does the current user have access? + "on" = enabled, // is turret turned on? + "lethal" = lethal, + "lethal_is_configurable" = lethal_is_configurable + ) + return data /obj/machinery/porta_turret/Initialize() //Sets up a spark system @@ -401,102 +377,99 @@ lethal_shot_sound = 'sound/weapons/eluger.ogg' shot_sound = 'sound/weapons/Taser.ogg' -/obj/machinery/porta_turret/proc/isLocked(mob/user) - if(ailock && issilicon(user)) - to_chat(user, "There seems to be a firewall preventing you from accessing this device.") - return 1 - - if(locked && !issilicon(user)) - to_chat(user, "Controls locked.") - return 1 - - return 0 - -/obj/machinery/porta_turret/attack_ai(mob/user) - if(isLocked(user)) - return - - ui_interact(user) - -/obj/machinery/porta_turret/attack_hand(mob/user) - if(isLocked(user)) - return - - ui_interact(user) - -/obj/machinery/porta_turret/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - data["access"] = !isLocked(user) - data["locked"] = locked - data["enabled"] = enabled - data["is_lethal"] = 1 - data["lethal"] = lethal - - if(data["access"]) - var/settings[0] - settings[++settings.len] = list("category" = "Neutralize All Non-Synthetics", "setting" = "check_synth", "value" = check_synth) - settings[++settings.len] = list("category" = "Check Weapon Authorization", "setting" = "check_weapons", "value" = check_weapons) - settings[++settings.len] = list("category" = "Check Security Records", "setting" = "check_records", "value" = check_records) - settings[++settings.len] = list("category" = "Check Arrest Status", "setting" = "check_arrest", "value" = check_arrest) - settings[++settings.len] = list("category" = "Check Access Authorization", "setting" = "check_access", "value" = check_access) - settings[++settings.len] = list("category" = "Check misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies) - settings[++settings.len] = list("category" = "Neutralize All Entities", "setting" = "check_all", "value" = check_all) - settings[++settings.len] = list("category" = "Neutralize Downed Entities", "setting" = "check_down", "value" = check_down) - data["settings"] = settings - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - /obj/machinery/porta_turret/proc/HasController() var/area/A = get_area(src) return A && A.turret_controls.len > 0 -/obj/machinery/porta_turret/CanUseTopic(var/mob/user) +/obj/machinery/porta_turret/proc/isLocked(mob/user) if(HasController()) - to_chat(user, "Turrets can only be controlled using the assigned turret controller.") - return STATUS_CLOSE + return TRUE + if(isrobot(user) || isAI(user)) + if(ailock) + to_chat(user, "There seems to be a firewall preventing you from accessing this device.") + return TRUE + else + return FALSE + if(isobserver(user)) + var/mob/observer/dead/D = user + if(D.can_admin_interact()) + return FALSE + else + return TRUE + if(locked) + return TRUE + return FALSE - if(isLocked(user)) - return STATUS_CLOSE +/obj/machinery/porta_turret/attack_ai(mob/user) + tgui_interact(user) +/obj/machinery/porta_turret/attack_ghost(mob/user) + tgui_interact(user) + +/obj/machinery/porta_turret/attack_hand(mob/user) + tgui_interact(user) + +/obj/machinery/porta_turret/tgui_interact(mob/user, datum/tgui/ui = null) + if(HasController()) + to_chat(user, "[src] can only be controlled using the assigned turret controller.") + return if(!anchored) - to_chat(user, "\The [src] has to be secured first!") - return STATUS_CLOSE + to_chat(user, "[src] has to be secured first!") + return + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PortableTurret", name, 500, 400) + ui.open() - return ..() +/obj/machinery/porta_turret/tgui_data(mob/user) + var/list/data = list( + "locked" = isLocked(user), // does the current user have access? + "on" = enabled, + "targetting_is_configurable" = targetting_is_configurable, // If false, targetting settings don't show up + "lethal" = lethal, + "lethal_is_configurable" = lethal_is_configurable, + "check_weapons" = check_weapons, + "neutralize_noaccess" = check_access, + "neutralize_norecord" = check_records, + "neutralize_criminals" = check_arrest, + "neutralize_all" = check_all, + "neutralize_nonsynth" = check_synth, + "neutralize_unidentified" = check_anomalies, + "neutralize_down" = check_down, + ) + return data -/obj/machinery/porta_turret/Topic(href, href_list) +/obj/machinery/porta_turret/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return 1 + return TRUE + if(isLocked(usr)) + return TRUE + . = TRUE - if(href_list["command"] && href_list["value"]) - var/value = text2num(href_list["value"]) - if(href_list["command"] == "enable") - enabled = value - else if(href_list["command"] == "lethal") - lethal = value - else if(href_list["command"] == "check_synth") - check_synth = value - else if(href_list["command"] == "check_weapons") - check_weapons = value - else if(href_list["command"] == "check_records") - check_records = value - else if(href_list["command"] == "check_arrest") - check_arrest = value - else if(href_list["command"] == "check_access") - check_access = value - else if(href_list["command"] == "check_anomalies") - check_anomalies = value - else if(href_list["command"] == "check_all") - check_all = value - else if(href_list["command"] == "check_down") - check_down = value - - return 1 + switch(action) + if("power") + enabled = !enabled + if("lethal") + if(lethal_is_configurable) + lethal = !lethal + if(targetting_is_configurable) + switch(action) + if("authweapon") + check_weapons = !check_weapons + if("authaccess") + check_access = !check_access + if("authnorecord") + check_records = !check_records + if("autharrest") + check_arrest = !check_arrest + if("authxeno") + check_anomalies = !check_anomalies + if("authsynth") + check_synth = !check_synth + if("authall") + check_all = !check_all + if("authdown") + check_down = !check_down /obj/machinery/porta_turret/power_change() if(powered()) @@ -929,6 +902,7 @@ var/check_weapons var/check_anomalies var/check_all + var/check_down var/ailock /obj/machinery/porta_turret/proc/setState(var/datum/turret_checks/TC) @@ -944,6 +918,7 @@ check_weapons = TC.check_weapons check_anomalies = TC.check_anomalies check_all = TC.check_all + check_down = TC.check_down ailock = TC.ailock power_change() diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index e87de196d96..86b339e6d55 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -104,7 +104,6 @@ var/list/obj/machinery/requests_console/allConsoles = list() /obj/machinery/requests_console/attack_hand(user as mob) if(..(user)) return - ui_interact(user) tgui_interact(user) /obj/machinery/requests_console/tgui_interact(mob/user, datum/tgui/ui) diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 31dd9d2e130..cc8c2628034 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -11,7 +11,7 @@ var/id = null var/one_time_use = 0 //Used for one-time-use teleport cards (such as clown planet coordinates.) //Setting this to 1 will set locked to null after a player enters the portal and will not allow hand-teles to open portals to that location. - var/datum/nano_module/program/teleport_control/teleport_control + var/datum/tgui_module/teleport_control/teleport_control /obj/machinery/computer/teleporter/New() id = "[rand(1000, 9999)]" @@ -44,7 +44,7 @@ teleport_control.station = station /obj/machinery/computer/teleporter/Destroy() - qdel_null(teleport_control) + QDEL_NULL(teleport_control) return ..() /obj/machinery/computer/teleporter/attackby(I as obj, mob/living/user as mob) @@ -96,108 +96,13 @@ attack_hand() /obj/machinery/computer/teleporter/attack_ai(mob/user) - ui_interact(user) + teleport_control.tgui_interact(user) /obj/machinery/computer/teleporter/attack_hand(mob/user) add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - ui_interact(user) - -/obj/machinery/computer/teleporter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - teleport_control.ui_interact(user, ui_key, ui, force_open) - -/obj/machinery/computer/teleporter/interact(mob/user) - teleport_control.ui_interact(user) - -////// -////// Nano-module for teleporter -////// -/datum/nano_module/program/teleport_control - name = "Teleporter Control" - var/locked_name = "Not Locked" - var/obj/item/locked = null - var/obj/machinery/teleport/station/station = null - var/obj/machinery/teleport/hub/hub = null - -/datum/nano_module/program/teleport_control/Topic(href, href_list) - if(..()) return 1 - - if(href_list["select_target"]) - var/list/L = list() - var/list/areaindex = list() - - for(var/obj/item/device/radio/beacon/R in all_beacons) - var/turf/T = get_turf(R) - if(!T) - continue - if(!(T.z in using_map.player_levels)) - continue - var/tmpname = T.loc.name - if(areaindex[tmpname]) - tmpname = "[tmpname] ([++areaindex[tmpname]])" - else - areaindex[tmpname] = 1 - L[tmpname] = R - - for (var/obj/item/weapon/implant/tracking/I in all_tracking_implants) - if(!I.implanted || !ismob(I.loc)) - continue - else - var/mob/M = I.loc - if(M.stat == 2) - if(M.timeofdeath + 6000 < world.time) - continue - var/turf/T = get_turf(M) - if(T) continue - if(T.z == 2) continue - var/tmpname = M.real_name - if(areaindex[tmpname]) - tmpname = "[tmpname] ([++areaindex[tmpname]])" - else - areaindex[tmpname] = 1 - L[tmpname] = I - - var/desc = input("Please select a location to lock in.", "Locking Menu") in L|null - if(!desc) - return 0 - if(get_dist(host, usr) > 1 && !issilicon(usr)) - return 0 - - locked = L[desc] - locked_name = desc - return 1 - - if(href_list["test_fire"]) - station?.testfire() - return 1 - - if(href_list["toggle_on"]) - if(!station) - return 0 - - if(station.engaged) - station.disengage() - else - station.engage() - - return 1 - -/datum/nano_module/program/teleport_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/list/data = host.initial_data() - - data["locked_name"] = locked_name ? locked_name : "No Target" - data["station_connected"] = station ? 1 : 0 - data["hub_connected"] = hub ? 1 : 0 - data["calibrated"] = hub ? hub.accurate : 0 - data["teleporter_on"] = station ? station.engaged : 0 - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "teleport_control.tmpl", "Teleport Control Console", 400, 500, state = state) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + teleport_control.tgui_interact(user) /obj/machinery/computer/teleporter/verb/set_id(t as text) set category = "Object" @@ -211,14 +116,6 @@ id = t return -/proc/find_loc(obj/R as obj) - if(!R) return null - var/turf/T = R.loc - while(!istype(T, /turf)) - T = T.loc - if(!T || istype(T, /area)) return null - return T - ////// ////// Root of all the machinery ////// diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm index a3d10db557c..ad55fe14a17 100644 --- a/code/game/machinery/turret_control.dm +++ b/code/game/machinery/turret_control.dm @@ -11,31 +11,35 @@ desc = "Used to control a room's automated defenses." icon = 'icons/obj/machines/turret_control.dmi' icon_state = "control_standby" - anchored = 1 - density = 0 - var/enabled = 0 - var/lethal = 0 - var/locked = 1 + anchored = TRUE + density = FALSE + var/enabled = FALSE + var/lethal = FALSE + var/lethal_is_configurable = TRUE + var/locked = TRUE var/area/control_area //can be area name, path or nothing. - var/check_arrest = 1 //checks if the perp is set to arrest - var/check_records = 1 //checks if a security record exists at all - var/check_weapons = 0 //checks if it can shoot people that have a weapon they aren't authorized to have - var/check_access = 1 //if this is active, the turret shoots everything that does not meet the access requirements - var/check_anomalies = 1 //checks if it can shoot at unidentified lifeforms (ie xenos) - var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg - var/check_all = 0 //If active, will shoot at anything. - var/ailock = 0 //Silicons cannot use this + var/targetting_is_configurable = TRUE // if false, you cannot change who this turret attacks via its UI + var/check_arrest = TRUE //checks if the perp is set to arrest + var/check_records = TRUE //checks if a security record exists at all + var/check_weapons = FALSE //checks if it can shoot people that have a weapon they aren't authorized to have + var/check_access = TRUE //if this is active, the turret shoots everything that does not meet the access requirements + var/check_anomalies = TRUE //checks if it can shoot at unidentified lifeforms (ie xenos) + var/check_synth = FALSE //if active, will shoot at anything not an AI or cyborg + var/check_all = FALSE //If active, will shoot at anything. + var/check_down = TRUE //If active, won't shoot laying targets. + var/ailock = FALSE //Silicons cannot use this + var/syndicate = FALSE req_access = list(access_ai_upload) /obj/machinery/turretid/stun - enabled = 1 + enabled = TRUE icon_state = "control_stun" /obj/machinery/turretid/lethal - enabled = 1 - lethal = 1 + enabled = TRUE + lethal = TRUE icon_state = "control_kill" /obj/machinery/turretid/Destroy() @@ -67,21 +71,24 @@ . = ..() /obj/machinery/turretid/proc/isLocked(mob/user) - if(ailock && issilicon(user)) - to_chat(user, "There seems to be a firewall preventing you from accessing this device.") - return 1 + if(isrobot(user) || isAI(user)) + if(ailock) + to_chat(user, "There seems to be a firewall preventing you from accessing this device.") + return TRUE + else + return FALSE - if(locked && !issilicon(user)) - to_chat(user, "Access denied.") - return 1 + if(isobserver(user)) + var/mob/observer/dead/D = user + if(D.can_admin_interact()) + return FALSE + else + return TRUE - return 0 + if(locked) + return TRUE -/obj/machinery/turretid/CanUseTopic(mob/user) - if(isLocked(user)) - return STATUS_CLOSE - - return ..() + return FALSE /obj/machinery/turretid/attackby(obj/item/weapon/W, mob/user) if(stat & BROKEN) @@ -100,77 +107,80 @@ /obj/machinery/turretid/emag_act(var/remaining_charges, var/mob/user) if(!emagged) to_chat(user, "You short out the turret controls' access analysis module.") - emagged = 1 - locked = 0 - ailock = 0 - return 1 + emagged = TRUE + locked = FALSE + ailock = FALSE + return TRUE /obj/machinery/turretid/attack_ai(mob/user as mob) - if(isLocked(user)) - return + tgui_interact(user) - ui_interact(user) +/obj/machinery/turretid/attack_ghost(mob/user as mob) + tgui_interact(user) /obj/machinery/turretid/attack_hand(mob/user as mob) - if(isLocked(user)) + tgui_interact(user) + +/obj/machinery/turretid/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PortableTurret", name) // 500, 400 + ui.open() + +/obj/machinery/turretid/tgui_data(mob/user) + var/list/data = list( + "locked" = isLocked(user), // does the current user have access? + "on" = enabled, + "targetting_is_configurable" = targetting_is_configurable, + "lethal" = lethal, + "lethal_is_configurable" = lethal_is_configurable, + "check_weapons" = check_weapons, + "neutralize_noaccess" = check_access, + "one_access" = FALSE, + "selectedAccess" = list(), + "access_is_configurable" = FALSE, + "neutralize_norecord" = check_records, + "neutralize_criminals" = check_arrest, + "neutralize_nonsynth" = check_synth, + "neutralize_all" = check_all, + "neutralize_unidentified" = check_anomalies, + "neutralize_down" = check_down, + ) + return data + +/obj/machinery/turretid/tgui_act(action, params) + if(..()) + return + if(isLocked(usr)) return - ui_interact(user) + . = TRUE + switch(action) + if("power") + enabled = !enabled + if("lethal") + if(lethal_is_configurable) + lethal = !lethal + if(targetting_is_configurable) + switch(action) + if("authweapon") + check_weapons = !check_weapons + if("authaccess") + check_access = !check_access + if("authnorecord") + check_records = !check_records + if("autharrest") + check_arrest = !check_arrest + if("authxeno") + check_anomalies = !check_anomalies + if("authsynth") + check_synth = !check_synth + if("authall") + check_all = !check_all + if("authdown") + check_down = !check_down -/obj/machinery/turretid/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - data["access"] = !isLocked(user) - data["locked"] = locked - data["enabled"] = enabled - data["is_lethal"] = 1 - data["lethal"] = lethal - - if(data["access"]) - var/settings[0] - settings[++settings.len] = list("category" = "Neutralize All Non-Synthetics", "setting" = "check_synth", "value" = check_synth) - settings[++settings.len] = list("category" = "Check Weapon Authorization", "setting" = "check_weapons", "value" = check_weapons) - settings[++settings.len] = list("category" = "Check Security Records", "setting" = "check_records", "value" = check_records) - settings[++settings.len] = list("category" = "Check Arrest Status", "setting" = "check_arrest", "value" = check_arrest) - settings[++settings.len] = list("category" = "Check Access Authorization", "setting" = "check_access", "value" = check_access) - settings[++settings.len] = list("category" = "Check misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies) - settings[++settings.len] = list("category" = "Neutralize All Entities", "setting" = "check_all", "value" = check_all) - - data["settings"] = settings - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/turretid/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["command"] && href_list["value"]) - var/value = text2num(href_list["value"]) - if(href_list["command"] == "enable") - enabled = value - else if(href_list["command"] == "lethal") - lethal = value - else if(href_list["command"] == "check_synth") - check_synth = value - else if(href_list["command"] == "check_weapons") - check_weapons = value - else if(href_list["command"] == "check_records") - check_records = value - else if(href_list["command"] == "check_arrest") - check_arrest = value - else if(href_list["command"] == "check_access") - check_access = value - else if(href_list["command"] == "check_anomalies") - check_anomalies = value - else if(href_list["command"] == "check_all") - check_all = value - - updateTurrets() - return 1 + updateTurrets() /obj/machinery/turretid/proc/updateTurrets() var/datum/turret_checks/TC = new @@ -183,10 +193,11 @@ TC.check_weapons = check_weapons TC.check_anomalies = check_anomalies TC.check_all = check_all + TC.check_down = check_down TC.ailock = ailock if(istype(control_area)) - for (var/obj/machinery/porta_turret/aTurret in control_area) + for(var/obj/machinery/porta_turret/aTurret in control_area) aTurret.setState(TC) update_icon() diff --git a/code/game/machinery/vitals_monitor.dm b/code/game/machinery/vitals_monitor.dm index a26c3ff706e..e6d1ba58114 100644 --- a/code/game/machinery/vitals_monitor.dm +++ b/code/game/machinery/vitals_monitor.dm @@ -144,6 +144,6 @@ if(!istype(user)) return - if(CanInteract(user, physical_state)) + if(CanInteract(user, GLOB.tgui_physical_state)) beep = !beep to_chat(user, "You turn the sound on \the [src] [beep ? "on" : "off"].") diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index a6aafb577eb..b1aa1fb888d 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -559,12 +559,12 @@ target.attack_hand(src.occupant) return 1 if(istype(target, /obj/machinery/embedded_controller)) - target.ui_interact(src.occupant) + target.tgui_interact(src.occupant) return 1 return 0 -/obj/mecha/contents_nano_distance(var/src_object, var/mob/living/user) - . = user.shared_living_nano_distance(src_object) //allow them to interact with anything they can interact with normally. +/obj/mecha/contents_tgui_distance(var/src_object, var/mob/living/user) + . = user.shared_living_tgui_distance(src_object) //allow them to interact with anything they can interact with normally. if(. != STATUS_INTERACTIVE) //Allow interaction with the mecha or anything that is part of the mecha if(src_object == src || (src_object in src)) diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm index edcfde30748..358ef3b61b6 100644 --- a/code/game/objects/items/devices/communicator/communicator.dm +++ b/code/game/objects/items/devices/communicator/communicator.dm @@ -233,7 +233,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list() initialize_exonet(user) alert_called = 0 update_icon() - ui_interact(user) // TGUITODO: Remove tgui_interact(user) if(video_source) watch_video(user) diff --git a/code/game/objects/items/devices/hacktool.dm b/code/game/objects/items/devices/hacktool.dm index da1c165e9e6..b221ff875c3 100644 --- a/code/game/objects/items/devices/hacktool.dm +++ b/code/game/objects/items/devices/hacktool.dm @@ -5,7 +5,7 @@ var/in_hack_mode = 0 var/list/known_targets var/list/supported_types - var/datum/topic_state/default/must_hack/hack_state + var/datum/tgui_state/default/must_hack/hack_state /obj/item/device/multitool/hacktool/New() ..() @@ -39,7 +39,8 @@ if(!attempt_hack(user, A)) return 0 - A.ui_interact(user, state = hack_state) + // Note, if you ever want to expand supported_types, you must manually add the custom state argument to their tgui_interact + A.tgui_interact(user, custom_state = hack_state) return 1 /obj/item/device/multitool/hacktool/proc/attempt_hack(var/mob/user, var/atom/target) @@ -83,18 +84,18 @@ /obj/item/device/multitool/hacktool/proc/on_target_destroy(var/target) known_targets -= target -/datum/topic_state/default/must_hack +/datum/tgui_state/default/must_hack var/obj/item/device/multitool/hacktool/hacktool -/datum/topic_state/default/must_hack/New(var/hacktool) +/datum/tgui_state/default/must_hack/New(var/hacktool) src.hacktool = hacktool ..() -/datum/topic_state/default/must_hack/Destroy() +/datum/tgui_state/default/must_hack/Destroy() hacktool = null return ..() -/datum/topic_state/default/must_hack/can_use_topic(var/src_object, var/mob/user) +/datum/tgui_state/default/must_hack/can_use_topic(src_object, mob/user) if(!hacktool || !hacktool.in_hack_mode || !(src_object in hacktool.known_targets)) return STATUS_CLOSE return ..() diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index f1990c7fe2d..d2511038dcc 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -151,18 +151,10 @@ var/global/list/default_medbay_channels = list( return tgui_interact(user) -/obj/item/device/radio/ui_interact(mob/user, ui_key, datum/nanoui/ui, force_open, datum/nano_ui/master_ui, datum/topic_state/state) - log_runtime(EXCEPTION("Warning: [user] attempted to call ui_interact on radio [src] [type]. This is deprecated. Please update the caller to tgui_interact.")) - -/obj/item/device/radio/Topic(href, href_list) - if(href_list["track"]) - log_runtime(EXCEPTION("Warning: Topic() was improperly called on radio [src] [type], with the track href and \[[href] [json_encode(href_list)]]. Please update the caller to use tgui_act.")) - . = ..() - -/obj/item/device/radio/tgui_interact(mob/user, datum/tgui/ui) +/obj/item/device/radio/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, "Radio", name) + ui = new(user, src, "Radio", name, parent_ui) ui.open() /obj/item/device/radio/tgui_data(mob/user) diff --git a/code/game/objects/items/devices/tvcamera.dm b/code/game/objects/items/devices/tvcamera.dm index e8b6df0b981..acf4b7cc3a9 100644 --- a/code/game/objects/items/devices/tvcamera.dm +++ b/code/game/objects/items/devices/tvcamera.dm @@ -54,7 +54,7 @@ popup.set_content(jointext(dat,null)) popup.open() -/obj/item/device/tvcamera/Topic(bred, href_list, state = physical_state) +/obj/item/device/tvcamera/Topic(bred, href_list, state = GLOB.tgui_physical_state) if(..()) return 1 if(href_list["channel"]) diff --git a/code/game/objects/items/weapons/id cards/syndicate_ids.dm b/code/game/objects/items/weapons/id cards/syndicate_ids.dm index 68cb0298a49..afb85ecb7a5 100644 --- a/code/game/objects/items/weapons/id cards/syndicate_ids.dm +++ b/code/game/objects/items/weapons/id cards/syndicate_ids.dm @@ -6,8 +6,11 @@ var/electronic_warfare = 1 var/mob/registered_user = null + var/datum/tgui_module/agentcard/agentcard_module + /obj/item/weapon/card/id/syndicate/Initialize() . = ..() + agentcard_module = new(src) access = syndicate_access.Copy() /obj/item/weapon/card/id/syndicate/station_access/Initialize() @@ -15,6 +18,7 @@ access |= get_all_station_access() /obj/item/weapon/card/id/syndicate/Destroy() + QDEL_NULL(agentcard_module) unset_registered_user(registered_user) return ..() @@ -36,33 +40,12 @@ if(registered_user == user) switch(alert("Would you like edit the ID, or show it?","Show or Edit?", "Edit","Show")) if("Edit") - ui_interact(user) + agentcard_module.tgui_interact(user) if("Show") ..() else ..() -/obj/item/weapon/card/id/syndicate/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - var/entries[0] - entries[++entries.len] = list("name" = "Age", "value" = age) - entries[++entries.len] = list("name" = "Appearance", "value" = "Set") - entries[++entries.len] = list("name" = "Assignment", "value" = assignment) - entries[++entries.len] = list("name" = "Blood Type", "value" = blood_type) - entries[++entries.len] = list("name" = "DNA Hash", "value" = dna_hash) - entries[++entries.len] = list("name" = "Fingerprint Hash", "value" = fingerprint_hash) - entries[++entries.len] = list("name" = "Name", "value" = registered_name) - entries[++entries.len] = list("name" = "Photo", "value" = "Update") - entries[++entries.len] = list("name" = "Sex", "value" = sex) - entries[++entries.len] = list("name" = "Factory Reset", "value" = "Use With Care") - data["electronic_warfare"] = electronic_warfare - data["entries"] = entries - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "agent_id_card.tmpl", "Fake ID", 600, 400) - ui.set_initial_data(data) - ui.open() /obj/item/weapon/card/id/syndicate/proc/register_user(var/mob/user) if(!istype(user) || user == registered_user) @@ -79,114 +62,6 @@ registered_user.unregister(OBSERVER_EVENT_DESTROY, src) registered_user = null -/obj/item/weapon/card/id/syndicate/CanUseTopic(mob/user) - if(user != registered_user) - return STATUS_CLOSE - return ..() - -/obj/item/weapon/card/id/syndicate/Topic(href, href_list, var/datum/topic_state/state) - if(..()) - return 1 - - var/user = usr - if(href_list["electronic_warfare"]) - electronic_warfare = text2num(href_list["electronic_warfare"]) - to_chat(user, "Electronic warfare [electronic_warfare ? "enabled" : "disabled"].") - else if(href_list["set"]) - switch(href_list["set"]) - if("Age") - var/new_age = input(user,"What age would you like to put on this card?","Agent Card Age", age) as null|num - if(!isnull(new_age) && CanUseTopic(user, state)) - if(new_age < 0) - age = initial(age) - else - age = new_age - to_chat(user, "Age has been set to '[age]'.") - . = 1 - if("Appearance") - var/datum/card_state/choice = input(user, "Select the appearance for this card.", "Agent Card Appearance") as null|anything in id_card_states() - if(choice && CanUseTopic(user, state)) - src.icon_state = choice.icon_state - src.item_state = choice.item_state - to_chat(usr, "Appearance changed to [choice].") - . = 1 - if("Assignment") - var/new_job = sanitize(input(user,"What assignment would you like to put on this card?\nChanging assignment will not grant or remove any access levels.","Agent Card Assignment", assignment) as null|text) - if(!isnull(new_job) && CanUseTopic(user, state)) - src.assignment = new_job - to_chat(user, "Occupation changed to '[new_job]'.") - update_name() - . = 1 - if("Blood Type") - var/default = blood_type - if(default == initial(blood_type) && ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.dna) - default = H.dna.b_type - var/new_blood_type = sanitize(input(user,"What blood type would you like to be written on this card?","Agent Card Blood Type",default) as null|text) - if(!isnull(new_blood_type) && CanUseTopic(user, state)) - src.blood_type = new_blood_type - to_chat(user, "Blood type changed to '[new_blood_type]'.") - . = 1 - if("DNA Hash") - var/default = dna_hash - if(default == initial(dna_hash) && ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.dna) - default = H.dna.unique_enzymes - var/new_dna_hash = sanitize(input(user,"What DNA hash would you like to be written on this card?","Agent Card DNA Hash",default) as null|text) - if(!isnull(new_dna_hash) && CanUseTopic(user, state)) - src.dna_hash = new_dna_hash - to_chat(user, "DNA hash changed to '[new_dna_hash]'.") - . = 1 - if("Fingerprint Hash") - var/default = fingerprint_hash - if(default == initial(fingerprint_hash) && ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.dna) - default = md5(H.dna.uni_identity) - var/new_fingerprint_hash = sanitize(input(user,"What fingerprint hash would you like to be written on this card?","Agent Card Fingerprint Hash",default) as null|text) - if(!isnull(new_fingerprint_hash) && CanUseTopic(user, state)) - src.fingerprint_hash = new_fingerprint_hash - to_chat(user, "Fingerprint hash changed to '[new_fingerprint_hash]'.") - . = 1 - if("Name") - var/new_name = sanitizeName(input(user,"What name would you like to put on this card?","Agent Card Name", registered_name) as null|text) - if(!isnull(new_name) && CanUseTopic(user, state)) - src.registered_name = new_name - update_name() - to_chat(user, "Name changed to '[new_name]'.") - . = 1 - if("Photo") - set_id_photo(user) - to_chat(user, "Photo changed.") - . = 1 - if("Sex") - var/new_sex = sanitize(input(user,"What sex would you like to put on this card?","Agent Card Sex", sex) as null|text) - if(!isnull(new_sex) && CanUseTopic(user, state)) - src.sex = new_sex - to_chat(user, "Sex changed to '[new_sex]'.") - . = 1 - if("Factory Reset") - if(alert("This will factory reset the card, including access and owner. Continue?", "Factory Reset", "No", "Yes") == "Yes" && CanUseTopic(user, state)) - age = initial(age) - access = syndicate_access.Copy() - assignment = initial(assignment) - blood_type = initial(blood_type) - dna_hash = initial(dna_hash) - electronic_warfare = initial(electronic_warfare) - fingerprint_hash = initial(fingerprint_hash) - icon_state = initial(icon_state) - name = initial(name) - registered_name = initial(registered_name) - unset_registered_user() - sex = initial(sex) - to_chat(user, "All information has been deleted from \the [src].") - . = 1 - - // Always update the UI, or buttons will spin indefinitely - SSnanoui.update_uis(src) - /var/global/list/id_card_states /proc/id_card_states() if(!id_card_states) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 9bca1c29331..688236eda85 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -42,7 +42,7 @@ old_turf.unregister_dangerous_object(src) new_turf.register_dangerous_object(src) -/obj/Topic(href, href_list, var/datum/topic_state/state = default_state) +/obj/Topic(href, href_list, var/datum/tgui_state/state = GLOB.tgui_default_state) if(usr && ..()) return 1 @@ -55,7 +55,7 @@ CouldNotUseTopic(usr) return 1 -/obj/CanUseTopic(var/mob/user, var/datum/topic_state/state = default_state) +/obj/CanUseTopic(var/mob/user, var/datum/tgui_state/state = GLOB.tgui_default_state) if(user.CanUseObjTopic(src)) return ..() to_chat(user, "[bicon(src)]Access Denied!") @@ -69,7 +69,7 @@ return 1 /obj/proc/CouldUseTopic(var/mob/user) - var/atom/host = nano_host() + var/atom/host = tgui_host() host.add_hiddenprint(user) /obj/proc/CouldNotUseTopic(var/mob/user) @@ -135,7 +135,6 @@ in_use = 0 /obj/attack_ghost(mob/user) - ui_interact(user) tgui_interact(user) ..() diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index fad039445ed..a6dc8e42ac4 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -20,8 +20,90 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) var/has_items = FALSE var/dismantled = TRUE var/signs = 0 //maximum capacity hardcoded below + var/list/tgui_icons = list() + var/static/list/equippable_item_whitelist +/obj/structure/janitorialcart/proc/equip_janicart_item(mob/user, obj/item/I) + if(!equippable_item_whitelist) + equippable_item_whitelist = typecacheof(list( + /obj/item/weapon/storage/bag/trash, + /obj/item/weapon/mop, + /obj/item/weapon/reagent_containers/spray, + /obj/item/device/lightreplacer, + /obj/item/clothing/suit/caution, + )) + + if(!is_type_in_typecache(I, equippable_item_whitelist)) + to_chat(user, "There's no room in [src] for [I].") + return FALSE + + if(!user.unEquip(I, 0, src)) + to_chat(user, "[I] is stuck to your hand.") + return FALSE + + if(istype(I, /obj/item/weapon/storage/bag/trash)) + if(mybag) + to_chat(user, "[src] already has \an [I].") + return FALSE + mybag = I + setTguiIcon("mybag", mybag) + + else if(istype(I, /obj/item/weapon/mop)) + if(mymop) + to_chat(user, "[src] already has \an [I].") + return FALSE + mymop = I + setTguiIcon("mymop", mymop) + + else if(istype(I, /obj/item/weapon/reagent_containers/spray)) + if(myspray) + to_chat(user, "[src] already has \an [I].") + return FALSE + myspray = I + setTguiIcon("myspray", myspray) + + else if(istype(I, /obj/item/device/lightreplacer)) + if(myreplacer) + to_chat(user, "[src] already has \an [I].") + return FALSE + myreplacer = I + setTguiIcon("myreplacer", myreplacer) + + else if(istype(I, /obj/item/clothing/suit/caution)) + if(signs < 4) + signs++ + setTguiIcon("signs", I) + else + to_chat(user, "[src] can't hold any more signs.") + return FALSE + else + // This may look like duplicate code, but it's important that we don't call unEquip *and* warn the user if + // something horrible goes wrong. (this else is never supposed to happen) + to_chat(user, "There's no room in [src] for [I].") + return FALSE + + update_icon() + to_chat(user, "You put [I] into [src].") + return TRUE + +/obj/structure/janitorialcart/proc/setTguiIcon(key, atom/A) + if(!istype(A) || !key) + return + + var/icon/F = getFlatIcon(A, defdir = SOUTH, no_anim = TRUE) + tgui_icons["[key]"] = "'data:image/png;base64,[icon2base64(F)]'" + SStgui.update_uis(src) + +/obj/structure/janitorialcart/proc/nullTguiIcon(key) + if(!key) + return + tgui_icons.Remove(key) + SStgui.update_uis(src) + +/obj/structure/janitorialcart/proc/clearTguiIcons() + tgui_icons.Cut() + SStgui.update_uis(src) /obj/structure/janitorialcart/Destroy() QDEL_NULL(mybag) @@ -29,6 +111,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) QDEL_NULL(myspray) QDEL_NULL(myreplacer) QDEL_NULL(mybucket) + clearTguiIcons() return ..() /obj/structure/janitorialcart/examine(mob/user) @@ -43,6 +126,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) if (istype(O, /obj/structure/mopbucket) && !mybucket) O.forceMove(src) mybucket = O + setTguiIcon("mybucket", mybucket) to_chat(user, "You mount the [O] on the janicart.") update_icon() else @@ -70,38 +154,19 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) return 1 else if(istype(I, /obj/item/weapon/reagent_containers/spray) && !myspray) - user.unEquip(I, 0, src) - myspray = I - update_icon() - updateUsrDialog() - to_chat(user, "You put [I] into [src].") + equip_janicart_item(user, I) return 1 else if(istype(I, /obj/item/device/lightreplacer) && !myreplacer) - user.unEquip(I, 0, src) - myreplacer = I - update_icon() - updateUsrDialog() - to_chat(user, "You put [I] into [src].") + equip_janicart_item(user, I) return 1 else if(istype(I, /obj/item/weapon/storage/bag/trash) && !mybag) - user.unEquip(I, 0, src) - mybag = I - update_icon() - updateUsrDialog() - to_chat(user, "You put [I] into [src].") + equip_janicart_item(user, I) return 1 else if(istype(I, /obj/item/clothing/suit/caution)) - if(signs < 4) - user.unEquip(I, 0, src) - signs++ - update_icon() - updateUsrDialog() - to_chat(user, "You put [I] into [src].") - else - to_chat(user, "[src] can't hold any more signs.") + equip_janicart_item(user, I) return 1 else if(mybag) @@ -124,16 +189,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) if(user.incapacitated() || !Adjacent(user)) return var/obj/I = usr.get_active_hand() if(istype(I, /obj/item/weapon/mop)) - if(!mymop) - usr.drop_from_inventory(I,src) - mymop = I - update_icon() - updateUsrDialog() - to_chat(usr, "You put [I] into [src].") - update_icon() - else - to_chat(usr, "The cart already has a mop attached") - return + equip_janicart_item(user, I) else if(istype(I, /obj/item/weapon/reagent_containers) && mybucket) var/obj/item/weapon/reagent_containers/C = I C.afterattack(mybucket, usr, 1) @@ -141,75 +197,95 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) /obj/structure/janitorialcart/attack_hand(mob/user) - ui_interact(user) + tgui_interact(user) return -/obj/structure/janitorialcart/ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = TRUE) - var/data[0] - data["name"] = capitalize(name) - data["bag"] = mybag ? capitalize(mybag.name) : null - data["bucket"] = mybucket ? capitalize(mybucket.name) : null - data["mop"] = mymop ? capitalize(mymop.name) : null - data["spray"] = myspray ? capitalize(myspray.name) : null - data["replacer"] = myreplacer ? capitalize(myreplacer.name) : null - data["signs"] = signs ? "[signs] sign\s" : null - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) +/obj/structure/janitorialcart/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "janitorcart.tmpl", "Janitorial cart", 240, 160) - ui.set_initial_data(data) + ui = new(user, src, "JanitorCart", name) // 240, 160 + ui.set_autoupdate(FALSE) ui.open() +/obj/structure/janitorialcart/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() -/obj/structure/janitorialcart/Topic(href, href_list) - if(!in_range(src, usr)) - return - if(!isliving(usr)) - return - var/mob/living/user = usr + data["mybag"] = mybag ? capitalize(mybag.name) : null + data["mybucket"] = mybucket ? capitalize(mybucket.name) : null + data["mymop"] = mymop ? capitalize(mymop.name) : null + data["myspray"] = myspray ? capitalize(myspray.name) : null + data["myreplacer"] = myreplacer ? capitalize(myreplacer.name) : null + data["signs"] = signs ? "[signs] sign\s" : null - if(href_list["take"]) - switch(href_list["take"]) - if("garbage") - if(mybag) - user.put_in_hands(mybag) - to_chat(user, "You take [mybag] from [src].") - mybag = null - if("mop") - if(mymop) - user.put_in_hands(mymop) - to_chat(user, "You take [mymop] from [src].") - mymop = null - if("spray") - if(myspray) - user.put_in_hands(myspray) - to_chat(user, "You take [myspray] from [src].") - myspray = null - if("replacer") - if(myreplacer) - user.put_in_hands(myreplacer) - to_chat(user, "You take [myreplacer] from [src].") - myreplacer = null - if("sign") - if(signs) - var/obj/item/clothing/suit/caution/Sign = locate() in src - if(Sign) - user.put_in_hands(Sign) - to_chat(user, "You take \a [Sign] from [src].") - signs-- - else - warning("[src] signs ([signs]) didn't match contents") - signs = 0 - if("bucket") - if(mybucket) - mybucket.forceMove(get_turf(user)) - to_chat(user, "You unmount [mybucket] from [src].") - mybucket = null + data["icons"] = tgui_icons + return data + +/obj/structure/janitorialcart/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + var/obj/item/I = usr.get_active_hand() + + switch(action) + if("bag") + if(mybag) + usr.put_in_hands(mybag) + to_chat(usr, "You take [mybag] from [src].") + mybag = null + nullTguiIcon("mybag") + else if(is_type_in_typecache(I, equippable_item_whitelist)) + equip_janicart_item(usr, I) + if("mop") + if(mymop) + usr.put_in_hands(mymop) + to_chat(usr, "You take [mymop] from [src].") + mymop = null + nullTguiIcon("mymop") + else if(is_type_in_typecache(I, equippable_item_whitelist)) + equip_janicart_item(usr, I) + if("spray") + if(myspray) + usr.put_in_hands(myspray) + to_chat(usr, "You take [myspray] from [src].") + myspray = null + nullTguiIcon("myspray") + else if(is_type_in_typecache(I, equippable_item_whitelist)) + equip_janicart_item(usr, I) + if("replacer") + if(myreplacer) + usr.put_in_hands(myreplacer) + to_chat(usr, "You take [myreplacer] from [src].") + myreplacer = null + nullTguiIcon("myreplacer") + else if(is_type_in_typecache(I, equippable_item_whitelist)) + equip_janicart_item(usr, I) + if("sign") + if(istype(I, /obj/item/clothing/suit/caution) && signs < 4) + equip_janicart_item(usr, I) + else if(signs) + var/obj/item/clothing/suit/caution/sign = locate() in src + if(sign) + usr.put_in_hands(sign) + to_chat(usr, "You take \a [sign] from [src].") + signs-- + if(!signs) + nullTguiIcon("signs") + else + to_chat(usr, "[src] doesn't have any signs left.") + if("bucket") + if(mybucket) + mybucket.forceMove(get_turf(usr)) + to_chat(usr, "You unmount [mybucket] from [src].") + mybucket = null + nullTguiIcon("mybucket") + else + to_chat(usr, "((Drag and drop a mop bucket onto [src] to equip it.))") + return FALSE + else + return FALSE update_icon() - updateUsrDialog() - - + return TRUE /obj/structure/janitorialcart/update_icon() overlays.Cut() @@ -229,11 +305,6 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) if(signs) overlays += "cart_sign[signs]" - - - - - //This is called if the cart is caught in an explosion, or destroyed by weapon fire /obj/structure/janitorialcart/proc/spill(var/chance = 100) var/turf/dropspot = get_turf(src) @@ -275,6 +346,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) mybag = null update_icon() + clearTguiIcons() diff --git a/code/game/objects/structures/under_wardrobe.dm b/code/game/objects/structures/under_wardrobe.dm index cb5db5411da..c919663eaa6 100644 --- a/code/game/objects/structures/under_wardrobe.dm +++ b/code/game/objects/structures/under_wardrobe.dm @@ -67,7 +67,7 @@ if(!UWC) return var/datum/category_item/underwear/selected_underwear = input(H, "Choose underwear:", "Choose underwear", H.all_underwear[UWC.name]) as null|anything in UWC.items - if(selected_underwear && CanUseTopic(H, default_state)) + if(selected_underwear && CanUseTopic(H, GLOB.tgui_default_state)) H.all_underwear[UWC.name] = selected_underwear H.hide_underwear[UWC.name] = FALSE . = TRUE diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index df3e6956283..bb43597d952 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -433,45 +433,6 @@ // Insert("polycrystal", 'icons/obj/telescience.dmi', "polycrystal") // ..() -/datum/asset/nanoui - var/list/common = list() - - var/list/common_dirs = list( - "nano/css/", - "nano/images/", - "nano/images/modular_computers/", - "nano/js/" - ) - var/list/template_dirs = list( - "nano/templates/" - ) - -/datum/asset/nanoui/register() - // Crawl the directories to find files. - for(var/path in common_dirs) - var/list/filenames = flist(path) - for(var/filename in filenames) - if(copytext(filename, length(filename)) != "/") // Ignore directories. - if(fexists(path + filename)) - common[filename] = fcopy_rsc(path + filename) - register_asset(filename, common[filename]) - // Combine all templates into a single bundle. - var/list/template_data = list() - for(var/path in template_dirs) - var/list/filenames = flist(path) - for(var/filename in filenames) - if(copytext(filename, length(filename) - 4) == ".tmpl") // Ignore directories. - template_data[filename] = file2text(path + filename) - var/template_bundle = "function nanouiTemplateBundle(){return [json_encode(template_data)];}" - var/fname = "data/nano_templates_bundle.js" - fdel(fname) - text2file(template_bundle, fname) - register_asset("nano_templates_bundle.js", fcopy_rsc(fname)) - fdel(fname) - -/datum/asset/nanoui/send(client) - send_asset_list(client, common) - //Pill sprites for UIs /datum/asset/chem_master var/assets = list() @@ -522,4 +483,29 @@ /datum/asset/spritesheet/sheetmaterials/register() InsertAll("", 'icons/obj/stacks.dmi') - ..() \ No newline at end of file + ..() + +// Nanomaps +/datum/asset/simple/nanomaps + // It REALLY doesnt matter too much if these arent up to date + // They are relatively big + assets = list( + "southern_cross_nanomap_z1.png" = 'icons/_nanomaps/southern_cross_nanomap_z1.png', + "southern_cross_nanomap_z10.png" = 'icons/_nanomaps/southern_cross_nanomap_z10.png', + "southern_cross_nanomap_z2.png" = 'icons/_nanomaps/southern_cross_nanomap_z2.png', + "southern_cross_nanomap_z3.png" = 'icons/_nanomaps/southern_cross_nanomap_z3.png', + "southern_cross_nanomap_z5.png" = 'icons/_nanomaps/southern_cross_nanomap_z5.png', + "southern_cross_nanomap_z6.png" = 'icons/_nanomaps/southern_cross_nanomap_z6.png', + "tether_nanomap_z1.png" = 'icons/_nanomaps/tether_nanomap_z1.png', + "tether_nanomap_z10.png" = 'icons/_nanomaps/tether_nanomap_z10.png', + "tether_nanomap_z13.png" = 'icons/_nanomaps/tether_nanomap_z13.png', + "tether_nanomap_z14.png" = 'icons/_nanomaps/tether_nanomap_z14.png', + "tether_nanomap_z2.png" = 'icons/_nanomaps/tether_nanomap_z2.png', + "tether_nanomap_z3.png" = 'icons/_nanomaps/tether_nanomap_z3.png', + "tether_nanomap_z4.png" = 'icons/_nanomaps/tether_nanomap_z4.png', + "tether_nanomap_z5.png" = 'icons/_nanomaps/tether_nanomap_z5.png', + "tether_nanomap_z6.png" = 'icons/_nanomaps/tether_nanomap_z6.png', + "tether_nanomap_z7.png" = 'icons/_nanomaps/tether_nanomap_z7.png', + "tether_nanomap_z8.png" = 'icons/_nanomaps/tether_nanomap_z8.png', + "tether_nanomap_z9.png" = 'icons/_nanomaps/tether_nanomap_z9.png', + ) \ No newline at end of file diff --git a/code/modules/clothing/glasses/hud_vr.dm b/code/modules/clothing/glasses/hud_vr.dm index 613c09e91e4..718b9e6908f 100644 --- a/code/modules/clothing/glasses/hud_vr.dm +++ b/code/modules/clothing/glasses/hud_vr.dm @@ -8,8 +8,6 @@ var/obj/item/clothing/glasses/hud/omni/hud = null var/mode = "civ" icon_state = "glasses" - var/datum/nano_module/arscreen - var/arscreen_path var/datum/tgui_module/tgarscreen var/tgarscreen_path var/flash_prot = 0 //0 for none, 1 for flash weapon protection, 2 for welder protection @@ -18,34 +16,24 @@ /obj/item/clothing/glasses/omnihud/New() ..() - if(arscreen_path) - arscreen = new arscreen_path(src) if(tgarscreen_path) tgarscreen = new tgarscreen_path(src) /obj/item/clothing/glasses/omnihud/Destroy() - QDEL_NULL(arscreen) QDEL_NULL(tgarscreen) . = ..() /obj/item/clothing/glasses/omnihud/dropped() - if(arscreen) - SSnanoui.close_uis(src) if(tgarscreen) SStgui.close_uis(src) ..() /obj/item/clothing/glasses/omnihud/emp_act(var/severity) - if(arscreen) - SSnanoui.close_uis(src) if(tgarscreen) SStgui.close_uis(src) - var/disconnect_ar = arscreen var/disconnect_tgar = tgarscreen - arscreen = null tgarscreen = null spawn(20 SECONDS) - arscreen = disconnect_ar tgarscreen = disconnect_tgar //extra fun for non-sci variants; a small chance flip the state to the dumb 3d glasses when EMP'd diff --git a/code/modules/clothing/spacesuits/rig/modules/computer.dm b/code/modules/clothing/spacesuits/rig/modules/computer.dm index cf055ae9c08..fbf08479f49 100644 --- a/code/modules/clothing/spacesuits/rig/modules/computer.dm +++ b/code/modules/clothing/spacesuits/rig/modules/computer.dm @@ -23,7 +23,7 @@ to_chat(usr, "Your module is not installed in a hardsuit.") return - module.holder.ui_interact(usr, nano_state = contained_state) + module.holder.tgui_interact(usr, custom_state = GLOB.tgui_contained_state) /obj/item/rig_module/ai_container diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm b/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm index e6848a66d0d..4f7dfef043e 100644 --- a/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm +++ b/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm @@ -134,7 +134,7 @@ if(!target) if(ai_card) if(istype(ai_card,/obj/item/device/aicard)) - ai_card.tgui_interact(H, custom_state = deep_inventory_state) + ai_card.tgui_interact(H, custom_state = GLOB.tgui_deep_inventory_state) else eject_ai(H) update_verb_holder() diff --git a/code/modules/economy/Accounts_DB.dm b/code/modules/economy/Accounts_DB.dm index 9e116ecf60d..68f71184e99 100644 --- a/code/modules/economy/Accounts_DB.dm +++ b/code/modules/economy/Accounts_DB.dm @@ -15,7 +15,7 @@ var/const/fund_cap = 1000000 /obj/machinery/account_database/proc/get_access_level() - if (!held_card) + if(!held_card) return 0 if(access_cent_captain in held_card.access) return 2 @@ -53,19 +53,24 @@ O.loc = src held_card = O - SSnanoui.update_uis(src) + SStgui.update_uis(src) attack_hand(user) /obj/machinery/account_database/attack_hand(mob/user as mob) if(stat & (NOPOWER|BROKEN)) return - ui_interact(user) + tgui_interact(user) -/obj/machinery/account_database/ui_interact(mob/user, ui_key="main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) +/obj/machinery/account_database/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AccountsTerminal", name) + ui.open() + + +/obj/machinery/account_database/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() - var/data[0] - data["src"] = "\ref[src]" data["id_inserted"] = !!held_card data["id_card"] = held_card ? text("[held_card.registered_name], [held_card.assignment]") : "-----" data["access_level"] = get_access_level() @@ -73,10 +78,14 @@ data["creating_new_account"] = creating_new_account data["detailed_account_view"] = !!detailed_account_view data["station_account_number"] = station_account.account_number - data["transactions"] = null - data["accounts"] = null - if (detailed_account_view) + data["account_number"] = null + data["owner_name"] = null + data["money"] = null + data["suspended"] = null + data["transactions"] = list() + + if(detailed_account_view) data["account_number"] = detailed_account_view.account_number data["owner_name"] = detailed_account_view.owner_name data["money"] = detailed_account_view.money @@ -92,11 +101,10 @@ "amount" = T.amount, \ "source_terminal" = T.source_terminal))) - if (trx.len > 0) - data["transactions"] = trx + data["transactions"] = trx - var/list/accounts[0] - for(var/i=1, i<=all_money_accounts.len, i++) + var/list/accounts = list() + for(var/i in 1 to LAZYLEN(all_money_accounts)) var/datum/money_account/D = all_money_accounts[i] if(D.offmap) continue @@ -106,174 +114,168 @@ "suspended"=D.suspended ? "SUSPENDED" : "",\ "account_index"=i))) - if (accounts.len > 0) - data["accounts"] = accounts + data["accounts"] = accounts - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "accounts_terminal.tmpl", src.name, 400, 640) - ui.set_initial_data(data) - ui.open() + return data -/obj/machinery/account_database/Topic(href, href_list) +/obj/machinery/account_database/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return 1 + return TRUE - var/datum/nanoui/ui = SSnanoui.get_open_ui(usr, src, "main") + switch(action) + if("create_account") + creating_new_account = 1 - if(href_list["choice"]) - switch(href_list["choice"]) - if("create_account") - creating_new_account = 1 + if("add_funds") + var/amount = input("Enter the amount you wish to add", "Silently add funds") as num + if(detailed_account_view) + detailed_account_view.money = min(detailed_account_view.money + amount, fund_cap) - if("add_funds") - var/amount = input("Enter the amount you wish to add", "Silently add funds") as num - if(detailed_account_view) - detailed_account_view.money = min(detailed_account_view.money + amount, fund_cap) + if("remove_funds") + var/amount = input("Enter the amount you wish to remove", "Silently remove funds") as num + if(detailed_account_view) + detailed_account_view.money = max(detailed_account_view.money - amount, -fund_cap) - if("remove_funds") - var/amount = input("Enter the amount you wish to remove", "Silently remove funds") as num - if(detailed_account_view) - detailed_account_view.money = max(detailed_account_view.money - amount, -fund_cap) + if("toggle_suspension") + if(detailed_account_view) + detailed_account_view.suspended = !detailed_account_view.suspended + callHook("change_account_status", list(detailed_account_view)) - if("toggle_suspension") - if(detailed_account_view) - detailed_account_view.suspended = !detailed_account_view.suspended - callHook("change_account_status", list(detailed_account_view)) + if("finalise_create_account") + var/account_name = params["holder_name"] + var/starting_funds = max(text2num(params["starting_funds"]), 0) - if("finalise_create_account") - var/account_name = href_list["holder_name"] - var/starting_funds = max(text2num(href_list["starting_funds"]), 0) + starting_funds = CLAMP(starting_funds, 0, station_account.money) // Not authorized to put the station in debt. + starting_funds = min(starting_funds, fund_cap) // Not authorized to give more than the fund cap. - starting_funds = CLAMP(starting_funds, 0, station_account.money) // Not authorized to put the station in debt. - starting_funds = min(starting_funds, fund_cap) // Not authorized to give more than the fund cap. + create_account(account_name, starting_funds, src) + if(starting_funds > 0) + //subtract the money + station_account.money -= starting_funds - create_account(account_name, starting_funds, src) - if(starting_funds > 0) - //subtract the money - station_account.money -= starting_funds - - //create a transaction log entry - var/trx = create_transation(account_name, "New account activation", "([starting_funds])") - station_account.transaction_log.Add(trx) - - creating_new_account = 0 - ui.close() + //create a transaction log entry + var/trx = create_transation(account_name, "New account activation", "([starting_funds])") + station_account.transaction_log.Add(trx) creating_new_account = 0 - if("insert_card") - if(held_card) - held_card.loc = src.loc - if(ishuman(usr) && !usr.get_active_hand()) - usr.put_in_hands(held_card) - held_card = null + creating_new_account = 0 + if("insert_card") + if(held_card) + held_card.loc = src.loc - else - var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id)) - var/obj/item/weapon/card/id/C = I - usr.drop_item() - C.loc = src - held_card = C + if(ishuman(usr) && !usr.get_active_hand()) + usr.put_in_hands(held_card) + held_card = null - if("view_account_detail") - var/index = text2num(href_list["account_index"]) - if(index && index <= all_money_accounts.len) - detailed_account_view = all_money_accounts[index] + else + var/obj/item/I = usr.get_active_hand() + if(istype(I, /obj/item/weapon/card/id)) + var/obj/item/weapon/card/id/C = I + usr.drop_item() + C.loc = src + held_card = C - if("view_accounts_list") - detailed_account_view = null - creating_new_account = 0 + if("view_account_detail") + var/index = text2num(params["account_index"]) + if(index && index <= all_money_accounts.len) + detailed_account_view = all_money_accounts[index] - if("revoke_payroll") - var/funds = detailed_account_view.money - var/account_trx = create_transation(station_account.owner_name, "Revoke payroll", "([funds])") - var/station_trx = create_transation(detailed_account_view.owner_name, "Revoke payroll", funds) + if("view_accounts_list") + detailed_account_view = null + creating_new_account = 0 - station_account.money += funds - detailed_account_view.money = 0 + if("revoke_payroll") + var/funds = detailed_account_view.money + var/account_trx = create_transation(station_account.owner_name, "Revoke payroll", "([funds])") + var/station_trx = create_transation(detailed_account_view.owner_name, "Revoke payroll", funds) - detailed_account_view.transaction_log.Add(account_trx) - station_account.transaction_log.Add(station_trx) + station_account.money += funds + detailed_account_view.money = 0 - callHook("revoke_payroll", list(detailed_account_view)) + detailed_account_view.transaction_log.Add(account_trx) + station_account.transaction_log.Add(station_trx) - if("print") - var/text - var/obj/item/weapon/paper/P = new(loc) - if (detailed_account_view) - P.name = "account #[detailed_account_view.account_number] details" - var/title = "Account #[detailed_account_view.account_number] Details" - text = {" - [accounting_letterhead(title)] - Holder: [detailed_account_view.owner_name]
- Balance: $[detailed_account_view.money]
- Status: [detailed_account_view.suspended ? "Suspended" : "Active"]
- Transactions: ([detailed_account_view.transaction_log.len])
- - - - - - - - - - - - "} + callHook("revoke_payroll", list(detailed_account_view)) - for (var/datum/transaction/T in detailed_account_view.transaction_log) - text += {" - - - - - - - - "} + if("print") + print() - text += {" - -
TimestampTargetReasonValueTerminal
[T.date] [T.time][T.target_name][T.purpose][T.amount][T.source_terminal]
- "} + return TRUE - else - P.name = "financial account list" - text = {" - [accounting_letterhead("Financial Account List")] +/obj/machinery/account_database/proc/print() + var/text + var/obj/item/weapon/paper/P = new(loc) + if(detailed_account_view) + P.name = "account #[detailed_account_view.account_number] details" + var/title = "Account #[detailed_account_view.account_number] Details" + text = {" + [accounting_letterhead(title)] + Holder: [detailed_account_view.owner_name]
+ Balance: $[detailed_account_view.money]
+ Status: [detailed_account_view.suspended ? "Suspended" : "Active"]
+ Transactions: ([detailed_account_view.transaction_log.len])
+ + + + + + + + + + + + "} -
TimestampTargetReasonValueTerminal
- - - - - - - - - - "} + for (var/datum/transaction/T in detailed_account_view.transaction_log) + text += {" + + + + + + + + "} - for(var/i=1, i<=all_money_accounts.len, i++) - var/datum/money_account/D = all_money_accounts[i] - text += {" - - - - - - - "} + text += {" + +
Account NumberHolderBalanceStatus
[T.date] [T.time][T.target_name][T.purpose][T.amount][T.source_terminal]
#[D.account_number][D.owner_name]$[D.money][D.suspended ? "Suspended" : "Active"]
+ "} - text += {" - - - "} + else + P.name = "financial account list" + text = {" + [accounting_letterhead("Financial Account List")] - P.info = text - state("The terminal prints out a report.") + + + + + + + + + + + "} - return 1 + for(var/i=1, i<=all_money_accounts.len, i++) + var/datum/money_account/D = all_money_accounts[i] + text += {" + + + + + + + "} + + text += {" + +
Account NumberHolderBalanceStatus
#[D.account_number][D.owner_name]$[D.money][D.suspended ? "Suspended" : "Active"]
+ "} + + P.info = text + state("The terminal prints out a report.") \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/assemblies/device.dm b/code/modules/integrated_electronics/core/assemblies/device.dm index 3170393fc38..8500f4dafcf 100644 --- a/code/modules/integrated_electronics/core/assemblies/device.dm +++ b/code/modules/integrated_electronics/core/assemblies/device.dm @@ -78,7 +78,7 @@ output.assembly = src /obj/item/device/electronic_assembly/device/check_interactivity(mob/user) - if(!CanInteract(user, state = deep_inventory_state)) + if(!CanInteract(user, state = GLOB.tgui_deep_inventory_state)) return 0 return 1 diff --git a/code/modules/integrated_electronics/core/pins.dm b/code/modules/integrated_electronics/core/pins.dm index ddc0b06f8a5..c194b4a8a2d 100644 --- a/code/modules/integrated_electronics/core/pins.dm +++ b/code/modules/integrated_electronics/core/pins.dm @@ -40,8 +40,8 @@ D [1]/ || holder = null . = ..() -/datum/integrated_io/nano_host() - return holder.nano_host() +/datum/integrated_io/tgui_host() + return holder.tgui_host() /datum/integrated_io/proc/data_as_type(var/as_type) diff --git a/code/modules/integrated_electronics/core/special_pins/list_pin.dm b/code/modules/integrated_electronics/core/special_pins/list_pin.dm index 77d83f82b5c..4eeb756cd0d 100644 --- a/code/modules/integrated_electronics/core/special_pins/list_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/list_pin.dm @@ -117,7 +117,7 @@ /datum/integrated_io/list/display_pin_type() return IC_FORMAT_LIST -/datum/integrated_io/list/Topic(href, href_list, state = interactive_state) +/datum/integrated_io/list/Topic(href, href_list, state = GLOB.tgui_always_state) if(!holder.check_interactivity(usr)) return if(..()) diff --git a/code/modules/integrated_electronics/core/tools.dm b/code/modules/integrated_electronics/core/tools.dm index 79533bfe256..5bf48370e20 100644 --- a/code/modules/integrated_electronics/core/tools.dm +++ b/code/modules/integrated_electronics/core/tools.dm @@ -115,7 +115,7 @@ /obj/item/device/integrated_electronics/debugger/attack_self(mob/user) var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null") - if(!CanInteract(user, physical_state)) + if(!CanInteract(user, GLOB.tgui_physical_state)) return var/new_data = null @@ -124,13 +124,13 @@ accepting_refs = 0 new_data = input("Now type in a string.","[src] string writing") as null|text new_data = sanitizeSafe(new_data, MAX_MESSAGE_LEN, 0, 0) - if(istext(new_data) && CanInteract(user, physical_state)) + if(istext(new_data) && CanInteract(user, GLOB.tgui_physical_state)) data_to_write = new_data to_chat(user, "You set \the [src]'s memory to \"[new_data]\".") if("number") accepting_refs = 0 new_data = input("Now type in a number.","[src] number writing") as null|num - if(isnum(new_data) && CanInteract(user, physical_state)) + if(isnum(new_data) && CanInteract(user, GLOB.tgui_physical_state)) data_to_write = new_data to_chat(user, "You set \the [src]'s memory to [new_data].") if("ref") diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index a0846336426..9c140cedaeb 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -54,7 +54,7 @@ /obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user) var/new_input = input(user, "Enter a number, please.","Number pad", get_pin_data(IC_OUTPUT, 1)) as null|num - if(isnum(new_input) && CanInteract(user, physical_state)) + if(isnum(new_input) && CanInteract(user, GLOB.tgui_physical_state)) set_pin_data(IC_OUTPUT, 1, new_input) push_data() activate_pin(1) @@ -73,7 +73,7 @@ /obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user) var/new_input = input(user, "Enter some words, please.","Number pad", get_pin_data(IC_OUTPUT, 1)) as null|text - if(istext(new_input) && CanInteract(user, physical_state)) + if(istext(new_input) && CanInteract(user, GLOB.tgui_physical_state)) set_pin_data(IC_OUTPUT, 1, new_input) push_data() activate_pin(1) @@ -92,7 +92,7 @@ /obj/item/integrated_circuit/input/colorpad/ask_for_input(mob/user) var/new_color = input(user, "Enter a color, please.", "Color pad", get_pin_data(IC_OUTPUT, 1)) as color|null - if(new_color && CanInteract(user, physical_state)) + if(new_color && CanInteract(user, GLOB.tgui_physical_state)) set_pin_data(IC_OUTPUT, 1, new_color) push_data() activate_pin(1) diff --git a/code/modules/integrated_electronics/subtypes/memory.dm b/code/modules/integrated_electronics/subtypes/memory.dm index 630136e7d0b..90cb23de352 100644 --- a/code/modules/integrated_electronics/subtypes/memory.dm +++ b/code/modules/integrated_electronics/subtypes/memory.dm @@ -89,7 +89,7 @@ /obj/item/integrated_circuit/memory/constant/attack_self(mob/user) var/datum/integrated_io/O = outputs[1] var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null") - if(!CanInteract(user, physical_state)) + if(!CanInteract(user, GLOB.tgui_physical_state)) return var/new_data = null @@ -97,13 +97,13 @@ if("string") accepting_refs = 0 new_data = input("Now type in a string.","[src] string writing") as null|text - if(istext(new_data) && CanInteract(user, physical_state)) + if(istext(new_data) && CanInteract(user, GLOB.tgui_physical_state)) O.data = new_data to_chat(user, "You set \the [src]'s memory to [O.display_data(O.data)].") if("number") accepting_refs = 0 new_data = input("Now type in a number.","[src] number writing") as null|num - if(isnum(new_data) && CanInteract(user, physical_state)) + if(isnum(new_data) && CanInteract(user, GLOB.tgui_physical_state)) O.data = new_data to_chat(user, "You set \the [src]'s memory to [O.display_data(O.data)].") if("ref") diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 031ad576cde..0c20f6bf31a 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -20,7 +20,6 @@ var/list/ai_verbs_default = list( /mob/living/silicon/ai/proc/ai_call_shuttle, /mob/living/silicon/ai/proc/ai_camera_track, /mob/living/silicon/ai/proc/ai_camera_list, - /mob/living/silicon/ai/proc/ai_roster, /mob/living/silicon/ai/proc/ai_checklaws, /mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/take_image, @@ -355,12 +354,6 @@ var/list/ai_verbs_default = list( if(new_sprite) selected_sprite = new_sprite updateicon() -// this verb lets the ai see the stations manifest -/mob/living/silicon/ai/proc/ai_roster() - set category = "AI Commands" - set name = "Show Crew Manifest" - show_station_manifest() - /mob/living/silicon/ai/var/message_cooldown = 0 /mob/living/silicon/ai/proc/ai_announcement() set category = "AI Commands" diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 6e4cd0a4010..cf135f9d559 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -213,7 +213,7 @@ medicalActive1 = null medicalActive2 = null medical_cannotfind = 0 - SSnanoui.update_uis(src) + SStgui.update_uis(src) to_chat(usr, "You reset your record-viewing software.") /mob/living/silicon/pai/cancel_camera() diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 342e8d7f5c8..cad5229097e 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -41,27 +41,24 @@ var/global/list/default_pai_software = list() set category = "pAI Commands" set name = "Software Interface" - ui_interact(src) + tgui_interact(src) -/mob/living/silicon/pai/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) - if(user != src) - if(ui) ui.set_status(STATUS_CLOSE, 0) - return +/mob/living/silicon/pai/tgui_state(mob/user) + return GLOB.tgui_self_state - if(ui_key != "main") - var/datum/pai_software/S = software[ui_key] - if(S && !S.toggle) - S.on_ui_interact(src, ui, force_open) - else - if(ui) ui.set_status(STATUS_CLOSE, 0) - return - - var/data[0] +/mob/living/silicon/pai/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIInterface", "pAI Software Interface") + ui.open() +/mob/living/silicon/pai/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + // Software we have bought - var/bought_software[0] + var/list/bought_software = list() // Software we have not bought - var/not_bought_software[0] + var/list/not_bought_software = list() for(var/key in pai_software_by_key) var/datum/pai_software/S = pai_software_by_key[key] @@ -70,63 +67,52 @@ var/global/list/default_pai_software = list() software_data["id"] = S.id if(key in software) software_data["on"] = S.is_active(src) - bought_software[++bought_software.len] = software_data + bought_software.Add(list(software_data)) else software_data["ram"] = S.ram_cost - not_bought_software[++not_bought_software.len] = software_data + not_bought_software.Add(list(software_data)) data["bought"] = bought_software data["not_bought"] = not_bought_software data["available_ram"] = ram // Emotions - var/emotions[0] + var/list/emotions = list() for(var/name in pai_emotions) - var/emote[0] + var/list/emote = list() emote["name"] = name emote["id"] = pai_emotions[name] - emotions[++emotions.len] = emote + emotions.Add(list(emote)) data["emotions"] = emotions data["current_emotion"] = card.current_emotion - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "pai_interface.tmpl", "pAI Software Interface", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data -/mob/living/silicon/pai/Topic(href, href_list) - . = ..() - if(.) return +/mob/living/silicon/pai/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE - if(href_list["software"]) - var/soft = href_list["software"] - var/datum/pai_software/S = software[soft] - if(S.toggle) - S.toggle(src) - else - ui_interact(src, ui_key = soft) - S.tgui_interact(src) - return 1 + switch(action) + if("software") + var/soft = params["software"] + var/datum/pai_software/S = software[soft] + if(S.toggle) + S.toggle(src) + else + S.tgui_interact(src, parent_ui = ui) + return TRUE - else if(href_list["stopic"]) - var/soft = href_list["stopic"] - var/datum/pai_software/S = software[soft] - if(S) - return S.Topic(href, href_list) + if("purchase") + var/soft = params["purchase"] + var/datum/pai_software/S = pai_software_by_key[soft] + if(S && (ram >= S.ram_cost)) + ram -= S.ram_cost + software[S.id] = S + return TRUE - else if(href_list["purchase"]) - var/soft = href_list["purchase"] - var/datum/pai_software/S = pai_software_by_key[soft] - if(S && (ram >= S.ram_cost)) - ram -= S.ram_cost - software[S.id] = S - return 1 - - else if(href_list["image"]) - var/img = text2num(href_list["image"]) - if(1 <= img && img <= (pai_emotions.len)) - card.setEmotion(img) - return 1 + if("image") + var/img = text2num(params["image"]) + if(1 <= img && img <= (pai_emotions.len)) + card.setEmotion(img) + return TRUE diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm index dd92edfdab1..e518e74a4a2 100644 --- a/code/modules/mob/living/silicon/pai/software_modules.dm +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -12,14 +12,11 @@ // Whether pAIs should automatically receive this module at no cost var/default = 0 - proc/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - return +/datum/pai_software/proc/toggle(mob/living/silicon/pai/user) + return - proc/toggle(mob/living/silicon/pai/user) - return - - proc/is_active(mob/living/silicon/pai/user) - return 0 +/datum/pai_software/proc/is_active(mob/living/silicon/pai/user) + return 0 /datum/pai_software/tgui_state(mob/user) return GLOB.tgui_always_state @@ -36,55 +33,58 @@ toggle = 0 default = 1 - on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/pai_software/directives/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIDirectives", name, parent_ui) + ui.open() - data["master"] = user.master - data["dna"] = user.master_dna - data["prime"] = user.pai_law0 - data["supplemental"] = user.pai_laws +/datum/pai_software/directives/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = list() - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_directives.tmpl", "pAI Directives", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + data["master"] = user.master + data["dna"] = user.master_dna + data["prime"] = user.pai_law0 + data["supplemental"] = user.pai_laws - Topic(href, href_list) - var/mob/living/silicon/pai/P = usr - if(!istype(P)) return + return data - if(href_list["getdna"]) - var/mob/living/M = P.loc - var/count = 0 +/datum/pai_software/directives/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) + return TRUE + if(..()) + return TRUE - // Find the carrier - while(!istype(M, /mob/living)) - if(!M || !M.loc || count > 6) - //For a runtime where M ends up in nullspace (similar to bluespace but less colourful) - to_chat(src, "You are not being carried by anyone!") - return 0 - M = M.loc - count++ + if(action == "getdna") + var/mob/living/M = P.loc - // Check the carrier - var/datum/gender/TM = gender_datums[M.get_visible_gender()] - var/answer = input(M, "[P] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[P] Check DNA", "No") in list("Yes", "No") - if(answer == "Yes") - var/turf/T = get_turf_or_move(P.loc) - for (var/mob/v in viewers(T)) - v.show_message("[M] presses [TM.his] thumb against [P].", 3, "[P] makes a sharp clicking sound as it extracts DNA material from [M].", 2) - var/datum/dna/dna = M.dna - to_chat(P, "

[M]'s UE string : [dna.unique_enzymes]

") - if(dna.unique_enzymes == P.master_dna) - to_chat(P, "DNA is a match to stored Master DNA.") - else - to_chat(P, "DNA does not match stored Master DNA.") + var/count = 0 + // Find the carrier + while(!istype(M, /mob/living)) + if(!M || !M.loc || count > 6) + //For a runtime where M ends up in nullspace (similar to bluespace but less colourful) + to_chat(src, "You are not being carried by anyone!") + return 0 + M = M.loc + count++ + + // Check the carrier + var/datum/gender/TM = gender_datums[M.get_visible_gender()] + var/answer = input(M, "[P] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[P] Check DNA", "No") in list("Yes", "No") + if(answer == "Yes") + var/turf/T = get_turf(P.loc) + for (var/mob/v in viewers(T)) + v.show_message("[M] presses [TM.his] thumb against [P].", 3, "[P] makes a sharp clicking sound as it extracts DNA material from [M].", 2) + var/datum/dna/dna = M.dna + to_chat(P, "

[M]'s UE string : [dna.unique_enzymes]

") + if(dna.unique_enzymes == P.master_dna) + to_chat(P, "DNA is a match to stored Master DNA.") else - to_chat(P, "[M] does not seem like [TM.he] is going to provide a DNA sample willingly.") - return 1 + to_chat(P, "DNA does not match stored Master DNA.") + else + to_chat(P, "[M] does not seem like [TM.he] is going to provide a DNA sample willingly.") + return TRUE /datum/pai_software/radio_config name = "Radio Configuration" @@ -93,35 +93,8 @@ toggle = 0 default = 1 - on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui = null, force_open = 1) - var/data[0] - - data["listening"] = user.radio.broadcasting - data["frequency"] = format_frequency(user.radio.frequency) - - var/channels[0] - for(var/ch_name in user.radio.channels) - var/ch_stat = user.radio.channels[ch_name] - var/ch_dat[0] - ch_dat["name"] = ch_name - // FREQ_LISTENING is const in /obj/item/device/radio - ch_dat["listening"] = !!(ch_stat & user.radio.FREQ_LISTENING) - channels[++channels.len] = ch_dat - - data["channels"] = channels - - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - ui = new(user, user, id, "pai_radio.tmpl", "Radio Configuration", 300, 150) - ui.set_initial_data(data) - ui.open() - - Topic(href, href_list) - var/mob/living/silicon/pai/P = usr - if(!istype(P)) return - - P.radio.Topic(href, href_list) - return 1 +/datum/pai_software/radio_config/tgui_interact(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui/parent_ui) + return user.radio.tgui_interact(user, parent_ui = parent_ui) /datum/pai_software/crew_manifest name = "Crew Manifest" @@ -129,20 +102,18 @@ id = "manifest" toggle = 0 - on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) +/datum/pai_software/crew_manifest/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "CrewManifest", name, parent_ui) + ui.open() + +/datum/pai_software/crew_manifest/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + if(data_core) data_core.get_manifest_list() - - var/data[0] - // This is dumb, but NanoUI breaks if it has no data to send - data["manifest"] = PDA_Manifest - - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "crew_manifest.tmpl", "Crew Manifest", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + data["manifest"] = PDA_Manifest + return data /datum/pai_software/messenger name = "Digital Messenger" @@ -151,7 +122,7 @@ toggle = 0 /datum/pai_software/messenger/tgui_interact(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui/parent_ui) - return user.pda.tgui_interact(user) + return user.pda.tgui_interact(user, parent_ui = parent_ui) /datum/pai_software/med_records name = "Medical Records" @@ -159,53 +130,55 @@ id = "med_records" toggle = 0 - on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/pai_software/med_records/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIMedrecords", name, parent_ui) + ui.open() - var/records[0] - for(var/datum/data/record/general in sortRecord(data_core.general)) - var/record[0] - record["name"] = general.fields["name"] - record["ref"] = "\ref[general]" - records[++records.len] = record +/datum/pai_software/med_records/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/list/records = list() + for(var/datum/data/record/general in sortRecord(data_core.general)) + var/list/record = list() + record["name"] = general.fields["name"] + record["ref"] = "\ref[general]" + records.Add(list(record)) - data["records"] = records + data["records"] = records - var/datum/data/record/G = user.medicalActive1 - var/datum/data/record/M = user.medicalActive2 - data["general"] = G ? G.fields : null - data["medical"] = M ? M.fields : null - data["could_not_find"] = user.medical_cannotfind + var/datum/data/record/G = user.medicalActive1 + var/datum/data/record/M = user.medicalActive2 + data["general"] = G ? G.fields : null + data["medical"] = M ? M.fields : null + data["could_not_find"] = user.medical_cannotfind - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_medrecords.tmpl", "Medical Records", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data - Topic(href, href_list) - var/mob/living/silicon/pai/P = usr - if(!istype(P)) return +/datum/pai_software/med_records/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + . = ..() + var/mob/living/silicon/pai/P = usr + if(!istype(P)) + return - if(href_list["select"]) - var/datum/data/record/record = locate(href_list["select"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/M = null - if (!( data_core.general.Find(R) )) - P.medical_cannotfind = 1 - else - P.medical_cannotfind = 0 - for(var/datum/data/record/E in data_core.medical) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - M = E - P.medicalActive1 = R - P.medicalActive2 = M - else + if(action == "select") + var/datum/data/record/record = locate(params["select"]) + if(record) + var/datum/data/record/R = record + var/datum/data/record/M = null + if (!( data_core.general.Find(R) )) P.medical_cannotfind = 1 - return 1 + else + P.medical_cannotfind = 0 + for(var/datum/data/record/E in data_core.medical) + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + M = E + P.medicalActive1 = R + P.medicalActive2 = M + else + P.medical_cannotfind = 1 + return 1 /datum/pai_software/sec_records name = "Security Records" @@ -213,57 +186,59 @@ id = "sec_records" toggle = 0 - on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/pai_software/sec_records/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAISecrecords", name, parent_ui) + ui.open() - var/records[0] - for(var/datum/data/record/general in sortRecord(data_core.general)) - var/record[0] - record["name"] = general.fields["name"] - record["ref"] = "\ref[general]" - records[++records.len] = record +/datum/pai_software/sec_records/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/list/records = list() + for(var/datum/data/record/general in sortRecord(data_core.general)) + var/list/record = list() + record["name"] = general.fields["name"] + record["ref"] = "\ref[general]" + records.Add(list(record)) - data["records"] = records + data["records"] = records - var/datum/data/record/G = user.securityActive1 - var/datum/data/record/S = user.securityActive2 - data["general"] = G ? G.fields : null - data["security"] = S ? S.fields : null - data["could_not_find"] = user.security_cannotfind + var/datum/data/record/G = user.securityActive1 + var/datum/data/record/S = user.securityActive2 + data["general"] = G ? G.fields : null + data["security"] = S ? S.fields : null + data["could_not_find"] = user.security_cannotfind - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_secrecords.tmpl", "Security Records", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data - Topic(href, href_list) - var/mob/living/silicon/pai/P = usr - if(!istype(P)) return +/datum/pai_software/sec_records/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + . = ..() + var/mob/living/silicon/pai/P = usr + if(!istype(P)) + return - if(href_list["select"]) - var/datum/data/record/record = locate(href_list["select"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/S = null - if (!( data_core.general.Find(R) )) - P.securityActive1 = null - P.securityActive2 = null - P.security_cannotfind = 1 - else - P.security_cannotfind = 0 - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - S = E - P.securityActive1 = R - P.securityActive2 = S - else + if(action == "select") + var/datum/data/record/record = locate(params["select"]) + if(record) + var/datum/data/record/R = record + var/datum/data/record/S = null + if (!( data_core.general.Find(R) )) P.securityActive1 = null P.securityActive2 = null P.security_cannotfind = 1 - return 1 + else + P.security_cannotfind = 0 + for(var/datum/data/record/E in data_core.security) + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + S = E + P.securityActive1 = R + P.securityActive2 = S + else + P.securityActive1 = null + P.securityActive2 = null + P.security_cannotfind = 1 + return TRUE /datum/pai_software/door_jack name = "Door Jack" @@ -271,47 +246,49 @@ id = "door_jack" toggle = 0 - on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/pai_software/door_jack/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIDoorjack", "Door Jack", parent_ui) + ui.open() - data["cable"] = user.cable != null - data["machine"] = user.cable && (user.cable.machine != null) - data["inprogress"] = user.hackdoor != null - data["progress_a"] = round(user.hackprogress / 10) - data["progress_b"] = user.hackprogress % 10 - data["aborted"] = user.hack_aborted +/datum/pai_software/door_jack/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_doorjack.tmpl", "Door Jack", 300, 150) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + data["cable"] = user.cable != null + data["machine"] = user.cable && (user.cable.machine != null) + data["inprogress"] = user.hackdoor != null + data["progress_a"] = round(user.hackprogress / 10) + data["progress_b"] = user.hackprogress % 10 + data["aborted"] = user.hack_aborted - Topic(href, href_list) - var/mob/living/silicon/pai/P = usr - if(!istype(P)) return + return data - if(href_list["jack"]) +/datum/pai_software/door_jack/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + var/mob/living/silicon/pai/P = usr + if(!istype(P) || ..()) + return TRUE + + switch(action) + if("jack") if(P.cable && P.cable.machine) P.hackdoor = P.cable.machine P.hackloop() return 1 - else if(href_list["cancel"]) + if("cancel") P.hackdoor = null return 1 - else if(href_list["cable"]) - var/turf/T = get_turf_or_move(P.loc) + if("cable") + var/turf/T = get_turf(P) P.hack_aborted = 0 P.cable = new /obj/item/weapon/pai_cable(T) for(var/mob/M in viewers(T)) M.show_message("A port on [P] opens to reveal [P.cable], which promptly falls to the floor.", 3, - "You hear the soft click of something light and hard falling to the ground.", 2) + "You hear the soft click of something light and hard falling to the ground.", 2) return 1 /mob/living/silicon/pai/proc/hackloop() - var/turf/T = get_turf_or_move(src.loc) + var/turf/T = get_turf(src) for(var/mob/living/silicon/ai/AI in player_list) if(T.loc) to_chat(AI, "Network Alert: Brute-force encryption crack in progress in [T.loc].") @@ -345,134 +322,155 @@ id = "atmos_sense" toggle = 0 - on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/pai_software/atmosphere_sensor/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIAtmos", name, parent_ui) + ui.open() - var/turf/T = get_turf_or_move(user.loc) - if(!T) - data["reading"] = 0 - data["pressure"] = 0 - data["temperature"] = 0 - data["temperatureC"] = 0 - data["gas"] = list() - else - var/datum/gas_mixture/env = T.return_air() - data["reading"] = 1 - var/pres = env.return_pressure() * 10 - data["pressure"] = "[round(pres/10)].[pres%10]" - data["temperature"] = round(env.temperature) - data["temperatureC"] = round(env.temperature-T0C) +/datum/pai_software/atmosphere_sensor/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() - var/t_moles = env.total_moles - var/gases[0] - for(var/g in env.gas) - var/gas[0] - gas["name"] = gas_data.name[g] - gas["percent"] = round((env.gas[g] / t_moles) * 100) - gases[++gases.len] = gas - data["gas"] = gases + var/list/results = list() + var/turf/T = get_turf(user) + if(!isnull(T)) + var/datum/gas_mixture/environment = T.return_air() + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles + if (total_moles) + var/o2_level = environment.gas["oxygen"]/total_moles + var/n2_level = environment.gas["nitrogen"]/total_moles + var/co2_level = environment.gas["carbon_dioxide"]/total_moles + var/phoron_level = environment.gas["phoron"]/total_moles + var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level) - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_atmosphere.tmpl", "Atmosphere Sensor", 350, 300) - ui.set_initial_data(data) - ui.open() + // entry is what the element is describing + // Type identifies which unit or other special characters to use + // Val is the information reported + // Bad_high/_low are the values outside of which the entry reports as dangerous + // Poor_high/_low are the values outside of which the entry reports as unideal + // Values were extracted from the template itself + results = list( + list("entry" = "Pressure", "units" = "kPa", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80), + list("entry" = "Temperature", "units" = "°C", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5), + list("entry" = "Oxygen", "units" = "kPa", "val" = "[round(o2_level*100,0.1)]", "bad_high" = 140, "poor_high" = 135, "poor_low" = 19, "bad_low" = 17), + list("entry" = "Nitrogen", "units" = "kPa", "val" = "[round(n2_level*100,0.1)]", "bad_high" = 105, "poor_high" = 85, "poor_low" = 50, "bad_low" = 40), + list("entry" = "Carbon Dioxide", "units" = "kPa", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0), + list("entry" = "Phoron", "units" = "kPa", "val" = "[round(phoron_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0), + list("entry" = "Other", "units" = "kPa", "val" = "[round(unknown_level, 0.01)]", "bad_high" = 1, "poor_high" = 0.5, "poor_low" = 0, "bad_low" = 0) + ) + + if(isnull(results)) + results = list(list("entry" = "pressure", "units" = "kPa", "val" = "0", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80)) + + data["aircontents"] = results + + return data /datum/pai_software/sec_hud name = "Security HUD" ram_cost = 20 id = "sec_hud" - toggle(mob/living/silicon/pai/user) - user.secHUD = !user.secHUD - user.plane_holder.set_vis(VIS_CH_ID, user.secHUD) - user.plane_holder.set_vis(VIS_CH_WANTED, user.secHUD) - user.plane_holder.set_vis(VIS_CH_IMPTRACK, user.secHUD) - user.plane_holder.set_vis(VIS_CH_IMPLOYAL, user.secHUD) - user.plane_holder.set_vis(VIS_CH_IMPCHEM, user.secHUD) +/datum/pai_software/sec_hud/toggle(mob/living/silicon/pai/user) + user.secHUD = !user.secHUD + user.plane_holder.set_vis(VIS_CH_ID, user.secHUD) + user.plane_holder.set_vis(VIS_CH_WANTED, user.secHUD) + user.plane_holder.set_vis(VIS_CH_IMPTRACK, user.secHUD) + user.plane_holder.set_vis(VIS_CH_IMPLOYAL, user.secHUD) + user.plane_holder.set_vis(VIS_CH_IMPCHEM, user.secHUD) - is_active(mob/living/silicon/pai/user) - return user.secHUD +/datum/pai_software/sec_hud/is_active(mob/living/silicon/pai/user) + return user.secHUD /datum/pai_software/med_hud name = "Medical HUD" ram_cost = 20 id = "med_hud" - toggle(mob/living/silicon/pai/user) - user.medHUD = !user.medHUD - user.plane_holder.set_vis(VIS_CH_STATUS, user.medHUD) - user.plane_holder.set_vis(VIS_CH_HEALTH, user.medHUD) +/datum/pai_software/med_hud/toggle(mob/living/silicon/pai/user) + user.medHUD = !user.medHUD + user.plane_holder.set_vis(VIS_CH_STATUS, user.medHUD) + user.plane_holder.set_vis(VIS_CH_HEALTH, user.medHUD) - is_active(mob/living/silicon/pai/user) - return user.medHUD +/datum/pai_software/med_hud/is_active(mob/living/silicon/pai/user) + return user.medHUD /datum/pai_software/translator name = "Universal Translator" ram_cost = 35 id = "translator" - toggle(mob/living/silicon/pai/user) - // Sol Common, Tradeband, Terminus and Gutter are added with New() and are therefore the current default, always active languages - user.translator_on = !user.translator_on - if(user.translator_on) - user.add_language(LANGUAGE_UNATHI) - user.add_language(LANGUAGE_SIIK) - user.add_language(LANGUAGE_AKHANI) - user.add_language(LANGUAGE_SKRELLIAN) - user.add_language(LANGUAGE_ZADDAT) - user.add_language(LANGUAGE_SCHECHI) - else - user.remove_language(LANGUAGE_UNATHI) - user.remove_language(LANGUAGE_SIIK) - user.remove_language(LANGUAGE_AKHANI) - user.remove_language(LANGUAGE_SKRELLIAN) - user.remove_language(LANGUAGE_ZADDAT) - user.remove_language(LANGUAGE_SCHECHI) +/datum/pai_software/translator/toggle(mob/living/silicon/pai/user) + // Sol Common, Tradeband, Terminus and Gutter are added with New() and are therefore the current default, always active languages + user.translator_on = !user.translator_on + if(user.translator_on) + user.add_language(LANGUAGE_UNATHI) + user.add_language(LANGUAGE_SIIK) + user.add_language(LANGUAGE_AKHANI) + user.add_language(LANGUAGE_SKRELLIAN) + user.add_language(LANGUAGE_ZADDAT) + user.add_language(LANGUAGE_SCHECHI) + else + user.remove_language(LANGUAGE_UNATHI) + user.remove_language(LANGUAGE_SIIK) + user.remove_language(LANGUAGE_AKHANI) + user.remove_language(LANGUAGE_SKRELLIAN) + user.remove_language(LANGUAGE_ZADDAT) + user.remove_language(LANGUAGE_SCHECHI) - is_active(mob/living/silicon/pai/user) - return user.translator_on +/datum/pai_software/translator/is_active(mob/living/silicon/pai/user) + return user.translator_on /datum/pai_software/signaller - name = "Remote Signaller" + name = "Remote Signaler" ram_cost = 5 id = "signaller" toggle = 0 - on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/pai_software/signaller/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Signaler", "Signaler", parent_ui) + ui.open() - data["frequency"] = format_frequency(user.sradio.frequency) - data["code"] = user.sradio.code +/datum/pai_software/signaller/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/obj/item/radio/integrated/signal/R = user.sradio - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_signaller.tmpl", "Signaller", 320, 150) - ui.set_initial_data(data) - ui.open() + data["frequency"] = R.frequency + data["minFrequency"] = RADIO_LOW_FREQ + data["maxFrequency"] = RADIO_HIGH_FREQ + data["code"] = R.code - Topic(href, href_list) - var/mob/living/silicon/pai/P = usr - if(!istype(P)) return + return data - if(href_list["send"]) - P.sradio.send_signal("ACTIVATE") - for(var/mob/O in hearers(1, P.loc)) - O.show_message("[bicon(P)] *beep* *beep*", 3, "*beep* *beep*", 2) - return 1 +/datum/pai_software/signaller/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE - else if(href_list["freq"]) - var/new_frequency = (P.sradio.frequency + text2num(href_list["freq"])) - if(new_frequency < PUBLIC_LOW_FREQ || new_frequency > PUBLIC_HIGH_FREQ) - new_frequency = sanitize_frequency(new_frequency) - P.sradio.set_frequency(new_frequency) - return 1 + var/mob/living/silicon/pai/user = usr + if(istype(user)) + var/obj/item/radio/integrated/signal/R = user.sradio - else if(href_list["code"]) - P.sradio.code += text2num(href_list["code"]) - P.sradio.code = round(P.sradio.code) - P.sradio.code = min(100, P.sradio.code) - P.sradio.code = max(1, P.sradio.code) - return 1 + switch(action) + if("signal") + spawn(0) + R.send_signal("ACTIVATE") + for(var/mob/O in hearers(1, R.loc)) + O.show_message("[bicon(R)] *beep* *beep*", 3, "*beep* *beep*", 2) + if("freq") + var/frequency = unformat_frequency(params["freq"]) + frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ) + R.set_frequency(frequency) + . = TRUE + if("code") + R.code = clamp(round(text2num(params["code"])), 1, 100) + . = TRUE + if("reset") + if(params["reset"] == "freq") + R.set_frequency(initial(R.frequency)) + else + R.code = initial(R.code) + . = TRUE diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index ad1e767acab..7d67ca3cc32 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -349,12 +349,6 @@ updatename() updateicon() -// this verb lets cyborgs see the stations manifest -/mob/living/silicon/robot/verb/cmd_station_manifest() - set category = "Robot Commands" - set name = "Show Crew Manifest" - show_station_manifest() - /mob/living/silicon/robot/proc/self_diagnosis() if(!is_component_functioning("diagnosis unit")) return null diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index b6cf748fb82..b9c2c60c471 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -153,18 +153,6 @@ show_malf_ai() ..() -// this function displays the stations manifest in a separate window -/mob/living/silicon/proc/show_station_manifest() - var/dat = "
" - if(!data_core) - to_chat(src, "There is no data to form a manifest with. Contact your Nanotrasen administrator.") - return - dat += data_core.get_manifest(1) //The 1 makes it monochrome. - - var/datum/browser/popup = new(src, "Crew Manifest", "Crew Manifest", 370, 420, src) - popup.set_content(dat) - popup.open() - //can't inject synths /mob/living/silicon/can_inject(var/mob/user, var/error_msg) if(error_msg) diff --git a/code/modules/mob/living/silicon/subystems.dm b/code/modules/mob/living/silicon/subystems.dm index be6a68591d8..890f1a8b370 100644 --- a/code/modules/mob/living/silicon/subystems.dm +++ b/code/modules/mob/living/silicon/subystems.dm @@ -2,6 +2,7 @@ var/register_alarms = 1 var/datum/tgui_module/alarm_monitor/all/robot/alarm_monitor var/datum/tgui_module/atmos_control/robot/atmos_control + var/datum/tgui_module/crew_manifest/robot/crew_manifest var/datum/tgui_module/crew_monitor/robot/crew_monitor var/datum/tgui_module/law_manager/robot/law_manager var/datum/tgui_module/power_monitor/robot/power_monitor @@ -10,6 +11,7 @@ /mob/living/silicon var/list/silicon_subsystems = list( /mob/living/silicon/proc/subsystem_alarm_monitor, + /mob/living/silicon/proc/subsystem_crew_manifest, /mob/living/silicon/proc/subsystem_law_manager ) @@ -17,6 +19,7 @@ silicon_subsystems = list( /mob/living/silicon/proc/subsystem_alarm_monitor, /mob/living/silicon/proc/subsystem_atmos_control, + /mob/living/silicon/proc/subsystem_crew_manifest, /mob/living/silicon/proc/subsystem_crew_monitor, /mob/living/silicon/proc/subsystem_law_manager, /mob/living/silicon/proc/subsystem_power_monitor, @@ -30,6 +33,7 @@ /mob/living/silicon/proc/init_subsystems() alarm_monitor = new(src) atmos_control = new(src) + crew_manifest = new(src) crew_monitor = new(src) law_manager = new(src) power_monitor = new(src) @@ -60,6 +64,15 @@ atmos_control.tgui_interact(usr) +/******************** +* Crew Manifest * +********************/ +/mob/living/silicon/proc/subsystem_crew_manifest() + set category = "Subystems" + set name = "Crew Manifest" + + crew_manifest.tgui_interact(usr) + /******************** * Crew Monitor * ********************/ diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index ffaeef3c09d..d965956dfe4 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -1,5 +1,4 @@ /mob/Logout() - SSnanoui.user_logout(src) // this is used to clean up (remove) this user's Nano UIs SStgui.on_logout(src) // Cleanup any TGUIs the user has open player_list -= src disconnect_time = world.realtime //VOREStation Addition: logging when we disappear. diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 8bc12174bfc..d5e55940d0c 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -220,12 +220,6 @@ else return -1 -/obj/item/modular_computer/initial_data() - return get_header_data() - -/obj/item/modular_computer/update_layout() - return TRUE - /datum/computer_file/program/apply_visual(mob/M) if(TM) return TM.apply_visual(M) diff --git a/code/modules/nano/interaction/admin.dm b/code/modules/nano/interaction/admin.dm deleted file mode 100644 index dd4ce6ad17e..00000000000 --- a/code/modules/nano/interaction/admin.dm +++ /dev/null @@ -1,7 +0,0 @@ -/* - This state checks that the user is an admin, end of story -*/ -/var/global/datum/topic_state/admin_state/admin_state = new() - -/datum/topic_state/admin_state/can_use_topic(var/src_object, var/mob/user) - return check_rights(R_ADMIN|R_EVENT, 0, user) ? STATUS_INTERACTIVE : STATUS_CLOSE diff --git a/code/modules/nano/interaction/base.dm b/code/modules/nano/interaction/base.dm deleted file mode 100644 index eb3e9ae5c15..00000000000 --- a/code/modules/nano/interaction/base.dm +++ /dev/null @@ -1,37 +0,0 @@ -/datum/proc/nano_host() - return src - -/datum/proc/nano_container() - return src - -/datum/proc/CanUseTopic(var/mob/user, var/datum/topic_state/state) - var/src_object = nano_host() - return state.can_use_topic(src_object, user) - -/datum/topic_state/proc/href_list(var/mob/user) - return list() - -/datum/topic_state/proc/can_use_topic(var/src_object, var/mob/user) - return STATUS_CLOSE - -/mob/proc/shared_nano_interaction() - if (src.stat || !client) - return STATUS_CLOSE // no updates, close the interface - else if (incapacitated()) - return STATUS_UPDATE // update only (orange visibility) - return STATUS_INTERACTIVE - -/mob/living/silicon/ai/shared_nano_interaction() - if(lacks_power()) - return STATUS_CLOSE - if (check_unable(1, 0)) - return STATUS_CLOSE - return ..() - -/mob/living/silicon/robot/shared_nano_interaction() - . = STATUS_INTERACTIVE - if(!has_power) - return STATUS_CLOSE - if(lockdown) - . = STATUS_DISABLED - return min(., ..()) diff --git a/code/modules/nano/interaction/conscious.dm b/code/modules/nano/interaction/conscious.dm deleted file mode 100644 index 143bc24956f..00000000000 --- a/code/modules/nano/interaction/conscious.dm +++ /dev/null @@ -1,7 +0,0 @@ -/* - This state only checks if user is conscious. -*/ -/var/global/datum/topic_state/conscious_state/conscious_state = new() - -/datum/topic_state/conscious_state/can_use_topic(var/src_object, var/mob/user) - return user.stat == CONSCIOUS ? STATUS_INTERACTIVE : STATUS_CLOSE diff --git a/code/modules/nano/interaction/contained.dm b/code/modules/nano/interaction/contained.dm deleted file mode 100644 index 9ef595d020c..00000000000 --- a/code/modules/nano/interaction/contained.dm +++ /dev/null @@ -1,18 +0,0 @@ -/* - This state checks if user is somewhere within src_object, as well as the default NanoUI interaction. -*/ -/var/global/datum/topic_state/contained_state/contained_state = new() - -/datum/topic_state/contained_state/can_use_topic(var/atom/src_object, var/mob/user) - if(!src_object.contains(user)) - return STATUS_CLOSE - - return user.shared_nano_interaction() - -/atom/proc/contains(var/atom/location) - if(!location) - return 0 - if(location == src) - return 1 - - return contains(location.loc) diff --git a/code/modules/nano/interaction/default.dm b/code/modules/nano/interaction/default.dm deleted file mode 100644 index dbb0781d33e..00000000000 --- a/code/modules/nano/interaction/default.dm +++ /dev/null @@ -1,91 +0,0 @@ -/var/global/datum/topic_state/default/default_state = new() - -/datum/topic_state/default/href_list(var/mob/user) - return list() - -/datum/topic_state/default/can_use_topic(var/src_object, var/mob/user) - return user.default_can_use_topic(src_object) - -/mob/proc/default_can_use_topic(var/src_object) - return STATUS_CLOSE // By default no mob can do anything with NanoUI - -/mob/observer/dead/default_can_use_topic(var/src_object) - if(can_admin_interact()) - return STATUS_INTERACTIVE // Admins are more equal - if(!client || get_dist(src_object, src) > client.view) // Preventing ghosts from having a million windows open by limiting to objects in range - return STATUS_CLOSE - return STATUS_UPDATE // Ghosts can view updates - -/mob/living/silicon/pai/default_can_use_topic(var/src_object) - if((src_object == src || src_object == radio || src_object == communicator) && !stat) - return STATUS_INTERACTIVE - else - return ..() - -/mob/living/silicon/robot/default_can_use_topic(var/src_object) - . = shared_nano_interaction() - if(. <= STATUS_DISABLED) - return - - // robots can interact with things they can see within their view range - if((src_object in view(src)) && get_dist(src_object, src) <= src.client.view) - return STATUS_INTERACTIVE // interactive (green visibility) - return STATUS_DISABLED // no updates, completely disabled (red visibility) - -/mob/living/silicon/ai/default_can_use_topic(var/src_object) - . = shared_nano_interaction() - if(. != STATUS_INTERACTIVE) - return - - // Prevents the AI from using Topic on admin levels (by for example viewing through the court/thunderdome cameras) - // unless it's on the same level as the object it's interacting with. - var/turf/T = get_turf(src_object) - if(!T || !(z == T.z || (T.z in using_map.player_levels))) - return STATUS_CLOSE - - // If an object is in view then we can interact with it - if(src_object in view(client.view, src)) - return STATUS_INTERACTIVE - - // If we're installed in a chassi, rather than transfered to an inteliCard or other container, then check if we have camera view - if(is_in_chassis()) - //stop AIs from leaving windows open and using then after they lose vision - if(cameranet && !cameranet.checkTurfVis(get_turf(src_object))) - return STATUS_CLOSE - return STATUS_INTERACTIVE - else if(get_dist(src_object, src) <= client.view) // View does not return what one would expect while installed in an inteliCard - return STATUS_INTERACTIVE - - return STATUS_CLOSE - -//Some atoms such as vehicles might have special rules for how mobs inside them interact with NanoUI. -/atom/proc/contents_nano_distance(var/src_object, var/mob/living/user) - return user.shared_living_nano_distance(src_object) - -/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object) - if (!(src_object in view(4, src))) // If the src object is not in visable, disable updates - return STATUS_CLOSE - - var/dist = get_dist(src_object, src) - if (dist <= 1) - return STATUS_INTERACTIVE // interactive (green visibility) - else if (dist <= 2) - return STATUS_UPDATE // update only (orange visibility) - else if (dist <= 4) - return STATUS_DISABLED // no updates, completely disabled (red visibility) - return STATUS_CLOSE - -/mob/living/default_can_use_topic(var/src_object) - . = shared_nano_interaction(src_object) - if(. != STATUS_CLOSE) - if(loc) - . = min(., loc.contents_nano_distance(src_object, src)) - if(STATUS_INTERACTIVE) - return STATUS_UPDATE - -/mob/living/carbon/human/default_can_use_topic(var/src_object) - . = shared_nano_interaction(src_object) - if(. != STATUS_CLOSE) - . = min(., shared_living_nano_distance(src_object)) - if(. == STATUS_UPDATE && (TK in mutations)) // If we have telekinesis and remain close enough, allow interaction. - return STATUS_INTERACTIVE diff --git a/code/modules/nano/interaction/default_vr.dm b/code/modules/nano/interaction/default_vr.dm deleted file mode 100644 index 963963b3d76..00000000000 --- a/code/modules/nano/interaction/default_vr.dm +++ /dev/null @@ -1,6 +0,0 @@ -/mob/living/simple_mob/default_can_use_topic(var/src_object) - . = shared_nano_interaction(src_object) - if(. != STATUS_CLOSE) - . = min(., shared_living_nano_distance(src_object)) - -//Allows simple mobs to interact with nanoui as long as they have "has_hands = TRUE" \ No newline at end of file diff --git a/code/modules/nano/interaction/interactive.dm b/code/modules/nano/interaction/interactive.dm deleted file mode 100644 index ddd8f8f9e11..00000000000 --- a/code/modules/nano/interaction/interactive.dm +++ /dev/null @@ -1,7 +0,0 @@ -/* - This state always returns STATUS_INTERACTIVE -*/ -/var/global/datum/topic_state/interactive/interactive_state = new() - -/datum/topic_state/interactive/can_use_topic(var/src_object, var/mob/user) - return STATUS_INTERACTIVE diff --git a/code/modules/nano/interaction/inventory.dm b/code/modules/nano/interaction/inventory.dm deleted file mode 100644 index dd320f2bb25..00000000000 --- a/code/modules/nano/interaction/inventory.dm +++ /dev/null @@ -1,11 +0,0 @@ -/* - This state checks that the src_object is somewhere in the user's first-level inventory (in hands, on ear, etc.), but not further down (such as in bags). -*/ -/var/global/datum/topic_state/inventory_state/inventory_state = new() - -/datum/topic_state/inventory_state/can_use_topic(var/src_object, var/mob/user) - if(!(src_object in user)) - return STATUS_CLOSE - - - return user.shared_nano_interaction() diff --git a/code/modules/nano/interaction/inventory_deep.dm b/code/modules/nano/interaction/inventory_deep.dm deleted file mode 100644 index 9637c4df751..00000000000 --- a/code/modules/nano/interaction/inventory_deep.dm +++ /dev/null @@ -1,10 +0,0 @@ -/* - This state checks if src_object is contained anywhere in the user's inventory, including bags, etc. -*/ -/var/global/datum/topic_state/deep_inventory_state/deep_inventory_state = new() - -/datum/topic_state/deep_inventory_state/can_use_topic(var/src_object, var/mob/user) - if(!user.contains(src_object)) - return STATUS_CLOSE - - return user.shared_nano_interaction() diff --git a/code/modules/nano/interaction/inventory_vr.dm b/code/modules/nano/interaction/inventory_vr.dm deleted file mode 100644 index 21ee1ca590f..00000000000 --- a/code/modules/nano/interaction/inventory_vr.dm +++ /dev/null @@ -1,32 +0,0 @@ -/* - This state checks that the src_object is on the user's glasses slot. -*/ -/var/global/datum/topic_state/glasses_state/glasses_state = new() - -/datum/topic_state/glasses_state/can_use_topic(var/src_object, var/mob/user) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.glasses == src_object) - return user.shared_nano_interaction() - - return STATUS_CLOSE - -/var/global/datum/topic_state/nif_state/nif_state = new() - -/datum/topic_state/nif_state/can_use_topic(var/src_object, var/mob/user) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.nif && H.nif.stat == NIF_WORKING && src_object == H.nif) - return user.shared_nano_interaction() - - return STATUS_CLOSE - -/var/global/datum/topic_state/commlink_state/commlink_state = new() - -/datum/topic_state/commlink_state/can_use_topic(var/src_object, var/mob/user) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.nif && H.nif.stat == NIF_WORKING && H.nif.comm == src_object) - return user.shared_nano_interaction() - - return STATUS_CLOSE diff --git a/code/modules/nano/interaction/outside.dm b/code/modules/nano/interaction/outside.dm deleted file mode 100644 index 9ae0e24fe01..00000000000 --- a/code/modules/nano/interaction/outside.dm +++ /dev/null @@ -1,6 +0,0 @@ -/var/global/datum/topic_state/default/outside/outside_state = new() - -/datum/topic_state/default/outside/can_use_topic(var/src_object, var/mob/user) - if(user in src_object) - return STATUS_CLOSE - return ..() diff --git a/code/modules/nano/interaction/physical.dm b/code/modules/nano/interaction/physical.dm deleted file mode 100644 index 05710084817..00000000000 --- a/code/modules/nano/interaction/physical.dm +++ /dev/null @@ -1,18 +0,0 @@ -/var/global/datum/topic_state/physical/physical_state = new() - -/datum/topic_state/physical/can_use_topic(var/src_object, var/mob/user) - . = user.shared_nano_interaction(src_object) - if(. > STATUS_CLOSE) - return min(., user.check_physical_distance(src_object)) - -/mob/proc/check_physical_distance(var/src_object) - return STATUS_CLOSE - -/mob/observer/dead/check_physical_distance(var/src_object) - return default_can_use_topic(src_object) - -/mob/living/check_physical_distance(var/src_object) - return shared_living_nano_distance(src_object) - -/mob/living/silicon/check_physical_distance(var/src_object) - return max(STATUS_UPDATE, shared_living_nano_distance(src_object)) diff --git a/code/modules/nano/interaction/remote.dm b/code/modules/nano/interaction/remote.dm deleted file mode 100644 index 8e6ded6c846..00000000000 --- a/code/modules/nano/interaction/remote.dm +++ /dev/null @@ -1,39 +0,0 @@ -/* - This state checks that user is capable, within range of the remoter, etc. and that src_object meets the basic requirements for interaction (being powered, non-broken, etc. - Whoever initializes this state is also responsible for deleting it properly. -*/ -/datum/topic_state/remote - var/datum/remoter - var/datum/remote_target - var/datum/topic_state/remoter_state - -/datum/topic_state/remote/New(var/remoter, var/remote_target, var/datum/topic_state/remoter_state = default_state) - src.remoter = remoter - src.remote_target = remote_target - src.remoter_state = remoter_state - ..() - -/datum/topic_state/remote/Destroy() - src.remoter = null - src.remoter_state = null - - // Force an UI update before we go, ensuring that any windows we may have opened for the remote target closes. - SSnanoui.update_uis(remote_target.nano_container()) - remote_target = null - return ..() - -/datum/topic_state/remote/can_use_topic(var/datum/src_object, var/mob/user) - if(!(remoter && remoter_state)) // The remoter is gone, let us leave - return STATUS_CLOSE - - if(src_object != remote_target) - error("remote - Unexpected src_object: Expected '[remote_target]'/[remote_target.type], was '[src_object]'/[src_object.type]") - - // This checks if src_object is powered, etc. - // The interactive state is otherwise simplistic and only returns STATUS_INTERACTIVE and never checks distances, etc. - . = src_object.CanUseTopic(user, interactive_state) - if(. == STATUS_CLOSE) - return - - // This is the (generally) heavy checking, making sure the user is capable, within range of the remoter source, etc. - return min(., remoter.CanUseTopic(user, remoter_state)) diff --git a/code/modules/nano/interaction/self.dm b/code/modules/nano/interaction/self.dm deleted file mode 100644 index 639e50e1611..00000000000 --- a/code/modules/nano/interaction/self.dm +++ /dev/null @@ -1,9 +0,0 @@ -/* - This state checks that the src_object is the same the as user -*/ -/var/global/datum/topic_state/self_state/self_state = new() - -/datum/topic_state/self_state/can_use_topic(var/src_object, var/mob/user) - if(src_object != user) - return STATUS_CLOSE - return user.shared_nano_interaction() diff --git a/code/modules/nano/interaction/zlevel.dm b/code/modules/nano/interaction/zlevel.dm deleted file mode 100644 index 80d4c2e601c..00000000000 --- a/code/modules/nano/interaction/zlevel.dm +++ /dev/null @@ -1,13 +0,0 @@ -/* - This state checks that the user is on the same Z-level as src_object -*/ - -/var/global/datum/topic_state/z_state/z_state = new() - -/datum/topic_state/z_state/can_use_topic(var/src_object, var/mob/user) - var/turf/turf_obj = get_turf(src_object) - var/turf/turf_usr = get_turf(user) - if(!turf_obj || !turf_usr) - return STATUS_CLOSE - - return turf_obj.z == turf_usr.z ? STATUS_INTERACTIVE : STATUS_CLOSE diff --git a/code/modules/nano/modules/nano_module.dm b/code/modules/nano/modules/nano_module.dm deleted file mode 100644 index 87199e79dcc..00000000000 --- a/code/modules/nano/modules/nano_module.dm +++ /dev/null @@ -1,60 +0,0 @@ -/datum/nano_module - var/name - var/datum/host - var/list/using_access - -/datum/nano_module/New(var/datum/host) - ..() - src.host = host.nano_host() - -/datum/nano_module/nano_host() - return host ? host : src - -/datum/nano_module/proc/can_still_topic(var/datum/topic_state/state = default_state) - return CanUseTopic(usr, state) == STATUS_INTERACTIVE - -/datum/nano_module/proc/check_eye(var/mob/user) - return -1 - -/datum/nano_module/proc/check_access(var/mob/user, var/access) - if(!access) - return 1 - - if(using_access) - if(access in using_access) - return 1 - else - return 0 - - if(!istype(user)) - return 0 - - var/obj/item/weapon/card/id/I = user.GetIdCard() - if(!I) - return 0 - - if(access in I.access) - return 1 - - return 0 - -/datum/nano_module/proc/print_text(var/text, var/mob/user) - var/obj/item/modular_computer/MC = nano_host() - if(istype(MC)) - if(!MC.nano_printer) - to_chat(user, "Error: No printer detected. Unable to print document.") - return - - if(!MC.nano_printer.print_text(text)) - to_chat(user, "Error: Printer was unable to print the document. It may be out of paper.") - else - to_chat(user, "Error: Unable to detect compatible printer interface. Are you running NTOSv2 compatible system?") - -/datum/proc/initial_data() - return list() - -/datum/proc/update_layout() - return FALSE - -/datum/nano_module/proc/relaymove(var/mob/user, direction) - return FALSE diff --git a/code/modules/nano/nanoexternal.dm b/code/modules/nano/nanoexternal.dm deleted file mode 100644 index 08f9deffa9f..00000000000 --- a/code/modules/nano/nanoexternal.dm +++ /dev/null @@ -1,44 +0,0 @@ - // This file contains all Nano procs/definitions for external classes/objects - - /** - * Called when a Nano UI window is closed - * This is how Nano handles closed windows - * It must be a verb so that it can be called using winset - * - * @return nothing - */ -/client/verb/nanoclose(var/uiref as text) - set hidden = 1 // hide this verb from the user's panel - set name = "nanoclose" - - var/datum/nanoui/ui = locate(uiref) - - if (istype(ui)) - ui.close() - - if(ui.ref) - var/href = "close=1" - src.Topic(href, params2list(href), ui.ref) // this will direct to the atom's Topic() proc via client.Topic() - else if (ui.on_close_logic) - // no atomref specified (or not found) - // so just reset the user mob's machine var - if(src && src.mob) - src.mob.unset_machine() - - /** - * The ui_interact proc is used to open and update Nano UIs - * If ui_interact is not used then the UI will not update correctly - * ui_interact is currently defined for /atom/movable - * - * @param user /mob The mob who is interacting with this ui - * @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main") - * @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui - * @param force_open boolean Force the UI to (re)open, even if it's already open - * - * @return nothing - */ -/datum/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nano_ui/master_ui = null, var/datum/topic_state/state = default_state) - return - -// Used by the Nano UI Manager (/datum/nanomanager) to track UIs opened by this mob -/mob/var/list/open_uis = list() diff --git a/code/modules/nano/nanomanager.dm b/code/modules/nano/nanomanager.dm deleted file mode 100644 index 69b0e7b77ea..00000000000 --- a/code/modules/nano/nanomanager.dm +++ /dev/null @@ -1,224 +0,0 @@ - - /** - * Get an open /nanoui ui for the current user, src_object and ui_key and try to update it with data - * - * @param user /mob The mob who opened/owns the ui - * @param src_object /obj|/mob The obj or mob which the ui belongs to - * @param ui_key string A string key used for the ui - * @param ui /datum/nanoui An existing instance of the ui (can be null) - * @param data list The data to be passed to the ui, if it exists - * @param force_open boolean The ui is being forced to (re)open, so close ui if it exists (instead of updating) - * - * @return /nanoui Returns the found ui, for null if none exists - */ -/datum/controller/subsystem/nanoui/proc/try_update_ui(var/mob/user, src_object, ui_key, var/datum/nanoui/ui, data, var/force_open = 0) - if (isnull(ui)) // no ui has been passed, so we'll search for one - { - ui = get_open_ui(user, src_object, ui_key) - } - if (!isnull(ui)) - // The UI is already open - if (!force_open) - ui.push_data(data) - return ui - else - ui.reinitialise(new_initial_data=data) - return ui - - return null - - /** - * Get an open /nanoui ui for the current user, src_object and ui_key - * - * @param user /mob The mob who opened/owns the ui - * @param src_object /obj|/mob The obj or mob which the ui belongs to - * @param ui_key string A string key used for the ui - * - * @return /nanoui Returns the found ui, or null if none exists - */ -/datum/controller/subsystem/nanoui/proc/get_open_ui(var/mob/user, src_object, ui_key) - var/src_object_key = "\ref[src_object]" - if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) - //testing("nanomanager/get_open_ui mob [user.name] [src_object:name] [ui_key] - there are no uis open") - return null - else if (isnull(open_uis[src_object_key][ui_key]) || !istype(open_uis[src_object_key][ui_key], /list)) - //testing("nanomanager/get_open_ui mob [user.name] [src_object:name] [ui_key] - there are no uis open for this object") - return null - - for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key]) - if (ui.user == user) - return ui - - //testing("nanomanager/get_open_ui mob [user.name] [src_object:name] [ui_key] - ui not found") - return null - - /** - * Update all /nanoui uis attached to src_object - * - * @param src_object /obj|/mob The obj or mob which the uis are attached to - * - * @return int The number of uis updated - */ -/datum/controller/subsystem/nanoui/proc/update_uis(src_object) - var/src_object_key = "\ref[src_object]" - if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) - return 0 - - var/update_count = 0 - for (var/ui_key in open_uis[src_object_key]) - for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key]) - if(ui && ui.src_object && ui.user && ui.src_object.nano_host()) - ui.process(1) - update_count++ - return update_count - - /** - * Close all /nanoui uis attached to src_object - * - * @param src_object /obj|/mob The obj or mob which the uis are attached to - * - * @return int The number of uis close - */ -/datum/controller/subsystem/nanoui/proc/close_uis(src_object) - var/src_object_key = "\ref[src_object]" - if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) - return 0 - - var/close_count = 0 - for (var/ui_key in open_uis[src_object_key]) - for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key]) - if(ui && ui.src_object && ui.user && ui.src_object.nano_host()) - ui.close() - close_count++ - return close_count - - /** - * Update /nanoui uis belonging to user - * - * @param user /mob The mob who owns the uis - * @param src_object /obj|/mob If src_object is provided, only update uis which are attached to src_object (optional) - * @param ui_key string If ui_key is provided, only update uis with a matching ui_key (optional) - * - * @return int The number of uis updated - */ -/datum/controller/subsystem/nanoui/proc/update_user_uis(var/mob/user, src_object = null, ui_key = null) - if (isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0) - return 0 // has no open uis - - var/update_count = 0 - for (var/datum/nanoui/ui in user.open_uis) - if ((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key)) - ui.process(1) - update_count++ - - return update_count - - /** - * Close /nanoui uis belonging to user - * - * @param user /mob The mob who owns the uis - * @param src_object /obj|/mob If src_object is provided, only close uis which are attached to src_object (optional) - * @param ui_key string If ui_key is provided, only close uis with a matching ui_key (optional) - * - * @return int The number of uis closed - */ -/datum/controller/subsystem/nanoui/proc/close_user_uis(var/mob/user, src_object = null, ui_key = null) - if (isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0) - //testing("nanomanager/close_user_uis mob [user.name] has no open uis") - return 0 // has no open uis - - var/close_count = 0 - for (var/datum/nanoui/ui in user.open_uis) - if ((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key)) - ui.close() - close_count++ - - //testing("nanomanager/close_user_uis mob [user.name] closed [open_uis.len] of [close_count] uis") - - return close_count - - /** - * Add a /nanoui ui to the list of open uis - * This is called by the /nanoui open() proc - * - * @param ui /nanoui The ui to add - * - * @return nothing - */ -/datum/controller/subsystem/nanoui/proc/ui_opened(var/datum/nanoui/ui) - var/src_object_key = "\ref[ui.src_object]" - if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) - open_uis[src_object_key] = list(ui.ui_key = list()) - else if (isnull(open_uis[src_object_key][ui.ui_key]) || !istype(open_uis[src_object_key][ui.ui_key], /list)) - open_uis[src_object_key][ui.ui_key] = list(); - - ui.user.open_uis |= ui - var/list/uis = open_uis[src_object_key][ui.ui_key] - uis |= ui - processing_uis |= ui - //testing("nanomanager/ui_opened mob [ui.user.name] [ui.src_object:name] [ui.ui_key] - user.open_uis [ui.user.open_uis.len] | uis [uis.len] | processing_uis [processing_uis.len]") - - /** - * Remove a /nanoui ui from the list of open uis - * This is called by the /nanoui close() proc - * - * @param ui /nanoui The ui to remove - * - * @return int 0 if no ui was removed, 1 if removed successfully - */ -/datum/controller/subsystem/nanoui/proc/ui_closed(var/datum/nanoui/ui) - var/src_object_key = "\ref[ui.src_object]" - if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) - return 0 // wasn't open - else if (isnull(open_uis[src_object_key][ui.ui_key]) || !istype(open_uis[src_object_key][ui.ui_key], /list)) - return 0 // wasn't open - - processing_uis.Remove(ui) - if(ui.user) // Sanity check in case a user has been deleted (say a blown up borg watching the alarm interface) - ui.user.open_uis.Remove(ui) - var/list/uis = open_uis[src_object_key][ui.ui_key] - uis.Remove(ui) - - //testing("nanomanager/ui_closed mob [ui.user.name] [ui.src_object:name] [ui.ui_key] - user.open_uis [ui.user.open_uis.len] | uis [uis.len] | processing_uis [processing_uis.len]") - - return 1 - - /** - * This is called on user logout - * Closes/clears all uis attached to the user's /mob - * - * @param user /mob The user's mob - * - * @return nothing - */ - -// -/datum/controller/subsystem/nanoui/proc/user_logout(var/mob/user) - //testing("nanomanager/user_logout user [user.name]") - return close_user_uis(user) - - /** - * This is called when a player transfers from one mob to another - * Transfers all open UIs to the new mob - * - * @param oldMob /mob The user's old mob - * @param newMob /mob The user's new mob - * - * @return nothing - */ -/datum/controller/subsystem/nanoui/proc/user_transferred(var/mob/oldMob, var/mob/newMob) - //testing("nanomanager/user_transferred from mob [oldMob.name] to mob [newMob.name]") - if (!oldMob || isnull(oldMob.open_uis) || !istype(oldMob.open_uis, /list) || open_uis.len == 0) - //testing("nanomanager/user_transferred mob [oldMob.name] has no open uis") - return 0 // has no open uis - - if (isnull(newMob.open_uis) || !istype(newMob.open_uis, /list)) - newMob.open_uis = list() - - for (var/datum/nanoui/ui in oldMob.open_uis) - ui.user = newMob - newMob.open_uis.Add(ui) - - oldMob.open_uis.Cut() - - return 1 // success \ No newline at end of file diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm deleted file mode 100644 index 29863f56170..00000000000 --- a/code/modules/nano/nanoui.dm +++ /dev/null @@ -1,529 +0,0 @@ -/********************************************************** -NANO UI FRAMEWORK - -nanoui class (or whatever Byond calls classes) - -nanoui is used to open and update nano browser uis -**********************************************************/ - -/datum/nanoui - // the user who opened this ui - var/mob/user - // the object this ui "belongs" to - var/datum/src_object - // the title of this ui - var/title - // the key of this ui, this is to allow multiple (different) uis for each src_object - var/ui_key - // window_id is used as the window name/identifier for browse and onclose - var/window_id - // the browser window width - var/width = 0 - // the browser window height - var/height = 0 - // whether to use extra logic when window closes - var/on_close_logic = 1 - // an extra ref to use when the window is closed, usually null - var/atom/ref = null - // options for modifying window behaviour - var/window_options = "focus=0;can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id - // the list of stylesheets to apply to this ui - var/list/stylesheets = list() - // the list of javascript scripts to use for this ui - var/list/scripts = list() - // a list of templates which can be used with this ui - var/templates[0] - // the layout key for this ui (this is used on the frontend, leave it as "default" unless you know what you're doing) - var/layout_key = "default" - // this sets whether to re-render the ui layout with each update (default 0, turning on will break the map ui if it's in use) - var/auto_update_layout = 0 - // this sets whether to re-render the ui content with each update (default 1) - var/auto_update_content = 1 - // the default state to use for this ui (this is used on the frontend, leave it as "default" unless you know what you're doing) - var/state_key = "default" - // show the map ui, this is used by the default layout - var/show_map = 0 - // the map z level to display - var/map_z_level = 1 - // initial data, containing the full data structure, must be sent to the ui (the data structure cannot be extended later on) - var/list/initial_data[0] - // set to 1 to update the ui automatically every master_controller tick - var/is_auto_updating = 0 - // the current status/visibility of the ui - var/status = STATUS_INTERACTIVE - - // Relationship between a master interface and its children. Used in update_status - var/datum/nanoui/master_ui - var/list/datum/nanoui/children = list() - var/datum/topic_state/state = null - - /** - * Create a new nanoui instance. - * - * @param nuser /mob The mob who has opened/owns this ui - * @param nsrc_object /obj|/mob The obj or mob which this ui belongs to - * @param nui_key string A string key to use for this ui. Allows for multiple unique uis on one src_oject - * @param ntemplate string The filename of the template file from /nano/templates (e.g. "my_template.tmpl") - * @param ntitle string The title of this ui - * @param nwidth int the width of the ui window - * @param nheight int the height of the ui window - * @param nref /atom A custom ref to use if "on_close_logic" is set to 1 - * - * @return /nanoui new nanoui object - */ -/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, var/datum/nanoui/master_ui = null, var/datum/topic_state/state = default_state) - user = nuser - src_object = nsrc_object - ui_key = nui_key - window_id = "[ui_key]\ref[src_object]" - - src.master_ui = master_ui - if(master_ui) - master_ui.children += src - src.state = state - - // add the passed template filename as the "main" template, this is required - add_template("main", ntemplate_filename) - - if (ntitle) - title = sanitize(ntitle) - if (nwidth) - width = nwidth - if (nheight) - height = nheight - if (nref) - ref = nref - - add_common_assets() - - /** - * Use this proc to add assets which are common to (and required by) all nano uis - * - * @return nothing - */ -/datum/nanoui/proc/add_common_assets() - add_script("libraries.min.js") // A JS file comprising of jQuery, doT.js and jQuery Timer libraries (compressed together) - add_script("nano_utility.js") // The NanoUtility JS, this is used to store utility functions. - add_script("nano_templates_bundle.js") // Contains all templates, generated by asset cache system at server start. - add_script("nano_template.js") // The NanoTemplate JS, this is used to render templates. - add_script("nano_state_manager.js") // The NanoStateManager JS, it handles updates from the server and passes data to the current state - add_script("nano_state.js") // The NanoState JS, this is the base state which all states must inherit from - add_script("nano_state_default.js") // The NanoStateDefault JS, this is the "default" state (used by all UIs by default), which inherits from NanoState - add_script("nano_state_pda.js") // The NanoStatePDA JS, this is the state used for PDAs. - add_script("nano_base_callbacks.js") // The NanoBaseCallbacks JS, this is used to set up (before and after update) callbacks which are common to all UIs - add_script("nano_base_helpers.js") // The NanoBaseHelpers JS, this is used to set up template helpers which are common to all UIs - add_stylesheet("shared.css") // this CSS sheet is common to all UIs - add_stylesheet("shared_vr.css") // VOREStation Add - add_stylesheet("icons.css") // this CSS sheet is common to all UIs - - /** - * Set the current status (also known as visibility) of this ui. - * - * @param state int The status to set, see the defines at the top of this file - * @param push_update int (bool) Push an update to the ui to update it's status (an update is always sent if the status has changed to red (0)) - * - * @return nothing - */ -/datum/nanoui/proc/set_status(state, push_update) - if (state != status) // Only update if it is different - if (status == STATUS_DISABLED) - status = state - if (push_update) - update() - else - status = state - if (push_update || status == 0) - push_data(null, 1) // Update the UI, force the update in case the status is 0, data is null so that previous data is used - - /** - * Update the status (visibility) of this ui based on the user's status - * - * @param push_update int (bool) Push an update to the ui to update it's status. This is set to 0/false if an update is going to be pushed anyway (to avoid unnessary updates) - * - * @return nothing - */ -/datum/nanoui/proc/update_status(var/push_update = 0) - var/obj/host = src_object.nano_host() - var/new_status = host.CanUseTopic(user, state) - if(master_ui) - new_status = min(new_status, master_ui.status) - - set_status(new_status, push_update) - if(new_status == STATUS_CLOSE) - close() - - /** - * Set the ui to auto update (every master_controller tick) - * - * @param state int (bool) Set auto update to 1 or 0 (true/false) - * - * @return nothing - */ -/datum/nanoui/proc/set_auto_update(nstate = 1) - is_auto_updating = nstate - - /** - * Set the initial data for the ui. This is vital as the data structure set here cannot be changed when pushing new updates. - * - * @param data /list The list of data for this ui - * - * @return nothing - */ -/datum/nanoui/proc/set_initial_data(list/data) - initial_data = data - - /** - * Get config data to sent to the ui. - * - * @return /list config data - */ -/datum/nanoui/proc/get_config_data() - var/name = "[src_object]" - name = sanitize(name) - var/list/config_data = list( - "title" = title, - "srcObject" = list("name" = name), - "stateKey" = state_key, - "status" = status, - "autoUpdateLayout" = auto_update_layout, - "autoUpdateContent" = auto_update_content, - "showMap" = show_map, - "mapZLevel" = map_z_level, - "user" = list("name" = user.name) - ) - return config_data - - /** - * Get data to sent to the ui. - * - * @param data /list The list of general data for this ui (can be null to use previous data sent) - * - * @return /list data to send to the ui - */ -/datum/nanoui/proc/get_send_data(var/list/data) - var/list/config_data = get_config_data() - - var/list/send_data = list("config" = config_data) - - if (!isnull(data)) - send_data["data"] = data - - return send_data - - /** - * Set the browser window options for this ui - * - * @param nwindow_options string The new window options - * - * @return nothing - */ -/datum/nanoui/proc/set_window_options(nwindow_options) - window_options = nwindow_options - - /** - * Add a CSS stylesheet to this UI - * These must be added before the UI has been opened, adding after that will have no effect - * - * @param file string The name of the CSS file from /nano/css (e.g. "my_style.css") - * - * @return nothing - */ -/datum/nanoui/proc/add_stylesheet(file) - stylesheets.Add(file) - - /** - * Add a JavsScript script to this UI - * These must be added before the UI has been opened, adding after that will have no effect - * - * @param file string The name of the JavaScript file from /nano/js (e.g. "my_script.js") - * - * @return nothing - */ -/datum/nanoui/proc/add_script(file) - scripts.Add(file) - - /** - * Add a template for this UI - * Templates are combined with the data sent to the UI to create the rendered view - * These must be added before the UI has been opened, adding after that will have no effect - * - * @param key string The key which is used to reference this template in the frontend - * @param filename string The name of the template file from /nano/templates (e.g. "my_template.tmpl") - * - * @return nothing - */ -/datum/nanoui/proc/add_template(key, filename) - templates[key] = filename - - /** - * Set the layout key for use in the frontend Javascript - * The layout key is the basic layout key for the page - * Two files are loaded on the client based on the layout key varable: - * -> a template in /nano/templates with the filename "layout_.tmpl - * -> a CSS stylesheet in /nano/css with the filename "layout_.css - * - * @param nlayout string The layout key to use - * - * @return nothing - */ -/datum/nanoui/proc/set_layout_key(nlayout_key) - layout_key = lowertext(nlayout_key) - - /** - * Set the ui to update the layout (re-render it) on each update, turning this on will break the map ui (if it's being used) - * - * @param state int (bool) Set update to 1 or 0 (true/false) (default 0) - * - * @return nothing - */ -/datum/nanoui/proc/set_auto_update_layout(nstate) - auto_update_layout = nstate - - /** - * Set the ui to update the main content (re-render it) on each update - * - * @param state int (bool) Set update to 1 or 0 (true/false) (default 1) - * - * @return nothing - */ -/datum/nanoui/proc/set_auto_update_content(nstate) - auto_update_content = nstate - - /** - * Set the state key for use in the frontend Javascript - * - * @param nstate_key string The key of the state to use - * - * @return nothing - */ -/datum/nanoui/proc/set_state_key(nstate_key) - state_key = nstate_key - - /** - * Toggle showing the map ui - * - * @param nstate_key boolean 1 to show map, 0 to hide (default is 0) - * - * @return nothing - */ -/datum/nanoui/proc/set_show_map(nstate) - show_map = nstate - - /** - * Toggle showing the map ui - * - * @param nstate_key boolean 1 to show map, 0 to hide (default is 0) - * - * @return nothing - */ -/datum/nanoui/proc/set_map_z_level(nz) - map_z_level = nz - - /** - * Set whether or not to use the "old" on close logic (mainly unset_machine()) - * - * @param state int (bool) Set on_close_logic to 1 or 0 (true/false) - * - * @return nothing - */ -/datum/nanoui/proc/use_on_close_logic(state) - on_close_logic = state - - /** - * Return the HTML for this UI - * - * @return string HTML for the UI - */ -/datum/nanoui/proc/get_html() - - // before the UI opens, add the layout files based on the layout key - add_stylesheet("layout_[layout_key].css") - add_template("layout", "layout_[layout_key].tmpl") - - var/head_content = "" - - for (var/filename in scripts) - head_content += " " - - for (var/filename in stylesheets) - head_content += " " - - var/template_data_json = "{}" // An empty JSON object - if (templates.len > 0) - template_data_json = strip_improper(json_encode(templates)) - - var/list/send_data = get_send_data(initial_data) - var/initial_data_json = replacetext(replacetext(json_encode(send_data), """, "&#34;"), "'", "'") - initial_data_json = strip_improper(initial_data_json); - - var/url_parameters_json = json_encode(list("src" = "\ref[src]")) - - return {" - - - - - - - [head_content] - - -
-
- - - - "} - - /** - * Open this UI - * - * @return nothing - */ -/datum/nanoui/proc/open() - if(!user.client) - return - - // An attempted fix to UIs sometimes locking up spamming runtime errors due to src_object being null for whatever reason. - // This hard-deletes the UI, preventing the device that uses the UI from being locked up permanently. - if(!src_object) - del(src) - - var/window_size = "" - if (width && height) - window_size = "size=[width]x[height];" - update_status(0) - if(status == STATUS_CLOSE) - return - - user << browse(get_html(), "window=[window_id];[window_size][window_options]") - winset(user, "mapwindow.map", "focus=true") // return keyboard focus to map - on_close_winset() - //onclose(user, window_id) - SSnanoui.ui_opened(src) - - /** - * Reinitialise this UI, potentially with a different template and/or initial data - * - * @return nothing - */ -/datum/nanoui/proc/reinitialise(template, new_initial_data) - if(template) - add_template("main", template) - if(new_initial_data) - set_initial_data(new_initial_data) - open() - - /** - * Close this UI - * - * @return nothing - */ -/datum/nanoui/proc/close() - is_auto_updating = 0 - SSnanoui.ui_closed(src) - user << browse(null, "window=[window_id]") - for(var/datum/nanoui/child in children) - child.close() - children.Cut() - state = null - master_ui = null - - /** - * Set the UI window to call the nanoclose verb when the window is closed - * This allows Nano to handle closed windows - * - * @return nothing - */ -/datum/nanoui/proc/on_close_winset() - if(!user.client) - return - var/params = "\ref[src]" - - winset(user, window_id, "on-close=\"nanoclose [params]\"") - - /** - * Push data to an already open UI window - * - * @return nothing - */ -/datum/nanoui/proc/push_data(data, force_push = 0) - update_status(0) - if (status == STATUS_DISABLED && !force_push) - return // Cannot update UI, no visibility - - var/list/send_data = get_send_data(data) - - //to_chat(user,list2json_usecache(send_data)) // used for debugging //NANO DEBUG HOOK - user << output(list2params(list(strip_improper(json_encode(send_data)))),"[window_id].browser:receiveUpdateData") - - /** - * This Topic() proc is called whenever a user clicks on a link within a Nano UI - * If the UI status is currently STATUS_INTERACTIVE then call the src_object Topic() - * If the src_object Topic() returns 1 (true) then update all UIs attached to src_object - * - * @return nothing - */ -/datum/nanoui/Topic(href, href_list) - update_status(0) // update the status - if (status != STATUS_INTERACTIVE || user != usr) // If UI is not interactive or usr calling Topic is not the UI user - return - - // This is used to toggle the nano map ui - var/map_update = 0 - if(href_list["showMap"]) - set_show_map(text2num(href_list["showMap"])) - map_update = 1 - - if(href_list["mapZLevel"]) - set_map_z_level(text2num(href_list["mapZLevel"])) - map_update = 1 - - if ((src_object && src_object.Topic(href, href_list, state)) || map_update) - SSnanoui.update_uis(src_object) // update all UIs attached to src_object - - /** - * Process this UI, updating the entire UI or just the status (aka visibility) - * This process proc is called by the master_controller - * - * @param update string For this UI to update - * - * @return nothing - */ -/datum/nanoui/process(update = 0) - if (!src_object || !user) - close() - return - - if (status && (update || is_auto_updating)) - update() // Update the UI (update_status() is called whenever a UI is updated) - else - update_status(1) // Not updating UI, so lets check here if status has changed - - /** - * Update the UI - * - * @return nothing - */ -/datum/nanoui/proc/update(var/force_open = 0) - src_object.ui_interact(user, ui_key, src, force_open, master_ui, state) diff --git a/code/modules/overmap/ships/computers/shuttle.dm b/code/modules/overmap/ships/computers/shuttle.dm index f51587d5942..76c0d3e6d15 100644 --- a/code/modules/overmap/ships/computers/shuttle.dm +++ b/code/modules/overmap/ships/computers/shuttle.dm @@ -47,6 +47,6 @@ else to_chat(usr,"No valid landing sites in range.") possible_d = shuttle.get_possible_destinations() - if(CanInteract(usr, global.default_state) && (D in possible_d)) + if(CanInteract(usr, GLOB.tgui_default_state) && (D in possible_d)) shuttle.set_destination(possible_d[D]) return TRUE diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index 269c0fc995e..9f4a183b31e 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -17,8 +17,10 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins active_power_usage = 200 circuit = /obj/item/weapon/circuitboard/fax - var/obj/item/weapon/card/id/scan = null // identification - var/authenticated = 0 + var/obj/item/weapon/card/id/scan = null + var/authenticated = null + var/rank = null + var/sendcooldown = 0 // to avoid spamming fax messages var/department = "Unknown" // our department var/destination = null // the department we're sending to @@ -33,91 +35,101 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins /obj/machinery/photocopier/faxmachine/attack_hand(mob/user as mob) user.set_machine(src) - ui_interact(user) + tgui_interact(user) -/** - * Display the NanoUI window for the fax machine. - * - * See NanoUI documentation for details. - */ -/obj/machinery/photocopier/faxmachine/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) +/obj/machinery/photocopier/faxmachine/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Fax", name) + ui.open() - var/list/data = list() - if(scan) - data["scanName"] = scan.name - else - data["scanName"] = null - data["bossName"] = using_map.boss_name +/obj/machinery/photocopier/faxmachine/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + data["scan"] = scan ? scan.name : null data["authenticated"] = authenticated + data["rank"] = rank + data["isAI"] = isAI(user) + data["isRobot"] = isrobot(user) + + data["bossName"] = using_map.boss_name data["copyItem"] = copyitem - if(copyitem) - data["copyItemName"] = copyitem.name - else - data["copyItemName"] = null data["cooldown"] = sendcooldown data["destination"] = destination - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "fax.tmpl", src.name, 500, 500) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(10) //this machine is so unimportant let's not have it update that often. + return data -/obj/machinery/photocopier/faxmachine/Topic(href, href_list) - if(href_list["send"]) - if(copyitem) - if (destination in admin_departments) - send_admin_fax(usr, destination) - else - sendfax(destination) +/obj/machinery/photocopier/faxmachine/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE - if (sendcooldown) - spawn(sendcooldown) // cooldown time - sendcooldown = 0 - - else if(href_list["remove"]) - if(copyitem) - if(get_dist(usr, src) >= 2) - to_chat(usr, "\The [copyitem] is too far away for you to remove it.") - return - copyitem.loc = usr.loc - usr.put_in_hands(copyitem) - to_chat(usr, "You take \the [copyitem] out of \the [src].") - copyitem = null - - if(href_list["scan"]) - if (scan) - if(ishuman(usr)) - scan.loc = usr.loc - if(!usr.get_active_hand()) + switch(action) + if("scan") + if(scan) + scan.forceMove(loc) + if(ishuman(usr) && !usr.get_active_hand()) usr.put_in_hands(scan) scan = null else - scan.loc = src.loc + var/obj/item/I = usr.get_active_hand() + if(istype(I, /obj/item/weapon/card/id)) + usr.drop_item() + I.forceMove(src) + scan = I + return TRUE + if("login") + var/login_type = text2num(params["login_type"]) + if(login_type == LOGIN_TYPE_NORMAL && istype(scan)) + if(check_access(scan)) + authenticated = scan.registered_name + rank = scan.assignment + else if(login_type == LOGIN_TYPE_AI && isAI(usr)) + authenticated = usr.name + rank = "AI" + else if(login_type == LOGIN_TYPE_ROBOT && isrobot(usr)) + authenticated = usr.name + var/mob/living/silicon/robot/R = usr + rank = "[R.modtype] [R.braintype]" + return TRUE + if("logout") + if(scan) + scan.forceMove(loc) + if(ishuman(usr) && !usr.get_active_hand()) + usr.put_in_hands(scan) scan = null - else - var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) - I.loc = src - scan = I - authenticated = 0 + authenticated = null + return TRUE + if("remove") + if(copyitem) + if(get_dist(usr, src) >= 2) + to_chat(usr, "\The [copyitem] is too far away for you to remove it.") + return + copyitem.forceMove(loc) + usr.put_in_hands(copyitem) + to_chat(usr, "You take \the [copyitem] out of \the [src].") + copyitem = null - if(href_list["dept"]) - var/lastdestination = destination - destination = input(usr, "Which department?", "Choose a department", "") as null|anything in (alldepartments + admin_departments) - if(!destination) destination = lastdestination + if(!authenticated) + return + + switch(action) + if("send") + if(copyitem) + if (destination in admin_departments) + send_admin_fax(usr, destination) + else + sendfax(destination) - if(href_list["auth"]) - if ( (!( authenticated ) && (scan)) ) - if (check_access(scan)) - authenticated = 1 + if (sendcooldown) + spawn(sendcooldown) // cooldown time + sendcooldown = 0 - if(href_list["logout"]) - authenticated = 0 + if("dept") + var/lastdestination = destination + destination = input(usr, "Which department?", "Choose a department", "") as null|anything in (alldepartments + admin_departments) + if(!destination) + destination = lastdestination - SSnanoui.update_uis(src) + return TRUE /obj/machinery/photocopier/faxmachine/attackby(obj/item/O as obj, mob/user as mob) if(O.is_multitool() && panel_open) diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 5bf6a9102ad..07009a99c09 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -33,33 +33,71 @@ /obj/machinery/photocopier/attack_hand(mob/user as mob) user.set_machine(src) - ui_interact(user) + tgui_interact(user) -/** - * Display the NanoUI window for the photocopier. - * - * See NanoUI documentation for details. - */ -/obj/machinery/photocopier/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) - - var/list/data = list() - data["copyItem"] = copyitem - data["assPresent"] = has_buckled_mobs() - data["toner"] = toner - data["copies"] = copies - data["maxCopies"] = maxcopies - if(istype(user,/mob/living/silicon)) - data["isSilicon"] = 1 - else - data["isSilicon"] = null - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "photocopier.tmpl", src.name, 300, 250) - ui.set_initial_data(data) +/obj/machinery/photocopier/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Photocopier", name) ui.open() - ui.set_auto_update(10) + +/obj/machinery/photocopier/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + data["has_item"] = copyitem || has_buckled_mobs() // VOREStation Edit: Ass copying + data["isAI"] = issilicon(user) + data["can_AI_print"] = (toner >= 5) + data["has_toner"] = !!toner + data["current_toner"] = toner + data["max_toner"] = 40 + data["num_copies"] = copies + data["max_copies"] = maxcopies + + return data + +/obj/machinery/photocopier/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + switch(action) + if("make_copy") + addtimer(CALLBACK(src, .proc/copy_operation, usr), 0) + . = TRUE + if("remove") + if(copyitem) + copyitem.loc = usr.loc + usr.put_in_hands(copyitem) + to_chat(usr, "You take \the [copyitem] out of \the [src].") + copyitem = null + else if(has_buckled_mobs()) + to_chat(buckled_mobs[1], "You feel a slight pressure on your ass.") // It can't eject your asscheeks, but it'll try. + . = TRUE + if("set_copies") + copies = clamp(text2num(params["num_copies"]), 1, maxcopies) + . = TRUE + if("ai_photo") + if(!issilicon(usr)) + return + if(stat & (BROKEN|NOPOWER)) + return + + if(toner >= 5) + var/mob/living/silicon/tempAI = usr + var/obj/item/device/camera/siliconcam/camera = tempAI.aiCamera + + if(!camera) + return + var/obj/item/weapon/photo/selection = camera.selectpicture() + if (!selection) + return + + var/obj/item/weapon/photo/p = photocopy(selection) + if (p.desc == "") + p.desc += "Copied by [tempAI.name]" + else + p.desc += " - Copied by [tempAI.name]" + toner -= 5 + . = TRUE /obj/machinery/photocopier/proc/copy_operation(var/mob/user) if(copying) @@ -104,51 +142,6 @@ use_power(active_power_usage) copying = FALSE -/obj/machinery/photocopier/Topic(href, href_list) - if(href_list["copy"]) - if(stat & (BROKEN|NOPOWER)) - return - addtimer(CALLBACK(src, .proc/copy_operation, usr), 0) - - else if(href_list["remove"]) - if(copyitem) - copyitem.loc = usr.loc - usr.put_in_hands(copyitem) - to_chat(usr, "You take \the [copyitem] out of \the [src].") - copyitem = null - else if(has_buckled_mobs()) - to_chat(buckled_mobs[1], "You feel a slight pressure on your ass.") // It can't eject your asscheeks, but it'll try. - return TOPIC_REFRESH - else if(href_list["min"]) - if(copies > 1) - copies-- - else if(href_list["add"]) - if(copies < maxcopies) - copies++ - else if(href_list["aipic"]) - if(!istype(usr,/mob/living/silicon)) return - if(stat & (BROKEN|NOPOWER)) return - - if(toner >= 5) - var/mob/living/silicon/tempAI = usr - var/obj/item/device/camera/siliconcam/camera = tempAI.aiCamera - - if(!camera) - return - var/obj/item/weapon/photo/selection = camera.selectpicture() - if (!selection) - return - - var/obj/item/weapon/photo/p = photocopy(selection) - if (p.desc == "") - p.desc += "Copied by [tempAI.name]" - else - p.desc += " - Copied by [tempAI.name]" - toner -= 5 - sleep(15) - - SSnanoui.update_uis(src) - /obj/machinery/photocopier/attackby(obj/item/O as obj, mob/user as mob) if(istype(O, /obj/item/weapon/paper) || istype(O, /obj/item/weapon/photo) || istype(O, /obj/item/weapon/paper_bundle)) if(!copyitem) diff --git a/code/modules/pda/ai.dm b/code/modules/pda/ai.dm index b8a0d99a390..9072eef96ee 100644 --- a/code/modules/pda/ai.dm +++ b/code/modules/pda/ai.dm @@ -4,7 +4,12 @@ icon_state = "NONE" ttone = "data" detonate = 0 - + touch_silent = TRUE + programs = list( + new/datum/data/pda/app/main_menu, + new/datum/data/pda/app/notekeeper, + new/datum/data/pda/app/news, + new/datum/data/pda/app/messenger) /obj/item/device/pda/ai/proc/set_name_and_job(newname as text, newjob as text, newrank as null|text) owner = newname @@ -16,70 +21,18 @@ name = newname + " (" + ownjob + ")" //AI verb and proc for sending PDA messages. -/obj/item/device/pda/ai/verb/cmd_send_pdamesg() +/obj/item/device/pda/ai/verb/cmd_pda_open_ui() set category = "AI IM" - set name = "Send PDA Message" + set name = "Use PDA" set src in usr if(!can_use()) return - var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) - if(!M) - to_chat(usr, "Cannot use messenger!") - var/list/plist = M.available_pdas() - if(plist) - var/c = input(usr, "Please select a PDA") as null|anything in sortList(plist) - if(!c) // if the user hasn't selected a PDA file we can't send a message - return - var/selected = plist[c] - M.create_message(usr, selected) - -/obj/item/device/pda/ai/verb/cmd_toggle_pda_receiver() - set category = "AI IM" - set name = "Toggle Sender/Receiver" - set src in usr - - if(!can_use()) - return - var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) - M.toff = !M.toff - to_chat(usr, "PDA sender/receiver toggled [(M.toff ? "Off" : "On")]!") - -/obj/item/device/pda/ai/verb/cmd_toggle_pda_silent() - set category = "AI IM" - set name = "Toggle Ringer" - set src in usr - - if(!can_use()) - return - var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) - M.notify_silent = !M.notify_silent - to_chat(usr, "PDA ringer toggled [(M.notify_silent ? "Off" : "On")]!") - -/obj/item/device/pda/ai/verb/cmd_show_message_log() - set category = "AI IM" - set name = "Show Message Log" - set src in usr - - if(!can_use()) - return - var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) - if(!M) - to_chat(usr, "Cannot use messenger!") - var/HTML = "AI PDA Message Log" - for(var/index in M.tnote) - if(index["sent"]) - HTML += addtext("→ To ", index["owner"],":
", index["message"], "
") - else - HTML += addtext("← From ", index["owner"],":
", index["message"], "
") - HTML +="" - usr << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0") - + tgui_interact(usr) /obj/item/device/pda/ai/can_use() return 1 - /obj/item/device/pda/ai/attack_self(mob/user as mob) if ((honkamt > 0) && (prob(60)))//For clown virus. honkamt-- @@ -90,11 +43,6 @@ /obj/item/device/pda/ai/pai ttone = "assist" var/our_owner = null // Ref to a pAI - touch_silent = TRUE - programs = list( - new/datum/data/pda/app/main_menu, - new/datum/data/pda/app/notekeeper, - new/datum/data/pda/app/messenger) /obj/item/device/pda/ai/pai/New(mob/living/silicon/pai/P) if(istype(P)) diff --git a/code/modules/pda/pda_tgui.dm b/code/modules/pda/pda_tgui.dm index 4937d423252..0d70b6db02d 100644 --- a/code/modules/pda/pda_tgui.dm +++ b/code/modules/pda/pda_tgui.dm @@ -7,10 +7,10 @@ if(!can_use()) . = min(., STATUS_UPDATE) -/obj/item/device/pda/tgui_interact(mob/user, datum/tgui/ui) +/obj/item/device/pda/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, "Pda", "Personal Data Assistant") + ui = new(user, src, "Pda", "Personal Data Assistant", parent_ui) ui.open() /obj/item/device/pda/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) diff --git a/code/modules/power/batteryrack.dm b/code/modules/power/batteryrack.dm index f6bc1c9ff68..dc1dbe7e584 100644 --- a/code/modules/power/batteryrack.dm +++ b/code/modules/power/batteryrack.dm @@ -25,6 +25,7 @@ var/equalise = 0 // If true try to equalise charge between cells var/icon_update = 0 // Timer in ticks for icon update. var/ui_tick = 0 + should_be_mapped = TRUE /obj/machinery/power/smes/batteryrack/New() @@ -113,6 +114,8 @@ if(equalise) // Now try to get least charged cell and use the power from it. var/obj/item/weapon/cell/CL = get_least_charged_cell() + if(!CL) + return amount -= CL.give(amount) if(!amount) return @@ -209,8 +212,43 @@ celldiff = min(min(celldiff, most.charge), least.maxcharge - least.charge) least.give(most.use(celldiff)) -/obj/machinery/power/smes/batteryrack/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/power/smes/batteryrack/dismantle() + for(var/obj/item/weapon/cell/C in internal_cells) + C.forceMove(get_turf(src)) + internal_cells -= C + return ..() + +/obj/machinery/power/smes/batteryrack/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + if(istype(W, /obj/item/weapon/cell)) // ID Card, try to insert it. + if(insert_cell(W, user)) + to_chat(user, "You insert \the [W] into \the [src].") + else + to_chat(user, "\The [src] has no empty slot for \the [W]") + if(!..()) + return 0 + if(default_deconstruction_crowbar(user, W)) + return + if(default_part_replacement(user, W)) + return + +/obj/machinery/power/smes/batteryrack/inputting() + return + +/obj/machinery/power/smes/batteryrack/outputting() + return + +/obj/machinery/power/smes/batteryrack/attack_hand(var/mob/user) + tgui_interact(user) + +/obj/machinery/power/smes/batteryrack/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Batteryrack", name) + ui.open() + +/obj/machinery/power/smes/batteryrack/tgui_data(mob/user) + // DO NOT CALL PARENT. + var/list/data = list() data["mode"] = mode data["transfer_max"] = max_transfer_rate @@ -238,75 +276,44 @@ cells += list(cell) data["cells_list"] = cells - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "psu.tmpl", "Cell Rack PSU", 500, 430) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data -/obj/machinery/power/smes/batteryrack/dismantle() - for(var/obj/item/weapon/cell/C in internal_cells) - C.forceMove(get_turf(src)) - internal_cells -= C - return ..() - -/obj/machinery/power/smes/batteryrack/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) - if(!..()) - return 0 - if(default_deconstruction_crowbar(user, W)) - return - if(default_part_replacement(user, W)) - return - if(istype(W, /obj/item/weapon/cell)) // ID Card, try to insert it. - if(insert_cell(W, user)) - to_chat(user, "You insert \the [W] into \the [src].") - else - to_chat(user, "\The [src] has no empty slot for \the [W]") - -/obj/machinery/power/smes/batteryrack/attack_hand(var/mob/user) - ui_interact(user) - -/obj/machinery/power/smes/batteryrack/inputting() - return - -/obj/machinery/power/smes/batteryrack/outputting() - return - -/obj/machinery/power/smes/batteryrack/Topic(href, href_list) +/obj/machinery/power/smes/batteryrack/tgui_act(action, list/params) // ..() would respond to those topic calls, but we don't want to use them at all. // Calls to these shouldn't occur anyway, due to usage of different nanoUI, but // it's here in case someone decides to try hrefhacking/modified templates. - if(href_list["input"] || href_list["output"]) - return 1 + if(!(action in list("disable", "enable", "equaliseon", "equaliseoff", "ejectcell"))) + return TRUE if(..()) - return 1 - if( href_list["disable"] ) - update_io(0) - return 1 - else if( href_list["enable"] ) - update_io(between(1, text2num(href_list["enable"]), 3)) - return 1 - else if( href_list["equaliseon"] ) - equalise = 1 - return 1 - else if( href_list["equaliseoff"] ) - equalise = 0 - return 1 - else if( href_list["ejectcell"] ) - var/obj/item/weapon/cell/C - for(var/obj/item/weapon/cell/CL in internal_cells) - if(CL.c_uid == text2num(href_list["ejectcell"])) - C = CL - break + return TRUE - if(!istype(C)) - return 1 + switch(action) + if("disable") + update_io(0) + return TRUE + if("enable") + update_io(between(1, text2num(params["enable"]), 3)) + return TRUE + if("equaliseon") + equalise = 1 + return TRUE + if("equaliseoff") + equalise = 0 + return TRUE + if("ejectcell") + var/obj/item/weapon/cell/C + for(var/obj/item/weapon/cell/CL in internal_cells) + if(CL.c_uid == text2num(params["ejectcell"])) + C = CL + break - C.forceMove(get_turf(src)) - internal_cells -= C - update_icon() - RefreshParts() - update_maxcharge() - return 1 \ No newline at end of file + if(!istype(C)) + return TRUE + + C.forceMove(get_turf(src)) + internal_cells -= C + update_icon() + RefreshParts() + update_maxcharge() + return TRUE \ No newline at end of file diff --git a/code/modules/power/grid_checker.dm b/code/modules/power/grid_checker.dm index 224eade429c..53766098f06 100644 --- a/code/modules/power/grid_checker.dm +++ b/code/modules/power/grid_checker.dm @@ -59,7 +59,7 @@ if(opened) wires.Interact(user) - return ui_interact(user) + return tgui_interact(user) /obj/machinery/power/grid_checker/proc/power_failure(var/announce = TRUE) if(announce) diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index 2caa008f0c0..1d5262044ef 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -345,59 +345,59 @@ /obj/machinery/computer/turbine_computer/attack_hand(var/mob/user as mob) if((. = ..())) return - src.interact(user) + tgui_interact(user) -/obj/machinery/computer/turbine_computer/interact(mob/user) - return ui_interact(user) +/obj/machinery/computer/turbine_computer/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "TurbineControl", name) + ui.open() -/obj/machinery/computer/turbine_computer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/computer/turbine_computer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) var/list/data = list() data["connected"] = (compressor && compressor.turbine) ? TRUE : FALSE data["compressor_broke"] = (!compressor || (compressor.stat & BROKEN)) ? TRUE : FALSE data["turbine_broke"] = (!compressor || !compressor.turbine || (compressor.turbine.stat & BROKEN)) ? TRUE : FALSE data["broken"] = (data["compressor_broke"] || data["turbine_broke"]) data["door_status"] = door_status ? TRUE : FALSE + + data["online"] = FALSE + data["power"] = 0 + data["rpm"] = 0 + data["temp"] = 0 + if(compressor && compressor.turbine) data["online"] = compressor.starter - data["power"] = DisplayPower(compressor.turbine.lastgen) + data["power"] = compressor.turbine.lastgen // DisplayPower data["rpm"] = compressor.rpm data["temp"] = compressor.gas_contained.temperature - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "turbine_computer.tmpl", name, 520, 440) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every Master Controller tick - ui.set_auto_update(TRUE) + return data -/obj/machinery/computer/turbine_computer/Topic(href, href_list) +/obj/machinery/computer/turbine_computer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return - if(href_list["power-on"]) - if(compressor && compressor.turbine) - compressor.starter = TRUE + return TRUE + + switch(action) + if("power-on") + if(compressor && compressor.turbine) + compressor.starter = TRUE + . = TRUE + if("power-off") + if(compressor && compressor.turbine) + compressor.starter = FALSE + . = TRUE + if("reconnect") + locate_machinery() . = TRUE - else if(href_list["power-off"]) - if(compressor && compressor.turbine) - compressor.starter = FALSE + if("doors") + door_status = !door_status + for(var/obj/machinery/door/blast/D in src.doors) + if (door_status) + spawn(0) D.close() + else + spawn(0)D.open() . = TRUE - else if(href_list["reconnect"]) - locate_machinery() - . = TRUE - else if(href_list["doors"]) - door_status = !door_status - for(var/obj/machinery/door/blast/D in src.doors) - if (door_status) - spawn(0) D.close() - else - spawn(0)D.open() - . = TRUE #undef COMPFRICTION #undef COMPSTARTERLOAD diff --git a/code/modules/reagents/dispenser/dispenser2_energy.dm b/code/modules/reagents/dispenser/dispenser2_energy.dm index 84c5260c3fe..b0dec9f65bc 100644 --- a/code/modules/reagents/dispenser/dispenser2_energy.dm +++ b/code/modules/reagents/dispenser/dispenser2_energy.dm @@ -25,7 +25,7 @@ C.reagents.add_reagent(id, to_restore) . = 1 if(.) - SSnanoui.update_uis(src) + SStgui.update_uis(src) /obj/machinery/chemical_dispenser dispense_reagents = list( diff --git a/code/modules/resleeving/infomorph.dm b/code/modules/resleeving/infomorph.dm index 248444f1dff..fed79fe078f 100644 --- a/code/modules/resleeving/infomorph.dm +++ b/code/modules/resleeving/infomorph.dm @@ -147,9 +147,9 @@ var/list/infomorph_emotions = list( return 0 ..() -/mob/living/silicon/infomorph/default_can_use_topic(var/src_object) +/mob/living/silicon/infomorph/default_can_use_tgui_topic(var/src_object) if(src_object in src) - return shared_nano_interaction() + return shared_tgui_interaction() /////////// DAMAGES /mob/living/silicon/infomorph/emp_act(severity) @@ -190,7 +190,7 @@ var/list/infomorph_emotions = list( medicalActive1 = null medicalActive2 = null medical_cannotfind = 0 - SSnanoui.update_uis(src) + SStgui.update_uis(src) to_chat(usr, "You reset your record-viewing software.") /* @@ -463,94 +463,81 @@ var/global/list/default_infomorph_software = list() set category = "Card Commands" set name = "Software Interface" - ui_interact(src) + tgui_interact(src) -/mob/living/silicon/infomorph/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, key_state = self_state) - if(user != src) - if(ui) ui.set_status(STATUS_CLOSE, 0) - return +/mob/living/silicon/infomorph/tgui_state(mob/user) + return GLOB.tgui_self_state - if(ui_key != "main") - var/datum/infomorph_software/S = software[ui_key] - if(S && !S.toggle) - S.on_ui_interact(src, ui, force_open) - else - if(ui) ui.set_status(STATUS_CLOSE, 0) - return - - var/data[0] +/mob/living/silicon/infomorph/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIInterface", "Card Software Interface") + ui.open() +/mob/living/silicon/infomorph/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + // Software we have bought - var/bought_software[0] + var/list/bought_software = list() // Software we have not bought - var/not_bought_software[0] + var/list/not_bought_software = list() for(var/key in infomorph_software_by_key) var/datum/infomorph_software/S = infomorph_software_by_key[key] - var/software_data[0] + var/list/software_data = list() software_data["name"] = S.name software_data["id"] = S.id if(key in software) software_data["on"] = S.is_active(src) - bought_software[++bought_software.len] = software_data + bought_software.Add(list(software_data)) else software_data["ram"] = S.ram_cost - not_bought_software[++not_bought_software.len] = software_data + not_bought_software.Add(list(software_data)) data["bought"] = bought_software data["not_bought"] = not_bought_software data["available_ram"] = ram // Emotions - var/emotions[0] + var/list/emotions = list() for(var/name in infomorph_emotions) - var/emote[0] + var/list/emote = list() emote["name"] = name emote["id"] = infomorph_emotions[name] - emotions[++emotions.len] = emote + emotions.Add(list(emote)) data["emotions"] = emotions data["current_emotion"] = card.current_emotion - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open, key_state) - if (!ui) - ui = new(user, src, ui_key, "pai_interface.tmpl", "Card Software Interface", 450, 600, state = key_state) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data -/mob/living/silicon/infomorph/Topic(href, href_list) - . = ..() - if(.) return +/mob/living/silicon/infomorph/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE - if(href_list["software"]) - var/soft = href_list["software"] - var/datum/infomorph_software/S = software[soft] - if(S.toggle) - S.toggle(src) - else - ui_interact(src, ui_key = soft) - return 1 + switch(action) + if("software") + var/soft = params["software"] + var/datum/infomorph_software/S = software[soft] + if(S.toggle) + S.toggle(src) + else + S.tgui_interact(src, parent_ui = ui) + return TRUE - else if(href_list["stopic"]) - var/soft = href_list["stopic"] - var/datum/infomorph_software/S = software[soft] - if(S) - return S.Topic(href, href_list) + if("purchase") + var/soft = params["purchase"] + var/datum/infomorph_software/S = infomorph_software_by_key[soft] + if(S && (ram >= S.ram_cost)) + ram -= S.ram_cost + software[S.id] = S + return TRUE - else if(href_list["purchase"]) - var/soft = href_list["purchase"] - var/datum/infomorph_software/S = infomorph_software_by_key[soft] - if(S && (ram >= S.ram_cost)) - ram -= S.ram_cost - software[S.id] = S - return 1 - - else if(href_list["image"]) - var/img = href_list["image"] - if(img) - card.setEmotion(img) - return 1 + if("image") + var/img = text2num(params["image"]) + if(img) + card.setEmotion(img) + return TRUE /mob/living/silicon/infomorph/examine(mob/user) . = ..(user, infix = ", personal AI") diff --git a/code/modules/resleeving/infomorph_software.dm b/code/modules/resleeving/infomorph_software.dm index 2d2439b614a..67a2bd47f93 100644 --- a/code/modules/resleeving/infomorph_software.dm +++ b/code/modules/resleeving/infomorph_software.dm @@ -12,35 +12,38 @@ // Whether pAIs should automatically receive this module at no cost var/default = 0 - proc/on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) - return +/datum/infomorph_software/tgui_state(mob/user) + return GLOB.tgui_always_state - proc/toggle(mob/living/silicon/infomorph/user) - return +/datum/infomorph_software/tgui_status(mob/user) + if(!istype(user, /mob/living/silicon/infomorph)) + return STATUS_CLOSE + return ..() - proc/is_active(mob/living/silicon/infomorph/user) - return 0 +/datum/infomorph_software/proc/toggle(mob/living/silicon/infomorph/user) + return + +/datum/infomorph_software/proc/is_active(mob/living/silicon/infomorph/user) + return 0 /datum/infomorph_software/crew_manifest name = "Crew Manifest" - ram_cost = 15 + ram_cost = 5 id = "manifest" toggle = 0 - on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) +/datum/infomorph_software/crew_manifest/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "CrewManifest", name, parent_ui) + ui.open() + +/datum/infomorph_software/crew_manifest/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + if(data_core) data_core.get_manifest_list() - - var/data[0] - // This is dumb, but NanoUI breaks if it has no data to send - data["manifest"] = PDA_Manifest - - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_manifest.tmpl", "Crew Manifest", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + data["manifest"] = PDA_Manifest + return data /datum/infomorph_software/med_records name = "Medical Records" @@ -48,53 +51,55 @@ id = "med_records" toggle = 0 - on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/infomorph_software/med_records/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIMedrecords", name, parent_ui) + ui.open() - var/records[0] - for(var/datum/data/record/general in sortRecord(data_core.general)) - var/record[0] - record["name"] = general.fields["name"] - record["ref"] = "\ref[general]" - records[++records.len] = record +/datum/infomorph_software/med_records/tgui_data(mob/living/silicon/infomorph/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/list/records = list() + for(var/datum/data/record/general in sortRecord(data_core.general)) + var/list/record = list() + record["name"] = general.fields["name"] + record["ref"] = "\ref[general]" + records.Add(list(record)) - data["records"] = records + data["records"] = records - var/datum/data/record/G = user.medicalActive1 - var/datum/data/record/M = user.medicalActive2 - data["general"] = G ? G.fields : null - data["medical"] = M ? M.fields : null - data["could_not_find"] = user.medical_cannotfind + var/datum/data/record/G = user.medicalActive1 + var/datum/data/record/M = user.medicalActive2 + data["general"] = G ? G.fields : null + data["medical"] = M ? M.fields : null + data["could_not_find"] = user.medical_cannotfind - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_medrecords.tmpl", "Medical Records", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data - Topic(href, href_list) - var/mob/living/silicon/infomorph/P = usr - if(!istype(P)) return +/datum/infomorph_software/med_records/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + . = ..() + var/mob/living/silicon/infomorph/P = usr + if(!istype(P)) + return - if(href_list["select"]) - var/datum/data/record/record = locate(href_list["select"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/M = null - if (!( data_core.general.Find(R) )) - P.medical_cannotfind = 1 - else - P.medical_cannotfind = 0 - for(var/datum/data/record/E in data_core.medical) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - M = E - P.medicalActive1 = R - P.medicalActive2 = M - else + if(action == "select") + var/datum/data/record/record = locate(params["select"]) + if(record) + var/datum/data/record/R = record + var/datum/data/record/M = null + if (!( data_core.general.Find(R) )) P.medical_cannotfind = 1 - return 1 + else + P.medical_cannotfind = 0 + for(var/datum/data/record/E in data_core.medical) + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + M = E + P.medicalActive1 = R + P.medicalActive2 = M + else + P.medical_cannotfind = 1 + return 1 /datum/infomorph_software/sec_records name = "Security Records" @@ -102,57 +107,59 @@ id = "sec_records" toggle = 0 - on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/infomorph_software/sec_records/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAISecrecords", name, parent_ui) + ui.open() - var/records[0] - for(var/datum/data/record/general in sortRecord(data_core.general)) - var/record[0] - record["name"] = general.fields["name"] - record["ref"] = "\ref[general]" - records[++records.len] = record +/datum/infomorph_software/sec_records/tgui_data(mob/living/silicon/infomorph/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/list/records = list() + for(var/datum/data/record/general in sortRecord(data_core.general)) + var/list/record = list() + record["name"] = general.fields["name"] + record["ref"] = "\ref[general]" + records.Add(list(record)) - data["records"] = records + data["records"] = records - var/datum/data/record/G = user.securityActive1 - var/datum/data/record/S = user.securityActive2 - data["general"] = G ? G.fields : null - data["security"] = S ? S.fields : null - data["could_not_find"] = user.security_cannotfind + var/datum/data/record/G = user.securityActive1 + var/datum/data/record/S = user.securityActive2 + data["general"] = G ? G.fields : null + data["security"] = S ? S.fields : null + data["could_not_find"] = user.security_cannotfind - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_secrecords.tmpl", "Security Records", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data - Topic(href, href_list) - var/mob/living/silicon/infomorph/P = usr - if(!istype(P)) return +/datum/infomorph_software/sec_records/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + . = ..() + var/mob/living/silicon/infomorph/P = usr + if(!istype(P)) + return - if(href_list["select"]) - var/datum/data/record/record = locate(href_list["select"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/S = null - if (!( data_core.general.Find(R) )) - P.securityActive1 = null - P.securityActive2 = null - P.security_cannotfind = 1 - else - P.security_cannotfind = 0 - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - S = E - P.securityActive1 = R - P.securityActive2 = S - else + if(action == "select") + var/datum/data/record/record = locate(params["select"]) + if(record) + var/datum/data/record/R = record + var/datum/data/record/S = null + if (!( data_core.general.Find(R) )) P.securityActive1 = null P.securityActive2 = null P.security_cannotfind = 1 - return 1 + else + P.security_cannotfind = 0 + for(var/datum/data/record/E in data_core.security) + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + S = E + P.securityActive1 = R + P.securityActive2 = S + else + P.securityActive1 = null + P.securityActive2 = null + P.security_cannotfind = 1 + return TRUE /datum/infomorph_software/door_jack name = "Door Jack" @@ -160,44 +167,45 @@ id = "door_jack" toggle = 0 - on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/infomorph_software/door_jack/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIDoorjack", "Door Jack", parent_ui) + ui.open() - data["cable"] = user.cable != null - data["machine"] = user.cable && (user.cable.machine != null) - data["inprogress"] = user.hackdoor != null - data["progress_a"] = round(user.hackprogress) - data["progress_b"] = user.hackprogress % 10 - data["aborted"] = user.hack_aborted +/datum/infomorph_software/door_jack/tgui_data(mob/living/silicon/infomorph/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_doorjack.tmpl", "Door Jack", 300, 150) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + data["cable"] = user.cable != null + data["machine"] = user.cable && (user.cable.machine != null) + data["inprogress"] = user.hackdoor != null + data["progress_a"] = round(user.hackprogress / 10) + data["progress_b"] = user.hackprogress % 10 + data["aborted"] = user.hack_aborted - Topic(href, href_list) - var/mob/living/silicon/infomorph/P = usr - if(!istype(P)) return + return data - if(href_list["jack"]) +/datum/infomorph_software/door_jack/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + var/mob/living/silicon/infomorph/P = usr + if(!istype(P) || ..()) + return TRUE + + switch(action) + if("jack") if(P.cable && P.cable.machine) P.hackdoor = P.cable.machine P.hackloop() return 1 - else if(href_list["cancel"]) + if("cancel") P.hackdoor = null return 1 - else if(href_list["cable"]) + if("cable") var/turf/T = get_turf(P) P.hack_aborted = 0 P.cable = new /obj/item/weapon/pai_cable(T) - if(ishuman(P.card.loc)) - var/mob/living/carbon/human/H = P.card.loc - H.put_in_any_hand_if_possible(P.cable) - T.visible_message("A port on \the [P] opens to reveal \the [P.cable].") + for(var/mob/M in viewers(T)) + M.show_message("A port on [P] opens to reveal [P.cable], which promptly falls to the floor.", 3, + "You hear the soft click of something light and hard falling to the ground.", 2) return 1 /mob/living/silicon/infomorph/proc/hackloop() @@ -239,43 +247,54 @@ /datum/infomorph_software/atmosphere_sensor name = "Atmosphere Sensor" - ram_cost = 15 + ram_cost = 5 id = "atmos_sense" toggle = 0 - on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/infomorph_software/atmosphere_sensor/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "pAIAtmos", name, parent_ui) + ui.open() - var/turf/T = get_turf_or_move(user.loc) - if(!T) - data["reading"] = 0 - data["pressure"] = 0 - data["temperature"] = 0 - data["temperatureC"] = 0 - data["gas"] = list() - else - var/datum/gas_mixture/env = T.return_air() - data["reading"] = 1 - var/pres = env.return_pressure() * 10 - data["pressure"] = "[round(pres/10)].[pres%10]" - data["temperature"] = round(env.temperature) - data["temperatureC"] = round(env.temperature-T0C) +/datum/infomorph_software/atmosphere_sensor/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() - var/t_moles = env.total_moles - var/gases[0] - for(var/g in env.gas) - var/gas[0] - gas["name"] = gas_data.name[g] - gas["percent"] = round((env.gas[g] / t_moles) * 100) - gases[++gases.len] = gas - data["gas"] = gases + var/list/results = list() + var/turf/T = get_turf(user) + if(!isnull(T)) + var/datum/gas_mixture/environment = T.return_air() + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles + if (total_moles) + var/o2_level = environment.gas["oxygen"]/total_moles + var/n2_level = environment.gas["nitrogen"]/total_moles + var/co2_level = environment.gas["carbon_dioxide"]/total_moles + var/phoron_level = environment.gas["phoron"]/total_moles + var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level) - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_atmosphere.tmpl", "Atmosphere Sensor", 350, 300) - ui.set_initial_data(data) - ui.open() + // entry is what the element is describing + // Type identifies which unit or other special characters to use + // Val is the information reported + // Bad_high/_low are the values outside of which the entry reports as dangerous + // Poor_high/_low are the values outside of which the entry reports as unideal + // Values were extracted from the template itself + results = list( + list("entry" = "Pressure", "units" = "kPa", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80), + list("entry" = "Temperature", "units" = "°C", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5), + list("entry" = "Oxygen", "units" = "kPa", "val" = "[round(o2_level*100,0.1)]", "bad_high" = 140, "poor_high" = 135, "poor_low" = 19, "bad_low" = 17), + list("entry" = "Nitrogen", "units" = "kPa", "val" = "[round(n2_level*100,0.1)]", "bad_high" = 105, "poor_high" = 85, "poor_low" = 50, "bad_low" = 40), + list("entry" = "Carbon Dioxide", "units" = "kPa", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0), + list("entry" = "Phoron", "units" = "kPa", "val" = "[round(phoron_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0), + list("entry" = "Other", "units" = "kPa", "val" = "[round(unknown_level, 0.01)]", "bad_high" = 1, "poor_high" = 0.5, "poor_low" = 0, "bad_low" = 0) + ) + + if(isnull(results)) + results = list(list("entry" = "pressure", "units" = "kPa", "val" = "0", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80)) + + data["aircontents"] = results + + return data /datum/infomorph_software/ar_hud name = "AR HUD" @@ -302,45 +321,56 @@ is_active(mob/living/silicon/infomorph/user) return user.translator.listening + /datum/infomorph_software/signaller - name = "Remote Signaller" - ram_cost = 15 + name = "Remote Signaler" + ram_cost = 5 id = "signaller" toggle = 0 - on_ui_interact(mob/living/silicon/infomorph/user, datum/nanoui/ui=null, force_open=1) - var/data[0] +/datum/infomorph_software/signaller/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Signaler", "Signaler", parent_ui) + ui.open() - data["frequency"] = format_frequency(user.sradio.frequency) - data["code"] = user.sradio.code +/datum/infomorph_software/signaller/tgui_data(mob/living/silicon/infomorph/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/obj/item/radio/integrated/signal/R = user.sradio - ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_signaller.tmpl", "Signaller", 320, 150) - ui.set_initial_data(data) - ui.open() + data["frequency"] = R.frequency + data["minFrequency"] = RADIO_LOW_FREQ + data["maxFrequency"] = RADIO_HIGH_FREQ + data["code"] = R.code - Topic(href, href_list) - var/mob/living/silicon/infomorph/P = usr - if(!istype(P)) return + return data - if(href_list["send"]) - P.sradio.send_signal("ACTIVATE") - for(var/mob/O in hearers(1, P.loc)) - O.show_message("[bicon(P)] *beep* *beep*", 3, "*beep* *beep*", 2) - return 1 +/datum/infomorph_software/signaller/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE - else if(href_list["freq"]) - var/new_frequency = (P.sradio.frequency + text2num(href_list["freq"])) - if(new_frequency < PUBLIC_LOW_FREQ || new_frequency > PUBLIC_HIGH_FREQ) - new_frequency = sanitize_frequency(new_frequency) - P.sradio.set_frequency(new_frequency) - return 1 + var/mob/living/silicon/infomorph/user = usr + if(istype(user)) + var/obj/item/radio/integrated/signal/R = user.sradio - else if(href_list["code"]) - P.sradio.code += text2num(href_list["code"]) - P.sradio.code = round(P.sradio.code) - P.sradio.code = min(100, P.sradio.code) - P.sradio.code = max(1, P.sradio.code) - return 1 + switch(action) + if("signal") + spawn(0) + R.send_signal("ACTIVATE") + for(var/mob/O in hearers(1, R.loc)) + O.show_message("[bicon(R)] *beep* *beep*", 3, "*beep* *beep*", 2) + if("freq") + var/frequency = unformat_frequency(params["freq"]) + frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ) + R.set_frequency(frequency) + . = TRUE + if("code") + R.code = clamp(round(text2num(params["code"])), 1, 100) + . = TRUE + if("reset") + if(params["reset"] == "freq") + R.set_frequency(initial(R.frequency)) + else + R.code = initial(R.code) + . = TRUE diff --git a/code/modules/resleeving/sleevecard.dm b/code/modules/resleeving/sleevecard.dm index 7da45bbdb1c..1fc6b8decaf 100644 --- a/code/modules/resleeving/sleevecard.dm +++ b/code/modules/resleeving/sleevecard.dm @@ -1,6 +1,9 @@ /obj/item/device/radio/sleevecard canhear_range = 0 +/obj/item/device/radio/sleevecard/tgui_state(mob/user) + return GLOB.tgui_always_state + /obj/item/device/sleevecard name = "sleevecard" desc = "This KHI-upgraded pAI module has enough capacity to run a whole mind of human-level intelligence." diff --git a/code/modules/shuttles/shuttle_console_multi.dm b/code/modules/shuttles/shuttle_console_multi.dm index 9226caebfb7..2e45441b1a1 100644 --- a/code/modules/shuttles/shuttle_console_multi.dm +++ b/code/modules/shuttles/shuttle_console_multi.dm @@ -26,7 +26,7 @@ switch(action) if("pick") var/dest_key = input("Choose shuttle destination", "Shuttle Destination") as null|anything in shuttle.get_destinations() - if(dest_key && CanInteract(usr, global.default_state)) + if(dest_key && CanInteract(usr, GLOB.tgui_default_state)) shuttle.set_destination(dest_key, usr) return TRUE diff --git a/code/modules/shuttles/shuttle_emergency.dm b/code/modules/shuttles/shuttle_emergency.dm index b6302a50d11..8a947154a77 100644 --- a/code/modules/shuttles/shuttle_emergency.dm +++ b/code/modules/shuttles/shuttle_emergency.dm @@ -175,84 +175,3 @@ /obj/machinery/computer/shuttle_control/emergency/attackby(obj/item/weapon/W as obj, mob/user as mob) read_authorization(W) ..() - -/obj/machinery/computer/shuttle_control/emergency/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - var/datum/shuttle/autodock/ferry/emergency/shuttle = SSshuttles.shuttles[shuttle_tag] - if (!istype(shuttle)) - return - - var/shuttle_state - switch(shuttle.moving_status) - if(SHUTTLE_IDLE) shuttle_state = "idle" - if(SHUTTLE_WARMUP) shuttle_state = "warmup" - if(SHUTTLE_INTRANSIT) shuttle_state = "in_transit" - - var/shuttle_status - switch (shuttle.process_state) - if(IDLE_STATE) - if (shuttle.in_use) - shuttle_status = "Busy." - else if (!shuttle.location) - shuttle_status = "Standing by at [station_name()]." - else - shuttle_status = "Standing by at [using_map.dock_name]." - if(WAIT_LAUNCH, FORCE_LAUNCH) - shuttle_status = "Shuttle has received command and will depart shortly." - if(WAIT_ARRIVE) - shuttle_status = "Proceeding to destination." - if(WAIT_FINISH) - shuttle_status = "Arriving at destination now." - - //build a list of authorizations - var/list/auth_list[req_authorizations] - - if (!emagged) - var/i = 1 - for (var/dna_hash in authorized) - auth_list[i++] = list("auth_name"=authorized[dna_hash], "auth_hash"=dna_hash) - - while (i <= req_authorizations) //fill up the rest of the list with blank entries - auth_list[i++] = list("auth_name"="", "auth_hash"=null) - else - for (var/i = 1; i <= req_authorizations; i++) - auth_list[i] = list("auth_name"="ERROR", "auth_hash"=null) - - var/has_auth = has_authorization() - - data = list( - "shuttle_status" = shuttle_status, - "shuttle_state" = shuttle_state, - "has_docking" = shuttle.active_docking_controller? 1 : 0, - "docking_status" = shuttle.active_docking_controller? shuttle.active_docking_controller.get_docking_status() : null, - "docking_override" = shuttle.active_docking_controller? shuttle.active_docking_controller.override_enabled : null, - "can_launch" = shuttle.can_launch(src), - "can_cancel" = shuttle.can_cancel(src), - "can_force" = shuttle.can_force(src), - "auth_list" = auth_list, - "has_auth" = has_auth, - "user" = debug? user : null, - ) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - - if (!ui) - ui = new(user, src, ui_key, "escape_shuttle_control_console.tmpl", "Shuttle Control", 470, 420) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/computer/shuttle_control/emergency/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["removeid"]) - var/dna_hash = href_list["removeid"] - authorized -= dna_hash - - if(!emagged && href_list["scanid"]) - //They selected an empty entry. Try to scan their id. - if (ishuman(usr)) - var/mob/living/carbon/human/H = usr - if (!read_authorization(H.get_active_hand())) //try to read what's in their hand first - read_authorization(H.wear_id) diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm index 1119e565eff..d2a6a0a35a4 100644 --- a/code/modules/telesci/telesci_computer.dm +++ b/code/modules/telesci/telesci_computer.dm @@ -6,7 +6,7 @@ circuit = /obj/item/weapon/circuitboard/telesci_console var/sending = 1 var/obj/machinery/telepad/telepad = null - var/temp_msg = "Telescience control console initialized.
Welcome." + var/temp_msg = "Telescience control console initialized. Welcome." // VARIABLES // var/teles_left // How many teleports left until it becomes uncalibrated @@ -83,16 +83,21 @@ /obj/machinery/computer/telescience/attack_hand(mob/user) if(..()) return - ui_interact(user) + tgui_interact(user) -/obj/machinery/computer/telescience/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) +/obj/machinery/computer/telescience/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "TelesciConsole", name) + ui.open() - var/data[0] +/obj/machinery/computer/telescience/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = list() if(!telepad) in_use = 0 //Yeah so if you deconstruct teleporter while its in the process of shooting it wont disable the console data["noTelepad"] = 1 else + data["noTelepad"] = 0 data["insertedGps"] = inserted_gps data["rotation"] = rotation data["currentZ"] = z_co @@ -110,6 +115,7 @@ //We'll base our options on connected z's or overmap data["sectorOptions"] = using_map.get_map_levels(z, TRUE, overmap_range) + data["lastTeleData"] = null if(last_tele_data) data["lastTeleData"] = list() data["lastTeleData"]["src_x"] = last_tele_data.src_x @@ -117,12 +123,61 @@ data["lastTeleData"]["distance"] = last_tele_data.distance data["lastTeleData"]["time"] = last_tele_data.time - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "telescience_console.tmpl", src.name, 400, 450) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(5) + return data + +/obj/machinery/computer/telescience/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + if(!telepad || telepad.panel_open) + return TRUE + + switch(action) + if("setrotation") + rotation = CLAMP(text2num(params["val"]), -900, 900) + rotation = round(rotation, 0.01) + + if("setdistance") + distance = CLAMP(text2num(params["val"]), 1, get_max_allowed_distance()) + distance = FLOOR(distance, 1) + + if("setz") + var/new_z = text2num(params["setz"]) + if(new_z in using_map.player_levels) + z_co = new_z + + if("ejectGPS") + if(inserted_gps) + inserted_gps.forceMove(loc) + inserted_gps = null + + if("setMemory") + if(last_target && inserted_gps) + // TODO - What was this even supposed to do?? + //inserted_gps.locked_location = last_target + temp_msg = "Location saved." + else + temp_msg = "ERROR! No data was stored." + + if("send") + sending = 1 + teleport(usr) + + if("receive") + sending = 0 + teleport(usr) + + if("recal") + recalibrate() + sparks() + temp_msg = "NOTICE: Calibration successful." + + if("eject") + eject() + temp_msg = "NOTICE: Bluespace crystals ejected." + else + return FALSE + + return TRUE /obj/machinery/computer/telescience/proc/sparks() if(telepad) @@ -198,7 +253,7 @@ playsound(telepad, 'sound/weapons/flash.ogg', 50, 1) // Wait depending on the time the projectile took to get there teleporting = 1 - temp_msg = "Powering up bluespace crystals.
Please wait." + temp_msg = "Powering up bluespace crystals. Please wait." spawn(spawn_time) // in deciseconds if(!telepad) @@ -218,12 +273,12 @@ if(!A || (A.flags & BLUE_SHIELDED)) telefail() - temp_msg = "ERROR!
Target is shielded from bluespace intersection!" + temp_msg = "ERROR! Target is shielded from bluespace intersection!" return - temp_msg = "Teleport successful.
" + temp_msg = "Teleport successful. " if(teles_left < 10) - temp_msg += "Calibration required soon.
" + temp_msg += "Calibration required soon. " temp_msg += "Data printed below." var/sparks = get_turf(target) @@ -286,11 +341,11 @@ /obj/machinery/computer/telescience/proc/teleport(mob/user) distance = CLAMP(distance, 0, get_max_allowed_distance()) if(rotation == null || distance == null || z_co == null) - temp_msg = "ERROR!
Set a distance, rotation and sector." + temp_msg = "ERROR! Set a distance, rotation and sector." return if(distance <= 0) telefail() - temp_msg = "ERROR!
No distance selected!" + temp_msg = "ERROR! No distance selected!" return if(!(z_co in using_map.player_levels)) telefail() @@ -300,7 +355,7 @@ doteleport(user) else telefail() - temp_msg = "ERROR!
Calibration required." + temp_msg = "ERROR! Calibration required." return return @@ -310,64 +365,6 @@ crystals -= I distance = 0 -/obj/machinery/computer/telescience/Topic(href, href_list) - if(..()) - return - if(!telepad || telepad.panel_open) - updateDialog() - return - - if(href_list["setrotation"]) - var/new_rot = input("Please input desired bearing in degrees.", name, rotation) as num - if(..()) // Check after we input a value, as they could've moved after they entered something - return - rotation = CLAMP(new_rot, -900, 900) - rotation = round(rotation, 0.01) - - if(href_list["setdistance"]) - var/new_pow = input("Please input desired distance in meters.", name, rotation) as num - if(..()) // Check after we input a value, as they could've moved after they entered something - return - distance = CLAMP(new_pow, 1, get_max_allowed_distance()) - distance = FLOOR(distance, 1) - - if(href_list["setz"]) - var/new_z = text2num(href_list["setz"]) - if(new_z in using_map.player_levels) - z_co = new_z - - if(href_list["ejectGPS"]) - if(inserted_gps) - inserted_gps.forceMove(loc) - inserted_gps = null - - if(href_list["setMemory"]) - if(last_target && inserted_gps) - // TODO - What was this even supposed to do?? - //inserted_gps.locked_location = last_target - temp_msg = "Location saved." - else - temp_msg = "ERROR!
No data was stored." - - if(href_list["send"]) - sending = 1 - teleport(usr) - - if(href_list["receive"]) - sending = 0 - teleport(usr) - - if(href_list["recal"]) - recalibrate() - sparks() - temp_msg = "NOTICE:
Calibration successful." - - if(href_list["eject"]) - eject() - temp_msg = "NOTICE:
Bluespace crystals ejected." - - updateDialog() - /obj/machinery/computer/telescience/proc/recalibrate() teles_left = rand(40, 50) distance_off = rand(-4, 4) diff --git a/code/modules/tgui/modules/agentcard.dm b/code/modules/tgui/modules/agentcard.dm new file mode 100644 index 00000000000..7d35a9bc4a3 --- /dev/null +++ b/code/modules/tgui/modules/agentcard.dm @@ -0,0 +1,135 @@ +/datum/tgui_module/agentcard + name = "Agent Card" + tgui_id = "AgentCard" + +/datum/tgui_module/agentcard/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/obj/item/weapon/card/id/syndicate/S = tgui_host() + if(!istype(S)) + return list() + + var/list/entries = list() + entries += list(list("name" = "Age", "value" = S.age)) + entries += list(list("name" = "Appearance", "value" = "Set")) + entries += list(list("name" = "Assignment", "value" = S.assignment)) + entries += list(list("name" = "Blood Type", "value" = S.blood_type)) + entries += list(list("name" = "DNA Hash", "value" = S.dna_hash)) + entries += list(list("name" = "Fingerprint Hash", "value" = S.fingerprint_hash)) + entries += list(list("name" = "Name", "value" = S.registered_name)) + entries += list(list("name" = "Photo", "value" = "Update")) + entries += list(list("name" = "Sex", "value" = S.sex)) + entries += list(list("name" = "Factory Reset", "value" = "Use With Care")) + data["entries"] = entries + + data["electronic_warfare"] = S.electronic_warfare + + return data + +/datum/tgui_module/agentcard/tgui_status(mob/user, datum/tgui_state/state) + var/obj/item/weapon/card/id/syndicate/S = tgui_host() + if(!istype(S)) + return STATUS_CLOSE + if(user != S.registered_user) + return STATUS_CLOSE + return ..() + +/datum/tgui_module/agentcard/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + var/obj/item/weapon/card/id/syndicate/S = tgui_host() + switch(action) + if("electronic_warfare") + S.electronic_warfare = !S.electronic_warfare + to_chat(usr, "Electronic warfare [S.electronic_warfare ? "enabled" : "disabled"].") + . = TRUE + if("age") + var/new_age = input(usr,"What age would you like to put on this card?","Agent Card Age", S.age) as null|num + if(!isnull(new_age) && tgui_status(usr, state) == STATUS_INTERACTIVE) + if(new_age < 0) + S.age = initial(S.age) + else + S.age = new_age + to_chat(usr, "Age has been set to '[S.age]'.") + . = TRUE + if("appearance") + var/datum/card_state/choice = input(usr, "Select the appearance for this card.", "Agent Card Appearance") as null|anything in id_card_states() + if(choice && tgui_status(usr, state) == STATUS_INTERACTIVE) + S.icon_state = choice.icon_state + S.item_state = choice.item_state + to_chat(usr, "Appearance changed to [choice].") + . = TRUE + if("assignment") + var/new_job = sanitize(input(usr,"What assignment would you like to put on this card?\nChanging assignment will not grant or remove any access levels.","Agent Card Assignment", S.assignment) as null|text) + if(!isnull(new_job) && tgui_status(usr, state) == STATUS_INTERACTIVE) + S.assignment = new_job + to_chat(usr, "Occupation changed to '[new_job]'.") + S.update_name() + . = TRUE + if("bloodtype") + var/default = S.blood_type + if(default == initial(S.blood_type) && ishuman(usr)) + var/mob/living/carbon/human/H = usr + if(H.dna) + default = H.dna.b_type + var/new_blood_type = sanitize(input(usr,"What blood type would you like to be written on this card?","Agent Card Blood Type",default) as null|text) + if(!isnull(new_blood_type) && tgui_status(usr, state) == STATUS_INTERACTIVE) + S.blood_type = new_blood_type + to_chat(usr, "Blood type changed to '[new_blood_type]'.") + . = TRUE + if("dnahash") + var/default = S.dna_hash + if(default == initial(S.dna_hash) && ishuman(usr)) + var/mob/living/carbon/human/H = usr + if(H.dna) + default = H.dna.unique_enzymes + var/new_dna_hash = sanitize(input(usr,"What DNA hash would you like to be written on this card?","Agent Card DNA Hash",default) as null|text) + if(!isnull(new_dna_hash) && tgui_status(usr, state) == STATUS_INTERACTIVE) + S.dna_hash = new_dna_hash + to_chat(usr, "DNA hash changed to '[new_dna_hash]'.") + . = TRUE + if("fingerprinthash") + var/default = S.fingerprint_hash + if(default == initial(S.fingerprint_hash) && ishuman(usr)) + var/mob/living/carbon/human/H = usr + if(H.dna) + default = md5(H.dna.uni_identity) + var/new_fingerprint_hash = sanitize(input(usr,"What fingerprint hash would you like to be written on this card?","Agent Card Fingerprint Hash",default) as null|text) + if(!isnull(new_fingerprint_hash) && tgui_status(usr, state) == STATUS_INTERACTIVE) + S.fingerprint_hash = new_fingerprint_hash + to_chat(usr, "Fingerprint hash changed to '[new_fingerprint_hash]'.") + . = TRUE + if("name") + var/new_name = sanitizeName(input(usr,"What name would you like to put on this card?","Agent Card Name", S.registered_name) as null|text) + if(!isnull(new_name) && tgui_status(usr, state) == STATUS_INTERACTIVE) + S.registered_name = new_name + S.update_name() + to_chat(usr, "Name changed to '[new_name]'.") + . = TRUE + if("photo") + S.set_id_photo(usr) + to_chat(usr, "Photo changed.") + . = TRUE + if("sex") + var/new_sex = sanitize(input(usr,"What sex would you like to put on this card?","Agent Card Sex", S.sex) as null|text) + if(!isnull(new_sex) && tgui_status(usr, state) == STATUS_INTERACTIVE) + S.sex = new_sex + to_chat(usr, "Sex changed to '[new_sex]'.") + . = TRUE + if("factoryreset") + if(alert("This will factory reset the card, including access and owner. Continue?", "Factory Reset", "No", "Yes") == "Yes" && tgui_status(usr, state) == STATUS_INTERACTIVE) + S.age = initial(S.age) + S.access = syndicate_access.Copy() + S.assignment = initial(S.assignment) + S.blood_type = initial(S.blood_type) + S.dna_hash = initial(S.dna_hash) + S.electronic_warfare = initial(S.electronic_warfare) + S.fingerprint_hash = initial(S.fingerprint_hash) + S.icon_state = initial(S.icon_state) + S.name = initial(S.name) + S.registered_name = initial(S.registered_name) + S.unset_registered_user() + S.sex = initial(S.sex) + to_chat(usr, "All information has been deleted from \the [src].") + . = TRUE diff --git a/code/modules/tgui/modules/atmos_control.dm b/code/modules/tgui/modules/atmos_control.dm index 83d3db4d1e8..4fd477a531b 100644 --- a/code/modules/tgui/modules/atmos_control.dm +++ b/code/modules/tgui/modules/atmos_control.dm @@ -34,6 +34,11 @@ ui.set_map_z_level(params["mapZLevel"]) return TRUE +/datum/tgui_module/atmos_control/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/simple/nanomaps), + ) + /datum/tgui_module/atmos_control/tgui_interact(mob/user, datum/tgui/ui = null) ui = SStgui.try_update_ui(user, src, ui) if(!ui) diff --git a/code/modules/tgui/modules/crew_manifest.dm b/code/modules/tgui/modules/crew_manifest.dm new file mode 100644 index 00000000000..7c4daf7f2a5 --- /dev/null +++ b/code/modules/tgui/modules/crew_manifest.dm @@ -0,0 +1,14 @@ +/datum/tgui_module/crew_manifest + name = "Crew Manifest" + tgui_id = "CrewManifest" + +/datum/tgui_module/crew_manifest/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + if(data_core) + data_core.get_manifest_list() + data["manifest"] = PDA_Manifest + return data + +/datum/tgui_module/crew_manifest/robot +/datum/tgui_module/crew_manifest/robot/tgui_state(mob/user) + return GLOB.tgui_self_state \ No newline at end of file diff --git a/code/modules/tgui/modules/crew_monitor.dm b/code/modules/tgui/modules/crew_monitor.dm index 9d4af686526..d24cd3414a4 100644 --- a/code/modules/tgui/modules/crew_monitor.dm +++ b/code/modules/tgui/modules/crew_monitor.dm @@ -2,6 +2,11 @@ name = "Crew monitor" tgui_id = "CrewMonitor" +/datum/tgui_module/crew_monitor/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/simple/nanomaps), + ) + /datum/tgui_module/crew_monitor/tgui_act(action, params, datum/tgui/ui) if(..()) return TRUE diff --git a/code/modules/tgui/modules/teleporter.dm b/code/modules/tgui/modules/teleporter.dm new file mode 100644 index 00000000000..05529390fe6 --- /dev/null +++ b/code/modules/tgui/modules/teleporter.dm @@ -0,0 +1,85 @@ +/datum/tgui_module/teleport_control + name = "Teleporter Control" + tgui_id = "Teleporter" + var/locked_name = "Not Locked" + var/obj/item/locked = null + var/obj/machinery/teleport/station/station = null + var/obj/machinery/teleport/hub/hub = null + +/datum/tgui_module/teleport_control/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + data["locked_name"] = locked_name || "No Target" + data["station_connected"] = !!station + data["hub_connected"] = !!hub + data["calibrated"] = hub?.accurate + data["teleporter_on"] = station?.engaged + + return data + +/datum/tgui_module/teleport_control/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + switch(action) + if("select_target") + var/list/L = list() + var/list/areaindex = list() + + for(var/obj/item/device/radio/beacon/R in all_beacons) + var/turf/T = get_turf(R) + if(!T) + continue + if(!(T.z in using_map.player_levels)) + continue + var/tmpname = T.loc.name + if(areaindex[tmpname]) + tmpname = "[tmpname] ([++areaindex[tmpname]])" + else + areaindex[tmpname] = 1 + L[tmpname] = R + + for(var/obj/item/weapon/implant/tracking/I in all_tracking_implants) + if(!I.implanted || !ismob(I.loc)) + continue + else + var/mob/M = I.loc + if(M.stat == 2) + if(M.timeofdeath + 6000 < world.time) + continue + var/turf/T = get_turf(M) + if(T) + continue + if(!(T in using_map.station_levels)) + continue + var/tmpname = M.real_name + if(areaindex[tmpname]) + tmpname = "[tmpname] ([++areaindex[tmpname]])" + else + areaindex[tmpname] = 1 + L[tmpname] = I + + var/desc = input("Please select a location to lock in.", "Locking Menu") in L|null + if(!desc) + return FALSE + if(tgui_status(usr, state) != STATUS_INTERACTIVE) + return FALSE + + locked = L[desc] + locked_name = desc + return TRUE + + if("test_fire") + station?.testfire() + return TRUE + + if("toggle_on") + if(!station) + return FALSE + + if(station.engaged) + station.disengage() + else + station.engage() + + return TRUE diff --git a/code/modules/nano/nanomapgen.dm b/code/modules/tgui/nanomapgen.dm similarity index 97% rename from code/modules/nano/nanomapgen.dm rename to code/modules/tgui/nanomapgen.dm index d5a7cfaf693..79c2332901d 100644 --- a/code/modules/nano/nanomapgen.dm +++ b/code/modules/tgui/nanomapgen.dm @@ -48,7 +48,7 @@ sleep(3) return NANOMAP_TERMINALERR - var/icon/Tile = icon(file("nano/mapbase1200.png")) + var/icon/Tile = icon('icons/_nanomaps/mapbase1200.png') if (Tile.Width() != NANOMAP_MAX_ICON_DIMENSION || Tile.Height() != NANOMAP_MAX_ICON_DIMENSION) to_world_log("NanoMapGen: ERROR: BASE IMAGE DIMENSIONS ARE NOT [NANOMAP_MAX_ICON_DIMENSION]x[NANOMAP_MAX_ICON_DIMENSION]") sleep(3) diff --git a/code/modules/tgui/states.dm b/code/modules/tgui/states.dm index 111ee9e30be..b2208e4f992 100644 --- a/code/modules/tgui/states.dm +++ b/code/modules/tgui/states.dm @@ -123,3 +123,7 @@ if((TK in mutations) && (get_dist(src, src_object) <= 2)) return STATUS_INTERACTIVE return ..() + +// Topic Extensions for old UIs +/datum/proc/CanUseTopic(var/mob/user, var/datum/tgui_state/state) + return tgui_status(user, state) \ No newline at end of file diff --git a/code/modules/tgui/states/deep_inventory.dm b/code/modules/tgui/states/deep_inventory.dm index 137f262a0ea..14419874538 100644 --- a/code/modules/tgui/states/deep_inventory.dm +++ b/code/modules/tgui/states/deep_inventory.dm @@ -10,3 +10,11 @@ GLOBAL_DATUM_INIT(tgui_deep_inventory_state, /datum/tgui_state/deep_inventory_st if(!user.contains(src_object)) return STATUS_CLOSE return user.shared_tgui_interaction(src_object) + +/atom/proc/contains(var/atom/location) + if(!location) + return 0 + if(location == src) + return 1 + + return contains(location.loc) diff --git a/code/modules/tgui/states/default.dm b/code/modules/tgui/states/default.dm index ba8d132e0b8..a69295452b3 100644 --- a/code/modules/tgui/states/default.dm +++ b/code/modules/tgui/states/default.dm @@ -68,12 +68,12 @@ GLOBAL_DATUM_INIT(tgui_default_state, /datum/tgui_state/default, new) /mob/living/silicon/pai/default_can_use_tgui_topic(src_object) // pAIs can only use themselves and the owner's radio. - if((src_object == src || src_object == radio) && !stat) + if((src_object == src || src_object == radio || src_object == communicator) && !stat) return STATUS_INTERACTIVE else return ..() /mob/observer/dead/default_can_use_tgui_topic() - if(check_rights(R_ADMIN, 0, src)) + if(can_admin_interact()) return STATUS_INTERACTIVE // Admins are more equal return STATUS_UPDATE // Ghosts can view updates diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index 2f928ae6fa5..eb128a129bd 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -114,7 +114,6 @@ closing = TRUE for(var/datum/tgui/child in children) child.close(can_be_suspended, logout) - children.Cut() // If we don't have window_id, open proc did not have the opportunity // to finish, therefore it's safe to skip this whole block. if(window) @@ -126,6 +125,8 @@ src_object.tgui_close(user) SStgui.on_close(src) state = null + if(parent_ui) + parent_ui.children -= src parent_ui = null qdel(src) diff --git a/nano/mapbase1200.png b/icons/_nanomaps/mapbase1200.png similarity index 100% rename from nano/mapbase1200.png rename to icons/_nanomaps/mapbase1200.png diff --git a/nano/images/nanomapBackground.png b/icons/_nanomaps/nanomapBackground.png similarity index 100% rename from nano/images/nanomapBackground.png rename to icons/_nanomaps/nanomapBackground.png diff --git a/nano/images/southern_cross_nanomap_z1.png b/icons/_nanomaps/southern_cross_nanomap_z1.png similarity index 100% rename from nano/images/southern_cross_nanomap_z1.png rename to icons/_nanomaps/southern_cross_nanomap_z1.png diff --git a/nano/images/southern_cross_nanomap_z10.png b/icons/_nanomaps/southern_cross_nanomap_z10.png similarity index 100% rename from nano/images/southern_cross_nanomap_z10.png rename to icons/_nanomaps/southern_cross_nanomap_z10.png diff --git a/nano/images/southern_cross_nanomap_z2.png b/icons/_nanomaps/southern_cross_nanomap_z2.png similarity index 100% rename from nano/images/southern_cross_nanomap_z2.png rename to icons/_nanomaps/southern_cross_nanomap_z2.png diff --git a/nano/images/southern_cross_nanomap_z3.png b/icons/_nanomaps/southern_cross_nanomap_z3.png similarity index 100% rename from nano/images/southern_cross_nanomap_z3.png rename to icons/_nanomaps/southern_cross_nanomap_z3.png diff --git a/nano/images/southern_cross_nanomap_z5.png b/icons/_nanomaps/southern_cross_nanomap_z5.png similarity index 100% rename from nano/images/southern_cross_nanomap_z5.png rename to icons/_nanomaps/southern_cross_nanomap_z5.png diff --git a/nano/images/southern_cross_nanomap_z6.png b/icons/_nanomaps/southern_cross_nanomap_z6.png similarity index 100% rename from nano/images/southern_cross_nanomap_z6.png rename to icons/_nanomaps/southern_cross_nanomap_z6.png diff --git a/nano/images/tether_nanomap_z1.png b/icons/_nanomaps/tether_nanomap_z1.png similarity index 100% rename from nano/images/tether_nanomap_z1.png rename to icons/_nanomaps/tether_nanomap_z1.png diff --git a/nano/images/tether_nanomap_z10.png b/icons/_nanomaps/tether_nanomap_z10.png similarity index 100% rename from nano/images/tether_nanomap_z10.png rename to icons/_nanomaps/tether_nanomap_z10.png diff --git a/nano/images/tether_nanomap_z13.png b/icons/_nanomaps/tether_nanomap_z13.png similarity index 100% rename from nano/images/tether_nanomap_z13.png rename to icons/_nanomaps/tether_nanomap_z13.png diff --git a/nano/images/tether_nanomap_z14.png b/icons/_nanomaps/tether_nanomap_z14.png similarity index 100% rename from nano/images/tether_nanomap_z14.png rename to icons/_nanomaps/tether_nanomap_z14.png diff --git a/nano/images/tether_nanomap_z2.png b/icons/_nanomaps/tether_nanomap_z2.png similarity index 100% rename from nano/images/tether_nanomap_z2.png rename to icons/_nanomaps/tether_nanomap_z2.png diff --git a/nano/images/tether_nanomap_z3.png b/icons/_nanomaps/tether_nanomap_z3.png similarity index 100% rename from nano/images/tether_nanomap_z3.png rename to icons/_nanomaps/tether_nanomap_z3.png diff --git a/nano/images/tether_nanomap_z4.png b/icons/_nanomaps/tether_nanomap_z4.png similarity index 100% rename from nano/images/tether_nanomap_z4.png rename to icons/_nanomaps/tether_nanomap_z4.png diff --git a/nano/images/tether_nanomap_z5.png b/icons/_nanomaps/tether_nanomap_z5.png similarity index 100% rename from nano/images/tether_nanomap_z5.png rename to icons/_nanomaps/tether_nanomap_z5.png diff --git a/nano/images/tether_nanomap_z6.png b/icons/_nanomaps/tether_nanomap_z6.png similarity index 100% rename from nano/images/tether_nanomap_z6.png rename to icons/_nanomaps/tether_nanomap_z6.png diff --git a/nano/images/tether_nanomap_z7.png b/icons/_nanomaps/tether_nanomap_z7.png similarity index 100% rename from nano/images/tether_nanomap_z7.png rename to icons/_nanomaps/tether_nanomap_z7.png diff --git a/nano/images/tether_nanomap_z8.png b/icons/_nanomaps/tether_nanomap_z8.png similarity index 100% rename from nano/images/tether_nanomap_z8.png rename to icons/_nanomaps/tether_nanomap_z8.png diff --git a/nano/images/tether_nanomap_z9.png b/icons/_nanomaps/tether_nanomap_z9.png similarity index 100% rename from nano/images/tether_nanomap_z9.png rename to icons/_nanomaps/tether_nanomap_z9.png diff --git a/maps/offmap_vr/talon/talon.dm b/maps/offmap_vr/talon/talon.dm index b05b7ec13ab..b11afb614f3 100644 --- a/maps/offmap_vr/talon/talon.dm +++ b/maps/offmap_vr/talon/talon.dm @@ -404,7 +404,7 @@ Once in open space, consider disabling nonessential power-consuming electronics /datum/tgui_module/camera/ntos/talon_ship name = "Talon Ship Camera Monitor" -/datum/nano_module/camera_monitor/talon_ship/New(host) +/datum/tgui_module/camera/ntos/New(host) . = ..(host, list(NETWORK_TALON_SHIP, NETWORK_THUNDER)) /datum/tgui_module/camera/ntos/talon_helmet diff --git a/nano/README.md b/nano/README.md deleted file mode 100644 index 5a3f55425b8..00000000000 --- a/nano/README.md +++ /dev/null @@ -1,297 +0,0 @@ - - -- [NanoUI](#nanoui) - - [Introduction](#introduction) - - [Components](#components) - - [`ui_interact()`](#ui_interact) - - [`Topic()`](#topic) - - [Template (doT)](#template-dot) - - [Helpers](#helpers) - - [Link](#link) - - [displayBar](#displayBar) - - [doT](#dot) - - [Styling](#styling) - - [Contributing](#contributing) - - -# NanoUI - -## Introduction - -### Credit goes to Neersighted of /tg/station for the styling and large chunks of content of this README. - -NanoUI is one of the three primary user interface libraries currently in use -on Polaris (browse(), /datum/browser, NanoUI). It is the most complex of the three, -but offers quite a few advantages, most notably in default features. - -NanoUI adds a `ui_interact()` proc to all atoms, which, ideally, should be called -via `interact()`; However, the current standardized layout is `ui_interact()` being -directly called from anywhere in the atom, generally `attack_hand()` or `attack_self()`. -The `ui_interact()` proc should not contain anything but NanoUI data and code. - -Here is a simple example from -[poolcontroller.dm @ ParadiseSS13/Paradise](https://github.com/ParadiseSS13/Paradise/blob/master/code/game/machinery/poolcontroller.dm). - -``` - /obj/machinery/poolcontroller/attack_hand(mob/user) - ui_interact(user) - - /obj/machinery/poolcontroller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - - data["currentTemp"] = temperature - data["emagged"] = emagged - data["TempColor"] = temperaturecolor - - ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "poolcontroller.tmpl", "Pool Controller Interface", 520, 410) - ui.set_initial_data(data) - ui.open() -``` - - - -## Components - -### `ui_interact()` - -The `ui_interact()` proc is used to open a NanoUI (or update it if already open). -As NanoUI will call this proc to update your UI, you should include the data list -within it. On /tg/station, this is handled via `get_ui_data()`, however, as it would -take quite a long time to convert every single one of the 100~ UI's to using such a method, -it is instead just directly created within `ui_interact()`. - -The parameters for `try_update_ui` and `/datum/nanoui/New()` are documented in -the code [here](https://github.com/PolarisSS13/Polaris/tree/master/code/modules/nano). - -For: -`/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, var/datum/nanoui/master_ui = null, var/datum/topic_state/state = default_state)` -Most of the parameters are fairly self explanatory. - - `nuser` is the person who gets to see the UI window - - `nsrc_obj` is the thing you want to call Topic() on - - `nui_key` should almost always be `main` - - `ntemplate_filename` is the filename with `.tmpl` extension in /nano/templates/ - - `ntitle` is what you want to show at the top of the UI window - - `nwidth` is the width of the new window - - `nheight` is the height of the new window - - `nref` is used for onclose() - - `master_ui` is used for UIs that have multiple children, see code for examples - - And finally, `state`. - -The most interesting parameter here is `state`, which allows the object to choose the -checks that allow the UI to be interacted with. - -The default state (`default_state`) checks that the user is alive, conscious, -and within a few tiles. It allows universal access to silicons. Other states -exist, and may be more appropriate for different interfaces. For example, -`physical_state` requires the user to be nearby, even if they are a silicon. -`inventory_state` checks that the user has the object in their first-level -(not container) inventory, this is suitable for devices such as radios; -`admin_state` checks that the user is an admin (good for admin tools). - -``` - /obj/item/the/thing/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0) - var/data[0] - - ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open = force_open) - if(!ui) - ui = new(user, src, ui_key, "template_name_here.tmpl", title, width, height) - ui.set_initial_data(data) - ui.open() -``` - -### `Topic()` - -`Topic()` handles input from the UI. Typically you will recieve some data from -a button press, or pop up a input dialog to take a numerical value from the -user. Sanity checking is useful here, as `Topic()` is trivial to spoof with -arbitrary data. - -The `Topic()` interface is just the same as with more conventional, -stringbuilder-based UIs, and this needs little explanation. - -``` - /obj/item/weapon/tank/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["dist_p"]) - if(href_list["dist_p"] == "custom") - var/custom = input(usr, "What rate do you set the regulator to? The dial reads from 0 to [TANK_MAX_RELEASE_PRESSURE].") as null|num - if(isnum(custom)) - href_list["dist_p"] = custom - .() - else if(href_list["dist_p"] == "reset") - distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE - else if(href_list["dist_p"] == "min") - distribute_pressure = TANK_MIN_RELEASE_PRESSURE - else if(href_list["dist_p"] == "max") - distribute_pressure = TANK_MAX_RELEASE_PRESSURE - else - distribute_pressure = text2num(href_list["dist_p"]) - distribute_pressure = min(max(round(distribute_pressure), TANK_MIN_RELEASE_PRESSURE), TANK_MAX_RELEASE_PRESSURE) - if(href_list["stat"]) - if(istype(loc,/mob/living/carbon)) - var/mob/living/carbon/location = loc - if(location.internal == src) - location.internal = null - location.internals.icon_state = "internal0" - to_chat(usr, "You close the tank release valve.") - if(location.internals) - location.internals.icon_state = "internal0" - else - if(location.wear_mask && (location.wear_mask.flags & MASKINTERNALS)) - location.internal = src - to_chat(usr, "You open \the [src] valve.") - if(location.internals) - location.internals.icon_state = "internal1" - else - to_chat(usr, "You need something to connect to \the [src]!") -``` - -### Template (doT) - -NanoUI templates are written in a customized version of -[doT](https://olado.github.io/doT/index.html), -a Javascript template engine. Data is accessed from the `data` object, -configuration (not used in pratice) from the `config` object, and template -helpers are accessed from the `helper` object. - -It is worth explaining that Polaris's version of doT uses custom syntax -for the templates. The `?` operator is split into `if`, `else if parameter`, and `else`, -instead of `?`, `?? paramater`, `??`, and the `=` operator is replaced with `:`. Refer -to the chart below for a full comparison. - -#### Helpers - -##### Link - -`{{:helpers.link(text, icon, {'parameter': true}, status, class, id)}}` - -Used to create a link (button), which will pass its parameters to `Topic()`. - -* Text: The text content of the link/button -* Icon: The icon shown to the left of the link (http://fontawesome.io/) -* Parameters: The values to be passed to `Topic()`'s `href_list`. -* Status: `null` for clickable, a class for selected/unclickable. -* Class: Styling to apply to the link. -* ID: Sets the element ID. - -Status and Class have almost the same effect. However, changing a link's status -from `null` to something else makes it unclickable, while setting a custom Class -does not. - -Ternary operators are often used to avoid writing many `if` statements. -For example, depending on if a value in `data` is true or false we can set a -button to clickable or selected: - -`{{:helper.link('Close', 'lock', {'stat': 1}, data.valveOpen ? null : 'selected')}}` - -Available classes/statuses are: - -* null (normal) -* selected -* disabled -* yellowButton -* redButton -* linkDanger - -##### displayBar - -`{{:helpers.displayBar(value, min, max, class, text)}}` - -Used to create a bar, to display a numerical value visually. Min and Max default -to 0 and 100, but you can change them to avoid doing your own percent calculations. - -* Value: Defaults to a percentage but can be a straight number if Min/Max are set -* Min: The minimum value (left hand side) of the bar -* Max: The maximum value (right hand side) of the bar -* Class: The color of the bar (null/normal, good, average, bad) -* Text: The text label for the data contained in the bar (often just number form) - -As with buttons, ternary operators are quite useful: - -`{{:helper.bar(data.tankPressure, 0, 1013, (data.tankPressure > 200) ? 'good' : ((data.tankPressure > 100) ? 'average' : 'bad'))}}` - - -#### doT - -doT is a simple template language, with control statements mixed in with -regular HTML and interpolation expressions. - -However, Polaris uses a custom version with a different syntax. Refer -to the chart below for the differences. - -Operator | doT | equiv | -|-----------|------------|-------------------| -|Conditional| ? | if | -| | ?? | else | -| | ?? (param) | else if(param) | -|Interpolate| = | : | -|^ + Encode | ! | > | -|Evaluation | # | # | -|Defines | ## # | ## # | -|Iteration | ~ (param) | for (param) | - -Here is a simple example from tanks, checking if a variable is true: - -``` - {{if data.maskConnected}} - The regulator is connected to a mask. - {{else if}} - The regulator is not connected to a mask. - {{/if}} -``` - -The doT tutorial is [here](https://olado.github.io/doT/tutorial.html). - -__Print Tag__ -- The print tag outputs the given expression as text to the UI. - -`{{:data.variable}}` -`{{:functioncall()}}` - -(with escape): - -`{{>expression }}` - - -__If Tag__ -- The if tag displays content conditionally based on the provided expression being true. -- When combined with the else tag the if tag can also show content if the provided expression is false. -- The else tag can optionally have an expression provided (e.g. "`{{else expression2}}`"), giving it "elseif" functionality. - -`{{if expression}} {{/if}}` -`{{if expression}} {{else}} {{/if}}` -`{{if expression1}} {{else expression2}} {{/if}}` - -__For Tag__ -- Loop through entries in an array; it can be associative (with keys) or numerical indexed, but you have to use some special syntax for assocative lists. -- Each time the `for` tag iterates though the array it sets a variable (default "value") to the data of the current entry (another variable, default "index", contains the index). An example of this is using the print tag to print the contents (e.g. `{{:value.key1}}` and `{{:value.key2}}`). -- If combined with an `empty` tag the for tag can display content when the array is empty. - -Indexed: -`{{for array}} {{/for}}` -`{{for array}} {{empty}} {{/for}}` - -Associative: -`{{for object:key:index}} {{/for}}` - - -__Inclusion Tag__ -- Include the contents of another template which has been added to the ui. -`{{#def.atmosphericScan}}` - -- You first must have added a template to the ui server side in your DM code: -`ui.add_template("atmosphericScan", "atmospheric_scan.tmpl")` - -- Then you can reference it in the main template. The tag will be replaced by the contents of the named template. All tags in the named template are evaluated as normal. - -#### Styling -/tg/station has standardized styling, with specific article tags, and headers, and sections. -However, as the templates are already horrifying unstandardized, Polaris does not have any -particular styling standards. - -The only real requirement is that it, A. Looks alrightish, and B. Functions properly. Try -to avoid snowflaking anything into the main CSS file, please. diff --git a/nano/Update BYOND Cache.py b/nano/Update BYOND Cache.py deleted file mode 100644 index 032c42ff1ba..00000000000 --- a/nano/Update BYOND Cache.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/python3 -# Setup -import os, json, shutil, glob, platform - -if(platform.system() != "Windows"): - print("Error: This script doesn't work on anything but Windows. How are you even planning to develop BYOND off windows?") - exit() - -cdir = (os.getcwd()) -if(cdir[-4:] != "nano"): - print("This script must be run from the nano directory.") - exit() - -def find_cache(): - target = os.path.join(os.path.expanduser("~"), "Documents", "BYOND", "cache") - for root, dirs, files in os.walk(target): - if "nano_templates_bundle.js" in files: - return root - -cache = find_cache() -if cache == None: - print("Failed to find BYOND Cache.") - exit() - -# Send all of the random files to the cache -def send_to_cache(arrayOfFiles): - for file in arrayOfFiles: - target = os.path.join(cache, os.path.split(file)[1]) - shutil.copyfile(file, target) - -send_to_cache([os.path.join(cdir, "css", f) for f in os.listdir(os.path.join(cdir, "css")) if os.path.isfile(os.path.join(cdir, "css", f))]) -send_to_cache([os.path.join(cdir, "images", f) for f in os.listdir(os.path.join(cdir, "images")) if os.path.isfile(os.path.join(cdir, "images", f))]) -send_to_cache([os.path.join(cdir, "js", f) for f in os.listdir(os.path.join(cdir, "js")) if os.path.isfile(os.path.join(cdir, "js", f))]) - -# Handle creating the tmpl bundle -arrOfFiles = glob.glob(os.path.join(cdir, "templates", "*.tmpl")) - -tmpl_bundle_header = "function nanouiTemplateBundle(){return " -tmpl_bundle_footer = ";}" - -big_json_array = {} - -for file in arrOfFiles: - tmpl_name = os.path.split(file)[1] - with open(file, 'r') as tmpl: - big_json_array[tmpl_name] = tmpl.read() - -tmpl_bundle = tmpl_bundle_header + json.dumps(big_json_array) + tmpl_bundle_footer - -# Send the tmpl bundle to the cache -with open(os.path.join(cache, "nano_templates_bundle.js"), "w") as templateBundleFile: - templateBundleFile.write(tmpl_bundle) - templateBundleFile.close() \ No newline at end of file diff --git a/nano/css/icons.css b/nano/css/icons.css deleted file mode 100644 index 23d4ba0606c..00000000000 --- a/nano/css/icons.css +++ /dev/null @@ -1,378 +0,0 @@ -/* Icons -----------------------------------*/ - -.icon24 -{ - width: 24px; - height: 24px; -} - -.icon24.uiStatusGood -{ - background: url(uiIcons24.png) 0 0 no-repeat; -} - -.icon24.uiStatusAverage -{ - background: url(uiIcons24.png) 0 -24px no-repeat; -} - -.icon24.uiStatusBad -{ - background: url(uiIcons24.png) 0 -48px no-repeat; -} - -/* states and images */ -.uiIcon16 { - float: left; - width: 16px; - height: 16px; - margin: 2px 2px 0 2px; - background-image: url(uiIcons16.png); -} - -.uiLinkPendingIcon { - display: none; - float: left; - width: 16px; - height: 16px; - margin: 2px 2px 0 2px; - background-image: url(uiLinkPendingIcon.gif); -} - -.linkPending .uiIcon16 { - display: none; -} - -.linkPending .uiLinkPendingIcon { - display: block; -} - -/* positioning */ -.uiIcon16.icon-blank { background-position: 16px 16px; } - -.uiIcon16.icon-carat-1-n { background-position: 0 0; } -.uiIcon16.icon-carat-1-ne { background-position: -16px 0; } -.uiIcon16.icon-carat-1-e { background-position: -32px 0; } -.uiIcon16.icon-carat-1-se { background-position: -48px 0; } -.uiIcon16.icon-carat-1-s { background-position: -64px 0; } -.uiIcon16.icon-carat-1-sw { background-position: -80px 0; } -.uiIcon16.icon-carat-1-w { background-position: -96px 0; } -.uiIcon16.icon-carat-1-nw { background-position: -112px 0; } -.uiIcon16.icon-carat-2-n-s { background-position: -128px 0; } -.uiIcon16.icon-carat-2-e-w { background-position: -144px 0; } - -.uiIcon16.icon-triangle-1-n { background-position: 0 -16px; } -.uiIcon16.icon-triangle-1-ne { background-position: -16px -16px; } -.uiIcon16.icon-triangle-1-e { background-position: -32px -16px; } -.uiIcon16.icon-triangle-1-se { background-position: -48px -16px; } -.uiIcon16.icon-triangle-1-s { background-position: -64px -16px; } -.uiIcon16.icon-triangle-1-sw { background-position: -80px -16px; } -.uiIcon16.icon-triangle-1-w { background-position: -96px -16px; } -.uiIcon16.icon-triangle-1-nw { background-position: -112px -16px; } -.uiIcon16.icon-triangle-2-n-s { background-position: -128px -16px; } -.uiIcon16.icon-triangle-2-e-w { background-position: -144px -16px; } - -.uiIcon16.icon-arrow-1-n { background-position: 0 -32px; } -.uiIcon16.icon-arrow-1-ne { background-position: -16px -32px; } -.uiIcon16.icon-arrow-1-e { background-position: -32px -32px; } -.uiIcon16.icon-arrow-1-se { background-position: -48px -32px; } -.uiIcon16.icon-arrow-1-s { background-position: -64px -32px; } -.uiIcon16.icon-arrow-1-sw { background-position: -80px -32px; } -.uiIcon16.icon-arrow-1-w { background-position: -96px -32px; } -.uiIcon16.icon-arrow-1-nw { background-position: -112px -32px; } -.uiIcon16.icon-arrow-2-n-s { background-position: -128px -32px; } -.uiIcon16.icon-arrow-2-ne-sw { background-position: -144px -32px; } -.uiIcon16.icon-arrow-2-e-w { background-position: -160px -32px; } -.uiIcon16.icon-arrow-2-se-nw { background-position: -176px -32px; } - -.uiIcon16.icon-arrowstop-1-n { background-position: -192px -32px; } -.uiIcon16.icon-arrowstop-1-e { background-position: -208px -32px; } -.uiIcon16.icon-arrowstop-1-s { background-position: -224px -32px; } -.uiIcon16.icon-arrowstop-1-w { background-position: -240px -32px; } - -.uiIcon16.icon-arrowthick-1-n { background-position: 0 -48px; } -.uiIcon16.icon-arrowthick-1-ne { background-position: -16px -48px; } -.uiIcon16.icon-arrowthick-1-e { background-position: -32px -48px; } -.uiIcon16.icon-arrowthick-1-se { background-position: -48px -48px; } -.uiIcon16.icon-arrowthick-1-s { background-position: -64px -48px; } -.uiIcon16.icon-arrowthick-1-sw { background-position: -80px -48px; } -.uiIcon16.icon-arrowthick-1-w { background-position: -96px -48px; } -.uiIcon16.icon-arrowthick-1-nw { background-position: -112px -48px; } -.uiIcon16.icon-arrowthick-2-n-s { background-position: -128px -48px; } -.uiIcon16.icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -.uiIcon16.icon-arrowthick-2-e-w { background-position: -160px -48px; } -.uiIcon16.icon-arrowthick-2-se-nw { background-position: -176px -48px; } - -.uiIcon16.icon-arrowthickstop-1-n { background-position: -192px -48px; } -.uiIcon16.icon-arrowthickstop-1-e { background-position: -208px -48px; } -.uiIcon16.icon-arrowthickstop-1-s { background-position: -224px -48px; } -.uiIcon16.icon-arrowthickstop-1-w { background-position: -240px -48px; } - -.uiIcon16.icon-arrowreturnthick-1-w { background-position: 0 -64px; } -.uiIcon16.icon-arrowreturnthick-1-n { background-position: -16px -64px; } -.uiIcon16.icon-arrowreturnthick-1-e { background-position: -32px -64px; } -.uiIcon16.icon-arrowreturnthick-1-s { background-position: -48px -64px; } - -.uiIcon16.icon-arrowreturn-1-w { background-position: -64px -64px; } -.uiIcon16.icon-arrowreturn-1-n { background-position: -80px -64px; } -.uiIcon16.icon-arrowreturn-1-e { background-position: -96px -64px; } -.uiIcon16.icon-arrowreturn-1-s { background-position: -112px -64px; } -.uiIcon16.icon-arrowrefresh-1-w { background-position: -128px -64px; } -.uiIcon16.icon-arrowrefresh-1-n { background-position: -144px -64px; } -.uiIcon16.icon-arrowrefresh-1-e { background-position: -160px -64px; } -.uiIcon16.icon-arrowrefresh-1-s { background-position: -176px -64px; } - -.uiIcon16.icon-arrow-4 { background-position: 0 -80px; } -.uiIcon16.icon-arrow-4-diag { background-position: -16px -80px; } -.uiIcon16.icon-extlink { background-position: -32px -80px; } -.uiIcon16.icon-newwin { background-position: -48px -80px; } -.uiIcon16.icon-refresh { background-position: -64px -80px; } -.uiIcon16.icon-shuffle { background-position: -80px -80px; } -.uiIcon16.icon-transfer-e-w { background-position: -96px -80px; } -.uiIcon16.icon-transferthick-e-w { background-position: -112px -80px; } -.uiIcon16.icon-radiation { background-position: -128px -80px; } -.uiIcon16.icon-folder-collapsed { background-position: 0 -96px; } -.uiIcon16.icon-folder-open { background-position: -16px -96px; } -.uiIcon16.icon-document { background-position: -32px -96px; } -.uiIcon16.icon-document-b { background-position: -48px -96px; } -.uiIcon16.icon-note { background-position: -64px -96px; } -.uiIcon16.icon-mail-closed { background-position: -80px -96px; } -.uiIcon16.icon-mail-open { background-position: -96px -96px; } -.uiIcon16.icon-suitcase { background-position: -112px -96px; } -.uiIcon16.icon-comment { background-position: -128px -96px; } -.uiIcon16.icon-person { background-position: -144px -96px; } -.uiIcon16.icon-print { background-position: -160px -96px; } -.uiIcon16.icon-trash { background-position: -176px -96px; } -.uiIcon16.icon-locked { background-position: -192px -96px; } -.uiIcon16.icon-unlocked { background-position: -208px -96px; } -.uiIcon16.icon-bookmark { background-position: -224px -96px; } -.uiIcon16.icon-tag { background-position: -240px -96px; } -.uiIcon16.icon-home { background-position: 0 -112px; } -.uiIcon16.icon-flag { background-position: -16px -112px; } -.uiIcon16.icon-calendar { background-position: -32px -112px; } -.uiIcon16.icon-cart { background-position: -48px -112px; } -.uiIcon16.icon-pencil { background-position: -64px -112px; } -.uiIcon16.icon-clock { background-position: -80px -112px; } -.uiIcon16.icon-disk { background-position: -96px -112px; } -.uiIcon16.icon-calculator { background-position: -112px -112px; } -.uiIcon16.icon-zoomin { background-position: -128px -112px; } -.uiIcon16.icon-zoomout { background-position: -144px -112px; } -.uiIcon16.icon-search { background-position: -160px -112px; } -.uiIcon16.icon-wrench { background-position: -176px -112px; } -.uiIcon16.icon-gear { background-position: -192px -112px; } -.uiIcon16.icon-heart { background-position: -208px -112px; } -.uiIcon16.icon-star { background-position: -224px -112px; } -.uiIcon16.icon-link { background-position: -240px -112px; } -.uiIcon16.icon-cancel { background-position: 0 -128px; } -.uiIcon16.icon-plus { background-position: -16px -128px; } -.uiIcon16.icon-plusthick { background-position: -32px -128px; } -.uiIcon16.icon-minus { background-position: -48px -128px; } -.uiIcon16.icon-minusthick { background-position: -64px -128px; } -.uiIcon16.icon-close { background-position: -80px -128px; } -.uiIcon16.icon-closethick { background-position: -96px -128px; } -.uiIcon16.icon-key { background-position: -112px -128px; } -.uiIcon16.icon-lightbulb { background-position: -128px -128px; } -.uiIcon16.icon-scissors { background-position: -144px -128px; } -.uiIcon16.icon-clipboard { background-position: -160px -128px; } -.uiIcon16.icon-copy { background-position: -176px -128px; } -.uiIcon16.icon-contact { background-position: -192px -128px; } -.uiIcon16.icon-image { background-position: -208px -128px; } -.uiIcon16.icon-video { background-position: -224px -128px; } -.uiIcon16.icon-script { background-position: -240px -128px; } -.uiIcon16.icon-alert { background-position: 0 -144px; } -.uiIcon16.icon-alert-red { background-image: url(uiIcons16Red.png); background-position: 0 -144px; } -.uiIcon16.icon-info { background-position: -16px -144px; } -.uiIcon16.icon-notice { background-position: -32px -144px; } -.uiIcon16.icon-help { background-position: -48px -144px; } -.uiIcon16.icon-check { background-position: -64px -144px; } -.uiIcon16.icon-bullet { background-position: -80px -144px; } -.uiIcon16.icon-radio-on { background-position: -96px -144px; } -.uiIcon16.icon-radio-off { background-position: -112px -144px; } -.uiIcon16.icon-pin-w { background-position: -128px -144px; } -.uiIcon16.icon-pin-s { background-position: -144px -144px; } -.uiIcon16.icon-phone { background-position: -160px -144px; } -.uiIcon16.icon-list { background-position: -176px -144px; } -.uiIcon16.icon-syringe { background-position: -192px -144px; } -.uiIcon16.icon-play { background-position: 0 -160px; } -.uiIcon16.icon-pause { background-position: -16px -160px; } -.uiIcon16.icon-seek-next { background-position: -32px -160px; } -.uiIcon16.icon-seek-prev { background-position: -48px -160px; } -.uiIcon16.icon-seek-end { background-position: -64px -160px; } -.uiIcon16.icon-seek-start { background-position: -80px -160px; } - -/* uiIcon-seek-first is deprecated, use uiIcon-seek-start instead */ -.uiIcon16.icon-seek-first { background-position: -80px -160px; } -.uiIcon16.icon-stop { background-position: -96px -160px; } -.uiIcon16.icon-eject { background-position: -112px -160px; } -.uiIcon16.icon-volume-off { background-position: -128px -160px; } -.uiIcon16.icon-volume-on { background-position: -144px -160px; } -.uiIcon16.icon-power { background-position: 0 -176px; } -.uiIcon16.icon-signal-diag { background-position: -16px -176px; } -.uiIcon16.icon-signal { background-position: -32px -176px; } -.uiIcon16.icon-signal-green { background-image: url(uiIcons16Green.png); background-position: -32px -176px; } - -.uiIcon16.icon-battery-0 { background-position: -48px -176px; } -.uiIcon16.icon-battery-1 { background-position: -64px -176px; } -.uiIcon16.icon-battery-2 { background-position: -80px -176px; } -.uiIcon16.icon-battery-3 { background-position: -96px -176px; } - -.uiIcon16.icon-circle-plus { background-position: 0 -192px; } -.uiIcon16.icon-circle-minus { background-position: -16px -192px; } -.uiIcon16.icon-circle-close { background-position: -32px -192px; } -.uiIcon16.icon-circle-triangle-e { background-position: -48px -192px; } -.uiIcon16.icon-circle-triangle-s { background-position: -64px -192px; } -.uiIcon16.icon-circle-triangle-w { background-position: -80px -192px; } -.uiIcon16.icon-circle-triangle-n { background-position: -96px -192px; } -.uiIcon16.icon-circle-arrow-e { background-position: -112px -192px; } -.uiIcon16.icon-circle-arrow-s { background-position: -128px -192px; } -.uiIcon16.icon-circle-arrow-w { background-position: -144px -192px; } -.uiIcon16.icon-circle-arrow-n { background-position: -160px -192px; } -.uiIcon16.icon-circle-zoomin { background-position: -176px -192px; } -.uiIcon16.icon-circle-zoomout { background-position: -192px -192px; } -.uiIcon16.icon-circle-check { background-position: -208px -192px; } - -.uiIcon16.icon-circlesmall-plus { background-position: 0 -208px; } -.uiIcon16.icon-circlesmall-minus { background-position: -16px -208px; } -.uiIcon16.icon-circlesmall-close { background-position: -32px -208px; } - -.uiIcon16.icon-squaresmall-plus { background-position: -48px -208px; } -.uiIcon16.icon-squaresmall-minus { background-position: -64px -208px; } -.uiIcon16.icon-squaresmall-close { background-position: -80px -208px; } - -.uiIcon16.icon-grip-dotted-vertical { background-position: 0 -224px; } -.uiIcon16.icon-grip-dotted-horizontal { background-position: -16px -224px; } -.uiIcon16.icon-grip-solid-vertical { background-position: -32px -224px; } -.uiIcon16.icon-grip-solid-horizontal { background-position: -48px -224px; } -.uiIcon16.icon-gripsmall-diagonal-se { background-position: -64px -224px; } -.uiIcon16.icon-grip-diagonal-se { background-position: -80px -224px; } - -.uiIcon16.icon-batt_full { background-image: url(c_max.gif); background-position: 0px 0px } -.uiIcon16.icon-batt_disc { background-image: url(c_discharging.gif); background-position: 0px 0px } -.uiIcon16.icon-batt_chrg { background-image: url(c_charging.gif); background-position: 0px 0px } - -/*yes, defining these all like this is awful, but unless the javascript for icon handling is sorted out this will have to do*/ -.uiIcon16.icon-empty64 { background-image: url(uiIcons64.png); background-position: 0 0; width: 64px; height: 64px; } -.uiIcon16.icon-phone64 { background-image: url(uiIcons64.png); background-position: -64px 0; width: 64px; height: 64px; } -.uiIcon16.icon-comment64 { background-image: url(uiIcons64.png); background-position: -128px 0; width: 64px; height: 64px; } -.uiIcon16.icon-list64 { background-image: url(uiIcons64.png); background-position: -192px 0; width: 64px; height: 64px; } -.uiIcon16.icon-gear64 { background-image: url(uiIcons64.png); background-position: -256px 0; width: 64px; height: 64px; } -.uiIcon16.icon-person64 { background-image: url(uiIcons64.png); background-position: -320px 0; width: 64px; height: 64px; } -.uiIcon16.icon-newspaper64 { background-image: url(uiIcons64.png); background-position: 0 -64px; width: 64px; height: 64px; } -.uiIcon16.icon-note64 { background-image: url(uiIcons64.png); background-position: -64px -64px; width: 64px; height: 64px; } -.uiIcon16.icon-close64 { background-image: url(uiIcons64.png); background-position: -128px -64px; width: 64px; height: 64px; } -.uiIcon16.icon-sun64 { background-image: url(uiIcons64.png); background-position: -192px -64px; width: 64px; height: 64px; } -.uiIcon16.icon-external64 { background-image: url(uiIcons64.png); background-position: -256px -64px; width: 64px; height: 64px; } - -.uiIcon16.icon-pill { background-image: url(pills32.png); width: 32px; height: 32px;} -.uiIcon16.icon-pill.pill1 { background-position: -64px -96px; } -.uiIcon16.icon-pill.pill2 { background-position: -64px -96px; } -.uiIcon16.icon-pill.pill3 { background-position: -96px -32px; } -.uiIcon16.icon-pill.pill4 { background-position: -96px -32px; } -.uiIcon16.icon-pill.pill5 { background-position: 0 0; } -.uiIcon16.icon-pill.pill6 { background-position: -32px 0; } -.uiIcon16.icon-pill.pill7 { background-position: -64px 0; } -.uiIcon16.icon-pill.pill8 { background-position: -96px 0; } -.uiIcon16.icon-pill.pill9 { background-position: -128px 0; } -.uiIcon16.icon-pill.pill10 { background-position: 0 -32px; } -.uiIcon16.icon-pill.pill11 { background-position: -32px -32px; } -.uiIcon16.icon-pill.pill12 { background-position: -64px -32px; } -.uiIcon16.icon-pill.pill13 { background-position: -96px -32px; } -.uiIcon16.icon-pill.pill14 { background-position: -128px -32px; } -.uiIcon16.icon-pill.pill15 { background-position: 0 -64px; } -.uiIcon16.icon-pill.pill16 { background-position: -32px -64px; } -.uiIcon16.icon-pill.pill17 { background-position: -64px -64px; } -.uiIcon16.icon-pill.pill18 { background-position: -96px -64px; } -.uiIcon16.icon-pill.pill19 { background-position: -128px -64px; } -.uiIcon16.icon-pill.pill20 { background-position: 0 -96px; } -.uiIcon16.icon-pill.pill21 { background-position: -32px -96px; } -.uiIcon16.icon-pill.pill22 { background-position: -64px -96px; } -.uiIcon16.icon-pill.pill23 { background-position: -96px -96px; } -.uiIcon16.icon-pill.pill24 { background-position: -128px -96px; } -.uiIcon16.icon-pill.bottle1 { background-position: 0 -128px; } -.uiIcon16.icon-pill.bottle2 { background-position: -32px -128px; } -.uiIcon16.icon-pill.bottle3 { background-position: -64px -128px; } -.uiIcon16.icon-pill.bottle4 { background-position: -96px -128px; } - -.mapIcon16 { - position: absolute; - width: 16px; - height: 16px; - background-image: url(uiIcons16Green.png); - background-position: -144px -96px; - background-repeat: no-repeat; - zoom: 0.125; - margin-left: -1px; - /*margin-bottom: -1px;*/ -} -.mapIcon16.dead { - background-image: url(uiIcons16Red.png); -} - -/* Command Positions */ -.mapIcon16.rank-captain { - background-position: -224px -112px; -} -.mapIcon16.rank-headofpersonnel { - background-position: -112px -96px; -} -.mapIcon16.rank-headofsecurity { - background-position: -112px -128px; -} -.mapIcon16.rank-chiefengineer { - background-position: -176px -112px; -} -.mapIcon16.rank-researchdirector { - background-position: -128px -128px; -} -.mapIcon16.rank-chiefmedicalofficer { - background-position: -32px -128px; -} - -/* Engineering Positions */ -.mapIcon16.rank-stationengineer { - background-position: -176px -112px; -} -.mapIcon16.rank-atmospherictechnician { - background-position: -176px -112px; -} - -/* Medical Positions */ -.mapIcon16.rank-medicaldoctor { - background-position: -32px -128px; -} -.mapIcon16.rank-geneticist { - background-position: -32px -128px; -} -.mapIcon16.rank-psychiatrist { - background-position: -32px -128px; -} -.mapIcon16.rank-chemist { - background-position: -32px -128px; -} - -/* Science Positions */ -.mapIcon16.rank-scientist { - background-position: -128px -128px; -} -.mapIcon16.rank-geneticist { - background-position: -128px -128px; -} -.mapIcon16.rank-roboticist { - background-position: -128px -128px; -} -.mapIcon16.rank-xenobiologist { - background-position: -128px -128px; -} - -/* Security Positions */ -.mapIcon16.rank-warden { - background-position: -112px -128px; -} -.mapIcon16.rank-detective { - background-position: -112px -128px; -} -.mapIcon16.rank-securityofficer { - background-position: -112px -128px; -} - diff --git a/nano/css/layout_basic.css b/nano/css/layout_basic.css deleted file mode 100644 index 30a75490f39..00000000000 --- a/nano/css/layout_basic.css +++ /dev/null @@ -1,21 +0,0 @@ -body { - background: #272727 url(uiBasicBackground.png) 50% 0 repeat-x; -} - -#uiContent { - clear: both; - padding: 8px; -} - -#uiLoadingNotice { - position: relative; - background: url(uiNoticeBackground.jpg) 50% 50%; - color: #000000; - font-size: 14px; - font-style: italic; - font-weight: bold; - padding: 3px 4px 3px 4px; - margin: 4px 0 4px 0; -} - - diff --git a/nano/css/layout_default.css b/nano/css/layout_default.css deleted file mode 100644 index 47002ef5d57..00000000000 --- a/nano/css/layout_default.css +++ /dev/null @@ -1,128 +0,0 @@ -body { - background: #272727 url(uiBackground.png) 50% 0 repeat-x; -} - -#uiWrapper { - width: 100%; - height: 100%; - -ms-user-select: none; - user-select: none; -} - -#uiTitleWrapper { - position: relative; - height: 30px; -} - -#uiTitleText { - position: absolute; - top: 6px; - left: 44px; - width: 66%; - overflow: hidden; - color: #E9C183; - font-size: 16px; -} - -#uiTitle.icon { - padding: 6px 8px 6px 42px; - background-position: 2px 50%; - background-repeat: no-repeat; -} - -#uiTitleFluff { - position: absolute; - top: 4px; - right: 12px; - width: 42px; - height: 24px; - background: url(uiTitleFluff.png) 50% 50% no-repeat; -} - -#uiStatusIcon { - position: absolute; - top: 4px; - left: 12px; - width: 24px; - height: 24px; -} - -#uiMapWrapper { - clear: both; - padding: 8px; -} - -#uiMapHeader { - position: relative; - clear: both; -} - -#uiMapContainer { - position: relative; - width: 100%; - height: 550px; - overflow: hidden; - border: 1px solid #40628a; - background: url(nanomapBackground.png); -} - -#uiMap { - position: absolute; - top: 50%; - left: 50%; - margin: -280px 0 0 -280px; /* VOREStation Edit - Tether map is small */ - width: 140px; /* VOREStation Edit - Tether map is small */ - height: 140px; /* VOREStation Edit - Tether map is small */ - overflow: hidden; - zoom: 4; -} - -#uiMapImage { - position: absolute; - bottom: 1px; - left: 1px; - width: 140px; /* VOREStation Edit - Tether map is small */ - height: 140px; /* VOREStation Edit - Tether map is small */ -} - -#uiMapContent { - position: absolute; - bottom: 0px; - left: 0px; - width: 140px; /* VOREStation Edit - Tether map is small */ - height: 140px; /* VOREStation Edit - Tether map is small */ -} - -#uiMapFooter { - position: relative; - clear: both; -} - -#uiContent { - clear: both; - padding: 8px; -} - -#uiMapTooltip { - position: absolute; - right: 10px; - top: 10px; - border: 1px solid #40628a; - background-color: #272727; - padding: 8px; - display: none; - z-index: 9999; -} - -#uiLoadingNotice { - position: relative; - background: url(uiNoticeBackground.jpg) 50% 50%; - color: #000000; - font-size: 14px; - font-style: italic; - font-weight: bold; - padding: 3px 4px 3px 4px; - margin: 4px 0 4px 0; -} - - diff --git a/nano/css/shared.css b/nano/css/shared.css deleted file mode 100644 index 3517402e2af..00000000000 --- a/nano/css/shared.css +++ /dev/null @@ -1,803 +0,0 @@ -body { - padding: 0; - margin: 0; - font-size: 12px; - color: #ffffff; - line-height: 170%; - font-family: Verdana, Geneva, sans-serif; - background: #272727; -} - -#uiNoScript { - position: fixed; - top: 50%; - left: 50%; - margin: -60px 0 0 -150px; - width: 280px; - height: 120px; - background: #ffffff; - border: 2px solid #ff0000; - color: #000000; - font-size: 10px; - font-weight: bold; - z-index: 9999; - padding: 0px 10px; - text-align: center; -} - -hr { - background-color: #40628a; - height: 1px; -} - -.link, .linkOn, .linkOff, .selected, .disabled, .yellowButton, .redButton { - float: left; - min-width: 15px; - height: 16px; - text-align: center; - color: #ffffff; - text-decoration: none; - background: #40628a; - border: 1px solid #161616; - padding: 0px 4px 4px 4px; - margin: 0 2px 2px 0; - cursor: default; - white-space: nowrap; -} - -.link32 { - float: left; - min-width: 15px; - max-width: 31px; - height: 31px; - text-align: center; - text-decoration: none; - background: #40628a; - border: 1px solid #161616; - margin: 0 2px 2px 0; - cursor: default; -} - -.hasIcon { - padding: 0px 4px 4px 0px; -} - -a:hover, .zoomLink:hover, .linkActive:hover { - background: #507aac; -} - -.linkPending, .linkPending:hover { - color: #ffffff; - background: #507aac; -} - -a.white, a.white:link, a.white:visited, a.white:active { - color: #40628a; - text-decoration: none; - background: #ffffff; - border: 1px solid #161616; - padding: 1px 4px 1px 4px; - margin: 0 2px 0 0; - cursor: default; -} - -a.white:hover { - color: #ffffff; - background: #40628a; -} - -.hidden { - display: none; -} - -.linkOn, a.linkOn:link, a.linkOn:visited, a.linkOn:active, a.linkOn:hover, .selected, a.selected:link, a.selected:visited, a.selected:active, a.selected:hover { - color: #ffffff; - background: #2f943c; -} - -.linkOff, a.linkOff:link, a.linkOff:visited, a.linkOff:active, a.linkOff:hover, .disabled, a.disabled:link, a.disabled:visited, a.disabled:active, a.disabled:hover { - color: #ffffff; - background: #999999; - border-color: #666666; -} - -a.icon, .linkOn.icon, .linkOff.icon, .selected.icon, .disabled.icon { - position: relative; - padding: 1px 4px 2px 20px; -} - -a.icon img, .linkOn.icon img, .linkOff.icon img, .selected.icon img, .disabled.icon img { - position: absolute; - top: 0; - left: 0; - width: 18px; - height: 18px; -} - -.linkDanger, a.linkDanger:link, a.linkDanger:visited, a.linkDanger:active { - color: #ffffff; - background-color: #ff0000; - border-color: #aa0000; -} - -.linkDanger:hover { - background-color: #ff6666; -} - -ul { - padding: 4px 0 0 10px; - margin: 0; - list-style-type: none; -} - -li { - padding: 0 0 2px 0; -} - -img, a img { - border-style: none; -} - -h1, h2, h3, h4, h5, h6 { - margin: 0; - padding: 12px 0 6px 0; - color: #FFFFFF; - clear: both; -} - -h1 { - font-size: 18px; -} - -h2 { - font-size: 16px; -} - -h3 { - font-size: 14px; -} - -h4 { - font-size: 12px; -} - -.white { - color: white; - font-weight: bold; -} - -.good { - color: #4f7529; - font-weight: bold; -} - -.average { - color: #cd6500; - font-weight: bold; -} - -.bad { - color: #ee0000; - font-weight: bold; -} - -.idle { - color: #272727; - font-weight: bold; -} - -.redButton { - background: #ea0000; -} - -.greenButton { - background: #00aa00; -} - -.yellowButton { - background: #cacc00; -} - -.highlight { - color: #8BA5C4; -} - -.dark { - color: #272727; -} - -.caption { - font-size: 10px; - font-weight: bold; - padding: 5px; -} - -.footer { - font-size: 10px; -} - -.multiLine { - white-space: pre-wrap; -} - -.noticePlaceholder { - position: relative; - font-size: 12px; - font-style: italic; - font-weight: bold; - padding: 3px 4px 3px 4px; - margin: 4px 0 4px 0; -} - -.notice { - position: relative; - background: url(uiNoticeBackground.jpg) 50% 50%; - color: #000000; - font-size: 12px; - font-style: italic; - font-weight: bold; - padding: 3px 4px 3px 4px; - margin: 4px 0 4px 0; -} - -.notice.icon { - padding: 2px 4px 0 20px; -} - -.notice img { - position: absolute; - top: 0; - left: 0; - width: 16px; - height: 16px; -} - -div.notice { - clear: both; -} - -.itemGroup { - border: 1px solid #e9c183; - background: #2c2c2c; - padding: 4px; - clear: both; -} - -.item { - width: 100%; - margin: 4px 0 0 0; - clear: both; - overflow: auto; -} - -.itemContentNarrow, .itemContent, .itemContentWide, .itemContentSmall, .itemContentMedium { - float: left; -} - -.itemContentNarrow { - width: 30%; -} - -.itemContent { - width: 69%; -} - -.itemLabelNarrow, .itemLabel, .itemLabelWide, .itemLabelWider, .itemLabelWidest { - float: left; - color: #e9c183; -} - -.itemLabelNarrow { - width: 20%; -} - -.itemLabel { - width: 30%; -} - -.itemLabelWide { - width: 45%; -} - -.itemLabelWider { - width: 69%; -} - -.itemLabelWidest { - width: 100%; -} - -.itemContentWide { - width: 79%; -} - -.itemContentSmall { - width: 33%; -} - -.itemContentMedium { - width: 55%; -} - -.statusDisplay { - background: #000000; - color: #ffffff; - border: 1px solid #40628a; - padding: 4px; - margin: 3px 0; - overflow: hidden; -} - -.statusDisplayRecords { - background: #000000; - color: #ffffff; - border: 1px solid #40628a; - padding: 4px; - margin: 3px 0; - overflow-x: hidden; - overflow-y: auto; -} - -.statusDisplayComm { - width: 100%; - background: rgba(0, 0, 0, 0.5); - color: #ffffff; - padding-bottom: 4px; - border-top: 0 none; - border-left: 0 none; - border-right: 0 none; - border-bottom: 2px inset #40628a; - margin: 3px 0; - overflow: hidden; -} - -.statusLabel { - width: 138px; - float: left; - overflow: hidden; - color: #98B0C3; -} - -.statusValue { - float: left; -} - -.block { - padding: 8px; - margin: 10px 4px 4px 4px; - border: 1px solid #40628a; - background-color: #202020; -} - -.block h3 { - padding: 0; -} - -.displayBar { - position: relative; - width: 236px; - height: 16px; - border: 1px solid #666666; - float: left; - margin: 0 5px 0 0; - overflow: hidden; - background: #000000; -} - -.displayBarText, .displayBarVerticalText, .displayBarBeakerText{ - position: absolute; - top: -2px; - left: 5px; - width: 100%; - height: 100%; - color: #ffffff; - font-weight: normal; -} - -.displayBarFill { - width: 0%; - height: 100%; - background: #40628a; - overflow: hidden; - float: left; -} - -.displayBarVertical { - position: relative; - width: 16px; - height: 200px; - border: 1px solid #666666; - float: left; - margin: 0 5px 0 0; - overflow: hidden; - background: #40628a; -} - -.displayBarVerticalFill { - width: 100%; - height: 0%; - overflow: hidden; - float: left; - background: #000000; -} - -/*used in xenobio2 computer*/ - -.displayBarBeaker { - position: relative; - width: 100px; - height: 110px; - border-right: 2px solid rgb(102, 179, 255); - border-left: 2px solid rgb(102, 179, 255); - border-bottom: 2px solid rgb(102, 179, 255); - float: left; - margin: 0 5px 0 0; - overflow: hidden; - background: #40628a; -} - -.displayBarBeakerFill { - width: 100%; - height: 0%; - overflow: hidden; - float: left; - background: rgba(153, 204, 255, 0.3); -} - -.displayBarFill.alignRight { - float: right; -} - -.displayBarFill.good { - color: #ffffff; - background: #4f7529; -} - -.displayBarFill.average { - color: #ffffff; - background: #cd6500; -} - -.displayBarFill.bad { - color: #ffffff; - background: #ee0000; -} - -.displayBarFill.highlight { - color: #ffffff; - background: #8BA5C4; -} - -.clearBoth { - clear: both; -} - -.clearLeft { - clear: left; -} - -.clearRight { - clear: right; -} - -.line { - width: 100%; - clear: both; -} - -.inactive, a.inactive:link, a.inactive:visited, a.inactive:active, a.inactive:hover { - color: #ffffff; - background: #999999; - border-color: #666666; -} - -.fixedLeft { - width: 110px; - float: left; -} - -.fixedLeftWide { - width: 165px; - float: left; -} - -.fixedLeftWider { - width: 220px; - float: left; -} - -.fixedLeftWidest { - width: 250px; - float: left; -} - -.fixedLeftWiderRed { - width: 220px; - float: left; - background: #ee0000; -} - -.floatRight { - float: right; -} - -.floatLeft { - float: left; -} - -/* Used in PDA */ - -.wholeScreen { - position: absolute; - color: #517087; - font-size: 16px; - font-weight: bold; - text-align: center; -} - -.pdalink { - float: left; - white-space: nowrap; -} - -/* DNA Modifier UI (dna_modifier.tmpl) */ - -.dnaBlock { - float: left; - width: 90px; - padding: 0 0 5px 0; -} - -.dnaBlockNumber { - font-family: Fixed, monospace; - float: left; - color: #ffffff; - background: #363636; - min-width: 20px; - height: 20px; - padding: 0; - text-align: center; -} - -.dnaSubBlock { - font-family: Fixed, monospace; - float: left; - padding: 0; - min-width: 16px; - height: 20px; - text-align: center; -} - -.mask { - position: fixed; - left: 0; - top: 0; - width: 100%; - height: 100%; - background: url(uiMaskBackground.png); -} - -.maskContent { - width: 100%; - height: 200px; - margin: 200px 0; - text-align: center; -} - -table.fixed { - table-layout:fixed; -} - -table.fixed td { - overflow: hidden; -} - -/* Table stuffs for power monitor */ -table.pmon { - border: 2px solid RoyalBlue; -} - -table.pmon td, table.pmon th { - border-bottom: 1px dotted black; - padding: 0px 5px 0px 5px; -} - -/* Table Stuffs for manifest*/ - -th.Command { - background: #3333FF; - font-weight: bold; - color: #ffffff; -} - -th.Security { - background: #8e0000; - font-weight: bold; - color: #ffffff; -} - -th.Medical { - background: #006600; - font-weight: bold; - color: #ffffff; -} - -th.Engineering { - background: #b27300; - font-weight: bold; - color: #ffffff; -} - -th.Science { - background: #a65ba6; - font-weight: bold; - color: #ffffff; -} - -th.Cargo { - background: #bb9040; - font-weight: bold; - color: #ffffff; -} - -th.Planetside{ - background: #555555; - font-weight: bold; - color: #ffffff; -} - -th.Civilian { - background: #a32800; - font-weight: bold; - color: #ffffff; -} - -th.Miscellaneous { - background: #666666; - font-weight: bold; - color: #ffffff; -} - -th.Silicon { - background: #222222; - font-weight: bold; - color: #ffffff; -} -/* Damage/health colors for crew monitoring computer */ - -.dead { - color: red; -} - -.alive { - color: #7cfc00; -} - -.burn { - color: orange; -} - -.brute { - color: red; -} - -.toxin { - color: lime; -} - -.oxyloss { - color: cyan; -} - -/* 75px width used in power monitoring console buttons */ -.width75btn { - width: 75px; -} - -/*Communicator Homescreen*/ -div.homeContainer { - width: 100%; - text-align: center; - margin: auto; - padding-top: 5px; -} - -div.homeScreen { - padding: 0 20px 0 20px; -} - -.link64 { - float: left; - min-width: 15px; - max-width: 68px; - height: 64px; - text-align: center; - color: #ffffff; - text-decoration: none; - background: rgba(64, 98, 138, 0.6); - border: 1px solid #161616; - padding: 0 0 4px 0; - margin: 0 0 30px 5.5%; - cursor: default; - border-radius: 10px; -} - -.link64:hover { - font-size: 13px; -} - -/*Communicator Dialing*/ -.dialPad { - clear: both; - text-align: center; - margin: auto; -} - -.dialPadKeys { - float: left; - width: 47px; - height: 47px; - font-size: 32px; - text-align: center; - color: #ffffff; - text-decoration: none; - background: rgba(64, 98, 138, 0.15); - border: 1px inset rgba(100, 100, 100, 0.25); - cursor: default; - line-height: 47px; -} - -.dialPadKeys:hover { - background: rgba(80, 122, 172, 0.5); -} - -.dialPadButtons { - float: left; - width: 63.2px; - height: 63.2px; - text-align: center; - color: #ffffff; - text-decoration: none; - background: rgba(64, 98, 138, 0.15); - border: 1px inset rgba(100, 100, 100, 0.25); - padding: 0 0 4px 0; - cursor: default; - margin-bottom: 25px; -} - -.dialPadButtons:hover { - background: rgba(80, 122, 172, 0.5); - font-size: 13px; - -} - -.dialPadAddress { - float: left; - width: 192px; - height: 18px; - background: rgba(64, 98, 138, 0.15); - color: #ffffff; - border-left: 1px inset #40628a; - border-top: 1px inset #40628a; - border-bottom: 1px inset #40628a; - -} - -.dialPadAddress:hover{ - background: rgba(80, 122, 172, 0.5); -} - -.dialPadClear { - float: left; - width: 19%; - height: 18px; - background: rgba(64, 98, 138, 0.15); - color: #ffffff; - border-right: 1px inset #40628a; - border-top: 1px inset #40628a; - border-bottom: 1px inset #40628a; -} - -.dialPadClear:hover{ - background: rgba(80, 122, 172, 0.5); -} \ No newline at end of file diff --git a/nano/css/shared_vr.css b/nano/css/shared_vr.css deleted file mode 100644 index a368b1fac50..00000000000 --- a/nano/css/shared_vr.css +++ /dev/null @@ -1,5 +0,0 @@ -th.Exploration{ - background: #bab421; - font-weight: bold; - color: #ffffff; -} \ No newline at end of file diff --git a/nano/images/nanomap_z1.png b/nano/images/nanomap_z1.png deleted file mode 100644 index bd575097c31..00000000000 Binary files a/nano/images/nanomap_z1.png and /dev/null differ diff --git a/nano/images/nanomap_z10.png b/nano/images/nanomap_z10.png deleted file mode 100644 index c12164d92e1..00000000000 Binary files a/nano/images/nanomap_z10.png and /dev/null differ diff --git a/nano/images/nanomap_z13.png b/nano/images/nanomap_z13.png deleted file mode 100644 index 6f87d9911fd..00000000000 Binary files a/nano/images/nanomap_z13.png and /dev/null differ diff --git a/nano/images/nanomap_z14.png b/nano/images/nanomap_z14.png deleted file mode 100644 index 84d106a5ac5..00000000000 Binary files a/nano/images/nanomap_z14.png and /dev/null differ diff --git a/nano/images/nanomap_z2.png b/nano/images/nanomap_z2.png deleted file mode 100644 index 5ccd4618085..00000000000 Binary files a/nano/images/nanomap_z2.png and /dev/null differ diff --git a/nano/images/nanomap_z3.png b/nano/images/nanomap_z3.png deleted file mode 100644 index 0761eed916c..00000000000 Binary files a/nano/images/nanomap_z3.png and /dev/null differ diff --git a/nano/images/nanomap_z5.png b/nano/images/nanomap_z5.png deleted file mode 100644 index d8aece303d7..00000000000 Binary files a/nano/images/nanomap_z5.png and /dev/null differ diff --git a/nano/images/nanomap_z6.png b/nano/images/nanomap_z6.png deleted file mode 100644 index 7fb5111527d..00000000000 Binary files a/nano/images/nanomap_z6.png and /dev/null differ diff --git a/nano/images/nanomap_z7.png b/nano/images/nanomap_z7.png deleted file mode 100644 index 7645d78d098..00000000000 Binary files a/nano/images/nanomap_z7.png and /dev/null differ diff --git a/nano/images/nanomap_z8.png b/nano/images/nanomap_z8.png deleted file mode 100644 index c973b2b7842..00000000000 Binary files a/nano/images/nanomap_z8.png and /dev/null differ diff --git a/nano/images/nanomap_z9.png b/nano/images/nanomap_z9.png deleted file mode 100644 index bff91820dd8..00000000000 Binary files a/nano/images/nanomap_z9.png and /dev/null differ diff --git a/nano/images/pills32.png b/nano/images/pills32.png deleted file mode 100644 index 61459093c1c..00000000000 Binary files a/nano/images/pills32.png and /dev/null differ diff --git a/nano/images/source/NTLogoRevised.fla b/nano/images/source/NTLogoRevised.fla deleted file mode 100644 index 47ea8143449..00000000000 Binary files a/nano/images/source/NTLogoRevised.fla and /dev/null differ diff --git a/nano/images/source/icon-eye.xcf b/nano/images/source/icon-eye.xcf deleted file mode 100644 index 53ba7383726..00000000000 Binary files a/nano/images/source/icon-eye.xcf and /dev/null differ diff --git a/nano/images/source/uiBackground-Syndicate.xcf b/nano/images/source/uiBackground-Syndicate.xcf deleted file mode 100644 index c86cea69d14..00000000000 Binary files a/nano/images/source/uiBackground-Syndicate.xcf and /dev/null differ diff --git a/nano/images/source/uiBackground.fla b/nano/images/source/uiBackground.fla deleted file mode 100644 index 60f9f1ee941..00000000000 Binary files a/nano/images/source/uiBackground.fla and /dev/null differ diff --git a/nano/images/source/uiBackground.xcf b/nano/images/source/uiBackground.xcf deleted file mode 100644 index d20db24ff89..00000000000 Binary files a/nano/images/source/uiBackground.xcf and /dev/null differ diff --git a/nano/images/source/uiBasicBackground.xcf b/nano/images/source/uiBasicBackground.xcf deleted file mode 100644 index 56a31d7b2fc..00000000000 Binary files a/nano/images/source/uiBasicBackground.xcf and /dev/null differ diff --git a/nano/images/source/uiIcons16Green.xcf b/nano/images/source/uiIcons16Green.xcf deleted file mode 100644 index a7027a28734..00000000000 Binary files a/nano/images/source/uiIcons16Green.xcf and /dev/null differ diff --git a/nano/images/source/uiIcons16Red.xcf b/nano/images/source/uiIcons16Red.xcf deleted file mode 100644 index c07e4f64c7b..00000000000 Binary files a/nano/images/source/uiIcons16Red.xcf and /dev/null differ diff --git a/nano/images/source/uiIcons24.xcf b/nano/images/source/uiIcons24.xcf deleted file mode 100644 index 5dcd8fd216a..00000000000 Binary files a/nano/images/source/uiIcons24.xcf and /dev/null differ diff --git a/nano/images/source/uiIcons64.xcf b/nano/images/source/uiIcons64.xcf deleted file mode 100644 index 76c06ea1b6f..00000000000 Binary files a/nano/images/source/uiIcons64.xcf and /dev/null differ diff --git a/nano/images/source/uiNoticeBackground.xcf b/nano/images/source/uiNoticeBackground.xcf deleted file mode 100644 index d1f074f1025..00000000000 Binary files a/nano/images/source/uiNoticeBackground.xcf and /dev/null differ diff --git a/nano/images/source/uiTitleBackground.xcf b/nano/images/source/uiTitleBackground.xcf deleted file mode 100644 index 7de149075fd..00000000000 Binary files a/nano/images/source/uiTitleBackground.xcf and /dev/null differ diff --git a/nano/images/status_icons/c_charging.gif b/nano/images/status_icons/c_charging.gif deleted file mode 100644 index e080e27cfc6..00000000000 Binary files a/nano/images/status_icons/c_charging.gif and /dev/null differ diff --git a/nano/images/status_icons/c_discharging.gif b/nano/images/status_icons/c_discharging.gif deleted file mode 100644 index 793fa589c2f..00000000000 Binary files a/nano/images/status_icons/c_discharging.gif and /dev/null differ diff --git a/nano/images/status_icons/c_max.gif b/nano/images/status_icons/c_max.gif deleted file mode 100644 index 7f26e51d20e..00000000000 Binary files a/nano/images/status_icons/c_max.gif and /dev/null differ diff --git a/nano/images/uiBackground-Syndicate.png b/nano/images/uiBackground-Syndicate.png deleted file mode 100644 index 3ca932cb835..00000000000 Binary files a/nano/images/uiBackground-Syndicate.png and /dev/null differ diff --git a/nano/images/uiBackground.png b/nano/images/uiBackground.png deleted file mode 100644 index 32aa9dd7f63..00000000000 Binary files a/nano/images/uiBackground.png and /dev/null differ diff --git a/nano/images/uiBasicBackground.png b/nano/images/uiBasicBackground.png deleted file mode 100644 index 03131d1e94c..00000000000 Binary files a/nano/images/uiBasicBackground.png and /dev/null differ diff --git a/nano/images/uiIcons16.png b/nano/images/uiIcons16.png deleted file mode 100644 index 2017c88d6cc..00000000000 Binary files a/nano/images/uiIcons16.png and /dev/null differ diff --git a/nano/images/uiIcons16Green.png b/nano/images/uiIcons16Green.png deleted file mode 100644 index de0e33db1c7..00000000000 Binary files a/nano/images/uiIcons16Green.png and /dev/null differ diff --git a/nano/images/uiIcons16Red.png b/nano/images/uiIcons16Red.png deleted file mode 100644 index 1c72dfe1430..00000000000 Binary files a/nano/images/uiIcons16Red.png and /dev/null differ diff --git a/nano/images/uiIcons24.png b/nano/images/uiIcons24.png deleted file mode 100644 index ddf88b0dcda..00000000000 Binary files a/nano/images/uiIcons24.png and /dev/null differ diff --git a/nano/images/uiIcons64.png b/nano/images/uiIcons64.png deleted file mode 100644 index d849b3e8699..00000000000 Binary files a/nano/images/uiIcons64.png and /dev/null differ diff --git a/nano/images/uiLinkPendingIcon.gif b/nano/images/uiLinkPendingIcon.gif deleted file mode 100644 index c3070fd157a..00000000000 Binary files a/nano/images/uiLinkPendingIcon.gif and /dev/null differ diff --git a/nano/images/uiMaskBackground.png b/nano/images/uiMaskBackground.png deleted file mode 100644 index 6494f78a611..00000000000 Binary files a/nano/images/uiMaskBackground.png and /dev/null differ diff --git a/nano/images/uiNoticeBackground.jpg b/nano/images/uiNoticeBackground.jpg deleted file mode 100644 index dffe2f296b8..00000000000 Binary files a/nano/images/uiNoticeBackground.jpg and /dev/null differ diff --git a/nano/images/uiTitleFluff-Syndicate.png b/nano/images/uiTitleFluff-Syndicate.png deleted file mode 100644 index b09f5ba6b29..00000000000 Binary files a/nano/images/uiTitleFluff-Syndicate.png and /dev/null differ diff --git a/nano/images/uiTitleFluff.png b/nano/images/uiTitleFluff.png deleted file mode 100644 index 513ba0c4965..00000000000 Binary files a/nano/images/uiTitleFluff.png and /dev/null differ diff --git a/nano/js/libraries-old.min.js b/nano/js/libraries-old.min.js deleted file mode 100644 index fabe4e7dc54..00000000000 --- a/nano/js/libraries-old.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(e,t){function H(e){var t=e.length,n=w.type(e);if(w.isWindow(e)){return false}if(e.nodeType===1&&t){return true}return n==="array"||n!=="function"&&(t===0||typeof t==="number"&&t>0&&t-1 in e)}function j(e){var t=B[e]={};w.each(e.match(S)||[],function(e,n){t[n]=true});return t}function q(e,n,r,i){if(!w.acceptData(e)){return}var s,o,u=w.expando,a=e.nodeType,f=a?w.cache:e,l=a?e[u]:e[u]&&u;if((!l||!f[l]||!i&&!f[l].data)&&r===t&&typeof n==="string"){return}if(!l){if(a){l=e[u]=c.pop()||w.guid++}else{l=u}}if(!f[l]){f[l]=a?{}:{toJSON:w.noop}}if(typeof n==="object"||typeof n==="function"){if(i){f[l]=w.extend(f[l],n)}else{f[l].data=w.extend(f[l].data,n)}}o=f[l];if(!i){if(!o.data){o.data={}}o=o.data}if(r!==t){o[w.camelCase(n)]=r}if(typeof n==="string"){s=o[n];if(s==null){s=o[w.camelCase(n)]}}else{s=o}return s}function R(e,t,n){if(!w.acceptData(e)){return}var r,i,s=e.nodeType,o=s?w.cache:e,u=s?e[w.expando]:w.expando;if(!o[u]){return}if(t){r=n?o[u]:o[u].data;if(r){if(!w.isArray(t)){if(t in r){t=[t]}else{t=w.camelCase(t);if(t in r){t=[t]}else{t=t.split(" ")}}}else{t=t.concat(w.map(t,w.camelCase))}i=t.length;while(i--){delete r[t[i]]}if(n?!z(r):!w.isEmptyObject(r)){return}}}if(!n){delete o[u].data;if(!z(o[u])){return}}if(s){w.cleanData([e],true)}else if(w.support.deleteExpando||o!=o.window){delete o[u]}else{o[u]=null}}function U(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(I,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r==="string"){try{r=r==="true"?true:r==="false"?false:r==="null"?null:+r+""===r?+r:F.test(r)?w.parseJSON(r):r}catch(s){}w.data(e,n,r)}else{r=t}}return r}function z(e){var t;for(t in e){if(t==="data"&&w.isEmptyObject(e[t])){continue}if(t!=="toJSON"){return false}}return true}function it(){return true}function st(){return false}function ot(){try{return o.activeElement}catch(e){}}function ct(e,t){do{e=e[t]}while(e&&e.nodeType!==1);return e}function ht(e,t,n){if(w.isFunction(t)){return w.grep(e,function(e,r){return!!t.call(e,r,e)!==n})}if(t.nodeType){return w.grep(e,function(e){return e===t!==n})}if(typeof t==="string"){if(ut.test(t)){return w.filter(t,e,n)}t=w.filter(t,e)}return w.grep(e,function(e){return w.inArray(e,t)>=0!==n})}function pt(e){var t=dt.split("|"),n=e.createDocumentFragment();if(n.createElement){while(t.length){n.createElement(t.pop())}}return n}function Mt(e,t){return w.nodeName(e,"table")&&w.nodeName(t.nodeType===1?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function _t(e){e.type=(w.find.attr(e,"type")!==null)+"/"+e.type;return e}function Dt(e){var t=Ct.exec(e.type);if(t){e.type=t[1]}else{e.removeAttribute("type")}return e}function Pt(e,t){var n,r=0;for(;(n=e[r])!=null;r++){w._data(n,"globalEval",!t||w._data(t[r],"globalEval"))}}function Ht(e,t){if(t.nodeType!==1||!w.hasData(e)){return}var n,r,i,s=w._data(e),o=w._data(t,s),u=s.events;if(u){delete o.handle;o.events={};for(n in u){for(r=0,i=u[n].length;r").css("cssText","display:block !important")).appendTo(t.documentElement);t=(It[0].contentWindow||It[0].contentDocument).document;t.write("");t.close();n=fn(e,t);It.detach()}Qt[e]=n}return n}function fn(e,t){var n=w(t.createElement(e)).appendTo(t.body),r=w.css(n[0],"display");n.remove();return r}function vn(e,t,n,r){var i;if(w.isArray(t)){w.each(t,function(t,i){if(n||cn.test(e)){r(e,i)}else{vn(e+"["+(typeof i==="object"?t:"")+"]",i,n,r)}})}else if(!n&&w.type(t)==="object"){for(i in t){vn(e+"["+i+"]",t[i],n,r)}}else{r(e,t)}}function _n(e){return function(t,n){if(typeof t!=="string"){n=t;t="*"}var r,i=0,s=t.toLowerCase().match(S)||[];if(w.isFunction(n)){while(r=s[i++]){if(r[0]==="+"){r=r.slice(1)||"*";(e[r]=e[r]||[]).unshift(n)}else{(e[r]=e[r]||[]).push(n)}}}}}function Dn(e,t,n,r){function o(u){var a;i[u]=true;w.each(e[u]||[],function(e,u){var f=u(t,n,r);if(typeof f==="string"&&!s&&!i[f]){t.dataTypes.unshift(f);o(f);return false}else if(s){return!(a=f)}});return a}var i={},s=e===An;return o(t.dataTypes[0])||!i["*"]&&o("*")}function Pn(e,n){var r,i,s=w.ajaxSettings.flatOptions||{};for(i in n){if(n[i]!==t){(s[i]?e:r||(r={}))[i]=n[i]}}if(r){w.extend(true,e,r)}return e}function Hn(e,n,r){var i,s,o,u,a=e.contents,f=e.dataTypes;while(f[0]==="*"){f.shift();if(s===t){s=e.mimeType||n.getResponseHeader("Content-Type")}}if(s){for(u in a){if(a[u]&&a[u].test(s)){f.unshift(u);break}}}if(f[0]in r){o=f[0]}else{for(u in r){if(!f[0]||e.converters[u+" "+f[0]]){o=u;break}if(!i){i=u}}o=o||i}if(o){if(o!==f[0]){f.unshift(o)}return r[o]}}function Bn(e,t,n,r){var i,s,o,u,a,f={},l=e.dataTypes.slice();if(l[1]){for(o in e.converters){f[o.toLowerCase()]=e.converters[o]}}s=l.shift();while(s){if(e.responseFields[s]){n[e.responseFields[s]]=t}if(!a&&r&&e.dataFilter){t=e.dataFilter(t,e.dataType)}a=s;s=l.shift();if(s){if(s==="*"){s=a}else if(a!=="*"&&a!==s){o=f[a+" "+s]||f["* "+s];if(!o){for(i in f){u=i.split(" ");if(u[1]===s){o=f[a+" "+u[0]]||f["* "+u[0]];if(o){if(o===true){o=f[i]}else if(f[i]!==true){s=u[0];l.unshift(u[1])}break}}}}if(o!==true){if(o&&e["throws"]){t=o(t)}else{try{t=o(t)}catch(c){return{state:"parsererror",error:o?c:"No conversion from "+a+" to "+s}}}}}}}return{state:"success",data:t}}function zn(){try{return new e.XMLHttpRequest}catch(t){}}function Wn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function Yn(){setTimeout(function(){Xn=t});return Xn=w.now()}function Zn(e,t,n){var r,i=(Gn[t]||[]).concat(Gn["*"]),s=0,o=i.length;for(;s)[^>]*|#([\w-]*))$/,N=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,C=/^[\],:{}\s]*$/,k=/(?:^|:|,)(?:\s*\[)+/g,L=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,O=/^-ms-/,M=/-([\da-z])/gi,_=function(e,t){return t.toUpperCase()},D=function(e){if(o.addEventListener||e.type==="load"||o.readyState==="complete"){P();w.ready()}},P=function(){if(o.addEventListener){o.removeEventListener("DOMContentLoaded",D,false);e.removeEventListener("load",D,false)}else{o.detachEvent("onreadystatechange",D);e.detachEvent("onload",D)}};w.fn=w.prototype={jquery:h,constructor:w,init:function(e,n,r){var i,s;if(!e){return this}if(typeof e==="string"){if(e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3){i=[null,e,null]}else{i=T.exec(e)}if(i&&(i[1]||!n)){if(i[1]){n=n instanceof w?n[0]:n;w.merge(this,w.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,true));if(N.test(i[1])&&w.isPlainObject(n)){for(i in n){if(w.isFunction(this[i])){this[i](n[i])}else{this.attr(i,n[i])}}}return this}else{s=o.getElementById(i[2]);if(s&&s.parentNode){if(s.id!==i[2]){return r.find(e)}this.length=1;this[0]=s}this.context=o;this.selector=e;return this}}else if(!n||n.jquery){return(n||r).find(e)}else{return this.constructor(n).find(e)}}else if(e.nodeType){this.context=this[0]=e;this.length=1;return this}else if(w.isFunction(e)){return r.ready(e)}if(e.selector!==t){this.selector=e.selector;this.context=e.context}return w.makeArray(e,this)},selector:"",length:0,toArray:function(){return v.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);t.prevObject=this;t.context=this.context;return t},each:function(e,t){return w.each(this,e,t)},ready:function(e){w.ready.promise().done(e);return this},slice:function(){return this.pushStack(v.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n0){return}n.resolveWith(o,[w]);if(w.fn.trigger){w(o).trigger("ready").off("ready")}},isFunction:function(e){return w.type(e)==="function"},isArray:Array.isArray||function(e){return w.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){if(e==null){return String(e)}return typeof e==="object"||typeof e==="function"?l[g.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||w.type(e)!=="object"||e.nodeType||w.isWindow(e)){return false}try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf")){return false}}catch(r){return false}if(w.support.ownLast){for(n in e){return y.call(e,n)}}for(n in e){}return n===t||y.call(e,n)},isEmptyObject:function(e){var t;for(t in e){return false}return true},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){if(!e||typeof e!=="string"){return null}if(typeof t==="boolean"){n=t;t=false}t=t||o;var r=N.exec(e),i=!n&&[];if(r){return[t.createElement(r[1])]}r=w.buildFragment([e],t,i);if(i){w(i).remove()}return w.merge([],r.childNodes)},parseJSON:function(t){if(e.JSON&&e.JSON.parse){return e.JSON.parse(t)}if(t===null){return t}if(typeof t==="string"){t=w.trim(t);if(t){if(C.test(t.replace(L,"@").replace(A,"]").replace(k,""))){return(new Function("return "+t))()}}}w.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!=="string"){return null}try{if(e.DOMParser){i=new DOMParser;r=i.parseFromString(n,"text/xml")}else{r=new ActiveXObject("Microsoft.XMLDOM");r.async="false";r.loadXML(n)}}catch(s){r=t}if(!r||!r.documentElement||r.getElementsByTagName("parsererror").length){w.error("Invalid XML: "+n)}return r},noop:function(){},globalEval:function(t){if(t&&w.trim(t)){(e.execScript||function(t){e["eval"].call(e,t)})(t)}},camelCase:function(e){return e.replace(O,"ms-").replace(M,_)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,s=e.length,o=H(e);if(n){if(o){for(;is.cacheLength){delete t[e.shift()]}return t[n]=r}var e=[];return t}function at(e){e[b]=true;return e}function ft(e){var t=h.createElement("div");try{return!!e(t)}catch(n){return false}finally{if(t.parentNode){t.parentNode.removeChild(t)}t=null}}function lt(e,t){var n=e.split("|"),r=e.length;while(r--){s.attrHandle[n[r]]=t}}function ct(e,t){var n=t&&e,r=n&&e.nodeType===1&&t.nodeType===1&&(~t.sourceIndex||O)-(~e.sourceIndex||O);if(r){return r}if(n){while(n=n.nextSibling){if(n===t){return-1}}}return e?1:-1}function ht(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function pt(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function dt(e){return at(function(t){t=+t;return at(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--){if(n[i=s[o]]){n[i]=!(r[i]=n[i])}}})})}function vt(){}function mt(e,t){var n,r,i,o,u,a,f,l=N[e+" "];if(l){return t?0:l.slice(0)}u=e;a=[];f=s.preFilter;while(u){if(!n||(r=X.exec(u))){if(r){u=u.slice(r[0].length)||u}a.push(i=[])}n=false;if(r=V.exec(u)){n=r.shift();i.push({value:n,type:r[0].replace(W," ")});u=u.slice(n.length)}for(o in s.filter){if((r=G[o].exec(u))&&(!f[o]||(r=f[o](r)))){n=r.shift();i.push({value:n,type:o,matches:r});u=u.slice(n.length)}}if(!n){break}}return t?u.length:u?ot.error(e):N(e,a).slice(0)}function gt(e){var t=0,n=e.length,r="";for(;t1?function(t,n,r){var i=e.length;while(i--){if(!e[i](t,n,r)){return false}}return true}:e[0]}function wt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1){s[f]=!(o[f]=c)}}}}else{g=wt(g===o?g.splice(d,g.length):g);if(i){i(null,o,g,a)}else{H.apply(o,g)}}})}function St(e){var t,n,r,i=e.length,o=s.relative[e[0].type],u=o||s.relative[" "],a=o?1:0,l=yt(function(e){return e===t},u,true),c=yt(function(e){return j.call(t,e)>-1},u,true),h=[function(e,n,r){return!o&&(r||n!==f)||((t=n).nodeType?l(e,n,r):c(e,n,r))}];for(;a1&&bt(h),a>1&>(e.slice(0,a-1).concat({value:e[a-2].type===" "?"*":""})).replace(W,"$1"),n,a0,o=e.length>0,u=function(u,a,l,c,p){var d,v,m,g=[],y=0,b="0",w=u&&[],E=p!=null,x=f,T=u||o&&s.find["TAG"]("*",p&&a.parentNode||a),N=S+=x==null?1:Math.random()||.1;if(E){f=a!==h&&a;i=n}for(;(d=T[b])!=null;b++){if(o&&d){v=0;while(m=e[v++]){if(m(d,a,l)){c.push(d);break}}if(E){S=N;i=++n}}if(r){if(d=!m&&d){y--}if(u){w.push(d)}}}y+=b;if(r&&b!==y){v=0;while(m=t[v++]){m(w,g,a,l)}if(u){if(y>0){while(b--){if(!(w[b]||g[b])){g[b]=D.call(c)}}}g=wt(g)}H.apply(c,g);if(E&&!u&&g.length>0&&y+t.length>1){ot.uniqueSort(c)}}if(E){S=N;f=x}return w};return r?at(u):u}function Tt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&r.getById&&t.nodeType===9&&d&&s.relative[u[1].type]){t=(s.find["ID"](f.matches[0].replace(rt,it),t)||[])[0];if(!t){return n}e=e.slice(u.shift().value.length)}o=G["needsContext"].test(e)?0:u.length;while(o--){f=u[o];if(s.relative[l=f.type]){break}if(c=s.find[l]){if(i=c(f.matches[0].replace(rt,it),$.test(u[0].type)&&t.parentNode||t)){u.splice(o,1);e=i.length&>(u);if(!e){H.apply(n,i);return n}break}}}}}a(e,h)(i,t,!d,n,$.test(e));return n}var n,r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b="sizzle"+ -(new Date),E=e.document,S=0,x=0,T=ut(),N=ut(),C=ut(),k=false,L=function(e,t){if(e===t){k=true;return 0}return 0},A=typeof t,O=1<<31,M={}.hasOwnProperty,_=[],D=_.pop,P=_.push,H=_.push,B=_.slice,j=_.indexOf||function(e){var t=0,n=this.length;for(;t+~]|"+I+")"+I+"*"),$=new RegExp(I+"*[+~]"),J=new RegExp("="+I+"*([^\\]'\"]*)"+I+"*\\]","g"),K=new RegExp(z),Q=new RegExp("^"+R+"$"),G={ID:new RegExp("^#("+q+")"),CLASS:new RegExp("^\\.("+q+")"),TAG:new RegExp("^("+q.replace("w","w*")+")"),ATTR:new RegExp("^"+U),PSEUDO:new RegExp("^"+z),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+I+"*(even|odd|(([+-]|)(\\d*)n|)"+I+"*(?:([+-]|)"+I+"*(\\d+)|))"+I+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+I+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+I+"*((?:-\\d)?\\d*)"+I+"*\\)|)(?=[^-]|$)","i")},Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=new RegExp("\\\\([\\da-f]{1,6}"+I+"?|("+I+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,r&1023|56320)};try{H.apply(_=B.call(E.childNodes),E.childNodes);_[E.childNodes.length].nodeType}catch(st){H={apply:_.length?function(e,t){P.apply(e,B.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]){}e.length=n-1}}}u=ot.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":false};r=ot.support={};c=ot.setDocument=function(e){var t=e?e.ownerDocument||e:E,n=t.defaultView;if(t===h||t.nodeType!==9||!t.documentElement){return h}h=t;p=t.documentElement;d=!u(t);if(n&&n.attachEvent&&n!==n.top){n.attachEvent("onbeforeunload",function(){c()})}r.attributes=ft(function(e){e.className="i";return!e.getAttribute("className")});r.getElementsByTagName=ft(function(e){e.appendChild(t.createComment(""));return!e.getElementsByTagName("*").length});r.getElementsByClassName=ft(function(e){e.innerHTML="
";e.firstChild.className="i";return e.getElementsByClassName("i").length===2});r.getById=ft(function(e){p.appendChild(e).id=b;return!t.getElementsByName||!t.getElementsByName(b).length});if(r.getById){s.find["ID"]=function(e,t){if(typeof t.getElementById!==A&&d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}};s.filter["ID"]=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}}else{delete s.find["ID"];s.filter["ID"]=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}}s.find["TAG"]=r.getElementsByTagName?function(e,t){if(typeof t.getElementsByTagName!==A){return t.getElementsByTagName(e)}}:function(e,t){var n,r=[],i=0,s=t.getElementsByTagName(e);if(e==="*"){while(n=s[i++]){if(n.nodeType===1){r.push(n)}}return r}return s};s.find["CLASS"]=r.getElementsByClassName&&function(e,t){if(typeof t.getElementsByClassName!==A&&d){return t.getElementsByClassName(e)}};m=[];v=[];if(r.qsa=Y.test(t.querySelectorAll)){ft(function(e){e.innerHTML="";if(!e.querySelectorAll("[selected]").length){v.push("\\["+I+"*(?:value|"+F+")")}if(!e.querySelectorAll(":checked").length){v.push(":checked")}});ft(function(e){var n=t.createElement("input");n.setAttribute("type","hidden");e.appendChild(n).setAttribute("t","");if(e.querySelectorAll("[t^='']").length){v.push("[*^$]="+I+"*(?:''|\"\")")}if(!e.querySelectorAll(":enabled").length){v.push(":enabled",":disabled")}e.querySelectorAll("*,:x");v.push(",.*:")})}if(r.matchesSelector=Y.test(g=p.webkitMatchesSelector||p.mozMatchesSelector||p.oMatchesSelector||p.msMatchesSelector)){ft(function(e){r.disconnectedMatch=g.call(e,"div");g.call(e,"[s!='']:x");m.push("!=",z)})}v=v.length&&new RegExp(v.join("|"));m=m.length&&new RegExp(m.join("|"));y=Y.test(p.contains)||p.compareDocumentPosition?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&(n.contains?n.contains(r):e.compareDocumentPosition&&e.compareDocumentPosition(r)&16))}:function(e,t){if(t){while(t=t.parentNode){if(t===e){return true}}}return false};L=p.compareDocumentPosition?function(e,n){if(e===n){k=true;return 0}var i=n.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(n);if(i){if(i&1||!r.sortDetached&&n.compareDocumentPosition(e)===i){if(e===t||y(E,e)){return-1}if(n===t||y(E,n)){return 1}return l?j.call(l,e)-j.call(l,n):0}return i&4?-1:1}return e.compareDocumentPosition?-1:1}:function(e,n){var r,i=0,s=e.parentNode,o=n.parentNode,u=[e],a=[n];if(e===n){k=true;return 0}else if(!s||!o){return e===t?-1:n===t?1:s?-1:o?1:l?j.call(l,e)-j.call(l,n):0}else if(s===o){return ct(e,n)}r=e;while(r=r.parentNode){u.unshift(r)}r=n;while(r=r.parentNode){a.unshift(r)}while(u[i]===a[i]){i++}return i?ct(u[i],a[i]):u[i]===E?-1:a[i]===E?1:0};return t};ot.matches=function(e,t){return ot(e,null,null,t)};ot.matchesSelector=function(e,t){if((e.ownerDocument||e)!==h){c(e)}t=t.replace(J,"='$1']");if(r.matchesSelector&&d&&(!m||!m.test(t))&&(!v||!v.test(t))){try{var n=g.call(e,t);if(n||r.disconnectedMatch||e.document&&e.document.nodeType!==11){return n}}catch(i){}}return ot(t,h,null,[e]).length>0};ot.contains=function(e,t){if((e.ownerDocument||e)!==h){c(e)}return y(e,t)};ot.attr=function(e,n){if((e.ownerDocument||e)!==h){c(e)}var i=s.attrHandle[n.toLowerCase()],o=i&&M.call(s.attrHandle,n.toLowerCase())?i(e,n,!d):t;return o===t?r.attributes||!d?e.getAttribute(n):(o=e.getAttributeNode(n))&&o.specified?o.value:null:o};ot.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)};ot.uniqueSort=function(e){var t,n=[],i=0,s=0;k=!r.detectDuplicates;l=!r.sortStable&&e.slice(0);e.sort(L);if(k){while(t=e[s++]){if(t===e[s]){i=n.push(s)}}while(i--){e.splice(n[i],1)}}return e};o=ot.getText=function(e){var t,n="",r=0,i=e.nodeType;if(!i){for(;t=e[r];r++){n+=o(t)}}else if(i===1||i===9||i===11){if(typeof e.textContent==="string"){return e.textContent}else{for(e=e.firstChild;e;e=e.nextSibling){n+=o(e)}}}else if(i===3||i===4){return e.nodeValue}return n};s=ot.selectors={cacheLength:50,createPseudo:at,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:true}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:true},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){e[1]=e[1].replace(rt,it);e[3]=(e[4]||e[5]||"").replace(rt,it);if(e[2]==="~="){e[3]=" "+e[3]+" "}return e.slice(0,4)},CHILD:function(e){e[1]=e[1].toLowerCase();if(e[1].slice(0,3)==="nth"){if(!e[3]){ot.error(e[0])}e[4]=+(e[4]?e[5]+(e[6]||1):2*(e[3]==="even"||e[3]==="odd"));e[5]=+(e[7]+e[8]||e[3]==="odd")}else if(e[3]){ot.error(e[0])}return e},PSEUDO:function(e){var n,r=!e[5]&&e[2];if(G["CHILD"].test(e[0])){return null}if(e[3]&&e[4]!==t){e[2]=e[4]}else if(r&&K.test(r)&&(n=mt(r,true))&&(n=r.indexOf(")",r.length-n)-r.length)){e[0]=e[0].slice(0,n);e[2]=r.slice(0,n)}return e.slice(0,3)}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return e==="*"?function(){return true}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=T[e+" "];return t||(t=new RegExp("(^|"+I+")"+e+"("+I+"|$)"))&&T(e,function(e){return t.test(typeof e.className==="string"&&e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=ot.attr(r,e);if(i==null){return t==="!="}if(!t){return true}i+="";return t==="="?i===n:t==="!="?i!==n:t==="^="?n&&i.indexOf(n)===0:t==="*="?n&&i.indexOf(n)>-1:t==="$="?n&&i.slice(-n.length)===n:t==="~="?(" "+i+" ").indexOf(n)>-1:t==="|="?i===n||i.slice(0,n.length+1)===n+"-":false}},CHILD:function(e,t,n,r,i){var s=e.slice(0,3)!=="nth",o=e.slice(-4)!=="last",u=t==="of-type";return r===1&&i===0?function(e){return!!e.parentNode}:function(t,n,a){var f,l,c,h,p,d,v=s!==o?"nextSibling":"previousSibling",m=t.parentNode,g=u&&t.nodeName.toLowerCase(),y=!a&&!u;if(m){if(s){while(v){c=t;while(c=c[v]){if(u?c.nodeName.toLowerCase()===g:c.nodeType===1){return false}}d=v=e==="only"&&!d&&"nextSibling"}return true}d=[o?m.firstChild:m.lastChild];if(o&&y){l=m[b]||(m[b]={});f=l[e]||[];p=f[0]===S&&f[1];h=f[0]===S&&f[2];c=p&&m.childNodes[p];while(c=++p&&c&&c[v]||(h=p=0)||d.pop()){if(c.nodeType===1&&++h&&c===t){l[e]=[S,p,h];break}}}else if(y&&(f=(t[b]||(t[b]={}))[e])&&f[0]===S){h=f[1]}else{while(c=++p&&c&&c[v]||(h=p=0)||d.pop()){if((u?c.nodeName.toLowerCase()===g:c.nodeType===1)&&++h){if(y){(c[b]||(c[b]={}))[e]=[S,h]}if(c===t){break}}}}h-=i;return h===r||h%r===0&&h/r>=0}}},PSEUDO:function(e,t){var n,r=s.pseudos[e]||s.setFilters[e.toLowerCase()]||ot.error("unsupported pseudo: "+e);if(r[b]){return r(t)}if(r.length>1){n=[e,e,"",t];return s.setFilters.hasOwnProperty(e.toLowerCase())?at(function(e,n){var i,s=r(e,t),o=s.length;while(o--){i=j.call(e,s[o]);e[i]=!(n[i]=s[o])}}):function(e){return r(e,0,n)}}return r}},pseudos:{not:at(function(e){var t=[],n=[],r=a(e.replace(W,"$1"));return r[b]?at(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--){if(s=o[u]){e[u]=!(t[u]=s)}}}):function(e,i,s){t[0]=e;r(t,null,s,n);return!n.pop()}}),has:at(function(e){return function(t){return ot(e,t).length>0}}),contains:at(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:at(function(e){if(!Q.test(e||"")){ot.error("unsupported lang: "+e)}e=e.replace(rt,it).toLowerCase();return function(t){var n;do{if(n=d?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang")){n=n.toLowerCase();return n===e||n.indexOf(e+"-")===0}}while((t=t.parentNode)&&t.nodeType===1);return false}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===p},focus:function(e){return e===h.activeElement&&(!h.hasFocus||h.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===false},disabled:function(e){return e.disabled===true},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling){if(e.nodeName>"@"||e.nodeType===3||e.nodeType===4){return false}}return true},parent:function(e){return!s.pseudos["empty"](e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},text:function(e){var t;return e.nodeName.toLowerCase()==="input"&&e.type==="text"&&((t=e.getAttribute("type"))==null||t.toLowerCase()===e.type)},first:dt(function(){return[0]}),last:dt(function(e,t){return[t-1]}),eq:dt(function(e,t,n){return[n<0?n+t:n]}),even:dt(function(e,t){var n=0;for(;n=0;){e.push(r)}return e}),gt:dt(function(e,t,n){var r=n<0?n+t:n;for(;++r";e.firstChild.setAttribute("value","");return e.firstChild.getAttribute("value")===""})){lt("value",function(e,t,n){if(!n&&e.nodeName.toLowerCase()==="input"){return e.defaultValue}})}if(!ft(function(e){return e.getAttribute("disabled")==null})){lt(F,function(e,t,n){var r;if(!n){return(r=e.getAttributeNode(t))&&r.specified?r.value:e[t]===true?t.toLowerCase():null}})}w.find=ot;w.expr=ot.selectors;w.expr[":"]=w.expr.pseudos;w.unique=ot.uniqueSort;w.text=ot.getText;w.isXMLDoc=ot.isXML;w.contains=ot.contains})(e);var B={};w.Callbacks=function(e){e=typeof e==="string"?B[e]||j(e):w.extend({},e);var n,r,i,s,o,u,a=[],f=!e.once&&[],l=function(t){r=e.memory&&t;i=true;o=u||0;u=0;s=a.length;n=true;for(;a&&o-1){a.splice(r,1);if(n){if(r<=s){s--}if(r<=o){o--}}}})}return this},has:function(e){return e?w.inArray(e,a)>-1:!!(a&&a.length)},empty:function(){a=[];s=0;return this},disable:function(){a=f=r=t;return this},disabled:function(){return!a},lock:function(){f=t;if(!r){c.disable()}return this},locked:function(){return!f},fireWith:function(e,t){if(a&&(!i||f)){t=t||[];t=[e,t.slice?t.slice():t];if(n){f.push(t)}else{l(t)}}return this},fire:function(){c.fireWith(this,arguments);return this},fired:function(){return!!i}};return c};w.extend({Deferred:function(e){var t=[["resolve","done",w.Callbacks("once memory"),"resolved"],["reject","fail",w.Callbacks("once memory"),"rejected"],["notify","progress",w.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){i.done(arguments).fail(arguments);return this},then:function(){var e=arguments;return w.Deferred(function(n){w.each(t,function(t,s){var o=s[0],u=w.isFunction(e[t])&&e[t];i[s[1]](function(){var e=u&&u.apply(this,arguments);if(e&&w.isFunction(e.promise)){e.promise().done(n.resolve).fail(n.reject).progress(n.notify)}else{n[o+"With"](this===r?n.promise():this,u?[e]:arguments)}})});e=null}).promise()},promise:function(e){return e!=null?w.extend(e,r):r}},i={};r.pipe=r.then;w.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add;if(u){o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock)}i[s[0]]=function(){i[s[0]+"With"](this===i?r:this,arguments);return this};i[s[0]+"With"]=o.fireWith});r.promise(i);if(e){e.call(i,i)}return i},when:function(e){var t=0,n=v.call(arguments),r=n.length,i=r!==1||e&&w.isFunction(e.promise)?r:0,s=i===1?e:w.Deferred(),o=function(e,t,n){return function(r){t[e]=this;n[e]=arguments.length>1?v.call(arguments):r;if(n===u){s.notifyWith(t,n)}else if(!--i){s.resolveWith(t,n)}}},u,a,f;if(r>1){u=new Array(r);a=new Array(r);f=new Array(r);for(;t
a";n=p.getElementsByTagName("*")||[];r=p.getElementsByTagName("a")[0];if(!r||!r.style||!n.length){return t}u=o.createElement("select");f=u.appendChild(o.createElement("option"));s=p.getElementsByTagName("input")[0];r.style.cssText="top:1px;float:left;opacity:.5";t.getSetAttribute=p.className!=="t";t.leadingWhitespace=p.firstChild.nodeType===3;t.tbody=!p.getElementsByTagName("tbody").length;t.htmlSerialize=!!p.getElementsByTagName("link").length;t.style=/top/.test(r.getAttribute("style"));t.hrefNormalized=r.getAttribute("href")==="/a";t.opacity=/^0.5/.test(r.style.opacity);t.cssFloat=!!r.style.cssFloat;t.checkOn=!!s.value;t.optSelected=f.selected;t.enctype=!!o.createElement("form").enctype;t.html5Clone=o.createElement("nav").cloneNode(true).outerHTML!=="<:nav>";t.inlineBlockNeedsLayout=false;t.shrinkWrapBlocks=false;t.pixelPosition=false;t.deleteExpando=true;t.noCloneEvent=true;t.reliableMarginRight=true;t.boxSizingReliable=true;s.checked=true;t.noCloneChecked=s.cloneNode(true).checked;u.disabled=true;t.optDisabled=!f.disabled;try{delete p.test}catch(d){t.deleteExpando=false}s=o.createElement("input");s.setAttribute("value","");t.input=s.getAttribute("value")==="";s.value="t";s.setAttribute("type","radio");t.radioValue=s.value==="t";s.setAttribute("checked","t");s.setAttribute("name","t");a=o.createDocumentFragment();a.appendChild(s);t.appendChecked=s.checked;t.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;if(p.attachEvent){p.attachEvent("onclick",function(){t.noCloneEvent=false});p.cloneNode(true).click()}for(h in{submit:true,change:true,focusin:true}){p.setAttribute(l="on"+h,"t");t[h+"Bubbles"]=l in e||p.attributes[l].expando===false}p.style.backgroundClip="content-box";p.cloneNode(true).style.backgroundClip="";t.clearCloneStyle=p.style.backgroundClip==="content-box";for(h in w(t)){break}t.ownLast=h!=="0";w(function(){var n,r,s,u="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",a=o.getElementsByTagName("body")[0];if(!a){return}n=o.createElement("div");n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";a.appendChild(n).appendChild(p);p.innerHTML="
t
";s=p.getElementsByTagName("td");s[0].style.cssText="padding:0;margin:0;border:0;display:none";c=s[0].offsetHeight===0;s[0].style.display="";s[1].style.display="none";t.reliableHiddenOffsets=c&&s[0].offsetHeight===0;p.innerHTML="";p.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";w.swap(a,a.style.zoom!=null?{zoom:1}:{},function(){t.boxSizing=p.offsetWidth===4});if(e.getComputedStyle){t.pixelPosition=(e.getComputedStyle(p,null)||{}).top!=="1%";t.boxSizingReliable=(e.getComputedStyle(p,null)||{width:"4px"}).width==="4px";r=p.appendChild(o.createElement("div"));r.style.cssText=p.style.cssText=u;r.style.marginRight=r.style.width="0";p.style.width="1px";t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)}if(typeof p.style.zoom!==i){p.innerHTML="";p.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1";t.inlineBlockNeedsLayout=p.offsetWidth===3;p.style.display="block";p.innerHTML="
";p.firstChild.style.width="5px";t.shrinkWrapBlocks=p.offsetWidth!==3;if(t.inlineBlockNeedsLayout){a.style.zoom=1}}a.removeChild(n);n=p=s=r=null});n=u=a=f=r=s=null;return t}({});var F=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,I=/([A-Z])/g;w.extend({cache:{},noData:{applet:true,embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){e=e.nodeType?w.cache[e[w.expando]]:e[w.expando];return!!e&&!z(e)},data:function(e,t,n){return q(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return q(e,t,n,true)},_removeData:function(e,t){return R(e,t,true)},acceptData:function(e){if(e.nodeType&&e.nodeType!==1&&e.nodeType!==9){return false}var t=e.nodeName&&w.noData[e.nodeName.toLowerCase()];return!t||t!==true&&e.getAttribute("classid")===t}});w.fn.extend({data:function(e,n){var r,i,s=null,o=0,u=this[0];if(e===t){if(this.length){s=w.data(u);if(u.nodeType===1&&!w._data(u,"parsedAttrs")){r=u.attributes;for(;o1?this.each(function(){w.data(this,e,n)}):u?U(u,e,w.data(u,e)):null},removeData:function(e){return this.each(function(){w.removeData(this,e)})}});w.extend({queue:function(e,t,n){var r;if(e){t=(t||"fx")+"queue";r=w._data(e,t);if(n){if(!r||w.isArray(n)){r=w._data(e,t,w.makeArray(n))}else{r.push(n)}}return r||[]}},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),s=w._queueHooks(e,t),o=function(){w.dequeue(e,t)};if(i==="inprogress"){i=n.shift();r--}if(i){if(t==="fx"){n.unshift("inprogress")}delete s.stop;i.call(e,o,s)}if(!r&&s){s.empty.fire()}},_queueHooks:function(e,t){var n=t+"queueHooks";return w._data(e,n)||w._data(e,n,{empty:w.Callbacks("once memory").add(function(){w._removeData(e,t+"queue");w._removeData(e,n)})})}});w.fn.extend({queue:function(e,n){var r=2;if(typeof e!=="string"){n=e;e="fx";r--}if(arguments.length1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})},prop:function(e,t){return w.access(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){e=w.propFix[e]||e;return this.each(function(){try{this[e]=t;delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o=0,u=this.length,a=typeof e==="string"&&e;if(w.isFunction(e)){return this.each(function(t){w(this).addClass(e.call(this,t,this.className))})}if(a){t=(e||"").match(S)||[];for(;o=0){r=r.replace(" "+i+" "," ")}}n.className=e?w.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e;if(typeof t==="boolean"&&n==="string"){return t?this.addClass(e):this.removeClass(e)}if(w.isFunction(e)){return this.each(function(n){w(this).toggleClass(e.call(this,n,this.className,t),t)})}return this.each(function(){if(n==="string"){var t,r=0,s=w(this),o=e.match(S)||[];while(t=o[r++]){if(s.hasClass(t)){s.removeClass(t)}else{s.addClass(t)}}}else if(n===i||n==="boolean"){if(this.className){w._data(this,"__className__",this.className)}this.className=this.className||e===false?"":w._data(this,"__className__")||""}})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0){return true}}return false},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s){r=w.valHooks[s.type]||w.valHooks[s.nodeName.toLowerCase()];if(r&&"get"in r&&(n=r.get(s,"value"))!==t){return n}n=s.value;return typeof n==="string"?n.replace($,""):n==null?"":n}return}i=w.isFunction(e);return this.each(function(n){var s;if(this.nodeType!==1){return}if(i){s=e.call(this,n,w(this).val())}else{s=e}if(s==null){s=""}else if(typeof s==="number"){s+=""}else if(w.isArray(s)){s=w.map(s,function(e){return e==null?"":e+""})}r=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()];if(!r||!("set"in r)||r.set(this,s,"value")===t){this.value=s}})}});w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return t!=null?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0){n=true}}if(!n){e.selectedIndex=-1}return s}}},attr:function(e,n,r){var s,o,u=e.nodeType;if(!e||u===3||u===8||u===2){return}if(typeof e.getAttribute===i){return w.prop(e,n,r)}if(u!==1||!w.isXMLDoc(e)){n=n.toLowerCase();s=w.attrHooks[n]||(w.expr.match.bool.test(n)?X:W)}if(r!==t){if(r===null){w.removeAttr(e,n)}else if(s&&"set"in s&&(o=s.set(e,r,n))!==t){return o}else{e.setAttribute(n,r+"");return r}}else if(s&&"get"in s&&(o=s.get(e,n))!==null){return o}else{o=w.find.attr(e,n);return o==null?t:o}},removeAttr:function(e,t){var n,r,i=0,s=t&&t.match(S);if(s&&e.nodeType===1){while(n=s[i++]){r=w.propFix[n]||n;if(w.expr.match.bool.test(n)){if(Y&&G||!Q.test(n)){e[r]=false}else{e[w.camelCase("default-"+n)]=e[r]=false}}else{w.attr(e,n,"")}e.removeAttribute(G?n:r)}}},attrHooks:{type:{set:function(e,t){if(!w.support.radioValue&&t==="radio"&&w.nodeName(e,"input")){var n=e.value;e.setAttribute("type",t);if(n){e.value=n}return t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,s,o,u=e.nodeType;if(!e||u===3||u===8||u===2){return}o=u!==1||!w.isXMLDoc(e);if(o){n=w.propFix[n]||n;s=w.propHooks[n]}if(r!==t){return s&&"set"in s&&(i=s.set(e,r,n))!==t?i:e[n]=r}else{return s&&"get"in s&&(i=s.get(e,n))!==null?i:e[n]}},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):J.test(e.nodeName)||K.test(e.nodeName)&&e.href?0:-1}}}});X={set:function(e,t,n){if(t===false){w.removeAttr(e,n)}else if(Y&&G||!Q.test(n)){e.setAttribute(!G&&w.propFix[n]||n,n)}else{e[w.camelCase("default-"+n)]=e[n]=true}return n}};w.each(w.expr.match.bool.source.match(/\w+/g),function(e,n){var r=w.expr.attrHandle[n]||w.find.attr;w.expr.attrHandle[n]=Y&&G||!Q.test(n)?function(e,n,i){var s=w.expr.attrHandle[n],o=i?t:(w.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;w.expr.attrHandle[n]=s;return o}:function(e,n,r){return r?t:e[w.camelCase("default-"+n)]?n.toLowerCase():null}});if(!Y||!G){w.attrHooks.value={set:function(e,t,n){if(w.nodeName(e,"input")){e.defaultValue=t}else{return W&&W.set(e,t,n)}}}}if(!G){W={set:function(e,n,r){var i=e.getAttributeNode(r);if(!i){e.setAttributeNode(i=e.ownerDocument.createAttribute(r))}i.value=n+="";return r==="value"||n===e.getAttribute(r)?n:t}};w.expr.attrHandle.id=w.expr.attrHandle.name=w.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.value!==""?i.value:null};w.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:W.set};w.attrHooks.contenteditable={set:function(e,t,n){W.set(e,t===""?false:t,n)}};w.each(["width","height"],function(e,t){w.attrHooks[t]={set:function(e,n){if(n===""){e.setAttribute(t,"auto");return n}}}})}if(!w.support.hrefNormalized){w.each(["href","src"],function(e,t){w.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})}if(!w.support.style){w.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}}if(!w.support.optSelected){w.propHooks.selected={get:function(e){var t=e.parentNode;if(t){t.selectedIndex;if(t.parentNode){t.parentNode.selectedIndex}}return null}}}w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});if(!w.support.enctype){w.propFix.enctype="encoding"}w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(w.isArray(t)){return e.checked=w.inArray(w(e).val(),t)>=0}}};if(!w.support.checkOn){w.valHooks[this].get=function(e){return e.getAttribute("value")===null?"on":e.value}}});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;w.event={global:{},add:function(e,n,r,s,o){var u,a,f,l,c,h,p,d,v,m,g,y=w._data(e);if(!y){return}if(r.handler){l=r;r=l.handler;o=l.selector}if(!r.guid){r.guid=w.guid++}if(!(a=y.events)){a=y.events={}}if(!(h=y.handle)){h=y.handle=function(e){return typeof w!==i&&(!e||w.event.triggered!==e.type)?w.event.dispatch.apply(h.elem,arguments):t};h.elem=e}n=(n||"").match(S)||[""];f=n.length;while(f--){u=rt.exec(n[f])||[];v=g=u[1];m=(u[2]||"").split(".").sort();if(!v){continue}c=w.event.special[v]||{};v=(o?c.delegateType:c.bindType)||v;c=w.event.special[v]||{};p=w.extend({type:v,origType:g,data:s,handler:r,guid:r.guid,selector:o,needsContext:o&&w.expr.match.needsContext.test(o),namespace:m.join(".")},l);if(!(d=a[v])){d=a[v]=[];d.delegateCount=0;if(!c.setup||c.setup.call(e,s,m,h)===false){if(e.addEventListener){e.addEventListener(v,h,false)}else if(e.attachEvent){e.attachEvent("on"+v,h)}}}if(c.add){c.add.call(e,p);if(!p.handler.guid){p.handler.guid=r.guid}}if(o){d.splice(d.delegateCount++,0,p)}else{d.push(p)}w.event.global[v]=true}e=null},remove:function(e,t,n,r,i){var s,o,u,a,f,l,c,h,p,d,v,m=w.hasData(e)&&w._data(e);if(!m||!(l=m.events)){return}t=(t||"").match(S)||[""];f=t.length;while(f--){u=rt.exec(t[f])||[];p=v=u[1];d=(u[2]||"").split(".").sort();if(!p){for(p in l){w.event.remove(e,p+t[f],n,r,true)}continue}c=w.event.special[p]||{};p=(r?c.delegateType:c.bindType)||p;h=l[p]||[];u=u[2]&&new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)");a=s=h.length;while(s--){o=h[s];if((i||v===o.origType)&&(!n||n.guid===o.guid)&&(!u||u.test(o.namespace))&&(!r||r===o.selector||r==="**"&&o.selector)){h.splice(s,1);if(o.selector){h.delegateCount--}if(c.remove){c.remove.call(e,o)}}}if(a&&!h.length){if(!c.teardown||c.teardown.call(e,d,m.handle)===false){w.removeEvent(e,p,m.handle)}delete l[p]}}if(w.isEmptyObject(l)){delete m.handle;w._removeData(e,"events")}},trigger:function(n,r,i,s){var u,a,f,l,c,h,p,d=[i||o],v=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.namespace.split("."):[];f=h=i=i||o;if(i.nodeType===3||i.nodeType===8){return}if(nt.test(v+w.event.triggered)){return}if(v.indexOf(".")>=0){m=v.split(".");v=m.shift();m.sort()}a=v.indexOf(":")<0&&"on"+v;n=n[w.expando]?n:new w.Event(v,typeof n==="object"&&n);n.isTrigger=s?2:3;n.namespace=m.join(".");n.namespace_re=n.namespace?new RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null;n.result=t;if(!n.target){n.target=i}r=r==null?[n]:w.makeArray(r,[n]);c=w.event.special[v]||{};if(!s&&c.trigger&&c.trigger.apply(i,r)===false){return}if(!s&&!c.noBubble&&!w.isWindow(i)){l=c.delegateType||v;if(!nt.test(l+v)){f=f.parentNode}for(;f;f=f.parentNode){d.push(f);h=f}if(h===(i.ownerDocument||o)){d.push(h.defaultView||h.parentWindow||e)}}p=0;while((f=d[p++])&&!n.isPropagationStopped()){n.type=p>1?l:c.bindType||v;u=(w._data(f,"events")||{})[n.type]&&w._data(f,"handle");if(u){u.apply(f,r)}u=a&&f[a];if(u&&w.acceptData(f)&&u.apply&&u.apply(f,r)===false){n.preventDefault()}}n.type=v;if(!s&&!n.isDefaultPrevented()){if((!c._default||c._default.apply(d.pop(),r)===false)&&w.acceptData(i)){if(a&&i[v]&&!w.isWindow(i)){h=i[a];if(h){i[a]=null}w.event.triggered=v;try{i[v]()}catch(g){}w.event.triggered=t;if(h){i[a]=h}}}}return n.result},dispatch:function(e){e=w.event.fix(e);var n,r,i,s,o,u=[],a=v.call(arguments),f=(w._data(this,"events")||{})[e.type]||[],l=w.event.special[e.type]||{};a[0]=e;e.delegateTarget=this;if(l.preDispatch&&l.preDispatch.call(this,e)===false){return}u=w.event.handlers.call(this,e,f);n=0;while((s=u[n++])&&!e.isPropagationStopped()){e.currentTarget=s.elem;o=0;while((i=s.handlers[o++])&&!e.isImmediatePropagationStopped()){if(!e.namespace_re||e.namespace_re.test(i.namespace)){e.handleObj=i;e.data=i.data;r=((w.event.special[i.origType]||{}).handle||i.handler).apply(s.elem,a);if(r!==t){if((e.result=r)===false){e.preventDefault();e.stopPropagation()}}}}}if(l.postDispatch){l.postDispatch.call(this,e)}return e.result},handlers:function(e,n){var r,i,s,o,u=[],a=n.delegateCount,f=e.target;if(a&&f.nodeType&&(!e.button||e.type!=="click")){for(;f!=this;f=f.parentNode||this){if(f.nodeType===1&&(f.disabled!==true||e.type!=="click")){s=[];for(o=0;o=0:w.find(r,this,null,[f]).length}if(s[r]){s.push(i)}}if(s.length){u.push({elem:f,handlers:s})}}}}if(a1?w.unique(n):n);n.selector=this.selector?this.selector+" "+e:e;return n},has:function(e){var t,n=w(e,this),r=n.length;return this.filter(function(){for(t=0;t-1:n.nodeType===1&&w.find.matchesSelector(n,e))){n=s.push(n);break}}}return this.pushStack(s.length>1?w.unique(s):s)},index:function(e){if(!e){return this[0]&&this[0].parentNode?this.first().prevAll().length:-1}if(typeof e==="string"){return w.inArray(this[0],w(e))}return w.inArray(e.jquery?e[0]:e,this)},add:function(e,t){var n=typeof e==="string"?w(e,t):w.makeArray(e&&e.nodeType?[e]:e),r=w.merge(this.get(),n);return this.pushStack(w.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}});w.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return w.dir(e,"parentNode")},parentsUntil:function(e,t,n){return w.dir(e,"parentNode",n)},next:function(e){return ct(e,"nextSibling")},prev:function(e){return ct(e,"previousSibling")},nextAll:function(e){return w.dir(e,"nextSibling")},prevAll:function(e){return w.dir(e,"previousSibling")},nextUntil:function(e,t,n){return w.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return w.dir(e,"previousSibling",n)},siblings:function(e){return w.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return w.sibling(e.firstChild)},contents:function(e){return w.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:w.merge([],e.childNodes)}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);if(e.slice(-5)!=="Until"){r=n}if(r&&typeof r==="string"){i=w.filter(r,i)}if(this.length>1){if(!lt[e]){i=w.unique(i)}if(at.test(e)){i=i.reverse()}}return this.pushStack(i)}});w.extend({filter:function(e,t,n){var r=t[0];if(n){e=":not("+e+")"}return t.length===1&&r.nodeType===1?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return e.nodeType===1}))},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!w(s).is(r))){if(s.nodeType===1){i.push(s)}s=s[n]}return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling){if(e.nodeType===1&&e!==t){n.push(e)}}return n}});var dt="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|"+"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",vt=/ jQuery\d+="(?:null|\d+)"/g,mt=new RegExp("<(?:"+dt+")[\\s/>]","i"),gt=/^\s+/,yt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,wt=/\s*$/g,Lt={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:w.support.htmlSerialize?[0,"",""]:[1,"X
","
"]},At=pt(o),Ot=At.appendChild(o.createElement("div"));Lt.optgroup=Lt.option;Lt.tbody=Lt.tfoot=Lt.colgroup=Lt.caption=Lt.thead;Lt.th=Lt.td;w.fn.extend({text:function(e){return w.access(this,function(e){return e===t?w.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){var t=Mt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){var t=Mt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){if(this.parentNode){this.parentNode.insertBefore(e,this)}})},after:function(){return this.domManip(arguments,function(e){if(this.parentNode){this.parentNode.insertBefore(e,this.nextSibling)}})},remove:function(e,t){var n,r=e?w.filter(e,this):this,i=0;for(;(n=r[i])!=null;i++){if(!t&&n.nodeType===1){w.cleanData(jt(n))}if(n.parentNode){if(t&&w.contains(n.ownerDocument,n)){Pt(jt(n,"script"))}n.parentNode.removeChild(n)}}return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){if(e.nodeType===1){w.cleanData(jt(e,false))}while(e.firstChild){e.removeChild(e.firstChild)}if(e.options&&w.nodeName(e,"select")){e.options.length=0}}return this},clone:function(e,t){e=e==null?false:e;t=t==null?e:t;return this.map(function(){return w.clone(this,e,t)})},html:function(e){return w.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t){return n.nodeType===1?n.innerHTML.replace(vt,""):t}if(typeof e==="string"&&!St.test(e)&&(w.support.htmlSerialize||!mt.test(e))&&(w.support.leadingWhitespace||!gt.test(e))&&!Lt[(bt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(yt,"<$1>");try{for(;r")){s=e.cloneNode(true)}else{Ot.innerHTML=e.outerHTML;Ot.removeChild(s=Ot.firstChild)}if((!w.support.noCloneEvent||!w.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!w.isXMLDoc(e)){r=jt(s);u=jt(e);for(o=0;(i=u[o])!=null;++o){if(r[o]){Bt(i,r[o])}}}if(t){if(n){u=u||jt(e);r=r||jt(s);for(o=0;(i=u[o])!=null;o++){Ht(i,r[o])}}else{Ht(e,s)}}r=jt(s,"script");if(r.length>0){Pt(r,!a&&jt(e,"script"))}r=u=i=null;return s},buildFragment:function(e,t,n,r){var i,s,o,u,a,f,l,c=e.length,h=pt(t),p=[],d=0;for(;d")+l[2];i=l[0];while(i--){u=u.lastChild}if(!w.support.leadingWhitespace&>.test(s)){p.push(t.createTextNode(gt.exec(s)[0]))}if(!w.support.tbody){s=a==="table"&&!wt.test(s)?u.firstChild:l[1]===""&&!wt.test(s)?u:0;i=s&&s.childNodes.length;while(i--){if(w.nodeName(f=s.childNodes[i],"tbody")&&!f.childNodes.length){s.removeChild(f)}}}w.merge(p,u.childNodes);u.textContent="";while(u.firstChild){u.removeChild(u.firstChild)}u=h.lastChild}}}if(u){h.removeChild(u)}if(!w.support.appendChecked){w.grep(jt(p,"input"),Ft)}d=0;while(s=p[d++]){if(r&&w.inArray(s,r)!==-1){continue}o=w.contains(s.ownerDocument,s);u=jt(h.appendChild(s),"script");if(o){Pt(u)}if(n){i=0;while(s=u[i++]){if(Nt.test(s.type||"")){n.push(s)}}}}u=null;return h},cleanData:function(e,t){var n,r,s,o,u=0,a=w.expando,f=w.cache,l=w.support.deleteExpando,h=w.event.special;for(;(n=e[u])!=null;u++){if(t||w.acceptData(n)){s=n[a];o=s&&f[s];if(o){if(o.events){for(r in o.events){if(h[r]){w.event.remove(n,r)}else{w.removeEvent(n,r,o.handle)}}}if(f[s]){delete f[s];if(l){delete n[a]}else if(typeof n.removeAttribute!==i){n.removeAttribute(a)}else{n[a]=null}c.push(s)}}}}},_evalUrl:function(e){return w.ajax({url:e,type:"GET",dataType:"script",async:false,global:false,"throws":true})}});w.fn.extend({wrapAll:function(e){if(w.isFunction(e)){return this.each(function(t){w(this).wrapAll(e.call(this,t))})}if(this[0]){var t=w(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){t.insertBefore(this[0])}t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1){e=e.firstChild}return e}).append(this)}return this},wrapInner:function(e){if(w.isFunction(e)){return this.each(function(t){w(this).wrapInner(e.call(this,t))})}return this.each(function(){var t=w(this),n=t.contents();if(n.length){n.wrapAll(e)}else{t.append(e)}})},wrap:function(e){var t=w.isFunction(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){if(!w.nodeName(this,"body")){w(this).replaceWith(this.childNodes)}}).end()}});var It,qt,Rt,Ut=/alpha\([^)]*\)/i,zt=/opacity\s*=\s*([^)]*)/,Wt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Vt=/^margin/,$t=new RegExp("^("+E+")(.*)$","i"),Jt=new RegExp("^("+E+")(?!px)[a-z%]+$","i"),Kt=new RegExp("^([+-])=("+E+")","i"),Qt={BODY:"block"},Gt={position:"absolute",visibility:"hidden",display:"block"},Yt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];w.fn.extend({css:function(e,n){return w.access(this,function(e,n,r){var i,s,o={},u=0;if(w.isArray(n)){s=qt(e);i=n.length;for(;u1)},show:function(){return rn(this,true)},hide:function(){return rn(this)},toggle:function(e){if(typeof e==="boolean"){return e?this.show():this.hide()}return this.each(function(){if(nn(this)){w(this).show()}else{w(this).hide()}})}});w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Rt(e,"opacity");return n===""?"1":n}}}},cssNumber:{columnCount:true,fillOpacity:true,fontWeight:true,lineHeight:true,opacity:true,order:true,orphans:true,widows:true,zIndex:true,zoom:true},cssProps:{"float":w.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style){return}var s,o,u,a=w.camelCase(n),f=e.style;n=w.cssProps[a]||(w.cssProps[a]=tn(f,a));u=w.cssHooks[n]||w.cssHooks[a];if(r!==t){o=typeof r;if(o==="string"&&(s=Kt.exec(r))){r=(s[1]+1)*s[2]+parseFloat(w.css(e,n));o="number"}if(r==null||o==="number"&&isNaN(r)){return}if(o==="number"&&!w.cssNumber[a]){r+="px"}if(!w.support.clearCloneStyle&&r===""&&n.indexOf("background")===0){f[n]="inherit"}if(!u||!("set"in u)||(r=u.set(e,r,i))!==t){try{f[n]=r}catch(l){}}}else{if(u&&"get"in u&&(s=u.get(e,false,i))!==t){return s}return f[n]}},css:function(e,n,r,i){var s,o,u,a=w.camelCase(n);n=w.cssProps[a]||(w.cssProps[a]=tn(e.style,a));u=w.cssHooks[n]||w.cssHooks[a];if(u&&"get"in u){o=u.get(e,true,r)}if(o===t){o=Rt(e,n,i)}if(o==="normal"&&n in Yt){o=Yt[n]}if(r===""||r){s=parseFloat(o);return r===true||w.isNumeric(s)?s||0:o}return o}});if(e.getComputedStyle){qt=function(t){return e.getComputedStyle(t,null)};Rt=function(e,n,r){var i,s,o,u=r||qt(e),a=u?u.getPropertyValue(n)||u[n]:t,f=e.style;if(u){if(a===""&&!w.contains(e.ownerDocument,e)){a=w.style(e,n)}if(Jt.test(a)&&Vt.test(n)){i=f.width;s=f.minWidth;o=f.maxWidth;f.minWidth=f.maxWidth=f.width=a;a=u.width;f.width=i;f.minWidth=s;f.maxWidth=o}}return a}}else if(o.documentElement.currentStyle){qt=function(e){return e.currentStyle};Rt=function(e,n,r){var i,s,o,u=r||qt(e),a=u?u[n]:t,f=e.style;if(a==null&&f&&f[n]){a=f[n]}if(Jt.test(a)&&!Wt.test(n)){i=f.left;s=e.runtimeStyle;o=s&&s.left;if(o){s.left=e.currentStyle.left}f.left=n==="fontSize"?"1em":a;a=f.pixelLeft+"px";f.left=i;if(o){s.left=o}}return a===""?"auto":a}}w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n){return e.offsetWidth===0&&Xt.test(w.css(e,"display"))?w.swap(e,Gt,function(){return un(e,t,r)}):un(e,t,r)}},set:function(e,n,r){var i=r&&qt(e);return sn(e,n,r?on(e,t,r,w.support.boxSizing&&w.css(e,"boxSizing",false,i)==="border-box",i):0)}}});if(!w.support.opacity){w.cssHooks.opacity={get:function(e,t){return zt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=w.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if((t>=1||t==="")&&w.trim(s.replace(Ut,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(t===""||r&&!r.filter){return}}n.filter=Ut.test(s)?s.replace(Ut,i):s+" "+i}}}w(function(){if(!w.support.reliableMarginRight){w.cssHooks.marginRight={get:function(e,t){if(t){return w.swap(e,{display:"inline-block"},Rt,[e,"marginRight"])}}}}if(!w.support.pixelPosition&&w.fn.position){w.each(["top","left"],function(e,t){w.cssHooks[t]={get:function(e,n){if(n){n=Rt(e,t);return Jt.test(n)?w(e).position()[t]+"px":n}}}})}});if(w.expr&&w.expr.filters){w.expr.filters.hidden=function(e){return e.offsetWidth<=0&&e.offsetHeight<=0||!w.support.reliableHiddenOffsets&&(e.style&&e.style.display||w.css(e,"display"))==="none"};w.expr.filters.visible=function(e){return!w.expr.filters.hidden(e)}}w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){var r=0,i={},s=typeof n==="string"?n.split(" "):[n];for(;r<4;r++){i[e+Zt[r]+t]=s[r]||s[r-2]||s[0]}return i}};if(!Vt.test(e)){w.cssHooks[e+t].set=sn}});var ln=/%20/g,cn=/\[\]$/,hn=/\r?\n/g,pn=/^(?:submit|button|image|reset|file)$/i,dn=/^(?:input|select|textarea|keygen)/i;w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&dn.test(this.nodeName)&&!pn.test(e)&&(this.checked||!xt.test(e))}).map(function(e,t){var n=w(this).val();return n==null?null:w.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(hn,"\r\n")}}):{name:t.name,value:n.replace(hn,"\r\n")}}).get()}});w.param=function(e,n){var r,i=[],s=function(e,t){t=w.isFunction(t)?t():t==null?"":t;i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t){n=w.ajaxSettings&&w.ajaxSettings.traditional}if(w.isArray(e)||e.jquery&&!w.isPlainObject(e)){w.each(e,function(){s(this.name,this.value)})}else{for(r in e){vn(r,e[r],n,s)}}return i.join("&").replace(ln,"+")};w.each(("blur focus focusin focusout load resize scroll unload click dblclick "+"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave "+"change select submit keydown keypress keyup error contextmenu").split(" "),function(e,t){w.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}});w.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return arguments.length===1?this.off(e,"**"):this.off(t,e||"**",n)}});var mn,gn,yn=w.now(),bn=/\?/,wn=/#.*$/,En=/([?&])_=[^&]*/,Sn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,xn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Tn=/^(?:GET|HEAD)$/,Nn=/^\/\//,Cn=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,kn=w.fn.load,Ln={},An={},On="*/".concat("*");try{gn=s.href}catch(Mn){gn=o.createElement("a");gn.href="";gn=gn.href}mn=Cn.exec(gn.toLowerCase())||[];w.fn.load=function(e,n,r){if(typeof e!=="string"&&kn){return kn.apply(this,arguments)}var i,s,o,u=this,a=e.indexOf(" ");if(a>=0){i=e.slice(a,e.length);e=e.slice(0,a)}if(w.isFunction(n)){r=n;n=t}else if(n&&typeof n==="object"){o="POST"}if(u.length>0){w.ajax({url:e,type:o,dataType:"html",data:n}).done(function(e){s=arguments;u.html(i?w("
").append(w.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){u.each(r,s||[e.responseText,t,e])})}return this};w.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){w.fn[t]=function(e){return this.on(t,e)}});w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:gn,type:"GET",isLocal:xn.test(mn[1]),global:true,processData:true,async:true,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":On,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":true,"text json":w.parseJSON,"text xml":w.parseXML},flatOptions:{url:true,context:true}},ajaxSetup:function(e,t){return t?Pn(Pn(e,w.ajaxSettings),t):Pn(w.ajaxSettings,e)},ajaxPrefilter:_n(Ln),ajaxTransport:_n(An),ajax:function(e,n){function N(e,n,r,i){var l,g,y,E,S,T=n;if(b===2){return}b=2;if(u){clearTimeout(u)}f=t;o=i||"";x.readyState=e>0?4:0;l=e>=200&&e<300||e===304;if(r){E=Hn(c,x,r)}E=Bn(c,E,x,l);if(l){if(c.ifModified){S=x.getResponseHeader("Last-Modified");if(S){w.lastModified[s]=S}S=x.getResponseHeader("etag");if(S){w.etag[s]=S}}if(e===204||c.type==="HEAD"){T="nocontent"}else if(e===304){T="notmodified"}else{T=E.state;g=E.data;y=E.error;l=!y}}else{y=T;if(e||!T){T="error";if(e<0){e=0}}}x.status=e;x.statusText=(n||T)+"";if(l){d.resolveWith(h,[g,T,x])}else{d.rejectWith(h,[x,T,y])}x.statusCode(m);m=t;if(a){p.trigger(l?"ajaxSuccess":"ajaxError",[x,c,l?g:y])}v.fireWith(h,[x,T]);if(a){p.trigger("ajaxComplete",[x,c]);if(!--w.active){w.event.trigger("ajaxStop")}}}if(typeof e==="object"){n=e;e=t}n=n||{};var r,i,s,o,u,a,f,l,c=w.ajaxSetup({},n),h=c.context||c,p=c.context&&(h.nodeType||h.jquery)?w(h):w.event,d=w.Deferred(),v=w.Callbacks("once memory"),m=c.statusCode||{},g={},y={},b=0,E="canceled",x={readyState:0,getResponseHeader:function(e){var t;if(b===2){if(!l){l={};while(t=Sn.exec(o)){l[t[1].toLowerCase()]=t[2]}}t=l[e.toLowerCase()]}return t==null?null:t},getAllResponseHeaders:function(){return b===2?o:null},setRequestHeader:function(e,t){var n=e.toLowerCase();if(!b){e=y[n]=y[n]||e;g[e]=t}return this},overrideMimeType:function(e){if(!b){c.mimeType=e}return this},statusCode:function(e){var t;if(e){if(b<2){for(t in e){m[t]=[m[t],e[t]]}}else{x.always(e[x.status])}}return this},abort:function(e){var t=e||E;if(f){f.abort(t)}N(0,t);return this}};d.promise(x).complete=v.add;x.success=x.done;x.error=x.fail;c.url=((e||c.url||gn)+"").replace(wn,"").replace(Nn,mn[1]+"//");c.type=n.method||n.type||c.method||c.type;c.dataTypes=w.trim(c.dataType||"*").toLowerCase().match(S)||[""];if(c.crossDomain==null){r=Cn.exec(c.url.toLowerCase());c.crossDomain=!!(r&&(r[1]!==mn[1]||r[2]!==mn[2]||(r[3]||(r[1]==="http:"?"80":"443"))!==(mn[3]||(mn[1]==="http:"?"80":"443"))))}if(c.data&&c.processData&&typeof c.data!=="string"){c.data=w.param(c.data,c.traditional)}Dn(Ln,c,n,x);if(b===2){return x}a=c.global;if(a&&w.active++===0){w.event.trigger("ajaxStart")}c.type=c.type.toUpperCase();c.hasContent=!Tn.test(c.type);s=c.url;if(!c.hasContent){if(c.data){s=c.url+=(bn.test(s)?"&":"?")+c.data;delete c.data}if(c.cache===false){c.url=En.test(s)?s.replace(En,"$1_="+yn++):s+(bn.test(s)?"&":"?")+"_="+yn++}}if(c.ifModified){if(w.lastModified[s]){x.setRequestHeader("If-Modified-Since",w.lastModified[s])}if(w.etag[s]){x.setRequestHeader("If-None-Match",w.etag[s])}}if(c.data&&c.hasContent&&c.contentType!==false||n.contentType){x.setRequestHeader("Content-Type",c.contentType)}x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+On+"; q=0.01":""):c.accepts["*"]);for(i in c.headers){x.setRequestHeader(i,c.headers[i])}if(c.beforeSend&&(c.beforeSend.call(h,x,c)===false||b===2)){return x.abort()}E="abort";for(i in{success:1,error:1,complete:1}){x[i](c[i])}f=Dn(An,c,n,x);if(!f){N(-1,"No Transport")}else{x.readyState=1;if(a){p.trigger("ajaxSend",[x,c])}if(c.async&&c.timeout>0){u=setTimeout(function(){x.abort("timeout")},c.timeout)}try{b=1;f.send(g,N)}catch(T){if(b<2){N(-1,T)}else{throw T}}}return x},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,n){return w.get(e,t,n,"script")}});w.each(["get","post"],function(e,n){w[n]=function(e,r,i,s){if(w.isFunction(r)){s=s||i;i=r;r=t}return w.ajax({url:e,type:n,dataType:s,data:r,success:i})}});w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){w.globalEval(e);return e}}});w.ajaxPrefilter("script",function(e){if(e.cache===t){e.cache=false}if(e.crossDomain){e.type="GET";e.global=false}});w.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=o.head||w("head")[0]||o.documentElement;return{send:function(t,i){n=o.createElement("script");n.async=true;if(e.scriptCharset){n.charset=e.scriptCharset}n.src=e.url;n.onload=n.onreadystatechange=function(e,t){if(t||!n.readyState||/loaded|complete/.test(n.readyState)){n.onload=n.onreadystatechange=null;if(n.parentNode){n.parentNode.removeChild(n)}n=null;if(!t){i(200,"success")}}};r.insertBefore(n,r.firstChild)},abort:function(){if(n){n.onload(t,true)}}}}});var jn=[],Fn=/(=)\?(?=&|$)|\?\?/;w.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=jn.pop()||w.expando+"_"+yn++;this[e]=true;return e}});w.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.jsonp!==false&&(Fn.test(n.url)?"url":typeof n.data==="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Fn.test(n.data)&&"data");if(a||n.dataTypes[0]==="jsonp"){s=n.jsonpCallback=w.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback;if(a){n[a]=n[a].replace(Fn,"$1"+s)}else if(n.jsonp!==false){n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+s}n.converters["script json"]=function(){if(!u){w.error(s+" was not called")}return u[0]};n.dataTypes[0]="json";o=e[s];e[s]=function(){u=arguments};i.always(function(){e[s]=o;if(n[s]){n.jsonpCallback=r.jsonpCallback;jn.push(s)}if(u&&w.isFunction(o)){o(u[0])}u=o=t});return"script"}});var In,qn,Rn=0,Un=e.ActiveXObject&&function(){var e;for(e in In){In[e](t,true)}};w.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&zn()||Wn()}:zn;qn=w.ajaxSettings.xhr();w.support.cors=!!qn&&"withCredentials"in qn;qn=w.support.ajax=!!qn;if(qn){w.ajaxTransport(function(n){if(!n.crossDomain||w.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();if(n.username){a.open(n.type,n.url,n.async,n.username,n.password)}else{a.open(n.type,n.url,n.async)}if(n.xhrFields){for(u in n.xhrFields){a[u]=n.xhrFields[u]}}if(n.mimeType&&a.overrideMimeType){a.overrideMimeType(n.mimeType)}if(!n.crossDomain&&!i["X-Requested-With"]){i["X-Requested-With"]="XMLHttpRequest"}try{for(u in i){a.setRequestHeader(u,i[u])}}catch(f){}a.send(n.hasContent&&n.data||null);r=function(e,i){var u,f,l,c;try{if(r&&(i||a.readyState===4)){r=t;if(o){a.onreadystatechange=w.noop;if(Un){delete In[o]}}if(i){if(a.readyState!==4){a.abort()}}else{c={};u=a.status;f=a.getAllResponseHeaders();if(typeof a.responseText==="string"){c.text=a.responseText}try{l=a.statusText}catch(h){l=""}if(!u&&n.isLocal&&!n.crossDomain){u=c.text?200:404}else if(u===1223){u=204}}}}catch(p){if(!i){s(-1,p)}}if(c){s(u,l,c,f)}};if(!n.async){r()}else if(a.readyState===4){setTimeout(r)}else{o=++Rn;if(Un){if(!In){In={};w(e).unload(Un)}In[o]=r}a.onreadystatechange=r}},abort:function(){if(r){r(t,true)}}}}})}var Xn,Vn,$n=/^(?:toggle|show|hide)$/,Jn=new RegExp("^(?:([+-])=|)("+E+")([a-z%]*)$","i"),Kn=/queueHooks$/,Qn=[nr],Gn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Jn.exec(t),s=i&&i[3]||(w.cssNumber[e]?"":"px"),o=(w.cssNumber[e]||s!=="px"&&+r)&&Jn.exec(w.css(n.elem,e)),u=1,a=20;if(o&&o[3]!==s){s=s||o[3];i=i||[];o=+r||1;do{u=u||".5";o=o/u;w.style(n.elem,e,o+s)}while(u!==(u=n.cur()/r)&&u!==1&&--a)}if(i){o=n.start=+o||+r||0;n.unit=s;n.end=i[1]?o+(i[1]+1)*i[2]:+i[2]}return n}]};w.Animation=w.extend(er,{tweener:function(e,t){if(w.isFunction(e)){t=e;e=["*"]}else{e=e.split(" ")}var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;if(a){l=i.position();c=l.top;h=l.left}else{c=parseFloat(o)||0;h=parseFloat(u)||0}if(w.isFunction(t)){t=t.call(e,n,s)}if(t.top!=null){f.top=t.top-s.top+c}if(t.left!=null){f.left=t.left-s.left+h}if("using"in t){t.using.call(e,f)}else{i.css(f)}}};w.fn.extend({position:function(){if(!this[0]){return}var e,t,n={top:0,left:0},r=this[0];if(w.css(r,"position")==="fixed"){t=r.getBoundingClientRect()}else{e=this.offsetParent();t=this.offset();if(!w.nodeName(e[0],"html")){n=e.offset()}n.top+=w.css(e[0],"borderTopWidth",true);n.left+=w.css(e[0],"borderLeftWidth",true)}return{top:t.top-n.top-w.css(r,"marginTop",true),left:t.left-n.left-w.css(r,"marginLeft",true)}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||u;while(e&&!w.nodeName(e,"html")&&w.css(e,"position")==="static"){e=e.offsetParent}return e||u})}});w.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);w.fn[e]=function(i){return w.access(this,function(e,i,s){var o=sr(e);if(s===t){return o?n in o?o[n]:o.document.documentElement[i]:e[i]}if(o){o.scrollTo(!r?s:w(o).scrollLeft(),r?s:w(o).scrollTop())}else{e[i]=s}},e,i,arguments.length,null)}});w.each({Height:"height",Width:"width"},function(e,n){w.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){w.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!=="boolean"),u=r||(i===true||s===true?"margin":"border");return w.access(this,function(n,r,i){var s;if(w.isWindow(n)){return n.document.documentElement["client"+e]}if(n.nodeType===9){s=n.documentElement;return Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])}return i===t?w.css(n,r,u):w.style(n,r,i,u)},n,o?i:t,o,null)}})});w.fn.size=function(){return this.length};w.fn.andSelf=w.fn.addBack;if(typeof module==="object"&&module&&typeof module.exports==="object"){module.exports=w}else{e.jQuery=e.$=w;if(typeof define==="function"&&define.amd){define("jquery",[],function(){return w})}}})(window);jQuery.fn.extend({everyTime:function(e,t,n,r){return this.each(function(){jQuery.timer.add(this,e,t,n,r)})},oneTime:function(e,t,n){return this.each(function(){jQuery.timer.add(this,e,t,n,1)})},stopTime:function(e,t){return this.each(function(){jQuery.timer.remove(this,e,t)})}});jQuery.extend({timer:{global:[],guid:1,dataKey:"jQuery.timer",regex:/^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,powers:{ms:1,cs:10,ds:100,s:1e3,das:1e4,hs:1e5,ks:1e6},timeParse:function(e){if(e==undefined||e==null)return null;var t=this.regex.exec(jQuery.trim(e.toString()));return t[2]?parseFloat(t[1])*(this.powers[t[2]]||1):e},add:function(e,t,n,r,i){var s=0;if(jQuery.isFunction(n)){i||(i=r);r=n;n=t}t=jQuery.timer.timeParse(t);if(!(typeof t!="number"||isNaN(t)||t<0)){if(typeof i!="number"||isNaN(i)||i<0)i=0;i=i||0;var o=jQuery.data(e,this.dataKey)||jQuery.data(e,this.dataKey,{});o[n]||(o[n]={});r.timerID=r.timerID||this.guid++;var u=function(){if(++s>i&&i!==0||r.call(e,s)===false)jQuery.timer.remove(e,n,r)};u.timerID=r.timerID;o[n][r.timerID]||(o[n][r.timerID]=window.setInterval(u,t));this.global.push(e)}},remove:function(e,t,n){var r=jQuery.data(e,this.dataKey),i;if(r){if(t){if(r[t]){if(n){if(n.timerID){window.clearInterval(r[t][n.timerID]);delete r[t][n.timerID]}}else for(n in r[t]){window.clearInterval(r[t][n]);delete r[t][n]}for(i in r[t])break;if(!i){i=null;delete r[t]}}}else for(t in r)this.remove(e,t,n);for(i in r)break;i||jQuery.removeData(e,this.dataKey)}}}});jQuery(window).bind("unload",function(){jQuery.each(jQuery.timer.global,function(e,t){jQuery.timer.remove(t)})});(function(){"use strict";function encodeHTMLSource(){var e={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},t=/&(?!#?\w+;)|<|>|"|'|\//g;return function(){return this?this.replace(t,function(t){return e[t]||t}):this}}function resolveDefs(e,t,n){return(typeof t==="string"?t:t.toString()).replace(e.define||skip,function(t,r,i,s){if(r.indexOf("def.")===0){r=r.substring(4)}if(!(r in n)){if(i===":"){if(e.defineParams)s.replace(e.defineParams,function(e,t,i){n[r]={arg:t,text:i}});if(!(r in n))n[r]=s}else{(new Function("def","def['"+r+"']="+s))(n)}}return""}).replace(e.use||skip,function(t,r){if(e.useParams)r=r.replace(e.useParams,function(e,t,r,i){if(n[r]&&n[r].arg&&i){var s=(r+":"+i).replace(/'|\\/g,"_");n.__exp=n.__exp||{};n.__exp[s]=n[r].text.replace(new RegExp("(^|[^\\w$])"+n[r].arg+"([^\\w$])","g"),"$1"+i+"$2");return t+"def.__exp['"+s+"']"}});var i=(new Function("def","return "+r))(n);return i?resolveDefs(e,i,n):i})}function unescape(e){return e.replace(/\\('|\\)/g,"$1").replace(/[\r\t\n]/g," ")}var doT={version:"1.0.1-nanoui",templateSettings:{evaluate:/\{\{([\s\S]+?)\}\}/g,interpolate:/\{\{:([\s\S]+?)\}\}/g,encode:/\{\{>([\s\S]+?)\}\}/g,use:/\{\{#([\s\S]+?)\}\}/g,define:/\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,conditional:/\{\{\/?if\s*([\s\S]*?)\s*\}\}/g,conditionalElse:/\{\{else\s*([\s\S]*?)\s*\}\}/g,iterate:/\{\{\/?for\s*(?:\}\}|([\s\S]+?)\s*(?:\:\s*([\w$]+))?\s*(?:\:\s*([\w$]+))?\s*\}\})/g,props:/\{\{\/?props\s*(?:\}\}|([\s\S]+?)\s*(?:\:\s*([\w$]+))?\s*(?:\:\s*([\w$]+))?\s*\}\})/g,empty:/\{\{empty\}\}/g,varname:"data, config, helper",strip:true,append:true,selfcontained:false},template:undefined,compile:undefined},global;if(typeof module!=="undefined"&&module.exports){module.exports=doT}else if(typeof define==="function"&&define.amd){define(function(){return doT})}else{global=function(){return this||(0,eval)("this")}();global.doT=doT}String.prototype.encodeHTML=encodeHTMLSource();var startend={append:{start:"'+(",end:")+'",endencode:"||'').toString().encodeHTML()+'"},split:{start:"';out+=(",end:");out+='",endencode:"||'').toString().encodeHTML();out+='"}},skip=/$^/;doT.template=function(e,t,n){t=t||doT.templateSettings;var r=t.append?startend.append:startend.split,i,s=0,o=t.use||t.define?resolveDefs(t,e,n||{}):e;o=("var out='"+(t.strip?o.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):o).replace(/'|\\/g,"\\$&").replace(t.interpolate||skip,function(e,t){return r.start+unescape(t)+r.end}).replace(t.encode||skip,function(e,t){i=true;return r.start+unescape(t)+r.endencode}).replace(t.conditional||skip,function(e,t){return t?"';if("+unescape(t)+"){out+='":"';}out+='"}).replace(t.conditionalElse||skip,function(e,t){return t?"';}else if("+unescape(t)+"){out+='":"';}else{out+='"}).replace(t.iterate||skip,function(e,t,n,r){if(!t)return"';} } out+='";s+=1;n=n||"value";r=r||"index";t=unescape(t);var i="arr"+s;return"';var "+i+"="+t+";if("+i+" && "+i+".length > 0){var "+n+","+r+"=-1,l"+s+"="+i+".length-1;while("+r+" 0){var "+n+";for( var "+r+" in "+i+"){ if (!"+i+".hasOwnProperty("+r+")) continue; "+n+"="+i+"["+r+"];out+='"}).replace(t.empty||skip,function(e){return"';}}else{if(true){out+='"}).replace(t.evaluate||skip,function(e,t){return"';"+unescape(t)+"out+='"})+"';return out;").replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/\r/g,"\\r").replace(/(\s|;|\}|^|\{)out\+='';/g,"$1").replace(/\+''/g,"").replace(/(\s|;|\}|^|\{)out\+=''\+/g,"$1out+=");if(i&&t.selfcontained){o="String.prototype.encodeHTML=("+encodeHTMLSource.toString()+"());"+o}try{return new Function(t.varname,o)}catch(u){if(typeof console!=="undefined")console.log("Could not create a template function: "+o);throw u}};doT.compile=function(e,t){return doT.template(e,null,t)}})();(function(e){if(typeof define==="function"&&define.amd){define(["jquery"],e)}else{e(jQuery)}})(function(e){function t(t,r){var i,s,o,u=t.nodeName.toLowerCase();if("area"===u){i=t.parentNode;s=i.name;if(!t.href||!s||i.nodeName.toLowerCase()!=="map"){return false}o=e("img[usemap=#"+s+"]")[0];return!!o&&n(o)}return(/input|select|textarea|button|object/.test(u)?!t.disabled:"a"===u?t.href||r:r)&&n(t)}function n(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return e.css(this,"visibility")==="hidden"}).length}e.ui=e.ui||{};e.extend(e.ui,{version:"1.11.0",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}});e.fn.extend({scrollParent:function(){var t=this.css("position"),n=t==="absolute",r=this.parents().filter(function(){var t=e(this);if(n&&t.css("position")==="static"){return false}return/(auto|scroll)/.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return t==="fixed"||!r.length?e(this[0].ownerDocument||document):r},uniqueId:function(){var e=0;return function(){return this.each(function(){if(!this.id){this.id="ui-id-"+ ++e}})}}(),removeUniqueId:function(){return this.each(function(){if(/^ui-id-\d+$/.test(this.id)){e(this).removeAttr("id")}})}});e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(n){return!!e.data(n,t)}}):function(t,n,r){return!!e.data(t,r[3])},focusable:function(n){return t(n,!isNaN(e.attr(n,"tabindex")))},tabbable:function(n){var r=e.attr(n,"tabindex"),i=isNaN(r);return(i||r>=0)&&t(n,!i)}});if(!e("").outerWidth(1).jquery){e.each(["Width","Height"],function(t,n){function o(t,n,i,s){e.each(r,function(){n-=parseFloat(e.css(t,"padding"+this))||0;if(i){n-=parseFloat(e.css(t,"border"+this+"Width"))||0}if(s){n-=parseFloat(e.css(t,"margin"+this))||0}});return n}var r=n==="Width"?["Left","Right"]:["Top","Bottom"],i=n.toLowerCase(),s={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+n]=function(t){if(t===undefined){return s["inner"+n].call(this)}return this.each(function(){e(this).css(i,o(this,t)+"px")})};e.fn["outer"+n]=function(t,r){if(typeof t!=="number"){return s["outer"+n].call(this,t)}return this.each(function(){e(this).css(i,o(this,t,true,r)+"px")})}})}if(!e.fn.addBack){e.fn.addBack=function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}if(e("").data("a-b","a").removeData("a-b").data("a-b")){e.fn.removeData=function(t){return function(n){if(arguments.length){return t.call(this,e.camelCase(n))}else{return t.call(this)}}}(e.fn.removeData)}e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());e.fn.extend({focus:function(t){return function(n,r){return typeof n==="number"?this.each(function(){var t=this;setTimeout(function(){e(t).focus();if(r){r.call(t)}},n)}):t.apply(this,arguments)}}(e.fn.focus),disableSelection:function(){var e="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(e+".ui-disableSelection",function(e){e.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(t){if(t!==undefined){return this.css("zIndex",t)}if(this.length){var n=e(this[0]),r,i;while(n.length&&n[0]!==document){r=n.css("position");if(r==="absolute"||r==="relative"||r==="fixed"){i=parseInt(n.css("zIndex"),10);if(!isNaN(i)&&i!==0){return i}}n=n.parent()}}return 0}});e.ui.plugin={add:function(t,n,r){var i,s=e.ui[t].prototype;for(i in r){s.plugins[i]=s.plugins[i]||[];s.plugins[i].push([n,r[i]])}},call:function(e,t,n,r){var i,s=e.plugins[t];if(!s){return}if(!r&&(!e.element[0].parentNode||e.element[0].parentNode.nodeType===11)){return}for(i=0;i",options:{disabled:false,create:null},_createWidget:function(t,n){n=e(n||this.defaultElement||this)[0];this.element=e(n);this.uuid=r++;this.eventNamespace="."+this.widgetName+this.uuid;this.options=e.widget.extend({},this.options,this._getCreateOptions(),t);this.bindings=e();this.hoverable=e();this.focusable=e();if(n!==this){e.data(n,this.widgetFullName,this);this._on(true,this.element,{remove:function(e){if(e.target===n){this.destroy()}}});this.document=e(n.style?n.ownerDocument:n.document||n);this.window=e(this.document[0].defaultView||this.document[0].parentWindow)}this._create();this._trigger("create",null,this._getCreateEventData());this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy();this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName));this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled");this.bindings.unbind(this.eventNamespace);this.hoverable.removeClass("ui-state-hover");this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(t,n){var r=t,i,s,o;if(arguments.length===0){return e.widget.extend({},this.options)}if(typeof t==="string"){r={};i=t.split(".");t=i.shift();if(i.length){s=r[t]=e.widget.extend({},this.options[t]);for(o=0;o=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}});(function(){function h(e,t,n){return[parseFloat(e[0])*(l.test(e[0])?t/100:1),parseFloat(e[1])*(l.test(e[1])?n/100:1)]}function p(t,n){return parseInt(e.css(t,n),10)||0}function d(t){var n=t[0];if(n.nodeType===9){return{width:t.width(),height:t.height(),offset:{top:0,left:0}}}if(e.isWindow(n)){return{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}}if(n.preventDefault){return{width:0,height:0,offset:{top:n.pageY,left:n.pageX}}}return{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()}}e.ui=e.ui||{};var t,n,r=Math.max,i=Math.abs,s=Math.round,o=/left|center|right/,u=/top|center|bottom/,a=/[\+\-]\d+(\.[\d]+)?%?/,f=/^\w+/,l=/%$/,c=e.fn.position;e.position={scrollbarWidth:function(){if(t!==undefined){return t}var n,r,i=e("
"),s=i.children()[0];e("body").append(i);n=s.offsetWidth;i.css("overflow","scroll");r=s.offsetWidth;if(n===r){r=i[0].clientWidth}i.remove();return t=n-r},getScrollInfo:function(t){var n=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),r=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),i=n==="scroll"||n==="auto"&&t.width0?"right":"center",vertical:u<0?"top":o>0?"bottom":"middle"};if(vr(i(o),i(u))){l.important="horizontal"}else{l.important="vertical"}t.using.call(this,e,l)}}a.offset(e.extend(k,{using:u}))})};e.ui.position={fit:{left:function(e,t){var n=t.within,i=n.isWindow?n.scrollLeft:n.offset.left,s=n.width,o=e.left-t.collisionPosition.marginLeft,u=i-o,a=o+t.collisionWidth-s-i,f;if(t.collisionWidth>s){if(u>0&&a<=0){f=e.left+u+t.collisionWidth-s-i;e.left+=u-f}else if(a>0&&u<=0){e.left=i}else{if(u>a){e.left=i+s-t.collisionWidth}else{e.left=i}}}else if(u>0){e.left+=u}else if(a>0){e.left-=a}else{e.left=r(e.left-o,e.left)}},top:function(e,t){var n=t.within,i=n.isWindow?n.scrollTop:n.offset.top,s=t.within.height,o=e.top-t.collisionPosition.marginTop,u=i-o,a=o+t.collisionHeight-s-i,f;if(t.collisionHeight>s){if(u>0&&a<=0){f=e.top+u+t.collisionHeight-s-i;e.top+=u-f}else if(a>0&&u<=0){e.top=i}else{if(u>a){e.top=i+s-t.collisionHeight}else{e.top=i}}}else if(u>0){e.top+=u}else if(a>0){e.top-=a}else{e.top=r(e.top-o,e.top)}}},flip:{left:function(e,t){var n=t.within,r=n.offset.left+n.scrollLeft,s=n.width,o=n.isWindow?n.scrollLeft:n.offset.left,u=e.left-t.collisionPosition.marginLeft,a=u-o,f=u+t.collisionWidth-s-o,l=t.my[0]==="left"?-t.elemWidth:t.my[0]==="right"?t.elemWidth:0,c=t.at[0]==="left"?t.targetWidth:t.at[0]==="right"?-t.targetWidth:0,h=-2*t.offset[0],p,d;if(a<0){p=e.left+l+c+h+t.collisionWidth-s-r;if(p<0||p0){d=e.left-t.collisionPosition.marginLeft+l+c+h-o;if(d>0||i(d)a&&(v<0||v0){d=e.top-t.collisionPosition.marginTop+c+h+p-o;if(e.top+c+h+p>f&&(d>0||i(d)10&&s<11;t.innerHTML="";r.removeChild(t)})()})();var a=e.ui.position;e.widget("ui.draggable",e.ui.mouse,{version:"1.11.0",widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false,drag:null,start:null,stop:null},_create:function(){if(this.options.helper==="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))){this.element[0].style.position="relative"}if(this.options.addClasses){this.element.addClass("ui-draggable")}if(this.options.disabled){this.element.addClass("ui-draggable-disabled")}this._setHandleClassName();this._mouseInit()},_setOption:function(e,t){this._super(e,t);if(e==="handle"){this._setHandleClassName()}},_destroy:function(){if((this.helper||this.element).is(".ui-draggable-dragging")){this.destroyOnClear=true;return}this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._removeHandleClassName();this._mouseDestroy()},_mouseCapture:function(t){var n=this.document[0],r=this.options;try{if(n.activeElement&&n.activeElement.nodeName.toLowerCase()!=="body"){e(n.activeElement).blur()}}catch(i){}if(this.helper||r.disabled||e(t.target).closest(".ui-resizable-handle").length>0){return false}this.handle=this._getHandle(t);if(!this.handle){return false}e(r.iframeFix===true?"iframe":r.iframeFix).each(function(){e("
").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")});return true},_mouseStart:function(t){var n=this.options;this.helper=this._createHelper(t);this.helper.addClass("ui-draggable-dragging");this._cacheHelperProportions();if(e.ui.ddmanager){e.ui.ddmanager.current=this}this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offsetParent=this.helper.offsetParent();this.offsetParentCssPosition=this.offsetParent.css("position");this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.offset.scroll=false;e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this.position=this._generatePosition(t,false);this.originalPageX=t.pageX;this.originalPageY=t.pageY;n.cursorAt&&this._adjustOffsetFromHelper(n.cursorAt);this._setContainment();if(this._trigger("start",t)===false){this._clear();return false}this._cacheHelperProportions();if(e.ui.ddmanager&&!n.dropBehaviour){e.ui.ddmanager.prepareOffsets(this,t)}this._mouseDrag(t,true);if(e.ui.ddmanager){e.ui.ddmanager.dragStart(this,t)}return true},_mouseDrag:function(t,n){if(this.offsetParentCssPosition==="fixed"){this.offset.parent=this._getParentOffset()}this.position=this._generatePosition(t,true);this.positionAbs=this._convertPositionTo("absolute");if(!n){var r=this._uiHash();if(this._trigger("drag",t,r)===false){this._mouseUp({});return false}this.position=r.position}this.helper[0].style.left=this.position.left+"px";this.helper[0].style.top=this.position.top+"px";if(e.ui.ddmanager){e.ui.ddmanager.drag(this,t)}return false},_mouseStop:function(t){var n=this,r=false;if(e.ui.ddmanager&&!this.options.dropBehaviour){r=e.ui.ddmanager.drop(this,t)}if(this.dropped){r=this.dropped;this.dropped=false}if(this.options.revert==="invalid"&&!r||this.options.revert==="valid"&&r||this.options.revert===true||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,r)){e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){if(n._trigger("stop",t)!==false){n._clear()}})}else{if(this._trigger("stop",t)!==false){this._clear()}}return false},_mouseUp:function(t){e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});if(e.ui.ddmanager){e.ui.ddmanager.dragStop(this,t)}this.element.focus();return e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){if(this.helper.is(".ui-draggable-dragging")){this._mouseUp({})}else{this._clear()}return this},_getHandle:function(t){return this.options.handle?!!e(t.target).closest(this.element.find(this.options.handle)).length:true},_setHandleClassName:function(){this._removeHandleClassName();e(this.options.handle||this.element).addClass("ui-draggable-handle")},_removeHandleClassName:function(){this.element.find(".ui-draggable-handle").addBack().removeClass("ui-draggable-handle")},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t])):n.helper==="clone"?this.element.clone().removeAttr("id"):this.element;if(!r.parents("body").length){r.appendTo(n.appendTo==="parent"?this.element[0].parentNode:n.appendTo)}if(r[0]!==this.element[0]&&!/(fixed|absolute)/.test(r.css("position"))){r.css("position","absolute")}return r},_adjustOffsetFromHelper:function(t){if(typeof t==="string"){t=t.split(" ")}if(e.isArray(t)){t={left:+t[0],top:+t[1]||0}}if("left"in t){this.offset.click.left=t.left+this.margins.left}if("right"in t){this.offset.click.left=this.helperProportions.width-t.right+this.margins.left}if("top"in t){this.offset.click.top=t.top+this.margins.top}if("bottom"in t){this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top}},_isRootNode:function(e){return/(html|body)/i.test(e.tagName)||e===this.document[0]},_getParentOffset:function(){var t=this.offsetParent.offset(),n=this.document[0];if(this.cssPosition==="absolute"&&this.scrollParent[0]!==n&&e.contains(this.scrollParent[0],this.offsetParent[0])){t.left+=this.scrollParent.scrollLeft();t.top+=this.scrollParent.scrollTop()}if(this._isRootNode(this.offsetParent[0])){t={top:0,left:0}}return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition!=="relative"){return{top:0,left:0}}var e=this.element.position(),t=this._isRootNode(this.scrollParent[0]);return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+(!t?this.scrollParent.scrollTop():0),left:e.left-(parseInt(this.helper.css("left"),10)||0)+(!t?this.scrollParent.scrollLeft():0)}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,n,r,i=this.options,s=this.document[0];this.relative_container=null;if(!i.containment){this.containment=null;return}if(i.containment==="window"){this.containment=[e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,e(window).scrollLeft()+e(window).width()-this.helperProportions.width-this.margins.left,e(window).scrollTop()+(e(window).height()||s.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];return}if(i.containment==="document"){this.containment=[0,0,e(s).width()-this.helperProportions.width-this.margins.left,(e(s).height()||s.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];return}if(i.containment.constructor===Array){this.containment=i.containment;return}if(i.containment==="parent"){i.containment=this.helper[0].parentNode}n=e(i.containment);r=n[0];if(!r){return}t=n.css("overflow")!=="hidden";this.containment=[(parseInt(n.css("borderLeftWidth"),10)||0)+(parseInt(n.css("paddingLeft"),10)||0),(parseInt(n.css("borderTopWidth"),10)||0)+(parseInt(n.css("paddingTop"),10)||0),(t?Math.max(r.scrollWidth,r.offsetWidth):r.offsetWidth)-(parseInt(n.css("borderRightWidth"),10)||0)-(parseInt(n.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(r.scrollHeight,r.offsetHeight):r.offsetHeight)-(parseInt(n.css("borderBottomWidth"),10)||0)-(parseInt(n.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom];this.relative_container=n},_convertPositionTo:function(e,t){if(!t){t=this.position}var n=e==="absolute"?1:-1,r=this._isRootNode(this.scrollParent[0]);return{top:t.top+this.offset.relative.top*n+this.offset.parent.top*n-(this.cssPosition==="fixed"?-this.offset.scroll.top:r?0:this.offset.scroll.top)*n,left:t.left+this.offset.relative.left*n+this.offset.parent.left*n-(this.cssPosition==="fixed"?-this.offset.scroll.left:r?0:this.offset.scroll.left)*n}},_generatePosition:function(e,t){var n,r,i,s,o=this.options,u=this._isRootNode(this.scrollParent[0]),a=e.pageX,f=e.pageY;if(!u||!this.offset.scroll){this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}}if(t){if(this.containment){if(this.relative_container){r=this.relative_container.offset();n=[this.containment[0]+r.left,this.containment[1]+r.top,this.containment[2]+r.left,this.containment[3]+r.top]}else{n=this.containment}if(e.pageX-this.offset.click.leftn[2]){a=n[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>n[3]){f=n[3]+this.offset.click.top}}if(o.grid){i=o.grid[1]?this.originalPageY+Math.round((f-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY;f=n?i-this.offset.click.top>=n[1]||i-this.offset.click.top>n[3]?i:i-this.offset.click.top>=n[1]?i-o.grid[1]:i+o.grid[1]:i;s=o.grid[0]?this.originalPageX+Math.round((a-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX;a=n?s-this.offset.click.left>=n[0]||s-this.offset.click.left>n[2]?s:s-this.offset.click.left>=n[0]?s-o.grid[0]:s+o.grid[0]:s}if(o.axis==="y"){a=this.originalPageX}if(o.axis==="x"){f=this.originalPageY}}return{top:f-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition==="fixed"?-this.offset.scroll.top:u?0:this.offset.scroll.top),left:a-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition==="fixed"?-this.offset.scroll.left:u?0:this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");if(this.helper[0]!==this.element[0]&&!this.cancelHelperRemoval){this.helper.remove()}this.helper=null;this.cancelHelperRemoval=false;if(this.destroyOnClear){this.destroy()}},_trigger:function(t,n,r){r=r||this._uiHash();e.ui.plugin.call(this,t,[n,r,this],true);if(t==="drag"){this.positionAbs=this._convertPositionTo("absolute")}return e.Widget.prototype._trigger.call(this,t,n,r)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});e.ui.plugin.add("draggable","connectToSortable",{start:function(t,n,r){var i=r.options,s=e.extend({},n,{item:r.element});r.sortables=[];e(i.connectToSortable).each(function(){var n=e(this).sortable("instance");if(n&&!n.options.disabled){r.sortables.push({instance:n,shouldRevert:n.options.revert});n.refreshPositions();n._trigger("activate",t,s)}})},stop:function(t,n,r){var i=e.extend({},n,{item:r.element});e.each(r.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;r.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert){this.instance.options.revert=this.shouldRevert}this.instance._mouseStop(t);this.instance.options.helper=this.instance.options._helper;if(r.options.helper==="original"){this.instance.currentItem.css({top:"auto",left:"auto"})}}else{this.instance.cancelHelperRemoval=false;this.instance._trigger("deactivate",t,i)}})},drag:function(t,n,r){var i=this;e.each(r.sortables,function(){var s=false,o=this;this.instance.positionAbs=r.positionAbs;this.instance.helperProportions=r.helperProportions;this.instance.offset.click=r.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){s=true;e.each(r.sortables,function(){this.instance.positionAbs=r.positionAbs;this.instance.helperProportions=r.helperProportions;this.instance.offset.click=r.offset.click;if(this!==o&&this.instance._intersectsWith(this.instance.containerCache)&&e.contains(o.instance.element[0],this.instance.element[0])){s=false}return s})}if(s){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=e(i).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return n.helper[0]};t.target=this.instance.currentItem[0];this.instance._mouseCapture(t,true);this.instance._mouseStart(t,true,true);this.instance.offset.click.top=r.offset.click.top;this.instance.offset.click.left=r.offset.click.left;this.instance.offset.parent.left-=r.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=r.offset.parent.top-this.instance.offset.parent.top;r._trigger("toSortable",t);r.dropped=this.instance.element;r.currentItem=r.element;this.instance.fromOutside=r}if(this.instance.currentItem){this.instance._mouseDrag(t)}}else{if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",t,this.instance._uiHash(this.instance));this.instance._mouseStop(t,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();if(this.instance.placeholder){this.instance.placeholder.remove()}r._trigger("fromSortable",t);r.dropped=false}}})}});e.ui.plugin.add("draggable","cursor",{start:function(t,n,r){var i=e("body"),s=r.options;if(i.css("cursor")){s._cursor=i.css("cursor")}i.css("cursor",s.cursor)},stop:function(t,n,r){var i=r.options;if(i._cursor){e("body").css("cursor",i._cursor)}}});e.ui.plugin.add("draggable","opacity",{start:function(t,n,r){var i=e(n.helper),s=r.options;if(i.css("opacity")){s._opacity=i.css("opacity")}i.css("opacity",s.opacity)},stop:function(t,n,r){var i=r.options;if(i._opacity){e(n.helper).css("opacity",i._opacity)}}});e.ui.plugin.add("draggable","scroll",{start:function(e,t,n){if(n.scrollParent[0]!==n.document[0]&&n.scrollParent[0].tagName!=="HTML"){n.overflowOffset=n.scrollParent.offset()}},drag:function(t,n,r){var i=r.options,s=false,o=r.document[0];if(r.scrollParent[0]!==o&&r.scrollParent[0].tagName!=="HTML"){if(!i.axis||i.axis!=="x"){if(r.overflowOffset.top+r.scrollParent[0].offsetHeight-t.pageY=0;h--){a=r.snapElements[h].left;f=a+r.snapElements[h].width;l=r.snapElements[h].top;c=l+r.snapElements[h].height;if(gf+v||bc+v||!e.contains(r.snapElements[h].item.ownerDocument,r.snapElements[h].item)){if(r.snapElements[h].snapping){r.options.snap.release&&r.options.snap.release.call(r.element,t,e.extend(r._uiHash(),{snapItem:r.snapElements[h].item}))}r.snapElements[h].snapping=false;continue}if(d.snapMode!=="inner"){i=Math.abs(l-b)<=v;s=Math.abs(c-y)<=v;o=Math.abs(a-g)<=v;u=Math.abs(f-m)<=v;if(i){n.position.top=r._convertPositionTo("relative",{top:l-r.helperProportions.height,left:0}).top-r.margins.top}if(s){n.position.top=r._convertPositionTo("relative",{top:c,left:0}).top-r.margins.top}if(o){n.position.left=r._convertPositionTo("relative",{top:0,left:a-r.helperProportions.width}).left-r.margins.left}if(u){n.position.left=r._convertPositionTo("relative",{top:0,left:f}).left-r.margins.left}}p=i||s||o||u;if(d.snapMode!=="outer"){i=Math.abs(l-y)<=v;s=Math.abs(c-b)<=v;o=Math.abs(a-m)<=v;u=Math.abs(f-g)<=v;if(i){n.position.top=r._convertPositionTo("relative",{top:l,left:0}).top-r.margins.top}if(s){n.position.top=r._convertPositionTo("relative",{top:c-r.helperProportions.height,left:0}).top-r.margins.top}if(o){n.position.left=r._convertPositionTo("relative",{top:0,left:a}).left-r.margins.left}if(u){n.position.left=r._convertPositionTo("relative",{top:0,left:f-r.helperProportions.width}).left-r.margins.left}}if(!r.snapElements[h].snapping&&(i||s||o||u||p)){r.options.snap.snap&&r.options.snap.snap.call(r.element,t,e.extend(r._uiHash(),{snapItem:r.snapElements[h].item}))}r.snapElements[h].snapping=i||s||o||u||p}}});e.ui.plugin.add("draggable","stack",{start:function(t,n,r){var i,s=r.options,o=e.makeArray(e(s.stack)).sort(function(t,n){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(n).css("zIndex"),10)||0)});if(!o.length){return}i=parseInt(e(o[0]).css("zIndex"),10)||0;e(o).each(function(t){e(this).css("zIndex",i+t)});this.css("zIndex",i+o.length)}});e.ui.plugin.add("draggable","zIndex",{start:function(t,n,r){var i=e(n.helper),s=r.options;if(i.css("zIndex")){s._zIndex=i.css("zIndex")}i.css("zIndex",s.zIndex)},stop:function(t,n,r){var i=r.options;if(i._zIndex){e(n.helper).css("zIndex",i._zIndex)}}});var f=e.ui.draggable}) \ No newline at end of file diff --git a/nano/js/libraries.min.js b/nano/js/libraries.min.js deleted file mode 100644 index a2cbbad8f1b..00000000000 --- a/nano/js/libraries.min.js +++ /dev/null @@ -1,50 +0,0 @@ -/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ -!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t="length"in e&&e.length,n=it.type(e);return"function"===n||it.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e}function r(e,t,n){if(it.isFunction(t))return it.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return it.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(ft.test(t))return it.filter(t,e,n);t=it.filter(t,e)}return it.grep(e,function(e){return it.inArray(e,t)>=0!==n})}function i(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function o(e){var t=xt[e]={};return it.each(e.match(bt)||[],function(e,n){t[n]=!0}),t}function a(){ht.addEventListener?(ht.removeEventListener("DOMContentLoaded",s,!1),e.removeEventListener("load",s,!1)):(ht.detachEvent("onreadystatechange",s),e.detachEvent("onload",s))}function s(){(ht.addEventListener||"load"===event.type||"complete"===ht.readyState)&&(a(),it.ready())}function l(e,t,n){if(void 0===n&&1===e.nodeType){var r="data-"+t.replace(Et,"-$1").toLowerCase();if(n=e.getAttribute(r),"string"==typeof n){try{n="true"===n?!0:"false"===n?!1:"null"===n?null:+n+""===n?+n:Nt.test(n)?it.parseJSON(n):n}catch(i){}it.data(e,t,n)}else n=void 0}return n}function u(e){var t;for(t in e)if(("data"!==t||!it.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function c(e,t,n,r){if(it.acceptData(e)){var i,o,a=it.expando,s=e.nodeType,l=s?it.cache:e,u=s?e[a]:e[a]&&a;if(u&&l[u]&&(r||l[u].data)||void 0!==n||"string"!=typeof t)return u||(u=s?e[a]=J.pop()||it.guid++:a),l[u]||(l[u]=s?{}:{toJSON:it.noop}),("object"==typeof t||"function"==typeof t)&&(r?l[u]=it.extend(l[u],t):l[u].data=it.extend(l[u].data,t)),o=l[u],r||(o.data||(o.data={}),o=o.data),void 0!==n&&(o[it.camelCase(t)]=n),"string"==typeof t?(i=o[t],null==i&&(i=o[it.camelCase(t)])):i=o,i}}function d(e,t,n){if(it.acceptData(e)){var r,i,o=e.nodeType,a=o?it.cache:e,s=o?e[it.expando]:it.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){it.isArray(t)?t=t.concat(it.map(t,it.camelCase)):t in r?t=[t]:(t=it.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;for(;i--;)delete r[t[i]];if(n?!u(r):!it.isEmptyObject(r))return}(n||(delete a[s].data,u(a[s])))&&(o?it.cleanData([e],!0):nt.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}function f(){return!0}function p(){return!1}function h(){try{return ht.activeElement}catch(e){}}function m(e){var t=Ft.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function g(e,t){var n,r,i=0,o=typeof e.getElementsByTagName!==Ct?e.getElementsByTagName(t||"*"):typeof e.querySelectorAll!==Ct?e.querySelectorAll(t||"*"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(r=n[i]);i++)!t||it.nodeName(r,t)?o.push(r):it.merge(o,g(r,t));return void 0===t||t&&it.nodeName(e,t)?it.merge([e],o):o}function v(e){jt.test(e.type)&&(e.defaultChecked=e.checked)}function y(e,t){return it.nodeName(e,"table")&&it.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function b(e){return e.type=(null!==it.find.attr(e,"type"))+"/"+e.type,e}function x(e){var t=Vt.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function w(e,t){for(var n,r=0;null!=(n=e[r]);r++)it._data(n,"globalEval",!t||it._data(t[r],"globalEval"))}function T(e,t){if(1===t.nodeType&&it.hasData(e)){var n,r,i,o=it._data(e),a=it._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)it.event.add(t,n,s[n][r])}a.data&&(a.data=it.extend({},a.data))}}function C(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!nt.noCloneEvent&&t[it.expando]){i=it._data(t);for(r in i.events)it.removeEvent(t,r,i.handle);t.removeAttribute(it.expando)}"script"===n&&t.text!==e.text?(b(t).text=e.text,x(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),nt.html5Clone&&e.innerHTML&&!it.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&jt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}function N(t,n){var r,i=it(n.createElement(t)).appendTo(n.body),o=e.getDefaultComputedStyle&&(r=e.getDefaultComputedStyle(i[0]))?r.display:it.css(i[0],"display");return i.detach(),o}function E(e){var t=ht,n=Zt[e];return n||(n=N(e,t),"none"!==n&&n||(Kt=(Kt||it("